Skip to content

Zařízení

Zařízení jsou fyzické prvky (zámky, světla, zásuvky) připojené k systému Dveřník.

Typy zařízení

Typ Popis Akce
lock Zámek (dveře, brána, turniket) open, close, short_open
light Osvětlení on, off, blink
outlet Zásuvka / napájení on, off
locker Skříňka open, close, short_open
custom Vlastní typ dle adaptéru

Role zařízení v zóně

Každé zařízení je přiřazeno k zóně přes kolekci zone_devices s jednou ze dvou rolí:

Primární zařízení (primary)

  • Řídí přístup do zóny (typicky zámek)
  • Každá zóna musí mít alespoň jedno primární zařízení
  • Při zahájení relace se odemkne
  • Při odchodu posledního uživatele se zavře
  • Určuje, zda je zóna "obsazena"

Sekundární zařízení (secondary)

  • Doplňková zařízení (světla, zásuvky)
  • Zapínají se při zahájení relace
  • Vypínají se při ukončení relace
  • Uživatelé je mohou během relace ovládat manuálně

Sdílení zařízení

Jedno fyzické zařízení může být přiřazeno k více zónám s různou rolí. Například zámek na chodbových dveřích může být primary v zóně A a secondary v zóně B.

Režimy zámku (lock_mode)

Primární zařízení typu lock mají nastavení režimu:

Režim Popis
permanent Zámek zůstane otevřený po celou dobu relace
short_open_5s Zámek se odemkne na 5 sekund a automaticky zavře
short_open_10s Zámek se odemkne na 10 sekund a automaticky zavře

Režim zámku se uplatňuje vždy — jak při zahájení relace, tak při manuálním ovládání během relace.

Hlavní dveře a ukončení relace

Zámek s rolí primary a režimem permanent se v panelu aktivní relace považuje za hlavní dveře. Když zákazník úspěšně zamkne všechny takové zámky zóny, aplikace sama otevře potvrzení ukončení relace (stejné jako tlačítko Ukončit), a pokud zákazník zůstane v relaci, zobrazí nad tlačítkem upozornění, že akce stále běží a účtuje se. Zámky s krátkým otevřením (short_open_*) a sekundární zámky tohle chování nespouštějí. Je to čistě chování rozhraní — na straně serveru se nic nemění.

Komunikační adaptéry

Každé zařízení má nastavený komunikační adaptér, který určuje jak systém komunikuje s fyzickým hardwarem.

Demo adaptér (demo)

Simuluje zařízení pro vývoj a testování. Stav se ukládá do kolekce app_config.

Konfigurace: adapter_config = null nebo libovolný JSON objekt (např. {}) — obsah se ignoruje.

Stav zařízení v app_config:

  • demo_lock_state_{device_id} — hodnoty: "open", "close"
  • demo_light_state_{device_id} — hodnoty: "on", "off"
  • demo_outlet_state_{device_id} — hodnoty: "on", "off"

REST API adaptér (rest_api)

Komunikuje s hardwarem přes HTTP. Koncové zařízení (Raspberry Pi, ESP, …) je „hloupý“ GPIO řadič — nic neví o zámcích ani světlech. Veškerý význam akcí je v adapter_config, kde pin_mapping říká, které piny se mají při které akci nastavit.

Adaptér mluví s řadičem dvěma endpointy:

Endpoint Účel
POST /gpio Nastaví stavy pinů: {"pins": [{"pin": 4, "state": "on", "duration_ms": 5000}]} (+ jméno uživatele pro audit). duration_ms = automatický návrat do původního stavu
GET /gpio/status Přečte aktuální stavy pinů (stav zařízení + heartbeat)

HTTP klient má timeout 15 sekund.

Příklad — zámek:

{
  "base_url": "http://192.168.1.50:9999",
  "auth_header": "Bearer váš-token",
  "pin_mapping": {
    "open":       {"pins": [{"pin": 4, "state": "on"}]},
    "close":      {"pins": [{"pin": 4, "state": "off"}]},
    "short_open": {"pins": [{"pin": 4, "state": "on", "duration_ms": 5000}]}
  },
  "status_pin": 4
}

Pole Povinné Popis
base_url ano Adresa řadiče, http:// nebo https:// + host (bez koncového lomítka)
auth_header ano Hodnota hlavičky Authorization, neprázdná
pin_mapping ano Objekt akce → {"pins": [...]} (viz níže)
status_pin ne Pin čtený z GET /gpio/status pro zjištění stavu; 0/vynecháno = stav neznámý. Pokud je > 0, musí se objevit v některé akci pin_mapping
sequence_delay_ms ne Pauza (ms) mezi piny jedné akce; při > 0 se piny posílají jeden po druhém (první synchronně, zbytek na pozadí) — chrání před proudovou špičkou při současném sepnutí více relé. Výchozí 0

Jiné klíče na nejvyšší úrovni nejsou povoleny.

Pin v pins (pole s alespoň jedním prvkem):

Pole Povinné Popis
pin ano Číslo pinu, celé číslo ≥ 0
state ano "on" nebo "off"
duration_ms ne Celé číslo ≥ 0; po této době se pin vrátí do původního stavu

Klíče pin_mapping mohou být pouze open, close, short_open, on, off, blink. Které jsou povinné a které povolené, závisí na typu zařízení:

Typ zařízení Povinné akce Povolené akce
lock, locker open, close open, close, short_open
light on, off on, off, blink
outlet on, off on, off
custom žádné všechny

Stav zařízení se odvozuje z status_pin a mapování: pokud pin 4 je u open ve stavu on, znamená on na pinu 4 „otevřeno“. Podporuje tak jakoukoli konvenci zapojení — viz invertovaný zámek v předvolbách (on = zavřeno).

Nezačínejte od prázdného JSONu

Ve formuláři zařízení zvolte Začít z předvolby — viz Předvolby a kontrola konfigurace. Předvolby obsahují ověřené konfigurace zámku (standardní i invertovaný), skříňky, světla (jednoduché, s blikáním, sekvenční), zásuvky i demo zařízení pro každý typ.

Kontrola konfigurace při uložení

Při vytvoření zařízení a při změně adapter_config, communication_adapter nebo device_type systém konfiguraci zkontroluje a při chybě zařízení neuloží; chyba obsahuje cestu k problému, např. pin_mapping.open.pins[0].state. Kontrola je pouze strukturální — nezjišťuje, zda je zařízení dostupné ani zda je aktivní. Neaktivní (ještě nezapojené) zařízení tak lze předem nakonfigurovat, ale musí mít stejně platnou konfiguraci.

Stávající zařízení se tím nerozbijí. Běh systému (sestavení adaptéru, ovládání, heartbeat) se nezměnil. U zařízení, jehož uložená konfigurace dnešním pravidlům neodpovídá, funguje dál přejmenování, aktivace/deaktivace i změna jiných polí — kontrola se spustí, až když změníte některé z výše uvedených tří polí. Přehled takových zařízení ukazuje kontrola stavu konfigurace.

Znak CHANGE_ME v hodnotě (např. Bearer CHANGE_ME z předvolby) vyvolá jen upozornění — uložit lze, ale zařízení s placeholderem nebude komunikovat, dokud hodnotu nenahradíte.

MQTT adaptér (mqtt)

Není implementován. Volba zůstává v databázi kvůli zpětné kompatibilitě, ale ve formuláři se nenabízí (zobrazí se jen u zařízení, které ji již má) a nové zařízení ani změnu konfigurace s ním systém neuloží.

Akce zařízení

Všechny příkazy jsou explicitní — systém nikdy nepoužívá "toggle". Vždy se posílá konkrétní příkaz (OPEN/CLOSE, ON/OFF).

Akce Popis
open Trvalé odemknutí
close Zamknutí
short_open Krátkodobé odemknutí (5–10 s) a automatické zamknutí
on Zapnutí (světla, zásuvky)
off Vypnutí
blink Zablikání (pouze světla — varování)

Stav zařízení v panelu relace

Panel aktivní relace ukazuje u zařízení stav (Svítí / Zhasnuto / Otevřeno / Zamčeno) jen tehdy, když ho adaptér skutečně potvrdil — to znamená, že dotaz na stav zařízení proběhl bez chyby a vrátil jiný stav než unknown. Jinak panel žádný stav nezobrazí a místo toho napíše poslední známý příkaz („Naposledy: zapnuto 18:02“).

Situace Co uvidí uživatel
Demo adaptér Potvrzený stav (demo je vlastním zdrojem pravdy)
REST API adaptér s nastaveným status_pin a dostupným zařízením Potvrzený stav
REST API adaptér bez status_pin Nepotvrzeno — jen „Naposledy: …“ (dostupnost se přesto ověřuje, viz heartbeat níže)
Zařízení nedostupné, chyba nebo timeout (2 s) Nepotvrzeno — jen „Naposledy: …“

Poslední příkaz se bere z action_logs napříč všemi relacemi (zařízení mohl mezitím přepnout jiný uživatel, cron nebo ukončení relace). Příkaz blink se nepočítá — stav zapnuto/vypnuto nepřepisuje. Chcete-li, aby panel ukazoval skutečný stav i u REST zařízení, nastavte status_pin.

Dotazy na stav se krátce (3 s) cachují, aby časté obnovování dashboardu nezatěžovalo řadič. Po úspěšném příkazu se cache daného zařízení hned zahodí.

Online / offline zařízení (heartbeat)

Cron úloha (výchozí interval DEVICE_HEARTBEAT_INTERVAL_MINUTES = 5 min) ověřuje dostupnost každého aktivního zařízení a ukládá čas posledního úspěšného ověření. Zařízení je online, jen pokud má platný heartbeat (ne starší než DEVICE_HEARTBEAT_TIMEOUT_MINUTES, výchozí 15 min); bez důkazu se nikdy neoznačí jako online.

  • REST API adaptér: heartbeat je autorizovaný dotaz GET /gpio/status na řadič. Provádí se vždy, i když zařízení nemá status_pin — status_pin ovlivňuje jen to, zda lze z odpovědi zjistit stav (zapnuto/vypnuto), nikoli zda je zařízení dostupné. Úspěchem je odpověď HTTP 200; chyba spojení, timeout (5 s na zařízení) nebo jiný HTTP kód heartbeat neobnoví, takže zařízení po vypršení timeoutu přejde na offline.
  • Demo adaptér: je vždy dostupný (simuluje se v databázi).

Zařízení se kontrolují postupně, každé nejvýše 5 s, takže nedostupné zařízení zdržuje běh jen o tento limit.

Auditní log

Každá akce zařízení se zaznamenává do action_logs s:

  • ID relace
  • ID zařízení
  • Typ akce
  • Kdo akci vyvolal (uživatel / systém)
  • Časová značka
  • Metadata (jméno uživatele, doba trvání)
  • Výsledek příkazu (status, failure_reason, error_detail)

Výsledek příkazu

Do action_logs se zapisuje každý pokus o příkaz zařízení, i ten nepovedený. Sloupec status má hodnoty:

status Význam Počítá se do ceny?
success Zařízení příkaz potvrdilo. Ano
failed Příkaz se nepodařilo provést (zařízení neodpovědělo, odmítlo příkaz nebo je špatně nastavené). Ne
not_sent Zaznamenáno, ale příkaz se neposlal — při odchodu z zóny, kterou dál používají jiní hráči, se světla ani zámky nevypínají. Ano (uživatel zónu opustil)
(prázdné) Starší nebo ručně vložený záznam. Chová se vždy jako success. Ano

U failed je v failure_reason důvod: timeout (zařízení neodpovědělo včas), unreachable (spojení se nepodařilo navázat), device_rejected (zařízení vrátilo chybu), config_error (chybí pin_mapping pro danou akci nebo je neplatný) a unknown. Pole error_detail (max. 1024 znaků, bez přihlašovacích údajů v URL a tokenů) obsahuje technický detail — HTTP status a tělo odpovědi zařízení — a vidí ho jen administrátor (admin tabulka akcí a časová osa relace); uživatel vidí jen přeložený důvod.

Neúspěšné pokusy nemění cenu relace: cena se počítá jen ze záznamů, které nejsou failed, takže výsledná cena je stejná, jako kdyby se pokus nikdy nestal. Stejně tak neúspěšný příkaz nepřepíše „poslední příkaz“ zařízení na dashboardu. Zapisují se tyto pokusy: otevření primárních zařízení při vstupu (včetně zavíracích pokusů při vrácení vstupu zpět), tlačítka v běžící relaci, vypnutí světel a zavření zámků při ukončení relace, vypnutí světel po zavření provozu (cron) a blikání před zavřením. Záznamy mají stejnou retenci jako ostatní action_logs (90 dní); relace zrušená kvůli nepovedenému vstupu se i s těmito záznamy smaže běžným úklidem prázdných relací.