@@ -17,8 +17,8 @@ The **`TIMEOUT`** option (default **3** seconds) is the deadline for:
1717- opening the link (connect), and
1818- each individual register read or write attempt.
1919
20- Each FC03 group is always attempted ** ` RETRY_ATTEMPTS ` (3) ** times , so a missing reply can take up
21- to ** 9 ** seconds ( ` TIMEOUT ` × 3) before that group fails.
20+ Each FC03 group is attempted ** ` READ_ATTEMPTS ` ** times (default ** 3 ** ) , so a missing reply can take
21+ up to ** ` TIMEOUT × READ_ATTEMPTS ` ** seconds before that group fails.
2222
2323It is ** not** a cap on an entire sensor batch or poll cycle. ` Sunsynk.read_sensors() ` may issue many
2424FC03 groups in one call; each group gets its own deadline.
@@ -50,10 +50,10 @@ all `for_unit()` handles on that port). **0** disables the gap.
5050
5151Library callers that omit ` message_spacing ` still get ` DEFAULT_MESSAGE_SPACING ` (0.05). On
5252** timeout** , ` Sunsynk.read_holding_registers() ` logs, increments ** ` timeouts ` ** , and retries up to
53- ** ` RETRY_ATTEMPTS ` (3) ** before raising ** ` ExceptionGroup ` ** . ** Serial ** links also call
54- ` ModbusConnection.disconnect() ` (not ` close() ` ) so the next FC03 reconnects with an empty receive
55- buffer. TCP, UDP, and Solarman do not flush on timeout. Other read errors still flush. tmodbus
56- already disconnects on desync (bad function code / header mismatch).
53+ ** ` read_attempts ` ** (add-on ** ` READ_ATTEMPTS ` ** , default ** 3 ** ) before raising ** ` ExceptionGroup ` ** .
54+ ** Serial ** links also call ` ModbusConnection.disconnect() ` (not ` close() ` ) so the next FC03
55+ reconnects with an empty receive buffer. TCP, UDP, and Solarman do not flush on timeout. Other read
56+ errors still flush. tmodbus already disconnects on desync (bad function code / header mismatch).
5757
5858---
5959
@@ -125,7 +125,7 @@ between commands on slow devices) and is the main pacing mitigation for #672 on
125125``` text
126126AInverter.read_sensors()
127127 → Sunsynk.read_sensors() # groups sensors, one FC03 per group
128- → Sunsynk.read_holding_registers() # RETRY_ATTEMPTS , then ExceptionGroup
128+ → Sunsynk.read_holding_registers() # read_attempts , then ExceptionGroup
129129 → unit.read_holding_registers()
130130 → modbus-connection TmodbusUnit # connect + Pacer (50ms) + tmodbus RTU
131131```
@@ -199,10 +199,10 @@ Solarman does **not** use modbus-connection or tmodbus. It uses
199199
200200- ** ` TIMEOUT ` ** maps to ** ` socket_timeout ` ** on the Solarman client (connect and reads).
201201- FC03 retries live on ** ` Sunsynk.read_holding_registers ` ** (shared with serial/TCP): up to
202- ** ` RETRY_ATTEMPTS ` (5) ** , then ** ` ExceptionGroup ` ** . No sleep between tries.
202+ ** ` read_attempts ` ** (default ** 3 ** ) , then ** ` ExceptionGroup ` ** . No sleep between tries.
203203- ** ` TimeoutError ` ** / ** ` GatewayTargetError ` ** : log, increment ** ` timeouts ` ** , disconnect/flush,
204204 retry.
205- - Other read errors: same loop; log includes ` (retry n/5) ` .
205+ - Other read errors: same loop; log includes ` [attempt n/READ_ATTEMPTS] ` .
206206- ** ` SolarmanUnit ` ** is a single attempt and ** disconnects** on error so the next retry reconnects.
207207
208208There is ** no** ` message_spacing ` knob on Solarman; pacing is whatever the dongle and
@@ -232,7 +232,7 @@ No shared `ModbusConnection`; one Solarman client per inverter port entry.
232232| Library | modbus-connection + tmodbus | PySolarmanV5Async |
233233| Add-on ` TIMEOUT ` | Per connect / FC03 / FC16 attempt | ` socket_timeout ` |
234234| Default gap after each reply | ** ` READ_MESSAGE_SPACING ` ** (default ** 0.05s** ) | — |
235- | Driver retry on ` TimeoutError ` | Yes (` RETRY_ATTEMPTS ` , then ` ExceptionGroup ` ) | Yes (same, on ` Sunsynk ` ) |
235+ | Driver retry on ` TimeoutError ` | Yes (` read_attempts ` , then ` ExceptionGroup ` ) | Yes (same, on ` Sunsynk ` ) |
236236| Add-on batch retry | Yes (` read_sensors_retry ` ) | Yes (same) |
237237| Multi-inverter same PORT | One connection, ` for_unit(MODBUS_ID) ` | Not supported (one dongle per entry) |
238238
@@ -243,7 +243,8 @@ User-facing keys from [multi-options](../www/docs/reference/multi-options.md) (a
243243
244244| Option | Role |
245245| ------------------------------- | --------------------------------------------------------------------------------------------- |
246- | ` TIMEOUT ` | Per-attempt deadline in ** seconds** (default ** 3** ); each FC03 read is tried ** 3** times |
246+ | ` TIMEOUT ` | Per-attempt deadline in ** seconds** (default ** 3** ) |
247+ | ` READ_ATTEMPTS ` | Tries per FC03/FC16 group (default ** 3** , max ** 5** ); worst case ` TIMEOUT × READ_ATTEMPTS ` |
247248| ` READ_MESSAGE_SPACING ` | Seconds to wait after each successful Modbus reply (default ** 0.05** ; ** 0** disables) |
248249| ` READ_SENSORS_BATCH_SIZE ` | Max registers per FC03 group (smaller → more requests, less time per request) |
249250| ` READ_ALLOW_GAP ` | Extra registers allowed between addresses so groups merge (fewer requests) |
0 commit comments