Wielozadaniowość#
vCLU obsługuje jednocześnie wiele zadań: odbiera wiadomości MQTT, serwuje panel webowy, odpala timery, monitoruje stan pinów GPIO i obsługuje żądania agenta AI. Pomimo tej złożoności, pisanie automatyzacji jest proste i bezpieczne.
Zasada nr 1: Twój kod Lua jest bezpieczny#
Twój kod automatyzacji wykonuje się sekwencyjnie – jeden callback po drugim, nigdy równocześnie. Nie musisz się martwić o:
- wyścigi danych (dwa skrypty zmieniające tę samą zmienną)
- blokady (deadlocki)
- niespójny stan urządzeń
To fundamentalna cecha vCLU. Mimo że w tle dzieje się wiele rzeczy jednocześnie, Twój kod Lua zawsze widzi spójny stan systemu.
Co działa w tle#
graph TD
subgraph "vCLU - przetwarzanie w tle"
mqtt["MQTT<br/>(broker)"]
web["Serwer<br/>web"]
mcp["Agent AI<br/>(MCP)"]
timers[Timery]
gpio["GPIO<br/>(czujniki)"]
metrics["Metryki<br/>(zbieranie)"]
queue["Kolejka zadań dla Lua<br/>(uporządkowana, jedno po drugim)"]
lua["Twój kod Lua<br/>(bezpieczne, sekwencyjne wykonanie)"]
mqtt --> queue
web --> queue
mcp --> queue
timers --> queue
gpio --> queue
metrics --> queue
queue --> lua
endKażdy podsystem (MQTT, timery, GPIO, serwer web) działa niezależnie i wrzuca zadania do kolejki. Lua przetwarza je jedno po drugim, co 10 milisekund.
Co to oznacza w praktyce#
Twoje callbacki nigdy nie kolidują#
-- Te dwa callbacki NIGDY nie wykonają się jednocześnie,
-- nawet jeśli oba zdarzenia nadejdą w tym samym momencie:
switch1:onChange(function()
-- ten kod wykona się w całości...
end)
switch2:onChange(function()
-- ...zanim ten zacznie działać
end)Trzymaj callbacki krótkie#
Ponieważ kod wykonuje się sekwencyjnie, długo działający callback blokuje przetwarzanie innych zdarzeń. Zasada: callback powinien trwać poniżej 100ms.
-- ZLE: długa operacja w callbacku
switch:onChange(function()
-- przetwarzanie trwające sekundy...
-- w tym czasie inne zdarzenia czekają!
end)
-- DOBRZE: szybka reakcja + timer do cięższej pracy
switch:onChange(function()
-- szybka reakcja (ustaw flagę, wyślij komendę)
needsProcessing = true
end)
every(5000, function()
if needsProcessing then
-- cięższa logika wykonuje się w osobnym cyklu
needsProcessing = false
end
end)Operacje sieciowe nie blokują#
Zapytania HTTP i publikacje MQTT są asynchroniczne – Twój kod wysyła żądanie i dostaje odpowiedź w callbacku, bez blokowania reszty systemu:
-- To NIE blokuje -- odpowiedź przyjdzie w callbacku
local http = HTTP:new()
http:asyncGET("http://api.weather.com/data", function(response)
log.info("Pogoda: " .. response.body)
end)
-- kod tu wykonuje się natychmiast, nie czeka na odpowiedźKiedy vCLU wydaje się wolne#
Jeśli zauważysz opóźnienia w reakcji systemu, najczęstsze przyczyny to:
- Zbyt długi callback – sprawdź logi, czy któryś skrypt nie trwa zbyt długo. Logger pokaże ostrzeżenie.
- Zbyt wiele timerów – system obsługuje do 1000 aktywnych timerów. Sprawdź, czy nie tworzysz timerów w pętli bez ich czyszczenia.
- Przeciążony MQTT – bufor mieści 1000 wiadomości. Przy bardzo dużym ruchu MQTT najstarsze wiadomości mogą być odrzucane.
Diagnostyka#
Sprawdź logi systemowe w panelu webowym. vCLU loguje:
- callbacki przekraczające timeout
- odrzucone wiadomości MQTT (przepełniony bufor)
- błędy w skryptach Lua
Podsumowanie#
| Aspekt | Jak to działa |
|---|---|
| Twój kod Lua | Sekwencyjny, bezpieczny, bez konfliktów |
| MQTT, timery, GPIO | Działają w tle, kolejkują zadania |
| Serwer web i MCP | Czekają na swoją kolej do wykonania Lua |
| Operacje sieciowe (HTTP, MQTT) | Asynchroniczne – nie blokują kodu |
| Cykl przetwarzania | Co 10ms system sprawdza wszystkie kolejki |