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.

Prognos

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

Prognos

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 \