Lightweight hardware sensor monitor for Windows — reads HWiNFO64 shared memory and logs JSON Lines
Project description
sensorwatch
A lightweight hardware sensor monitor for Windows. It reads HWiNFO64's shared-memory sensor feed and logs readings as JSON Lines with daily file rotation — a small, dependency-light background process you can leave running and analyze later.
PSU efficiency monitoring is the first use case (see the worked example below), but sensorwatch is sensor-agnostic: it captures anything HWiNFO exposes — temperatures, voltages, currents, power, fan speeds, clocks, and usage.
Flagship result: a ~5.5-hour real-world capture shows the MSI MEG Ai1600T exceeds 80 PLUS Titanium efficiency at every measured load point (peak 94.5%, zero samples below 92%). Data, charts, and analysis:
examples/psu-efficiency/.
Features
- Reads HWiNFO64 shared memory (
Global\HWiNFO_SENS_SM2) directly viactypes— no polling of HWiNFO's UI, no admin rights. - Sensor filtering by case-insensitive substring include/exclude patterns.
- JSON Lines output with daily file rotation and configurable retention.
- Graceful shutdown on Ctrl+C / signals.
- Light footprint — a handful of stdlib modules plus
pendulum.
Requirements
- Windows (x64)
- Python 3.12+
- HWiNFO64 running with Shared Memory Support enabled (Settings → Shared Memory Support) and the sensors window open.
Install
git clone https://github.com/lcjanke2020/sensorwatch
cd sensorwatch
pip install -e . # or: uv sync
Usage
# Run with the bundled default config
python -m sensorwatch
# Or use the installed console script
sensorwatch --config config.toml --verbose
If HWiNFO64 is not running (or shared memory is disabled), sensorwatch logs a warning and keeps trying — start HWiNFO and readings begin flowing.
Output format
One JSON object per sample, written to logs/sensors_YYYY-MM-DD.jsonl:
{"timestamp": "2026-02-18T08:17:48-05:00", "sensors": [
{"sensor": "MEG Ai1600T", "reading": "+12V", "type": "Voltage", "value": 12.03, "min": 12.01, "max": 12.17, "avg": 12.06, "unit": "V"}
]}
Configuration
config.toml:
| Key | Default | Description |
|---|---|---|
general.interval_seconds |
10 |
Seconds between samples |
general.log_dir |
"logs" |
Directory for JSONL output |
general.retention_days |
30 |
Delete log files older than this on startup (0 = keep all) |
sensors.include |
[] |
Substring patterns to capture (empty = all sensors) |
sensors.exclude |
[] |
Substring patterns to drop (applied after include) |
Example — capture only a specific PSU's sensors:
[sensors]
include = ["MEG Ai1600T"]
Testing / CI scope
Continuous integration runs the unit tests on Ubuntu and Windows across Python
3.12 and 3.13. The tests cover the parsing, configuration, and logging
logic — in particular, the HWiNFO shared-memory parser is exercised against
synthetic byte buffers (_parse_shared_memory()), so the untrusted-header
bounds checks are validated without a live sensor source.
CI does not — and cannot — exercise a real sensor read. That path requires HWiNFO64 running on Windows with Shared Memory Support enabled, and is verified manually. So a green CI badge means the logic is sound, not that end-to-end sensor reading has been validated on your machine.
Run the tests locally:
uv sync
uv run pytest
Roadmap
sensorwatch starts as a Python monitor and grows toward a general hardware observability toolkit:
- Source-adapter architecture — pluggable sensor sources behind one interface (HWiNFO today; UPS, AIDA64, and IPMI next) with stable sensor identities and per-reading quality flags.
- Optional localhost REST service for live queries (bound to
127.0.0.1). - Language bindings over a shared core.
- Agent integration via an MCP / skill layer so AI agents can query hardware state directly.
See SECURITY.md for the threat model covering these planned
components.
Security
sensorwatch reads read-only hardware data and writes local log files; it opens
no network listeners in its current form. The full threat model — shared-memory
attack surface, the planned REST service and agent layer, supply-chain notes —
is in SECURITY.md. Please report vulnerabilities privately (see
that document).
Contributing
Contributions are welcome — see CONTRIBUTING.md.
License
MIT © Leonard Janke
Project details
Release history Release notifications | RSS feed
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 sensorwatch-0.1.1.tar.gz.
File metadata
- Download URL: sensorwatch-0.1.1.tar.gz
- Upload date:
- Size: 75.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
abec8b2424e8a5c595fe3ac362f65a8bfb67d16c071c98ef6378e14cb4eb36b6
|
|
| MD5 |
11a219501633dbbbb9797fa3a65b36a7
|
|
| BLAKE2b-256 |
3a7d37b2cfb384ff479cf27895f0598896611b0c0a412a73518159e3e5e354cb
|
Provenance
The following attestation bundles were made for sensorwatch-0.1.1.tar.gz:
Publisher:
publish.yml on lcjanke2020/sensorwatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sensorwatch-0.1.1.tar.gz -
Subject digest:
abec8b2424e8a5c595fe3ac362f65a8bfb67d16c071c98ef6378e14cb4eb36b6 - Sigstore transparency entry: 1995763200
- Sigstore integration time:
-
Permalink:
lcjanke2020/sensorwatch@da0be3c9767d9c99280b83ef1aa6de554718c060 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/lcjanke2020
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@da0be3c9767d9c99280b83ef1aa6de554718c060 -
Trigger Event:
release
-
Statement type:
File details
Details for the file sensorwatch-0.1.1-py3-none-any.whl.
File metadata
- Download URL: sensorwatch-0.1.1-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64479818239fb79ee53f9a9eb1504ee4ee98b0bb818a2c154d70c6f8f7d7cd0e
|
|
| MD5 |
9796b81bae512d7ede0f6f0fc4c0af62
|
|
| BLAKE2b-256 |
bfbd52c658a44bbeeb24b5863e606ebae21194c413342fc00caff48ccdc278f8
|
Provenance
The following attestation bundles were made for sensorwatch-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on lcjanke2020/sensorwatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sensorwatch-0.1.1-py3-none-any.whl -
Subject digest:
64479818239fb79ee53f9a9eb1504ee4ee98b0bb818a2c154d70c6f8f7d7cd0e - Sigstore transparency entry: 1995763244
- Sigstore integration time:
-
Permalink:
lcjanke2020/sensorwatch@da0be3c9767d9c99280b83ef1aa6de554718c060 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/lcjanke2020
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@da0be3c9767d9c99280b83ef1aa6de554718c060 -
Trigger Event:
release
-
Statement type: