Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Rutger Wessels
Rutger Wessels

Posted on

     

Storing SMA Inverter Data In InfluxDB

December 2018, the kitchen table. My wife and I decided to have solar panels installed on our roof. For my wife, it was a way of saving money and CO2. For me, it was a opportuntiy to start a new data side project: collecting metrics from the inverter.

Original implementation

Not all inverter brands have the option of reading data locally. The worst case scenario: no local access, the only way to retrieve data is using the online portal maintained by the manufacturer. SMA inverters seemd to be open enough so I decided to order a SMA Sunny Boy. It had a local web interface and, after enabling using Installer account, can also expose data using Modbus.

I first spent some hours trying to use a Modbus implementation and get some data out of the inverter myself. Luckily, I found a working python script on aGerman forum. I adapted it so it would write to InfluxDB. I also started posting metrics to a MQTT server and from there, I stored 15-minute interval data in a PostgreSQL database.

However, after some time, I ended up with a pile of scripts that read data from some device and then saved it to InfluxDB. This became difficult to maintain and there was duplicated functionality (handling network errors, system reboots and such).

So I found out about Telegraf and started to move away from custom scripts and settled on Telegraf doing the metrics collection and sending it to MQTT and InfluxDB. At some point, all of my hacky scripts had been replaced by Telegraf. Except the metrics from SMA Modbus: they were still retrieved using the custom script.

Using Telegraf to read SMA Sunny Boy Modbus

Telegrafsupports Modbus. But Modbus is not trivial. You need to know about registers, data types and byte ordering. So after a lot of trial and error and Googling, I came up with this solution. It works for my inverter, which is a SB3.0-1AV-41 902 running on firmware 4.0.55.R.

[[inputs.modbus]]  name = "sma"  # Host address of the inverter  controller = "tcp://192.168.178.171:502"  configuration_type = "request"  timeout = "1s"  [[inputs.modbus.request]]    slave_id = 3    byte_order = "ABCD"    register = "holding"    measurement = "sma"    fields = [      { address=30513, name="wh_out_total",     type="UINT64", scale =   1.0 },      { address=30517, name="wh_out_today",     type="UINT64", scale =   1.0 },      { address=30783, name="phase_1_out_volt", type="UINT32", scale=   0.01 },      { address=30775, name="out_watt",         type="INT32",  scale =   1.0 },      { address=30769, name="string_a_amp",     type="INT32",  scale = 0.001 },      { address=30771, name="string_a_volt",    type="INT32",  scale =  0.01 },      { address=30773, name="string_a_watt",    type="INT32",  scale =   1.0 },      { address=30957, name="string_b_amp",     type="INT32",  scale = 0.001 },      { address=30959, name="string_b_volt",    type="INT32",  scale =  0.01 },      { address=30961, name="string_b_watt",    type="INT32",  scale =   1.0 },      { address=30953, name="inverter_temp",    type="INT32",  scale =   0.1 },    ][[processors.starlark]]  namepass = ["sma"]  source = '''def apply(metric):  if metric.fields['out_watt'] < 0 or metric.fields['phase_1_out_volt'] > 12000:    return None  return metric'''
Enter fullscreen modeExit fullscreen mode

The address numbers can be found in theModbus Documentation provided by SMA. I am only interested in a few but there are many more.

This results in a InfluxDB measurement calledsma and metrics from the specified registers. And now the metrics are coming in:

time                host    inverter_temp name out_watt phase_1_out_volt   slave_id string_a_amp       string_a_volt string_a_watt string_b_amp       string_b_volt      string_b_watt type             wh_out_today wh_out_total----                ----    ------------- ---- -------- ----------------   -------- ------------       ------------- ------------- ------------       -------------      ------------- ----             ------------ ------------1698579340000000000 server1 30.6          sma  835      225.66             3        3.355              201.3         675           1.345              170.55             229           holding_register 1635         105566101698579350000000000 server1 30.6          sma  805      225.33             3        3.283              197.51        648           1.34               166.72             223           holding_register 1638         105566121698579360000000000 server1 30.6          sma  712      225.27             3        2.833              205.09        581           1.167              174.29             203           holding_register 1640         105566141698579370000000000 server1 30.6          sma  480      223.78             3        1.823              208.75        380           0.975              174.23             169           holding_register 1642         105566161698579380000000000 server1 30.6          sma  328      221.49             3        1.217              205.34        249           0.877              166.97             146           holding_register 1643         105566171698579390000000000 server1 30.6          sma  318      220.92000000000002 3        1.188              201.87        239           0.862              170.48             146           holding_register 1644         10556618
Enter fullscreen modeExit fullscreen mode

The 'starlark' section is an hack: the inverter enters a sleep mode, after sunset. And in that case, it return the maximum values (or minimum for signed ints) that are possible:

time                host    inverter_temp name out_watt    phase_1_out_volt slave_id string_a_amp string_a_volt string_a_watt string_b_amp string_b_volt string_b_watt type             wh_out_today wh_out_total----                ----    ------------- ---- --------    ---------------- -------- ------------ ------------- ------------- ------------ ------------- ------------- ----             ------------ ------------1697052610000000000 server1 -214748364.8  sma  -2147483648 42949672.95      3        -2147483.648 -21474836.48  -2147483648   -2147483.648 -21474836.48  -214748364.8  holding_register 2393         10507239
Enter fullscreen modeExit fullscreen mode

Before the numbers are sent to InfluxDB, this little function will check if the values are valid and if not, return None, which will not be saved in InfluxDB. So we don't store metrics in case the inverter is in standby.

End result

This is how my metrics setup looks:

Image description

  • The smart meter is read using aYouless and Telegraf will talk to the Youless
  • The SMA is read directly by Telegraf using Modbus
  • A few Zigbee devices are exposed using Zigbee2MQTT which is read by Telegraf

So everthing is going through Telegraf, which turns out to be a stable and reliable solution

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Solving problems.
  • Location
    Assen, the Netherlands
  • Joined

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp