Bug description
A GoodWe GW8KN-ET with WiFi/LAN dongle can get stuck after the forty-two-watts controller is power-cycled/rebooted without a clean TCP close.
The driver enters a rapid modbus reconnected loop. TCP connects to port 502 succeed, but Modbus frames receive no response until the GoodWe dongle/inverter is physically power-cycled.
Reported environment
- Device: GoodWe GW8KN-ET
- Connectivity: GoodWe WiFi/LAN dongle
- Protocol: Modbus TCP on port 502
- Reporter: Discord user frekes
Suspected cause
The dongle appears to allow only one Modbus TCP client/session. If the controller disappears without sending FIN (power loss / hard reboot), the dongle may hold the old socket as established for a long time. A new TCP handshake succeeds, but the Modbus application layer may still be bound to the ghost socket and ignore the new client's frames.
Current go/internal/modbus/client.go uses simonvetter/modbus, which dials TCP via net.DialTimeout and does not expose TCP keepalive configuration. The 42W wrapper reconnects on transport errors, but that does not help if the dongle accepts the TCP connection while ignoring Modbus frames.
Proposed fix
Enable TCP keepalive on Modbus TCP sockets, ideally with a short period (for example 15-30s) so ghost sockets clear within roughly a minute after controller power loss.
Implementation may require one of:
- upstream change/fork/wrapper in
simonvetter/modbus to set keepalive on the TCP conn before newTCPTransport, or
- replacing the TCP transport path with a 42W-owned dialer/transport that uses
net.Dialer{KeepAlive: ...} / (*net.TCPConn).SetKeepAlivePeriod(...).
Workaround
Physically power-cycle the GoodWe dongle/inverter after a controller hard reboot if it gets stuck in this state.
Acceptance criteria
- Modbus TCP client sockets have TCP keepalive enabled with a configurable or documented short period.
- Reconnection after controller hard reboot recovers without requiring GoodWe dongle power cycle.
- Add regression coverage where practical for the dialer/socket setup.
Bug description
A GoodWe GW8KN-ET with WiFi/LAN dongle can get stuck after the forty-two-watts controller is power-cycled/rebooted without a clean TCP close.
The driver enters a rapid
modbus reconnectedloop. TCP connects to port 502 succeed, but Modbus frames receive no response until the GoodWe dongle/inverter is physically power-cycled.Reported environment
Suspected cause
The dongle appears to allow only one Modbus TCP client/session. If the controller disappears without sending FIN (power loss / hard reboot), the dongle may hold the old socket as established for a long time. A new TCP handshake succeeds, but the Modbus application layer may still be bound to the ghost socket and ignore the new client's frames.
Current
go/internal/modbus/client.gousessimonvetter/modbus, which dials TCP vianet.DialTimeoutand does not expose TCP keepalive configuration. The 42W wrapper reconnects on transport errors, but that does not help if the dongle accepts the TCP connection while ignoring Modbus frames.Proposed fix
Enable TCP keepalive on Modbus TCP sockets, ideally with a short period (for example 15-30s) so ghost sockets clear within roughly a minute after controller power loss.
Implementation may require one of:
simonvetter/modbusto set keepalive on the TCP conn beforenewTCPTransport, ornet.Dialer{KeepAlive: ...}/(*net.TCPConn).SetKeepAlivePeriod(...).Workaround
Physically power-cycle the GoodWe dongle/inverter after a controller hard reboot if it gets stuck in this state.
Acceptance criteria