Files
solaredge_modbus_mqtt/README.md
T
dj7nt b168e2da43 Replace MQTT output with direct InfluxDB writes
Polls now cover meter 1, battery 1 and storage control blocks,
plus inverter event registers for off-grid detection (vendor
event bit 0). Register layout validated by probing a
SE10K-RWB48BFN4 with fw 0004.0025.0011; battery and storage
floats are word-swapped on this device.

Failed Influx writes spool to disk and replay on the next
success (Influx reached over WAN). Modbus blocks that fail to
read are skipped for that cycle; the flaky gateway must not
kill the daemon. Battery lifetime counters at 0xE176/0xE17A
hang the device and are never read.

BREAKING CHANGE: config.yaml 'mqtt:' section replaced by
'influx:', Home Assistant discovery removed.
2026-10-10 15:42:48 +02:00

2.8 KiB

Usage

Installation

The easiest way this is to run the docker container and set it to restart always. This basically makes it a system service that will always run.

To make it safe and avoid passing credentials we're using a configuration file.

mkdir /etc/solaredge_modbus_mqtt
chmod 700 /etc/solaredge_modbus_mqtt
cp config.yaml-dist /etc/solaredge_modbus_mqtt/config.yaml
docker run --detach --name=solaredge_modbus_mqtt --restart=always --volume=/etc/solaredge_modbus_mqtt/config.yaml:/app/config.yaml marijnkoesen/solaredge_modbus_mqtt:latest

Configuration

modbus:
    host: 192.168.178.28     # inverter (SunSpec over Modbus TCP)
    port: 1502
    timeout: 1
    unit: 1

influx:
    url: http://influx.example.com:8086
    db: solaredge
    user: ~                   # optional basic-auth user with WRITE on the db
    pass: ~
    measurement: solaredge

poll_interval: 3

The daemon polls the inverter and writes one line-protocol point per cycle directly to InfluxDB. If InfluxDB is unreachable, points are spooled to spool.txt and replayed on the next successful write (capped at 20000 lines). Mount a volume for /app/spool.txt if backlog across container restarts matters.

model and serialnumber are written as tags; everything else as fields.

Off-grid / fail-over

  • offgrid — boolean, true while the inverter runs islanded (off-grid) — vendor event bit
  • error_code — inverter vendor error bitmask (0 = none), LCD-style codes
  • storage_control_mode_text — e.g. Backup Only, Maximize Self Consumption
  • battery1_* — SOE/SOH, power, voltage, temperatures, status of battery 1

Register addresses were validated by probing a SE10K-RWB48BFN4 (fw 0004.0025.0011) with one battery and one meter. Blocks that fail to read (flaky gateway) are skipped for that cycle; the fields are simply absent from the point.

Uninstall

docker update --restart=no solaredge_modbus_mqtt
docker stop solaredge_modbus_mqtt

Update

docker update --restart=no solaredge_modbus_mqtt
docker stop solaredge_modbus_mqtt
docker rm solaredge_modbus_mqtt
docker run --detach --name=solaredge_modbus_mqtt --restart=always --volume=/etc/solaredge_modbus_mqtt/config.yaml:/app/config.yaml marijnkoesen/solaredge_modbus_mqtt:latest

For developers

Building and running the docker image

docker build -t solaredge_modbus_mqtt:latest .
or
docker buildx build --platform linux/amd64 solaredge_modbus_mqtt:latest .

cp config.yaml-dist config.yaml
docker run --volume=$PWD/config.yaml:/app/config.yaml solaredge_modbus_mqtt:latest

Running without docker

pip3 install -r requirements.txt
cp config.yaml-dist config.yaml
python3 solaredge_modbus_mqtt.py

Running tests

pip3 install -r requirements.txt
python3 -m unittest