Setting template sensor to stay in a defined range, as close as possible to another sensors value

NB - Post rewritten to make the intention more clear.

Hi all,

I am trying to set the limit of a solar inverter according to the power consumption (wattage) in my household during nights. I want the inverter to feed only the wattage that’s needed into the household, up to a maximum of 150W.

The Inverter limit can be set through MQTT. I also have a sensor that measures the power consumption in my household (Shelly 3em) and I configured a sensor to calculate the excess wattage which is being fed into the grid.

The excess should be as little as possible and the amount of power the inverter is feeding in to my household should be as close as possible to my power consumption, but not less that 75W.

I am testing following sensor at the moment, but some times the limit drops to low which apparently shuts down the inverter.

- name: "inverter limit v2"
        unique_id: "inverterlimitv2"
        unit_of_measurement: W
        state: >
         {% if states('sensor.excess_wattage') | float(0) > 0 %}
          {{ states('input_number.inverter_limit_night')|float(0) - states('sensor.excess_wattage') | float(0) }}
         {% else %}
          {% if states('sensor.total_power_consumption')|float(0) <= states('inverter_limit_night')|float(0) %}
         {{ states('sensor.total_power_consumption')|float(0) }}
          {% else %}
         {{ states('input_number.inverter_limit_night')|float(0) }}
          {% endif %}
          {% endif %}

My automation code so far:

- id: '1680376680691'
  alias: Solar HM1500 Options Limiter
  description: ''
  trigger:
  - platform: sun
    event: sunrise
    offset: +00:30:00
  condition:
  - condition: numeric_state
    entity_id: sensor.solar_production_wattage
    above: 0
  action:
  - repeat:
      while:
      - condition: sun
        before: sunset
        after: sunrise
      sequence:
      - choose:
        - conditions:
          - condition: numeric_state
            entity_id: sensor.excess_wattage
            below: 1
          - condition: numeric_state
            entity_id: sensor.solar_production_wattage
            below: 600
          sequence:
          - service: mqtt.publish
            data:
              qos: 0
              retain: false
              topic: inverter/ctrl/limit/0
              payload_template: '{{ states("sensor.inverter_limit_percentage") }}'
        - conditions:
          - condition: numeric_state
            entity_id: sensor.household_total_power_consumption
            above: 600
          sequence:
          - service: mqtt.publish
            data:
              qos: 0
              retain: false
              topic: inverter/ctrl/limit/0
              payload: '100'
        - conditions:
          - condition: numeric_state
            entity_id: sensor.excess_wattage
            above: 1
          sequence:
          - service: mqtt.publish
            data:
              qos: 0
              retain: false
              topic: inverter/ctrl/limit/0
              payload_template: '{{ states("sensor.inverter_limit_percentage_when_excess_wattage")
                }}'
      - delay:
          hours: 0
          minutes: 0
          seconds: 5
          milliseconds: 0
  mode: single

In my configuration.yaml I am doing few calculations to support the limiter:

Calculate: Required Limit to cut excess

- name: "inverter dynamic limit"
        unique_id: "inverterdynamiclimit"
        unit_of_measurement: W
        state: >
         {{ states('sensor.household_total_power_consumption')|float(0) - states('sensor.sensor.excess_wattage)|float(0) }}  

Calculate inverter limit for the case: no excess wattage and power consumption below 600W

- name: "inverter limit percentage"
        unique_id: "inverterlimitpercentage"
        unit_of_measurement: '%'
        state: >
         {{ 100/states('input_number.inverter_limit')|float(0) * states('sensor.household_total_power_consumption')|float(0)| round() }}            

Calculate inverter limit for the case: excess wattage

- name: "inverter limit percentage when excess wattage"
        unique_id: "inverterlimitpercentagewhenexcesswattage"
        unit_of_measurement: '%'
        state: >
         {{ 100/states('input_number.inverter_limit')|float(0) * states('sensor.inverter_dynamic_limit')|float(0)| round() }}

Will test this whit some sun light but wanted to ask whether this logic makes sense or can be improved?

So the above doesn’t really work.

The MQTT does work and the inverter gets the limits, but the calculation of the limits is wrong.

Setting the limit dynamically:

This calculation moves the limit in the wrong direction; e.g. my consumption is 200W, solar provides 400W so my excess is 200W (I calculate the excess value as positive value in another sensor).

The code results is a dynamic limit of -400, but it should be 200W.

- name: "inverter dynamic limit"
        unique_id: "inverterdynamiclimit"
        unit_of_measurement: W
        state: >
         {{ states('sensor.household_total_power_consumption')|float(0) - states('sensor.sensor.excess_wattage)|float(0) }}

I think the whole automation and templating could be streamlined.

Setting the inverter limit dynamically in no code language:

If total_power_consumption < 0 then (set dynamic_limit = solar_production - excess_wattage)
else if total_power_consumption > 0 and < 600 then (set dynamic limit = total_power_consumption)
else if total_power_consumption > 600 then (set dynamic limit = 600)

I think the most important part is the first “if” which basically should do:

inverter_limit = solar_production - excess

The screenshot below shows the solar panels producing more than I need, hence I have a lot of excess wattage wich drives my total power consumption sensor to negative.

Bildschirmfoto 2023-04-02 um 10.36.03

I think this would eliminate the need for the other limit calculation I am doing. I would then still need to convert the watt value into % from 600 (set by input_number.inverter_limit), since 600W is the legal limit in Germany.

Can anyone assist with this one?

Testing this code at the moment:

# setting the inverter limit dynamically v2
      - name: "inverter limit v2"
        unique_id: "inverterlimitv2"
        unit_of_measurement: W
        state: >
         {% if states('sensor.total_power_consumption')|float(0) < 0 %}
          {{ ( (states('sensor.solar_production') | float(0) ) - (states('sensor.excess_wattage') | float(0)) ) }}
         {% elif states('sensor.total_power_sonumption')|float(0) > 0 and states('sensor.total_power_sonumption')|float(0) < 600 %}
          {{ states('sensor.total_power_sonumption')|float(0) }}
         {% elif states('sensor.total_power_sonumption')|float(0) > 600 %}
          {{ 600 }}
         {% endif %}

Initial post updated with the code & context of this post.

I am getting closer to a working sensor, however the hoymilies inverters seem to shut down if certain lower limits are pushed through MQTT.

I am using rolling code atm to calculate the inverter limit:

  - name: "inverter limit v2"
        unique_id: "inverterlimitv2"
        unit_of_measurement: W
        state: >
         {% if states('sensor.excess_wattage') | float(0) > 0 %}
          {{ states('input_number.inverter_limit_night')|float(0) - states('sensor.excess_wattage') | float(0) }}
         {% else %}
          {% if states('sensor.total_power_consumption')|float(0) <= states('inverter_limit_night')|float(0) %}
         {{ states('sensor.total_power_consumption')|float(0) }}
          {% else %}
         {{ states('input_number.inverter_limit_night')|float(0) }}
          {% endif %}
          {% endif %}

Question: How can I limit the first two if conditional calculations to a lower limit of 75?

My inverter limit for the night is 150 W and the power consumption moves between 70 - 170W. I want the inverter to feed max. 150W but not less that 75W.

any help is appreciated :slight_smile: