Dashboard pogody z pluginem Weather#
Plugin Weather pobiera pogodę z OpenWeatherMap, a jeden moduł Lua rysuje z niej dashboard: temperaturę, wilgotność, ciśnienie, wiatr, opady i wykresy z ostatniej doby. Całość zajmuje kwadrans, a większość z tego to założenie konta po klucz API.
Co zbudujemy#
- plugin Weather skonfigurowany dla Twojej miejscowości
- moduł
pogoda, który czyta plugin - dashboard pod adresem
/d/pogoda - na koniec automatykę, która reaguje na początek deszczu
Czego potrzebujesz#
| Co | Uwagi |
|---|---|
| Działające vCLU | np. po tutorialu Standalone |
| Konto w OpenWeatherMap | darmowy plan wystarcza: 1000 zapytań dziennie, plugin robi 24 |
Krok 1: Klucz API#
- Załóż konto na openweathermap.org.
- Otwórz API keys i skopiuj klucz.
Nowy klucz zaczyna działać po kilkunastu minutach do kilku godzin. Do tego czasu plugin zgłasza w logach HTTP 401.
Krok 2: Instalacja i konfiguracja pluginu#
W panelu vCLU otwórz Plugins, znajdź Weather Plugin i kliknij Install, a potem Configure:
| Pole | Wartość |
|---|---|
apiKey | klucz z kroku 1 |
city | miejscowość z kodem kraju, np. Kraków,pl |
interval | co ile sekund pobierać pogodę; 3600 to raz na godzinę |
units | metric, czyli °C i m/s |

Kod kraju po przecinku ma znaczenie: bez niego OpenWeatherMap może wybrać miejscowość o tej samej nazwie w innym kraju.
Po zapisaniu plugin od razu pobiera pierwszy odczyt. W logach vCLU pojawi się linia w rodzaju:
Weather: Clear, 13.3°C, 62% humidityKrok 3: Moduł pogoda#
Kod trzymamy w module: katalog modules/pogoda/ z plikiem init.lua. Moduł jest jedynym miejscem, które czyta plugin. Dashboard i wszystko, co dopiszesz później (eksport do InfluxDB, automatyki), bierze odczyty z modułu, więc wszędzie widać te same wartości.
W panelu otwórz Editor i utwórz plik modules/pogoda/init.lua:
-- modules/pogoda/init.lua
-- Pogoda z pluginu @vclu/weather (OpenWeatherMap): odczyty i metryki.
local weather = Plugin.getPlugin("@vclu/weather")
if not weather then
print("[POGODA] Plugin @vclu/weather niezaładowany, moduł pominięty")
return nil
end
-- Przed pierwszą odpowiedzią plugin trzyma zera, więc do tego czasu
-- zwracamy nil i widget zostaje pusty zamiast pokazywać 0 °C.
local function read(field)
return function()
local d = weather:getData()
if not d.ready then return nil end
return d[field]
end
end
local M = {
temp = read("temp"),
feelsLike = read("feelsLike"),
humidity = read("humidity"),
pressure = read("pressure"),
wind = read("windSpeed"),
windDeg = read("windDeg"),
clouds = read("clouds"),
rain = read("rain"),
}
-- OpenWeatherMap podaje warunki po angielsku, w polu `condition`.
local CONDITIONS = {
Clear = "Bezchmurnie", Clouds = "Pochmurno", Rain = "Deszcz",
Drizzle = "Mżawka", Thunderstorm = "Burza", Snow = "Śnieg",
Mist = "Mgła", Fog = "Mgła", Haze = "Zamglenie",
}
function M.condition()
local c = read("condition")()
if not c then return nil end
return CONDITIONS[c] or c
end
-- Kierunek, z którego wieje, z kąta w stopniach.
local DIRECTIONS = { "N", "NE", "E", "SE", "S", "SW", "W", "NW" }
function M.windText()
local speed, deg = M.wind(), M.windDeg()
if not speed then return nil end
local dir = DIRECTIONS[math.floor((deg + 22.5) / 45) % 8 + 1]
return string.format("%.1f m/s %s", speed, dir)
end
function M.updated()
local d = weather:getData()
if not d.ready then return "czekam na pierwszy odczyt" end
return os.date("%H:%M", d.lastUpdate) .. ", " .. d.city
end
function M.refresh() weather:refresh() end
-- Historia do wykresów na dashboardzie
metric("pogoda:temp", M.temp, { unit = "°C", interval = 600, decimals = 1 })
metric("pogoda:cisnienie", M.pressure, { unit = "hPa", interval = 600 })
metric("pogoda:wilgotnosc", M.humidity, { unit = "%", interval = 600 })
return MCo tu się dzieje:
Plugin.getPlugin("@vclu/weather")zwraca zainstalowany plugin. Jeśli go nie ma, moduł kończy się bez błędu, a reszta systemu działa dalej.read(field)tworzy funkcję, która przy każdym wywołaniu oddaje bieżący odczyt. Dashboard dostaje funkcje, a nie wartości, dlatego zawsze pokazuje to, co plugin pobrał ostatnio.metric(...)co 10 minut zapisuje wartość do historii, z której korzystają wykresy. Historia zaczyna się od załadowania modułu, więc wykresy zapełnią się po dobie.return Moddaje odczyty innym plikom: każdy, kto zrobirequire("pogoda"), dostanie tę tabelę.
Krok 4: Plik dashboardu#
Dashboard tylko rysuje. Utwórz modules/dashboards/pogoda.lua:
-- modules/dashboards/pogoda.lua
local pogoda = require("pogoda")
-- Bez pluginu moduł zwraca nil, a require oddaje wtedy true, nie tabelę.
if type(pogoda) ~= "table" then return end
local dash = Dashboard.new("pogoda")
:name("Pogoda")
:icon("cloud-sun")
:columns(3)
:auth("session")
:poll(60)
dash:header()
:status("temp", "Temperatura", "thermometer-half", pogoda.temp, "°C",
{ spark = "pogoda:temp", sparkRange = "24h" })
:status("warunki", "Warunki", "cloud-sun", pogoda.condition)
:status("odczuwalna", "Odczuwalna", "person", pogoda.feelsLike, "°C")
dash:section("Powietrze", "droplet", { columns = 3 })
:status("wilgotnosc", "Wilgotność", "droplet", pogoda.humidity, "%")
:status("cisnienie", "Ciśnienie", "speedometer2", pogoda.pressure, "hPa")
:status("chmury", "Zachmurzenie", "clouds", pogoda.clouds, "%")
dash:section("Wiatr i opady", "wind", { columns = 2 })
:status("wiatr", "Wiatr", "wind", pogoda.windText)
:status("opady", "Opady", "cloud-rain", pogoda.rain, "mm/h")
dash:section("Odczyt", "clock", { columns = 2 })
:status("odczyt", "Ostatni odczyt", "clock", pogoda.updated)
:button("odswiez", "Odśwież", "arrow-clockwise", pogoda.refresh)
dash:section("Historia — 24h", "graph-up", { columns = 1 })
:chart("ch_temp", "Temperatura", "pogoda:temp",
{ unit = "°C", range = "24h", span = 3, fill = true })
:chart("ch_cisnienie", "Ciśnienie", "pogoda:cisnienie",
{ unit = "hPa", range = "24h", span = 3 })
dash:build()Przycisk Odśwież pobiera pogodę od razu, bez czekania na kolejny cykl pluginu.
Krok 5: Rejestracja w modules/init.lua#
vCLU sam ładuje tylko pliki leżące bezpośrednio w modules/. Katalogi trzeba wskazać w modules/init.lua, najpierw moduł, potem dashboard:
require("pogoda") -- modules/pogoda/init.lua
require("dashboards/pogoda") -- modules/dashboards/pogoda.luaZapisz (Ctrl+S) i kliknij Reload. Błędy zobaczysz w panelu na dole edytora.
Krok 6: Dashboard#
Otwórz http://<adres-vclu>:8080/d/pogoda. Dashboard jest też na liście w panelu, na stronie Dashboards.

Plugin pobiera pogodę raz na godzinę, a dashboard odświeża się co minutę, więc wartości zmieniają się co godzinę. Pole Ostatni odczyt pokazuje, kiedy plugin pobrał dane.
Dalej: automatyka na deszcz#
Plugin ogłasza zdarzenie weather:rain, gdy po suchym odczycie przychodzi odczyt z opadem. Dopisz reakcję w module pogoda, przed return M, np. powiadomienie albo zwinięcie markizy:
EventBus:on("weather:rain", function(data)
print(string.format("[POGODA] Zaczęło padać: %.1f mm/h", data.rain))
-- tu np. markiza:close()
end)Plugin pobiera pogodę co interval sekund, więc reakcja przyjdzie z takim opóźnieniem. Do markizy, która ma zwinąć się zanim zmoknie, lepszy jest czujnik deszczu na budynku. Pogoda z internetu wystarczy do powiadomień i rzeczy mniej pilnych.
Pozostałe metody pluginu (getTemperature(), getHumidity(), getWind()…) opisuje README pluginu.