Releases: dgprivate/kronoterm2mqtt
Release list
0.1.20
Two additions, and both were checked rather than asserted.
services:
kronoterm2mqtt:
image: hausbit/kronoterm2mqtt:0.1.20Home Assistant add-on
Home Assistant OS and Supervised installations can install this from an add-on repository instead of running a container by hand: Settings → Add-ons → Add-on store → ⋮ → Repositories, add https://github.com/dgprivate/kronoterm2mqtt, install kronoterm2mqtt.
- Every setting is on the Configuration tab — MQTT, TLS, the heat pump, the health endpoint, and all of the custom expander including its lists. A test walks the settings dataclasses and fails if the manifest misses one, and a second fails if it offers something the app does not know.
- The broker fills itself in.
use_supervisortakes the address and credentials from the Mosquitto add-on, because Home Assistant already knows them. - Still unprivileged. The entrypoint starts as root to write
/data, then drops to UID 65532 before starting the app. - Watched. The Supervisor polls the same health endpoint the container health check uses, and restarts the add-on when it stops answering.
Documentation for every option is in ha-addon/DOCS.md.
Fuzzing
Three Atheris targets over the input the project does not control — the health report read off a socket, the settings file edited by hand, and the bytes a Modbus gateway sends — run per pull request and weekly, with the corpus cached so coverage accumulates. See fuzz/README.md.
It found two defects in the health command in its first two runs, both fixed here with the inputs pinned as tests:
- a report missing the keys the command expects — an older container, a truncated answer, or something else on that port — ended in a
KeyErrortraceback instead of a status - a report value containing square brackets, which a Modbus error such as
Invalid response [0x10]is, was read by rich as markup and ended in aMarkupError
Also
- The repository's
mainbranch is protected: pull requests, passing tests on 3.12/3.13/3.14, and resolved conversations before a merge. - Renovate leaves the add-on's own image tag alone, since the release moves it together with the version.
Vulnerabilities
No publicly known run-time vulnerabilities were fixed in this release.
0.1.19
Everything in this release is about being able to check what the project claims, rather than take it on trust.
services:
kronoterm2mqtt:
image: hausbit/kronoterm2mqtt:0.1.19Tests and correctness
- 200 tests, coverage 83% → 96%, and the build now fails below 95%
- Writing them turned up three real defects, all fixed: the loop mode callback compared an enum member against a string so expedited heating never switched itself off after five hours; an unknown MQTT payload escaped the callback that was written to catch it; and
ranges()was annotated as returning a list while being a generator - Two pieces of dead code removed: a
get_definitions()copied onto a class that lacks the field it reads, and thetomlifallback that cannot run on Python 3.12
Documentation
REFERENCE.md— every command, setting, Modbus register source, MQTT topic and health responseCONTRIBUTING.md— what a change has to pass before it can be mergedSECURITY.mdandCODE_OF_CONDUCT.md— how to report something, privately- README now leads with the published image and says where to send a bug report
Supply chain
security/README.mdmaps the CIS Docker Benchmark controls to the command that verifies each one, and states what is deliberately not claimed: FIPS, STIG, or any patching service level- OpenVEX statements record findings that cannot be fixed and do not apply here, in a form
grype --vexandtrivy --vexread - Renovate keeps the base image digest, syft, uv, the actions and
uv.lockmoving; the image is rebuilt weekly - Every GitHub Action is pinned by commit SHA, uv is copied from a digest-pinned image instead of installed with pip, CodeQL runs on every push, and OpenSSF Scorecard grades the result
- This release carries its SBOM as an asset, with a Sigstore bundle beside it:
cosign verify-blob --bundle kronoterm2mqtt-v0.1.19.sbom.cdx.json.sigstore.json \
--certificate-identity-regexp '^https://github.com/.+/.github/workflows/publish-image.yml@.+' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
kronoterm2mqtt-v0.1.19.sbom.cdx.jsonNo change to how the service behaves: same Modbus handling, same MQTT entities, same health endpoint as 0.1.18.
0.1.18
First release published as a container image.
services:
kronoterm2mqtt:
image: hausbit/kronoterm2mqtt:0.1.18Built for linux/amd64 and linux/arm64, so a server and a Raspberry Pi take the same tag. 26 MB compressed.
What is in it
- Modbus resilience: retries with reconnect, tolerance for gateways that greet a new connection with their MAC address, and an undefined register value no longer takes the publish loop down
- a health endpoint on 127.0.0.1:8099 with
docker compose exec kronoterm2mqtt health, and a watchdog that ends the process after a long outage so the restart policy takes over - hardened image: Alpine, unprivileged UID 65532, all capabilities dropped, read-only root filesystem, no package managers, base pinned by digest
- Python 3.14 with every dependency at its current release
- an SBOM at
/usr/share/kronoterm2mqtt/sbom.cdx.json, registry SBOM and provenance attestations, and a keyless Sigstore signature - 139 tests, 83% coverage
Verify what you pulled
cosign verify hausbit/kronoterm2mqtt:0.1.18 \
--certificate-identity-regexp '^https://github.com/.+/.github/workflows/publish-image.yml@.+' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comSee security/README.md for what is and is not claimed.