You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
v1.7.0 gave serial entries a shared connection and, with it, a connection held
open for the lifetime of the entry. That is right for TCP and wrong for serial: a
serial port is exclusive, so holding it denies it to everything else on the
machine.
A reporter with two SPF inverters went from working on v1.6.6 to one inverter
permanently offline, with pyserial reporting 'Could not exclusively lock port
/dev/ttyUSB3' on every poll. Before v1.7.0 the port was opened and closed per
poll, so two entries naming the same adapter differently alternated and mostly
worked; holding it turned that into a hard lockout for whichever lost the race.
end_poll() gives the port back after each poll for serial and leaves TCP alone.
Reopening costs ~2 ms against a poll that reads 98 registers. Entries that do
share a hub are still serialized by the lock.
Also: a failed serial open now explains itself instead of surfacing as a bare
'Failed to connect', and the docs cover choosing a stable path - CH340 adapters
(vendor 1a86) have no serial number, so by-id cannot distinguish two of them and
ttyUSBn numbering swaps on reboot, which is how two entries end up on one
adapter without anyone noticing.
Verified red without the fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/troubleshooting/rs485-gateways.md
+23Lines changed: 23 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -165,6 +165,29 @@ The integration handles this for you: every entry pointing at the same device pa
165
165
166
166
**Serial setups need v1.7.0 or later for this.** Before that, only TCP entries were coordinated — each serial entry opened its own client on the same adapter and paced only itself, which produced random read failures on *all* the inverters sharing that bus. If you have two entries on one adapter and see unexplained dropouts, this is the first thing to rule out.
167
167
168
+
### Two adapters: check they are actually two
169
+
170
+
The most common cheap USB-RS485 adapters use the **CH340** chip (USB vendor `1a86`), and CH340s ship **without a serial number**. That has two consequences if you own two of them:
171
+
172
+
- Their `/dev/serial/by-id/` names do not distinguish them — you may see one entry, or two that differ only by an index that can move.
173
+
- Their `/dev/ttyUSBn` numbers are assigned in enumeration order and **swap between reboots**.
174
+
175
+
So it is entirely possible to configure two entries that both point at the *same* adapter under different names, leaving the second adapter unused. The symptom is one entry working and the other failing with:
176
+
177
+
```
178
+
[Errno 11] Could not exclusively lock port /dev/ttyUSB3: Resource temporarily unavailable
179
+
```
180
+
181
+
A serial port can only be held by one owner. If you see that, run:
182
+
183
+
```bash
184
+
ls -l /dev/serial/by-id/ /dev/serial/by-path/
185
+
```
186
+
187
+
Both listings show what each name resolves to. If two entries land on the same `ttyUSBn`, that is the problem.
188
+
189
+
**For adapters without a serial number, prefer `/dev/serial/by-path/`.** It identifies the physical USB socket rather than the device, so it stays stable across reboots *and* distinguishes two identical adapters — which `by-id` cannot. Use `by-id` when the adapter does have a serial number (FTDI adapters usually do); it survives being moved to a different socket.
190
+
168
191
Two consequences worth knowing:
169
192
170
193
-**Polls queue, they do not overlap.** With several inverters the effective cycle is the sum of their polls. If a single poll takes 8 s, three inverters need an interval comfortably above 24 s.
0 commit comments