Skip to content

Guide

Monitor a Solplanet battery locally in Home Assistant, with fault emails you can trust

Published · Updated

My home battery is a Solplanet system. Its Ai-Dongle, the inverter’s network module, answers on the local network, and a Home Assistant integration reads it every 60 seconds, with no cloud account in the path.

A drawing: the sun shines on a solar panel that charges a home battery, next to an envelope with a green tick

Getting the numbers in is easy. Trusting them is harder. The dongle reports the inverter as waiting while it’s producing 2.8 kW, drops off the network for minutes at a time, and locks everyone out if it’s asked too often. My first fault email sent 27 false alarms in 10 days. Here’s the setup and the automation I ended up with.

Diagram: solar panels feed a Fronius solar inverter. A Solplanet hybrid inverter with a 35 kWh battery sits on the same switchboard as the grid and the home loads. Two Eastron meters, one on the Fronius and one on the grid, report to the Solplanet inverter. Its Ai-Dongle talks to Home Assistant on a Raspberry Pi 5 over Wi-Fi and HTTPS, polled every 60 seconds, read-only, with no cloud.

Power on the left, data on the right. This guide is about the dongle-to-Home Assistant link.

Part Model
Hybrid inverter Solplanet ASW10kH-T3, 10 kW
Battery Solplanet AP-H series, 35 kWh (7 modules)
Solar inverter Fronius Primo 5.0-1, with 6.6 kW of panels
Meters 2× Eastron SEM3: one on the Fronius output, one on the grid
Dongle Solplanet Ai-Dongle, on Wi-Fi

The system is AC-coupled. The panels feed the Fronius, which has its own built-in Home Assistant integration. The Solplanet inverter charges and discharges the battery on the AC side, and its two meters tell it what the Fronius makes and what goes to and from the grid.

You need Home Assistant with HACS, and the dongle on your network.

Search HACS for “Solplanet”. Two integrations show up: the original by zbigniewmotyka, and calvinbui’s fork, which focuses on the newer “v2” dongle firmware. I use the fork, v1.1.0. Restart Home Assistant, then add it in Settings → Devices & services with the dongle’s IP address. Leave the update interval at 60 seconds (step 2 says why).

Mine speaks v2 over HTTPS on port 443. The integration finds that by itself.

The Ai-Dongle has a rate limit. Ask it too often and it rejects every request, Home Assistant’s included, for a while. Home Assistant already polls it every 60 seconds, so a script of yours on top is how you’d trip it.

Diagram: Home Assistant polls the Ai-Dongle every 60 seconds, one request at a time, and keeps the results in its database and log. You read history and raw replies from Home Assistant, not from the dongle. Direct requests only with Home Assistant’s polling paused, one at a time, well apart.

Read from Home Assistant, not from the dongle.

Everything is already in Home Assistant: the history of every entity, and, at debug level, every raw reply from the dongle. Turn that on without a restart, in Developer tools → Actions:

action: logger.set_level
data:
custom_components.solplanet: debug

The replies show up in Settings → System → Logs, base64-encoded (b'eyJ...'). Decode one with echo 'eyJ...' | base64 -d | jq ., then set the level back to warning.

Step 3: Turn on the dongle’s Wi-Fi signal sensor

Section titled “Step 3: Turn on the dongle’s Wi-Fi signal sensor”

The dongle device has a WiFi signal strength sensor, disabled by default. Enable it on the dongle’s device page. It costs no extra requests: the integration fetches that value anyway, once an hour.

Mine reads -66 dBm, which is borderline (about -67 dBm is the usual limit for a reliable link). When the dongle drops out, its history shows whether Wi-Fi is to blame.

Create an automation, switch to YAML (⋮ → Edit in YAML), and paste this. Replace the entity IDs with yours: the integration names them after your devices, so the inverter’s start with its model, asw10kh_t3_, and notify.email is your notifier.

alias: Solplanet battery/inverter fault email
description: >-
Email me when the Solplanet inverter or battery reports a fault that lasts
5 min. Separate email when the dongle is unreachable for 1 h.
triggers:
- trigger: state
id: fault
entity_id:
- sensor.battery_errors
- sensor.battery_warnings
- sensor.inverter_error_code
- sensor.inverter_status
- sensor.battery_communication_status
not_to:
- unavailable
- unknown
for: "00:05:00"
- trigger: state
id: unreachable
entity_id:
- sensor.inverter_status
- sensor.battery_communication_status
to: unavailable
for: "01:00:00"
actions:
- choose:
- conditions:
- condition: trigger
id: unreachable
sequence:
- action: smtp.send_message
target:
entity_id: notify.email
data:
title: Solplanet dongle unreachable for 1 h
message: >-
Home Assistant can't read the Solplanet Ai-Dongle. This means
no data, not a fault: the inverter and battery most likely keep
running. Check the dongle's Wi-Fi signal, or reboot it.
default:
- if:
- condition: not
conditions:
- condition: and
conditions:
- condition: state
entity_id: sensor.battery_errors
state: [No errors, unavailable, unknown]
- condition: state
entity_id: sensor.battery_warnings
state: [No warnings, unavailable, unknown]
- condition: state
entity_id: sensor.inverter_error_code
state: [No error, unavailable, unknown]
- condition: state
entity_id: sensor.inverter_status
state: [Normal, unavailable, unknown]
- condition: state
entity_id: sensor.battery_communication_status
state: [Normal, unavailable, unknown]
then:
- action: smtp.send_message
target:
entity_id: notify.email
data:
title: Solplanet fault
message: >-
Inverter: {{ states('sensor.inverter_status') }},
{{ states('sensor.inverter_error_code') }}.
Battery: {{ states('sensor.battery_errors') }},
{{ states('sensor.battery_warnings') }}, comms
{{ states('sensor.battery_communication_status') }},
{{ states('sensor.battery_state_of_charge') }}%.
mode: single
max_exceeded: silent

smtp.send_message needs Home Assistant 2026.8 or newer. With another notifier, use notify.send_message with the same target and data.

Flow chart: the “fault” trigger fires when one of the 5 entities changes to a real state and stays 5 minutes. The check then asks whether everything is OK, counting unavailable or unknown as OK. All OK: no email. Something isn’t: a “Solplanet fault” email. The “unreachable” trigger fires when the inverter status or battery communication is unavailable for an hour, and sends a separate “dongle unreachable” email.

Two triggers, one check. A change back to Normal fires “fault” too; the check is what stops those emails.

The first version emailed on any change to a bad state. In 10 days it sent 27 emails saying the inverter had gone from Normal to Wait. Each time, the dongle reported Wait for a single 60-second poll, and the next poll was Normal again. A real Wait means no output, but the inverter was producing 2,779 W during one of them. None of the 27 was real.

A row of 60-second polls: Normal, Normal, Normal, Wait, Normal and so on. Without a delay, the single Wait at 10 on 28 September, with 2,779 W of output, sends an email straight away. With for: 5 minutes, Wait would have to last 5 minutes; it’s Normal again after one poll, so nothing is sent.

One poll of Wait, while the inverter produced 2.8 kW.

Fix: for: "00:05:00", so a bad state has to last 5 minutes. The trade-off: a real fault that clears within 5 minutes no longer emails.

On 12 October I got 11 fault emails in one afternoon. None was a fault. Home Assistant lost contact with the dongle from 14:15 to 21:51, and the entities kept flipping to unavailable for 1 to 10 minutes at a time.

Five minutes wasn’t enough because of the integration’s back-off. After 3 failed polls in a row, it only tries again every 10 minutes, so the entities stay unavailable for at least 10 minutes, and a 5-minute trigger fires every time.

Timeline: three polls fail, up to 30 seconds each. After the third, the next poll is 10 minutes away. The entity is unavailable for those 10 minutes, so a 5-minute trigger used to send a fault email. Now unavailable is ignored, and only an hour of it sends a “dongle unreachable” email.

Three failures, then a 10-minute wait: long enough to beat a 5-minute trigger.

Fix: the fault trigger ignores changes to unavailable and unknown (not_to), and the check counts them as OK. A dongle that stays silent is a different problem, so the unreachable trigger sends one separate email after an hour. The longest gap that day was 38 minutes.

The system itself kept working the whole time:

Bar chart of battery power by hour on 12 October 2026: charging in the morning, up to 8.6 kW at noon, then discharging at about 4 kW from 17 to 21. The afternoon gap is marked: 14 to 21, Home Assistant kept losing the dongle.

Battery power on 12 October, from Home Assistant’s history. Only the data link was down.

I haven’t found the cause yet. The dongle answered pings slowly the next day (64 ms on average, against 1 to 5 ms for the Wi-Fi access points), so its Wi-Fi link is my suspect. The automation doesn’t need to know.

Change history

  • : First published.

This guide as plain Markdown, for LLMs and scripts: solplanet-battery-home-assistant-local.md. All posts: API and Markdown.

Text, photos and drawings: CC BY 4.0. Code: MIT. Share and adapt them, crediting HomeLab Guides (blog.jacq.cc). Licence and privacy