Skip to main content

wattchli

wattchli is a simple HUD that allows you to keep an eye on your cycling stats while playing games or watching videos.

SuperTuxKart

Big Buck Bunny

Installation

wattchli is a Python application, so you can install/run it in whatever way you want.

For example:

# option 1: run from manual local clone
git clone https://codeberg.org/cyctlr/wattchli.git
cd wattchli
uv sync
uv run wattchli

# option 2: install with pipx
pipx install git+https://codeberg.org/cyctlr/wattchli.git
wattchli

# option 3: install with uv tool
uv tool install git+https://codeberg.org/cyctlr/wattchli.git
wattchli

Interaction

The HUD is a frameless window but there's a drag handle at the bottom-right that allows you to move it around by pressing the left mouse button in that area. It's usually necessary to move the HUD into the right position before opening a game in fullscreen mode. The context menu can be opened by right-clicking on the drag handle.

Sensors

The app supports cycling power sensors, heart rate sensors and cycling speed & cadence sensors.

Currently the app connects automatically to nearby sensors.

Customization

wattchli can be customized via config.json and style.css placed into ~/.config/wattchli (or %APPDATA%\wattchli).

It is recommended to start wattchli with --mock_sensors while configuring things. This mocks the sensors and gives instant feedback.

Configuration

config.json allows you to configure every aspect of the application, most importantly, the metrics you want to display (via pages/rows/cols).

Here's an example with all configuration values. It should be mostly self-explanatory.

{
  "wheelCircumferenceMm": 2100,
  "pages": [
    {
      "name": "page0",
      "rows": [
        {
          "cols": [
            { "widget": { "widgetType": "metric", "metricType": "heartRate" } },
            { "widget": { "widgetType": "metric", "metricType": "power" } }
          ]
        },
        {
          "cols": [
            { "widget": { "widgetType": "metric", "metricType": "power3s" } },
            { "widget": { "widgetType": "metric", "metricType": "cadence" } }
          ]
        },
        {
          "cols": [
            { "widget": { "widgetType": "metric", "metricType": "speed" } },
            { "widget": { "widgetType": "metric", "metricType": "distance" } }
          ]
        }
      ]
    },
    {
      "name": "page1",
      "rows": [
        {
          "cols": [
            { "widget": { "widgetType": "metric", "metricType": "speed" } },
            { "widget": { "widgetType": "blank" } }
          ]
        },
        {
          "cols": [
            { "widget": { "widgetType": "blank" } },
            {
              "widget": {
                "widgetType": "metric",
                "metricType": "heartRate",
                "formatter": "f'{value}<span style=\"color:red;\">\u2764</span>'"
              }
            }
          ]
        }
      ]
    }
  ],
  "disableClickthrough": false,
  "cursorPollMs": 50,
  "mockSensors": false,
  "logLevel": "info"
}

The values can also be overridden with CLI arguments (see --help).

Advanced

It's possible to configure a custom formatter. The formatter is a Python expression evaluated by simpleeval. The value variable is available as a float and must be converted to a string. The string supports rich text. So it's possible to pass simple HTML.

Examples:

  • f'{value}'
  • f'{value:.0f}'
  • f'{value}<span style=\"color:red;\">\u2764</span>'

Styling

The app can be styled with CSS.

The app's base stylesheet is the following, and the user's stylesheet is appended to it.

/* common to all metric texts: title, value, unit */
.metric-text {
  color: white;
  outline-color: black;
  font-weight: bold;
}

.metric-value {
  font-family: system-fixed;
  font-size: 3em;
}

.metric-title {
  font-family: system-title;
}
.metric-unit {
  font-family: system-small;
  /* hide if not needed */
  /* display: none; */
}

page {
  margin: 20px 10px 20px 10px;
  row-gap: 10px;
  column-gap: 10px;
}

window {
  color: #40000000;
  border-color: #40ffffff;
  border-width: 1px;
  border-radius: 16px;
}

Platform Notes

macOS

Cold Start Times

Cold starts on macOS might be slow (~5s) due to Apple scanning dynamically loaded libraries with syspolicyd. Consecutive runs will be much faster.

(It is not recommended to do so, but to temporarily avoid this overhead, add and activate your terminal under Privacy & Security -> Developer Tools, then restart your terminal.)

Windows

Note that the HUD may not appear over exclusive fullscreen games. If possible switch to borderless windowed mode.

License

GNU General Public License v3.0 or later - see LICENSE for details.

Metadata

Release files for wattchli 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wattchli 0.0.1
File Size Uploaded Provenance Actions
wattchli-0.0.1.tar.gz 104.1 kB Without provenance Details for wattchli-0.0.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for wattchli 0.0.1
File Interpreter ABI Platform Actions
wattchli-0.0.1-py3-none-any.whl Python 3 none any Details for wattchli-0.0.1-py3-none-any.whl

Total release size: 227.4 kB

Release files / wattchli-0.0.1.tar.gz

Download URL wattchli-0.0.1.tar.gz
Size 104.1 kB
Tags Source
SHA-256 checksum
How to use checksums
ffd27ef67fcf1801bd41c786a7447c71066ff1ad19f87c881107d53751fb7441
BLAKE2b-256 checksum
How to use checksums
cc15e8d2f2d6ed959b5f870229e4f9b31cef3ff45fd132c33dfb6f7f90031e0d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / wattchli-0.0.1-py3-none-any.whl

Download URL wattchli-0.0.1-py3-none-any.whl
Size 123.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9ff22b68aeac6839102a7268fd38801a557bd80859cc97bb981dda3070c4cf3a
BLAKE2b-256 checksum
How to use checksums
2d7f609f75bdac7dcfb86b7565b9322f40eafab75bb5c3360db1be1104533e60
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for wattchli 0.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page