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#

ParametrWartosc
Max liczba timerow1000
Min interwal (every)10ms
Min timeout (after)1ms
Max okres24h (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/false

getAllScenes()#

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)    -- 50

lerp(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)  -- 25

map(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.1

Logowanie - 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#

PoziomOpis
debugSzczegolowe informacje (domyslnie wylaczone)
infoNormalne komunikaty
warnOstrzezenia
errorBledy

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#

FunkcjaOpis
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