Lähtökohta
Uuden kehittäminen on hauskaa, mutta yhdessä kehittäminen on hauskempaa. Pari viikkoa sitten mietime tiimin kesken toimistolla, että mitä kivaa voisimme tehdä yhdessä. Pienen brainstorm-session jälkeen päädyimme ideaan, kuinka voisimme hyödyntää IoT -antureita tai koneoppimista meidän omassa toimistoympäristössä.
Demon tarkoitus
Halusimme tehdä demon ihan demomerkityksessä, niin itsellemme, kuin myös asiakkaillemme. Nyt kun IoT-pohjaisia ratkaisuja on tehty Bilotilla muutama, niin halusimme myös kokeilla, kuinka nopeasti ja helposti tällainen nousisi. Alkuvaiheessa kuuntelimme pari vinkkiä kokeneemmilta, mutta aika nopeasti demo-tiimimme pääsi ratkaisun kanssa vauhtiin.
Demon aihe ja rajaus
Päädyimme tekemään palvelun, joka erillisten sensoreiden kautta kerää mittaustietoja neuvotteluhuoneiden ilmasta kahden minuutin välein (lämpötila, kosteus, paine), ja näyttää nämä tiedot kätevässä yhteenvetomuodossa jatkuvasti päivittyvän web-applikaation kautta. Toteutettu versio demosta on katsottavissa täältä: Bilot IoT Demo, ensikäynnistyksellä pitää hetkinen odotella datan latautumista.
Tämän tyyppisen ratkaisun kohdalla tietoteknisiä arkkitehtuurivaihtoehtoja ei tarvinnut kauan puntaroida. Tässä tarvitaan jokin komponentti keräämään ja syöttämään dataa, toinen komponentti tallettamaan datat, kolmas palvelu jakelemaan tallennettu data, ja neljäs esittämään tiedot käyttäjälle kätevässä ja miellyttävässä muodossa.
Lähes yhtä nopeasti meille valkeni oikeat teknologiat: sensoreina käytetään suomalaisen Ruuvi -yhtiön IoT-sensoreita, paikallisena tiedonkeruualustana (ns. ”edge device”) käytetään Raspberry Pi -minitietokonetta, palvelimena meillä on Microsoft Azure ja applikaatio toteutetaan Reactilla.
Toteutus
Palvelin
Aloitimme palvelun rakentamisen keskeltä, eli tarvittavista Azure-palveluista. Pienen selvittelyn jälkeen Azuren tarjonnasta valittiin tähän ratkaisuun käytettäväksi:
- Azure IoT Hub, jonka kautta määritettiin ulkoiset laitteet millä dataa kerättiin, ja joka ottaa ulkoa lähetetyn datan talteen.
- Azure Stream Analytics, jota käytettiin lukemaan IoT hubin vastaanottamat mittaustiedot ja kirjoittamaan tiedot tietovarastoon sopivassa muodossa
- Azure SQL Database, mihin mittaustiedot tallennettiin
- Azure functions jota käytettiin välittämään haluttuja tietoja käyttöliittymään.
Isommassa ratkaisussa tietovarastona pelkkä Azure SQL Database ei ehkä olisi riittävä, mutta tähän käyttöön se kelpasi hyvin. Muista palveluista poiketen se ei ole ilmainen, mutta tässä tapauksessa edullisimmat versiot riittävät hyvin. Kustannus on alle 12 euroa kuukaudessa.
Varsinaiseksi palvelintoteutukseksi jäi siis IoT -hub -palvelun konfigurointi, SQL-tietokannan ja -taulujen perustaminen, Stream Analytics -palvelun ja siihen liittyvän kyselyn konfiguroiminen ja aplikaatiota palvelevan Azure-funktion laatiminen.
Mittausdatan kerääminen
Ruuvi-yhtiön Bluetooth-sensorit olivat lopulta helppo valinta, verrattuna muihin vastaaviin. Laitteiden saatavuus on hyvä, ne ovat edullisia, ja käyttäjäkunta on aktiivista, joten erilaisia foorumi- ja blogipostauksia oli sopivasti tarjolla.
Sensorit käyttäytyvät Bluetooth-majakoina, eli tällaisen lukemiseksi laitteita ei tarvitse erityisesti parittaa. Mittalaitteet vain lähettävät dataa yltympäriinsä, ja jokainen kantavuusalueella oleva Bluetooth-laite voi tätä signaalia kuunnella. Jossakin käyttötapauksessa tämä saattaa olla turhan huoleton käytäntö, mutta ainakaan demon tapauksessa emme tästä olleet murheissamme.
Lisäksi päädyimme käyttämään niin sanottua ”Edge deviceä”. Termille ei ole kovin vakiintunutta suomenkielistä käännöstä, mutta jonkinlainen ”Reunalaite” se on. Kyseessä on tietynlainen silta, internetiin kytketty laite, joka osaa keskustella Azure IoT Hubin kanssa, ja joka osaa kerätä mittaussensorien lähettämät tiedot. Edge devicen tarve on helppo nähdä tässä tilanteessa, jossa mittalaitteet lähettävät tietonsa vain Bluetoothilla, mutta tällainen välilaite on usein hyödyllinen silloinkin, kun mittaussensorit osaisivat itsekin kytkeytyä internetiin.
Meiltä kun sattui löytymään Raspberry Pi 3 valmiina ja sen käyttöön tässä tarkoituksessa löytyi hyvin ohjeita, niin se oli aika luonnollinen valinta tähän tarkoitukseen.
Seuraavaksi piti ohjelmoida Raspberry-tietokone ottamaan vastaan mittausdataa sensoreilta, ja lähettämään tämä data sopivassa muodossa Azure IoT Hub -palvelulle. Tämänkin olisi voinut tehdä monin keinoin, mutta tässä valitsimme pienimmän vastuksen tien, ja teimme Edge Device -ohjelman Pythonilla. Azuren IoT-palvelu olisi tarjonnut tähän hienompiakin konsteja, jotka olisivat mahdollistaneet Edge devicen etähallinnan ja muutakin, mutta demon vaatimustason kannalta nämä olivat tarpeettomia.
Pythoniin meille taas oli tarjolla valmis ruuvitag-sensor -kirjasto, joka tarjosi paljon aihepiiriin liittyvää toiminnallisuutta valmiina. Lisäksi tarjolle paljastui myös DeviceClient.py -kirjasto, joka tarjoaa metodit tietojen lähettämiseksi Azure IoT Hubille. Python-ohjelmalle syötettiin Azure IoT Hubista saadut tunnistetiedot, jotka toimivat tietojenlähetyksessä tunniste- ja pääsynhallintatietoina. Python-ohjelma ottaa kahden minuutin välein sensorien tiedot talteen, ja lähettää ne IoT Hubille.
(Raspberry Pi -koneeseen olisi voinut asentaa myös Windows 10:n IoT -version, mutta tätä emme kokeilleet. Koneen käyttöjärjestelmänä sai toimia oletuksena asentunut Raspbian.)
Mittausdatan tallentaminen palvelimelle
Koska palvelinpään toiminnallisuus oli tehty jo alkuvaiheessa, varsinaisen kerätyn datan tallennus ei vaatinut kuin pienen tarkastuksen. Raspberry Pi -tietokoneen Python ohjelma keräsi ja edelleen lähetti mittaustiedot aivan odotetusti, joten palvelimella lähinnä riitti todeta tilanne ja katsoa miten mittaustietorivejä ilmestyi tietokantaan.
Mittausdatan julkaiseminen
Palvelimen ja applikaation välinen tietoliikenne toteutettiin tämänhetkisen normaalikäytännön mukaisesti REST-palveluna. Azure-palveluun laadittiin ja asennettiin Azure-funktio, joka palauttaa mittaustiedot JSON -sanomana, kahdessa eri muodossa. Toinen muoto tuottaa suoraviivaisen mittausdatan: mikä lämpötila on milläkin hetkellä kussakin huoneessa ollut, toinen muokkaa mittausriveistä koostedataa, eli päivittäiset keskiarvot jokaisesta huoneesta.
Funktio toteutettiin Visual Studio 2019:lla, joka tarjoaa Azure-funktion valmiina projektityyppinä. Tietokantayhteyttä varten emme ottaneet käyttöön Entity Frameworkia, koska ajattelimme näin suoraviivaisen toteutuksen hoituvan nopsemmin suorilla ADO-kyselyillä. Todennäköisesti EF olisi kuitenkin ollut helpompi, mutta menee se näinkin. Palvelinfunktiota varten emme perustaneet CI/CD -putkea, funktio julkaistaan suoraan Visual Studiosta.
Rajapinnan hallinnan tähden otimme käyttöön Azuren API Management -palvelun, jonka kautta funktiota kutsutaan. API Managementilla pystymme rajoittamaan montako rajapintakutsua suostumme aikayksikön sisällä palvelemaan, ja täten kontrolloimaan resurssien käyttöä ja kustannuksia.
Applikaation suunnittelu ja toteutus
Kuten oikeissakin projekteissa, niin ennen kuin käyttäjäpuolen applikaatiota lähdettiin toteuttamaan, niin ensiksi se piti tietenkin suunnitella. Tässä tapauksessa käyttäjätarpeet kerättiin suoraan tiimistä, koska itsellemmehän me tätä pitkälti teimme. Kun post-iteja oli lätkitty tarpeeksi, niin alettiin sitten rakentelemaan designia Adobe XD:llä ja visuaalisia komponentteja Adobe Illustraattorilla.
Koska React on ollut viime aikoina ahkerassa käytössä, niin siihen Reduxin kanssa päädyttiin JavaScript kirjasto/framework vertailussa lähes automaattisesti.
Applikaation ulkoasun rakentamisessa lähdettiin ensiksi hyödyntämään suosittua React käyttöliittymä frameworkia, Material UI:ta, mutta jotenkin se vain tuntui epäkäytännölliseltä ja saikin poistua lähes saman tien perinteisen SCSS lähestymisen tieltä.
Joitain lisäpaketteja asenneltiin sitten vielä tarpeen mukaan:
- Recharts osoittautui nopeaksi ja käteväksi graafi-työkaluksi
- API-kutsut hoidettiin Axioksen avulla
- Päivämäärien ja kellonaikojen esittämisessä hyödynnettiin js:ää
Yhteenveto
Demo valmistui jopa yllättävän sukkelasti. Azure-palveluiden asennus ja konfigurointi vei työaikaa parilta ihmiseltä noin päivän. Edge-laitteen konfigurointi ja ohjelmointi vei päivän sekin, sisältäen yllättäen eteen tulleen tarpeen opiskella Pythonia. Ensimmäisen toimivan version jälkeen molempia kohtia viimeisteltiin vielä jonkin verran, mutta voimme pää pystyssä todeta tällaisen syntyvän muutamassa päivässä.
Eniten aikaa kului applikaation toteutukseen. Tässäkin tapauksessa ensimmäinen versio syntyi parin päivän työllä, mutta suunnittelun iterointi, responsiivisuus ja käytettävyyden yksityiskohtien hiominen toivat muutamia päiviä lisää ja tuovat vielä jatkossakin, kun kerrankin on ratkaisu minkä käyttöliittymä kehityksessä ei ole mitään rajoitteita ja mihin voi palata aina yhä uudelleen, uusien ideoiden kanssa.
Alkuvaiheessa tehdyt arkkitehtuuri- ja teknologiavalinnat osoittautuivat kaikki hyviksi. Muutama pieni tyyliseikka jäi kaihertamaan, Azure-funktiota varten olisi kuitenkin kannattanut tehdä CI/CD -putki, ja olisi sen Entity Frameworkin voinut myös mukaan ottaa. Edge -laitteen Python-sovellus on myös hieman harrastusprojektihenkinen, tuotantokäyttöön tekisimme hieman viimeistellymmän ja vakaamman toteutuksen, mutta ei tämä nykyinenkään ole käynnistyksensä jälkeen mitään ongelmia tai poikkeuksia aiheuttanut.
Kaiken kaikkiaan ”projekti” oli onnistunut kokonaisuus, jossa muutaman ihmisen pienellä panostuksella saatiin hauska kokonaisuus aikaiseksi, opittiin hieman uutta ja luotiin pohja minkä päälle rakentaa lisää.
Jatkoakin on jo suunniteltu. Tarkoituksena olisi seuraavaksi integroida applikaatioon tieto neuvotteluhuoneiden varaustilanteesta, käyttöasteista jne.
Tämä blogi on kirjoitettu yhteistyössä Erkka Puustin kanssa.