Hue Ambilight

Tämän viikonlopun harrasteprojektinani oli kodin valaisimien automatisointi Philips Huen, Z-Waven ja AWS IoT:n avulla. Halusin ratkaisun, jossa valot menevät automaattisesti päälle kotiin saapuessa ja toimintaa voi ohjailla pilvestä käsin.

Palapelin palaset olivat:

Kuten valinnoista voi arvata, projektin tavoitteena ei ollut yksinkertaisin mahdollinen ratkaisu, vaan käytännön tuntuman saaminen AWS IoT -alustaan ja Z-Waveen. Helpompaan kotiautomaatioon löytyy muita ratkaisuja.

Osa 1: Z-Wave

Z-Wave hieman kiistanalainen standardi enkä ole tähän mennessä osannut päättää, pidänkö siitä vai en. Joissakin tuotteissa on tunnettuja tietoturvaongelmia, mutta toisaalta Z-Wave-standardia noudattavat laitteet toimivat ilmeisesti aika hyvin yhteen. Kommunikaatio tapahtuu matalalla taajuudella (~ 900 MHz) ja läpäisee sen vuoksi huonekalut ja seinät ongelmitta.

Z-Waven ohjelmointi on ikävää. USB-ohjaintikku ilmestyy Macissa, Linuxissa tai Windowsissa näkyviin tavallisena sarjaporttina. Sarjaportin kautta puhutaan binääristä protokollaa, jota on mahdotonta kirjoittaa tai tulkita tavallisella terminaaliohjelmalla. Tarvitaan siis avuksi C++-pohjainen OpenZWave, joka on ainoa tuntemani avoimen lähdekoodin Z-Wave-kirjasto. Sen Node.js-versio on pari vuotta vanha ja vaatii vanhan 0.1x-sarjan Node.js-ympäristön toimiakseen. Ilmeisesti tällä saralla ei ole kovin paljon aktiivisia harrastelijoita.

Z-Waveen liittyy pakollinen laitteiden liittäminen toisiinsa. USB-ohjaintikku muistaa siihen liitetyt laitteet, vaikka se irrotettaisiin välillä tietokoneesta. Koska Node-OpenZWave-kirjasto ei sisällä tukea tälle liittämiselle, jouduin hoitamaan asian Domoticz-ohjelmistolla. Operaatio oli kertaluonteinen ja sen jälkeen tikku alkoi tunnistaa Vision ZP3102 -liikkeentunnistimen myös Node.js:llä.

Jouduin itse lisäämään OpenZWave-kirjaston Node.js-toteutukseen tuen Z-Wave Event -tapahtumille. Vision ZP3102 lähettää tällaisen tapahtuman koodilla 255 aina havaitessaan liikettä. Hetken päästä laite lähettää tapahtuman 0, kun liike on lakannut. Alla lyhyt esimerkki siitä, miten tapahtumia kuunnellaan Node.js -sovelluksessa:

zwave.on('node event', function (nodeid, event) {
  if (nodeid == PIR_NODE_ID && event > 0) {
    // Motion detected
  } else if (nodeid == PIR_NODE_ID && event == 0) {
    // Motion ended
  }
});

Osa 2: AWS IoT ja Lambda

Amazonin julkaisi viime vuonna AWS-pilvipalveluihinsa kuuluvan IoT-alustan. Alustan tarkoituksena on tarjota helppo tapa liittää erilaisia laitteita pilveen, kerätä laitteista dataa sekä ohjata niitä. Amazonin IoT Device SDK on ohjelmointialusta, joka tekee laitteiden liittämisen kivuttomaksi joko C:llä, Arduinolla tai Node.js:llä.

AWS IoT perustuu MQTT-standardiin ja lisää sen päälle hieman Amazonin omaa toiminnallisuutta. AWS IoT:n GUI-työkalulla (tai APIlla) hallitaan laitteita ja niihin liitettyjä sertifikaatteja sekä datan käsittelysääntöjä. Jokainen laite tarvitsee oman sertifikaatin ja salaisen avaimen, joiden avulla se tunnistautuu lähettäessään pilveen dataa.

Erillistä MQTT-palvelinta ei tarvita, vaan se sisältyy AWS IoT -alustaan ja skaalautuu automaattisesti. Juuri tämän vuoksi pidän AWS IoT:stä ja muista samantapaisista pilvipalveluista. Palvelussa ei ole mitään kuukausimaksua, vaan siitä maksetaan toteutuneen käytön mukaan. Miljoona IoT-viestiä maksaa $5, joka riittää optimistisesti laskien noin tuhanneksi vuodeksi yhden kodin iltavalaistuksen ohjaamiseen.

Sovelluskehityksen kannalta AWS IoT:n olennaisin ero pelkkään MQTT:hen nähden ovat Amazonin Device Shadow -profiilit. AWS IoT -alusta pitää yllä jokaisesta laitteesta omaa "varjoa", jossa näkyy laitteen viimeksi raportoima tila. Tämä tila on käytännössä JSON-dokumentti. Varjoprofiiliin voidaan myös asettaa toivottu tila, ja kun laite seuraavan kerran kytkeytyy pilveen, se näkee toiveen ja yrittää asettaa itsensä toivottuun tilaan.

Omaa sovellustani varten loin AWS IoT:hen kaksi laitetta: liikkeentunnistimen ja valo-ohjaimen. Liikkeentunnistin toimii MQTT:llä ja julkaisee aina ilmoituksen, kun liikettä havaitaan. Valo-ohjain taas pitää yllä varjoprofiilia valaistuksen nykytilasta sekä seuraavasta toivotusta tilasta.

AWS IoT kytkeytyy suoraan Amazonin muihin pilvipalveluihin. Kun se vastaanottaa laitteelta MQTT-viestin, viesti voidaan ohjata esimerkiksi tietokantaan tai jonoon. Itse ohjasin viestit SNS-palveluun, joka toimii publish & subscribe -rajapintana. Sen kautta viestit voidaan ohjata edelleen useaan eri paikkaan, kuten esimerkiksi sähköpostiin ja Lambda-mikropalveluun.

Lambda-mikropalvelussani on puolestaan pieni sovelluslogiikka, joka käsittelee vastaanotetut viestit. SNS:n kautta vastaanotettu viesti näkyy suoraan Lambda-funktion event-objektina. Lambdasta voidaan lähettää uusia viestejä AWS IoT -laitteille käyttämällä AWS JavaScript SDK:ta ja sen IotData-luokkaa. Jos kellonaika on oikea, mikropalvelu lähettää Philips Hue -ohjaimelle pyynnön asettaa päälle tietty valaistus.

Osa 3: Philips Hue

Olen omistanut Philips Hue -tukiaseman ja muutaman siihen liitetyn valaisimen jo pitkään. Nyt pääsin kokeilemaan Huen REST APIa käytännössä. Tukiasemaa voidaan ohjata tällä APIlla oman kotiverkon sisällä. Ohjaamiseen ei tarvita erityistä kirjastoa, vaan sen voi tehdä tavallisilla HTTP-pyynnöillä Node.js-sovelluksesta käsin.

Oma sovellukseni tarkistaa REST APIa käyttäen säännöllisin väliajoin Hue-valaisimien nykytilan ja raportoi sen muutokset pilveen AWS IoT:lle. AWS IoT pitää yllä valaistuksen varjoprofiilia, jota voi tarkastella GUI-työkaluilla etäältäkin. Näin pilvi saa tiedon, jos valaistusta säädetään kotona käsin.

Vastaavasti sovellus vastaanottaa pilvestä pyyntöjä valaistuksen muuttamiseksi. AWS IoT:n varjoprofiiliin voidaan asettaa toivotuksi tilaksi tietty Hue Scene, ja kun sovellus saa tästä tiedon, se pyytää Hue-tukiasemaa aktivoimaan tämän Scenen.

Hue-sovelluskehitykseen liittyy tiettyjä haasteita sen suhteen, että Hue-tukiaseman rajapinta ei palauta tällä hetkellä aktiivista Sceneä. Valaistukseen saatetaan tehdä muutoksia koska tahansa esimerkiksi iPhone-sovelluksella. Rajapinnalta voi vain tiedustella yksittäisten valaisimien nykytilaa. Sovellus ei siis tiedä, onko tietty Scene tietyllä hetkellä käytössä vai ei, joten on tehtävä kompromisseja sen suhteen, mitä pilvessä olevaan varjoprofiiliin raportoidaan.

Yhteenveto

Tämä harrasteprojekti oli omalla mittapuullani varsin onnistunut. Puuhasteluun ja opiskeluun kului aikaa yksi lauantaipäivä. Projektista sai käytännön kokemusta Z-Wavesta, MQTT:stä sekä AWS IoT:n varjoprofiileista. Aika näyttää, onko toteutus pitemmän päälle luotettava ja toimiva. Heikoimmaksi lenkiksi arvioin UZB-ohjaintikun, jota saattaa joutua resetoimaan eri tavoin ajan mittaan.