Long-term maximum and minimum temperature from a sensor

This is the code to create long-term maximum and minimum sensors that read data from another sensor, temperature sensor in my case, but any sensor can be used.

It has these features:

  • It removes wrong sensor values when the difference between new value and last one is higher than input_number.max_temp_step, which can be changed through Lovelace.
  • It can be reset by activating input_boolean.reset_max_min, which works as a dry contact through an automation.
  • It stores last update as an attribute.
  • It self-initializes its value.

The code is:

template:
  - trigger:
    - platform: state
      entity_id: sensor.pws_temp  # Source sensor
    - platform: state
      entity_id: input_number.max_temp_step
    - platform: state
      entity_id: input_boolean.reset_max_min
      from: "off"
      to: "on"
    sensor:
      - name: "Tª max Exterior"
        state: >-
          {% if ((state_attr('sensor.ta_max_exterior','last_valid_sensor_value')|float(states('sensor.pws_temp'))|float 
            - states('sensor.pws_temp')|float(-10))|abs < states('input_number.max_temp_step')|float) 
            and (states('sensor.pws_temp')|float > states('sensor.ta_max_exterior')|float(-10)) %}
            {{ states('sensor.pws_temp') }}
          {% else %}
            {{ states('sensor.ta_max_exterior') }}
          {% endif %}
        unit_of_measurement: "ºC"
        icon: mdi:thermometer-chevron-up
        attributes:
          last_update: >-
            {% if ((state_attr('sensor.ta_max_exterior','last_valid_sensor_value')|float(states('sensor.pws_temp'))|float 
              - states('sensor.pws_temp')|float(-10))|abs < states('input_number.max_temp_step')|float)
              and (states('sensor.pws_temp')|float > states('sensor.ta_max_exterior')|float(-10)) %}
              {{ now() }}
            {% else %}
              {{ state_attr('sensor.ta_max_exterior','last_update') }}
            {% endif %}
          last_valid_sensor_value: >-
            {% if ((state_attr('sensor.ta_max_exterior','last_valid_sensor_value')|float(states('sensor.pws_temp'))|float 
              - states('sensor.pws_temp')|float(-10))|abs < states('input_number.max_temp_step')|float) %}
              {{ states('sensor.pws_temp') }}
            {% else %}
              {{ state_attr('sensor.ta_max_exterior','last_valid_sensor_value') }}
            {% endif %}

  - trigger:
    - platform: state
      entity_id: sensor.pws_vallad_temp
    - platform: state
      entity_id: input_number.max_temp_step
    - platform: state
      entity_id: input_boolean.reset_max_min
      from: "off"
      to: "on"
    sensor:
      - name: "Tª min Exterior"
        state: >-
          {% if ((state_attr('sensor.ta_min_exterior','last_valid_sensor_value')|float(states('sensor.pws_temp'))|float 
            - states('sensor.pws_temp')|float(45))|abs < states('input_number.max_temp_step')|float) 
            and (states('sensor.pws_temp')|float < states('sensor.ta_min_exterior')|float(45)) %}
            {{ states('sensor.pws_temp') }}
          {% else %}
            {{ states('sensor.ta_min_exterior') }}
          {% endif %}
        unit_of_measurement: "ºC"
        icon: mdi:thermometer-chevron-up
        attributes:
          last_update: >-
            {% if ((state_attr('sensor.ta_min_exterior','last_valid_sensor_value')|float(states('sensor.pws_temp'))|float 
              - states('sensor.pws_temp')|float(45))|abs < states('input_number.max_temp_step')|float)
              and (states('sensor.pws_temp')|float < states('sensor.ta_min_exterior')|float(45)) %}
              {{ now() }}
            {% else %}
              {{ state_attr('sensor.ta_min_exterior','last_update') }}
            {% endif %}
          last_valid_sensor_value: >-
            {% if ((state_attr('sensor.ta_min_exterior','last_valid_sensor_value')|float(states('sensor.pws_temp'))|float 
              - states('sensor.pws_temp')|float(45))|abs < states('input_number.max_temp_step')|float) %}
              {{ states('sensor.pws_temp') }}
            {% else %}
              {{ state_attr('sensor.ta_min_exterior','last_valid_sensor_value') }}
            {% endif %}

input_number:
  max_temp_step:
    name: Max temp step
    min: 0
    max: 20
    initial: 5

input_boolean:
  reset_max_min:
    name: Reset max min
    initial: False
    icon: mdi:alert

automation:
  - id: toggle_reset_min_max
    alias: "Toggle reset_min_max"
    description: "When input_boolean.reset_max_min is set to on, automatically set it to off after 2 seconds"
    trigger:
      - platform: state
        entity_id: input_boolean.reset_max_min
        from: "off"
        to: "on"
    condition: []
    action:
      - delay: '00:00:01'
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.reset_max_min
    mode: single

Edit: I’ve added default values to input sensors to avoid an unknown value distorted the state of the sensor.

1 Like