(solved) Help getting a value from negative to positive in template (*-1)

Hey,

I hope this is a super, super quick question. I have a modbus variable/readout that contains the current Power Grid Usage, in near-realtime. Sensor is sensor.e3dc_grid_power. This is…

a) Zero if total equilibrium is reached (this like, never happens).
b) positive number if I am TAKING power FROM the grid INTO my house or
c) negative number if I am PUTTING power FROM my HOUSE into the GRID.

For the energy dashboard I need two different sensors, one for “grid in” and the other “grid out”. So I created two new sensors:

  - sensor:
      - name: "Grid Power In"
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power
        state: >
          {% if states('sensor.e3dc_grid_power') | float(0) >= 0 %}
            {% set gridin = states('sensor.e3dc_grid_power') | float(0) %}
          {% else %}
            {% set gridin = 0 %}
          {% endif %}
          {{ gridin }}
        attributes:
          last_reset: '1970-01-01T00:00:00+00:00'

This works; I get 0 if the reading is below zero, else the readout of the variable. For the opposite direction I have this:

  - sensor:
      - name: "Grid Power Out"
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power
        state: >
          {% if states('sensor.e3dc_grid_power') | float(0) =< 0 %}
            {% set gridout = (states('sensor.e3dc_grid_power') *-1) %}
          {% else %}
            {% set gridout = 0 %}
          {% endif %}
          {{ gridout }}
        attributes:
          last_reset: '1970-01-01T00:00:00+00:00'

This… Does not work. If the reading is positive, zero is returned. But I need a positive reading so I wanted to add a “*-1”, so the negative value is converted to the positive value. Yields… nothing, tho. What am I doing wrong here?

After I got both sensors up, I can use the Riemann Sum Integral to get that into the Dashboard. Which already works in one direction. I am just missing the other way :slight_smile:

Thanks!

1 Like

Here’s from one of my template sensors:

{{ (states('input_number.6900_upstairs_hvac_on_threshold') | float)*-1 }}

Would test in the /developer-tools/template section to confirm intended behavior.

1 Like

I use a minus at the front, this changes a negative number to positive or a positive number to negative:

{% set gridout = -states('sensor.e3dc_grid_power') %}

1 Like

just use absolute pipe

|abs

1 Like

just tested this in the dev tools and it works fine (returns -2)

{% set gridout = (2 *-1) %}
{{ gridout }}

there must be some other issue.

or use | abs as suggested.

Any hints in the log?

Did you try with the float cast? Usually states() returns a string and strings don’t like math operations.

 {% set gridout = (states('sensor.e3dc_grid_power') | float | abs) %}
1 Like

Yep, probably it. I completely missed that.

Hey,

thanks for all your replies – the issue is solved. I tried several approaches, all valid. The only faulty one way my code. Thanks!

Finally, what was the template code of your 2 sensor?

Necromancy!

But I am using the edited post above:

  - sensor:
      - name: "Grid Power In"
        unit_of_measurement: "W"
        state_class: measurement
        device_class: power
        state: >
          {% if states('sensor.e3dc_grid_power') | float(0) >= 0 %}
            {% set gridin = states('sensor.e3dc_grid_power') | float(0) %}
          {% else %}
            {% set gridin = 0 %}
          {% endif %}
          {{ gridin }}
        attributes:
          last_reset: '1970-01-01T00:00:00+00:00'
1 Like

Could you please send the whole config for the 2 sensors.

I have tried to realize the “Grid out” sensor

  - sensor: 
      name: "Varta Grid Power In"
      unit_of_measurement: "W"
      state_class: measurement
      device_class: power
      state: >
        {% if states('sensor.mb_varta_grid_power') | float(0) >= 0 %}
          {% set gridin = states('sensor.mb_varta_grid_power') | float(0) %}
        {% else %}
          {% set gridin = 0 %}
        {% endif %}
        {{ gridin }}
      attributes:
        last_reset: '1970-01-01T00:00:00+00:00'
  - sensor:
      name: "Varta Grid Power Out"
      unit_of_measurement: "W"
      state_class: measurement
      device_class: power
      state: >
        {% if states('sensor.mb_varta_grid_power') | float(0) =< 0 %}
          {% set gridout = (states('sensor.mb_varta_grid_power') | float(0) | abs) %}
        {% else %}
          {% set gridout = 0 %}
        {% endif %}
        {{ gridout }}
      attributes:
        last_reset: '1970-01-01T00:00:00+00:00'

However there is an error:

Invalid config for 'template' at configuration.yaml, line 313: invalid template (TemplateSyntaxError: expected token 'end of statement block', got '=') for dictionary value 'sensor->0->state', got "{% if states('sensor.mb_varta_grid_power') | float(0) =< 0 %}\n {% set gridout = (states('sensor.mb_varta_grid_power') | float | abs) %}\n{% else %}\n {% set gridout = 0 %}\n{% endif %} {{ gridout }}\n"

Your error is the use of =< which should be <=. I’d just use:

state: >
  {{ min(0, states('sensor.mb_varta_grid_power')|float(0))|abs }}

Finds the minimum of zero and your sensor, then returns the absolute (positive) value of that. For the grid-in, use

state: >
  {{ max(0, states('sensor.mb_varta_grid_power')|float(0)) }}

That has been the point, thank you so much!

I will try your short version too but this works for me:

  - sensor: 
      name: "Varta Grid Power Out"
      unit_of_measurement: "W"
      state_class: measurement
      device_class: power
      state: >
        {% if states('sensor.mb_varta_grid_power') | float(0) >= 0 %}
          {% set gridout = states('sensor.mb_varta_grid_power') | float(0) %}
        {% else %}
          {% set gridout = 0 %}
        {% endif %}
        {{ gridout }}
      attributes:
        last_reset: '1970-01-01T00:00:00+00:00'
  - sensor: 
      name: "Varta Grid Power In"
      unit_of_measurement: "W"
      state_class: measurement
      device_class: power
      state: >
        {% if states('sensor.mb_varta_grid_power') | float(0) <= 0 %}
          {% set gridin = states('sensor.mb_varta_grid_power') | float | abs %}        
        {% else %}
          {% set gridin = 0 %}
        {% endif %}
        {{ gridin }}
      attributes:
        last_reset: '1970-01-01T00:00:00+00:00'

This works very good too:

  - sensor: 
      name: "Varta Grid Power Out"
      unit_of_measurement: "W"
      state_class: measurement
      device_class: power
      state: >
        {{ min(0, states('sensor.mb_varta_grid_power')|float(0))|abs }}
      attributes:
        last_reset: '1970-01-01T00:00:00+00:00'
  - sensor: 
      name: "Varta Grid Power In"
      unit_of_measurement: "W"
      state_class: measurement
      device_class: power
      state: >
        {{ max(0, states('sensor.mb_varta_grid_power')|float(0)) }}
      attributes:
        last_reset: '1970-01-01T00:00:00+00:00'
1 Like