Novinka od IKEA
Výrobky od IKEA mají v zásadě tu výhodu, že jsou velmi dobře navrženy. Doporučuji si na YouTube vyhledat třeba to, jak elektrikáři rozebírají a hodnotí nabíječky od IKEA. Kvalita je dána silnou distribucí – jak známo v IT se fixní náklady dobře rozprostírají mezi silnou uživatelskou základnu.
Zejména v IoT zařízeních jsou dva hlavní hráči – IKEA a Philips, do jisté míry se sem tam něco dobrého a levného dá sehnat třeba i od LIDLu. Většina těchto výrobců používá na komunikací zařízení protokol Zigbee, který má nízkou spotřebu a velký dosah a do budoucna bude nahrazen protokolem Matter – nový DIRIGERA hub od IKEA podporuje oba druhy protokolů. Nicméně protokol Matter současné čidlo nepodporuje, takže budeme používat Zigbee.
Dlouho jsem řešil, jak s těmito zařízeními komunikovat. Moje první myšlenka byla použití wrapperu nad zastaralou bránou IKEA, ale toto řešení nefungovalo příliš dobře. Až na posledních LinuxDays jsem se dozvěděl, že existuje něco jako Zigbee2Mqtt a byl jsem nadšený. Jak to vlastně funguje? U docker image se Zigbee2Mqtt (který můžete nainstalovat třeba na Raspberry Pi Zero) si s USB donglem (dá se koupit v českých speciálkách) můžete jednoduše napárovat zařízení s protokolem Zigbee, s kterým později komunikujete pomocí message queue.
Osobně mám pár projektů, které zprávy ze Zigbee zařízení zpracovávají (zpravidla čidla), nebo je na ně i odesílají (zpravidla zásuvky). Řešitelné je to jednoduše jak v Pythonu, tak v JavaScriptu (samozřejmě asi i v jiných jazycích), osobně zvládám oba jazyky, takže moje projekty jsou většinou v obou, nicméně výše zmíněný projekt je napsaný v JavaScriptu a pro komunikaci se Slackem používá knihovnu Bolt. Nějakou základní kostru programu vždy vygeneruji pomocí AI (funguje to relativně spolehlivě), a pak ručně upravuji podle svých potřeb.
Co aktuální aplikace umí a jak je navržena?
Aplikaci jsem navrhl tak, aby při sepnutí nebo rozepnutí senzoru poslala na kanál na Slacku zprávu „door open“ či „door closed“. Navíc taky při napsání slova „alarm“ lze zasílání zpráv vypnout.
Trošku jsem válčil s novým frameworkem Bolt od Slacku, jehož dokumentace není úplně špatná, ale také není úplně kompletní a hlavně chybí velké množství příkladů. Byl tedy drobný problém přijít na to, co se jak dělá – ale pomohly přesně míněné dotazy do Google, které vyhledaly starší dotazy jiných uživatelů na fórech.
Je potřeba mít také správně nastavená oznámení na telefonu, aby vás na všechny události upozorňovala pípnutím. Nedělám si iluze, že zařízení slouží jako dokonalý alarm, ale může vám poskytnout nějaké zajímavé informace. Třeba ho můžete namontovat do kanceláře a zjistit tak, jestli už je někdo v práci, nebo ho můžete třeba připojit na dveře racku v serverovně.
Vytvoření aplikace ve Slacku
Prvotní vytvoření aplikace ve Slacku je jednoduché, jen nesmíte na nic zapomenout. Celým procesem vás proto jednoduše provedu. První vytvoření aplikace můžete zvládnout na adrese api.slack.com/apps.
Postup
- Vytvořit aplikaci
- Zkopírovat „Signing secret“
- Nastavit „Permission“
- Nainstalovat do Workspace
- Získat „Bot token“
- Přihlásit se k „Event Subscribtion“
- Poznamenat si „Socket token“
- Přidat do kanálu
Jak vidíte, vytvoření aplikace ve Slacku je celkem komplexní proces, hlavně na nic nezapomenout, protože pak vám to určitě nebude fungovat. Po vytvoření aplikace byste měli vlastnit tři tokeny, které dále v aplikaci použijeme.
Samotné zapojení senzoru
Senzor se ke dveřím jednoduše přilepí. Podle mě velká výhoda senzoru od IKEA Parasoll je použitý článek AAA, který napájí senzor. S tím se u konkurence běžně nesetkáme, častěji se používají menší knoflíkové baterie.
Také je velmi příjemné, že se rozsvítí červená LED dioda, když se změní stav senzoru. Z hlediska konkurence se jedná asi o nejlépe provedený dveřní či okenní senzor, který jsem zaznamenal.
Zigbee2Mqtt
Pro spojení senzoru s počítačem je potřeba mít potřebné vybavení. Především bránu pro Zigbee – já jsem použil Home assistant SkyConnect USB, kterou jsem zakoupil za přibližně 700 Kč.
Karta se po zapojení do počítače tváří jako sériový port, což má mnoho výhod – například ji můžete nasdílet klidně do Kubernetes apod. Já jsem pro připojení použil Raspberry Pi Zero 2W v ceně kolem 400 Kč. Zde je třeba upozornit na to, že velmi doporučuji využít výkonnou SD kartu i pro IO zápisy standardu A1 nebo A2, osobně jsem použil SAMSUNG EVO Plus Micro SDXC 128GB za přibližně 350 Kč.
Ať použijete Raspberry Pi, nebo třeba vlastní počítač či server, je třeba nainstalovat produkt Zigbee2Mqtt, instalace pomocí Dockeru je popsána přímo na stránkách produktu v příručce Getting started. Jediné, na co musím upozornit, je to, že na Raspberry Pi Zero trvá trošku déle, i když výsledek pak běhá svižně. Pokud budete instalovat Raspbian, doporučuji kvůli významnému zrychlení vypnout grafické uživatelské rozhraní.
Připojení senzoru je relativně jednoduché, klikněte na tlačítko „Permit join (All)“, které na pá minut umožní párování a na senzoru Parasoll stiskněte párovací tlačítko – tím je hotovo. Po spárování se ještě podívejte do logů, jestli vidíte správně události zařízení.
Po spárování v „Logs“ uvidíte při změně stavu čidla jeho oznámení, zde je jen příklad s jiným čidlem
Samotná aplikace
Aplikaci mám zveřejněnou na GitHubu, a je napsaná v JavaScriptu. Standardně se zapíná s vypnutým alarmem, pro jeho zapnutí musíte zaškrtnout políčko enable – pak vám začnou chodit oznámení. Byl využit nový framework Bolt od Slacku, kterému v dokumentaci chybí různé příklady využití – je třeba hodně bádat na internetu, než na něco přijdete.
Například zapsání textu do chatu vypadá takto:
await app.client.chat.postMessage({channel:"home", text:"Alarm started in disabled state, type alarm to change"})
Připojení aplikace k mqtt serveru je relativně jednoduché, pokud máte v proměnných prostředí zadán mqtt server (tedy třeba IP adresu daného Raspberry Pi Zero s nainstalovaným Zigbee2Mqtt běžícím na portu 1833), přípojíte se následovně.
const mqttServer = process.env.MQTT_SERVER; const mqttTopic = process.env.MQTT_TOPIC; const mqtt = require('mqtt'); const client = mqtt.connect(mqttServer);
Poté stačí již jen čekat na zprávy ze senzoru Parasall, které se posílají v následujícím formátu.
{"battery":100,"battery_low":false,"contact":false,"linkquality":255,"tamper":false,"update":{"installed_version":16777241,"latest_version":16777241,"state":"idle"}}
Při jejich příjmu pak musíte vypsat vše do okna chatu Slack pomocí následujícího kódu.
client.on('message', (topic, message) => { if (topic === mqttTopic && enabled) { const data = JSON.parse(message); console.log("Contact: ", data.contact); app.client.chat.postMessage({channel:"home", text:`Door ${data.contact ? "closed": "opened"}`}) }
Aplikaci jednoduše nainstalujeme
$ git clone ... $ cd slack-alarm $ npm install
a poté spustíme příkazem
$ npm run dev
To samozřejmě předpokládá, že máte správně vyplněny proměnné prostředí v souboru .env
. Přiložen je .env.sample
, abyste věděli, jak na to.
Nasazení do Dockeru či Kubernetes
Samotná aplikace má poměrně jednoduchý Dockerfile, který jsem vygeneroval pomocí ChatGPT. Můžete si všimnout, že aplikaci spouštím pomocí npm run prod
, zatímco když jí spouštím samostatně, pouštím jí pomocí npm run dev
. Tyto příkazy jsou nadefinovány v souboru package.json
.
"scripts": { ... "dev": "node --env-file .env app.js", "prod": "node app.js"
Jediný rozdíl je v tom, že v případě prostředí dev
využívám soubor s proměnnými .env
, a v případě Kubernetes (ukázkový deployment je v kuberneters/slack-alarm.yml
) používám systémové proměnné, které dále přikládám v ConfigMapě.
apiVersion: v1 kind: ConfigMap metadata: name: slack-alarm-config data: SLACK_BOT_TOKEN: "xoxb-" SLACK_SIGNING_SECRET: "" SLACK_APP_TOKEN: "xapp-1-" MQTT_SERVER: "mqtt://server:port" MQTT_TOPIC: "zigbee2mqtt/0xXXXXXX" --- kind: Deployment apiVersion: apps/v1 metadata: name: slack-alarm spec: replicas: 1 selector: matchLabels: app: slack-alarm template: metadata: labels: app: slack-alarm spec: containers: - name: slack-alarm image: registry/slack-alarm:latest envFrom: - configMapRef: name: slack-alarm-config
Zde si musím trošku nasypat popel na hlavu, protože tokeny ukládám do ConfigMapy a ne do secrets, ale jde především o demonstrační ukázku. Osobně používám vlastní registry a vlastní GitHub Workflow Workery (jak na ně popisuji u sebe na webu – Self Hosted GitHub Action Runner on Kubernetes), nicméně protože v Dockerimage asi není nic nijak extra privátního, můžete použít i veřejné docker registry zdarma. Pokud byste si chtěli připravit vlastní GitHub Workflow, bude vypadat asi takto.
name: Slack-Alarm CI on: push: branches: [ "main" ] paths: - 'Kubernetes/slack-alarm/**' pull_request: branches: [ "main" ] paths: - 'Kubernetes/slack-alarm/**' jobs: build-docker-image: runs-on: ubuntu-latest steps: - name: Docker login uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Checkout uses: actions/checkout@v3 - name: Build docker image run: cd Kubernetes/slack-alarm && docker build . --file Dockerfile --tag ${{ secrets.DOCKERHUB_USERNAME }}/slack-alarm:$(date +%s) --tag ${{ secrets.DOCKERHUB_USERNAME }}/slack-alarm:latest && docker push ${{ secrets.DOCKERHUB_USERNAME }}/slack-alarm --all-tags
Samotný docker image zveřejňuji také na docker.io/krab55, takže ho můžete použít bez toho, aniž byste něco sami kompilovali.
Velmi jednoduše vše můžete samozřejmě i jako Docker image nainstalovat na původní Raspberry Pi Zero. Já jsem ale používal instalaci na Kubernetes, proto vám k tomu manuál nedám.
Inspirace pro další práci
Samotné řešení je spíše jako inspirace na ukázku toho, co je možné a jak lze vše pospojovat. Věřím, že mnoho čtenářů napadnou nějaká vylepšení či jiná využití s jinými senzory. S čím jsem asi nejvíce bojoval, bylo využití frameworku Bolt pro Slack, kde v dokumentaci scházely ukázky, všechno ostatní bylo relativně jednoduché, jen to samozřejmě zabralo čas to odladit.
Pro vás tu je již připravené řešení, které můžete zprovoznit za 30 minut a nemusíte se o nic starat. Můžete ho využít třeba na to, abyste evidovali přístupy do serverovny nebo třeba do garáže. Pokud máte nějaké návrhy na zlepšení, tak je rád uvítám v komentářích.
(Autorem obrázků je Martin Koníček.)