Helpery#
vCLU udostepnia zestaw globalnych funkcji pomocniczych dostepnych w user.lua i om.lua. Wszystkie sa zdefiniowane w Helpers.lua i ladowane automatycznie przy starcie runtime.
Timery - after / every / cancel#
Asynchroniczne timery oparte na Go (TimerManager). Rejestruja callback i wracaja natychmiast - nie blokuja runtime.
after(ms, callback)#
Wykonaj funkcje raz, po opoznieniu.
-- Wlacz lampe za 5 sekund
after(5000, function()
RELAY1:execute(DOUT.METHOD_SWITCH_ON)
end)Zwraca ID timera (do anulowania):
local id = after(10000, function()
log.info("za pozno!")
end)
-- Anuluj zanim sie odpali
cancel(id)every(ms, callback)#
Wykonuj funkcje cyklicznie co ms milisekund.
-- Loguj temperature co minute
every(60000, function()
local temp = _:get("CLU.ANA1"):get(0)
log.info("Temperatura: " .. temp)
end)cancel(id)#
Anuluj timer (jednorazowy lub cykliczny).
local id = every(1000, function() print("tick") end)
-- Po 10 sekundach - zatrzymaj
after(10000, function()
cancel(id)
end)Lua w vCLU jest jednowatkowy. **Nigdy nie uzywaj petli oczekujacej** (`while`, `repeat`, busy-wait) do opoznien - zablokuje to caly runtime (zdarzenia, MQTT, GPIO, timery). Zawsze uzywaj `after()` lub `every()`. ```lua -- ZLE - zawiesi CLU! local start = os.clock() while os.clock() - start < 1 do end doSomething() -- DOBRZE after(1000, function() doSomething() end) ```
Limity timerow#
| Parametr | Wartosc |
|---|---|
| Max liczba timerow | 1000 |
| Min interwal (every) | 10ms |
| Min timeout (after) | 1ms |
| Max okres | 24h (86 400 000ms) |
Sceny - scene / runScene / getScene#
Sceny to nazwane funkcje, ktore mozna wywolywac z kodu, eksponowac do Home Assistant / HomeKit, i wlaczac/wylaczac dynamicznie.
scene(name, fn)#
Definiuje scene. Zwraca obiekt sceny.
scene("wieczor", function()
_:get("CLU.DOU5048"):execute(DOUT.METHOD_SWITCH_ON)
_:get("CLU.DOU4458"):execute(DOUT.METHOD_SWITCH_OFF)
end)runScene(name, …)#
Uruchamia scene po nazwie. Argumenty sa przekazywane do funkcji sceny.
runScene("wieczor")getScene(name)#
Zwraca obiekt sceny (do eksponowania lub sterowania).
local s = getScene("wieczor")
s:run() -- uruchom
s:disable() -- wylacz (run() nie zrobi nic)
s:enable() -- wlacz ponownie
s:isEnabled() -- true/falsegetAllScenes()#
Zwraca posortowana liste nazw wszystkich scen.
local names = getAllScenes()
-- {"poranek", "wieczor", "wylacz_wszystko"}scenes.nazwa#
Dostep do scen przez namespace z kropka:
scenes.wieczor:run()
scenes.wieczor:disable()Eksponowanie scen#
Sceny mozna wyeksponowac do Home Assistant i HomeKit:
scene("wieczor", function()
_:get("CLU.DOU5048"):execute(DOUT.METHOD_SWITCH_ON)
end)
expose(getScene("wieczor"), "scene", {name = "Tryb wieczorny"})W HomeKit scena pojawia sie jako przycisk (wlacz → wykonaj → wroc do OFF). W Home Assistant jako switch.
Przyklady scen#
-- Scena z argumentami
scene("ustaw_jasnosc", function(poziom)
_:get("CLU.DIMM1"):set(0, poziom or 50)
end)
runScene("ustaw_jasnosc", 80)
-- Wlacz scene na przycisk GPIO
local btn = GPIO_DIN:new("BTN1", 27)
btn:add_event(DIN.EVENT_ON_CLICK, function()
runScene("wieczor")
end)
-- Scena warunkowa
scene("auto_swiatlo", function()
local lampa = _:get("CLU.DOU5048")
if lampa:get(DOUT.FEATURE_VALUE) == 1 then
lampa:execute(DOUT.METHOD_SWITCH_OFF)
else
lampa:execute(DOUT.METHOD_SWITCH_ON)
end
end)
-- Wylacz scene na noc
scene("tryb_nocny", function()
scenes.auto_swiatlo:disable()
end)
scene("tryb_dzienny", function()
scenes.auto_swiatlo:enable()
end)Sekwencje - sequence#
Sekwencja to lancuch akcji i opoznien, wykonywany asynchronicznie. Alternatywa dla zagniezdzonych after().
Tworzenie i uruchamianie#
sequence()
:add(function() r1:execute(DOUT.METHOD_SWITCH_ON) end)
:wait(500)
:add(function() r2:execute(DOUT.METHOD_SWITCH_ON) end)
:wait(500)
:add(function() r3:execute(DOUT.METHOD_SWITCH_ON) end)
:run()Odpowiednik z after() (mniej czytelny):
r1:execute(DOUT.METHOD_SWITCH_ON)
after(500, function()
r2:execute(DOUT.METHOD_SWITCH_ON)
after(500, function()
r3:execute(DOUT.METHOD_SWITCH_ON)
end)
end)Callback po zakonczeniu#
sequence()
:add(function() r1:execute(DOUT.METHOD_SWITCH_ON) end)
:wait(1000)
:add(function() r2:execute(DOUT.METHOD_SWITCH_ON) end)
:run(function()
log.info("Sekwencja zakonczona")
end)Zatrzymywanie#
local seq = sequence()
:add(function() r1:execute(DOUT.METHOD_SWITCH_ON) end)
:wait(5000)
:add(function() r2:execute(DOUT.METHOD_SWITCH_ON) end)
:run()
-- Przerwij sekwencje (r2 sie nie wlaczy)
after(2000, function()
seq:stop()
end)Sekwencja nie moze byc uruchomiona ponownie dopoki trwa - kolejne wywolanie `run()` jest ignorowane.
Kaskada - cascade#
Wykonuje funkcje na kazdym obiekcie w grupie z opoznieniem miedzy nimi.
-- Wlacz wszystkie lampy po kolei, co 300ms
local lampy = _:byTag("lights")
cascade(lampy, 300, function(obj, i)
obj:execute(DOUT.METHOD_SWITCH_ON)
end)Dostepna tez jako metoda na RemoteGroup:
_:byTag("lights"):cascade(300, function(obj, i)
obj:execute(DOUT.METHOD_SWITCH_ON)
end)Matematyka - clamp / lerp / map / round#
clamp(value, min, max)#
Ogranicza wartosc do zakresu.
clamp(150, 0, 100) -- 100
clamp(-5, 0, 100) -- 0
clamp(50, 0, 100) -- 50lerp(a, b, t)#
Interpolacja liniowa miedzy a i b. Parametr t od 0 do 1.
lerp(0, 100, 0.5) -- 50
lerp(0, 100, 0.25) -- 25map(value, inMin, inMax, outMin, outMax)#
Mapuje wartosc z jednego zakresu na drugi.
-- Czujnik 0-1023 → jasnosc 0-100
local brightness = map(sensorValue, 0, 1023, 0, 100)
-- Temperatura 15-30°C → pozycja zaworu 0-100%
local valve = map(temp, 15, 30, 0, 100)round(value, decimals)#
Zaokragla do podanej liczby miejsc po przecinku.
round(3.14159) -- 3
round(3.14159, 2) -- 3.14
round(3.14159, 1) -- 3.1Logowanie - log#
Globalny modul logowania z czterema poziomami. Logi trafiaja na stdout procesu Go.
log.debug("Szczegoly: pin=%d, value=%d", pin, val)
log.info("System uruchomiony")
log.warn("Brak polaczenia z brokerem")
log.error("Blad GPIO: %s", err)Poziomy#
| Poziom | Opis |
|---|---|
debug | Szczegolowe informacje (domyslnie wylaczone) |
info | Normalne komunikaty |
warn | Ostrzezenia |
error | Bledy |
Zmiana poziomu#
log.level = "debug" -- pokaz wszystko
log.level = "warn" -- tylko ostrzezenia i bledy`log.*` uzywa `string.format` - mozna uzywac formatowania: `log.info("Wartosc: %d, nazwa: %s", 42, "test")`.
Debug - inspect / dump#
inspect(value, depth)#
Zwraca czytelna reprezentacje dowolnej wartosci Lua. Rozpoznaje typy vCLU: Plugin, RemoteObject, RemoteGroup, obiekty registry.
local s = inspect(_:get("CLU.DOU5048"))
-- "RemoteObject<DOU5048>\n type: DOUT\n value: 0\n ..."
inspect({1, 2, 3}) -- "[1, 2, 3]"
inspect({a = 1, b = "x"}) -- "{\n a: 1,\n b: \"x\"\n}"
inspect(nil) -- "nil"Parametr depth (domyslnie 2) kontroluje glebokosc rekurencji dla zagniezdzonych tabel.
dump(value, label)#
Wypisuje inspect() przez print(). Opcjonalny label.
dump(_:get("CLU.DOU5048"))
dump(_:byTag("lights"), "Lampy")
-- Lampy: RemoteGroup<lights> (3 objects)
-- objects: [DOU5048, DOU4458, DOU3327]Stan obiektow - saveState / restoreState#
Dostepne na RemoteObject i RemoteGroup. Pozwalaja zapisac i przywrocic stan obiektow.
-- Zapisz stan przed scena
local lampy = _:byTag("lights")
local stan = lampy:saveState()
-- Uruchom scene "kino" (wylacz wszystkie lampy)
runScene("kino")
-- Po filmie - przywroc poprzedni stan
after(2 * 60 * 60 * 1000, function() -- po 2 godzinach
lampy:restoreState(stan)
end)Na pojedynczym obiekcie:
local lampa = _:get("CLU.DOU5048")
local stan = lampa:saveState()
-- ... operacje ...
lampa:restoreState(stan)Podsumowanie#
| Funkcja | Opis |
|---|---|
after(ms, fn) | Jednorazowy timer (asynchroniczny) |
every(ms, fn) | Cykliczny timer |
cancel(id) | Anuluj timer |
scene(name, fn) | Zdefiniuj scene |
runScene(name, ...) | Uruchom scene |
getScene(name) | Pobierz obiekt sceny |
getAllScenes() | Lista nazw scen |
sequence() | Lancuch akcji z opoznieniami |
cascade(group, ms, fn) | Akcja na grupie z opoznieniem |
clamp(v, min, max) | Ogranicz do zakresu |
lerp(a, b, t) | Interpolacja liniowa |
map(v, iMin, iMax, oMin, oMax) | Mapowanie zakresow |
round(v, dec) | Zaokraglenie |
log.info(fmt, ...) | Logowanie (debug/info/warn/error) |
inspect(value, depth) | Czytelna reprezentacja wartosci |
dump(value, label) | Wypisz inspect na stdout |