# Compact Multi-location Weather Display

**URL:** <https://discourse.nodered.org/t/compact-multi-location-weather-display/57833>\
**Category:** Share Your Projects\
**Tags:** node-red-dashboard\
**Created:** [5 February 2022 15:13 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833 "2022-02-05T15:13:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [5 February 2022 15:13 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/1 "2022-02-05T15:13:34Z")

</div>

This flow fetches weather data for a given location from [openweathermap.org](http://openweathermap.org) (you need a free API key) and crams it into a 9 x 4 unit UI template.

 ![Tobermory](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/0/50564309a23aaef1dc5ac4063335545961b96081.jpeg)

Features:

- Forecasts are shown hourly for up to 6 hours plus today and the next 4 days.
- Times (and days - Auckland) are the local time, not UTC
- The background colour blends from cool blue to warm red according to the "Feels Like" temperature.
- If there are weather alerts the text is shown and icons change colour for the affected period (Tobermory).
- Required inputs are Location name, latitude & longitude so it should be possible to pick from a map.
- Optional inputs are subjective cold and hot according to the location (a Greenlander probably feels hot at a lower temperature than a Sri Lankan). Obviously not so easy to derive from a map.
- The template is HTML and CSS only.

Issues:

- It's cramped. Very small text.
- If both rain and snow amounts are predicted, the snow amount is very cramped (Tobermory).
- But if neither, there is a noticeable gap below the icons (N'Djamena).
- Sometimes a weather alert is shown which relates to a day beyond the 5 days shown (Juneau).
- Weather alerts are in the local language? May cause display issues?

Would be nice?

- A local time digital clock.
- "Take an umbrella" notication.
- UV index.

 ![Untitled 1](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/2/8297a6f62bc4492e0a034470b202cf42cefc5428.jpeg)

 ![Bangui](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/5/a520e49955ab43f8eaf213ddd313b2272d2dfa9d.jpeg)

 ![Juneau](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/8/d8ef18c833e75ac81439e3e1b36260fb36a582d8.jpeg)

 ![Untitled 8](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/5/c5c1366a91c1c57661b3902ef3a6d7f3e2e286f1.jpeg)

```auto
[{"id":"80504545190c9b4d","type":"tab","label":"Weather Demo","disabled":false,"info":"","env":[]},{"id":"1d9a627667e3b8fc","type":"http request","z":"80504545190c9b4d","name":"Openweathermap","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":130,"y":180,"wires":[["cf1bc982dc9e353c"]]},{"id":"cf1bc982dc9e353c","type":"change","z":"80504545190c9b4d","name":"Temp for background colour","rules":[{"t":"set","p":"fudge","pt":"msg","to":"payload.current.feels_like","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":380,"y":180,"wires":[["1b6f730c6ab2223f"]]},{"id":"06c1eecd02273e6a","type":"ui_dropdown","z":"80504545190c9b4d","name":"Available locations","label":"","tooltip":"","place":"Select option","group":"0b2c5ed94dd5b6dc","order":8,"width":0,"height":0,"passthru":true,"multiple":false,"options":[{"label":"Trincomalee, Sri Lanka","value":"Trincomalee","type":"str"},{"label":"Juneau, Alaska","value":"Juneau","type":"str"},{"label":"Tobermory, Scotland","value":"Tobermory","type":"str"},{"label":"Qaqortaq, Greenland","value":"Qaqortaq","type":"str"},{"label":"N'Djamena, Chad","value":"N'Djamena","type":"str"},{"label":"Bangui. Central African Republic","value":"Bangui","type":"str"},{"label":"Auckland. New Zealand","value":"Auckland","type":"str"}],"payload":"","topic":"topic","topicType":"msg","className":"","x":130,"y":120,"wires":[["e01860f95dea2e98"]]},{"id":"e01860f95dea2e98","type":"function","z":"80504545190c9b4d","name":"Setup URL & location","func":"const appid = global.get('openweathermapid'); // Openweathermap API key\n\nconst hot = 32; // default \"hot\" temperature. Above this the background colour is 100% layer 2\nconst cold= 12; // default \"cold\" temperature. Below this the background colour is 100% Background\n\nconst locations = {\n\"Tobermory\": {lat: 56.622149, long: -6.069254, coldat:7, hotat:18}, //Good for weather alerts\n\"Trincomalee\": {lat: 8.647208, long: 81.177637}, //coldat and hotat unspecified\n\"Juneau\": {lat: 58.357577, long: -134.569945, coldat:0, hotat:15}, //Good for weather alerts, checking day names\n\"Qaqortaq\": {lat: 60.71839, long: -46.03561, coldat:-5, hotat:5}, //Reliably chilly\n\"N'Djamena\": {lat: 12.10672, long: 15.0444, coldat:20, hotat:30}, //Reliably warm\n\"Bangui\": {lat: 4.366667, long: 18.583333, coldat:20, hotat:30}, //Reliably warm\n\"Auckland\": {lat: -36.848461, long: 174.763336, coldat:10, hotat:25}, //Good for checking day names\n};\n\n\nmsg = {\n location: msg.payload, // Location name for display\n lat: locations[msg.payload].lat, // Must have\n long: locations[msg.payload].long, // Must have\n coldat: (locations[msg.payload].coldat || cold), // Subjective \"it feels hot/cold\" levels for location\n hotat: (locations[msg.payload].hotat || hot ),\n alertcolor: \"chocolate\", // Icons this colour if there is a weather alert\n}\n\nmsg.url=\"https://api.openweathermap.org/data/2.5/onecall?lat=\" + msg.lat + \"&lon=\" + msg.long + \"&units=metric&appid=\" + appid;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":120,"wires":[["1d9a627667e3b8fc"]]},{"id":"2c4e9abec36c3fb6","type":"ui_template","z":"80504545190c9b4d","group":"0b2c5ed94dd5b6dc","name":"Weather Widget","order":2,"width":"9","height":"4","format":"<div class=\"weatherwidget rounded\" style=\"--fudge: {{msg.fudge}}; --coldat: {{msg.coldat}}; --hotat: {{msg.hotat}}\">\n <div class=\"layer1 rounded\" style=\"--fudge: {{msg.fudge}}; --coldat: {{msg.coldat}}; --hotat: {{msg.hotat}}\">\n <div class=\"layer2 rounded bordered\" style=\"--fudge: {{msg.fudge}}; --coldat: {{msg.coldat}}; --hotat: {{msg.hotat}}\">\n <div class=\"location\">\n <span class=\"location\">{{(msg.location || \"no data\")}}</span>\n </div>\n <div class=\"temperature\">\n <div class=\"actual\">\n <div class=\"value\">{{msg.payload.current.temp | number:1}}°C</div>\n </div>\n <div class=\"feelslike\">\n <div class=\"value\">({{msg.payload.current.feels_like |number:0}}°)</div>\n </div>\n </div>\n <div class=\"currentwrapper\">\n <div class=\"current\">\n <div class=\"wind\">\n <span>Wind: {{msg.payload.current.wind_knots | number:0}}kt {{msg.payload.current.wind_point}}</span>\n </div>\n <div class=\"pressure\">\n <span>Press: {{msg.payload.current.pressure}}hPa</span>\n </div>\n <div class=\"humidity\">\n <span>Hum: {{msg.payload.current.humidity}}%</span>\n </div>\n </div>\n </div>\n \n <div class=\"comments\">{{msg.comments}}</div>\n \n <div class=\"iconswrapper\">\n <div class=\"hourly\">\n <div class=\"icon\">\n <div class=\"subtitle time\">{{msg.payload.hourly[1].localtime}}</div>\n <i class=\"wi wi-owm-{{msg.payload.hourly[1].weather[0].icon}}\" style=\"{{msg.payload.hourly[1].iconstyle}}\"></i>\n <div class=\"subtitle temp\">{{msg.payload.hourly[1].temp | number:0}}°</div>\n <div class=\"subtitle rain\">{{msg.payload.hourly[1].rainmm}}</div>\n <div class=\"subtitle snow\">{{msg.payload.hourly[1].snowmm}}</div>\n </div>\n <div class=\"icon\">\n <div class=\"subtitle time\">{{msg.payload.hourly[2].localtime}}</div>\n <i class=\"wi wi-owm-{{msg.payload.hourly[2].weather[0].icon}}\" style=\"{{msg.payload.hourly[2].iconstyle}}\"></i>\n <div class=\"subtitle temp\">{{msg.payload.hourly[2].temp | number:0}}°</div>\n <div class=\"subtitle rain\">{{msg.payload.hourly[2].rainmm}}</div>\n <div class=\"subtitle snow\">{{msg.payload.hourly[4].snowmm}}</div>\n </div>\n <div class=\"icon\">\n <div class=\"subtitle time\">{{msg.payload.hourly[3].localtime}}</div>\n <i class=\"wi wi-owm-{{msg.payload.hourly[3].weather[0].icon}}\" style=\"{{msg.payload.hourly[3].iconstyle}}\"></i>\n <div class=\"subtitle temp\">{{msg.payload.hourly[3].temp | number:0}}°</div>\n <div class=\"subtitle rain\">{{msg.payload.hourly[3].rainmm}}</div>\n <div class=\"subtitle snow\">{{msg.payload.hourly[3].snowmm}}</div>\n </div>\n <div class=\"icon\">\n <div class=\"subtitle time\">{{msg.payload.hourly[4].localtime}}</div>\n <i class=\"wi wi-owm-{{msg.payload.hourly[4].weather[0].icon}}\" style=\"{{msg.payload.hourly[4].iconstyle}}\"></i>\n <div class=\"subtitle temp\">{{msg.payload.hourly[4].temp | number:0}}°</div>\n <div class=\"subtitle rain\">{{msg.payload.hourly[4].rainmm}}</div>\n <div class=\"subtitle snow\">{{msg.payload.hourly[4].snowmm}}</div>\n </div>\n <div class=\"icon\">\n <div class=\"subtitle time\">{{msg.payload.hourly[5].localtime}}</div>\n <i class=\"wi wi-owm-{{msg.payload.hourly[5].weather[0].icon}}\" style=\"{{msg.payload.hourly[5].iconstyle}}\"></i>\n <div class=\"subtitle temp\">{{msg.payload.hourly[5].temp | number:0}}°</div>\n <div class=\"subtitle rain\">{{msg.payload.hourly[5].rainmm}}</div>\n <div class=\"subtitle snow\">{{msg.payload.hourly[5].snowmm}}</div>\n </div>\n <div class=\"icon\">\n <div class=\"subtitle time\">{{msg.payload.hourly[6].localtime}}</div>\n <i class=\"wi wi-owm-{{msg.payload.hourly[6].weather[0].icon}}\" style=\"{{msg.payload.hourly[6].iconstyle}}\"></i>\n <div class=\"subtitle temp\">{{msg.payload.hourly[6].temp | number:0}}°</div>\n <div class=\"subtitle rain\">{{msg.payload.hourly[6].rainmm}}</div>\n <div class=\"subtitle snow\">{{msg.payload.hourly[6].snowmm}}</div>\n </div>\n </div>\n \n <div class=\"daily\">\n <div class=\"icon\">\n <div class=\"subtitle time\">{{msg.payload.daily[0].day}}</div>\n <i class=\"wi wi-owm-{{msg.payload.daily[0].weather[0].icon}}\" style=\"{{msg.payload.daily[1].iconstyle}}\"></i>\n <div class=\"subtitle temp\">{{msg.payload.daily[0].temp.max | number:0}}°</div>\n <div class=\"subtitle rain\">{{msg.payload.daily[0].rainmm}}</div>\n <div class=\"subtitle snow\">{{msg.payload.daily[0].snowmm}}</div>\n </div>\n <div class=\"icon\">\n <div class=\"subtitle time\">{{msg.payload.daily[1].day}}</div>\n <i class=\"wi wi-owm-{{msg.payload.daily[1].weather[0].icon}}\" style=\"{{msg.payload.daily[1].iconstyle}}\"></i>\n <div class=\"subtitle temp\">{{msg.payload.daily[1].temp.max | number:0}}°</div>\n <div class=\"subtitle rain\">{{msg.payload.daily[1].rainmm}}</div>\n <div class=\"subtitle snow\">{{msg.payload.daily[1].snowmm}}</div>\n </div>\n <div class=\"icon\">\n <div class=\"subtitle time\">{{msg.payload.daily[2].day}}</div>\n <i class=\"wi wi-owm-{{msg.payload.daily[2].weather[0].icon}}\" style=\"{{msg.payload.daily[1].iconstyle}}\"></i>\n <div class=\"subtitle temp\">{{msg.payload.daily[2].temp.max | number:0}}°</div>\n <div class=\"subtitle rain\">{{msg.payload.daily[2].rainmm}}</div>\n <div class=\"subtitle snow\">{{msg.payload.daily[2].snowmm}}</div>\n </div> \n <div class=\"icon\">\n <div class=\"subtitle time\">{{msg.payload.daily[3].day}}</div>\n <i class=\"wi wi-owm-{{msg.payload.daily[3].weather[0].icon}}\" style=\"{{msg.payload.daily[1].iconstyle}}\"></i>\n <div class=\"subtitle temp\">{{msg.payload.daily[3].temp.max | number:0}}°</div>\n <div class=\"subtitle rain\">{{msg.payload.daily[3].rainmm}}</div>\n <div class=\"subtitle snow\">{{msg.payload.daily[3].snowmm}}</div>\n </div>\n <div class=\"icon\">\n <div class=\"subtitle time\">{{msg.payload.daily[4].day}}</div>\n <i class=\"wi wi-owm-{{msg.payload.daily[4].weather[0].icon}}\" style=\"{{msg.payload.daily[1].iconstyle}}\"></i>\n <div class=\"subtitle temp\">{{msg.payload.daily[4].temp.max | number:0}}°</div>\n <div class=\"subtitle rain\">{{msg.payload.daily[4].rainmm}}</div>\n <div class=\"subtitle snow\">{{msg.payload.daily[4].snowmm}}</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"copyright\"><span>Weather data from openweathermap.org</span></div>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":800,"y":180,"wires":[[]]},{"id":"1b6f730c6ab2223f","type":"function","z":"80504545190c9b4d","name":"Adjust output","func":"const alertstyle = \"color: var(--alertcolor)\";\nmsg.debug = {location: msg.location, alerts:{}, days:\"\", hours:\"\"};\nfunction dayName(unixTime){\n var dateObject = new Date(unixTime * 1000);\n return dateObject.toLocaleString(\"default\", { weekday: \"short\" })\n}\nfunction timeConvert(UNIX_timestamp){\n var dateObject = new Date(UNIX_timestamp * 1000);\n return dateObject.toLocaleString('en', { timezone: msg.payload.timezone, hour12: false, hour: 'numeric'}) + ':00';\n}\nfunction degreesToCompass(deg){\n if (deg>11.25 && deg<=33.75){return \"NNE\";}\n else if (deg<=56.25){return \"NE\";}\n else if (deg<=78.75){return \"ENE\";}\n else if (deg<=101.25){return \"E\";}\n else if (deg<=123.75){return \"ESE\";}\n else if (deg<=146.25){return \"SE\";}\n else if (deg<=168.75){return \"SSE\";}\n else if (deg<=191.25){return \"S\";}\n else if (deg<=213.75){return \"SSW\";}\n else if (deg<=236.25){return \"SW\";}\n else if (deg<=258.75){return \"WSW\";}\n else if (deg<=281.25){return \"W\";}\n else if (deg<=303.75){return \"WNW\";}\n else if (deg<=326.25){return \"NW\";}\n else if (deg<=348.75){return \"NNW\";}\n else {return \"N\";}\n}\n\n// wind as compass points \nmsg.payload.current.wind_point = degreesToCompass(msg.payload.current.wind_deg);\nmsg.payload.current.wind_knots = msg.payload.current.wind_speed * 1.944;\nmsg.payload.current.wind_mph = msg.payload.current.wind_speed * 2.237;\n\n// Weather alerts\nif (msg.payload.hasOwnProperty('alerts')) { // There may be several weather alerts but only space to show one\n msg.comments = msg.payload.alerts[0].event; // No good way to pick the most urgent\n}\n\n// Get rain & snow qty and alerts for each hour, Adjust display to show local time\n// Not sure if browser timezone is relevant?\nmsg.payload.hourly.forEach(element => {\n const adjustedtime = element.dt + msg.payload.timezone_offset;\n element.localtime = timeConvert(adjustedtime); \n element.day = dayName(adjustedtime);\n if (element.hasOwnProperty('rain')) {element.rainmm = Math.round(element.rain[\"1h\"]) + \"mm\";}\n if (element.hasOwnProperty('snow')) {element.snowmm = Math.round(element.snow[\"1h\"]) + \"mm\";}\n if (msg.payload.hasOwnProperty('alerts')) {\n msg.payload.alerts.forEach(alert => {\n if (element.dt <= alert.end && (element.dt + 3600) >= alert.start) {\n element.warning = alert.event;\n element.iconstyle = alertstyle;\n }\n });\n }\n});\n\n// Get rain & snow qty and alerts for each day\nmsg.payload.daily.forEach(element => {\n const adjustedtime = element.dt + msg.payload.timezone_offset;\n element.localtime = timeConvert(adjustedtime);\n element.day = dayName(adjustedtime);\n if (element.hasOwnProperty('rain')) {\n element.rainmm = Math.round(element.rain) + \"mm\";\n }\n if (element.hasOwnProperty('snow')) {\n element.snowmm = Math.round(element.snow) + \"mm\";\n }\n if (msg.payload.hasOwnProperty('alerts')) {\n msg.payload.alerts.forEach(alert => {\n if (element.dt <= alert.end && (element.dt + 86400) >= alert.start) {\n element.warning = alert.event;\n element.iconstyle = alertstyle;\n }\n });\n }\n});\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":610,"y":180,"wires":[["2c4e9abec36c3fb6"]]},{"id":"953c086699766456","type":"ui_template","z":"80504545190c9b4d","group":"0b2c5ed94dd5b6dc","name":"CSS","order":3,"width":"0","height":"0","format":"<style>\n:root {\n/* these are the colours of the three layers */\n--background: 126,219,251;\n--r1: 250; --g1: 250; --b1: 147;\n--r2: 255; --g2: 179; --b2: 179;\n/* and text */\n--textcolor: black;\n--alertcolor: chocolate; \n/* You can adjust the blending of colours with this. Suggest 0.4 - 0.6 */\n--blend: 0.5;\n}\n.weatherwidget{\n position: relative;\n height: calc(100% - 8px);\n width: 100%;\n background-color: rgb(var(--background));\n}\n.weatherwidget .location {\n position: absolute;\n top: 0px;\n left: 5px;\n width: 100%;\n font-family: \"Times New Roman\", serif;\n font-size: 42px;\n color: var(--textcolor);\n}\n.weatherwidget .temperature {\n position: absolute;\n margin-left: 10px;\n top: 42px;\n width: 93%;\n height: 80%;\n color: var(--textcolor);\n font-family: calibri, sans-serif;\n}\n.weatherwidget .temperature .actual {\n position: relative;\n width: 120px; \n margin-left: 0px;\n min-height: 40px;\n float:left;\n top: 0px;\n}\n.weatherwidget .temperature .actual .value {\n position: absolute;\n top:0px;\n left:0px;\n font-size: 40px;\n}\n.weatherwidget .temperature .feelslike {\n position:relative;\n width: 80px;\n margin-left: 0px;\n height: 70px;\n float: left;\n top:0px;\n}\n.weatherwidget .temperature .feelslike .value {\n position: absolute;\n top: 3px;\n left:0px;\n font-size: 32px;\n}\n\n.weatherwidget .currentwrapper {\n position: absolute;\n width: 180px;\n right: 10px;\n top: 0px;\n}\n.weatherwidget .current {\n position: relative;\n color: var(--textcolor);\n font-size: 16px;\n font-family: verdana, sans-serif;\n}\n.weatherwidget .current .wind {\n position: absolute;\n top: 8px;\n right: 0px;\n}\n.weatherwidget .current .pressure {\n position: absolute;\n top: 26px;\n right:0px;\n}\n.weatherwidget .current .humidity {\n position: absolute;\n top: 44px;\n right: 0px;\n}\n\n.weatherwidget .comments {\n position: absolute;\n font-size: 18px;\n right:10px;\n top: 64px;\n color: var(--alertcolor);\n font-family: verdana, sans-serif;\n}\n\n.weatherwidget .iconswrapper {\n position: absolute;\n top: 92px;\n left: 10px;\n width: calc(100% - 10px);\n color: var(--textcolor);\n text-align: center;\n font-family: verdana, sans-serif;\n}\n.weatherwidget .iconswrapper .hourly {\n position: relative;\n top: 0px;\n float:left;\n}\n.weatherwidget .iconswrapper .daily {\n position: relative;\n top: 0px;\n float: right;\n}\n.weatherwidget .iconswrapper .icon {\n float: left;\n min-width: 40px;\n}\n.weatherwidget .iconswrapper .icon i {\n padding-bottom: 5px;\n font-size: 26px; /* using fa-2x instead makes icon slightly too wide */\n}\n.weatherwidget .iconswrapper .subtitle {\n font-size: 11px;\n margin-bottom: 2px;\n}\n.weatherwidget .iconswrapper .subtitle.time {\n margin-bottom: 5px;\n}\n.weatherwidget .iconswrapper .subtitle.rain {\n color: blue;\n}\n.weatherwidget .iconswrapper .subtitle.snow {\n color: white;\n}\n.bordered{\n box-sizing: border-box;\n border:4px solid black;\n margin-bottom: 2px;\n}\n.rounded {\n border-radius: 10px;\n}\n.weatherwidget .layer1 {\n--r: var(--r1);\n--g: var(--g1);\n--b: var(--b1);\n--start:var(--coldat);\n}\n.weatherwidget .layer2 {\n--r: var(--r2);\n--g: var(--g2);\n--b: var(--b2);\n--start:calc(var(--hotat) - (var(--span)));\n}\n.weatherwidget .layer2, .weatherwidget .layer1 {\n--span: calc((var(--hotat) - var(--coldat)) * var(--blend));\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n box-shadow: 4px 4px 28px 0px rgba(0,0,0,0.3) inset;\n background-color: rgba(var(--r), var(--g), var(--b), calc((var(--fudge) - var(--start)) / var(--span)));\n}\n.weatherwidget .copyright {\n position: absolute;\n bottom: -10px;\n right: 10px;\n font-size:10px;\n font-family: verdana, sans-serif;\n max-height: 15px;\n}\n</style>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":770,"y":120,"wires":[[]]},{"id":"0b2c5ed94dd5b6dc","type":"ui_group","name":"Demo","tab":"4311353dbffb7643","order":1,"disp":true,"width":"10","collapse":false,"className":""},{"id":"4311353dbffb7643","type":"ui_tab","name":"Demo","icon":"dashboard","disabled":false,"hidden":false}]

```

---

<div class="post-metadata">

**Author:** ![Sean-McG](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sean-mcg/32/54677_2.png) [@Sean-McG](https://discourse.nodered.org/u/Sean-McG)\
**Post date:** [5 February 2022 16:20 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/2 "2022-02-05T16:20:48Z")

</div>

Just don't eat the snow in Tobermory 🤣

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [5 February 2022 16:22 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/3 "2022-02-05T16:22:00Z")

</div>

Why, what did you do? 😜

---

<div class="post-metadata">

**Author:** ![Sean-McG](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sean-mcg/32/54677_2.png) [@Sean-McG](https://discourse.nodered.org/u/Sean-McG)\
**Post date:** [5 February 2022 16:24 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/4 "2022-02-05T16:24:34Z")

</div>

Apparently its Yellow 🤢

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [5 February 2022 16:26 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/5 "2022-02-05T16:26:58Z")

</div>

Womble spoor.

---

<div class="post-metadata">

**Author:** ![patrizioperrone](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/patrizioperrone/32/100573_2.png) [@patrizioperrone](https://discourse.nodered.org/u/patrizioperrone)\
**Post date:** [4 May 2025 12:30 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/6 "2025-05-04T12:30:15Z")

</div>

Hello guys do you have this template modified for Dashboard 2.0. I cannot make it to work with my poor knowledge. Thanks in advance

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [4 May 2025 14:22 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/7 "2025-05-04T14:22:30Z")

</div>

I started working on it but it's not complete.

If you show us your attempt so far we might be able to fix it between us.

---

<div class="post-metadata">

**Author:** ![patrizioperrone](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/patrizioperrone/32/100573_2.png) [@patrizioperrone](https://discourse.nodered.org/u/patrizioperrone)\
**Post date:** [5 May 2025 11:37 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/8 "2025-05-05T11:37:06Z")

</div>

SInce I am not an expert in programming I just copied and pasted the code from dashboard 1 to dashboard 2.0. And of course it did not work. I have no clue of ewhat the differences are sorry

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [5 May 2025 12:56 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/9 "2025-05-05T12:56:34Z")

</div>

I don't seem to be able to use OWM any more - I generated a new key but I keep getting a 401 response - invalid key.

---

<div class="post-metadata">

**Author:** ![patrizioperrone](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/patrizioperrone/32/100573_2.png) [@patrizioperrone](https://discourse.nodered.org/u/patrizioperrone)\
**Post date:** [5 May 2025 13:02 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/10 "2025-05-05T13:02:14Z")

</div>

i can provide you with my apikey temporarly to test if you like.

---

<div class="post-metadata">

**Author:** ![patrizioperrone](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/patrizioperrone/32/100573_2.png) [@patrizioperrone](https://discourse.nodered.org/u/patrizioperrone)\
**Post date:** [5 May 2025 13:03 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/11 "2025-05-05T13:03:02Z")

</div>

in anyway it takes some time for the api to get valid. it happened to me too in the past.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [5 May 2025 13:04 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/12 "2025-05-05T13:04:33Z")

</div>

I've use it in the past and had 2 other API keys which I also tried. So not sure what's wrong. If you want to pm me your key, I'll just use it for a one-off test.

I intended to create a uibuilder version of this example. 🙂

---

<div class="post-metadata">

**Author:** ![patrizioperrone](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/patrizioperrone/32/100573_2.png) [@patrizioperrone](https://discourse.nodered.org/u/patrizioperrone)\
**Post date:** [5 May 2025 13:07 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/13 "2025-05-05T13:07:54Z")

</div>

i just did it.

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [5 May 2025 13:08 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/14 "2025-05-05T13:08:37Z")

</div>

Are you using the "onecall" api?

A sample msg.url  
[https://api.openweathermap.org/data/3.0/onecall?lat=101.89&lon=7.12&units=metric&appid=0123456789abcdef01234567890abcdef](https://api.openweathermap.org/data/3.0/onecall?lat=101.89&lon=7.12&units=metric&appid=0123456789abcdef01234567890abcdef)

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [5 May 2025 13:10 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/15 "2025-05-05T13:10:23Z")

</div>

> [@TotallyInformation](#):
>
> I intended to create a uibuilder version of this example.

I was very proud of this dashboard until my other half told me the colours are ugly 😲

I think if I was doing it now, I'd try to use a single background colour using HSL color space and varying the hue.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [5 May 2025 13:11 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/16 "2025-05-05T13:11:06Z")

</div>

> [@patrizioperrone](#):
>
> i just did it.

Weird, that worked.

> [@jbudd](#):
>
> Are you using the "onecall" api?

No, I'm using the v2.5 API

This is direct from their API docs (missing the key obviously)

```auto
https://api.openweathermap.org/data/2.5/weather?lat=44.34&lon=10.99&appid=

```

> [@jbudd](#):
>
> until my other half told me the colours are ugly

🤣

---

<div class="post-metadata">

**Author:** ![patrizioperrone](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/patrizioperrone/32/100573_2.png) [@patrizioperrone](https://discourse.nodered.org/u/patrizioperrone)\
**Post date:** [5 May 2025 13:12 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/17 "2025-05-05T13:12:14Z")

</div>

yes. one call api 3.0

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [5 May 2025 13:12 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/18 "2025-05-05T13:12:51Z")

</div>

No, onecall 3.0 is a different subscription. Also free but you have to sign up separately.

---

<div class="post-metadata">

**Author:** ![patrizioperrone](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/patrizioperrone/32/100573_2.png) [@patrizioperrone](https://discourse.nodered.org/u/patrizioperrone)\
**Post date:** [5 May 2025 13:13 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/19 "2025-05-05T13:13:25Z")

</div>

i am just saying i am using api 3.0 not 2.5.

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [5 May 2025 13:15 UTC](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833/20 "2025-05-05T13:15:43Z")

</div>

Your URL works with my appid too

[Next page](https://discourse.nodered.org/t/compact-multi-location-weather-display/57833.md?page=2)
