Visar väderprognosen verkligen rätt? För att följa upp en prognos måste den sparas när den är aktuell och sen jämföras med den verkliga temperaturen. För att det ska bli lite effektivt måste det automatiseras. Ett script hämtar prognoser varje timme och den verkliga temperaturen var 10:e minut.

Bilden ovan visar SMHI och YR:s väderprognoser tillsammans med verklig utomhustemperatur de senaste dagarna och prognoserna för de kommande dagarna.

Detta diagram visar istället FELET mellan prognoserna och verklig utomhustemperatur. Den prognos med minsta medelfel är alltså bäst.
Hur data samlas in
Det går att hämta väderprognos från yr.no genom:curl -A "MyTestApp/0.1 support@example.com" -s 'https://api.met.no/weatherapi/locationforecast/2.0/compact?lat=64.754&lon=20.875' |json_pp > met-no.json
Prognosdata sparas då i en .json-fil för aktuell GPS-position som angetts i anropet. Dokumentation om met.no api.
och motsvarande för SMHI, med dokumentation:curl -A -s https://opendata-download-metfcst.smhi.se/api/category/pmp3g/version/2/geotype/point/lon/20.875/lat/64.754/data.json|json_pp > smhi.json
Med hjälp av jq kan ett script läsa ut prognosdata och spara i en RRD-databas med tidsstämpel en bit in i framtiden, med YR blir det då: t08h="$(more met-no.json |jq .properties.timeseries[$hours].data.instant.details.air_temperature)"
($hours är antal timmar i förväg)
Man kan använda https://jqplay.org/ för att prova jq på en jsontext för att hitta rätt data.
Den parameter vi vill läsa är har namnet “t”.timeSeries[].validTime
ger alla tider det finns prognosdata för.more smhi.json |jq '.timeSeries[8].parameters | map(select(.name == "t"))[0].values[0]'
ger den 8:e timmens temperaturprognos.
Då [8] i ett bash-script ersätts med en $hours måste den escapas i bash, t08h="$(more smhi.json |jq '.timeSeries['"$hours"'].parameters | map(select(.name == "t"))[0].values[0]')"
Aktuell utomhustemperatur hämtas tillbaka från temperatur.nu och sparas i en egen RRD med aktuell tidsstämpel.
Alla temperaturprognoser och den verkliga utomhustemperaturen ritas i några grafer med RRDtool graph.
/usr/bin/rrdtool graph /home/lars/prognos/graph_prognosis-comp.png -D -w 1024 -h 652 -a PNG -T 10 --start -3d --end +49h --alt-autoscale \
DEF:8h=/home/lars/prognos/prognosis08.rrd:08h:AVERAGE \
DEF:24h=/home/lars/prognos/prognosis24.rrd:24h:AVERAGE \
DEF:48h=/home/lars/prognos/prognosis48.rrd:48h:AVERAGE \
DEF:72h=/home/lars/prognos/prognosis72.rrd:72h:AVERAGE \
DEF:ute=/home/lars/prognos/utetemperatur.rrd:ute:AVERAGE \
DEF:8hs=/home/lars/prognos/prognosis08smhi.rrd:08h:AVERAGE \
DEF:24hs=/home/lars/prognos/prognosis24smhi.rrd:24h:AVERAGE \
DEF:48hs=/home/lars/prognos/prognosis48smhi.rrd:48h:AVERAGE \
DEF:72hs=/home/lars/prognos/prognosis72smhi.rrd:72h:AVERAGE \
DEF:8nu=/home/lars/prognos/prognosis08.rrd:08h:AVERAGE:start=-2d:end=+1s \
DEF:24nu=/home/lars/prognos/prognosis24.rrd:24h:AVERAGE:start=-2d:end=+1s \
DEF:48nu=/home/lars/prognos/prognosis48.rrd:48h:AVERAGE:start=-2d:end=+1s \
DEF:72nu=/home/lars/prognos/prognosis72.rrd:72h:AVERAGE:start=-2d:end=+1s \
DEF:8nus=/home/lars/prognos/prognosis08smhi.rrd:08h:AVERAGE:start=-2d:end=+1s \
DEF:24nus=/home/lars/prognos/prognosis24smhi.rrd:24h:AVERAGE:start=-2d:end=+1s \
DEF:48nus=/home/lars/prognos/prognosis48smhi.rrd:48h:AVERAGE:start=-2d:end=+1s \
DEF:72nus=/home/lars/prognos/prognosis72smhi.rrd:72h:AVERAGE:start=-2d:end=+1s \
CDEF:8fel=8nu,ute,- \
CDEF:24fel=24nu,ute,- \
CDEF:48fel=48nu,ute,- \
CDEF:72fel=72nu,ute,- \
CDEF:8fels=8nus,ute,- \
CDEF:24fels=24nus,ute,- \
CDEF:48fels=48nus,ute,- \
CDEF:72fels=72nus,ute,- \
CDEF:8afel=8fel,ABS \
CDEF:24afel=24fel,ABS \
CDEF:48afel=48fel,ABS \
CDEF:72afel=72fel,ABS \
CDEF:8afels=8fels,ABS \
CDEF:24afels=24fels,ABS \
CDEF:48afels=48fels,ABS \
CDEF:72afels=72fels,ABS \
--title="Översikt väderprognoser YR&SMHI 3 Senaste dygnen och 2 dygn prognoser" \
COMMENT:"\t\t\t\t\t Aktuell \t Medel \t\t Max \t\t Min \t\t\t Aktuellt fel \t Medelfel \t ABSMedel \tMaxfel+\t Maxfel-\\n" \
LINE2:8h#FC1303EE:"8h prognos YR\t" \
--vertical-label="temperatur" \
HRULE:0#000000:"" \
GPRINT:8nu:"LAST:%2.1lf \t" \
GPRINT:8nu:"AVERAGE:%2.1lf \t" \
GPRINT:8nu:"MAX:%2.1lf \t" \
GPRINT:8nu:"MIN:%2.1lf \t\t\t\t" \
GPRINT:8fel:"LAST:%2.1lf \t\t " \
GPRINT:8fel:"AVERAGE:%2.1lf \t" \
GPRINT:8afel:"AVERAGE:%2.1lf \t" \
GPRINT:8fel:"MAX:%2.1lf \t" \
GPRINT:8fel:"MIN:%2.1lf \\n" \
LINE2:24h#FC3D03EE:"24h prognos YR\t" \
GPRINT:24nu:"LAST:%2.1lf \t" \
GPRINT:24nu:"AVERAGE:%2.1lf \t" \
GPRINT:24nu:"MAX:%2.1lf \t" \
GPRINT:24nu:"MIN:%2.1lf \t\t\t\t" \
GPRINT:24fel:"LAST:%2.1lf \t\t " \
GPRINT:24fel:"AVERAGE:%2.1lf \t" \
GPRINT:24afel:"AVERAGE:%2.1lf \t" \
GPRINT:24fel:"MAX:%2.1lf \t" \
GPRINT:24fel:"MIN:%2.1lf \\n" \
LINE2:48h#FC6B03EE:"48h prognos YR\t" \
GPRINT:48nu:"LAST:%2.1lf \t" \
GPRINT:48nu:"AVERAGE:%2.1lf \t" \
GPRINT:48nu:"MAX:%2.1lf \t" \
GPRINT:48nu:"MIN:%2.1lf \t\t\t\t" \
GPRINT:48fel:"LAST:%2.1lf \t\t " \
GPRINT:48fel:"AVERAGE:%2.1lf \t" \
GPRINT:48afel:"AVERAGE:%2.1lf \t" \
GPRINT:48fel:"MAX:%2.1lf \t" \
GPRINT:48fel:"MIN:%2.1lf \\n" \
LINE2:8hs#030BFCEE:"8h prognos SMHI\t" \
GPRINT:8nus:"LAST:%2.1lf \t" \
GPRINT:8nus:"AVERAGE:%2.1lf \t" \
GPRINT:8nus:"MAX:%2.1lf \t" \
GPRINT:8nus:"MIN:%2.1lf \t\t\t\t" \
GPRINT:8fels:"LAST:%2.1lf \t\t " \
GPRINT:8fels:"AVERAGE:%2.1lf \t" \
GPRINT:8afels:"AVERAGE:%2.1lf \t" \
GPRINT:8fels:"MAX:%2.1lf \t" \
GPRINT:8fels:"MIN:%2.1lf \\n" \
LINE2:24hs#0349FCEE:"24h prognos SMHI\t" \
GPRINT:24nus:"LAST:%2.1lf \t" \
GPRINT:24nus:"AVERAGE:%2.1lf \t" \
GPRINT:24nus:"MAX:%2.1lf \t" \
GPRINT:24nus:"MIN:%2.1lf \t\t\t\t" \
GPRINT:24fels:"LAST:%2.1lf \t\t " \
GPRINT:24fels:"AVERAGE:%2.1lf \t" \
GPRINT:24afels:"AVERAGE:%2.1lf \t" \
GPRINT:24fels:"MAX:%2.1lf \t" \
GPRINT:24fels:"MIN:%2.1lf \\n" \
LINE2:48hs#038CFCEE:"48h prognos SMHI\t" \
GPRINT:48nus:"LAST:%2.1lf \t" \
GPRINT:48nus:"AVERAGE:%2.1lf \t" \
GPRINT:48nus:"MAX:%2.1lf \t" \
GPRINT:48nus:"MIN:%2.1lf \t\t\t\t" \
GPRINT:48fels:"LAST:%2.1lf \t\t " \
GPRINT:48fels:"AVERAGE:%2.1lf \t" \
GPRINT:48afels:"AVERAGE:%2.1lf \t" \
GPRINT:48fels:"MAX:%2.1lf \t" \
GPRINT:48fels:"MIN:%2.1lf \\n" \
LINE4:ute#222222:"Utetemp. \t\t" \
GPRINT:ute:"LAST:%2.1lf \t" \
GPRINT:ute:"AVERAGE:%2.1lf \t" \
GPRINT:ute:"MAX:%2.1lf \t" \
GPRINT:ute:"MIN:%2.1lf\\n" \
AREA:ute#22222220 \