healthypi — host library and CLI for HealthyPi 6
One package instead of nineteen scripts, on the same rule the firmware uses: a capability is implemented once, and the CLI is a thin adapter over it.
Distribution name protocentral-healthypi; the import package and the
console script are both healthypi. There is no hpi alias: the firmware's
own shell registers a root command by that name, which runs on the device and
has different verbs, so hpi ... in any instruction means the device shell and
healthypi ... means this tool.
pip install protocentral-healthypi # library only, stdlib deps
pip install "protocentral-healthypi[device]" # + smpclient/pyserial/cryptography
# from a checkout: install smpgroup from the same checkout, not from PyPI
pip install -e tools/smpgroup -e "tools/healthypi[device]"
What works today
| Module | State |
|---|---|
healthypi.hp6 |
✅ decode/verify/export/repair .HP6, files and live streams |
healthypi.smp.catalog |
✅ the group-64 single source of truth, drift-checked against the firmware |
healthypi.smp.group64 |
✅ wire classes, generated from the catalog |
healthypi.transport |
✅ CDC 1 connect + autodetect |
healthypi.openview |
✅ Wi-Fi (OpenView v2) decode + monitor |
healthypi.cli |
✅ the healthypi command |
healthypi.fw |
✅ .hpifw bundles, M7+M4 update, MCUboot serial recovery |
healthypi.hw |
✅ HealthyLink module EEPROM images |
healthypi.testing |
✅ the group-64 acceptance suite, importable |
171 tests, no hardware required.
healthypi.fw's offline half (bundle create, verify, and refusing a tampered or
wrongly-signed one) is covered by tests. Its device half — upload, commit,
reset and reconnect — has never run against a board since the fold; that is the
bench gate, not a green suite.
healthypi.hp6 and healthypi.smp.catalog are stdlib-only on purpose:
decoding a recording, and checking the protocol catalog against the firmware,
must never require a device stack to be installed.
hp6 — the container
from healthypi import hp6
header, blocks = hp6.read_file("REC0001.HP6")
for blk in blocks: # lazy: 2 GiB files stream
for s in blk.samples():
...
report = hp6.verify("REC0001.HP6") # CRCs, seq gaps, sync chain, counts
hp6.export_csv("REC0001.HP6", "out/") # one CSV per channel, streaming
hp6.repair("yanked.HP6") # → yanked.HP6.repaired
hp6.wrap_capture(cdc0_bytes, "capture.HP6") # a raw stream is not a file
The same DBLK frame carries the live CDC0 stream and the recorded file; only
the container differs (the file adds the 256-byte header, sync markers and
sidecars). Layout: docs/HP6_DATA_FORMAT.md.
The reader never aborts on bad data — a corrupt block resyncs to the next
DBLK and the loss is counted in ReadStats. That is required, not defensive:
the device drops frames on a full consumer ring rather than back-pressuring
acquisition, so gaps are normal.
smp.catalog — the protocol
from healthypi.smp import catalog
catalog.BY_NAME["telemetry"].response # every key the device sends
catalog.live() # 27 commands that really work
catalog.unlock_gated() # 9 that need the security unlock
catalog.err_hint(267) # 'no SD card present'
Transcribed from hpi_mgmt_group.h, the dispatch table in hpi_mgmt_group.c,
and the handler sources. tests/test_catalog_drift.py re-parses all three via
smpgroup.drift and fails on any disagreement — command ids,
dispatch status, error codes, and every request/response key. Prose version with
reference: docs/MCUMGR_COMMANDS.md.
smp.group64 — the wire
from healthypi.smp.group64 import g, fmt_error, is_error
async with SMPClient(SMPSerialTransport(), port) as client:
info = await client.request(g.device_info())
await client.request(g.stream_start(ch=0x03, ann=0))
await client.request(g.transfer_mode_write(on=True))
Generated from the catalog by smpgroup — there are no
hand-written request/response classes, and there must never be. A set of
requests is checked against golden wire bytes recorded when the update path was
validated on v5 hardware, so a catalog edit cannot silently change an encoding.
CLI
healthypi catalog # every group-64 command, and its real status
healthypi catalog --json --full # ...with request/reply schemas (for code generators)
healthypi catalog --formats # the .HP6 DBLK payload layouts, as JSON
healthypi hp6 verify REC0001.HP6 # CRCs, gaps, counters
healthypi hp6 to-csv REC0001.HP6 out/
healthypi device info # port autodetected
healthypi device reset # reboot (e.g. after an M4 commit)
healthypi telemetry --json
healthypi stream start --ch 0x03 # ECG + PPG
healthypi record start --name walk
healthypi transfer arm # SD card as a USB disk (drops the connection)
healthypi wifi-stream monitor --udp # Wi-Fi packet rate and loss
# firmware
healthypi fw info --bundle hpi6-1.0.0.hpifw --pubkey release.pem # offline
healthypi fw update --bundle hpi6-1.0.0.hpifw # all processors
healthypi fw update --bundle hpi6-1.0.0.hpifw --only m4 --force
healthypi fw enter-recovery # into MCUboot
healthypi fw recover --port <recovery-port> --bundle hpi6-1.0.0.hpifw
# acceptance suite (the bench gate)
healthypi test list # the cases and what each needs
healthypi test run # read-only by default
healthypi test run --destructive --group fw
healthypi test soak --iterations 60000 # 0 errors, p99 < 50 ms
# HealthyLink module EEPROMs
healthypi hl eeprom generate -m EEG-8CH -n "EEG-8CH" -s 10001 -o eeprom.bin
healthypi hl eeprom read eeprom.bin # non-zero exit on a bad CRC
healthypi hl eeprom stack --modules EEG-8CH TRIGGER-IO AI-ACCELERATOR
Update order is esp32c6 → m4 → m7; the M7 goes last because it is what applies
the other two. The C6 is skipped over USB — it updates itself over Wi-Fi.
The EEPROM verbs build the 256-byte image. Writing it to a real 24AA02 needs an external programmer (FT232H, Raspberry Pi I2C, CH341A, Bus Pirate) and that programmer's own tool; nothing here drives one.
--port is optional: CDC 1 is found by asking each serial port for an os echo, which only the control port answers. Every read verb takes --json.
Tests
pytest -q # 171 tests, no hardware
PYTHONPATH=src python3 -m pytest -m hw --port /dev/tty.usbmodem…3 # (P3+)
The drift tests skip cleanly outside the firmware tree, so the package stays testable standalone.
Metadata
Release files for protocentral-healthypi 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| protocentral_healthypi-0.1.2.tar.gz | 110.0 kB | With provenance | Details for protocentral_healthypi-0.1.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| protocentral_healthypi-0.1.2-py3-none-any.whl | Python 3 | none | any | Details for protocentral_healthypi-0.1.2-py3-none-any.whl |
Total release size: 206.3 kB
Release files / protocentral_healthypi-0.1.2.tar.gz
| Download URL | protocentral_healthypi-0.1.2.tar.gz |
|---|---|
| Size | 110.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2dd97685cd83f9fd24b5435cf2fff6f912603014ece1c08b953bba7d28ac2a9d
|
|
BLAKE2b-256 checksum How to use checksums |
77e33a2fa9b67543e9bee69cb219629d1fdb9040893dd1f5e8ea1db245d7c7f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.
Transparency logRelease files / protocentral_healthypi-0.1.2-py3-none-any.whl
| Download URL | protocentral_healthypi-0.1.2-py3-none-any.whl |
|---|---|
| Size | 96.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
18072fcb51a51c5bc65a8420591c7c4923f44bfafcae85080270d4fa46e43f4e
|
|
BLAKE2b-256 checksum How to use checksums |
e16e0edfe0aa570c58e797b48fcb8e942b15cc461f214dfb7d78faf8f2960779
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.
Transparency logSecurity for protocentral-healthypi 0.1.2
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for protocentral_healthypi-0.1.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.
Transparency logA 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.