Satel Integra#

Natywna integracja z centralami alarmowymi Satel Integra / Integra Plus przez moduł ETHM-1 Plus (TCP, port 7094). Strefy, partycje, wyjścia i czujniki temperatury centrali stają się zwykłymi obiektami vCLU — automatycznie dostępnymi w Home Assistant, HomeKit, MCP i na dashboardach, bez dodatkowej konfiguracji tych warstw.

Wymagania#

  • Centrala Integra (24/32/64/128/256 Plus) z modułem ETHM-1 Plus (firmware ≥ 2.00) lub INT-RS Plus. Podstawowa linia PERFECTA 16/32 nie wspiera protokołu integracyjnego.
  • Włączona integracja w ustawieniach modułu (DLOADX → ETHM-1 → „Integracja").
  • Opcjonalnie: klucz integracji (szyfrowanie AES-192) — vCLU wspiera oba tryby, szyfrowany i otwarty.
  • Kod użytkownika (PIN) — wymagany tylko do sterowania (uzbrajanie, wyjścia). Sam odczyt stanów działa bez PIN-u.
ETHM-1 obsługuje **jednego klienta integracji naraz**. Jeśli z centralą łączy się już inny system (np. Home Assistant bezpośrednio), vCLU zgłosi błąd „Busy". Wyłącz tamto połączenie — stany i tak trafią do HA przez vCLU.

Konfiguracja przez panel WWW (zalecana)#

Strona Integracje → Satel w panelu vCLU:

  1. Connection — adres ETHM-1, port, PIN, klucz integracji, interwał odpytywania, domyślny tryb uzbrojenia. Przycisk Test connection łączy się z centralą i pokazuje wykryty model (np. INTEGRA 128 v1.23) — od razu weryfikuje też poprawność klucza szyfrowania. Po zapisie wymagany jest restart vCLU.
  2. Zones & Objects — przycisk Scan panel odczytuje z centrali nazwy wszystkich stref, partycji i wyjść (trwa kilka sekund). Zaznacz te, które vCLU ma monitorować — zaznaczenia zapisują się jako zakresy w konfiguracji. Można też wpisać zakresy ręcznie (format 1-16,20,25).
  3. Live State — podgląd stanów na żywo: partycje (rozbrojona / uzbrojona / ALARM), strefy (OK / naruszona / sabotaż / blokada), wyjścia i temperatury.

Konfiguracja w .vclu.json#

Sekcja satel:

{
  "satel": {
    "enabled": true,
    "host": "192.168.1.100",
    "port": 7094,
    "userCode": "1234",
    "encryptionKey": "",
    "pollInterval": 1000,
    "zones": "1-32",
    "partitions": "1-4",
    "outputs": "1-16",
    "tempZones": "",
    "armMode": 0,
    "allowDisarm": false,
    "allowForceArm": false
  }
}
KluczDomyślnieOpis
enabledfalseWłącza integrację (wymaga restartu)
hostAdres IP modułu ETHM-1 Plus
port7094Port integracji
userCodePIN użytkownika do komend sterujących
encryptionKey""Klucz integracji (AES-192); pusty = bez szyfrowania
pollInterval1000Interwał odpytywania stanów w ms (250–10000)
zones"1-32"Monitorowane strefy
partitions"1-4"Monitorowane partycje
outputs"1-16"Sterowalne wyjścia
tempZones""Strefy z czujnikami temperatury (ATD-100)
armMode0Domyślny tryb uzbrojenia (0–3)
allowDisarmfalseZezwala na rozbrajanie i kasowanie alarmu
allowForceArmfalseZezwala na wymuszone uzbrojenie (ignoruje naruszone strefy)

Obiekty#

Po starcie vCLU tworzy obiekty dla skonfigurowanych zakresów i rejestruje je w _registry. Nazwy odczytuje z centrali (można nadpisać własnymi). Obiekty mają standardowe API Virtual* — działają z expose(), tagami, scenami i dashboardami jak każdy inny obiekt.

ŚcieżkaKlasaTyp exposeOpis
satel.zone.NSatelZonesensorStrefa: 1 = naruszona. Dodatkowo isTamper(), isAlarm(), isBypassed()
satel.partition.NSatelPartitionswitchPartycja: on = uzbrojona, switchOn() = uzbrojenie
satel.partition.N.alarmVirtualSensorsensorAlarm partycji (tylko odczyt)
satel.output.NSatelOutputswitchWyjście centrali
satel.temp.NSatelThermometertemperatureTemperatura ze strefy (ATD-100)
-- user.lua / modules/
local czujkaSalon = _registry["satel.zone.1"]
czujkaSalon:onSwitchOn(function()
    print("Ruch w salonie")
end)

-- alarm na partycji -> powiadomienie
_registry["satel.partition.1"]:onAlarm(function()
    print("ALARM na parterze!")
end)

-- uzbrojenie zamyka rolety
_registry["satel.partition.1"]:onArmed(function()
    _registry:byTag("rolety"):setValue(0)
end)

API Lua: Satel.*#

FunkcjaOpis
Satel.isConnected()Czy sesja z centralą jest aktywna
Satel.getZone(n){ violated, tamper, alarm, bypass, name } — odczyt z cache, natychmiastowy
Satel.getPartition(n){ armed, alarm, fireAlarm, entryTime, exitTime, name }
Satel.getOutput(n){ active, name }
Satel.getTemperature(n)Temperatura w °C lub nil
Satel.armPartition(n, mode)Uzbrojenie (asynchroniczne)
Satel.disarmPartition(n)Rozbrojenie — zablokowane bez allowDisarm
Satel.clearAlarm(n)Kasowanie alarmu — zablokowane bez allowDisarm
Satel.forceArm(n, mode)Wymuszone uzbrojenie — zablokowane bez allowForceArm
Satel.setOutput(n, on)Sterowanie wyjściem
Satel.zone(n) / partition(n) / output(n) / temp(n)Dostęp do obiektów

Wszystkie odczyty trafiają do cache po stronie Go — nigdy nie blokują pętli Lua. Komendy sterujące są kolejkowane (fire-and-forget); wynik wraca zdarzeniem.

Zdarzenia (EventBus)#

ZdarzeniePayload
satel.connection{ connected, panelType, message }
satel.zone.N.OnChange / satel.OnZoneChangestan strefy
satel.partition.N.OnChange / satel.OnPartitionChangestan partycji
satel.output.N.OnChangestan wyjścia
satel.temp.N.OnChange{ zone, value }
satel.result{ op, number, ok, code, message } — wynik komendy sterującej

Bezpieczeństwo#

Alarm to nie żarówka — domyślne ustawienia są restrykcyjne:

  • Rozbrajanie, kasowanie alarmu i wymuszone uzbrojenie są domyślnie zablokowane (allowDisarm: false, allowForceArm: false). Blokada działa w warstwie Go — żaden skrypt Lua, plugin, MQTT, HomeKit ani bot MCP nie może jej obejść.
  • Uzbrajanie i sterowanie wyjściami działają normalnie — to operacje, które najwyżej podnoszą poziom ochrony.
  • Po włączeniu allowDisarm rozbroić alarm może wszystko, co steruje obiektami vCLU (HA, HomeKit, dashboardy, boty MCP z uprawnieniem control). Włączaj świadomie.
  • PIN i klucz integracji nie są nigdy wysyłane do przeglądarki — formularz w panelu WWW jest write-only (puste pole = bez zmian).
  • PIN jest przechowywany w .vclu.json w postaci jawnej — protokół Satela wymaga przesłania kodu w każdej komendzie sterującej, więc nie może być hashowany. Chroń katalog danych vCLU tak jak inne sekrety (hasła MQTT, klucze API).

Architektura#

Całe I/O z centralą działa w osobnej goroutine Go (protokół Satela jest sekwencyjny — jedna komenda, jedna odpowiedź). vCLU odpytuje stany co pollInterval (bitmapy stref, partycji i wyjść), wykrywa różnice i publikuje tylko zmiany. Lua czyta wyłącznie ze snapshotu i drenuje kolejkę zdarzeń timerem co 100 ms — dokładnie tak samo jak integracja MQTT. Połączenie wznawia się automatycznie (exponential backoff), a po reconnect stany obiektów są odświeżane.

Ograniczenia#

  • Wymagany moduł ETHM-1 Plus lub INT-RS Plus (PERFECTA 16/32 — brak wsparcia).
  • Jeden klient integracji na ETHM-1 — patrz uwaga wyżej.
  • Stany są odpytywane (domyślnie co 1 s), nie push — opóźnienie zmiany to maks. jeden interwał.
  • Blokowanie/pominięcie stref (bypass) jest odczytywane, ale nie sterowane.