wattchli
wattchli is a simple HUD that allows you to keep an eye on your cycling stats while playing games or watching videos.
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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wattchli-0.0.1.tar.gz.
File metadata
- Download URL: wattchli-0.0.1.tar.gz
- Upload date:
- Size: 104.1 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ffd27ef67fcf1801bd41c786a7447c71066ff1ad19f87c881107d53751fb7441
|
|
| MD5 |
5b584227343ab67d88bb930e73295f97
|
|
| BLAKE2b-256 |
cc15e8d2f2d6ed959b5f870229e4f9b31cef3ff45fd132c33dfb6f7f90031e0d
|
File details
Details for the file wattchli-0.0.1-py3-none-any.whl.
File metadata
- Download URL: wattchli-0.0.1-py3-none-any.whl
- Upload date:
- Size: 123.3 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ff22b68aeac6839102a7268fd38801a557bd80859cc97bb981dda3070c4cf3a
|
|
| MD5 |
ea5b7d154a423ff2bee7bb3f9c950e24
|
|
| BLAKE2b-256 |
2d7f609f75bdac7dcfb86b7565b9322f40eafab75bb5c3360db1be1104533e60
|