Calculations with sensor values

No problem, I’ll try to keep it succinct. I can only really help with the storage OIDs for now, I’ll have to search for the others when I get home.

Fortunately, OIDs are the same across Windows systems, so they stay the same for the C,D,E drive, etc.

For the C-drive, you’d use:

- platform: snmp
  host: 192.168.2.200
  name: adUsed_Disk_C
  community: public
  baseoid: 1.3.6.1.2.1.25.2.3.1.6.1

and

- platform: snmp
  host: 192.168.2.200
  name: adTotal_Disk_C
  community: public
  baseoid: 1.3.6.1.2.1.25.2.3.1.5.1

The “1” on the end represents the drive, ie. 1 = C, 2 = D, 3 = E, and so on. The preceding number, ie the 6 and 5 represent the object, so 6 = Used Space and 5 = Total Disk Space.

That’s pretty much the construct.

As far as the sensor goes to calculate percentage:

- platform: template
  sensors:
    my_sensor_ad_c_used_percent:
      value_template: "{{ ((states.sensor.adused_disk_c.state|int) / (states.sensor.adtotal_disk_c.state|int) *100)|round(1) }}"

I think that should get you well on your way, I’ll see what I can do about the CPU and RAM OIDs.

Thanks, here is my config, finally (in French, but clear enough, I think), with some calculations to have the value in Gb (as they are stored in allocation units). I have left some calculations details instead of a simplified version with parts resolved, just to keep the logic. Some values could be retrieved (units size, etc.), but are not supposed to change, so I hardcoded some.

- platform: snmp
  name: 'Disque dur utilisé'
  host: 192.168.178.75
  baseoid: 1.3.6.1.2.1.25.2.3.1.6.1
  accept_errors: true
  unit_of_measurement: 'Go'
  value_template: ' {{(((value | int) * 4096) / 1000000000) | round(1) }} '
  
- platform: snmp
  name: 'Mémoire virtuelle utilisée'
  host: 192.168.178.75
  baseoid: 1.3.6.1.2.1.25.2.3.1.6.2
  accept_errors: true
  unit_of_measurement: 'Go'
  value_template: ' {{(((value | int) * 65536) / 1000000000) | round(1) }} '
  
- platform: snmp
  name: 'Mémoire physique utilisée'
  host: 192.168.178.75
  baseoid: 1.3.6.1.2.1.25.2.3.1.6.3
  accept_errors: true
  unit_of_measurement: 'Go'
  value_template: ' {{(((value | int) * 65536) / 1000000000) | round(1) }} '
  
- platform: snmp
  name: "Erreurs d'allocation disque"
  host: 192.168.178.75
  baseoid: 1.3.6.1.2.1.25.2.3.1.7.1
  accept_errors: true
  value_template: ' {{ value | int }} '

- platform: snmp
  name: "Temps depuis demarrage"
  host: 192.168.178.75
  baseoid: 1.3.6.1.2.1.25.1.1.0
  accept_errors: true
  unit_of_measurement: 'timeticks'

- platform: template
  sensors:
    snmp_dernier_demarrage:
      friendly_name: "Dernier démarrage"
      device_class: timestamp
      icon_template: 'mdi:timer'
      entity_id: sensor.temps_depuis_demarrage
      attribute_templates:
        timeticks: "{{ states('sensor.temps_depuis_demarrage') | int }} centièmes de seconde"
      value_template: >
        {% set mytime = (as_timestamp(now()) - ((states('sensor.temps_depuis_demarrage') | int) / 100) | int) %}
        {{ strptime(mytime | timestamp_local, '%Y-%m-%d %H:%M:00') }}
    snmp_memoire_ram:
      friendly_name: "Mémoire utilisée"
      entity_id: sensor.memoire_physique_utilisee, sensor.memoire_virtuelle_utilisee
      unit_of_measurement: '%'
      icon_template: 'mdi:memory'
      value_template: " {{ (((states('sensor.memoire_physique_utilisee') | float) / (((128601 | int) * 65536) / 1000000000))*100)|round }} "
      attribute_templates:
        memoire_virtuelle: "{{ (((states('sensor.memoire_virtuelle_utilisee') | float) / (((165465 | int) * 65536) / 1000000000))*100)|round }} %"
    snmp_disque_utilise:
      friendly_name: "Disque utilisé"
      entity_id: sensor.disque_dur_utilise
      unit_of_measurement: '%'
      value_template: " {{ (((states('sensor.disque_dur_utilise') | float) / (((30972671 | int) * 4096) / 1000000000))*100)|round }} "
      icon_template: 'mdi:harddisk'
      attribute_templates:
        taille_occupée: "{{ states('sensor.disque_dur_utilise') }} Go"

Newbie here just getting to grips with sensors in configuraion.yaml. I really like the way that you’ve used the variables to make this tidier (my first time with variables) so thought I’d give it a go.

I attempted this as shown below:

ram_free_percentage:
   value_template: >- 
      {% set t = states('sensor.media_pc_total_ram') | int %}
      {% set u = states('sensor.media_pc_used_ram') | int %}
      {{ ((t - u) / t) x 100 }}
    unit_of_measurement: '%'

But when I check configuration it indicates an error:

Invalid config for [sensor.template]: invalid template (TemplateSyntaxError: expected token ‘end of print statement’, got ‘x’) for dictionary value @ data[‘sensors’][‘ram_free_percentage’][‘value_template’]. Got ‘{% set t = states(‘sensor.media_pc_total_ram’) | int %} {% set u = states(‘sensor.media_pc_used_ram’) | int %} “{{ ((t - u) / t) x 100 }}”’. (See ?, line ?).

I’ve looked at the example on the template help page and can’t see any obvious issue when looking at the examples. Do you any guidance or ideas on what may be causing the error?

You indicate multiplication with an asterisk * not with the letter x. That’s what the error message is carping about:

expected token ‘end of print statement’, got ‘x’

I am doing my first sensor, and it calculates correct:


- platform: template

    sensors:

      elpris_kwh_total:

        value_template: "{{ (((states('sensor.nordpool_kwh_dk2_dkk_3_10_025') | float + (1.64)) |round(2)) | float) }}"

The problem is that the output is display as text, not as a graph in lovelace!!

What do I need to change to get the graph??

image

entities:
  - entity: sensor.nordpool_kwh_dk2_dkk_3_10_025
  - entity: sensor.elpris_kwh_total
hours_to_show: 72
refresh_interval: 0
title: Elpris
type: history-graph
3 Likes

A verry simple and clean way to make calculations! Thanks! :smiley:

Hi!

Maybe you already fixed the problem - but you need to set a unit to the value to get a graph, ie:

- platform: template
    sensors:
      elpris_kwh_total:
        unit_of_measurement: 'DKK/kWh'
        value_template: "{{ (((states('sensor.nordpool_kwh_dk2_dkk_3_10_025') | float + (1.64)) |round(2)) | float) }}"

Cheers,
Thomas

2 Likes

This is very helpful.

In the example below, does the variable water_volume persist across the sensor or just the value_template?

- platform: template
  sensors:
    circulation_time:
      friendly_name: "Circulation time"
      value_template: >-
        {% set lph = states('sensor.total_circulation_lph') | int(none) %}
        {% if lph %}
          {% set hours = 11526 / lph %}
          {% set minutes = ((hours % 1) * 60) | int %}
          {% set hours = (hours - (hours % 1)) | int %}
          {{ '%02i:%02i'%(hours, minutes) }}
        {% else %}
          none
        {% endif %}
    circulation_hours:
      friendly_name: "Circulation hours"
      value_template: >-
        {% set litres_per_hour = states('sensor.total_circulation_lph') | int(none) %}
        {% set water_volume = 11526 | int %}
        {{ water_volume / litres_per_hour }}

Is there a way to have water_volume be a global variable throughout the HA config?

The scope of a Jinja2 variable is limited to the option where it’s defined. So, no, water_volume isn’t defined outside of value_template.

There are no global Jinja2 variables in Home Assistant.

You can store a value in a Helper (input_number, input_text, etc) or use one of the third party custom_components that implement global variables (by storing them in special entities using the same principle as Helpers).

1 Like

Thank you!

I have looked for a custom component for implementing and using global variables. Can you please offer a suggestion.
Thank you.

Really appreciate all the info above. I am having a weird issue. When I enter the below into the developer tools Template section, it returns values as it should. When I add to my sensors.yaml file and reboot, new sensors are not created. Anything obvious standout to anyone? Each grid_usage sensor is a Utility sensor that collects data from other sensor. I don’t think it matters but figured I would mention.

sensor Electricity Cost Sensor:
  - platform: template
    sensors:
      yearly_electricity_cost:
        friendly_name: "Current Yearly Electricity Cost"
        value_template: >- 
          {% set grid_usage = states('sensor.yearly_net_grid_usage') | int %}
          {{ grid_usage * 0.18 }}
      monthly_electricity_cost:
        friendly_name: "Current Monthly Electricity Cost"
        value_template: >- 
          {% set grid_usage = states('sensor.monthly_net_grid_usage') | int %}
          {{ grid_usage * 0.18 }}
      daily_electricity_cost:
        friendly_name: "Current Daily Electriciy Cost"
        value_template: >- 
          {% set grid_usage = states('sensor.daily_net_grid_usage') | int %}
          {{ grid_usage * 0.18 }}

That is the legacy template format, newer format is here:

Can still use it though, not sure what your first line sensor Electricity Cost Sensor: is for ?

sensor:
  - platform: template
    sensors:
      yearly_electricity_cost:
        friendly_name: "Current Yearly Electricity Cost"
        value_template: >- 
          {% set grid_usage = states('sensor.yearly_net_grid_usage') | int %}
          {{ grid_usage * 0.18 }}
      monthly_electricity_cost:
        friendly_name: "Current Monthly Electricity Cost"
        value_template: >- 
          {% set grid_usage = states('sensor.monthly_net_grid_usage') | int %}
          {{ grid_usage * 0.18 }}
      daily_electricity_cost:
        friendly_name: "Current Daily Electriciy Cost"
        value_template: >- 
          {% set grid_usage = states('sensor.daily_net_grid_usage') | int %}
          {{ grid_usage * 0.18 }}

Also, no need to reboot, just reload Templates

1 Like

Maybe my current sensors work still because they were created years ago. There aren’t any errors in any of the logs. Will maybe create a new file (template.yaml) and try adding them in the new format there. Then I suspect I need to start migrating all my other template entities.
The Electricity Costs Sensor was a method that I used to group template sensors. I honestly never knew why it didn’t error. In other areas I just use comments now. Below is a larger sample.

######################################## Sensor for basement humidity ##################################
sensor EcoBee Sensors:
  - platform: template
    sensors:
      basement_humidity:
        friendly_name: "Basement Humidity"
        unit_of_measurement: "%"
        value_template: "{{ state_attr('climate.basement', 'current_humidity') }}"
      workout_server_room_humidity:
        friendly_name: "Workout & Server Room Humidity"
        unit_of_measurement: "%"
        value_template: "{{ state_attr('climate.workout_room', 'current_humidity') }}"
      2nd_floor_guest:
        value_template: >-
          {% if state_attr('climate.2nd_floor_guest', 'hvac_action') == "idle" %} OFF
          {% elif state_attr('climate.2nd_floor_guest', 'hvac_action') == "cooling" %} ON
          {% elif state_attr('climate.2nd_floor_guest', 'hvac_action') == "heating" %} ON
          {% endif %}
######################################## Sensor for Electriciy Costs ##################################
sensor Electricity Cost Sensor:
  - platform: template
    sensors:
      yearly_electricity_cost:
        friendly_name: "Current Yearly Electricity Cost"
        value_template: >- 
          {% set grid_usage = states('sensor.yearly_net_grid_usage') | int %}
          {{ grid_usage * 0.18 }}
        unit_of_measurement: '$'
      monthly_electricity_cost:
        friendly_name: "Current Monthly Electricity Cost"
        value_template: >- 
          {% set grid_usage = states('sensor.monthly_net_grid_usage') | int %}
          {{ grid_usage * 0.18 }}
        unit_of_measurement: '$'
      daily_electricity_cost:
        friendly_name: "Current Daily Electriciy Cost"
        value_template: >- 
          {% set grid_usage = states('sensor.daily_net_grid_usage') | int %}
          {{ grid_usage * 0.18 }}
        unit_of_measurement: '$'

sensor Electricity Usage Sensor:
  - platform: template
    sensors:
      net_daily_power:
        friendly_name: Net Daily Power
        unit_of_measurement: kWh
        value_template: "{{ states('sensor.daily_grid_usage')|float - states('sensor.daily_solar_generation')|float }}"

Thanks for the help. Placing the sensors under the new Template structure fixed my issue. Final config:

Template:
  - sensor:
    - name: Yearly Electricity Cost
      state: >- 
        {% set grid_usage = states('sensor.yearly_net_grid_usage') | int %}
        ${{ (grid_usage * 0.18) | round(2) }}
    - name: Monthly Electricity Cost
      state: >- 
        {% set grid_usage = states('sensor.monthly_net_grid_usage') | int %}
        ${{ (grid_usage * 0.18) | round(2) }}
    - name: Daily Electricity Cost
      state: >-
          {% set grid_usage = states('sensor.daily_net_grid_usage') | int %}
          ${{ (grid_usage * 0.18) | round(2) }}
        

Hello World!
I’m not sure how to convert the date into integer in the following template:

{% set today = now() %}
{% set birthday = state_attr('sensor.anniversary_urodziny_aga', 'date') %}
{% set days = (today - birthday) %}
{{today}}
{{birthday}}

{{days}}

The result is:

2023-08-19 11:59:00.140739+02:00
1974-12-23 00:00:00+01:00

17771 days, 11:59:00.140739

and basically this is OK.

Now I need to do some math calculations using days as a numerical parameter in sin(x) function.
(e.g. sin (17771) = 0.8358291413129607)
However, the following syntax: {{ sin (days) }} gives the following error:
ValueError: Template error: sin got invalid input '17771 days, 11:59:00.140739' when rendering template.

I tried using various methods and functions to convert this datetime object 17771 days, 11:59:00.140739 into pure integer 17771 but none of them returns the expected result. Now I’m stuck.
Can you please advise?

Any help or hint would be much appreciated.

Hi, I’m struggling to calculate the absolute humidity (i.e. water content) from the relative humidity and temperature. It’s a not a linear relationship so I need to use x ^ y in my calculation but this causes an error. What’s the right syntax for ‘to the power of’. Many thanks

sensor:
  - platform: template
    sensors: 
      weather_humidity:
        value_template: "{{ state_attr('weather.the_cwtch', 'humidity') }}"  
        friendly_name: 'humidity_outdoor'
        unit_of_measurement: '%'
      weather_temperature:
        value_template: "{{ state_attr('weather.the_cwtch', 'temperature') }}"  
        friendly_name: 'temperature_outdoor'
        unit_of_measurement: 'c°'
      weather_absolute_humidtity:
        value_template: "{{ (states('sensor.weather_humidity') | float * 0.6226 * 2.718282 ^ (0.0661 * states('sensor.weather_temperature') | float) * 10000) / (461.5 * (states('sensor.weather_temperature') | float+273))}}"
        friendly_name: 'water_content'
        unit_of_measurement: 'g_per_m3'

According to Jinja doc:

**
Raise the left operand to the power of the right operand. {{ 2**3 }} would return 8.

Source: Template Designer Documentation — Jinja Documentation (3.2.x)