I’ve created a trigger template to set a sensor for the max temperature during the day based on attributes from the met office entity. This works fine but I can’t help but think there is a neater way of writing the template which sets the sensor state.
template:
- trigger:
- platform: time_pattern
# This will update every morning at 06:05
hours: 06
minutes: 05
sensor:
# Loop the forecasts and if the datetime is less than today at 21:00 get the max temp for those results
- name: "Max Temp"
state: >-
{%- set ns = namespace(temp=0) %}
{% for forecast in states.weather.met_office_hunslet_3_hourly.attributes.forecast -%}
{% if as_timestamp(forecast.datetime) < as_timestamp(today_at("21:00")) %}
{% if forecast.temperature > ns.temp | int %}
{%- set ns.temp = forecast.temperature %}
{% endif -%}
{% endif -%}
{%- endfor %}
{{ ns.temp }}
unit_of_measurement: "C"
I’m thinking the state template section could be improved to not use a for loop - this doesn’t work but I was thinking something along the lines:
Since you’re taking this “snapshot” at the same time everyday, the number of forecasts should be the same every time… so you can use slice to sub divide your list of forecasts so that only the ones you are interested in are in the first grouping, then get the max of those. You will likely need to play with the value of “slice”…
{{ state_attr('weather.met_office_hunslet_3_hourly', 'forecast') | map(attribute='temperature') | slice(4)| list | first | max }}
@Didgeridrew that wont work because it’s utc compared to now. You’d need to compare in the correct tz.
This is one that compares utc formats to eachother.
{% set forcast = state_attr('weather.met_office_hunslet_3_hourly', 'forecast') | selectattr('datetime', '>=', utcnow().isoformat()) | list | first | default(none) %}
{{ forcast.temp if forcast is not none else none }}
Note: The sample in the screenshot was taken at 10am local time, so forecasts are for 09-00:00. If the sensor was triggered at 6:05, the forecasts should be for 06-21:00.
I tried that method first, but it throws a TypeError:
TypeError: '<=' not supported between instances of 'str' and 'datetime.datetime'"
In the second screenshot of my previous post, the value of datetime is also a string. However, the difference is that it’s UTC whereas yours is local time. I think that difference may determine how Home Assistant interprets the value’s type (although I don’t know why because both are convertible to datetime). It’s very clear from your screenshot that the value’s type is preserved as string and not converted to datetime.
FWIW, I’m testing this with the Environment Canada integration.
I installed the NWS integration with some random location in the NorthEast and can confirm that its datetime values are not handled as datetime objects. Comparison of the two integrations:
Also the template i provided just gets you the temperature After the supplied time. Changing it to max would be removing the |first and summing the attribute.
Am I understanding that this is a bug in the template helpers that they do not recognize valid isoformatted strings that are not in UTC? Or is it a bug that NWS does not provide it in that format? This should be put as an issue on GitHub either way.
I don’t think there’s any bug. 123 was expecting a datetime object, but the attribute was an isoformat datetime string. That is unless datetime is expected to be a datetime object, then NWS is incorrectly outputting a datetime isoformat string instead of datetime object.
Well it’s because the one attribute has the object vrs the string. Jinja can’t handle both together, it’s one or the other. If all forecast attributes are supposed to be the same across all weather domains, then it’s a bug. But when deserializing the data after a restart, it might be keeping these as strings. IIRC that’s expected behavior. I don’t know if the weather domain serializes and deserializes the states attributes on shutdown/restart in the database.