Skip to content

Releases: Zendure/Zendure-HA

Release 1.4.4 🌞

Choose a tag to compare

@FireSon FireSon released this 12 Aug 19:31

Release 1.4.4 🌞

Rolls back the 1.4.3 limit-write change that turned out to cause a regression, fixes a few device and startup issues, and adds the first Python test coverage to CI.

🩹 The 1.4.3 regression

  • Revert "Send the full command on limit writes" (#1507, reverted in 6fc073d): routing output_limit / input_limit entity writes through the manager's power routines made every external write carry smartMode, acMode and a forced zero on the opposite limit. For anyone driving those entities from their own automations that alternated smartMode 0/1 on every command and parked the device in standby (#1521, reported by @mania-x, @Anzlinger, @rdeklerk04-source and @lexe). Limit writes are a plain single-property write again, as they were from 1.1.0 through 1.4.2.

    Consequence: the change that was meant to address #1505 (a device at 100% SoC ignoring valid limit writes) is out with it. That one was never confirmed fixed, and the recovery its reporter measured was a different sequence: set the limit to 0, wait for the device to start moving on its own, then set it back.

🩹 Fixes

  • Manager mode select and ACE 1500 failing to load by @igosoft in #1527: guards an unusable property key, and a restored select value that is no longer in the option list now falls back instead of sticking.
  • SF4000 Mix AC+ internal battery misidentified by @Rolf-Smit in #1529: packType 70 is the 8 kWh internal pack, which shares its serial prefix with the 0.96 kWh AB1000S.
  • Do not report an unreachable zenSDK device as online (46fc9ad): a failed local poll returned an empty payload that was still applied, which pushed the device's last-seen forward and kept it online.
  • Halve the zenSDK HTTP timeout to 2s (aa6e93b): the local read runs per device sequentially inside the control loop, so an unreachable device stalled it for the full timeout.

βš™οΈ Devices and configuration

  • 4000 W and 5000 W fuse groups for the Mix series by @Rolf-Smit in #1556
  • Refresh zenSDK devices on every cycle by @2tefan in #1542: previously the local read happened only once at startup.

πŸ§ͺ Testing

  • A pytest test environment by @krenk80 in #1540: first Python test coverage in CI, 14 scenario tests across device, number and manager, running on every push and pull request.

πŸ“– Documentation

  • Troubleshooting for the Mosquitto protocol error by @Kieft-C in #1524

πŸ”§ Build and dependencies

  • ruff 0.15.21 to 0.16.1 (#1573), colorlog 6.10.1 to 6.12.0 (#1553), bleak-retry-connector to >=4.6.3 (#1552), pip to >=26.2.1 (#1585), actions/stale 10 to 11 (#1572)

Full Changelog: 1.4.3...1.4.4

Pre-release 1.4.4-pre1 🌞

Pre-release

Choose a tag to compare

@FireSon FireSon released this 11 Aug 11:38

Pre-release 1.4.4-pre1 🌞

A pre-release for testing. The headline is a rollback of the 1.4.3 limit-write change that turned out to cause a regression, plus a first pytest environment.

🩹 The 1.4.3 regression

  • Revert "Send the full command on limit writes" (#1507, reverted in 6fc073d): routing output_limit / input_limit entity writes through the manager's power routines made every external write carry smartMode, acMode and a forced zero on the opposite limit. For anyone driving those entities from their own automations that alternated smartMode 0/1 on every command and parked the device in standby (#1521, reported by @mania-x, @Anzlinger, @rdeklerk04-source and @lexe). Limit writes are a plain single-property write again, as they were from 1.1.0 through 1.4.2.

    Consequence: the change that was meant to address #1505 (a device at 100% SoC ignoring valid limit writes) is out with it. That one was never confirmed fixed, and the recovery its reporter measured was a different sequence: set the limit to 0, wait for the device to start moving on its own, then set it back.

🩹 Fixes

  • Manager mode select and ACE 1500 failing to load by @igosoft in #1527: guards an unusable property key, and a restored select value that is no longer in the option list now falls back instead of sticking.
  • SF4000 Mix AC+ internal battery misidentified by @Rolf-Smit in #1529: packType 70 is the 8 kWh internal pack, which shares its serial prefix with the 0.96 kWh AB1000S.
  • Do not report an unreachable zenSDK device as online (46fc9ad): a failed local poll returned an empty payload that was still applied, which pushed the device's last-seen forward and kept it online.
  • Halve the zenSDK HTTP timeout to 2s (aa6e93b): the local read runs per device sequentially inside the control loop, so an unreachable device stalled it for the full timeout.

βš™οΈ Devices and configuration

  • 4000 W and 5000 W fuse groups for the Mix series by @Rolf-Smit in #1556
  • Refresh zenSDK devices on every cycle by @2tefan in #1542: previously the local read happened only once at startup.

πŸ§ͺ Testing

  • A pytest test environment by @krenk80 in #1540: first Python test coverage in CI, 14 scenario tests across device, number and manager, running on every push and pull request.

πŸ“– Documentation

  • Troubleshooting for the Mosquitto protocol error by @Kieft-C in #1524

πŸ”§ Build and dependencies

  • ruff 0.15.21 to 0.16.1 (#1573), colorlog 6.10.1 to 6.12.0 (#1553), bleak-retry-connector to >=4.6.3 (#1552), pip to >=26.2.1 (#1585), actions/stale 10 to 11 (#1572)

Full Changelog: 1.4.3...1.4.4-pre1

Release 1.4.3 🌞

Choose a tag to compare

@FireSon FireSon released this 18 Jul 10:29

Release 1.4.3 🌞

Small fixes on top of 1.4.2 β€” a regression fix, two guards against a real control-loss incident, and a solar pass-through improvement.

🩹 Fixes

  • Fix Zero-Export / SOCFULL bypass with gridReverse "disabled" by @zaubara in #1512 β€” a regression from the 1.4.0 gridReverse rework: "disabled" (0) was treated as export-allowed, so a full battery could no longer follow the requested output. Only "allow" now enables the bypass accounting; "disabled" and "forbidden" both mean no export.
  • Feed all available solar at SOCFULL instead of stalling by @zaubara in #1511 β€” a SOCFULL device no longer gets stuck at ~50W; it now passes through the real available solar (bounded by demand and the discharge limit), so a full battery's panels aren't wasted.

πŸ›‘οΈ Control-loss guards (issue #1505)

A SolarFlow 2400 Pro was observed reporting a narrowed limit (inverseMaxPower=800) for hours and, at 100% SoC, silently ignoring commands β€” leaving the battery stuck while the house drew from the grid. Two independent guards:

  • Clamp number writes instead of failing by @marcokrenkel-collab in #1506 β€” when a device narrows an entity's range at runtime, a number.set_value above the narrowed max is now clamped (with a warning) instead of being rejected by Home Assistant and discarded. Control degrades gracefully rather than being lost.
  • Send the full command on limit writes by @marcokrenkel-collab in #1507 β€” external output_limit / input_limit writes now go through the same full command (smartMode/acMode) as the manager's own control, so they aren't silently ignored when the device has dropped out of smart mode.

βš™οΈ Manager

  • Pass through available solar in MATCHING_DISCHARGE by @igosoft in #1408 β€” smart-discharge now passes all available solar to the house and uses the battery only to cover remaining demand (never draining for export). Folds the "solar pass-through" use case into the existing mode, so no separate mode is needed.

πŸ”§ Build / dependencies

  • Bump ruff from 0.15.20 to 0.15.21 (#1509)

Full Changelog: 1.4.2...1.4.3

Release 1.4.2 🌞

Choose a tag to compare

@FireSon FireSon released this 06 Jul 15:38
29140b9

Release 1.4.2 🌞

Point release that completes the fix for the 1.4.0 SolarFlow AC+ upgrade regression. If you own a SolarFlow 2400 AC+, 1600 AC+ or 4000 AC+ and upgraded from 1.3.x, this is the release you want.

🚨 Completes the SolarFlow AC+ upgrade fix (#1477, #1475)

1.4.1 fixed the duplicate _2 entities, but some users found their device still showed as offline after upgrading: the Zendure Manager reported "No devices online", Global SOC stayed at 0%, and lifetime energy counters had reset.

Root cause (full trace by @qpaz in #1477): the 1.4.0 + β†’ _plus rename changed every affected entity's entity_id, and Home Assistant keys restore state by entity_id. So on upgrade the device-level settings lost their saved values and fell back to defaults:

  • connection β†’ cloud (if you were on local, the device never came online)
  • fuse group β†’ unused (the manager then excluded the device from control)
  • lifetime energy counters β†’ reset to 0

The integration already contained a migration that renames entities correctly and moves their restore state, but a stale version gate meant it never ran for 1.3.x installs. This release reactivates it (config-entry minor version bump 7 β†’ 8). On the first restart after upgrading:

  • entity ids and unique ids are migrated together (no _2 duplicates)
  • connection, fuse group and other settings keep their values
  • aggr_* lifetime counters keep their totals
  • recorder history and long-term statistics are carried over
  • references in your YAML (automations, dashboards) are rewritten automatically

No manual cleanup needed. If you already worked around this by hand (e.g. set fuse_group back to your group), your setup keeps working.

Big thanks to @qpaz for the detailed root-cause analysis and for testing the fix, and to @Bashbob and @fipiblitz for confirming the workaround that pointed at the cause.

Upgrade note

Take a Home Assistant backup before upgrading (good practice for any release that migrates the entity registry). The migration runs once and is idempotent.

Full Changelog: 1.4.1...1.4.2

Release 1.4.1 🌞

Choose a tag to compare

@FireSon FireSon released this 05 Jul 14:39
e278cce

Release 1.4.1 🌞

Point release on top of 1.4.0 that fixes a regression affecting every existing SolarFlow AC+ user (and any other device whose Zendure-app name contains a +).

🚨 Fix for the 1.4.0 SF2400AC+ / SF1600AC+ / SF4000AC+ regression

Users of SolarFlow AC+ devices upgrading from a pre-1.4.0 install reported that after the upgrade their entities split in two on the same device: the canonical number.solarflow_2400_ac_plus_output_limit became Unavailable while a duplicate ..._output_limit_2 variant carried the live value (#1477). The Zendure Manager consequently reported "No devices online" and manual output-limit changes never reached the device.

Root cause: the + β†’ _plus snakecase change in 1.4.0 made these devices produce entities under new unique_ids. check_entities() renamed the old registry rows to the new canonical entity_id but did not update their unique_id, so when the integration created the live entities with the new unique_id, HA had to append _2 (the canonical slot was squatted by an orphan).

The fix rewrites check_entities() to migrate entity_id AND unique_id in one operation, and to prefer the entry that already carries the correct unique_id when both an orphan and a _2 entity exist. On the first restart after upgrading to 1.4.1:

  • Unavailable orphan entities disappear.
  • _2 duplicates are renamed back to the canonical entity_id.
  • The live entity re-attaches to the same registry row, so recorder history is preserved on the row we kept.

No manual cleanup is needed. If you had already worked around it (renamed entities by hand, deleted orphans), that also continues to work.

🩹 Other fixes in this point release

  • No more "Detected blocking call to read_text" warning (#1474, #1435 by @zoic21) β€” the integration's one-time translation-map load now runs off the event loop, so Home Assistant no longer logs a blocking-call warning on every startup.
  • Clearer setup error messages (#1480) β€” a failed setup used to show only "invalid input". The config flow now tells you what actually went wrong: a malformed token, a network problem, an API rejection (with Zendure's own message), a valid token on an account/region with no devices, or a missing MQTT server. This directly helps the "invalid input" reports (#1310, #1263, #1390) where the real cause was a wrong account or region rather than the integration.
  • Device matching ignores spaces β€” device model names are now matched ignoring spacing, so variants like SolarFlow 800 Pro 2 vs SolarFlow 800 Pro2 resolve to the same device class.

πŸ†• New device support (from 1.4.0)

  • SolarFlow 4000 AC+ support added.
  • ACE 1500 controllable without a Hub by @ahocevar in #1338 β€” new hubMode toggle (paired / standalone). Paired mode is the default and byte-identical to previous behaviour. Standalone mode is opt-in for users without a Hub 1200/2000: the integration parks the device in autoModel=0 and drives charging directly via inputLimit writes, with 50 W quantization and a 30 s throttle to protect device flash memory.

⚠️ Notes for users

  • SF2400AC and SF2400AC+ in the same setup: this release resolves the unique_id collision that silently dropped the second device's entities when both kept their Zendure-default names.
  • Multi-device setups with SOCFULL bypass: PR #1422 fixes a regression where one SOCFULL device trickling a few watts to home caused an actively-charging sibling to cycle between 0 W and full power every ~60 s. If you experienced this pattern, please confirm it is resolved.
  • ACE 1500 owners: your ACE 1500 will gain a hubMode select entity, defaulting to paired (existing behaviour). If you run without a Hub, flip it to standalone to enable direct charge control.

🩹 Critical fixes (from 1.4.0)

  • Cap discharge_bypass per device by @zoic21 in #1422 β€” fixes the charge cycling regression of the #1151 fix.
  • SF2400AC+ no-start fix (kickstart walk introduced in 192bf64, charge-side completed by @zoic21 in #1434) β€” when the device fails to latch on the first start command, the integration walks the input/output limit by 4 W per tick (capped at 2 Γ— POWER_START) until the device starts drawing power. Replaces the random-jitter approach proposed in #1363.
  • Keep AC relay in input mode when smart_charging has no surplus by @zoic21 in #1427 β€” eliminates AC relay flap between input and output on every positive P1 fluctuation while charging.
  • Substitute + with _plus in snakecase (c603722) β€” prevents unique_id collision between SF2400AC and SF2400AC+ devices.
  • Fix p1 matching when SOCFULL and grid reverse disabled by @zaubara in #1296
  • Hub and ACE fixes by @harrymayr in #1287 β€” removes AC charge capability from HUB family (which doesn't support it), adds UPS pack_state for ACE 1500.
  • Register battery entities immediately on first packData by @devTechi in #1392 β€” batteries appearing on first HTTP-failed poll are no longer invisible until the next 60-second cycle.
  • Entity registry self-healing (eec95df) β€” stale entries with the wrong domain or none-typed entries are now cleaned up automatically on integration startup, no manual migration needed.

✨ New sensors (from 1.4.0)

  • Global SOC, battery voltage delta, round-trip efficiency by @zoic21 in #1426
    • global_soc on the Zendure Manager: weighted SOC across all online devices.
    • delta_voltage per battery: max cell voltage minus min cell voltage. A sustained value above ~0.15 V over an extended period may indicate cell imbalance.
    • roundtrip_efficiency per device: lifetime aggrDischarge / aggrCharge Γ— 100.

πŸ› οΈ Other fixes and improvements (from 1.4.0)

🌐 Translations (from 1.4.0)

πŸ”§ Build / dependencies

  • Bump ruff from 0.15.12 to 0.15.13 (#1384)
  • Bump ruff from 0.15.13 to 0.15.14 (#1401)
  • Bump ruff from 0.15.14 to 0.15.20 (#1462)
  • Update bleak-retry-connector requirement (#1400)
  • Bump actions/checkout from 6 to 7 (#1448)
  • Update pip requirement to >=26.1.1 (#1367)
  • Update pip requirement to >=26.1.2 (#1409)

πŸ‘‹ New contributors (since 1.3.1)

Full Changelog: 1.4.0...1.4.1

Release 1.4.0 🌞

Choose a tag to compare

@FireSon FireSon released this 03 Jul 17:36
b9e8e89

Release 1.4.0 🌞

New device support for SolarFlow 4000 AC+ and standalone ACE 1500 (without a Hub), three new sensors (global SOC, battery voltage delta, round-trip efficiency), and a batch of bug fixes accumulated since 1.3.1. Promoted from 1.4.0-pre1 after a 3-day bake with an added ACE 1500 standalone path.

πŸ†• New device support

  • SolarFlow 4000 AC+ support added.
  • ACE 1500 controllable without a Hub by @ahocevar in #1338 β€” new hubMode toggle (paired / standalone). Paired mode is the default and byte-identical to previous behaviour. Standalone mode is opt-in for users without a Hub 1200/2000: the integration parks the device in autoModel=0 and drives charging directly via inputLimit writes, with 50 W quantization and a 30 s throttle to protect device flash memory.

⚠️ Notes for users

  • SF2400AC and SF2400AC+ in the same setup: this release resolves the unique_id collision that silently dropped the second device's entities when both kept their Zendure-default names. Existing entities for the SF2400AC+ will be replaced with new ones using a ..._plus_... slug after upgrade; the previous entries stay in the registry with their history intact but stop updating. You can safely delete the orphaned old entities from the entity registry.
  • Multi-device setups with SOCFULL bypass: PR #1422 fixes a regression where one SOCFULL device trickling a few watts to home caused an actively-charging sibling to cycle between 0 W and full power every ~60 s. If you experienced this pattern, please confirm it is resolved.
  • ACE 1500 owners: your ACE 1500 will gain a hubMode select entity, defaulting to paired (existing behaviour). If you run without a Hub, flip it to standalone to enable direct charge control.

🩹 Critical fixes

  • Cap discharge_bypass per device by @zoic21 in #1422 β€” fixes the charge cycling regression of the #1151 fix.
  • SF2400AC+ no-start fix (kickstart walk introduced in 192bf64, charge-side completed by @zoic21 in #1434) β€” when the device fails to latch on the first start command, the integration walks the input/output limit by 4 W per tick (capped at 2 Γ— POWER_START) until the device starts drawing power. Replaces the random-jitter approach proposed in #1363.
  • Keep AC relay in input mode when smart_charging has no surplus by @zoic21 in #1427 β€” eliminates AC relay flap between input and output on every positive P1 fluctuation while charging.
  • Substitute + with _plus in snakecase (c603722) β€” prevents unique_id collision between SF2400AC and SF2400AC+ devices.
  • Fix p1 matching when SOCFULL and grid reverse disabled by @zaubara in #1296
  • Hub and ACE fixes by @harrymayr in #1287 β€” removes AC charge capability from HUB family (which doesn't support it), adds UPS pack_state for ACE 1500.
  • Register battery entities immediately on first packData by @devTechi in #1392 β€” batteries appearing on first HTTP-failed poll are no longer invisible until the next 60-second cycle.
  • Entity registry self-healing (eec95df) β€” stale entries with the wrong domain or none-typed entries are now cleaned up automatically on integration startup, no manual migration needed.

✨ New sensors

  • Global SOC, battery voltage delta, round-trip efficiency by @zoic21 in #1426
    • global_soc on the Zendure Manager: weighted SOC across all online devices.
    • delta_voltage per battery: max cell voltage minus min cell voltage. A sustained value above ~0.15 V over an extended period may indicate cell imbalance.
    • roundtrip_efficiency per device: lifetime aggrDischarge / aggrCharge Γ— 100.

πŸ› οΈ Other fixes and improvements

🌐 Translations

πŸ”§ Build / dependencies

  • Bump ruff from 0.15.12 to 0.15.13 (#1384)
  • Bump ruff from 0.15.13 to 0.15.14 (#1401)
  • Bump ruff from 0.15.14 to 0.15.20 (#1462)
  • Update bleak-retry-connector requirement (#1400)
  • Bump actions/checkout from 6 to 7 (#1448)
  • Update pip requirement to >=26.1.1 (#1367)
  • Update pip requirement to >=26.1.2 (#1409)

πŸ‘‹ New contributors

Full Changelog: 1.3.1...1.4.0

Pre-release 1.4.0-pre1 🌞

Pre-release

Choose a tag to compare

@FireSon FireSon released this 30 Jun 00:02

Pre-release 1.4.0-pre1 🌞

New device support for the SolarFlow 4000 AC+, three new sensors (global SOC, battery voltage delta, round-trip efficiency), and a batch of bug fixes accumulated since 1.3.1. Please test before the stable 1.4.0 tag goes out.

πŸ†• New device

  • SolarFlow 4000 AC+ support added.

⚠️ Notes for users

  • SF2400AC and SF2400AC+ in the same setup: this release resolves the unique_id collision that silently dropped the second device's entities when both kept their Zendure-default names. Existing entities for the SF2400AC+ will be replaced with new ones using a ..._plus_... slug after upgrade; the previous entries stay in the registry with their history intact but stop updating. You can safely delete the orphaned old entities from the entity registry.
  • Multi-device setups with SOCFULL bypass: PR #1422 fixes a regression where one SOCFULL device trickling a few watts to home caused an actively-charging sibling to cycle between 0 W and full power every ~60 s. If you experienced this pattern, please confirm it is resolved.

🩹 Critical fixes

  • Cap discharge_bypass per device by @zoic21 in #1422 β€” fixes the charge cycling regression of the #1151 fix.
  • SF2400AC+ no-start fix (kickstart walk introduced in 192bf64, charge-side completed by @zoic21 in #1434) β€” when the device fails to latch on the first start command, the integration walks the input/output limit by 4 W per tick (capped at 2 Γ— POWER_START) until the device starts drawing power. Replaces the random-jitter approach proposed in #1363.
  • Keep AC relay in input mode when smart_charging has no surplus by @zoic21 in #1427 β€” eliminates AC relay flap between input and output on every positive P1 fluctuation while charging.
  • Substitute + with _plus in snakecase (c603722) β€” prevents unique_id collision between SF2400AC and SF2400AC+ devices.
  • Fix p1 matching when SOCFULL and grid reverse disabled by @zaubara in #1296
  • Hub and ACE fixes by @harrymayr in #1287 β€” removes AC charge capability from HUB family (which doesn't support it), adds UPS pack_state for ACE 1500.
  • Register battery entities immediately on first packData by @devTechi in #1392 β€” batteries appearing on first HTTP-failed poll are no longer invisible until the next 60-second cycle.
  • Entity registry self-healing (eec95df) β€” stale entries with the wrong domain or none-typed entries are now cleaned up automatically on integration startup, no manual migration needed.

✨ New sensors

  • Global SOC, battery voltage delta, round-trip efficiency by @zoic21 in #1426
    • global_soc on the Zendure Manager: weighted SOC across all online devices.
    • delta_voltage per battery: max cell voltage minus min cell voltage. A sustained value above ~0.15 V over an extended period may indicate cell imbalance.
    • roundtrip_efficiency per device: lifetime aggrDischarge / aggrCharge Γ— 100.

πŸ› οΈ Other fixes and improvements

🌐 Translations

πŸ”§ Build / dependencies

  • Bump ruff from 0.15.12 to 0.15.13 (#1384)
  • Bump ruff from 0.15.13 to 0.15.14 (#1401)
  • Bump ruff from 0.15.14 to 0.15.20 (#1462)
  • Update bleak-retry-connector requirement (#1400)
  • Bump actions/checkout from 6 to 7 (#1448)
  • Update pip requirement (#1367)

πŸ‘‹ New contributors

Full Changelog: 1.3.1...1.4.0-pre1

New Devices, many fixes, updated migrations and more... 🌞

Choose a tag to compare

@FireSon FireSon released this 28 Apr 10:49
5a95a88

Patch release 1.3.1

Fixed some startup bugs. Increased POWER_START to 60

Fixes

  • Correct error 'ZendureNumber' object has no attribute 'asInt' by @zoic21 in #1298
  • Correct power start value for solarflow 2400 AC+ by @zoic21 in #1297
  • Fix total_kwh state_class and silence empty-sentinel warning by @LukasQ in #1300

Release 1.3.0

What's Changed

New Contributors

Full Changelog: 1.3.0...1.3.1

New Devices, many fixes, updated migrations and more... 🌞

Choose a tag to compare

@FireSon FireSon released this 27 Apr 22:18
10d6368

version 1.3.0

What's Changed

New Contributors

Full Changelog: https://github.com/Zendure/Zendure-HA/compare/1.2.5..1.3.0

READ before you install πŸš€πŸŒž ⚠️

Choose a tag to compare

@FireSon FireSon released this 30 Mar 00:59
8c39ce0

Patch version 1.2.7-pre4

🌞 ⚠️ Important change! We reverted the change of all the entity names!!
Actually we improved it, so all entities will be correct in automations, dashboards etc. Tested it extensively with backups, untill all worked well. Please still make a backup anyway before installing it. πŸš€ Since many other changes were added, it would be great to get feedback on all items. If all is OK, the new 1.2.7 can be released πŸ˜„

What's Changed in 1.2.7-pre4

  • Device ID migration, custom snakecase by @FireSon in #1237
  • Fix division by zero in power_charge and power_discharge by @fellek in #1221
  • Solves Error from #1209 by @fellek in #1210
  • feat: add support for new solarflow series's internal batteries by @thib3113 in #1226
  • security: opt-in MQTT user management and enforced local_only access by @thib3113 in #1228
  • Fix: off-grid consumer power causes incorrect zero-feed-in setpoint #1015 by @fellek in #1208

New Contributors

Full Changelog: 1.2.7-pre3...1.2.7-pre4