BKK Futár Microsoft Bandre – service és webtile (3. rész)

A Microsoft Band programozási lehetőségeinek és a BKK Futár API-jának a megismerése után el kellett döntenem, hogyan is szeretnék menetrendi adatokat megjeleníteni a Banden. Végül a webtile mellett döntöttem, leginkább azért, mert az SDK-s megoldás egy folyamatosan futó mobil alkalmazást igényelt volna.

A webtile korlátja, hogy sajnos nem tudjuk befolyásolni, mikor frissüljön, ezért nem álmodozhatunk olyan megoldásról, ami relatív időpontokat használ. Le kell tehát mondanunk a “3 perc múlva indul” stílusú, azonnal érthető megjelenítésről, helyette abszolút időpontokat használhatunk, azaz például “indulás 11:23-kor”. Ez nem annyira szép, de nem óriási probléma, hiszen a Band elsődleges képernyője (Me Tile) mindig a pontos időt mutatja, egy ilyen bonyolult kivonást pedig rá merek bízni a felhasználóra.

A nagyobb probléma, hogy ezzel megszűnik a “következő indulás” fogalma, hiszen a frissítési időközön belül akár több indulás is lehet, és előfordulhat, hogy egy vagy több már múltbeli lesz, mikor a felhasználó rápillant a csempére. Erre nem tudtam jobb megoldást kitalálni, mint hogy több indulási időpontot jelenítek meg, amiből majd a felhasználó némi humán komparálással kiválasztja, hogy melyik a legközelebbi. Egyébként is terveztem, hogy célszerű lenne több időpontot megmutatni, hiszen előfordulhat, hogy a nem a következő buszt, hanem csak a következő utánit szeretném elérni, mert túl messze van a megálló. A sajnálatos szépséghiba, hogy a listában jó eséllyel lesz múltbeli időpont is.

Az adatforrás

A leendő webtile-t természetesen el kell látni adatokkal, azaz szükséges hozzá egy GET-en elérhető szerviz. Bár ahogy az előző részben láttuk, létezik BKK Futár API, az sajnos nem tudja az adatokat pont olyan formában szolgáltatni, amire nekünk szükségünk van. Az eltérések:

  • A Futár API az indulási időpontokat epochtól eltelt másodpercben adja meg, azaz egy bazi nagy, igen barátságtalan számként. Ezt sajnos a webtile nem tudja emberileg fogyasztható formátumra konvertálni.
  • Az API-ban van predictedArrivalTime, arrivalTime és departureTime mező is, és változó, hogy mikor melyik van kitöltve, vagy melyiket érdemes használni. Dokumentáció híján csak tippelni tudok, melyik mit jelent, de a tapasztalat az, hogy a predicted csak a már közeledő járműveknél van kitöltve (tipikusan a következő vagy esetleg a következő kettő), és ez a legpontosabb. A sima arrivalTime szinte mindig ki van töltve, kivéve végállomásoknál, ahol csak a departureTime jelenik meg.
  • Az API hívás sikerességét nem (vagy nem csak?) a HTTP status code, hanem a HTTP válaszban lévő több mező értéke együttesen írja le, amit webtile esetén nem tudunk vizsgálni.
  • A Futár API-tól a következő indulások objektum tömbként kérhetők le, azonban egyik lehetséges webtile layout sem tudja azokat praktikusan megjeleníteni. Sokkal jobb lenne egy vesszővel elválasztott string, például “10:45, 10:56, 11:07”, de ilyen adat átalakításra a webtile nem képes.

Ezen problémák miatt végül úgy döntöttem, hogy készítek egy saját webszervizt, ami adatokkal fogja táplálni Bandit. Tekintve, hogy viszonylag primitív logikáról van szó, ellenben van benne JSON matatás rendesen, és mostanában elsősorban JavaScriptben dolgozom, egy Node.js-es szolgáltatást készítettem. Webszerver frameworkként Hapi-t, a Futár API hívásához pedig a request-promise NPM package-et választottam, mert ezeket már ismertem korábban.

Mivel a webtile nem paraméterezhető, nem láttam értelmét olyan szolgáltatást készítésének, amit bárki, bármilyen járat indulásainak lekérésére használhat. Ez nagyban egyszerűsítette a dolgomat, mert így a KoviBuszból kikeresett megálló azonosítókat én bizony simán beledrótoztam a forráskódba. Az én szervizem, az én megállóim. Persze a forráskódot kitettem Githubra, hogy bárki barkácsolhasson magának hasonlót, vagy még jobbat:

github-logo

 https://github.com/balassy/band-futar-tile

Íme néhány érdekesebb pont a kódból:

  • A webszerviz kódja az src mappában található, a webtile által hívott végpont pedig azon belül a next-ride mappában.
  • Azon belül a service.js hívja a Futár API-t a paraméterként kapott megálló azonosítóval.
  • A service.js-t a controller.js hívja, átadva neki a keresett megállók azonosítóit.
  • A gulpfile.js az urbanjs-tools nevű NPM package-t használja statikus kódelemzésre, ami nagyon kényelmessé teszi az ESLint és az ES6 használatát.
  • A forráskódot Visual Studio Code-dal írtam, erre utalnak a .vscode, typings mappák és a tsd.json fájl. (Igen, a typings mappát nem kellene betenni a repoba, de így sokkal kényelmesebb volt.)
  • A projektet pillanatok alatt sikerült bekötnöm Travisbe és AppVeyorba, ezek beállításai találhatók a .travis.yml és az appveyor.yml fájlokban. Ezek az ingyenes online build környezetek segítettek a forráskód folyamatos karbantartásában, mindkettőt csak ajánlani tudom.

Hosting környezetnek természetesen Azure-t választottam, mert piszkosul egyszerű egy Githubon tárolt web alkalmazás continuous deploymentjét összelőni. Most amint felküldök egy kód módosítást a Githubra, lefut a build Travisben és települ is ki automatikusan az Azure-os webszerverre. Ez az automatizmus még egy ilyen egyszerű alkalmazás esetén is óriási segítség fejlesztés közben.

A webtile

A webtile elkészítéséhez az első részben is említett varázslót használtam. Úgy döntöttem, hogy ez egyes járatok adatait külön page-en fogom megjeleníteni (Multiple page tile), azon belül egy a Scrolling text wrap (MSBand_ScrollingText) elrendezés bizonyult legpraktikusabbnak az ismeretlen hosszúságú szöveg megjelenítésére. Ezt így mutatja a varázsló (az 59-es villamos következő indulásai a Vas Gereben utcai megállóból):

band-webtile-wizard-preview-1

Jelenleg a szerviz az engem leginkább érdeklő három járat adatait adja vissza, ezek mind külön page-et kaptak, utánuk pedig egy negyedik oldalra az utolsó frissítés időpontját tettem. Ez hibakereséshez lehet jó, a szerviz a válasz JSON egyik property-jében visszaadja, hogy mikor kérte le utoljára az adatokat a Futár API-tól, így könnyű volt megjeleníteni:

band-webtile-wizard-preview-2

A varázsló által generált webtile-t nem közvetlenül telepítettem Bandira, hanem letöltöttem, kicsomagoltam (mert valójában egy ZIP fájl), és módosítottam rajta (a végeredmény megtalálható a a webtile/manifest.json fájlban):

  • Kijavítottam azokat az apró hibákat, amiket a webes varázslóban egyszerűen nem sikerült.
  • Beállítottam a refreshIntervalMinutes tulajdonság értékét 15-re, ami negyedórás frissítési időközt jelent, ennél sűrűbben nem is lehet.
  • Beállítottam a version és a versionString tulajdonságokat, és minden újabb kísérletnél inkrementáltam őket, hogy biztosan észrevegye a Microsoft Health alkalmazás, hogy újabb verziót akarok telepíteni.
  • Beállítottam a name, description, author, organization és contactEmail tulajdonságok értékeit, hogy azok kulturáltan jelenjenek meg telepítéskor.

Jelenleg a webszerviz HTTP 500 status code-dal tér vissza, ha valami nem sikerül szerver oldalon, de erősen gondolkodom rajta, hogy hibakeresési célzattal minden ilyen esetben HTTP 200 OK-val térjek vissza, és a hiba leírását adjam vissza a válaszban, hogy azt könnyen meg lehessen jeleníteni a Banden.

A végeredmény

Örömmel tölt el, hogy az elkészült megoldás működik, a Futár API-tól kapott adatok megjelennek, és a megoldás nem bonyolult.

band-futar-tile

band-futar-page

band-futar-update-page

A Futár igazi értéke abban van, hogy nem csak egy sima menetrend, hanem (elméletileg legalábbis) valós idejű adatokat tartalmaz, azaz az aktuális forgalmi helyzetet tükrözi. Sajnos a webtile legjobb esetben is negyedórás frissítési időköze ezt a remek lehetőséget tökéletesen megöli, ami már kevésbé örvendetes, hiszen így az esetek nagy részében “csak” a menetrendi adatokat látom, ami Tokióban minden bizonnyal tökéletesen működne, Budapesten még nem 100%-os. Mivel engem leggyakrabban egy villamosmegálló és egy buszvégállomás indulási időpontjai érdekelnek, számomra egészen jól használható a végeredmény.

Te milyen adatokat látnál szívesen az órádon?

 

Technorati-címkék: ,

Leave a comment