It’s a bit more complicated but you can give it a try.
I need to warn you about SMHIs API. They keep changing stuff that breaks the tags.
I don’t know if there is a more resilient way to build the yaml but it’s quite frustrating when they change the times in the API.
The first few days is more detailed but then it gets less detailed, and these times sometimes change, so instead of 8:00, they changed it to 7:00, and recently they did the same with the afternoon time.
But anyways…
First you need Node Red to get the data from SMHI.
Summary
[
{
"id": "baaeb67025c3b042",
"type": "function",
"z": "ad594fb84fe6d294",
"name": "",
"func": "var array = {};\nvar time;\nvar timestr;\n\ntime = new Date(msg.payload.approvedTime);\nvar offset = time.getTimezoneOffset(); \ntime = new Date(time.getTime() - (offset*60*1000)); \nmsg.state = time.toISOString().replace(\"T\", \" \").substring(0,16)\n\n\nfor (var index in msg.payload.timeSeries.slice(0,70)) {\n time = new Date(msg.payload.timeSeries[index].validTime);\n offset = time.getTimezoneOffset();\n time = new Date(time.getTime() - (offset * 60 * 1000)); \n timestr = time.toISOString().replace(\"T\", \" \").substring(0, 16);\n\n array[timestr] = { \"temp\": 0, \"wind\": 0, \"gust\": 0, \"nederbord\": 0, \"symbol\" : 0 };\n for (var val in msg.payload.timeSeries[index].parameters) {\n if (msg.payload.timeSeries[index].parameters[val][\"name\"] == \"t\") {\n array[timestr].temp = msg.payload.timeSeries[index].parameters[val].values[0]; // { \"temp\": Math.round(msg.payload.timeSeries[index].parameters[val].values[0]) }\n }else if (msg.payload.timeSeries[index].parameters[val][\"name\"] == \"ws\"){\n array[timestr].wind = msg.payload.timeSeries[index].parameters[val].values[0]; \n }else if (msg.payload.timeSeries[index].parameters[val][\"name\"] == \"gust\"){\n array[timestr].gust = msg.payload.timeSeries[index].parameters[val].values[0]; \n }else if (msg.payload.timeSeries[index].parameters[val][\"name\"] == \"pmean\") {\n array[timestr].nederbord = msg.payload.timeSeries[index].parameters[val].values[0]; \n } else if (msg.payload.timeSeries[index].parameters[val][\"name\"] == \"Wsymb2\") {\n array[timestr].symbol = msg.payload.timeSeries[index].parameters[val].values[0];\n }\n }\n}\nmsg.offset = offset;\nmsg.arr = array;\nreturn msg;",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 480,
"y": 160,
"wires": [
[
"3fe272e0830da4ad",
"99725a43c9239e9e"
]
]
},
{
"id": "994a4699a32ef4ec",
"type": "inject",
"z": "ad594fb84fe6d294",
"name": "",
"props": [
{
"p": "payload"
}
],
"repeat": "3600",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "str",
"x": 150,
"y": 120,
"wires": [
[
"8584052db0255346"
]
]
},
{
"id": "8584052db0255346",
"type": "http request",
"z": "ad594fb84fe6d294",
"name": "",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://opendata-download-metfcst.smhi.se/api/category/pmp3g/version/2/geotype/point/lon/[LON]/lat/[LAT]/data.json",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"senderr": false,
"x": 310,
"y": 120,
"wires": [
[
"baaeb67025c3b042"
]
]
},
{
"id": "99725a43c9239e9e",
"type": "debug",
"z": "ad594fb84fe6d294",
"name": "debug 13",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 640,
"y": 80,
"wires": []
},
{
"id": "3fe272e0830da4ad",
"type": "ha-sensor",
"z": "ad594fb84fe6d294",
"name": "smhi hourly",
"entityConfig": "aeb70bcf74c928d9",
"version": 0,
"state": "state",
"stateType": "msg",
"attributes": [
{
"property": "hourly",
"value": "arr",
"valueType": "msg"
}
],
"inputOverride": "allow",
"outputProperties": [],
"x": 670,
"y": 180,
"wires": [
[]
]
},
{
"id": "aeb70bcf74c928d9",
"type": "ha-entity-config",
"server": "4bbca37b.1700ec",
"deviceConfig": "",
"name": "sensor config for smhi hourly",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "smhi hourly"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": ""
},
{
"property": "device_class",
"value": ""
},
{
"property": "unit_of_measurement",
"value": ""
},
{
"property": "state_class",
"value": ""
}
],
"resend": true,
"debugEnabled": false
},
{
"id": "4bbca37b.1700ec",
"type": "server",
"name": "Home Assistant",
"version": 5,
"addon": true,
"rejectUnauthorizedCerts": true,
"ha_boolean": "y|yes|true|on|home|open",
"connectionDelay": true,
"cacheJson": true,
"heartbeat": false,
"heartbeatInterval": 30,
"areaSelector": "friendlyName",
"deviceSelector": "friendlyName",
"entitySelector": "friendlyName",
"statusSeparator": "at: ",
"statusYear": "hidden",
"statusMonth": "short",
"statusDay": "numeric",
"statusHourCycle": "h23",
"statusTimeFormat": "h:m",
"enableGlobalContextStore": true
}
]
In the http request node there is a URL https://opendata-download-metfcst.smhi.se/api/category/pmp3g/version/2/geotype/point/lon/[LON]/lat/[LAT]/data.json
Replace the lat and lon values with yours.
This gives the smhi hourly sensor.
The automation to update the tag is the following mess.
I have left the URL to my php page that gives the time. If you want to use a own php page then just replace that link at the end.
Summary
alias: Väder köksdisplay - Prognos
description: ""
triggers:
- hours: /3
trigger: time_pattern
- hours: /5
trigger: time_pattern
conditions: []
actions:
- target:
entity_id:
- open_epaper_link.0000021B76F73B18
data:
background: white
rotate: 0
payload: >
{%- set ns = namespace(list = [], out=[], cnt=0 , t=0, w=0, g=0, n=0,
s=0, c=0, done=false, days=[3,72,146,222], data=[3,73,148,223]) -%}
{%- set mdi =
["","weather-sunny","weather-sunny","weather-partly-cloudy","weather-partly-cloudy","weather-cloudy","weather-cloudy","weather-fog","weather-rainy","weather-rainy","weather-pouring","weather-lightning","weather-snowy-rainy","weather-snowy-rainy","weather-snowy-rainy","weather-snowy","weather-snowy-heavy","weather-snowy-heavy","weather-rainy","weather-rainy","weather-pouring","weather-lightning","weather-snowy-rainy","weather-snowy-rainy","weather-snowy-rainy","weather-snowy","weather-snowy-heavy","weather-snowy-heavy"]
-%}
{%- for s in state_attr('sensor.smhi_hourly', 'hourly') -%}
{%- if (s[0:10] | as_datetime).date() == now().date() + timedelta( days =1) and s[-5:] == "07:00" -%}
{%- set ns.t = 0 -%}
{%- set ns.w = 0 -%}
{%- set ns.g = 0 -%}
{%- set ns.n = 0 -%}
{%- set ns.s = 0 -%}
{%- set ns.c = 0 -%}
{%- endif -%}
{%- if s[11:13] | int >= 7 and s[11:13] | int <= 12 -%}
{%- set ns.t = ns.t + state_attr('sensor.smhi_hourly', 'hourly')[s]["temp"] -%}
{%- set ns.w = ns.w + state_attr('sensor.smhi_hourly', 'hourly')[s]["wind"] -%}
{%- set ns.g = ns.g + state_attr('sensor.smhi_hourly', 'hourly')[s]["gust"] -%}
{%- set ns.n = ns.n + state_attr('sensor.smhi_hourly', 'hourly')[s]["nederbord"] -%}
{%- set ns.s = ns.s + state_attr('sensor.smhi_hourly', 'hourly')[s]["symbol"] -%}
{%- set ns.c = ns.c + 1 -%}
{%- elif s[11:13] | int >= 13 and s[11:13] | int <= 18 -%}
{%- set ns.t = ns.t + state_attr('sensor.smhi_hourly', 'hourly')[s]["temp"] -%}
{%- set ns.w = ns.w + state_attr('sensor.smhi_hourly', 'hourly')[s]["wind"] -%}
{%- set ns.g = ns.g + state_attr('sensor.smhi_hourly', 'hourly')[s]["gust"] -%}
{%- set ns.n = ns.n + state_attr('sensor.smhi_hourly', 'hourly')[s]["nederbord"] -%}
{%- set ns.s = ns.s + state_attr('sensor.smhi_hourly', 'hourly')[s]["symbol"] -%}
{%- set ns.c = ns.c + 1 -%}
{%- endif -%}
{%- if (s[0:10] | as_datetime).date() == now().date() + timedelta( days =1) -%}
{%- if ns.c > 0 -%}
{%- if s[-5:] == "12:00" -%}
{%- set ns.list = ns.list + [{"date": s[0:10], "time": "morning", "t":(ns.t/ns.c)|round(0), "w": (ns.w/ns.c)|round(0), "g": (ns.g/ns.c)|round(0), "n": (ns.n/ns.c)|round(1), "s": (ns.s/ns.c)| round(0) }] -%}
{%- set ns.t = 0 -%}
{%- set ns.w = 0 -%}
{%- set ns.g = 0 -%}
{%- set ns.n = 0 -%}
{%- set ns.s = 0 -%}
{%- set ns.c = 0 -%}
{%- elif s[-5:] == "18:00" -%}
{%- set ns.list = ns.list + [{"date": s[0:10], "time": "afternoon", "t":(ns.t/ns.c)|round(0), "w": (ns.w/ns.c)|round(0), "g": (ns.g/ns.c)|round(0), "n": (ns.n/ns.c)|round(1), "s": (ns.s/ns.c)| round(0) }] -%}
{%- set ns.t = 0 -%}
{%- set ns.w = 0 -%}
{%- set ns.g = 0 -%}
{%- set ns.n = 0 -%}
{%- set ns.s = 0 -%}
{%- set ns.c = 0 -%}
{%- endif -%}
{%- endif -%}
{%- elif (s[0:10] | as_datetime).date() == now().date() + timedelta( days =2) -%}
{%- if ns.c > 0 -%}
{%- if s[-5:] == "12:00" or s[-5:] == "13:00" and ns.done == false -%}
{%- set ns.done = true -%}
{%- if s[-5:] == "12:00" -%}
{%- set ns.list = ns.list + [{"date": s[0:10], "time": "morning", "t":(ns.t/ns.c)|round(0), "w": (ns.w/ns.c)|round(0), "g": (ns.g/ns.c)|round(0), "n": (ns.n/ns.c)|round(1), "s": (ns.s/ns.c)| round(0) }] -%}
{%- else -%}
{%- set ns.list = ns.list + [{"date": s[0:10], "time": "morning", "t":(((ns.t-state_attr('sensor.smhi_hourly', 'hourly')[s]["temp"]))/ns.c)|round(0), "w": (((ns.w-state_attr('sensor.smhi_hourly', 'hourly')[s]["wind"])/(ns.c-1)))|round(0), "g": (((ns.g-state_attr('sensor.smhi_hourly', 'hourly')[s]["gust"]))/(ns.c-1))|round(0), "n": (ns.n-state_attr('sensor.smhi_hourly', 'hourly')[s]["nederbord"])|round(1), "s": ((ns.s-state_attr('sensor.smhi_hourly', 'hourly')[s]["symbol"])/ns.c)| round(0) }] -%}
{%- set ns.list = ns.list + [{"date": s[0:10], "time": "afternoon", "t":((state_attr('sensor.smhi_hourly', 'hourly')[s]["temp"])/ns.c)|round(0), "w": (state_attr('sensor.smhi_hourly', 'hourly')[s]["wind"])|round(0), "g": (state_attr('sensor.smhi_hourly', 'hourly')[s]["gust"])|round(0), "n": (state_attr('sensor.smhi_hourly', 'hourly')[s]["nederbord"])|round(1), "s": state_attr('sensor.smhi_hourly', 'hourly')[s]["symbol"] }] -%}
{%- endif -%}
{%- set ns.t = 0 -%}
{%- set ns.w = 0 -%}
{%- set ns.g = 0 -%}
{%- set ns.n = 0 -%}
{%- set ns.s = 0 -%}
{%- set ns.c = 0 -%}
{%- elif s[-5:] == "19:00" -%}
{%- set ns.list = ns.list + [{"date": s[0:10], "time": "afternoon", "t":(ns.t/ns.c)|round(0), "w": (ns.w/ns.c)|round(0), "g": (ns.g/ns.c)|round(0), "n": (ns.n/ns.c)|round(1), "s": (ns.s/ns.c)| round(0) }] -%}
{%- set ns.t = 0 -%}
{%- set ns.w = 0 -%}
{%- set ns.g = 0 -%}
{%- set ns.n = 0 -%}
{%- set ns.s = 0 -%}
{%- set ns.c = 0 -%}
{%- endif -%}
{%- endif -%}
{%- elif (s[0:10] | as_datetime).date() >= (now().date() + timedelta( days =3)) -%}
{%- if ns.c > 0 -%}
{%- if s[11:13] | int ==7 -%}
{%- set ns.list = ns.list + [{"date": s[0:10], "time": "morning", "t":(ns.t/ns.c)|round(0), "w": (ns.w/ns.c)|round(0), "g": (ns.g/ns.c)|round(0), "n": (ns.n/ns.c)|round(1), "s": (ns.s/ns.c)| round(0) }] -%}
{%- set ns.t = 0 -%}
{%- set ns.w = 0 -%}
{%- set ns.g = 0 -%}
{%- set ns.n = 0 -%}
{%- set ns.s = 0 -%}
{%- set ns.c = 0 -%}
{%- elif s[11:13] | int == 13-%}
{%- set ns.list = ns.list + [{"date": s[0:10], "time": "afternoon", "t":(ns.t/ns.c)|round(0), "w": (ns.w/ns.c)|round(0), "g": (ns.g/ns.c)|round(0), "n": (ns.n/ns.c)|round(1), "s": (ns.s/ns.c)| round(0) }] -%}
{%- set ns.t = 0 -%}
{%- set ns.w = 0 -%}
{%- set ns.g = 0 -%}
{%- set ns.n = 0 -%}
{%- set ns.s = 0 -%}
{%- set ns.c = 0 -%}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{%- for a in ns.list[0:8] -%}
{%- if a.time == "morning" -%}
{% set ns.out = ns.out +
[
{ "type": "text",
"value": ["Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag", "Söndag"][(a.date | as_datetime).weekday()],
"font": "ppb.ttf",
"x": 0 if (a.date | as_datetime).weekday() == 3 and ns.cnt == 0 else ns.days[ns.cnt] ,
"y": 2, "size": 15,
"color": "black"},
{ "type": "text",
"value": (a.n | string).replace(".", ",").replace(",0", "") ~ " mm",
"font": "ppb.ttf",
"x": ns.data[ns.cnt],
"y": 18, "size": 12,
"color": "black" if a.n == 0 else "red"},
{ "type": "text",
"value": a.w ~ "-" ~ a.g ~ " m/s",
"font": "ppb.ttf",
"x": ns.data[ns.cnt],
"y": 28, "size": 12,
"color": "red" if a.w | int > 7 or a.g |int > 10 else "black"},
{ "type": "text",
"value": a.t ~ "°",
"font": "ppb.ttf",
"x": ns.data[ns.cnt] ,
"y": 46, "size": 14,
"color": "black" if a.t >= 1 else "red"},
{"type": "icon",
"value": mdi[a.s],
"x": 25 + (73*ns.cnt),
"y": 40,
"size": 33,
"color": "black" if a.n == 0 else "red"},
] %}
{%- else -%}
{% set ns.out = ns.out +
[
{ "type": "text",
"value": (a.n | string).replace(".", ",").replace(",0", "") ~ " mm",
"font": "ppb.ttf",
"x": ns.data[ns.cnt],
"y": 76, "size": 12,
"color": "black" if a.n == 0 else "red"},
{ "type": "text",
"value": a.w ~ "-" ~ a.g ~ " m/s",
"font": "ppb.ttf",
"x": ns.data[ns.cnt],
"y": 86, "size": 12,
"color": "red" if a.w | int > 7 or a.g |int > 10 else "black"},
{ "type": "text",
"value": a.t ~ "°",
"font": "ppb.ttf",
"x": ns.data[ns.cnt],
"y": 105, "size": 13,
"color": "black" if a.t >= 1 else "red"},
{"type": "icon",
"value": mdi[a.s],
"x": 25 + (73*ns.cnt),
"y": 98,
"size": 33,
"color": "black" if a.n == 0 else "red"},
{"type": "line",
"fill": "black",
"width": 1,
"x_start": 70 + (75*ns.cnt),
"y_start": 20,
"x_end": 70 + (75*ns.cnt),
"y_end": 120}
] %}
{%- set ns.cnt = ns.cnt +1 -%}
{%- endif -%}
{%- endfor -%}
{% set ns.out = ns.out +
[
{"type": "line",
"fill": "black",
"width": 1,
"x_start": 10,
"y_start": 72,
"x_end": 282,
"y_end": 72},
{"type": "dlimg",
"url": "https://www.hoppvader.nu/hass/time.php",
"x": 281,
"y": 38,
"xsize": 12,
"ysize": 50,
"rotate": 270 }
] %}
{{ns.out }}
action: open_epaper_link.drawcustom
mode: single
And here is the portrait version with detailed today weather:
Summary
alias: Väder köksdisplay - idag
description: ""
mode: single
triggers:
- hours: /1
trigger: time_pattern
conditions: []
actions:
- target:
entity_id:
- open_epaper_link.0000021F49363B1D
data:
background: white
rotate: 270
payload: |
{%- set ns = namespace( text_list = [] ) -%}
{%- from 'SMHI_symbols.jinja' import smhi_mdi -%}
{%- for day in range(0,10) -%}
{%- if (state_attr('sensor.smhi_hourly', 'hourly')[((now().replace(minute=0) + timedelta(hours=loop.index)) | string)[0:16]]['nederbord']) >= 0.1 and (state_attr('sensor.smhi_hourly', 'hourly')[((now().replace(minute=0) + timedelta(hours=loop.index)) | string)[0:16]]['nederbord']) < 1 -%}
{%- set nederbord = (state_attr('sensor.smhi_hourly', 'hourly')[((now().replace(minute=0) + timedelta(hours=loop.index)) | string)[0:16]]['nederbord']) -%}
{%- else -%}
{%- set nederbord = (state_attr('sensor.smhi_hourly', 'hourly')[((now().replace(minute=0) + timedelta(hours=loop.index)) | string)[0:16]]['nederbord']) | round(0) -%}
{%- endif -%}
{% set temp = (state_attr('sensor.smhi_hourly', 'hourly')[((now().replace(minute=0) + timedelta(hours=loop.index)) | string)[0:16]]['temp']) | round(0) %}
{% set wind = (state_attr('sensor.smhi_hourly', 'hourly')[((now().replace(minute=0) + timedelta(hours=loop.index)) | string)[0:16]]['wind']) | round(0) %}
{% set time = ("0"~(now() + timedelta(hours=loop.index)).hour)[-2:] ~":00" %}
{%- set ns.text_list = ns.text_list +
[{ "type": "rectangle",
"x_start": 1,
"x_end": 127,
"y_start": 1 + (29*day),
"y_end": 30 + (29*day),
"width": 2,
"fill": "white",
"outline": "black"}] +
[{ "type": "text",
"value": time,
"font": "ppb.ttf",
"x": 5,
"y": 5 + (29*day),
"size": 12,
"color": "black"} ] +
[{ "type": "text",
"value": wind~"m/s",
"font": "ppb.ttf",
"x": 5,
"y": 15 + (29*day),
"size": 12,
"color": iif( wind > 7, "red", "black")} ] +
[{ "type": "icon",
"value": smhi_mdi(((now() + timedelta(hours=loop.index)).replace(minute=0) | string)[0:16]),
"y": (29*day),
"x": 46,
"size": 29,
"color": iif( nederbord > 0, "red", "black")} ] +
[{ "type": "text",
"value": temp~"°C",
"font": "ppb.ttf",
"x": 77,
"y": 5 + (29*day),
"size": 12,
"color": iif( temp <= 0, "red", "black")} ] +
[{ "type": "text",
"value": nederbord~"mm",
"font": "ppb.ttf",
"x": 77,
"y": 17 + (29*day),
"size": 12,
"color": iif( nederbord > 0, "red", "black")} ] -%}
{%- endfor -%}
{{ ns.text_list }}
enabled: true
action: open_epaper_link.drawcustom
and here is the macro that needs to be placed in /homeassistant/custom_templates/SMHI_symbols.jinja
:
Summary
{%- macro smhi_mdi(datetime) -%}
{%- set json = ["","weather-sunny","weather-sunny","weather-partly-cloudy","weather-partly-cloudy","weather-cloudy","weather-cloudy","weather-fog","weather-rainy","weather-rainy","weather-pouring","weather-lightning","weather-snowy-rainy","weather-snowy-rainy","weather-snowy-rainy","weather-snowy","weather-snowy-heavy","weather-snowy-heavy","weather-rainy","weather-rainy","weather-pouring","weather-lightning","weather-snowy-rainy","weather-snowy-rainy","weather-snowy-rainy","weather-snowy","weather-snowy-heavy","weather-snowy-heavy"] -%}
{{ json[state_attr('sensor.smhi_hourly', 'hourly')[datetime]["symbol"]] }}
{%- endmacro -%}
{% macro smhi_temp(datetime) %}
{{ state_attr('sensor.smhi_hourly', 'hourly')[datetime]["temp"] }}
{% endmacro %}
I’m not sure I use the smhi_temp macro. But the other one is used