Tekninen dokumentaatio - DigiaMinions/Project GitHub Wiki

Tekninen dokumentaatio

1. Johdanto

Tämä dokumentti sisältää DigiaMinions ryhmän tekemän POC:in (Proof of concept) teknisen dokumentaation.

1.1 Tarkoitus ja kattavuus

Dokumentaatio on tarkoitettu kaikille, jotka ovat kiinnostuneet tuotetun POC:in teknisestä toteutuksesta. Siinä tullaan käsittelemään POC:in ympäristöä, käyttötarkoitusta sekä teknisiä yksityiskohtia.

1.2 Tuote ja ympäristö

Päätarkoitus projektissa oli etsiä ja testata vaihtoehtoinen stack kokonaisuus IOT (Internet of things) järjestelmille.

Järjestelmällä on selainkäyttöliittymä, josta käyttäjät voivat nähdä ja hallita omia laitteitaan.

1.3 Dokumentaation yleiskuva

Tämä dokumentaatio sisältää tietoa POC:in ympäristöstä, arkkitehtuurista ja joitain jatkokehitysideoita.

2. Järjestelmän yleiskuva

POC:in aiheeksi valittiin järjestelmä, joka mahdollistaa lemmikkien ruokintaan tarkoitettujen IOT laitteiden hallinnoimisen käyttäjäkohtaisesti. Myös näistä IOT-laitteista toteutettiin protoversio.

2.1 Laiteympäristö

Fyysinen laite, mikä hoitaa ruokinnan ja mittauksen, sai keskusyksikökseen Raspberry Pi 3 Model B:n. Tähän on rakennettu mittaustaso, minkä sisällä mittauksesta ja datanvälityksestä Raspberry Pi:lle vastaa 1KG Scale Load Cell Weight Sensor ja HX711 24bit AD Module. Ruoansyöttöön on käytetty servoja PowerHD HD 6001MG ja HD 9001MG.

Laitteiston teline on suunniteltu Autodesk 123D Designilla ja toteutettu Felix 2.0 3D-tulostimella.

2.2 Ohjelmistoympäristö

Järjestelmä on toteutettu AWS (Amazon Web Services) pilvipalvelun päälle.

Stackin komponentteja ovat:

  • AWS IOT
  • Graphite
  • Grafana
  • Nodejs / React
  • MySQL

2.3 Tärkeimmät reunaehdot

Tärkein reunaehto stackille oli, ettei se saanut sisältää samoja komponentteja, joita TICK stackissa on.

3. Arkkitehtuurin kuvaus

3.1 Kokonaisarkkitehtuuri

3.2 Web-sovelluksen arkkitehtuuri

Tiedostorakenne

/
|-- .babelrc
|-- package.json
|-- server.js
|-- webpack.config.js
`-- tests
	| -- Home.test.js
	| -- Schedule.test.js
`-- src
	| -- index.jsx
	| -- passport.js
	| -- routes.js
	`-- components
		| -- App.jsx
		| -- AuthPage.jsx
		| -- CalendarComponent.jsx
		| -- Container.jsx
		| -- CreateScheduleComponent.jsx
		| -- GraphComponent.jsx
		| -- HeaderComponent.jsx
		| -- Home.jsx
		| -- LoginForm.jsx
		| -- Logout.jsx
		| -- ModalComponent.jsx
		| -- NotFound.jsx
		| -- OrderForm.jsx
		| -- Schedule.jsx
		| -- ScheduleListComponent.jsx
		| -- ScheduleListItem.jsx
		| -- SignUpForm.jsx
	`-- static
		| -- index.html
		`-- css
			| -- style.css

Sovelluksen frontti on tehty React:illa, joka käyttää komponenttipohjaista järjestelmää. Frontin entry pointtina toimii index.jsx, jossa tapahtuu myös reititys React Router:illa. Kaikki komponentit löytyvät components hakemiston alta. Jokunen fronttiin liittyvä testi löytyy tests hakemiston alta. Testit toteutettiin työkaluilla Jest & React Test Utilities. Testejä ei keretty montaa tekemään, lähinnä vain todentamaan automaattisen testauksen toimivuus CI/CD-putkessa.

Sovelluksen backend toteutettiin NodeJS:llä ja ExpressJS:llä, joten myös backend on JavaScriptillä koodattu. Backendistä pyrittiin tekemään API tyylinen toteutus, josta meillä ei ollut aikaisempaa kokemusta. Keskustelu frontista -> bäkkiin tapahtuu Fetch:illä. Backend käyttää Passportia käyttäjän kirjautumiseen, johon löytyy kattavat dokumentaatiot passportin omilta sivuilta. Backendiin liittyvät koodit löytyvät filuista: server.js (entry point), routes.js (API endpointit) ja passport.js (login). Routes.js filussa piti sijaita vain API endpointit, mutta sinne päätyi myös kaikki niihin liittyvä logiikka.

Pystytys

Stackin saa cloudformationilla pystyyn, mutta kaikkia konfiguraatioita ja sidonnaisuuksia ei kyetty asettamaan automoidusti. RDS:lle generoituu aina uusi endpoint, joka täytyy vaihtaa webserverin environment fileen jotta server.js toimii.

Yleistä

Web-sovelluksella voidaan tehdä seuraavia toimintoja:

  • Kirjautuminen / rekisteröityminen
  • Useiden laitteiden lisääminen käyttäjälle
  • Laitteen mittausdatan esittäminen graafina
    • Esitettävän mittausdatan aikavälin määrittäminen
  • Ruokinta (heti tapahtuva) napin painalluksella
  • Anturin kalibrointi napin painalluksella
  • Automaattinen ruokinta aikataulu
    • Aikataulun luominen ja tallentaminen laitteelle
    • Laitteelle tallennetun aikataulun esittäminen ja muokkaaminen
    • Aikataulu merkinnät
      • Toistuva ruokinta (joka viikko tiettyinä päivinä, tiettyyn kellonaikaan)
      • Kertaluontoinen ruokinta (tiettynä yhtenä päivämääränä, tiettyyn kellonaikaan)
      • Merkintä päälle/pois
      • Syötteen tarkistukset

Sovelluksen näkymät

Sovelluksen ulkoasu on pitkälti tehty käyttäen Bootstrap:ia ja siihen tehtyjä plugareita. Sovellus skaalautuu nätisti myös mobiilille.

Koti Koti

Aikataulu Aikataulu

Kalibrointi Kalibrointi Kalibrointi_success Kalibrointi_fail

Kirjautuminen Kirjautuminen

Sovelluksen ja laitteen välinen kommunikaatio

Viestintä web-sovellukselta laitteelle ja toisinpäin tapahtuu AWS IoT Device SDK:n avulla, joka perustuu MQTT-protokollaan. Protokolla toimii "publish-subscribe" periaatteella: AWS IoT palvelussa on kaksi topiccia jokaista laitetta kohti (AppToDevice & DeviceToApp). Laite siis kuuntelee (subscribe) AppToDevice-topiccia ja lähettää (publish) viestit DeviceToApp-topicciin. Sovellus taas kuuntelee DeviceToApp-topiccia ja lähettää viestit AppToDevice-topicciin.

3.3 Tietokanta-arkkitehtuuri

Järjestelmässä on kaksi tietokantaa. MySQL joka on tarkoitettu käyttäjien hallintaan sekä Graphite, johon laitteiden tuottama mittausdata tallennetaan.

Graphiten storage schema konfiguraatiot:

Graphite Storage Schema

MySQL ER-kaavio:

MySQL ER Graph

3.4 Laitteen arkkitehtuuri

Laitteen käyttöönotto kuvattu omalla sivullaan: Wiki / Raspberry Pi käyttöönotto

Laite

Tiedostorakenne

/
|-- root-CA.crt
`-- aws-iot-sdk
`-- feeder
	| -- createcert.py
	| -- FeederProgram.py
	| -- HX711.py
            | -- HX711.pyc
	| -- idconf.py
            | -- idconf.pyc
            | -- init.sh
	| -- JSONMaker.py
	| -- JSONMaker.pyc
	| -- offset.dat
	| -- schedule.dat
	| -- schedule_fedtoday.dat
	| -- start.sh
	| -- todaysnumber.dat
            `-- update
	`-- cert
		| -- laitekohtainen.crt
		| -- laitekohtainen.pem.key
		| -- laitekohtainen.pem.key
		`-- default
	`-- PIGPIO
		|-- ...

Laitteen ohjelmisto on kirjoitettu Pythonilla (versio 2.7) ja ohjelmiston käynnistykseen vaadittavat toiminnallisuudet Bash-scriptilla.

Yleistä

Laite sisältää seuraavat toiminnallisuudet:

  • start.sh
    • Internet-yhteyden tarkistus ja odotus
    • Päivitysten saatavuus ja asennus
    • AWS IoT Root CA -sertifikaatin löytyminen ja nouto
    • AWS IoT SDK:n nouto ja asennus
    • PiGPIO -kirjaston löytyminen ja asennus, daemonin käynnistys
    • HX711 AD-muuntimen kirjaston löytyminen ja asennus
    • Apache Subversion löytymisen tarkistus ja asennus
    • Tarkistus, onko laitekohtaiset sertifikaatit luotu AWS IoT:ia varten. Jos ei, ajaa createcert.py:n, muuten tai tämän jälkeen ajaa FeederProgram.py:n
  • createcert.py
    • Identifioi laitteen MAC:n perusteella käyttäjän rekisteröintiä varten
    • Pyytää oletussertifikaateilla laitekohtaisia sertifikaateja AWS IoT:sta
    • Vastauksen saavuttua tallentaa uudet sertifikaatit ja tuhoaa oletussertifikaatit
    • Luo laitteelle yksilöivän ID:n uusien sertifikaatien perusteella
  • FeederProgram.py
    • Rekisteröityy yksilöidysti AWS IoTiin
    • Mittausdatan keruu painoanturilta ja lähetys tietokantaan
    • Painoanturin kalibrointi ja kalibroinnin kuittaus käyttäjän pyynnöstä
    • Aikataulujen vastaanotto, tallennus ja vastaanoton kuittaus käyttäjältä
    • Laitteeseen tallennetun aikataulun palautus käyttäjälle
    • Välitön ruokinta ja ruokinnan kuittaus käyttäjän pyynnöstä

4. Hylätyt ratkaisut

Alkuperäisessä suunnitelmassa stackin visualisointityökaluna oli ajatuksena käyttää Microsoftin Power Bi:tä, mutta se osottautui kelpaamattomaksi käyttötarkoituksiimme.

5. Jatkokehitysideat

Suunitelmissa oli myös kameran käyttöönotto, jossa käyttäjä voisi reaaliajassa nähdä laitteelta tulevan streamin. Tämä ominaisuus jäi kumminkin toteuttamatta, joten se siirtyy jatkokehitysideoihin.

6. Jäljelle jääneet ongelmakohdat

  • Ryhmä ei keksinyt keinoa miten kameran syöte saataisiin käyttäjälle verkkosivulle siten, että video kulkisi AWS IoT:n kautta tai loppukäyttäjän ei tarvitsisi muuttaa palomuurin asetuksia.

  • Palvelimet eivät saa yhteyttä toisiinsa sisäverkon osoitteilla. Graphite&Grafana -palvelin konffattiin pitämään tietty ip cloudformationissa, jota pystyttiin kyllä pingaamaan mutta siihen ei saatu toiselta palvelimelta yhteyttä.

  • Stackin pystytys toiselle aws tilille sisältää joitakin ongelmia. Koodia joutuu muuttamaan niin raspin kuin webserverinkin puolelta manuaalisesti viittaamaan oikeaan aws tiliin