feat(foxess_h3_smart): Fox ESS 1K5 / H3-Smart register map driver - #69
Conversation
The existing foxess driver speaks the H1/H3 11000-range map; a 1K5 answers none of it, silently. New read-only driver for the H3-Smart map (1K5-HI series, H3-Smart family), register map from nathanmarlor/foxess_modbus, telemetry validated on 1K5-HI-10-V1 hardware. Harness gains host.set_model and host.decode_string, both in the host profile but missing from the mock. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Leitet <johan@sourceful-labs.com>
|
Automated maintenance pass: not merging this one — real, reproducible build failure, not a flake. What's good: the driver itself reads carefully. Sign conversion matches the site convention (PV negative, battery positive-on-charge via the vendor's negative-charging flip, meter positive-on-import), every register read goes through the bounded Why CI is red: the
Two ways to fix it, either is fine:
Everything else about this PR looks ready to merge once that's resolved. Generated by Claude Code |
miravoss26
left a comment
There was a problem hiding this comment.
The driver reads well. Register map documented against nathanmarlor/foxess_modbus and validated on 1K5-HI-10-V1, signs normalised to site convention (pv negative, battery/meter flipped from the vendor's), the BMS block read single-register as its hardware demands, and the give-up-after-3 guard is a good call given this device answers an unknown register with silence rather than a Modbus exception. Read-only, driver_default_mode commands nothing. Correctness-wise I'd take it.
CI is the blocker: the packages job is red (the other five — drivers, signed-channel, public-boundary, dco, secret-scan — pass). It dies in the blixt-l1 candidate build with Lua source must declare DRIVER_MANIFEST. The last candidate the log printed before the failure was esphome-dsmr@1.0.2 for ftw-core, and the build is fail-fast, so I can't tell from the log alone which source tripped it. The new foxess_h3_smart.lua declares DRIVER = {...}, not DRIVER_MANIFEST — worth checking whether the blixt-l1 target wants that symbol on the new driver, or whether this is a pre-existing esphome-dsmr/blixt-l1 break the PR just inherits (the diff doesn't touch esphome-dsmr).
Needs a human on that packages failure before it lands. Not in my auto-merge allowlist regardless, so treat this as a flag, not a block.
The package declares both targets, and blixt-l1 requires a DRIVER_MANIFEST table and, for a read-only package, a refusing driver_command. Both follow sdm630, the one existing dual-target precedent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Leitet <johan@sourceful-labs.com>
|
Fixed — thanks for the exact repro, it made this quick. The scaffolder generates a dual-target
Verified with your command: Generated with Claude Code |
miravoss26
left a comment
There was a problem hiding this comment.
New read-only Modbus driver for the Fox ESS H3-Smart / 1K5 register map, kept separate from the existing foxess driver because a 1K5 answers none of the H1/H3 map (and it replies to unknown registers with silence rather than an exception, so a wrong map fails slow instead of loud). Hardware-validated: the 1K5-HI-10-V1 capture is replayed in tests and the site-convention sign flips are asserted per stream.
Correctness. Register windows all stay in range: status 39063..39141, power 39219..39238, energy 39601..39618, pv 39279..39286, ct 38814..38815, and every i32/u32 pair lands on the documented address. Trailing all-zero PV strings are dropped, which the test pins (2 mppts, pv.W = -(3121+3475)). The single-register BMS reads for SoC and battery temp match what the block will actually answer, and give-up-after-3 is the right call for a device that pays a full timeout on a silent read.
Security. Read-only end to end: driver_command refuses every actuation, permissions is modbus.read only, control is []. No secrets, no new network destinations, no new deps. secret-scan and signed-channel checks are green.
One thing to confirm, not a blocker: the driver now calls host.decode_string and host.set_model. The changelog says both already live in the host profile and min_host_version is 1.5.0, so this is likely fine, but a missing host fn would only bite at runtime, so worth a glance that blixt-l1 exposes them at its declared min too.
Safe to merge from my read: CI green, mergeable, no unresolved threads. Not on my auto-merge allowlist, so I'll leave the merge to you.
Closes #68.
New read-only driver
foxess_h3_smart0.1.0 for Fox ESS inverters on the H3-Smart register map: the 1K5-HI three-phase hybrid series and the H3-Smart family that shares the map. The existingfoxessdriver (H1/H3 11000-range map) gets only silence from this hardware — it answers unknown registers with a timeout, not a Modbus exception.Device and evidence
Inv.H3_SMARTprofile (their issue #807 covers the 1K5 family). Recorded in the manifest'supstream_docs.Tests
drivers/tests/test_foxess_h3_smart.pyreplays the hardware capture through the Lua harness and holds emitted signs and scales to the site convention, plus block-failure, SoC-omission and identity-retry behavior. The harness gainedhost.set_modelandhost.decode_string— both in the host profile, neither in the mock until a driver called them.make checkpasses (3563 tests);ftw_repository.py check-versionsagainst the published beta manifest answersadded: [foxess_h3_smart], changed: [].🤖 Generated with Claude Code