Skip to content

Commit 1203f78

Browse files
committed
Check failed writes
1 parent ead3be1 commit 1203f78

4 files changed

Lines changed: 34 additions & 15 deletions

File tree

‎hass-addon-sunsynk-edge/CHANGELOG.md‎

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22

33
<https://github.com/kellerza/sunsynk/commits/>
44

5-
## Release 1.3.0
5+
## Unreleased
6+
7+
All items below are changes since add-on **1.3.0**.
68

7-
All items below are changes since add-on **1.2.0**.
9+
- Failed Modbus writes no longer update the local register cache. #692
10+
- Fix AsyncCallback checks. #693
11+
12+
## Release 1.3.0
813

914
- Single-phase **Grid Trickle Feed power** number (register 206, −500…500 W).
1015
- mqtt-entity ≥ 1.2.5.
@@ -14,8 +19,6 @@ All items below are changes since add-on **1.2.0**.
1419

1520
## Release 1.2.0
1621

17-
All items below are changes since add-on **1.1.1** (stable release on GitHub `main`).
18-
1922
- tmodbus 0.6.0 - improved re-synchronization logic for RTU-streams that got out of sync.
2023
- Prefix **`PORT`** with **`pymodbus-`** to use the pymodbus Modbus backend (e.g.
2124
`pymodbus-tcp://host:502`, `pymodbus-/dev/ttyUSB0`). Default is tmodbus.
@@ -34,14 +37,10 @@ All items below are changes since add-on **1.1.1** (stable release on GitHub `ma
3437

3538
## Release 1.1.1
3639

37-
All items below are changes since add-on **1.1.0**.
38-
3940
- Removed leftover `DRIVER` option from the add-on schema.
4041

4142
## Release 1.1.0
4243

43-
All items below are changes since add-on **1.0.0**.
44-
4544
- **Breaking:** three-phase **Parallel Mode** select options are **Client** (was Master) and
4645
**Server** (was Slave). The inverter LCD may still say Master/Slave. Update automations that match
4746
the old strings.
@@ -74,8 +73,6 @@ All items below are changes since add-on **1.0.0**.
7473

7574
## Release 1.0.0
7675

77-
All items below are changes since add-on **0.10.1**.
78-
7976
### Major changes
8077

8178
The following are major changes, but should accept and convert older configuration:

‎src/ha_addon_sunsynk_multi/sensor_callback.py‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,13 @@ async def callback_sensor(now: int) -> None: # noqa: PLR0915 PLR0912
8989
if not isinstance(sensor, RWSensor):
9090
continue
9191
await asyncio.sleep(0.1)
92-
await ist.write_sensor(sensor, value)
93-
await asyncio.sleep(0.05)
94-
await ist.read_sensors(sensors=[sensor], msg=sensor.name)
95-
sensors_to_publish.add(ist.ss[sensor.id])
92+
try:
93+
await ist.write_sensor(sensor, value)
94+
await asyncio.sleep(0.05)
95+
await ist.read_sensors(sensors=[sensor], msg=sensor.name)
96+
sensors_to_publish.add(ist.ss[sensor.id])
97+
except Exception as err:
98+
_LOG.error("Failed to write %s=%s: %s", sensor.id, value, err)
9699

97100
# add all read items
98101
for sec, srun in ist.sched.read.items():

‎src/sunsynk/sunsynk.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ async def write_sensor(
181181
for idx, addr in enumerate(sensor.address):
182182
if idx:
183183
await asyncio.sleep(0.05)
184-
await self.write_register(address=addr, value=regs[idx])
184+
if not await self.write_register(address=addr, value=regs[idx]):
185+
raise OSError(f"Failed to write register {addr}")
185186
self.state.registers[addr] = regs[idx]
186187

187188
async def read_holding_registers(self, start: int, length: int) -> Sequence[int]:

‎src/tests/sunsynk/test_sunsynk.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,24 @@ async def test_ss_write_sensor(
7474
assert "outside" in caplog.text
7575

7676

77+
@patch("sunsynk.Sunsynk.write_register", new_callable=AsyncMock)
78+
async def test_ss_write_sensor_raises_on_failed_write(
79+
wreg: AsyncMock, state: InverterState
80+
) -> None:
81+
"""Failed write_register must not update the register cache (#692)."""
82+
ss = _ss()
83+
ss.state = state
84+
sen = NumberRWSensor((1,), "s1")
85+
state.track(sen)
86+
wreg.return_value = False
87+
88+
with pytest.raises(OSError, match="Failed to write register 1"):
89+
await ss.write_sensor(sen, 44)
90+
91+
assert state.registers == {}
92+
wreg.assert_awaited_once_with(address=1, value=44)
93+
94+
7795
@patch("sunsynk.Sunsynk.read_holding_registers")
7896
@patch("sunsynk.Sunsynk.write_register")
7997
async def test_ss_write_sensor_bm(

0 commit comments

Comments
 (0)