Alkuvalmistelut

Ensto/Koodin dokumentaatio/Main/Alkuvalmistelut

Rivillä 426 alkaa ohjelman suoritus. Aluksi luodaan uusi bluetooth-olio, jolla alamme “mainostamaan” SiPyä bluetoothin kautta nimellä Kuormanohjausyksikkö. Tällöin muut laitteet pystyvät näkemään SiPyn ja yrittää muodostaa yhteyden siihen. Kyseessä ei ole kuitenkaan laitteiden pair:aus; puhelimeen tarvitaan erillinen applikaatio, joka yhdistää SiPyyn.

(Rivit 439-444)Luodaan bluetooth-palvelut ja niille characteristic:sit. Yhdistyneet laitteet pystyvät näkemään nämä palvelut. Se, että ne ovat primaarisia, tarkoittaa, että muut laitteet pystyvät näkemään ne. Sekundaariset palvelut ovat saatavilla vain laitteelle itselleen ja sen palveluille. Characteristic:siin pystytään tallentamaan yksi arvo. Niiden luonnissa pystytään määrittelemään mitä ominaisuuksia niillä on, esimerkiksi wifiChara-characteristic:silla on ominaisuus WRITE, eli characteristic:siin pystytään lähettämään dataa.

(Rivit 446-448)Seuraavaksi määritellään eri characteristic:sien callbackit. Toisin sanoen funktiot, joita kutsutaan kun jotakin tiettyä tapahtuu. Esimerkiksi kun bluetooth-characteristic:sissa tapahtuu joko tapahtuma CLIENT_CONNECTED tai CLIENT_DISCONNECTED, niin kutsutaan funktiota conn_cb. InfoCharan rekisteröidessä arvon lukemisen, kutsutaan sendInfo-funktiota, mutta emme tehneet tätä osaa ohjelmasta loppuun. Jos meillä olisi oma bluetooth-applikaatio puhelimessamme, voisimme lähettää tällä dataa puhelimeen SiPystä.

(Rivit 450-454,457)Connected-muuttuja kertoo onko meillä yhteys johonkin laitteeseen. Proceed-muuttuja kertoo haluammeko siirtyä ohjelmassa eteenpäin, vai odottaa laitteen yhdistämistä. BluetoothTimer on ajastin, joka mittaa kulunutta aikaa. Ssid ja password ovat muuttujia, joihin tallennetaan haluamamme wifi-yhteyden nimi ja salasana. Aluksi avaamme ne paikallisesta tiedostosta openWifiInfo-funktiolla.

(Rivit 456,458)Aloitamme SiPymme “mainostamisen” bluetoothissa ja aloitamme ajastimen ajanlaskun.

(Rivit 462-467)Loopataan, odottaen, että jokin laite yrittäisi ottaa yhteyttä SiPyyn. Mikäli yli kaksikymmentä sekuntia on kulunut, eikä yhteyttä ole luotu, etenee ohjelma.

(Rivit 429-437)Funktio conn_cb aktivoituu kun SiPy huomaa laitteen ottaneen yhteyden tai katkaisseen sen. Connected-muuttujan arvo muutetaan vastaamaan tätä tilannetta, jolloin ohjelma tietää odottaa lisää käskyjä bluetoothin kautta.

(Rivit 391-422)Funktiota receiveWifiInfo kutsutaan kun dataa vastaanotetaan puhelimesta Bluetoothin kautta. Globaalit muuttujat ssid, password, proceed ja bluetoothTimer julistetaan funktion aluksi. Muuttujiin ssid ja password tallennetaan vastaanotettu SSID ja salasana. Parametrina saadaan jonkin bluetooth-palvelun characteristic, josta saamme bluetooth-tapahtumat events()-funktiolla. Jos events-muuttuja ei ole tyhjä ja on tapahtunut bluetooth-kirjoitustapahtuma(SiPyä kohti) edetään koodissa.

Ohjelma pystyy vastaanottamaan neljä eri komentoa: “0 —”, joka vaihtaa ssid-muuttujan arvon kolmen viivan kohdalla olevaksi merkkijonoksi; “1 —”, joka vaihtaa password-muuttujan arvon; “2 ok”, joka kertoo ohjelmalle, että sen pitää lopettaa komentojen odottaminen bluetoothissa ja edetä suorituksessaan; sekä “33”, joka kertoo ohjelmalle, että halutulla SSID:llä ei ole salasanaa.

Aluksi syöttö muutetaan merkkijonoksi ottamalla aluksi characteristic:in arvo value-funktiolla ja sitten dekoodaamalla saatu tulos decode-funktiolla, syötteenä utf-8. Tämän jälkeen syöte jaetaan listaan osiin välilyöntien mukaan. Näitä arvoja verrataan olemassa oleviin komentoihin ja mikäli ne vastaavat, suoritetaan koodia. Kahdessa ensimmäisessä tapauksessa merkkijonot vain kopioidaan muuttujiin. Jos syöte on “2 ok”, proceed-muuttujan arvoksi asetetaan True, jotta ohjelma etenisi ja bluetoothTimer resetoidaan ja pysäytetään. Jos syöte on “33”, niin muuttujaan password tallennetaan tyhjä merkkijono.

Lopuksi ohjelma tallentaa uudet(tai vanhat) arvot paikallisesti saveWifiInfo-funktion avulla.

(Rivit 469-471)Seuraavaksi bluetoothTimer pysäytetään ja poistetaan muistin säästämiseksi.

(Rivit 473-490)Nyt kun tiedämme mihin wifiin haluamme yhdistää, otetaan yhteys siihen. Luodaan uusi wlan-olio, jonka asetuksena on STA, eli station, eli asema. Nets-listaan haetaan kaikki wlan:it, jotka SiPy löytää.

Seuraavaksi käymme niitä läpi ja tutkimme onko joku niistä samanniminen kuin haluamamme verkko. Mikäli on, yritetään yhdistystä connect-funktiolla, joko salasanalla tai ilman. Odotetaan kunnes yhteys onnistuu, tai kuluu 5 sekuntia, jonka jälkeen yritetään uudestaan. Jos yhteys onnistuu pystyy koodi taas etenemään. Rivillä 494 sammutetaan SiPyn automaattinen ledin vilkutus, koska käytämme lediä myöhemmin koodin etenemisen visualisoimiseen.

Rivillä 500 luodaan ajastin, jota käytetään mittausten välisen ajan mittaamiseen. Se pyörii jatkuvasti ja nykyistä arvoa verrataan edelliseen. Lisäksi asetamme voltage-muuttujan arvoksi 235. Oletamme siis, että jännite pysyy vakiona, vaikka se voikin todellisuudessa vaihdella.

(Rivit 509-521)Seuraavaksi määritellään tiedosto, jossa on tiedot pilven tietokannan käyttäjätunnuksista ja salasanoista. Lisäksi määritellään listat kuormille ja vaiheille, johon ne tallennetaan openLoads- ja openPhases-funktioiden avulla. Lopuksi kuormat lajitellaan oikeisiin vaiheisiin sortLoads-funktion avulla.

(Rivit 523-535)Nyt voimme luoda ohjausmuuttujien tarkistusta varten oman threadin pääohjelman rinnalle. Asetetaan startto-muuttuja epätodeksi, jottei threadi ala tekemään vielä mitään. Aktivoimme sen myöhemmin. Threadin luominen vie paljon muistia ja se ei aina onnistu. Tällöin SiPy yrittää uudelleen ja vilkuttaa vihreää valoa.

Muistia voi olla liian vähän, mutta meidän projektissamme ainakin ongelmana oli että se oli liian hajanaista. Threadi vaatii pitkän pätkän vapaata muistia, mutta ohjelmassamme oli yksittäisiä arvoja pitkien tyhjien alueiden välissä, jotka estivät threadin luomisen. Siirsimme siksi threadin luomisen aikaisempaan osaan ohjelmaa, jossa muuttujia ei ole määritelty vielä yhtä paljon. Luonti ei silti onnistu aina, joten sen voisi siirtää aivan ohjelman alkuun, tosin silloin pitäisi threadin käyttämät parametrit ja globaalit muuttujatkin määritellä ainakin alustavasti aikaisemmin ohjelman osassa.

(Rivit 537-543)Seuraavaksi initialisoimme SiPylle RTC:n (real-time clock), jonka avulla pystymme seuraamaan kuluvaa aikaa. Synkronoimme kellon vastaamaan nykyistä aikaa erään ntp-serverin avulla. Kun tämä on tehty, lopetamme yhteyden.

(Rivit 545-556)Seuraavaksi määrittelemme muuttujiin mitä tuntia mittaamme juuri tällä hetkellä. Käytämme tähän vuotta, kuukautta, päivää ja tuntia. Kun SiPy huomaa RTC:n tunnin olevan eri kuin nykyinen mitattava tunti, tietää se tunnin vaihtuneen. Lopuksi suljemme openLoads- ja openPhases-funktioiden palauttamat socketit, muistin vapauttamiseksi.

(Rivi 561)Avaamme openPass-funktiolla tiedostosta InfluxDB-tietokannan käyttäjätunnuksen ja salasanan.

(Rivit 563-565)Seuraavaksi haemme mahdolliset nykyisen kuluvan tunnin kulutukset pilven tietokannasta getCloudEnes-funktion avulla. Toisin sanoen jos SiPy sammuu kesken tunnin, kulutukset eivät resetoidu nollaan.

(Rivit 567-571)Määritellään tunnin aikana kulutettava maksimienergia wattitunteina ja siihen liittyvä maksimiteho. Näiden muuttujien arvot tulevat muuttumaan ohjelman aikana. Lisäksi määritellään hourThreshold-muuttuja, jonka avulla voidaan rajoittaa millä raja-arvolla maksimitehosta kuormia voidaan kytkeä takaisin päälle.

(Rivit 573-576)Lopuksi käynnistämme pääloopin. Tarkistamme, että tiedosto joka pyörittää koodia nyt on varmasti main-niminen, sen varalta että päälooppia ei käynnistetä jos tämä tiedosto tuotaisiin osaksi jotakin toista koodia, jolla on oma päälooppinsa.