# SolarEdge inverter + battery — `solaredge_modbus` setup guide

Tested against the SolarEdge SE10K-RWS three-phase inverter with
StorEdge battery interface, firmware 4.24.x. Should work on the
single-phase HD-Wave family and the three-phase RWS family. Modbus
TCP is the path; cloud-API is not used.

---

## Prerequisites

1. **A SolarEdge inverter with Modbus TCP enabled.** Most SE inverters
   support it but it's OFF by default. Enable via:
   - SetApp (modern installs): Site Communication → Modbus TCP → On,
     port 1502 (or your choice).
   - Older inverters with LCD: Communication → Server → LAN, then
     under Modbus TCP enable + set port.
2. **Wired or WiFi network connection** between your Otonomo box and
   the inverter. WiFi works but a wired link is more reliable.
   StorEdge battery readings update every ~5 s; a flaky link will
   show gaps.
3. **A known IP address** for the inverter. Reserve one via your
   router's DHCP table. The SolarEdge mobile app shows the IP under
   Site Communication.

---

## Verifying reachability

Before configuring the driver, confirm you can reach the inverter
over Modbus TCP from your Otonomo box:

```bash
# From your Otonomo box:
nc -vz <inverter-ip> 1502     # should say "open"
```

If that fails: inverter Modbus not enabled, wrong IP, or firewall.

---

## Configuring the driver

1. Open the local UI at `http://<box-ip>:8080/drivers`.
2. Find **solaredge_modbus** under "PV Inverter" and click **Install**.
3. Click **Add instance**:

   | Field | Value | Why |
   |-------|-------|-----|
   | Instance ID | `solaredge_modbus.pv` | Unique on this box |
   | `host` | `192.168.x.y` | Your inverter's IP (required) |
   | `port` | `1502` | SolarEdge default (NOT 502) |
   | `unit_id` | `1` | Always 1 for SolarEdge |
   | `timeout_s` | `3.0` | Inverter is slow on standby; 3 s is safe |

4. Click **Create instance**.

Within ~30 seconds:

- `pv.power_w` updates
- `battery.soc_pct` + `battery.power_w` if you have a StorEdge battery
- `grid.power_w` if you have the SE grid meter installed (Model 203)

---

## Verifying

`http://<box-ip>:8080/device/solar` — Solar Now + Solar Today cards.
`http://<box-ip>:8080/device/battery` — Battery SOC + Battery Power.
`http://<box-ip>:8080/device/grid` — Grid Power if meter present.

If only Solar shows up, the battery / grid meter aren't being polled —
check the inverter's "Device Manager" view in SetApp; battery + meter
appear there if SolarEdge sees them.

---

## Common pitfalls

### "DeviceUnreachable: ConnectionRefusedError"

Modbus TCP not enabled on the inverter, OR the inverter is in its
nightly self-test (~22:50 local for ~80 s — SolarEdge safety routine,
NOT a crash). If the error persists past midnight, SetApp the
inverter and re-toggle Modbus TCP.

### Battery showing wrong sign / direction

SolarEdge's Modbus reports battery power with a vendor-specific sign
convention: **negative when charging**, positive when discharging.
The Otonomo driver normalises this so positive = charging in our
canonical schema. If your dashboard shows opposite, you're hitting
a firmware variation — let us know via `support@otonomo.be` with
your inverter model + firmware version.

### Inverter on WiFi shows two IPs

Some SolarEdge inverters have BOTH ethernet AND WiFi active and listen
for Modbus on both. Either works — pick whichever is more reliable on
your network. Wired wins almost always.

### Grid power drifts vs per-phase sum

On firmware 4.24.22, the SunSpec Model 203 meter's `total_W` (offset
18) is the canonical grid reading. Per-phase sums (`WphA + WphB +
WphC`) drift by ~600 W at low power. The Otonomo driver uses the
total — don't try to derive it yourself.

### "AC clipping at 8 kW" but inverter is rated 10 kW

This is **expected** for SE inverters running into a backup-power
configuration with an upstream contactor. Status code 5
("THROTTLED") means the inverter is curtailing on the AC side, not a
DC limit. Nothing to do.

---

## What Otonomo will do with this driver

In **observe mode**:
- Polls PV power, battery SOC, battery power, grid power every ~10 s
- Visualizes on the dashboard, runs cloud orchestrators in shadow

In **active mode**, with `Battery dispatch` opt-in:
- Writes battery mode (StorCtl_Mod register) to schedule charging
  from grid during cheap hours
- Writes export limit to prevent injection during negative pricing
- Falls back to MaxSelfConsume on cloud-watchdog safe-mode

You can pause optimization at any time with the per-capability switch
in `/account/control`. The inverter resumes its prior internal
schedule within ~60 s of the cloud yielding control.

---

## Two-driver pattern (advanced)

For large fleets where the inverter is heavily polled, we use a
**split-driver pattern**: a read-only `solaredge_modbus` polling
instance + a separate `solaredge_modbus_write` actuator that opens a
Modbus connection only when writing. This avoids the SE firmware's
intolerance for two always-connected Modbus clients.

Most home installs don't need this. The single-driver setup above
works fine for one Otonomo box per inverter. If you see "ConnectionReset"
errors at high write frequency, ask `support@otonomo.be` about the
split pattern.

---

## References

- SolarEdge SunSpec Modbus implementation note:
  https://www.solaredge.com/sites/default/files/sunspec-implementation-technical-note.pdf
- SunSpec Information Models:
  https://sunspec.org/wp-content/uploads/2015/06/SunSpec-Information-Models-12041.pdf
- Otonomo driver source — `otonomo_drivers/drivers/solaredge_modbus/`

Otonomo's `solaredge_modbus` is an independent interoperability tool.
Not affiliated with SolarEdge Technologies.
