Skip to content

Instantly share code, notes, and snippets.

@10der

10der/README.md Secret

Last active January 13, 2022 06:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 10der/affa4bd5194a25019081d2ec8191fa48 to your computer and use it in GitHub Desktop.
Save 10der/affa4bd5194a25019081d2ec8191fa48 to your computer and use it in GitHub Desktop.
Get weather forecast from api.met.no (AKA yr.no)

Please change "set geolocation" node according your location.

PS: time rounded to near hour

PSS: cache data stored at flow.context

PSSS: please DO NOT poll yr.no without caching! otherwise you may BUNNED by IP via yr.no service.

[{"id":"ea60fc0d.0ac8","type":"http request","z":"e6a54674.5ab678","name":"api.met.no","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://api.met.no/weatherapi/locationforecast/2.0/.json?lat={{{lat}}}&lon={{{lon}}}","tls":"","persist":false,"proxy":"","authType":"","x":190,"y":1860,"wires":[["e7232287.fb624"]]},{"id":"e4492649.6d0e88","type":"debug","z":"e6a54674.5ab678","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":710,"y":1800,"wires":[]},{"id":"7a209ce8.986264","type":"inject","z":"e6a54674.5ab678","name":"","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"00 07 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":1740,"wires":[["5df118c8.e31f18"]]},{"id":"def2ae81.57c36","type":"change","z":"e6a54674.5ab678","name":"set geolocation","rules":[{"t":"set","p":"lat","pt":"msg","to":"46.76644","tot":"str"},{"t":"set","p":"lon","pt":"msg","to":"36.79872","tot":"str"},{"t":"set","p":"headers","pt":"msg","to":"[{\"User-Agent\":\"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36\"}]","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":200,"y":1820,"wires":[["a135101d.a08d"]]},{"id":"e7232287.fb624","type":"function","z":"e6a54674.5ab678","name":"save met_public_forecast","func":"if (msg.payload) {\n flow.set(\"met_public_forecast\", msg.payload);\n return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":390,"y":1860,"wires":[["c4c6c2fc.6484d"]]},{"id":"5df118c8.e31f18","type":"function","z":"e6a54674.5ab678","name":"check met_public_forecast","func":"var met_public_forecast = flow.get(\"met_public_forecast\") || null;\nif (met_public_forecast && met_public_forecast.properties)\n{\n var now = new Date();\n var updated = Date.parse(met_public_forecast.properties.meta.updated_at);\n var difference = now - updated;\n var hh = Math.floor(difference / 1000 / 60 / 60);\n if (hh < 12) {\n // cached data\n msg.payload = met_public_forecast;\n node.send([null, msg]);\n return \n }\n}\n\nnode.warn(\"update weather from met\");\nnode.send([msg, null]);\n\n","outputs":2,"noerr":0,"initialize":"","finalize":"","x":240,"y":1780,"wires":[["def2ae81.57c36"],["c4c6c2fc.6484d"]]},{"id":"c4c6c2fc.6484d","type":"function","z":"e6a54674.5ab678","name":"parse","func":"function updateNextData(item, result){\n for (var key in item) {\n if (item.hasOwnProperty(key)) {\n if (typeof item[key] === 'object') {\n updateNextData(item[key], result);\n } else {\n result[key] = item[key];\n }\n }\n }\n}\n\nfunction showForecast(start, end) {\n msg.payload.properties.timeseries.forEach(function (item) {\n var time = new Date(Date.parse(item.time));\n if (time >= start && time <= end) {\n var details = item.data.instant.details;\n details.time = time.getTime();\n updateNextData(item.data.next_12_hours, details);\n updateNextData(item.data.next_6_hours, details);\n updateNextData(item.data.next_1_hours, details);\n node.warn(details);\n }\n });\n}\n\n// today foracast \nlet start = new Date();\nstart.setHours(0,0,0,0); // last midnight\nlet end = new Date();\nend.setHours(24,0,0,0); // next midnight\nshowForecast(start, end); // forecast for the next X hours\n\n// forecast for the next X hours\nstart = new Date();\nend = new Date();\nend.setHours(end.getHours() + 6);\nshowForecast(start, end); \n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":550,"y":1800,"wires":[["e4492649.6d0e88"]]},{"id":"a135101d.a08d","type":"function","z":"e6a54674.5ab678","name":"headers","func":"msg.headers = {};\nmsg.headers['USER-AGENT'] = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36';\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":1820,"wires":[["ea60fc0d.0ac8"]]}]
@jasonlodder
Copy link

Thank you Oleg for this flow!

I have learned so much from playing with the values and adapting them to fit my location. It is currently displaying basic weather information on my custom-built smart mirror.

I have one question, how can I increase the time periods? Currently, it seems like it goes per hour but I would like to for example show the minimum and maximum temperature per day?

Thank you
Jason

@10der
Copy link
Author

10der commented Feb 28, 2021

has updated

@jasonlodder
Copy link

has updated

Thank you Oleg for your update. The minimum temperature seems to be working but the maximum temperature is still showing the current temperature for some reason and not the maximum temperature for today?

Is it possible to set the timeframe of 00:00 - 00:00(+24 hours) similar to other weather services?

Thank you
Jason

@10der
Copy link
Author

10der commented Feb 28, 2021

yr.nr can provide information about min / max only for the next 6h
image

@10der
Copy link
Author

10der commented Feb 28, 2021

so if you grab data from yr.nr now (for example now is 3PM) you can't get min temp for today, cuz we lost.

@jasonlodder
Copy link

Thank you Oleg,

I am still new to node red so I am still learning a lot. I noticed the new update is outputting an object that is in the format:
.{ "air_pressure_at_sea_level":1029.6,
"air_temperature":10.5, ... }

I am having trouble to access and display this on a simple text node on the UI.

Your previous version had an output in msg.payload which I am more used to accessing.
I looked through your parser function and it seems that this is where the code stops using the msg.payload and changes the object's format?

If I use a debug node I can access the data in JSONata but using it on a text node, I get completely lost

Can you please give me guidance on how to display this in UI?

Much appreciated and thank you
Jason

@Boardaren
Copy link

Updated the geolocation but got an error:
TypeError: Cannot read properties of undefined (reading 'model')
And this is why?

//Marius

@10der
Copy link
Author

10der commented Jan 13, 2022

idk.

fresh new node-red
node-red
image

import flow from gist
save
run

image

no issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment