Home Assistant#
vCLU integruje się z Home Assistant przez MQTT Discovery - automatycznie publikuje konfigurację urządzeń, więc HA wykrywa je bez ręcznego pisania YAML.
Jak to działa#
MQTT Broker
(wbudowany vCLU)
│
┌───────────────────┼───────────────────┐
│ │ │
Discovery config State updates Komendy
homeassistant/... vclu/.../state vclu/.../set
│ │ │
▼ ▼ ▼
HA wykrywa urządzenie HA widzi stan HA steruje urządzeniem- Discovery - vCLU publikuje wiadomości na topic
homeassistant/{typ}/{id}/configz payloadem JSON opisującym urządzenie (nazwa, topiki stanów/komend, typ). HA automatycznie tworzy encję. - Stany - gdy obiekt zmieni wartość, vCLU publikuje nowy stan na
vclu/{clu}/{komponent}/{obiekt}/state - Komendy - HA wysyła komendy (ON/OFF, OPEN/CLOSE, brightness) na
vclu/{clu}/{komponent}/{obiekt}/set, vCLU odbiera i wywołuje odpowiednią metodę na obiekcie
Wymagania#
- Wbudowany broker MQTT musi być włączony (patrz MQTT)
- Home Assistant musi mieć skonfigurowaną integrację MQTT wskazującą na adres IP vCLU, port 1883
Włączenie integracji#
Z panelu webowego#
Na stronie /mqtt kliknij kolejno:
- Publish HA Discovery - publikuje konfigurację wszystkich obiektów z OM
- Enable HA Commands - włącza nasłuchiwanie na komendy z HA i publikowanie stanów
Przez API#
# 1. Opublikuj discovery (konfiguracja urządzeń)
curl -X POST http://vclu:3000/api/ha/discovery/publish
# 2. Włącz obsługę komend i stanów
curl -X POST http://vclu:3000/api/ha/commands/enableOdpowiedź discovery:
{
"success": true,
"published": 42,
"states": 42,
"files": 2,
"errors": []
}Obsługiwane typy urządzeń#
| Typ Grenton | Komponent HA | Sterowanie |
|---|---|---|
| DOUT | switch | ON / OFF |
| DIN | binary_sensor | tylko odczyt |
| DIMMER | light | ON / OFF + brightness |
| LEDRGB | light | ON / OFF + brightness + kolor RGB |
| ROLLER, ROLLER_SH | cover | OPEN / CLOSE / STOP + pozycja |
| AnalogIN | sensor | tylko odczyt |
| AnalogOUT | number | wartość liczbowa |
| GPIO_DOUT | switch | ON / OFF |
| GPIO_DIN | binary_sensor | tylko odczyt |
| Timer | - | nie eksponowany |
Topiki MQTT#
Wszystkie topiki używają prefixu vclu/ i ID CLU:
# Discovery (retain, publikowane raz)
homeassistant/switch/vclu_clu221000290_dou5048/config
# Stan (retain, aktualizowany przy zmianie)
vclu/clu221000290/switch/dou5048/state → "ON" / "OFF"
# Komenda (z HA)
vclu/clu221000290/switch/dou5048/set ← "ON" / "OFF"Topiki dla poszczególnych typów#
Switch (DOUT):
.../switch/{id}/state → "ON" / "OFF"
.../switch/{id}/set ← "ON" / "OFF"Light (DIMMER):
.../light/{id}/state → "ON" / "OFF"
.../light/{id}/set ← "ON" / "OFF"
.../light/{id}/brightness → 0–100
.../light/{id}/brightness/set ← 0–100Light (LEDRGB):
.../light/{id}/state → {"state":"ON","brightness":80,"color":{"r":255,"g":100,"b":50}}
.../light/{id}/set ← {"state":"ON","brightness":80,"color":{"r":255,"g":100,"b":50}}Cover (ROLLER):
.../cover/{id}/state → "open" / "closed"
.../cover/{id}/set ← "OPEN" / "CLOSE" / "STOP"
.../cover/{id}/position → 0–100
.../cover/{id}/position/set ← 0–100Binary sensor (DIN):
.../binary_sensor/{id}/state → "ON" / "OFF"Number (AnalogOUT):
.../number/{id}/state → wartość liczbowa
.../number/{id}/set ← wartość liczbowaExposedObjects - obiekty z pluginów i user.lua#
Obiekty które nie pochodzą z OM (np. z pluginów, GPIO, user.lua) można wyeksponować ręcznie za pomocą expose():
-- Przekaźnik GPIO jako switch w HA
local relay = GPIO_DOUT:new("RELAY1", 17, {activeLow = true})
expose(relay, "switch", {name = "Przekaźnik GPIO"})
-- Przycisk GPIO jako binary_sensor
local btn = GPIO_DIN:new("BTN1", 27)
expose(btn, "sensor", {name = "Przycisk"})
-- Czujnik temperatury (wartość liczbowa)
expose({value = 22.5}, "temperature", {name = "Temp salon"})
-- Scena
scene("wieczor", function()
_:get("CLU.DOUT1"):execute(DOUT.METHOD_SWITCH_ON)
_:get("CLU.DOUT2"):execute(DOUT.METHOD_SWITCH_OFF)
end)
expose(getScene("wieczor"), "scene", {name = "Tryb wieczorny"})Obiekty wyeksponowane przez expose() pojawiają się w HA na topikach:
vclu/exposed/{base}/{komponent}/{id}/state
vclu/exposed/{base}/{komponent}/{id}/setexposeRegistry - auto-expose z OM#
-- Wyeksponuj wszystkie obiekty z registry (z OM)
-- Respektuje AccessControl - ukryte obiekty są pomijane
exposeRegistry()Obsługiwane typy expose#
| Typ | HA komponent | Opis |
|---|---|---|
switch | switch | ON/OFF |
light | light | ON/OFF + brightness |
dimmer | light | ON/OFF + brightness (0–100) |
sensor | binary_sensor | ON/OFF (odczyt) |
motion | binary_sensor | czujnik ruchu |
temperature | sensor | temperatura (°C) |
humidity | sensor | wilgotność (%) |
cover | cover | roleta z pozycją |
number | number | wartość liczbowa |
scene | switch | scena (bezstanowa) |
button | button | przycisk (zdarzenie) |
lock | lock | zamek |
fan | fan | wentylator z prędkością |
garage_door | cover | brama garażowa |
AccessControl#
Obiekty mogą mieć ograniczony dostęp przez MQTT:
| Poziom | Stany | Komendy |
|---|---|---|
full | publikowane | obsługiwane |
readonly | publikowane | ignorowane |
hidden | pomijane | pomijane |
Ukryte obiekty nie generują discovery - nie pojawiają się w HA.
Więcej: AccessControl
Przykład discovery payload#
Tak wygląda wiadomość discovery dla przełącznika DOUT:
{
"name": "P1_DACHOWE_ROZA",
"unique_id": "vclu_clu221000290_dou5048",
"object_id": "vclu_clu221000290_dou5048",
"command_topic": "vclu/clu221000290/switch/dou5048/set",
"state_topic": "vclu/clu221000290/switch/dou5048/state",
"payload_on": "ON",
"payload_off": "OFF",
"state_on": "ON",
"state_off": "OFF",
"availability_topic": "vclu/status",
"device": {
"identifiers": ["clu221000290"],
"name": "DOM20",
"manufacturer": "VCLU",
"model": "vclu"
}
}HA po odebraniu tej wiadomości na topiku homeassistant/switch/vclu_clu221000290_dou5048/config automatycznie tworzy encję switch.p1_dachowe_roza.
Jak działa pod spodem#
Publish discovery (jednorazowo)#
Go: omparser.Parse() → ParsedOM (obiekty z plików OM)
↓
Go: omparser.GenerateHADiscovery(parsed, config) → []HADiscoveryMessage
↓
Go: AccessControl filtruje ukryte obiekty
↓
Go: broker.Publish() → homeassistant/{typ}/{id}/config
↓
Go: GenerateInitialStates() → vclu/{clu}/{typ}/{id}/stateStany (ciągłe)#
Obiekt Lua zmienia wartość (np. DOUT przełączony)
↓
StateBus:emit("state_changed", {path, value, type})
↓
HAStatePublisher: nasłuchuje "state_changed"
↓
Formatuje stan (0/1 → "OFF"/"ON", pozycja, brightness, JSON RGB)
↓
MQTT:publish("vclu/{clu}/{typ}/{id}/state", stan)
↓
HA odbiera i aktualizuje encjęKomendy (ciągłe)#
HA wysyła komendę na vclu/{clu}/{typ}/{id}/set
↓
HACommands: subskrybuje vclu/+/+/+/set (i /brightness/set, /position/set)
↓
Parsuje topic → (cluId, component, objectId, subpath)
↓
Szuka obiektu w registry: _:get("CLU_ID.OBJECT_ID")
↓
Sprawdza AccessControl
↓
Wywołuje odpowiednią metodę:
switch: obj:execute(METHOD_SWITCH_ON) / obj:execute(METHOD_SWITCH_OFF)
light: obj:set(FEATURE_VALUE, brightness)
cover: obj:execute(METHOD_UP) / obj:execute(METHOD_DOWN) / obj:execute(METHOD_STOP)
number: obj:set(FEATURE_VALUE, value)