Tämän rakentelun toteutti Jere ja hän on tekemästään työstä kirjoittanut seuraavasti.
Elektroniikka-aiheisen sivuston vieraskynäilijän roolissa otan kunniatehtävän vastaan kirjoittaa hieman softapainotteisempi artikkeli.
Pääkaupunkiseudulla asuessani olen sataprosenttisesti julkisen liikenteen armoilla (ihan omasta tahdostani). HSL.fi –sivusto sekä Andropas-sovellus on tullut tutuksi kyytejä etsiessä. Kotona kuitenkin haluan vapautua samojen sivujen sekä jatkuvan klikkailun ja tarkistelun tuomasta taakasta. Tästä syntyi ajatus luoda kotiin alati päällä oleva bussiaikataulu, joka päivittyy itsestään. Valitsin alustaksi Raspberry Pi 3 model B:n sekä siihen Raspberry Pi 7” WVGA –kosketusnäytön. Minulle on tärkeää, että näyttö sopii hyllyyn, ja Raspberry toimii langattomassa verkossa. Joku on toteuttanut vastaavan projektin jo aikaisemmin television näytölle, mutta en ikinä avaa aamulla televisiota, joten tämä on itselleni luonnollisempi ratkaisu.
Tietojen kerääminen HSL:n sivuilta
Ensin piti ottaa selvää, millaista rajapintaa käyttäen saan tarvitsemani tiedot. Löysin HSL:n developer-sivuja kaivamalla tarvitsemani pdf-tiedoston (http://developer.reittiopas.fi/media/Omat_Lahdot_v101.pdf). Täältä löytyy WSDL-rajapintakuvaus, jonka voi avata esim. SoapUI-ohjelmassa. Tästä näkymästä huomasin, että getNextDepartures-rajapinta palvelee tarvettani täydellisesti.
Alla puurakenne rajapinnasta:
- HSL
- KAMOInterfaceBinding
- getLines
- getNextDepartures
- getNextDeparturesExt
- getNextDeparturesExtRT
- getNextDeparturesRT
- getNextDeparturesRTStops
- getPassingTimes
- getStopInfo
- KAMOInterfaceBinding
Rajapinnan ja toiminnallisuuden toteutus
Serverikielenä pidän PHP:sta, joten toteutin yksinkertaisen API:n hakemaan tiedot digitransitin SOAP-rajapinnan yli, iteroimaan tuloksen PHP-objektina ja paketoimaan halutut tiedot JSON-formaattiin.
Haku tapahtuu pysäkin id-tunnisteen perusteella, jonka kaivoin HSL:n sivujen kautta seuraavasti:
Navigoi hsl.fi ja kirjoita hakukenttään haluamasi pysäkin nimi. Tämän jälkeen hakutuloksista paina haluamasi pysäkin kohdalla aikataulu-linkkiä. Seuraavaksi avautuvan sivun URL-osoite on muotoa: https://aikataulut.reittiopas.fi/pysakit/fi/xxxxxxx.html
Jossa juuri ennen html-päätettä on seitsemän merkin mittainen numero. Tämä numero on tarvitsemasi id.
Client-osuuden toteutin Python 3:lla ja Tkinter-grafiikkakirjastolla. Päällimmäinen ajatus oli saada tiedot päivittymään automaattisesti ruudulle 30 sekunnin välein.
Tämän mahdollistaa Tkinterin after-metodi: self.main.after(30000, self.update_txt). Ohjelmasta piti saada myös tarpeeksi vakaa kestämään virheitä, joten kirjoitin metodin, joka nappaa suurimman osan PHP:n puolelta tulevista virhetilanteista ilman, että itse ohjelman suoritus kaatuu.
Bussipysäkin sijainnista johtuen määritin myös värikoodauksen: <= 2min punainen, > 2min ja >= 5min keltainen ja muuten valkoinen. Tämä tarkoittaa sitä, että punaiseen vuoroon en enää ehdi, ja keltaiseen pitää lähteä heti. Arvioitu ohitusaika pyöristetään lähimpään täyteen minuuttiin.
Ohjelmakoodin toteutukseen meni noin kolme – neljä päivää, ja lisäksi parin viikon testausjakson aikana korjailin koodia niin, että ohjelma pysyy käynnissä ympäri vuorokauden. Rajapinnan dokumentaatio ajoittuu vuodelle ~2010 ja huomasin, että joka aamuyö klo 4:15 SOAP-rajapinta palauttaa tyhjän objektin, johon koodini suoritus kaatui monta yötä peräkkäin.
Config.py-tiedostoon voi määrittää seuraavia haluamiaan arvoja:
showStopAndDestination=0 (näyttää lähtö- ja kohdepysäkit, ei suositella pienille näytöille)
waitUntilNextFullMinute=1 (debuggaukseen tarkoitettu ominaisuus)
stopId=1491123 (pysäkin tunniste, tässä tapauksessa oman lähipysäkkini id)
Lähdekoodit ja lopputulos
Jeren kirjoittama lähdekoodi tälle projektille löytyy kätevästi GitHubista, osoitteesta https://github.com/jerekarppinen/busdisplay/
Lopputuloksena syntyi alla olevan kuvan mukainen näyttö. Kiitoksia Jerelle vaivan näöstä artikkelin kirjoitukseen! Tulostin tämän projektin osalta myös Jeren näyttöön tukijalat 3D-tulostimellani, siitä voit lukea lisää tästä linkistä.