Daily min max temperature with time stamp

The value will be reset (to the current value) every time some trigger happens. One trigger will happen when a value is higher than the last max or at midnight (regardless the value).
So, this sensor won’t work until the midnight happens for the first time. You probably can set an initial value manually on Developer Tools > States, otherwise just wait for next midnight and it will work.

Sure! But then you probably will prefer using a template trigger instead of a time trigger. Something like this:

  - platform: template
    value_template: '{{ now().day == 1 and now().hour == 0 and now().minute == 0 and now().second == 0 }}'

Try this:

  - platform: template
    value_template: '{{ now().month == 1 and now().day == 1 and now().hour == 0 and now().minute == 0 and now().second == 0 }}'

So the full code will look like this:


template:
  - trigger:
    - platform: template
      value_template: '{{ now().month == 1 and now().day == 1 and now().hour == 0 and now().minute == 0 and now().second == 0 }}'
    - platform: template
      value_template: "{{ states('sensor.home_average_temperature') > states('sensor.home_yearly_max_average_temperature') }}"
    sensor:
      - name: Home - Yearly max average temperature
        unique_id: home_yearly_max_average_temperature
        unit_of_measurement: "°C"
        device_class: temperature
        icon: mdi:thermometer-chevron-up
        state: "{{ states('sensor.home_average_temperature')}}"
        attributes:
          datetime: "{{ now() }}"

  - trigger:
    - platform: template
      value_template: '{{ now().month == 1 and now().day == 1 and now().hour == 0 and now().minute == 0 and now().second == 0 }}'
    - platform: template
      value_template: "{{ states('sensor.home_average_temperature') < states('sensor.home_yearly_min_average_temperature') }}"
    sensor:
      - name: Home - Yearly min average temperature
        unique_id: home_yearly_min_average_temperature
        unit_of_measurement: "°C"
        device_class: temperature
        icon: mdi:thermometer-chevron-down
        state: "{{ states('sensor.home_average_temperature')}}"
        attributes:
          datetime: "{{ now() }}"

In both cases you probably should set the initial value manually (Developer Tools > States) otherwise you will have to wait for a new month/year to start getting this working.

3 Likes

Your template is a great idea

I’m currently testing it. The trigger for 00:00:00 works perfectly but not the one that compares the data with each other.

I’ve tested it in the development tool and I’ve got the sorted feedback.
I’ve also created an automated system that notifies me and this time the trigger doesn’t work. Only the 00:00:00 trigger works.

Here are the details of the automaton I’m using as a starting point
Perhaps you could give me some advice?

alias: Test température minimum
description: ""
trigger:
  - platform: template
    value_template: >-
      {{ states('sensor.sonde_cour_temperature') <
      states('sensor.stats_cour_temperature_min_jour') }}
  - platform: time
    at: "00:00:00"
condition: []
action:
  - service: notify.mobile_app_huawei
    data:
      message: Validation température minimum
mode: single

That was planned to work when changing the value on itself, not for an automation.
But anyhow, what do you have when using this in Developer Tools > Templates?

{{ states('sensor.sonde_cour_temperature') }}
{{ states('sensor.stats_cour_temperature_min_jour') }}

I’ve found this to not work consistently.
If the temp hits a high or a low for the period, it works fine. Like for the whole month of September, it has kept recording the monthly high. It peaked on Sept 7th, and has retained that value since.
However I just updated from 2023.9.2 to 2023.9.3, and now the value is undefined. (When clicking on the entity, HA says:

This entity is no longer being provided by the template integration. If the entity is no longer in use, delete it in settings.

I found the same issue with yearly and all time high. At some point it just… lost its value. However since (I think) it still sorta knows what the value was, until it hits a higher number, or the reset (Jan 1st for the yearly), it won’t update and will remain unavailable.
This is my template for the monthly. The yearly/all time are similar just with a different, or no reset trigger)

- trigger:
    - platform: template
      value_template: '{{ now().day == 1 and now().hour == 0 and now().minute == 0 and now().second == 0 }}'
    - platform: template
      value_template: "{{ states('sensor.gw1100b_temp') > states('sensor.outdoor_temperature_max_monthly') }}"
    sensor:
      - name: "Outdoor Temperature Max (Monthly)"
        unique_id: outdoor_temperature_max_monthly
        unit_of_measurement: "°F"
        device_class: temperature
        icon: mdi:thermometer-chevron-up
        state: "{{ states('sensor.gw1100b_temp') }}"
        attributes:
          datetime: "{{ now() }}"

The monthly low (and yearly/all time) are working fine as it looks like we regularly hit an update on that. (Most recently Sept 17th)
Is there something in HA that stops providing the sensor after x days because it hasn’t had an updated value in a while? (In which case, templates like this would not work for monthly/yearly/all time stats)
Or is there a way to force these to be retained over restarts?

1 Like

Automation is only for debugging time.
Thanks to your feedback I realise that I had renamed {{ states(‘sensor.stats_cour_temperature_min_jour’) }}

Now the automaton is working, I’m going to modify the template accordingly. Normally everything should work normally

Thanks for your feedback

1 Like

Hello @JvdMaat

I wonder if, for such long durations, you shouldn’t use a statistical map instead. It could be more solid, but you wouldn’t have an entity anymore.

1 Like

The end goal is to have these values display on a card. (to have an overview of yearly, monthly high/low, etc). And potentially at some point to compare last year’s high/low to this year’s for each month.

As @Percherie mentioned, a statistic sensor should work better in this case.
Normal template sensors won’t store data for that long.

How would I go about implementing that? Any suggestions?

You can create Statistic Card - Home Assistant

And chose min/max and période

@EdwardTFN The statistical map is not an entity that can be reused for calculations or other purposes.

Perhaps the template could include SQL integration to retrieve the last known value. This would make it possible to withstand a restart

Example where I need to retrieve the penultimate known value of the pH of the water even if the entity is unavailable.
The automaton is limited to 1 from_state. Thanks to SQL, I can manipulate several previous values for the same trigger

SELECT s.state_id, s.state, s.last_updated_ts, s.old_state_id
FROM states s, states_meta m
WHERE s.metadata_id = m.metadata_id
  -- Nom de l'entitée à suivre
  AND m.entity_id = 'sensor.spa_flipr_ph'
  AND s.state <> 'unavailable'
ORDER BY
  last_updated_ts DESC
LIMIT 1,1

This would be a patch until HA one day knows how to retain values and automations after a system upgrade.

I used the Statistics card, and that works, but I don’t like the formatting:
image
Very large compared to what I had, and does not list the date it happened:
image
But at least it works… So there’s that.
For those of you wanting to go that route, here’s my code:

type: grid
square: false
columns: 1
cards:
  - type: statistic
    entity: sensor.gw1100b_temp
    name: Today's high
    period:
      calendar:
        period: day
    stat_type: max
  - type: statistic
    entity: sensor.gw1100b_temp
    name: Yesterday's high
    period:
      calendar:
        period: day
        offset: -1
    stat_type: max
  - type: statistic
    entity: sensor.gw1100b_temp
    name: Today's low
    period:
      calendar:
        period: day
    stat_type: min
  - type: statistic
    entity: sensor.gw1100b_temp
    name: Yesterday's low
    period:
      calendar:
        period: day
        offset: -1
    stat_type: min
  - type: statistic
    entity: sensor.gw1100b_temp
    name: This month's high
    period:
      calendar:
        period: month
    stat_type: max
  - type: statistic
    entity: sensor.gw1100b_temp
    name: Last month's high
    period:
      calendar:
        period: month
        offset: -1
    stat_type: max
  - type: statistic
    entity: sensor.gw1100b_temp
    name: This month's low
    period:
      calendar:
        period: month
    stat_type: min
  - type: statistic
    entity: sensor.gw1100b_temp
    name: Last month's low
    period:
      calendar:
        period: month
        offset: -1
    stat_type: min
  - type: statistic
    entity: sensor.gw1100b_temp
    name: All time high
    period:
      fixed_period:
        start: '2023-05-29T00:00:00.000Z'
    stat_type: max
  - type: statistic
    entity: sensor.gw1100b_temp
    name: All time low
    period:
      fixed_period:
        start: '2023-05-29T00:00:00.000Z'
    stat_type: min

(Note for my all time high and low I have a start date, as I have some bad data the days prior to that. (outside thermometer sitting in sun while I was looking for a good placement location, so it reached over 100)

Instead I turned to my trusty NodeRed and coded a flow that uses my outdoor thermometer sensor as a trigger to check if we reach a new high/low.
Here’s the code you can import into NodeRed to get this setup. You just have to update this to your sensor and HA server:
(I pasted the code in two replies as it exceeded the character limit. Just combine them both and import into NodeRed)

It basically waits for the sensor to update, then pulls all the current high/low values (in series. I plan on fixing this with a Trigger node and a set delay; this is very much a v1.0), then goes through a function that checks if it’s higher or lower than the current daily high/low, and if it is, sets the new value and then moves on to weekly, etc. (so if it’s not higher/lower, it exists as that means it won’t be a weekly/monthly/yearly low/high).
There’s a codeblock in the function that initializes the values (as they start of as NaN (undefined)). Just uncomment that block, have it update once, and re-comment it out.
And then there’s an Inject node that runs daily at midnight to reset the values. Resets the daily values anytime it hits, and runs a function to see if it’s Monday (Day 1), 1st day of month, or first day of the year.
Just got this setup today, and it seems to be working, and hopefully will retain.
Only downside is that the Last Changed value is in UTC.
image
(I use a custom card for that, as the regular secondary info shows “4 days ago” instead of an actual date). Here’s the code:

  - entity: sensor.outdoor_temp_max_today
    name: Today's High
    type: custom:secondaryinfo-entity-row
    secondary_info: '[[ {entity}.last_changed ]]'

UPDATE. And it broke. Had to restart HA due to an integration issue, and all the sensors are now unavailable. So these sensors from NodeRed also do not carry over through a reboot. I can probably store them in NR as globals… And then if they come back as NaN, restore what I had stored. That would keep the values, but not the date. That would need to be a separate attribute. But again, that feels very hacky and not quite the right way to go about doing this. (And also if my docker host reboots, both HA and NR will lose the values)

I think I have finally found the … A solution.
I’m using nodered, and using this: Preserving variables in NodeRED - NotEnoughTech to store permanent variables. It’s convoluted. But it seems to work through HA and NodeRed reboots
I’m not going to share the flow. If you’re really interested, let me know and I can give you an export.
But here’s the gist:

  • Upon temp state change
  • Get the previous min and maxes for today/week/month/etc, and also get the full entity (as I save the date it occurred in an attribute)
  • I set the date from each entity attribute to a variable:
msg.mintodaydate = msg.mintodayentity.attributes.date;
  • Then I use isNaN() on each temp. If it is not a number (ie, undefined), I read from persistent storage, and if not there (ie, very first run), I set it to current temp, else I restore values since HA obviously lost them due to a reboot/update:
if (isNaN(msg.mintoday)) {
    tmpTemp = flow.get("TempMinToday", "persistent");
    if (isNaN(tmpTemp)) {
        msg.mintoday = msg.current;
    }
    else {
        msg.mintoday = tmpTemp;
        msg.mintodaydate = flow.get("TempMinTodayDate", "persistent");
    }
}
  • Then I do the min/max check, and overwrite variables if they have changed:
var d=new Date()
var timestamp = d.toLocaleString();

if (msg.current < msg.mintoday) {
    msg.mintoday = msg.current;
    msg.mintodaydate = timestamp;
    flow.set("TempMinToday", msg.current, "persistent");
    flow.set("TempMinTodayDate", timestamp, "persistent");
    if (msg.current < msg.minweek) {

And finally I set all the entities in HA with the Attribute Key for the date:
image

1 Like

that sounds quiet interesting, I am interested in the flow for Node-Red.

My goal is to monitor the minimum and maxium temperature over the calendar-year. for this purpose I use the statistics history which works fine. However I also want to see on which date the two temperatures were registered. Does your flow outputs the temperature AND date in one entity which is probably visible in your lovelace-dashboard?

here are my test-entitites. the temperatures arent representative as I configured them a couple of weeks ago and in Switzerland the higest temp was around 36C.

Yes, the entity will have a Date attribute which has the date and time (in local timezone):


This is what the card looks like:
image
(I use a custom secondary info entity row component: GitHub - custom-cards/secondaryinfo-entity-row: Custom entity row for HomeAssistant, providing additional types of data to be displayed in the secondary info area of the Lovelace Entities card)
I think you should be able to access the flow here: https://github.com/JvdMaat/shared/blob/d33b5f26b9e2ef142b339e96d8c819fd1a11dc57/HA%20Low-High%20Temp%20Persistent

thanks a lot! I could import the flow into Node-Red. how did you configure the sensors like sensor.outdoor_temp_min_today and temp max today? I guess these are template sensors or history_stats sensor?

I have a weather-station which reports the actual temperature as a base for further processing of the data.

would appreciate to get some additional information in order to replicate the sensors on my instance.

Ok, here’s a high level overview. You’ll need to fix a bunch of things to get this to work for you.


On the image above, all the min/max sensors get defined on the right. So NodeRed is the one creating the sensors in HA. If you want to rename them, just update those 10 sensors on the right.
You would probably want to update all of them with your HA server. (This goes for all the Blue nodes in that screenshot). Open them, and make sure the Server is pointing to your server. (Since the node was exported with my HA server ID):
image
You do not need to edit the 8 reset ones (in the middle at the bottom). Those are duplicates from the ones on the right.
You just have to edit them:
image
then:
image
(It’s a two-step process)
If you do rename the sensors, make sure you update them in the Get nodes (middle top) as well. (No need to update the reset ones, cause again, those are the same as the ones on the right and update in sync)
And lastly you’d want to update the entry node (Outdoor Temp) and the reset node (Current Temp) to use the sensor you want to monitor. All the functions just reference variables, so you should be all set.

Oh, and make sure you have enabled flow saving: Preserving variables in NodeRED - NotEnoughTech. I called mine persistent. If you name yours something different, update all the “persistent” entries in the functions to the name of your disk storage. This is my settings.js for NodeRed:
image
That will save the variables over NodeRed reboots. So if HA, NodeRed, or your whole docker server restart, the values will be stored and restored upon next run.
Good luck!

thanks a lot for your efforts, appreciate that! thats a great sunday-afternoon project, I have to think into it in order to get it working on my instance.

I uploaded a new JSON file for the NodeRed high/low. There was a bug in the reset code. Please grab the new version: https://github.com/JvdMaat/shared/blob/82b4663daca6314be80b3a8e11b647fcc49d63c9/HA%20Low-High%20Temp%20Persistent

Hi,
the idea to put the min and max temperature into the configuration.yaml is really nice, but I get the following errors when checking configuration:

Invalid config for ‘sensor’ at configuration.yaml, line 248: required key ‘platform’ not provided
Invalid config for ‘sensor’ at configuration.yaml, line 263: required key ‘platform’ not provided

It looks like the code from @EdwardTFN
What is wrong with my code ?

(line 248)
  - trigger:
      - platform: template
        value_template: "{{ states('sensor.aussen_thermometer_temperatur') > states('sensor.temp_max') }}"
      - platform: time
        at: "00:00:00"
    sensor:
      - name: Temp Max
        unique_id: temp_max
        unit_of_measurement: "°C"
        device_class: temperature
        icon: mdi:thermometer-chevron-up
        state: "{{ states('sensor.aussen_thermometer_temperatur')}}"
        attributes:
          datetime: "{{ now() }}"

(line 263)
  - trigger:
      - platform: time
        at: "00:00:00"
      - platform: template
        value_template: "{{ states('sensor.aussen_thermometer_temperatur') < states('sensor.temp_min') }}"
    sensor:
      - name: Temp Min
        unique_id: temp_min
        unit_of_measurement: "°C"
        device_class: temperature
        icon: mdi:thermometer-chevron-down
        state: "{{ states('sensor.aussen_thermometer_temperatur')}}"
        attributes:
          datetime: "{{ now() }}"

My HA version is 2024.1.5 / 11.4

Do you have the template: before all this code?

Something like this:

template:
  - trigger:
      - platform: template
        value_template: "{{ states('sensor.aussen_thermometer_temperatur') > states('sensor.temp_max') }}"
      - platform: time
        at: "00:00:00"
    sensor:
      - name: Temp Max
        unique_id: temp_max
        unit_of_measurement: "°C"
        device_class: temperature
        icon: mdi:thermometer-chevron-up
        state: "{{ states('sensor.aussen_thermometer_temperatur')}}"
        attributes:
          datetime: "{{ now() }}"

  - trigger:
      - platform: time
        at: "00:00:00"
      - platform: template
        value_template: "{{ states('sensor.aussen_thermometer_temperatur') < states('sensor.temp_min') }}"
    sensor:
      - name: Temp Min
        unique_id: temp_min
        unit_of_measurement: "°C"
        device_class: temperature
        icon: mdi:thermometer-chevron-down
        state: "{{ states('sensor.aussen_thermometer_temperatur')}}"
        attributes:
          datetime: "{{ now() }}"
1 Like