Hi everyone,
I was looking for a 24h precipitation forecast and display it just like the excellent card of @aex351 Neerslag Card (rain forecast) (Buienalarm and/or Buienradar).
So I came up with this.
Just follow the steps.
STEP 1
Get the latitude and longitude of your location.
STEP 2
Set up sensors in your configuration.yaml
file.
Buienalarm
- Replace
<lat-2-decimals>
and<lon-2-decimals>
with your values. scan_interval
is set to 1800 seconds = 30 minutes.
command_line:
- sensor:
name: weather_buienalarm_hours
command: python3 -c "import requests; response = requests.get('https://api.meteoplaza.com/buienalarm/v1/timeseries24/<lat-2-decimals>/<lon-2-decimals>',headers={'Cache-Control':'no-cache'}).text; print(response.replace('\r\n',' '));"
unique_id: 1704039709
json_attributes:
- data
value_template: "last_changed: {{states.sensor.weather_buienalarm_hours.last_changed | default(now())}}"
scan_interval: 1800
Buienradar
- Replace
<lat-3-decimals>
and<lon-3-decimals>
with your values. scan_interval
is set to 1800 seconds = 30 minutes.
command_line:
- sensor:
name: weather_buienradar_hours
command: python3 -c "import requests; response = requests.get('https://graphdata.buienradar.nl/3.0/forecast/geo/Rain24Hour?lat=<lat-3-decimals>&lon=<lon-3-decimals>',headers={'Cache-Control':'no-cache'}).text; data = '{\"data\":'+response.replace('\r\n',' ')+'}'; print(data);"
unique_id: 1704039881
json_attributes:
- data
value_template: "last_changed: {{states.sensor.weather_buienradar_hours.last_changed | default(now())}}"
scan_interval: 1800
Old sensors
For 24h data from buienalarm, which is provided by meteoserver.nl, you need an API key. Go to Meteoserver.nl and register a free account. On your account page you will find your API key. They offer 500 free request per month.
Buienalarm
If you don’t have an API key, go back to step 1 (you do not pass GO).
- For Holland, Belgium and Luxembourg the link start with
https://data.meteoserver.nl/api/uurverwachting.php
.
For other countries in Europe change it tohttps://data.meteoserver.nl/api/uurverwachting_gfs.php
. - Replace
<lat-3-decimals>
,<lon-3-decimals>
and<your-key>
with your values. scan_interval
is set to 7200 seconds = 2 hours. When you go lower than 5.357 seconds, you will exceed the 500 free requests.
sensor:
- platform: command_line
command: python3 -c $'import requests\nimport json\nimport random\nresponse=requests.get("https://data.meteoserver.nl/api/uurverwachting.php?lat=<lat-3-decimals>&long=<lon-3-decimals>&key=<your-key>&c="+str(random.randint(0,999999999999999)))\njx=response.json()\njh = []\nfor d in jx["data"]:\n jh.append({"tijd":d["tijd"],"neersl":d["neersl"]})\njx["data"]=jh\ndata={"data":jx}\nprint(json.dumps(data,separators=(",",":")))'
name: weather_buienalarm_hourly
json_attributes:
- data
value_template: 'last_changed: {{states.sensor.weather_buienalarm_hourly.last_changed | default(now())}}'
scan_interval: 7200
unique_id: 30adbaa8495152c67094a485fce3698d2d80c3aba876bb65ed1e996d65d6df72
Buienradar
- Change
<lat-2-decimals>
and<lon-2-decimals>
to your values. scan_interval
is set to 1800 seconds = 30 minutes.
sensor:
- platform: command_line
command: python3 -c $'import requests\nimport json\nimport random\nresponse=requests.get("https://forecast.buienradar.nl/2.0/forecast/?lat=<lat-2-decimals>&lon=<lon-2-decimals>&c="+str(random.randint(0,999999999999999)))\njx=response.json()\njx["days"]=jx["days"][:2]\nfor d in jx["days"]:\n if "hours" in d:\n jh=[]\n for h in d["hours"]:\n jh.append({"datetime":h["datetime"],"datetimeutc":h["datetimeutc"],"precipitationmm":h["precipitationmm"]})\n d["hours"]=jh\ndata={"data":jx}\nprint(json.dumps(data,separators=(",",":")))'
name: weather_buienradar_hourly
unique_id: 84f51bd539d6ea72ccbb0296847ed59cdfe67778b714bdf298793957301ba0d2
json_attributes:
- data
value_template: 'last_changed: {{states.sensor.weather_buienradar_hourly.last_changed | default(now())}}'
scan_interval: 1800
STEP 3
To display the graph you need the ApexCharts card - A highly customizable graph card by @RomRider.
Change <your-sensor>
(third line) with your hourly forecast sensor.
The data_generator
starts with some JS removing timepoints that have already passed.
type: custom:apexcharts-card
series:
- entity: sensor.weather_buienalarm_hours
name: buienalarm
color: rgb(3, 170, 244)
data_generator: >
var input=entity.attributes.data;var
out=[];input.map((entry,index)=>{if(new Date(entry.time)>new
Date()){out.push([new Date(entry.time),entry.precipitationrate])}});return
out.slice(0,22);
- entity: sensor.weather_buienradar_hours
name: buienradar
color: rgb(3, 150, 244)
data_generator: >
var input = entity.attributes.data.forecasts;var
out=[];input.map((entry,index)=>{if(new Date(entry.dateTime)>new
Date()){out.push([new Date(entry.dateTime),entry.dataValue])}});return
out.slice(0,22);
header:
show: true
title: 24h precipitation forecast
span:
start: minute
graph_span: 24h
all_series_config:
stroke_width: 3
unit: mm/u
type: area
opacity: 0.2
show:
offset_in_name: false
apex_config:
chart:
height: 250px
legend:
show: false
xaxis:
tooltip: false
border:
show: true
labels:
format: HH:mm
rotate: -45
rotateAlways: true
style:
fontSize: 10px
yaxis:
- min: 0
max: |
EVAL:function (max) {
window.chart24u_max = (Math.round(max*2)/2) + 0.5;
return window.chart24u_max;
}
tickAmount: 5
title:
text: rain (mm/u)
grid:
xaxis:
lines:
show: true
tooltip:
enabled: true
shared: true
x:
show: true
format: ddd d MMM HH:mm
'y':
formatter: |
EVAL:function (y) {
return y.toFixed(1)
}
annotations:
position: back
yaxis:
- 'y': 0.4
label:
text: 'EVAL:(window.chart24u_max > 0.4 ? ''Licht'' : '''')'
style:
background: '#666'
color: '#FFF'
borderColor: 'EVAL:(window.chart24u_max > 0.4 ? ''#000'' : ''none'')'
- label:
text: 'EVAL:(window.chart24u_max > 2 ? ''Matig'' : '''')'
style:
background: '#666'
color: '#FFF'
'y': 2
borderColor: 'EVAL:(window.chart24u_max > 2 ? ''#000'' : ''none'')'
- label:
text: 'EVAL:(window.chart24u_max > 5 ? ''Zwaar'' : '''')'
style:
background: '#666'
color: '#FFF'
'y': 5
borderColor: 'EVAL:(window.chart24u_max > 5 ? ''#000'' : ''none'')'
card_mod:
style: |
ha-card #graph {
margin: 3px 10px;
}
ha-card .apexcharts-canvas * {
font-family: var(--ha-card-font-family, inherit) !important;
}
ha-card #header__title {
color: var(--ha-card-header-color, --primary-text-color);
font-size: var(--ha-card-header-font-size, 24px);
padding-top: 10px;
font-weight: normal;
}
ha-card .apexcharts-tooltip * {
line-height: 0.5;
font-size: 12px !important;
}
Old data_generator
- entity: weather.<your-sensor>_hourly
name: weather
color: rgb(3, 170, 244)
data_generator: >
var today=new Date();var last=new
Date(Date.parse(today.getFullYear()+'-'+String(today.getMonth()+1).padStart(2,'0')+'-'+String(today.getDate()).padStart(2,'0')+'T'+String(today.getHours()+1).padStart(2,'0')+':00:00'));var
input=entity.attributes.forecast;for(var entry of input){if(last>new
Date(entry.datetime)){input.shift()}else{break}};return
input.map((entry)=>{return[new Date(entry.datetime),entry.precipitation]})
- entity: sensor.weather_buienalarm_hourly
name: buienalarm
color: rgb(3, 150, 244)
data_generator: >
var today=new Date();var last=new
Date(Date.parse(today.getFullYear()+'-'+String(today.getMonth()+1).padStart(2,'0')+'-'+String(today.getDate()).padStart(2,'0')+'T'+String(today.getHours()+1).padStart(2,'0')+':00:00'));var
input=entity.attributes.data.data;for(var entry of input){if(last>new
Date(entry.tijd*1000)){input.shift()}else{break}}return
input.map((entry)=>{return[new Date(entry.tijd*1000),entry.neersl]})
- entity: sensor.weather_buienradar_hourly
name: buienradar
color: rgb(3, 130, 244)
data_generator: >
var today=new Date();var last=new
Date(Date.parse(today.getFullYear()+'-'+String(today.getMonth()+1).padStart(2,'0')+'-'+String(today.getDate()).padStart(2,'0')+'T'+String(today.getHours()+1).padStart(2,'0')+':00:00'));var input= entity.attributes.data.days[0].hours.concat(entity.attributes.data.days[1].hours); for(var
entry of input){if(last>new
Date(Date.parse(entry.datetime))){input.shift()}else{break}}return
input.map((entry)=>{return[new
Date(Date.parse(entry.datetime)),entry.precipitationmm]})
This is the first version, that has been tested by my whole self and that’s it. So expect errors or bugs, let me know if they occur.
UPDATE 20-03-2023
I encountered the following error: “State attributes for sensor.weather_buienradar_hourly exceed maximum size of 16384 bytes. This can cause database performance issues; Attributes will not be stored”.
I updated the command line sensors, to truncate the JSON strings before storing them. I applied the changes above.
UPDATE 03-12-2023
You can find the configuration for a 2 hour forecast here.
UPDATE 03-01-2024
Sensors updated to current data source.
– Ingrid