HomeKit#

vCLU działa jako bridge HomeKit - pojawia się w aplikacji Dom (Apple Home) jako jedno urządzenie-mostek, pod którym widoczne są wszystkie wyeksponowane obiekty (lampy, przełączniki, rolety, czujniki).

Jak to działa#

graph TD
    app["Aplikacja Dom<br/>(iPhone/iPad/Mac)"]
    bridge["vCLU HomeKit Bridge (:5123)"]
    sw["switch<br/>(DOUT)"]
    cv["cover<br/>(ROLLER)"]
    sn["sensor<br/>(DIN)"]

    app <-->|"HAP (szyfrowane, lokalne)"| bridge
    bridge --- sw
    bridge --- cv
    bridge --- sn
  1. vCLU startuje bridge HAP na porcie 5123 (domyślnie)
  2. Bridge ogłasza się w sieci przez mDNS/Bonjour
  3. Użytkownik paruje bridge w aplikacji Dom podając PIN
  4. Wyeksponowane obiekty pojawiają się jako akcesoria HomeKit
  5. Zmiany stanu propagują się w czasie rzeczywistym

Konfiguracja#

Z panelu webowego#

Na stronie /homekit:

  • Włącz/wyłącz bridge
  • Ustaw PIN, nazwę bridge, port
  • Kliknij “Restart Bridge” po zmianach

Przez .vclu.json#

{
  "homeKit": {
    "enabled": true,
    "pin": "00102003",
    "port": 5123,
    "bridgeName": "vCLU Bridge",
    "serialNumber": "VCLU-001",
    "refreshInterval": 300
  }
}
ParametrOpisDomyślnie
enabledWłącz bridgefalse
pin8-cyfrowy PIN do parowania00102003
portPort HAP5123
bridgeNameNazwa bridge w aplikacji DomvCLU Bridge
serialNumberNumer seryjnyVCLU-001
refreshIntervalOdświeżanie stanów co X sekund (0 = wyłączone)300

API#

# Status bridge
curl http://vclu:3000/api/homekit/status

# Restart bridge (przeładuj akcesoria)
curl -X POST http://vclu:3000/api/homekit/restart

Parowanie#

  1. Włącz HomeKit w panelu /homekit
  2. Otwórz aplikację Dom na iPhonie/iPadzie
  3. Stuknij “+” → “Dodaj akcesorium”
  4. Wybierz “vCLU Bridge” (lub wpisz PIN ręcznie)
  5. Podaj PIN (domyślnie 001-02-003)

Baza parowania przechowywana jest w katalogu homekit-db/. Nie usuwaj tego katalogu - utracisz parowanie i trzeba będzie usunąć bridge z aplikacji Dom i sparować ponownie.

Eksponowanie obiektów#

HomeKit pokazuje tylko obiekty wyeksponowane przez expose() z flagą homekit = true (domyślnie włączona):

-- Przekaźnik GPIO jako przełącznik w HomeKit
local relay = GPIO_DOUT:new("RELAY1", 17, {activeLow = true})
expose(relay, "switch", {name = "Lampa salon"})

-- Roleta
expose(_:get("CLU.ROLLER1"), "cover", {name = "Roleta kuchnia"})

-- Czujnik temperatury
expose({value = 22.5}, "temperature", {name = "Temp salon"})

-- Czujnik ruchu
expose(btn, "motion", {name = "Ruch korytarz"})

-- Scena (w HomeKit jako przycisk - wykonaj i wróć do OFF)
scene("wieczor", function()
    _:get("CLU.DOUT1"):execute(DOUT.METHOD_SWITCH_ON)
end)
expose(getScene("wieczor"), "scene", {name = "Tryb wieczorny"})

Kontrola integracji#

-- Tylko HomeKit (bez MQTT/HA)
expose(obj, "switch", {name = "Lamp"}):homekitOnly()

-- Tylko MQTT (bez HomeKit)
expose(obj, "switch", {name = "Lamp"}):mqttOnly()

-- Tylko odczyt (widoczne ale nie sterowane)
expose(obj, "sensor", {name = "Temp"}):readonly()

Auto-expose z registry#

-- Wyeksponuj wszystkie obiekty z OM registry
-- Respektuje AccessControl
exposeRegistry()

Obsługiwane typy#

Typ exposeAkcesorium HomeKitOpis
switchSwitchprzełącznik ON/OFF
lightLightbulblampa ON/OFF
dimmerLightbulblampa z jasnością 0-100
coverWindowCoveringroleta z pozycją 0-100
sensorContactSensorczujnik binarny
motionMotionSensorczujnik ruchu
temperatureTemperatureSensortemperatura (°C)
humidityTemperatureSensorwilgotność (%)
sceneSwitch (bezstanowy)wykonaj i wróć do OFF
numberSwitchwartość > 0 = ON

Przepływ stanów i komend#

Stan zmieniony w vCLU - aktualizacja w HomeKit#

graph TD
    A["Obiekt Lua zmienia wartość"]
    B["StateBus:emit('state_changed',<br/>{path, value, type})"]
    C["bootstrap: __go_homekit_notify<br/>(path, value, type)"]
    D["Go: Server.NotifyStateChange()<br/>→ characteristic.SetValue()"]
    E["HAP powiadamia sparowane<br/>urządzenia Apple"]

    A --> B --> C --> D --> E

Komenda z HomeKit - wykonanie w vCLU#

graph TD
    A["Użytkownik w aplikacji Dom stuka 'włącz'"]
    B["HAP: OnValueRemoteUpdate(true)"]
    C["Go: luaExecutor.Execute<br/>('ExposedObjects:get(path):setValue(1)')"]
    D["Lua: obiekt.set() / obiekt.execute()"]
    E["UDP → zewnętrzny kontroler<br/>wykonuje komendę"]

    A --> B --> C --> D --> E

Odświeżanie periodyczne#

Oprócz zdarzeń w czasie rzeczywistym, bridge co refreshInterval sekund (domyślnie 300 = 5 min) odpytuje aktualny stan każdego akcesorium - zabezpieczenie przed przegapionymi aktualizacjami.

AccessControl#

Obiekty mogą mieć ograniczony dostęp w HomeKit:

PoziomWidocznośćSterowanie
fulltaktak
readonlytaknie
hiddennienie

Więcej: AccessControl