Solaredge Modbus Configuration for Single Inverter and Battery

I’ve just had a SolarEdge & StorEdge system set up. I’ve enabled modbus via TCP and have what looks like all the stats. Some of them don’t make any sense which makes me think some of the setup is wrong (e.g. it’s bright sunshine right now with no shading and our 5 kWp array is producing 400 W regardless of whether the sun is behind a cloud or not).

For example, m1_ac_power is always zero. I believe this is meant to show house consumption? If so, does that mean some CT clamp is missing or incorrectly wired?

EDIT: It looks like m1_ac_power is showing grid import/export and ac_power is showing house consumption. Haven’t yet figured out which stat is meant to show solar production. Given the battery discharge is just above the house consumption figure, I don’t think we’re producing anything currently.

Thank you! I will try your code and see if it works better (most of the time mine does seem to produce good results though, but sometimes when production is low I get strange values).

What I just noticed is that “Solar Panel Production” seems to be giving me random spikes when there is no sun at all. Do you have an idea what’s causing that?

It looks like those spikes started come in more often right after 20:00 (8pm), which is when I changed “my” code for your code. But that could just be a coincidence. Last night there were only very few spikes:

I’ve noticed a few “new” glitches myself recently. My house consumption drops to zero at times so I need to look at that. “Spikes” are often caused by the system trying to balance after a demand. Remember that the equipment is not perfect. When the house calls for power suddenly, eg when you turn on the kettle, that demand is immediately met by the grid because that’s always quickest to respond. Then the inverter realises it has power and jumps in. When that call for powed stops suddenly, eg when the kettle turns off, that power cannot suddenly stop. What you usually see is a short period of export, then the system settles down again. Likewise with panel production. The flow can seem to reverse for short periods while the system settles, giving you those strange spikes.

It’s always a good idea to have a copy of your “own” original code to go back to if you need to. I keep mine in a simple Notepad ++ file. It’s also useful for comparing code side by side.

Whenever I see an issue I copy the relevant piece of code into the Developer Tools > Template editor and watch what the results are. Then you an adjust the variables fo make sure it’s working before replacing code in the live version.

This morning my battery decided to switch back to “Disabled” a minute after being re-ebabled (sufficiently charged during off-peak, off-peak window ends).

This automation has been running flawlessly for a few weeks.

Anyone else seen this sort of thing happen?

Did the re-enable command fail or did the battery/inverter just decide to spontaneously change mode?

Yea, I do have a backup of “my” old code.

The spikes are fine, but it’s somewhat interesting that I get those spikes for “panel production”, at night, where there can’t be any panel production whatsoever. But I guess there is nothing I can do about that, as it is data coming via modbus from the SolarEdge system?

I do have an “issue” with your code now. The solar_grid_to_battery_w seems to be wrong, at least sometimes. Right now my battery is being charged my panel only, and I get the following:

image

The old code I was using was working, as far as I know. Do you know why that could be?

My old code:

      - name: "Solar Grid To Battery W"
        unique_id: solar_grid_to_battery_w
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power
        icon: mdi:battery-positive
        state: >
          {% set i1_ac_power = states('sensor.solaredge_i1_ac_power') | float(0) %}
          {% set i2_ac_power = states('sensor.solaredge_i2_ac_power') | float(0) %}
          {% set b1_dc_power = states('sensor.solaredge_b1_dc_power') | float(0) %}

          {% if ((i1_ac_power + i2_ac_power) <= 0 and b1_dc_power > 0) %}
            {{ b1_dc_power }}
          {% else %}
            0
          {% endif %}
        availability: >
          {{ states('sensor.solaredge_i1_ac_power') | is_number and states('sensor.solaredge_i2_ac_power') | is_number and states('sensor.solaredge_b1_dc_power') | is_number}}

Your code:

      - name: "Solar Grid To Battery W"
        unique_id: solar_grid_to_battery_w
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power
        icon: mdi:battery-positive
        state: >
          {% set i1_ac_power = states('sensor.solaredge_i1_ac_power') | float(0) %}

          {% set b1_dc_power = states('sensor.solaredge_b1_dc_power') | float(0) %}

          {% if i1_ac_power < 0 %}
            {% set i1_ac_power = (i1_ac_power * -1) %}
            {% else %}  
              {% set i1_ac_power = (states('sensor.solaredge_i1_ac_power') | float(0)) %}
              {% endif %}  
              {% if (i1_ac_power <= 0 and b1_dc_power > 0 ) %}
                {{ b1_dc_power }}
                {% else %}
                  0
                  {% endif %}
        availability: >
          {{ states('sensor.solaredge_i1_ac_power') | is_number and states('sensor.solaredge_b1_dc_power') | is_number}}

I’ve discovered the glitches in the code. Two sections of code are wrong. If you replace them with these then the flow to the house and battery should be correct.

The two sectiosn of code are panel_to_house_w and panel_to_battery_w

Replace them with these:

- name: "Solar Panel To House W"
        unique_id: solar_panel_to_house_w
        unit_of_measurement: "W"
        icon: mdi:solar-power
        state: >
          {% set i1_dc_power = states('sensor.solaredge_i1_dc_power') | float(0) %}
          {% set i2_dc_power = states('sensor.solaredge_i2_dc_power') | float(0) %}
          {% set i1_ac_power = states('sensor.solaredge_i1_ac_power') | float(0) %}
          {% set i2_ac_power = states('sensor.solaredge_i2_ac_power') | float(0) %}
          {% set b1_dc_power = states('sensor.solaredge_b1_dc_power') | float(0) %}
          {% set m1_ac_power = states('sensor.solaredge_m1_ac_power') | float(0) %}
          {% set inverter_efficiency = states('sensor.solar_inverter_efficiency') | float(0) %}

          {% if (b1_dc_power >= 0 and m1_ac_power > 0) %}
            {% if ((i1_dc_power + i2_dc_power) < 0 and (i1_ac_power + i2_ac_power) <= 0) %}
              {{ ((i1_dc_power + i2_dc_power) - m1_ac_power) }}
            {% else %}
              {{ ((i1_ac_power + i2_ac_power) - m1_ac_power) }}
            {% endif %}
          {% elif (b1_dc_power >= 0 and m1_ac_power <= 0) %}
            {% if ((i1_dc_power + i2_dc_power) < 0 and (i1_ac_power + i2_ac_power)  <= 0) %}
              {{ (i1_dc_power + i2_dc_power ) }}
            {% else %}
              {{ (i1_ac_power + i2_ac_power) }}
            {% endif %}
          {% elif (b1_dc_power < 0) %}
            {% if (i1_dc_power + i2_dc_power + b1_dc_power < 0) %}
              0
            {% else %}
              {{ ((i1_dc_power + i2_dc_power  + b1_dc_power) * inverter_effectiveness) }}
            {% endif %}   
          {% else %}
            0
          {% endif %}  
        availability: >
          {{ states('sensor.solaredge_i1_dc_power') | is_number and states('sensor.solaredge_i2_dc_power') | is_number and states('sensor.solaredge_i1_ac_power') | is_number and states('sensor.solaredge_i2_ac_power') | is_number and states('sensor.solaredge_b1_dc_power') | is_number and states('sensor.solaredge_m1_ac_power') | is_number }}
- name: "Solar Panel To Battery W"
        unique_id: solar_panel_to_battery_w
        unit_of_measurement: "W"
        icon: mdi:solar-power
        state: >
          {% set b1_dc_power = states('sensor.solaredge_b1_dc_power') | float(0) %}
          {% set grid_to_battery_w = states('sensor.solar_grid_to_battery_w') | float(0) %}
          {% set i1_dc_power = states('sensor.solaredge_i1_dc_power') | float(0) %}
          
          {% if i1_dc_power < 0 %}
            {% set i1_dc_power = (states('sensor.solaredge_i1_dc_power') | float (0) * -1) %}
          {% else %}
            {% set i1_dc_power = states('sensor.solaredge_i1_dc_power') | float(0) %}
          {% endif %}

          {% if (b1_dc_power > 0) %}
            {% if (grid_to_battery_w > 0) %}
              0
            {% else %}
              {{ b1_dc_power }}
            {% endif %} 
          {% else %}
            0
          {% endif %}
        availability: >
          {{ states('sensor.solaredge_b1_dc_power') | is_number }}

The tricky bit with two inverters is that i1_dc_power often goes negative in value while the battery is charging. With the original section of code, this fools the flow into thinking the battery is charging from the grid. The new piece of code simply watches for i1_dc_power going negative and makes it positive again.

Hope that works for you now

1 Like

Thank you! I will use that and keep an eye on the flows :slight_smile:

1 Like

Unfortunately, that didn’t fix it. I will have to take a closer look when I find the time. Sun is shining, house car is charging, oven is on… but panel to house is 0 for a short period. House consumption somehow is 0 as well.

image

That’s a shame. Perhaps your setup is not quite the same as mine. Currently, the sun is shining, the battery is charging and the house is drawing power.

House Flow

I did notice with mine that once the battery was charged, the panels appeared to show no generation.

That’s next on my list.

All good fun!

Mostly my flows work fine with my current code, but sometimes in the mornings I do see some negative panel production flow. Might be the negative values for DC power on inverter 1.

Also, efficiency calculations seem to be wrong with my code, so I will maybe try to use those parts from your code and see how that goes.

I had to set battery efficiency to 100 % for now, but of course that’s not correct.

Looks like my latest glitch was a loss of the sensor. It went unknown for a short time. Back now and all looks okay.

Battery full again. Hot water on now.

House flow battery full

Interestingly, this card always shows the right values, even when the flow card looks wrong. Good to have them side by side for comparison.

Power flow battery full

UPDATE

Got it. Line 183 is

{{ ((i1_dc_power + i2_dc_power + b1_dc_power) * inverter_effectiveness) }}

it should be

{{ ((i1_dc_power + i2_dc_power + b1_dc_power) * inverter_efficiency) }}

I changed the original inverter_effectiveness to inverter_efficiency

Thanks for the update. I missed that, should have seen that.

I am now trying “your code” again to see if there are any glitches :smiley:

The “Power Flow” card is great, I do look at that sometime as well. Do you display an average of the two inverter efficiency values or just the efficiency or inverter 1?

@P6Dave

Could I suggest this as a tad cleaner (hopefully i copied the right post… ):

- name: "Solar Panel To House W"
        unique_id: solar_panel_to_house_w
        unit_of_measurement: "W"
        icon: mdi:solar-power
        state: >
          {% set i1_dc_power = states('sensor.solaredge_i1_dc_power') | float(0) %}
          {% set i2_dc_power = states('sensor.solaredge_i2_dc_power') | float(0) %}
          {% set i_dc_power = (i1_dc_power + i2_dc_power) | float(0) %}
          {% set i1_ac_power = states('sensor.solaredge_i1_ac_power') | float(0) %}
          {% set i2_ac_power = states('sensor.solaredge_i2_ac_power') | float(0) %}
          {% set i_ac_power = (i1_ac_power + i2_ac_power) | float(0) %}
          {% set b1_dc_power = states('sensor.solaredge_b1_dc_power') | float(0) %}
          {% set m1_ac_power = states('sensor.solaredge_m1_ac_power') | float(0) %}
          {% set inverter_efficiency = states('sensor.solar_inverter_efficiency') | float(0) %}

          {% if (b1_dc_power >= 0 and m1_ac_power > 0) %}
            {% if (i_dc_power < 0 and i_ac_power <= 0) %}
              {{ (i_dc_power - m1_ac_power) }}
            {% else %}
              {{ (i_ac_power - m1_ac_power) }}
            {% endif %}
          {% elif (b1_dc_power >= 0 and m1_ac_power <= 0) %}
            {% if (i_dc_power < 0 and i_ac_power  <= 0) %}
              {{ i_dc_power }}
            {% else %}
              {{ i_ac_power }}
            {% endif %}
          {% elif (b1_dc_power < 0) %}
            {% if (i_dc_power + b1_dc_power < 0) %}
              0
            {% else %}
              {{ ((i_dc_power  + b1_dc_power) * inverter_effectiveness) }}
            {% endif %}   
          {% else %}
            0
          {% endif %}  
        availability: >
          {{ states('sensor.solaredge_i1_dc_power') | is_number and states('sensor.solaredge_i2_dc_power') | is_number and states('sensor.solaredge_i1_ac_power') | is_number and states('sensor.solaredge_i2_ac_power') | is_number and states('sensor.solaredge_b1_dc_power') | is_number and states('sensor.solaredge_m1_ac_power') | is_number }}

Basically i’ve just added to extra vars to hold i1_*_power so that it makes the addition etc later clearer

1 Like

Ooh, interesting. I’ll test that and see how it does. I do like a tidy bit of code :grinning_face_with_smiling_eyes:

Thanks.

I have another card in a sub view that displays this when you tap on the inverter efficiency bar:

1 Like

Thanks everyone for contributing. I need to catch up and adapt some of the latest config changes, which do iron out some of the last issues I think.

Just to this bit…I actually do not visualise it, but…as to your example: if you would turn on a kettle with 3 kW, that is what is being visualised in the flows. The battery does output more (probably not 6, since the system can only do 5) and this can be seen if you look at the sensor.solaredge_b1_dc_power, this is the actual output of the battery. The lower value is the solaredge_i1_dc_power, so the actual power the inverter is “receiving” from the battery. Out of this difference I show the effectivness as I called them.

If you start looking at the battery ouput and input values over the day, you can see that you actually put more power into your battery, as you are able to get out. In my case sometimes I charged 6 kWh but only got 3 kWh out of it, before the battery was at the same state of charge again.

So…my flows do not show what the battery outputs, but what gets delivered at the inverter so to say. Hope this explains it.

EDIT: Here you basically see what happens:
image

The house is consuming ac power from the inverter: 431 W
The inverter has 437.5 W on the DC side, so a loss of: 437.5-431/437.5= 0,01 * 100= 1 % Loss
This is the inverter effectivness as I called it. 100 - 1= 99%

So the battery outputs 489 W, but again at the inverter DC side there is only 437,5 W. So again here we lose 489 - 437,5 = 51,5 W, divided by the battery output = 51,5/489= 0,1 * 100 = 10% Loss.
This is the battery effectivness, in this case 90%.

And yes, I was quite shocked when I look at when the battery is at lower states of charge, how much power you actually lose in the circuit.

1 Like

Hi All, looking for a little help. I’ve got two batteries & one inverter.

I’ve created a template to combine both batteries, but my readings are wrong, can anyone with more experience point out where I have gone wrong with my version of energy.yaml please?


Edit: updated HA to 2023.3.5 fixed these issues, apart from the too many decimals which I know is down to a previous update where Home Assistant moved rounding from back end to front end.

Somehow battery efficiency is not working correctly with your code above.

Right now there is just a little solar production, about 1 kW of battery consumption. Battery efficiency is calculated as 0, as you can see in the screenshots.

This results in the house consumption being too low as well.

For now I put battery efficiency back to 100 % manually (so no calculation). Maybe you have a clue why this is happening :slight_smile:

Edit:

I have to add, that doesn’t happen often, that battery eff. is 0, just this morning when there is little solar consumption the battery is being used. Last night, battery efficiency seems to have been calculated correctly (between something like 80 and 99 % IIRC).

Okay, I’ve seen some low values for battery efficiency, but the only time it drops to zero is when there is a problem with the battery (yes that happens). Only thing I can suggest at this stage is perhaps I’ve missed an “effectiveness” to “efficiency” somewhere.

Keep an eye on it and let me know if it happens again.

Without looking through your entire code, can I suggest you look at the sections you’ve changed.

What I tend to do is copy the area of code I think is wrong into the Template Editor in Developer Tools and watch what results I get in the right hand side. You can then edit the code without fear of it messing up your live configuration until it does what you want it to do. If you need to see what any additional entities are doing, or what effect they are having on your code, simply add the states of those entities and label them so you know what they are.

Hope that helps.