Summary
Since 0.313.0, an external Modbus TCP client connecting through evcc's modbusproxy gets write: i/o timeout errors when the upstream Modbus device is slow to answer specific register groups (e.g. Huawei Smart Power Sensor via SUN2000). The proxy handles the request, but by the time the response is ready to be written back to the client, an internal timeout has fired and the client's connection is torn down.
Setting an explicit timeout: 60s on the modbusproxy entry eliminates the errors immediately — same value that the huawei-sun2000 meter template already uses internally. Without it, the proxy uses a default that is too aggressive for this backend since #31996.
Environment
- evcc 0.313.2 (Home Assistant Add-on,
49686a9f_evcc, but the proxy code path is generic)
- Upstream: Huawei SUN2000-8KTL-M1 + Luna2000 battery + DDSU666-H Smart Power Sensor over Modbus TCP
- External client through the proxy: Home Assistant
wlcrs/huawei_solar v2.1.1 (this integration migrated to a new Modbus library — tModbus — in its own 2.0 release, which likely surfaces the regression here because its client-side read timing is tighter than the previous pyModbus-based client)
Symptom
evcc itself reads everything correctly (its own meters all have timeout: 60s):
[site ] DEBUG 2026/08/10 13:09:29 pv 1 power: 5716W
[site ] DEBUG 2026/08/10 13:09:29 battery 1 soc: 100%
[site ] DEBUG 2026/08/10 13:09:29 battery 1 power: -0W
[site ] DEBUG 2026/08/10 13:09:28 grid power: -5269W
But every 60–90s, the proxy logs a failed write to the HA client:
[proxy-5200] DEBUG 2026/08/10 13:35:08 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:33:13 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:32:31 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:31:18 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
Downstream in HA, the huawei_solar power-meter coordinator ends up with all sensor.stromzahler_*_wirkleistung entities in unavailable, while the inverter and battery coordinators continue to work (they poll the fast register groups). This looked at first glance like a device-side failure, but the FusionSolar app and evcc itself see the meter fine — only the traffic through the proxy fails.
Steps to reproduce
- Run evcc 0.313.x with a
modbusproxy entry pointing at a Huawei SUN2000 (or any Modbus TCP backend that has a slower register group like a downstream power meter over RS485).
- Connect an external Modbus TCP client (e.g. HA
huawei_solar v2.x) to the proxy port.
- Watch the evcc log — after a few minutes,
[proxy-5200] failed to write response: write tcp ...: i/o timeout errors start appearing, and the external client's coordinator for the slower register groups goes stale/unavailable.
Configuration details (redacted)
meters:
- type: template
template: huawei-sun2000
id: 1
host: 192.168.178.194
port: 502
usage: pv
modbus: tcpip
timeout: 60s
name: pv2
- name: my_battery
type: template
template: huawei-sun2000
usage: battery
id: 1
host: 192.168.178.194
port: 502
modbus: tcpip
timeout: 60s
# ...
- name: my_grid
type: template
template: huawei-sun2000
usage: grid
id: 1
host: 192.168.178.194
port: 502
modbus: tcpip
timeout: 60s
# BEFORE FIX — no timeout, uses default, causes `write: i/o timeout`
modbusproxy:
- port: 5200
uri: 192.168.178.194:502
# AFTER FIX — explicit timeout matches the meters, no more errors
modbusproxy:
- port: 5200
uri: 192.168.178.194:502
timeout: 60s
Log details
Before the workaround (excerpt from docker logs/HA supervisor logs, filtered on proxy):
[proxy-5200] DEBUG 2026/08/10 13:39:30 modbus proxy for 192.168.178.194:502 listening at :5200
[proxy-5200] DEBUG 2026/08/10 13:35:08 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:33:13 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:32:31 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:31:18 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:23:06 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:15:59 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:14:46 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:11:31 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:09:27 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
[proxy-5200] DEBUG 2026/08/10 13:08:16 failed to write response: write tcp 192.168.178.189:5200->192.168.178.189:51646: i/o timeout
After adding timeout: 60s and restarting evcc — no more i/o timeout entries; the external client's coordinators recover on the next poll cycle and stay stable.
Root cause hypothesis
PR #31996 (0.313.0, "Modbus: unify delay and timeout settings") migrated server/modbus/proxy.go's StartProxy(port, config modbus.Settings, ...) to the new unified Settings.Connection(ctx) path. That path is fine for consumers that pass an explicit Timeout in their config, but a modbusproxy entry without a timeout key ends up with the zero-value Duration, which downstream translates into a much tighter default than the pre-0.313 pyModbus behavior. For a backend like a Huawei-attached Smart Power Sensor (which is measurably slower than the inverter's own registers), that default is too aggressive.
Notably, the meter templates for huawei-sun2000-inverter / -hybrid gained timeout: 15s device-level defaults in the same PR; the proxy path did not get an analogous default.
Suggested fix
Two independent options — either one would prevent the silent regression:
- Sensible default timeout for
modbusproxy entries. A single default (say, 10–15s — same magnitude as the huawei-sun2000 template default) would cover all normal upstream latencies. Users who need more can still override, but nobody's proxy silently breaks after an upgrade.
- Document the
timeout (and delay) options for modbusproxy explicitly in the docs / config UI. Currently the modbusproxy config docs don't mention them, so there's no discoverable path from the symptom to the fix — I only found timeout by reading the changed source.
Ideally both. Happy to test a fix on my setup.
Additional context
- On this setup, the Huawei power meter is a downstream RS485 slave behind the SUN2000 (Modbus register block accessed via the inverter's own Modbus TCP port 502). It is measurably slower to answer than the inverter's local register bank, which is why the proxy timeout hits only that data path and not the inverter/battery coordinators of the same client.
- Rolling back the evcc add-on to a specific old version through the HA Supervisor was not possible for this add-on (the store only carries the latest tag), so identifying the version-related regression required reading the release notes; the config-side workaround is a much better path anyway.
Summary
Since 0.313.0, an external Modbus TCP client connecting through evcc's
modbusproxygetswrite: i/o timeouterrors when the upstream Modbus device is slow to answer specific register groups (e.g. Huawei Smart Power Sensor via SUN2000). The proxy handles the request, but by the time the response is ready to be written back to the client, an internal timeout has fired and the client's connection is torn down.Setting an explicit
timeout: 60son themodbusproxyentry eliminates the errors immediately — same value that thehuawei-sun2000meter template already uses internally. Without it, the proxy uses a default that is too aggressive for this backend since #31996.Environment
49686a9f_evcc, but the proxy code path is generic)wlcrs/huawei_solarv2.1.1 (this integration migrated to a new Modbus library — tModbus — in its own 2.0 release, which likely surfaces the regression here because its client-side read timing is tighter than the previous pyModbus-based client)Symptom
evcc itself reads everything correctly (its own
metersall havetimeout: 60s):But every 60–90s, the proxy logs a failed write to the HA client:
Downstream in HA, the
huawei_solarpower-meter coordinator ends up with allsensor.stromzahler_*_wirkleistungentities inunavailable, while the inverter and battery coordinators continue to work (they poll the fast register groups). This looked at first glance like a device-side failure, but the FusionSolar app and evcc itself see the meter fine — only the traffic through the proxy fails.Steps to reproduce
modbusproxyentry pointing at a Huawei SUN2000 (or any Modbus TCP backend that has a slower register group like a downstream power meter over RS485).huawei_solarv2.x) to the proxy port.[proxy-5200] failed to write response: write tcp ...: i/o timeouterrors start appearing, and the external client's coordinator for the slower register groups goes stale/unavailable.Configuration details (redacted)
Log details
Before the workaround (excerpt from
docker logs/HA supervisor logs, filtered onproxy):After adding
timeout: 60sand restarting evcc — no morei/o timeoutentries; the external client's coordinators recover on the next poll cycle and stay stable.Root cause hypothesis
PR #31996 (0.313.0, "Modbus: unify delay and timeout settings") migrated
server/modbus/proxy.go'sStartProxy(port, config modbus.Settings, ...)to the new unifiedSettings.Connection(ctx)path. That path is fine for consumers that pass an explicitTimeoutin their config, but amodbusproxyentry without atimeoutkey ends up with the zero-value Duration, which downstream translates into a much tighter default than the pre-0.313 pyModbus behavior. For a backend like a Huawei-attached Smart Power Sensor (which is measurably slower than the inverter's own registers), that default is too aggressive.Notably, the meter templates for
huawei-sun2000-inverter/-hybridgainedtimeout: 15sdevice-level defaults in the same PR; the proxy path did not get an analogous default.Suggested fix
Two independent options — either one would prevent the silent regression:
modbusproxyentries. A single default (say, 10–15s — same magnitude as the huawei-sun2000 template default) would cover all normal upstream latencies. Users who need more can still override, but nobody's proxy silently breaks after an upgrade.timeout(anddelay) options formodbusproxyexplicitly in the docs / config UI. Currently the modbusproxy config docs don't mention them, so there's no discoverable path from the symptom to the fix — I only foundtimeoutby reading the changed source.Ideally both. Happy to test a fix on my setup.
Additional context