Creates a button on the bar which displays the current weather condition and temperature. Clicking the button opens a popup with forecast information for the next few days. Weather information is fetched from [wttr.in](https://wttr.in) via an external script. You will need to set up the script to be run as a service. ![custom weather widget, with popup open](https://f.jstanger.dev/github/ironbar/custom-weather.png) ## Configuration
JSON ```json { "end": [ { "type": "custom", "class": "weather", "bar": [ { "type": "button", "label": "#weather_current", "on_click": "popup:toggle" } ], "popup": [ { "type": "box", "orientation": "vertical", "widgets": [ { "type": "label", "name": "header", "label": "Forecast" }, { "type": "box", "widgets": [ { "type": "box", "name": "dates", "orientation": "vertical", "widgets": [ { "type": "label", "class": "weather-date", "label": "#weather_date_0" }, { "type": "label", "class": "weather-date", "label": "#weather_date_1" }, { "type": "label", "class": "weather-date", "label": "#weather_date_2" } ] }, { "type": "box", "name": "temps", "orientation": "vertical", "widgets": [ { "type": "box", "widgets": [ { "type": "label", "class": "weather-high", "label": " #weather_high_0" }, { "type": "label", "class": "weather-avg", "label": " #weather_avg_0" }, { "type": "label", "class": "weather-low", "label": " #weather_low_0" } ] }, { "type": "box", "widgets": [ { "type": "label", "class": "weather-high", "label": " #weather_high_1" }, { "type": "label", "class": "weather-avg", "label": " #weather_avg_1" }, { "type": "label", "class": "weather-low", "label": " #weather_low_1" } ] }, { "type": "box", "widgets": [ { "type": "label", "class": "weather-high", "label": " #weather_high_2" }, { "type": "label", "class": "weather-avg", "label": " #weather_avg_2" }, { "type": "label", "class": "weather-low", "label": " #weather_low_2" } ] } ] } ] } ] } ] } ] } ```
TOML ```toml [[end]] type = "custom" class = "weather" [[end.bar]] type = "button" label = "#weather_current" on_click = "popup:toggle" [[end.popup]] type = "box" orientation = "vertical" [[end.popup.widgets]] type = "label" name = "header" label = "Forecast" [[end.popup.widgets]] type = "box" [[end.popup.widgets.widgets]] type = "box" name = "dates" orientation = "vertical" [[end.popup.widgets.widgets.widgets]] type = "label" class = "weather-date" label = "#weather_date_0" [[end.popup.widgets.widgets.widgets]] type = "label" class = "weather-date" label = "#weather_date_1" [[end.popup.widgets.widgets.widgets]] type = "label" class = "weather-date" label = "#weather_date_2" [[end.popup.widgets.widgets]] type = "box" name = "temps" orientation = "vertical" [[end.popup.widgets.widgets.widgets]] type = "box" [[end.popup.widgets.widgets.widgets.widgets]] type = "label" class = "weather-high" label = " #weather_high_0" [[end.popup.widgets.widgets.widgets.widgets]] type = "label" class = "weather-avg" label = " #weather_avg_0" [[end.popup.widgets.widgets.widgets.widgets]] type = "label" class = "weather-low" label = " #weather_low_0" [[end.popup.widgets.widgets.widgets]] type = "box" [[end.popup.widgets.widgets.widgets.widgets]] type = "label" class = "weather-high" label = " #weather_high_1" [[end.popup.widgets.widgets.widgets.widgets]] type = "label" class = "weather-avg" label = " #weather_avg_1" [[end.popup.widgets.widgets.widgets.widgets]] type = "label" class = "weather-low" label = " #weather_low_1" [[end.popup.widgets.widgets.widgets]] type = "box" [[end.popup.widgets.widgets.widgets.widgets]] type = "label" class = "weather-high" label = " #weather_high_2" [[end.popup.widgets.widgets.widgets.widgets]] type = "label" class = "weather-avg" label = " #weather_avg_2" [[end.popup.widgets.widgets.widgets.widgets]] type = "label" class = "weather-low" label = " #weather_low_2" ```
YAML ```yaml end: - type: custom class: weather bar: - type: button label: '#weather_current' on_click: popup:toggle popup: - type: box orientation: vertical widgets: - type: label name: header label: Forecast - type: box widgets: - type: box name: dates orientation: vertical widgets: - type: label class: weather-date label: '#weather_date_0' - type: label class: weather-date label: '#weather_date_1' - type: label class: weather-date label: '#weather_date_2' - type: box name: temps orientation: vertical widgets: - type: box widgets: - type: label class: weather-high label: ' #weather_high_0' - type: label class: weather-avg label: ' #weather_avg_0' - type: label class: weather-low label: ' #weather_low_0' - type: box widgets: - type: label class: weather-high label: ' #weather_high_1' - type: label class: weather-avg label: ' #weather_avg_1' - type: label class: weather-low label: ' #weather_low_1' - type: box widgets: - type: label class: weather-high label: ' #weather_high_2' - type: label class: weather-avg label: ' #weather_avg_2' - type: label class: weather-low label: ' #weather_low_2' ```
Corn ```corn let { $weather = { type = "custom" class = "weather" bar = [ { type = "button" label = "#weather_current" on_click = "popup:toggle" } ] popup = [ { type = "box" orientation = "vertical" widgets = [ { type = "label" name = "header" label = "Forecast" } { type = "box" widgets = [ { type = "box" name="dates" orientation = "vertical" widgets = [ { type = "label" class="weather-date" label = "#weather_date_0" } { type = "label" class="weather-date" label = "#weather_date_1" } { type = "label" class="weather-date" label = "#weather_date_2" } ]} { type = "box" name="temps" orientation = "vertical" widgets = [ { type = "box" widgets = [ { type = "label" class="weather-high" label = " #weather_high_0" } { type = "label" class="weather-avg" label = " #weather_avg_0" } { type = "label" class="weather-low" label = " #weather_low_0" } ] } { type = "box" widgets = [ { type = "label" class="weather-high" label = " #weather_high_1" } { type = "label" class="weather-avg" label = " #weather_avg_1" } { type = "label" class="weather-low" label = " #weather_low_1" } ] } { type = "box" widgets = [ { type = "label" class="weather-high" label = " #weather_high_2" } { type = "label" class="weather-avg" label = " #weather_avg_2" } { type = "label" class="weather-low" label = " #weather_low_2" } ] } ] } ] } ] } ] } } in { end = [ $weather ] } ```
## Script Run the following script on a timer. Ensure to fill out your city name. ```js #!/usr/bin/env zx const location = "Canterbury"; // JS uses Sunday as first day const weekday = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]; // bar logic const data = await fetch(`https://wttr.in/${location}?format=%c %t|%m %t|%S|%s`) .then(r => r.text()); const [day, night, sunrise, sunset] = data.replaceAll("+", "").split("|"); const [sunriseH, sunriseM, sunriseS] = sunrise.split(":"); const [sunsetH, sunsetM, sunsetS] = sunset.split(":"); const currentTime = new Date(); const sunriseTime = new Date(currentTime); sunriseTime.setHours(sunriseH); sunriseTime.setMinutes(sunriseM); sunriseTime.setSeconds(sunriseS); const sunsetTime = new Date(currentTime); sunsetTime.setHours(sunsetH); sunsetTime.setMinutes(sunsetM); sunsetTime.setSeconds(sunsetS); let value = day; if(currentTime < sunriseTime || currentTime > sunsetTime) value = night; await $`ironbar set weather_current ${value}`; // popup logic const forecast = await fetch(`https://wttr.in/${location}?format=j1`).then(r => r.json()); for (const i in forecast.weather) { const report = forecast.weather[i]; const day = weekday[new Date(report.date).getDay()]; await $`ironbar set weather_date_${i} ${day}`; await $`ironbar set weather_avg_${i} ${report.avgtempC.padStart(2, "0")}`; await $`ironbar set weather_high_${i} ${report.maxtempC.padStart(2, "0")}`; await $`ironbar set weather_low_${i} ${report.mintempC.padStart(2, "0")}`; } ``` ## Styling ```css .popup-weather #header { font-size: 1.8em; padding-bottom: 0.4em; margin-bottom: 0.6em; border-bottom: 1px solid @color-border; } .popup-weather .weather-date { font-size: 1.5em; padding-right: 1em; } .popup-weather .weather-avg { margin-left: 0.5em; margin-right: 0.5em; } /* this is a hack to align the different font sizes on left/right you may need to adjust for different fonts */ .popup-weather #temps label { padding-top: 0.2em; margin-bottom: 0.7em; } ```