SMA Energy Meter in Home Assistant

I also have a sunny island 4.4 with speedwire card energy meter and sunny home manager. I believe that the last part, the home manager is the issue. It only seems to send data to SMA servers.
I dislike SMA’s current methods and will not be using them in the future.

I’ll add my question to this thread: I’ve got an SUNNY TRIPOWER 6.0 (https://www.sma.de/produkte/solar-wechselrichter/sunny-tripower-30-40-50-60.html) and am trying to get data into Homeassistant. This works half way though.
This is what the website of the inverter does display:


(Both DC inputs ([A] and [B]) are being used as you can see in the screenshot above)

I was able to find out the SMA sensor keys:

grafik

Using 6380_40251E00 will only return the first value (2.787W) to HomeAssistant. How can we retrieve the second one, too (730W)?
Thanks!

Could not start session, Session ID expected [result.sid], got {‘result’: {‘sid’: None}}

I get this error, anyone suggestions?

Solved it SUNNY TRIPOWER 6.0 / Inputs [A] and [B] / Home Assistant · Issue #20 · kellerza/pysma · GitHub

Did you get this to work?

Here is a way to get the data directly from the SMA Energy Meter or from the SMA Home Manager 2.0 by using Node Red. Why Node Red? It has all we need to intercept the udp multicast messages the Energy Meter sends out every second.

I assume a hass.io environment with installed Node-RED & Mosquitto broker Add-on
We use a function to extract data from the buffer containing the broadcast and feeding them via MQTT to HA.

  1. start a new Flow in Node-Red and call it SMA
  2. drag a “udp in” node (from the network section) on the canvas and configure it like this

    sorry about the German localization in the pic. We need to receive multicast data from the ip 239.12.255.254 using port 9522 to be passed on in a buffer which btw. will contain 608 Bytes per message with the actual firmware of the SMA device.

see also here: http://www.eb-systeme.de/wp-content/uploads/2019/12/EMETER-Protokoll-TI-de-10.pdf

If you connect a debug node to the output of the udp node you should already see the 608 Bytes message coming in every second. If you don’t see any activity it might be that the device you are running Node-Red on is blocking udp multicast messages. This can be the case if you run your instance on a NAS System. It will work perfectly on a PI running HASS.io

  1. drag a function node to the canvas and connect the output from the udp node to the input of the function node.
  2. Configure the function node to have 4 outputs and add the following code
var count = context.get('count')||0;
count += 1;

/*
IF you do not want to update HA every second you can set the fuction to pass
the data less often - see below
*/


if (count < 30) {         /* process data only every 30 seconds */
    context.set('count',count);
    return null;
}

count = 0;
context.set('count',count);

var msg1 = { payload:"actual consumption" };
var msg2 = { payload:"actual gridfeed" };
var msg3 = { payload:"consumption counter" };
var msg4 = { payload:"gridfeed counter" };


/* to get the actual grid consumption in W we need the offset 0.1.4.0 */
offset = msg.payload.indexOf("00010400", 0, "hex")+ 4;
var consumption = parseInt((msg.payload[offset+0]*0x1000000 + 
                            msg.payload[offset+1]*0x10000 + 
                            msg.payload[offset+2]*0x100  +
                            msg.payload[offset+3]) / 10);

/* to get the actual grid consumption counter in Wh we need the offset 0.1.8.0 */
offset = msg.payload.indexOf("00010800", 0, "hex")+ 4;
var consumption_c = parseInt((msg.payload[offset+0]*0x100000000000000 + 
                              msg.payload[offset+1]*0x1000000000000 + 
                              msg.payload[offset+2]*0x10000000000  +
                              msg.payload[offset+3]*0x100000000 +
                              msg.payload[offset+4]*0x1000000 + 
                              msg.payload[offset+5]*0x10000 + 
                              msg.payload[offset+6]*0x100  +
                              msg.payload[offset+7]) / 3600);

/* to get the actual grid feed in W we need the offset 0.2.4.0 */
offset = msg.payload.indexOf("00020400", 0, "hex")+ 4;
var gridfeed = parseInt((msg.payload[offset+0]*0x1000000 + 
                         msg.payload[offset+1]*0x10000 + 
                         msg.payload[offset+2]*0x100  +
                         msg.payload[offset+3]) / 10);

/* to get the actual grid feed counter in Wh we need the offset 0.2.8.0 */
offset = msg.payload.indexOf("00020800", 0, "hex")+ 4;
var gridfeed_c = parseInt((msg.payload[offset+0]*0x100000000000000 + 
                           msg.payload[offset+1]*0x1000000000000 + 
                           msg.payload[offset+2]*0x10000000000  +
                           msg.payload[offset+3]*0x100000000 +
                           msg.payload[offset+4]*0x1000000 + 
                           msg.payload[offset+5]*0x10000 + 
                           msg.payload[offset+6]*0x100  +
                           msg.payload[offset+7]) / 3600);


if (consumption >= 0 && consumption < 100000 ) {
    msg1.payload = consumption.toString();    
} else msg1 = null;

if (consumption_c >= 0 && consumption_c < 50000000 ) {
    msg2.payload = consumption_c.toString();   
} else msg2 = null;

if (gridfeed >= 0 && gridfeed < 100000 ) {
    msg3.payload = gridfeed.toString();    
} else msg3 = null;

if (gridfeed_c >= 0 && gridfeed_c < 5000000 ) {
    msg4.payload = gridfeed_c.toString();   
} else msg4 = null;


return [msg1, msg2, msg3, msg4 ];


  1. now the 4 outputs will push every 30s the following measurements:
    output 1: actual grid consumption in W
    output 2: grid consumption counter in Wh
    output 3: actual grid feed in W
    output 4: grid feed counter in Wh

  2. push this data back into HA using “MQTT out” nodes of your choosing.

  3. define corresponding mqtt sensors in HA to retrieve the data

5 Likes

Hey,
could it be that the smartmeter sends only data when the inverter is on? I tried it right now, but I couldn’t see any message and right now the inverter is probably switched off since it is dark outside …

I am referring to the SMA Energy Meter or the SMA Home Manager 2.0 which has a Energy Meter built-in. These devices measure the power consumption from the grid and the feed into the grid. If your inverter is inactive during the night you will still get power from the grid. It is therefore active 24/7.

There is an iOS app in the Appstore called “Energy Meter” it finds your SMA Device and reports all details . Unfortunately it costs 3 bucks but it is worth the money in my opinion (I am not affiliated with the author).

1 Like

I don’t know why but it was related to the fact that I had node-red running on my QNAP NAS. I configured the noodes but didn’t see the messages coming in. I then scanned the network with Wireshark and saw that the message are send even if the inverter is switched of - as you already stated. I tested it then with a spare Pi I had laying around. As soon as I deployed the nodes I saw the messages coming in. So I guess that my NAS is blocking this udp messages somehow…

Btw: which mdi icons are you using in HA?

Hi azrael,

glad that it worked for you. I added a comment in my description. I think the Synology NAS devices are also blocking the udp multicast messages.

and regarding the mdi icons have a look at mdi:counter and mdi:solar-power. Additionally if you also have data from your inverter about the solar power generation I recommend the power-wheel card. It is available via HACS and works really great

1 Like

If you own a SMA Inverter this post might help you to get the the actual power generation and the counter out of the device directly in HA via the modbus integration.

1 Like

Hi,
Just set this up as a potential replacement for Modbus. It’s working great. Thanks for taking the time to share this.

Can you obtain other parameters via this method? Things that interest me include yield, yield counter, battery %, battery power, etc. Not sure how after looking at the debug packets… Any help would be welcome.

Hi monkey-house. The UDP multicast message contains data from the SMA Energy Meter. In this document page 4 Section 3.1 you get a list of the available data:


In my example I just used the first two entries.

To get data from your inverter like yield and yield counter use modbus. See this document page 28 Section 5.4.1 for the available data for SMA Inverters: http://files.sma.de/dl/2585/WEBBOX-MODBUS-TB-en-19.pdf

Thanks for chiming in. I’m already using modbus for yield, battery, etc. as such:

- platform: modbus
  registers:
# SI
    - name: Modbus SI Battery Charge
      hub: 1
      slave: 3
      register: 30845
      unit_of_measurement: '%'
      precision: 1
      count: 2
      data_type: int
# #    - name: Modbus SI Battery Voltage
      # # hub: 1
# #      slave: 3
# #      register: 30851
# #      unit_of_measurement: V''
# #      scale: 0.01
# #      precision: 1
# #      count: 2
# #      data_type: int
    - name: Modbus SI Grid Frequency
      hub: 1
      slave: 3
      register: 30803
      unit_of_measurement: 'Hz'
      scale: 0.01
      precision: 2
      count: 2
      data_type: int
    - name: Modbus SI Grid Voltage
      hub: 1
      slave: 3
      register: 30783
      unit_of_measurement: 'V'
      scale: 0.01
      precision: 1
      count: 2
      data_type: int
    - name: Modbus SI Battery Charging
      hub: 1
      slave: 3
      register: 31393
      unit_of_measurement: 'W'
      count: 2
      data_type: int
    - name: Modbus SI Battery Discharging
      hub: 1
      slave: 3
      register: 31395
      unit_of_measurement: 'W'
      count: 2
      data_type: int
# #    - name: Modbus SI Load Power
# #      slave: 3
# #      register: 30861
# #      unit_of_measurement: 'W'
# #      count: 2
# #      data_type: int
    - name: Modbus SI Grid Today Raw
      hub: 1
      slave: 3
      register: 30577
      unit_of_measurement: 'kWh'
      count: 2
      scale: 0.001
      precision: 3     
      data_type: int
    - name: Modbus SB Daily Yield
      hub: 2
      unit_of_measurement: 'kWh'
      slave: 3
      register: 30517
      count: 4
      data_type: int
      scale: 0.001
      precision: 3
    - name: Modbus SB Total Yield
      hub: 2
      slave: 3
      register: 30513
      unit_of_measurement: 'kWh'
      count: 4
      data_type: int
      scale: 0.001
      precision: 3
    - name: Modbus SB PV Yield
      hub: 2
      slave: 3
      register: 30775
      unit_of_measurement: 'W'
      count: 2
      data_type: uint
    - name: Modbus SB Grid Consumption
      hub: 2
      slave: 3
      register: 30865
      unit_of_measurement: 'W'
      count: 2
      data_type: uint
    - name: Modbus SB Grid Feed
      hub: 2
      unit_of_measurement: 'W'
      slave: 3
      register: 30867
      count: 2
      data_type: uint

I’d love to get more frequent updates on some sensors (consumption, feed-in and yield amongst others), but do worry about overloading the inverter and battery charger. This is why I’m looking at this UDP path via the Home Manager 2…
From the doc of the Energy Manager Protocol, the only other useful sensor I can find is:

32 1:32.4.0 ‒ Voltage

I just have no idea how to code for this sensor. Can you help?

to decode the voltage from Phase1 (Parameter 32.4.0) you can do it similar to the actual grid consumption 1.4.0 the offset is then 0.32.4.0 (in hex 00200400).

So add a 5. output and the code below

/* to get the actual Voltage of Phase1 we need the offset 0.32.4.0 note 32 = 0x20 in hex*/
offset = msg.payload.indexOf("00200400", 0, "hex")+ 4;
var voltage_p1 = parseInt((msg.payload[offset+0]*0x1000000 + 
                           msg.payload[offset+1]*0x10000 + 
                           msg.payload[offset+2]*0x100  +
                           msg.payload[offset+3]) / 1000);
msg5.payload = voltage_p1.toString();

and of course add msg5 to the return statement at the end

return [msg1, msg2, msg3, msg4, msg5 ];
1 Like

Wow, thank you so much. I will try today.

Working great. Thanks Chris.

Here is my code:

var count = context.get('count')||0;
count += 1;

/*
IF you do not want to update HA every second you can set the fuction to pass
the data less often - see below
*/


if (count < 1) {         /* process data only every 30 seconds */
    context.set('count',count);
    return null;
}

count = 0;
context.set('count',count);

var msg1 = { payload:"actual consumption" };
var msg2 = { payload:"actual gridfeed" };
var msg3 = { payload:"consumption counter" };
var msg4 = { payload:"gridfeed counter" };
var msg5 = { payload:"voltage" };

/* to get the actual grid consumption in W we need the offset 0.1.4.0 */
offset = msg.payload.indexOf("00010400", 0, "hex")+ 4;
var consumption = parseInt((msg.payload[offset+0]*0x1000000 + 
                            msg.payload[offset+1]*0x10000 + 
                            msg.payload[offset+2]*0x100  +
                            msg.payload[offset+3]) / 10);

/* to get the actual grid consumption counter in Wh we need the offset 0.1.8.0 */
offset = msg.payload.indexOf("00010800", 0, "hex")+ 4;
var consumption_c = parseInt((msg.payload[offset+0]*0x100000000000000 + 
                              msg.payload[offset+1]*0x1000000000000 + 
                              msg.payload[offset+2]*0x10000000000  +
                              msg.payload[offset+3]*0x100000000 +
                              msg.payload[offset+4]*0x1000000 + 
                              msg.payload[offset+5]*0x10000 + 
                              msg.payload[offset+6]*0x100  +
                              msg.payload[offset+7]) / 3600);

/* to get the actual grid feed in W we need the offset 0.2.4.0 */
offset = msg.payload.indexOf("00020400", 0, "hex")+ 4;
var gridfeed = parseInt((msg.payload[offset+0]*0x1000000 + 
                         msg.payload[offset+1]*0x10000 + 
                         msg.payload[offset+2]*0x100  +
                         msg.payload[offset+3]) / 10);

/* to get the actual grid feed counter in Wh we need the offset 0.2.8.0 */
offset = msg.payload.indexOf("00020800", 0, "hex")+ 4;
var gridfeed_c = parseInt((msg.payload[offset+0]*0x100000000000000 + 
                           msg.payload[offset+1]*0x1000000000000 + 
                           msg.payload[offset+2]*0x10000000000  +
                           msg.payload[offset+3]*0x100000000 +
                           msg.payload[offset+4]*0x1000000 + 
                           msg.payload[offset+5]*0x10000 + 
                           msg.payload[offset+6]*0x100  +
                           msg.payload[offset+7]) / 3600);

/* to get the actual Voltage of Phase1 we need the offset 0.32.4.0 note 32 = 0x20 in hex*/
offset = msg.payload.indexOf("00200400", 0, "hex")+ 4;
var voltage = parseInt((msg.payload[offset+0]*0x1000000 + 
                           msg.payload[offset+1]*0x10000 + 
                           msg.payload[offset+2]*0x100  +
                           msg.payload[offset+3]) / 1000);
msg5.payload = voltage.toString();

if (consumption >= 0 && consumption < 100000 ) {
    msg1.payload = consumption.toString();    
} else msg1 = null;

if (consumption_c >= 0 && consumption_c < 50000000 ) {
    msg2.payload = consumption_c.toString();   
} else msg2 = null;

if (gridfeed >= 0 && gridfeed < 100000 ) {
    msg3.payload = gridfeed.toString();    
} else msg3 = null;

if (gridfeed_c >= 0 && gridfeed_c < 5000000 ) {
    msg4.payload = gridfeed_c.toString();   
} else msg4 = null;

if (voltage >= 0 && voltage < 1000 ) {
    msg5.payload = voltage.toString();   
} else msg5 = null;

return [msg1, msg2, msg3, msg4, msg5 ];

Do you remember where you have found these SMA sensors number?

How did you get it work with the Home Manager 2.0 ? I have the same - and looking for a good solution.

I’m doing this as per the description above. Using voltage as well as I log the grid fluctuations to show the utility company that there is a problem.
I’m also using Modbus with both inverter and battery charge. Descriptions can be found on this forum…