FailureNetworks / FailureWatt™

Growatt bridge for Home Assistant power users.

FailureWatt™ is a local Growatt / Voltronic-style inverter bridge that exposes RS485 Modbus RTU through a Raspberry Pi TCP port for Home Assistant. No cloud, no vendor dongle magic, no MQTT requirement.

v0.3 public notes Modbus RTU → TCP Raspberry Pi Home Assistant No unrestricted fork

Architecture

FailureWatt™ is intentionally simple: one serial adapter, one bridge service, one Home Assistant Modbus TCP connection.

01Growatt inverter

RS485 / Modbus RTU from the inverter communication port.

02USB-RS485

Example: Exar XR21B1411 or another Linux-compatible adapter.

03Raspberry Pi

Runs systemd + socat and owns the serial port.

04TCP port 5020

Local Modbus RTU-over-TCP bridge endpoint.

05Home Assistant

Built-in Modbus integration polls the bridge.

Important: Do not use unrestricted fork with one RS485 serial adapter. It can leave many socat child processes in CLOSE-WAIT and lock the USB serial driver.

Install on Raspberry Pi / Debian

Install dependencies, find the stable serial path, create the systemd bridge, then enable it at boot.

1. Install packages

sudo apt update
sudo apt install -y socat usbutils lsof python3 python3-venv

2. Find USB-RS485 adapter

lsusb
ls -lah /dev/serial/by-id/

Use /dev/serial/by-id/..., not plain /dev/ttyUSB0, because tty numbers can change.

3. Create /etc/systemd/system/growatt-socat.service

[Unit]
Description=FailureWatt Growatt Modbus RTU->TCP bridge
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=60
StartLimitBurst=5

[Service]
Type=simple
Environment=DEVICE=/dev/serial/by-id/usb-YOUR_RS485_ADAPTER
Environment=BRIDGE_IP=192.168.1.20
Environment=BRIDGE_PORT=5020

ExecStart=/usr/bin/socat -d -d \
  TCP-LISTEN:${BRIDGE_PORT},bind=${BRIDGE_IP},reuseaddr \
  FILE:${DEVICE},raw,b9600,cs8,parenb=0,cstopb=0

Restart=always
RestartSec=10
TimeoutStopSec=5
KillMode=control-group
SuccessExitStatus=143

User=root
Group=dialout

[Install]
WantedBy=multi-user.target

4. Enable and start

sudo systemctl daemon-reload
sudo systemctl enable growatt-socat.service
sudo systemctl start growatt-socat.service
sudo systemctl status growatt-socat.service --no-pager -l

Home Assistant connection

Home Assistant needs the built-in Modbus integration. No MQTT broker is required for this bridge.

Integration

Use Home Assistant's built-in Modbus integration. In YAML this is the modbus: section.

Host

The host is the Raspberry Pi / bridge machine IP. Example: 192.168.1.20.

Port

The bridge listens on TCP port 5020 by default.

Minimal connectivity example

modbus:
  - name: failurewatt
    type: tcp
    host: 192.168.1.20
    port: 5020
    timeout: 5
    delay: 1
    message_wait_milliseconds: 200
    sensors:
      - name: "FailureWatt raw holding 0"
        slave: 1
        address: 0
        input_type: holding
        data_type: uint16
        scan_interval: 30

After editing YAML, use Developer Tools → YAML → Reload all YAML. If the old TCP session is stuck, reload may be required before data starts moving again.

Troubleshooting

The most useful checks are process count, TCP state, serial ownership, and USB driver health.

SymptomLikely causeCheck
Hundreds of socat processesUnrestricted fork with repeated HA connectionsps -ef | grep socat
Many CLOSE-WAIT connectionsDead TCP sessions not cleaning serial childrensudo ss -tnp | grep :5020
Input/output errorUSB-serial adapter or driver is stuckdmesg -T | grep xr_serial
No /dev/ttyUSB0Adapter missing, not probed, or driver not attachedlsusb and ls /dev/serial/by-id/
Bridge listening but no HA dataHA Modbus session staleReload all YAML in Home Assistant

Known bad pattern

# Avoid this for a single Modbus RTU serial adapter:
TCP-LISTEN:5020,bind=192.168.1.20,reuseaddr,fork

Better pattern

# One serial user. No child-process explosion:
TCP-LISTEN:5020,bind=192.168.1.20,reuseaddr

Recovery checklist

Use this when Home Assistant stops receiving inverter data.

sudo systemctl stop growatt-socat.service
sudo systemctl reset-failed growatt-socat.service
sudo pkill -TERM -f "socat.*5020" || true
sleep 3
sudo pkill -KILL -f "socat.*5020" || true

lsusb | grep -Ei "Exar|XR21|RS485|USB"
ls -lah /dev/ttyUSB* /dev/serial/by-id/ 2>/dev/null || true

sudo stty -F /dev/serial/by-id/usb-YOUR_RS485_ADAPTER 9600 raw -echo
echo $?

sudo systemctl start growatt-socat.service
sudo journalctl -u growatt-socat.service -f

If the USB adapter reports repeated -32, Failed to set reg, or Input/output error, physically unplug the USB-RS485 adapter for 10 seconds and plug it back in. Then start the service and reload YAML in Home Assistant.

Downloads

Public templates and diagnostic tools. The Python tools are for debugging and dumping registers; the live bridge is the systemd + socat service.