Cross-platform .NET 10 Bluetooth LE heart-rate monitor server for the XOSS X1 Heart Rate Monitor Armband and compatible BLE HRM devices.
Streams real-time BPM data via WebSocket and JSON.
- Connects automatically to your XOSS X1 or other Bluetooth LE heart-rate monitors.
- Outputs live BPM readings to:
- WebSocket:
ws://localhost:5279/ws - HTTP JSON endpoint:
http://localhost:5279/latest - Rolling Stats:
http://localhost:5279/stats - Session History:
http://localhost:5279/history - HTML Dashboard:
http://localhost:5279/dashboard - Log Browser / CSV:
http://localhost:5279/logs
- WebSocket:
- Cross-platform — Windows and Linux (.NET 10 auto-selects the right target).
- Automatic port retry if the default port is in use.
- Shows live console output for debugging and verification.
- .NET 10 SDK
- Bluetooth LE adapter supported by your OS
(Windows Bluetooth stack or BlueZ on Linux)
Clone and run directly:
git clone https://github.com/troyBORG/XossHrmServer.git
cd XossHrmServer
dotnet runOn Windows it automatically targets net10.0-windows10.0.19041.0;
on Linux it uses net10.0.
When running successfully, you should see something like this:
$ dotnet run
[BLE] Starting BLE worker on Microsoft Windows 11...
[BLE] Worker starting on Microsoft Windows 11… token: XOSS
[LOG] Writing HRM data to logs/session_2025-12-03_17-54-30.csv
[BLE] Scanning for devices…
[HTTP] Server running on http://0.0.0.0:5279
[BLE] Connecting to XOSS_HRM_0376102 (D6:80:4B:E1:E7:A1) …
[BLE] Battery initial: 57%
[BLE] Subscribing to HR notifications…
[BLE] XOSS_HRM_0376102: 73 bpm
[BLE] XOSS_HRM_0376102: 69 bpm
[BLE] XOSS_HRM_0376102: 78 bpmOn Linux:
$ dotnet run -f net10.0
[BLE] Starting BLE worker on CachyOS...
[BLE] Worker starting on CachyOS… token: XOSS
[LOG] Writing HRM data to logs/session_2025-12-03_17-54-30.csv
[BLE] Scanning for devices…
[HTTP] Server running on http://0.0.0.0:5279
[BLE] Connecting to XOSS_HRM_0376102 (D6:80:4B:E1:E7:A1) …
[BLE] Battery initial: 57%
[BLE] Subscribing to HR notifications…
[BLE] XOSS_HRM_0376102: 81 bpmhttp://localhost:5279/latest
{
"device": "XOSS_HRM_0376102",
"bpm": 79,
"ts": "2025-10-06T18:19:26.3176012+00:00",
"battery": 100,
"rr": [],
"energy": null
}http://localhost:5279/stats
{
"from":"2025-10-06T18:20:01.120Z",
"to":"2025-10-06T18:21:01.987Z",
"count":58,
"bpmAvg":77.41,
"bpmMin":69,
"bpmMax":83,
"stdDev":3.92,
"ratePerSec":0.012,
"ratePer5Sec":-0.066,
"zScore":-0.51,
"rmssd":null,
"sdnn":null
}http://localhost:5279/history
Returns the full set of per-minute aggregated readings in JSON.
http://localhost:5279/dashboard
Interactive HTML chart displaying live and historical BPM data.
http://localhost:5279/logs
Lists all saved CSV sessions (when logging is enabled).
| Variable | Default | Description |
|---|---|---|
HRM_DEVICE_NAME |
XOSS |
Name token to match your HRM device |
PORT |
5279 |
HTTP / WebSocket server port (auto-retries if in use) |
DOTNET_DISABLE_BLE |
false |
Set to true to run in HTTP-only mode |
ALLOW_ZERO_BPM |
false |
Set to true to allow 0 BPM readings |
HRM_RECONNECT_DELAY_MS |
150 |
Delay (ms) before rescanning after a disconnect; lower = faster reconnect |
HRM_CONNECT_DELAY_MS |
150 |
Delay (ms) after scan before connecting |
HRM_CONNECT_RETRIES |
5 |
Number of connection attempts per scan before rescanning |
HRM_NO_DATA_TIMEOUT_SEC |
20 |
If no HR reading for this many seconds, attempt re-subscribe then reconnect |
HRM_AUTO_RESTART_BLUETOOTH |
false |
Linux only: auto-attempt systemctl restart bluetooth after repeated adapter-abort failures |
HRM_BLUETOOTH_RESTART_THRESHOLD |
12 |
Consecutive local-abort failures before auto-restart is attempted |
HRM_BLUETOOTH_RESTART_COOLDOWN_SEC |
120 |
Minimum seconds between bluetooth service auto-restart attempts |
- Uses InTheHand.BluetoothLE for cross-platform BLE support.
- Windows: Uses WinRT Bluetooth APIs
- Linux: Uses BlueZ via D-Bus (ensure BlueZ is installed:
sudo pacman -S bluez bluez-utilsorsudo apt install bluez)
/latestreturns 204 No Content until the first BPM packet is received./wsprovides a live WebSocket telemetry stream./stats,/history, and/dashboardprovide rolling analytics and CSV logging.- Session data is automatically logged to CSV files in the
logs/directory. - Connection drops (e.g. low Bluetooth signal): The server now attempts an in-place HR notification re-subscribe before forcing a reconnect, then uses aggressive reconnect defaults.
- Linux
le-connection-abort-by-local: The server uses adaptive cooldowns after repeated aborts to avoid tight failure loops. If failures continue, enableHRM_AUTO_RESTART_BLUETOOTH=trueand consider increasingLEAutoconnecttimeoutin/etc/bluetooth/main.conf(e.g.LEAutoconnecttimeout=16000).
MIT License © 2025 troyBORG