Home Assistant integration for SMA PV system
Earlier this year I’ve finally had a photovoltaic system installed in/on our house, and while three months later we still aren’t allowed to turn it on thanks to German bureaucracy, it does provide another playground for home automation integration. This should be easy, right? Our installation uses components from a major German supplier (SMA), there are HomeAssistant integrations for that.
Well.
Turns out that the inverter in our setup is of a new model line (SMA Tripower X), which isn’t supported by the official HomeAssistant integration. And while there exist individual data collection tools that can deal with this unit by scraping the parameter status information from it’s built-in web UI, and others that offer an architecture I liked, there was nothing out there combining the required device support, aesthetics and deployment options that I wanted.
Enter smahub
Combining the above situation with a long-standing desire to “do something with Python” and use all of this to check out the utility of LLMs as swiss-army-knifes of programming helpers, I decided to roll my own SMA data aggregator/forwarder. The result is smahub, which is a relatively straightforward combination of a central async-protected dictionary with a set of data source and data sink plugins.
Sources:
- demo: a minimal, hello-world style demo source plugin for anyone who wants to create their own
- SHM2: reads and decodes Sunny Home Manager 2.0 datagrams (see below)
- TripowerX: reads and decodes Tripower X inverter parameters via web-UI (see below)
Sinks:
- demo: a minimal, hello-world style demo source plugin for anyone who wants to create their own
- gen_ha_sensors: can be used to generate home assistant style sensor configuration blocks from smahub data
- ha_mqtt: MQTT publisher that utilizes home assistant MQTT sensor auto-discovery and -configuration features
- mqtt: MQTT publisher
Essentially, smahub will spawn any configured source plugins, and these will begin to collect or snoop data from SMA devices. Any data points collected by these plugins are published into the central dictionary, which in turn is feeding sink plugins that (regularly or on-change) publish these data points to external consumers, e.g. publish to a MQTT broker. For details, please look at the project README, plus the README files of the plugins that you are interested in. The code is open source and constructive criticism (aka pull requests) is welcome!
All of the actual SMA device data ingest was taken from existing projects - shout-out and kudos to:
- Sven (littleyoda) - Home-Assistant-Tripower-X-MQTT
- Wenger Florian (datenschuft) - SMA-EM
Currently, smahub supports a set of core plugins/SMA devices:
Tripower X inverters
These devices do offer a reduced modbus interface, which is not utilized by a smahub plugin at the moment as modbus data can be consumed by HomeAssistant directly.
Another way to extract live data from the inverter is via its web interface; this is how Sven did it in Home-Assistant-Tripower-X-MQTT, and that is the approach I adopted for the TripowerX source plugin. Essentially, the plugin logs into the inverter web interface and will then periodically get the live-data parameter page, extracting all data points contained there. This usually works nicely, and provides a wealth of operational data that is not accessible otherwise. However, it can happen that the inverter refuses the login after too many attempts (excessive testing sessions…), making this channel somewhat erratic.
Sunny Home Manager 2.0 electric meters
The other SMA device that is part of my setup is the Sunny Home Manager 2.0 (SHM2), which sits in the between the house mains and all connected consumers and suppliers in our house and measures how much electricity goes which way. SHM2 does not offer any interactive interface whatsoever, instead it periodically sends IP multicast messages (which miraculously also reach the SMA web portal to feed the manufacturer statistics and apps - anyone who knows why/how this works on network level, I’d be interested to learn) according to a SMA protocol called Speedwire. Luckily I did not have to get involved in the details of how to decode any of that, thanks to datenschufts SMA-EM project which has been there before. So I adopted Florians code into the smahub SHM2 plugin, which reads and decodes these periodic messages.
mqtt sink
The first data sink plugin I wrote was a very simple and straightforward MQTT publisher for the core smahub data dictionary. Essentially this either periodically and/or on-change writes datum/value pairs to MQTT topics, this can be complemented by a set of MQTT sensor configurations for HomeAssistant to make these items consumable there with decent names, unit definitions etc. - for more details on this, refer to the project and mqtt plugin docs, also including the gen_ha_sensors plugin if you want to auto-generate HomeAssistant config records yourself.
ha_mqtt sink
Becaus semi-manually creating and maintaining HomeAssistant sensor configurations for all the data points collected by smahub is quite a chore, this plugin uses another Python library (ha_mqtt_discoverable) that automatically publishes all information to MQTT that HomeAssistant needs to perform auto-discovery and -configuration of MQTT sensor data. This works beautifully and seamlessly, and is the preferred option for HomeAssistant publication. One caveat is that the ha_mqtt_discoverable library does not offer an option to use non-standard MQTT broker ports, so if you need that you have to take a look at the mqtt sink plugin.
Running smahub
Details on options and configuration can be found in the project README. In essence, smahub can be run both as a native Python application, and inside a docker container. Containers are also available on the GitHub Package registry, both for intel and arm architectures. Again, refer to the project README for pointers how to run and configure the containerized version - this is the recommended way to operate smahub.
HA integration
With the ha_mqtt sink plugin, integration of smahub data into HomeAssistant is trivial - configure and start smahub, and things magically appear in HA’s MQTT integration. The HA Energy dashboard essentially needs three values to be useful:
- Grid consumption: assign
Power Consumption Counter
- Return to grid: assign
Power Supply Counter
- Solar production: assign
Power
(sensor.power)
However! It does happen that the inverter rejects smahubs attempts to login and scrape the http parameter page, this happens in my case after excessive testing sessions where the device rejects further logins. This somewhat erratic behavior runs counter to my desire to have this part of my home data infrastructure be hassle-free and solid, which is why I decided on another way to get Tripower X data into HomeAssistant.
Modbus after all
This other way is to enable modbus on the inverter (via the device network configuration section), and directly snoop the modbus messages into HomeAssistant via the integrated modbus extension. The extension is included in HA by default, but does require manual sensor configuration via configuration.yaml
. I am including the modbus section below, this should only require putting in your device IP address to work:
modbus:
- name: SMA
type: tcp
host: <INVERTER IP>
port: 502
sensors:
- name: sma_power_ac_raw
state_class: measurement
unit_of_measurement: W
slave: 3
address: 30775
count: 2
data_type: uint32
scan_interval: 15
- name: sma_power_ac_l1_raw
unit_of_measurement: W
state_class: measurement
slave: 3
address: 30777
count: 2
data_type: int32
scan_interval: 15
- name: sma_power_ac_l2_raw
unit_of_measurement: W
state_class: measurement
slave: 3
count: 2
address: 30779
data_type: int32
scan_interval: 15
- name: sma_power_ac_l3_raw
unit_of_measurement: W
state_class: measurement
slave: 3
count: 2
address: 30781
data_type: int32
scan_interval: 15
- name: sma_power_total_production
unit_of_measurement: Wh
state_class: total_increasing
device_class: energy
slave: 3
address: 30513
scan_interval: 15
data_type: int64
- name: sma_status
slave: 3
address: 30201
scan_interval: 15
count: 2
data_type: int32
template:
- sensor:
- name: "sma_power_ac"
state: >-
unit_of_measurement: "W"
state_class: measurement
This configuration gives you a sensor called sma_power_total_production
, which can be used instead of sensor.Power (see above) for getting information about PV-generation. Either way, smahub or modbus - this should set you with a working HomeAssistant Energy dashboard.
Waymarks
- This would have been a very well-matched project for trialing Elixir, another todo on my list; however I wanted to painlessly reuse the SMA decoding code from the above mentioned projects, as well as offer a path of least resistance for anyone to complement and improve smahub in the future.
- I think some minor fixes still needed - more robustness for the http scraper in the smahub TripowerX plugin, maybe a unit dimension conversion here or there…