UNIVERZA V MARIBORU FAKULTETA ZA ELEKTROTEHNIKO, RAČUNALNIŠTVO IN INFORMATIKO POROČILO PRAKTIČNEGA IZOBRAŽEVANJA v Termoelektrarni Šoštanj Čas opravljanja od 22.4.2014 do 7.7.2014 Mentor v GD Marko Pečovnik Študent Rok Penšek Vpisna številka E1055883 E-pošta rok.pensek@gmail.com Telefon 031 705512 Šoštanj, julij 2014
2
3
Kazalo 1. Uvod... 6 2. Opis gospodarske družbe... 6 3. Opis praktičnega izobraževanja... 7 3.1. Opis Cordova... 7 3.2. Opis razvojnega okolja Eclipse... 9 3.3. Namestitev in nastavitev razvojnega okolja Eclipse... 10 3.4. Namestitev in nastavitev Cordova... 12 3.5. Nastavitve Android emulatorja in pogon aplikacije HelloWorld... 19 3.6. Delovanje Apache Cordova... 22 3.7. Programiranje aplikacije Kolibri v Apache Cordova... 23 4. Povzetek... 34 5. Zaključek... 35 Kazalo slik Slika 1: Logotip podjetja Temoelektrarna Šoštanj... 6 Slika 2: Logotipi Apache Cordova, Adobe PhoneGap in Adobe PhoneGap Build... 7 Slika 3: Logotip Eclipse... 9 Slika 4: IDE Eclipse ADT... 9 Slika 5: Zaslonska maska - Razvojno okolje Eclipse ADT... 10 Slika 6: Zaslonska maska - Uvoz projekta iz SVN repozitorija... 11 Slika 7: Logotip Node.js... 12 Slika 8: Zaslonska maska namestitve Cordova preko CLI... 12 Slika 9: Zaslonska maska - Preverjanje delovanja Cordove... 13 Slika 10: Zaslonska maska - Izdelava HelloWorld aplikacije v Cordova... 13 Slika 11: Zaslonska maska - Napaka ob dodajanju platforme Android... 14 Slika 12: Zaslonska maska - Nameščanje novejše različice Android API (19)... 15 Slika 13: Zaslonska maska - Uspešno dodana platforma Android... 15 4
Slika 14: Hierarhija map v Cordova HelloWorld projektu... 16 Slika 15: Zaslonska maska mape www v projektu HelloWorld... 17 Slika 16: Zaslonska maska - Prikaz aplikacije HelloWorld v brskalniku Chrome... 18 Slika 17: Zaslonska maska - Ustvarjanje Android virtualne naprave... 19 Slika 18: Zaslonska maska - Uspešno generiranje aplikacije in zagon Android emulatorja... 20 Slika 19: Zaslonska maska - Uspešen zagon mobilne aplikacije HelloWorld... 21 Slika 20: Logotip mobilne aplikacije Kolibri... 23 Slika 21: Zaslonska maska - Posodobitev projekta Kolibri... 24 Slika 22: Zaslonska maska - Mobilna aplikacija Kolibri... 24 Slika 23: Zaslonska maska - Uspešno implementiran meni... 27 Slika 24: Zaslonska maska - Prikaz grafičnega vmesnika Golob... 28 Kazalo programskih kod Programska koda 1: Datoteka index.html... 22 Programska koda 2: Datoteka index.js... 22 Programska koda 3: Uporaba jquery Mobile panelov v kombinaciji z Listview za izdelavo menija... 26 Programska koda 4: Implementacija Sinice... 27 Programska koda 5: Funkcija za prikaz uporabnikov v sklopu aplikacije Kolibri - Golob 32 Programska koda 6: Prikaz funkcij za spreminjanje stanja naročnin in uporabnikov... 33 5
1. Uvod Za praktični del visokošolskega izobraževanja v želji po pridobitvi čim večjega znanja v večjih podjetjih, sem opravljal v podjetju Termoelektrarna Šoštanj d.o.o. in sicer od 22. 4. 2014 ter do 7. 7. 2014 v prostorih upravne stavbe v TEŠ-u. Prvi dan so me v službi za izobraževanje seznanili z vsemi informacijami o zgodovini TEŠ-a, s čim vse se ukvarjajo, delovnimi navadami, varnosti pri delu in ISO standardi. Pred začetkom dela sem moral opraviti tudi kviz o varnosti pri delu, preko njihovega interaktivnega portala Moodle. V začetnem tednu sem tako spoznaval pisarniško delo v arhivu in knjižnici, z uporabo različnih orodij iz nabora Microsoft Office. Naslednja 2 tedna pa sem pričel z delom v podpornem centru TEŠ-a, kjer sem skrbel za namestitev in servis različnih pisarniških naprav, za odpravo osnovnih napak pri uporabnikih ob uporabi različnih pisarniških orodij. Zadnje tedne pa sem zaradi želje po večjem znanju pomagal pri razvoju mobilne aplikacije Kolibri s pomočjo zunanjih izvajalcev programerjev iz podjetja Artes. Večji del praktičnega izobraževanja v podjetju je bil namenjen razvoju mobilne aplikacije. Cordova tehnologija, ki sem jo uporabil je precej nova, zato bom le-to skozi poročilo tudi podrobno opisal. 2. Opis gospodarske družbe Slika 1: Logotip podjetja Temoelektrarna Šoštanj Termoelektrarna Šoštanj je družba z omejeno odgovornostjo, kjer se ukvarjajo pretežno z proizvodnjo elektrike in toplote za daljinsko ogrevanje. Proizvedejo 779 MW električne energije kar predstavlja približno tretjino energije, ki jo porabimo v državi, ob kriznih obdobjih pa pokrivajo tudi preko polovico porabe. Povprečna letna proizvodnja električne energije se giblje med 3.500 in 3.800 GWh. Povprečna letna proizvodnja toplotne energije, za daljinsko ogrevanje Šaleške doline, znaša 400-450 GWh. Za omenjeno letno proizvodnjo 6
električne in toplotne energije porabijo med 3,5 in 4,2 milijonov ton premoga in okoli 60 milijonov Sm 3 zemeljskega plina. Rezultate obratovalne pripravljenosti njihovih blokov lahko primerjamo z boljšimi evropskimi termoelektrarnami. 3. Opis praktičnega izobraževanja Kot sem že omenil v uvodu, bom v tem poročilu pretežno opisal proces dodelave mobilne aplikacije od namestitve razvojnega okolja Eclipse, namestitve Cordova, do izdelave preproste mobilne aplikacije ter pogona preko Android emulatorja ali testne mobilne naprave. Za začetek pa bom na kratko opisal kaj sploh je Cordova. 3.1. Opis Cordova Na začetku je bil PhoneGap odprtokodni projekt podjetja Nitobi. Kot del prevzema podjetja Nitobi s strani podjetja Adobe, so pridobili tudi pravice nad omenjeni projekt ter ga pričeli tržiti. Ker pa so od tega projekta pred prevzemom beneficirala večja podjetja kot je tudi IBM, so projekt dali organizaciji Apache Software Foundation pod imenom»callback«. Kasneje so ime spremenili v Cordova in tako danes obstajata dve rešitvi. Phonegap, ki je plačljiv in bazira na kodi Cordova ter Cordova kot odprtokodna rešitev. PhoneGap Build pa je ločena storitev, ki skrbi za gradnjo in testiranje mobilnih aplikacij v oblaku. To zgodovino sem obrazložil tudi zaradi tega, ker je veliko zmede na spletu glede teh dveh orodij. Slika 2: Logotipi Apache Cordova, Adobe PhoneGap in Adobe PhoneGap Build 7
Skratka Cordova je nabor API-jev za upravljanje z mobilnimi napravami in je del organizacije Apache. Ko orodje nabor API-jev Cordova za dostop do funkcij telefon (kamera, pomnilnik ipd.) kombiniramo s spletnimi jeziki kot so: HTML5, CSS3, JavaScript jquery, jquery UI, jquery Mobile, imamo možnost sprogramirati aplikacijo za pametne telefone brez znanja specifičnih jezikov za vsako napravo (Java, Objektni C, C#, ipd.). Na ta način lahko izdelamo aplikacijo v spletnih jezikih in če jo pišemo po zadnjih smernicah in se držimo standardov, lahko isto kodo z zelo majhnim številom popravkom ali odsotnostjo le-teh izdelamo aplikacijo za različne operacijske sisteme. Podprtih mobilnih operacijskih sistemov pa ni malo: Android Bada BlackBerry FirefoxOS ios WebOS Windows Phone 7 Windows Phone 8 Cordova nam omogoča z uporabo Javaskripte dostopati do sledečih glavnih funkcij mobilnih naprav: stanje baterije, kamera, kontakti, orientacija naprave, žiroskop, dialogi, datoteke, upravljanje z datotekami, geo lokacija, globalizacija, brskalnik znotraj aplikacije, informacije o povezljivosti (WIFI, podatkovni prenosi ipd.), če seveda te obstajajo v specifični napravi. 8
3.2. Opis razvojnega okolja Eclipse Ker sedaj vem kaj je Cordova, sem se moral odločiti v katerem razvojnem okolju bom programiral aplikacijo. Ker je aplikacija že napisana za Android in v podjetju Artes uporabljajo Eclipse, sem se odločil, da ga bom preizkusil. Slika 3: Logotip Eclipse Na kratko Eclipse je eno izmed najbolj popularnih orodij za razvoj programske opreme, ki se lahko postavi ob bok Microsoft Visual Studiju. V osnovi je bil Eclipse izdan pod licenco Common Public Licence, a so jo kasneje spremenili v Eclipse Public Licence. V osnovi je brezplačen ampak je nekompatibilen z GNU GPL licenco. Eclipse kot razvojno orodje ima poleg osnovne podpore oz. distribucije tudi veliko ostalih za različne namene. Osnovna oz. trenutna različica Eclipse Luna nudi podporo razvijalcem programskega jezika Java obstaja pa tudi veliko alternativnih distribucij, ki nudijo podporo drugim programskih jezikom kot npr: Eclipse PDT (PHP razvoja orodja), Eclipse ADT (Android razvojna orodja). Ker bom razvijal primarno aplikacijo za Android sem se odločil za uporabo Eclipse ADT. Slika 4: IDE Eclipse ADT 9
3.3. Namestitev in nastavitev razvojnega okolja Eclipse Najprej sem si snel 354MB velik paket Eclipse ADT iz android spletnega mesta za operacijski sistem Windows x64: http://developer.android.com/sdk/index.html. Naj omenim to zanimivost da v nasprotju z razvojnim okoljem Microsoft Visual Studio, Eclipse nima na voljo inštalacijskega programa. Za inštalacijo je potrebno.zip arhiv samo sneti in razpakirati na želeno mesto. Jaz sem ga namestil na C:\ADT. Ob prvem zagonu me vpraša za delovni prostor, ki sem ga definiral kot pot C:\ADT Projects\ in po nekaj trenutkih me že pričaka razvojno okolje. Slika 5: Zaslonska maska - Razvojno okolje Eclipse ADT Za lažje»ekipno«programiranje sem namestil tudi vtičnik Subversive Team Provider in SVN connector, ki mi pravzaprav omogoča dostop do SVN repozitorija kjer se že nahaja vsa koda mobilne aplikacije Kolibri. 10
Slika 6: Zaslonska maska - Uvoz projekta iz SVN repozitorija Prednost, ki jo SVN omogoča je ta, da programiramo lokalno ter vsakič, ko naložimo oz. shranimo na SVN naš projekt, se vedno ustvari nova revizija oz. različica projekta kot tudi datotek ločeno. Na ta način imam lahko za celoten projekt pregled vseh datotek za nazaj in se lahko kadarkoli v primeru težav ali izgube podatkov vrnemo nazaj. Lahko tudi izberemo najnovejšo različico projekta in posebej določimo oz. snamemo specifične datoteke starejših revizij. Namestil sem tudi Aptana Studio vtičnik, ki mi omogoča lažje urejanje datotek html, css, javascript, saj mi nudi vso podporo pri programiranju kot je recimo barvna usklajenost značk in lažja berljivost kode, pomaga pa mi tudi pri programiranju z predlaganjem funkcij. Ker zaradi standarda ISO 27001, ki opredeljuje varnost podatkov ne smem izdajati vpoglede v samo izvorno kodo aplikacije Kolibri, bom v naslednjih korakih prikazal namestitev, delovanje in izvajanje aplikacije preko Cordova na preprosti»helloworld«aplikaciji. 11
3.4. Namestitev in nastavitev Cordova Pri namestitvi Cordove sem si pomagal z vodičem v njihovi dokumentaciji na naslovu: https://cordova.apache.org/docs/en/2.9.0/guide_cli_index.md.html. Najprej sem si snel dol po navodilih snel Node.js, saj mi bo ta omogočal»node«in»npm«klice, ki so potrebni za avtomatizacijo inštalacije Cordova. Slika 7: Logotip Node.js Ker mi»npm«in»node«ukaza ni zaznalo preko vrstice, sem moral pod spremenljivke okolja še v spremenljivko»path«dodati:»;c:\program Files\nodejs\«. Zatem sem pognal Ukazno vrstico v Windows in vpisal sledeče komande: npm install g cordova npm update g cordova cordova -v Z zadnjo komando sem tako preveril različico cordove oz. pomembneje, preveril sem ali Cordova deluje. Slika 8: Zaslonska maska namestitve Cordova preko CLI 12
Slika 9: Zaslonska maska - Preverjanje delovanja Cordove Za začetek sem želel izdelavi Cordova projekt, ki vsebuje vse potrebno za izdelavo. Na spletu sem v dokumentaciji zasledil komando, ki izdela HelloWorld projekt, ki bi ga lahko kasneje pretestiral na emulatorju oz. testni napravi: cordova create HelloWorld com.example.hello "Hello World" Slika 10: Zaslonska maska - Izdelava HelloWorld aplikacije v Cordova Sedaj sem izdelal direktorij z HelloWorld aplikacijo v c:\adt Projects. Ker Cordova omogoča več platform je te potrebno dodati v HelloWorld direktorij. Ker bom testiral samo Android, bom izvedel samo sledečo komando: cordova platform add android Cordova me je ob zagonu te komande opozorila, da mi manjka ant vtičnik. Zato sem tega na snel na netu in ga razširil v C:\apache-ant-1.9.4 in nastavil spremenljivke okolja PATH, ANT_HOME in ANT_OPTS ter poskusil ponovno. Zatem sem prejel napako še z vidika Cordove, po nekaj zadetkih preko brskalnika Google sem našel krivca in sicer ADT SDK. Namreč spremenljivke okolja niso bile dodane ob konfiguraciji avtomatsko na Android SDK. 13
Te sem še dodal in sicer v spremenljivko PATH in sicer sledeče mape oz. poti: C:\ADT\sdk\tools\ C:\ADT\sdk\platform-tools\ C:\ADT\sdk\build-tools\ Poskusil sem ponovno in sem kasneje prejel še eno napako, češ da moram namestiti novejši Android SDK 19. Slika 11: Zaslonska maska - Napaka ob dodajanju platforme Android 14
Tako sem vnesel komando android in v Android SDK Managerjem prenesel novejšo različico SDK. Slika 12: Zaslonska maska - Nameščanje novejše različice Android API (19) Po uspešni namestivi novejšega SDK-ja sem končno prišel do uspešnega kreiranja platforme Android. Slika 13: Zaslonska maska - Uspešno dodana platforma Android 15
Za lažjo predstavo sem naredil tudi zaslonsko masko mape novo ustvarjenega projekta, ki ga bom poskusil razložiti v nekaj kratkih stavkih. Slika 14: Hierarhija map v Cordova HelloWorld projektu 16
Znotraj HelloWorld projekta oz. mape (Slika 14) imamo veliko map in podmap, ki nam jih je ustvarila Cordova. Na prvi ravni so: hooks, platforms, plugins in www. V mapi hooks lahko ustvarimo mape z vnaprej specificiranimi imeni (after-build, before-build, afterprepare itd.), znotraj teh pa skripte v priljubljenem jeziku bodisi bash, javascript, powershell in podobni. Namen ti. hooks-ov je da ob določenih akcijah sporočimo Cordovi naj izvede nekatere delčke naše kode. Lahko jih vršimo v procesu med dodajanjem novih platform, ob»compile«akciji oz.»build«in še bi lahko našteval. Mapa platforms se ustvari, ko ustvarimo projekt, znotraj teh map pa se ustvarijo mape»android«,»ios«,»bb«, in ostale, takrat ko dodajamo nove platforme. Znotraj teh map Cordova za vsako platformo posebej ustvari tudi potrebne Javaskripte za klicanje API-jev za dostop do naprav za vsak OS posebej, kot tudi ikone, dodatne Cordova knjižice, končne vršilne testne datoteke in navsezadnje našo kodo v platform_www. Vse te mape znotraj mape»platforms«se posodabljajo vsakič, ko vršimo»build«akcijo preko Cordove, zatorej programiranje znotraj mape»platforms«ni dovoljeno. Nam najbolj zanimiva mapa je vsekakor mapa www. Ta mapa ostaja ne glede na to katerokoli akcijo vršimo pri miru in vse spremembe, ki jih naredimo znotraj se aplicirajo na vse platforme ob akciji»build«. V tej mapi (Slika 15) lahko vidimo datoteke, ki bi jih običajno ustvarili ob izdelavi spletne strani. Slika 15: Zaslonska maska mape www v projektu HelloWorld 17
Če se odločimo pognati index.html datoteko, že vidimo približno kakšen prikaz nas čaka na mobilni napravi. Slika 16: Zaslonska maska - Prikaz aplikacije HelloWorld v brskalniku Chrome Sedaj ko imamo uspešno izdelan Cordova projekt in nastavljeno vso potrebno programsko opremo, bomo aplikacijo v naslednjem koraku poskusili pognati preko mobilnega operacijskega sistema Android. 18
3.5. Nastavitve Android emulatorja in pogon aplikacije HelloWorld Ker si ne lastim nobene Android naprave sem moral ustvariti emulator na računalniku za uspešno testiranje aplikacije. Pri ustvarjanju emulatorja sem si pomagal z Android Virtual Device (AVD) Managerjem. Slika 17: Zaslonska maska - Ustvarjanje Android virtualne naprave Pri ustvarjanju imam na srečo veliko kontrolo, saj lahko izbiram med različnimi napravami, ki bi jih emuliral (obstaja tudi možnost dodajanja novih). Izbiram lahko tudi velikost RAM pomnilnika, kot tudi kateri procesor bom emuliral. Ker predvidevam da je x86 nabor lažje emulirati iz računalnika, ki bazira na enakem naboru, sem se odločil da izberem Intel Atom procesor. Prav tako sem obkljukal možnost»use Host GPU«, kar pomeni da bo namesto procesorja za emulacijo uporabljal grafični procesor in s tem pohitril proces zagona in delovanja same virtualne naprave. 19
S testno napravo lahko s pomočjo komande preko ukazne vrstice (CLI) vršim komando: cordova run, ob tem moram paziti, da se nahajam preko ukazne vrstice v mapi projekta HelloWorld. Ob tem ukazu Cordova vse datoteke iz www prenese v mapo platforms in jo tam vključno z lastnimi datotekami ter API-ji»compile-a«v datoteko, ki jo potisne kasneje na testno napravo. Ob zagonu me hkrati še obvesti o napakah pri Java Development Kit-u, češ da nimam pravilno nastavljene spremenljivke okolja. Po namestitvi JDK in ponovnem zagonu komande ter po nekaj trenutkih opazim uspešno generirano aplikacijo, ter zagon emulatorja. Slika 18: Zaslonska maska - Uspešno generiranje aplikacije in zagon Android emulatorja 20
Kakšno minuto kasneje opazimo tudi uspešen zagon naše»helloworld«aplikacije s pomočjo emulatorja in naše virtualne naprav, ki smo jo ustvarili v prejšnjem koraku. Slika 19: Zaslonska maska - Uspešen zagon mobilne aplikacije HelloWorld Za razliko od zagona v brskalniku in preko emulatorja opazimo, da je aplikacija zaznala, da je pognana preko mobilne naprave in ne brskalnika in prikazala sporočilo»device is ready«. Na tem primeru lahko točno vidimo, delovanje API-jev Cordove, ki ga bom opisal v naslednjem poglavju. 21
3.6. Delovanje Apache Cordova Torej če na hitro pogledamo izvorno kodo index.html datoteke, ki jo najdemo v našem projektu v mapi www bomo opazili nekaj posebnih vrstic Javascript kode, ki so namenjene Cordovi. </head> <body> <div class="app"> <h1>apache Cordova</h1> <div id="deviceready" class="blink"> <p class="event listening">connecting to Device</p> <p class="event received">device is Ready</p> </div> </div> <script type="text/javascript" src="cordova.js"></script> <script type="text/javascript" src="js/index.js"></script> <script type="text/javascript"> app.initialize(); </script> </body> </html> Programska koda 1: Datoteka index.html Opazimo, da najprej kličemo javaskriptno knjižico cordova.js, zatem index.js na koncu pa kličemo funkcijo app.initialize. Da dobimo večji vpogled, kaj se dogaja še odpremo datoteko index.js. var app = { initialize: function() { this.bindevents(); }, bindevents: function() { document.addeventlistener('deviceready', this.ondeviceready, false); }, ondeviceready: function() { app.receivedevent('deviceready'); }, receivedevent: function(id) { var parentelement = document.getelementbyid(id); var listeningelement = parentelement.queryselector('.listening'); var receivedelement = parentelement.queryselector('.received'); listeningelement.setattribute('style', 'display:none;'); receivedelement.setattribute('style', 'display:block;'); }; } console.log('received Event: ' + id); Programska koda 2: Datoteka index.js 22
Iz te datoteke je razvidno, da kličemo EventListener-je kot so deviceready, nato pa na podlagi teh kličemo funkcijo, ki spremeni prikaz iz»connecting to device«v»device is ready«. Ta deviceready pa izhaja iz cordova.js, ta pa zna z generirano končno datoteko komunicirati s samo napravo. In tako samo z uporabo programskega jezika JavaScript in komand iz Apache Cordova lahko komuniciramo z napravo, lahko preverjamo status povezave, dostopamo do datotek, fotoaparata, geo lokacije in tako dalje. 3.7. Programiranje aplikacije Kolibri v Apache Cordova Moje delo v obdobju praktičnega izobraževanja, je bilo dodelava že obstoječe mobilne aplikacije Kolibri, ki je spisana s pomočjo Apache Cordova z novimi funkcijami in posodobitev programske kode iz starejše različice Cordova na novejšo. Na kratko aplikacija Kolibri služi specifičnim delavcem TEŠ-a prikaz stanja in meritve vseh merilnih naprav na območju Šaleške kotline kar preko mobilne naprave. Naloge oz. zahtevke sem prejemal iz podjetja Artes preko njihovega portala, ki bazira na odprtokodni rešitvi Redmine. Slika 20: Logotip mobilne aplikacije Kolibri Ker je aplikacija delovala samo na starejših napravah Android na novejših pa ne, je bilo potrebno posodobiti Cordova na sistemu in kasneje tudi celotni projekt v mapi platforms z uporabo sledečih komand: npm update g cordova cordova platform update android 23
Slika 21: Zaslonska maska - Posodobitev projekta Kolibri Po posodobitvi projekta sem opazil kar nekaj napak in opuščenih klicov (»deprecated«), katere sem moral v kodi aplikacije Kolibri skladno z novejšo dokumentacijo prirediti. Slika 22: Zaslonska maska - Mobilna aplikacija Kolibri 24
Slednjo nalogo, ki sem jo prejel je bila modularizacija aplikacije. Potrebna je bila racionalna implementacija novih funkcionalnosti preko vmesnika, ki je enostaven za uporabo in ni v napoto na morebitnih manjših mobilnih napravah. Idejni seznam vsebinskih modulov: TEŠ Kolibri (že implementiran) Sinica servisni posegi na AMP Golob upravljanje seznama prejemnikov SMS Za začetek sem najprej izdelal meni. Za pomoč sem si pomagal z dokumentacijo jquery Mobile, ki je dostopna na spletu in sicer točneje z elementom Panel v kombinaciji z Listview elementom: http://demos.jquerymobile.com/1.4.3/panel-responsive/. <body> <div data-role="page" id="home" data-theme="d"> <div data-role="header" data-theme="b"> <a href="#left-panel" data-theme="b" dataicon="arrow-r" data-iconpos="notext" data-shadow="false" dataiconshadow="false" class="ui-icon-nodisc">odpri meni</a> <h1>kolibri</h1> </div> <div data-role="content"> <div id="maincontainer" data-role="content"> Nalaganje slike... </div> </div> <!-- panel --> <div data-role="panel" id="left-panel" datatheme="b"> <ul data-role='listview'> <li> <a href="#home">kolibri</a> </li> <li> <a href="#sinica">sinica</a> </li> <li> <a href="#golob">golob</a> </li> <li> <a onclick="navigator.app.exitapp();" data-rel="back">izhod iz aplikacije</a> </li> </ul> </div> <!-- /panel --> </div> <div data-role="page" id="sinica"> <div data-role="header" data-theme="b"> 25
<a href="#left-panel" data-theme="b" dataicon="arrow-r" data-iconpos="notext" data-shadow="false" dataiconshadow="false" class="ui-icon-nodisc">odpri meni</a> <h1>sinica</h1> </div> <div data-role="content"> <div id="serviscontainer" data-role="content"> <iframe src="http://urlsinice.com" style="width:100%;" id="sinicaframe"></iframe> </div> </div> <!-- panel --> <div data-role="panel" id="left-panel" datatheme="b"> <ul data-role='listview'> <li> <a href="#home">kolibri</a> </li> <li> <a href="#sinica">sinica</a> </li> <li> <a href="#golob">golob</a> </li> <li> <a href="#">scada</a> </li> <li> <a onclick="navigator.app.exitapp();" data-rel="back">izhod iz aplikacije</a> </li> </ul> </div> <!-- /panel --> </div> Programska koda 3: Uporaba jquery Mobile panelov v kombinaciji z Listview za izdelavo menija Iz kode (Programska koda 3) je viden del kode, katerega sem repliciral za vsako stran aplikacije posebej, saj je bilo treba za vsako stran posebej definirati meni. 26
Slika 23: Zaslonska maska - Uspešno implementiran meni Ob uspešni implementaciji menija (Slika 23) je bilo sedaj potrebno za vsako stran izdelati dodatni prikaz oz. funkcionalnost. Za prikaz strani Sinica sem uporabil iframe klic na spletno stran, ki je že izdelana in prirejena za mobilne naprave, se pravi že vsebuje odziven dizajn. <div data-role="page" id="sinica"> <div data-role="header" data-theme="b"> <a href="#left-panel" data-theme="b" dataicon="arrow-r" data-iconpos="notext" data-shadow="false" dataiconshadow="false" class="ui-icon-nodisc">odpri meni</a> <h1>sinica</h1> </div> <div data-role="content"> <div id="serviscontainer" data-role="content"> <iframe src="http://sinica-url.si" style="width:100%;" id="sinicaframe"></iframe> </div> </div> </div> Programska koda 4: Implementacija Sinice 27
Za konec je bilo potrebno še implementirati Golob. Ta spletna stran pa ni narejena za mobilne naprave vendar ima na voljo nekaj klicev, ki vračajo XML. Zatorej smo se po sestanku zmenili, da bom izdelal lokalno aplikacijo z pomočjo jquery tehnologij in klical ustrezne POST in GET zahtevke ter izločil iz XML ustrezne informacije in jih predstavil mobilnim napravam prijaznem GUI-ju. V nekaj preletih po jquery dokumentacijah o uporabi AJAX tehnologije in testih ter nastavitvah na strežniškem delu Artesa tako, da je bilo moč črpati informacije v omrežju TEŠ sem pričel z izdelavo te funkcije. Najprej sem si izdelal HTML GUI vmesnik, katerega bo javaskripta kasneje sama dinamično generirala. Ker je aplikacija izdelana s pomočjo jquery Mobile, sem si pomagal s sledečimi tehnologijami iz njihove dokumentacije: Collapsible set, Collapsible, Listview, Control Group in prišel do končnega izgleda (Slika 24). Sedaj je bilo potrebno zadevo ustrezno sprogramirati z uporabo jquery in AJAX-a tako da je mobilna aplikacija sama razbrala vse potrebne vrednosti iz zahtevka oz. XML-ja ter zapolnila seznam uporabnikov in njihovih nastavitev. Slika 24: Zaslonska maska - Prikaz grafičnega vmesnika Golob 28
V osnovi je skripta klicala oddaljen povezavo na RESTful API na enem izmed strežnikov TEŠa, za demonstracijski primer pa bom uporabil lokalne xml datoteke. Torej ob zagonu sem moral s pomočjo AJAX iz končne XML datoteke datoteko prebrati in jo prikazati uporabniku na mobilni napravi. Ker vse informacije, ki so bile potrebne niso bile na voljo v enem XML-ju oz. so bile odvisne sem se lotil zadeve na sledeč način. Najprej sem snel z AJAX-om datoteko z SMS naročninami, nato sem snel datoteko z uporabniki in šel skozi zanko tako, da sem za vsakega uporabnika prebral pomembne informacije, tabelo id-jev in statusov sms naročnin in jo povezal z nazivi sms naročnin iz prejšnje datoteke. Poleg vsega tega, sem še moral poskrbeti za pravilno sestavljanje nizov, tako da jih je jquery Mobile pravilno interpretiral, odpravil nekaj napak, ko je zaznavanje zaključka seznama in označevanje le-tega, saj v nasprotnem primeru izpade slabši izgled ob koncu seznama in tako dalje. Največ preglavic mi je tukaj delal pravzaprav odsotnost prikaza na spremembe. Po iskanjem rešitev po spletu, sem zasledil, da je potrebno po vsaki akciji AJAX-a klicati prožilce (trigger), ki z jquery Mobile osvežijo seznam po opravljeni AJAX akciji (Programska koda 5). Ker je bilo potrebno implementirati tudi možnost urejanja stanja uporabnikov in njihovih naročnin, sem moral spisati nekaj dodatnih funkcij, ki so uporabljale POST in DELETE zahtevke (Programska koda 6). Pri DELETE zahtevku, kateremu funkcije namen je onemogočiti naročnino, uporabo takšne vrste zahtevka ni dovoljeval strežnik, zatorej bi za uspešno delovanje bilo potrebno na takratnem strežniku to dovoljenje omogočiti in bi zadeva delovala. Poleg omenjenih implementacij sem naletel še na nemalo napak, ki jih je bilo potrebno tekom razvoja popraviti za omogočanje novih funkcij. Bodisi posodabljanje jquery knjižice na novejšo različico kot izpred dobre leta nazaj in z njo vso kodo, ki je bila odvisna, kot tudi popravljanja prikaza na različnih napravah oz. različicah mobilnega operacijskega sistema Android. 29
function NaloziOsebe(Mzaporedje) { $.ajax({ type : "GET", url : "users.xml", /*crossdomain: true,*/ datatype : "xml", cache : false, success : function(xml) { console.log('success' + xml); /*Pobriši morebitno vsebino*/ $('#golobcontent').empty(); //uporablja se za extend izbire po spremembi stanja izbranega uporabnika var zaporedje = 1; var ArrayNarocnin = []; //Najdi seznam naročnin $.ajax({ type : "GET", url : "profiles.xml", datatype : "xml", cache: false, async: false, success : function(xml3) { $(xml3).find('profile').each(function(index) { //Ajax request za seznam naročnin, na katere je že prijavljen var profilnarocnina = $(this).find('name').text(); var opisnarocnina = $(this).find('description').text(); var narocnina = {ime:profilnarocnina,opis:opisnarocnina,obstaja:false}; ArrayNarocnin.push(narocnina); }); } }); $(xml).find('golob-user').each(function(index) { var firstname = $(this).find('firstname:first').text(); var lastname = $(this).find('lastname:first').text(); var email = $(this).find('email:first').text(); var gsm = $(this).find('gsm:first').text(); var stanje = ($(this).find('disabled:first').text() == "false")? "Aktiven" : "Neaktiven"; var stanjeslika = ($(this).find('disabled:first').text() == "false")? "<img src=\"img/user-enable.png\" style=\"height:27px;float:left;display:inline;\"></img>" : "<img src=\"img/user-disable.png\" style=\"height:27px;float:left;display:inline;\"></img>"; var spremenistanje = ($(this).find('disabled:first').text() == "false")? "true" : "false"; 30
var ikonastanje = ($(this).find('disabled:first').text() == "false")? "check" : "delete"; var upime = $(this).find('username:first').text(); var smsnarocnine = ''; //Variable za seznam vseh naročnin z označenimi naročninami na katere je prijavljen var seznamnarocnin = ""; //ponastavi nastavitve ArrayNarocnin.forEach(function(objekt) { objekt.obstaja=false; }); //..Zberi vse aktivne naročnine uporabnika $(this).find('bag').children().each(function(index) { smsnarocnine += $(this).find('name').text() + " "; var trenutnaaktivnanarocnina = $(this).find('name').text(); //in jih primerjaj.. ArrayNarocnin.forEach(function(objekt) { if(trenutnaaktivnanarocnina==objekt.ime) { //.. ter označi objekt.obstaja=true; } }); }); //Sestavljanje stringa ArrayNarocnin.forEach(function(objekt) { if(objekt.obstaja) seznamnarocnin+='<label><input type="checkbox" name="checkbox-0" checked="checked" onclick="onemogocinarocnino(\''+upime+'\',\''+objekt.ime+'\')">'+objekt.opis+'</label>'; else seznamnarocnin+='<label><input type="checkbox" name="checkbox-0 " onclick="omogocinarocnino(\''+upime+'\',\''+objekt.ime+'\')">'+objekt.o pis+'</label>'; }); smsnarocnine; if (smsnarocnine == '') smsnarocnine = "Brez SMS naročnin."; else smsnarocnine = "SMS naročnine: " + //Dodaj osebo $('#golobcontent').append('<div datarole="collapsible" data-inset="false" data-collapsed-icon="arrow-r" 31
data-expanded-icon="arrow-d"><h2>' + stanjeslika + ' <span style="lineheight:29px;margin-left:8px;">' + firstname + ' ' + lastname + '</span></h2><ul data-role="listview" data-split-icon="' + ikonastanje + '"><li>uporabniško ime: ' + upime + '</li><li>email: ' + email + '</li><li>tel. št: ' + gsm + '</li><li><div datarole="collapsible" data-inset="false" data-collapsed-icon="arrow-r" data-expanded-icon="arrow-d"><h2>' + smsnarocnine + '</h2><fieldset data-role="controlgroup" data-iconpos="right">' + seznamnarocnin + '</fieldset></li><li><a href="#">stanje: ' + stanje + '</a><a href="#" onclick="spremenistanje(\'' + upime + '\',\'' + spremenistanje + '\', ' + zaporedje + ')"></a></li></ul></div>').collapsibleset().trigger("create"); zaporedje++; }); if (Mzaporedje!= 0) $('#golobcontent').children(':nth-child(' + Mzaporedje + ')').trigger('expand'); }, error : function(xhr, ajaxoptions, thrownerror) { console.log(xhr.status); console.log(thrownerror); settimeout(getfile, 5000); console.log("error : " + thrownerror); alert("napaka! Ne najdem omrežja"); } }); } Programska koda 5: Funkcija za prikaz uporabnikov v sklopu aplikacije Kolibri - Golob 32
function SpremeniStanje(up_ime, stanje, zaporedje) { $.ajax({ type : "POST", url : "http://url-povezava-testna.si/golob/user/" + up_ime + "?disable=" + stanje, /*crossdomain: true,*/ success : function(xml) { console.log('success'); NaloziOsebe(zaporedje); }, error : function(xhr, ajaxoptions, thrownerror) { console.log(xhr.status); console.log(thrownerror); settimeout(getfile, 5000); console.log("error : " + thrownerror); } }); } function OmogociNarocnino(up_ime, ime_narocnine) { $.ajax({ type : "POST", url : "http://url-povezava-testna.si/golob/user/" + up_ime + "/profile?name=" + ime_narocnine, /*crossdomain: true,*/ success : function(xml) { console.log('success'); //Ni potrebe - NaloziOsebe(zaporedje); }, error : function(xhr, ajaxoptions, thrownerror) { console.log(xhr.status); console.log(thrownerror); settimeout(getfile, 5000); console.log("error : " + thrownerror); } }); } function OnemogociNarocnino(up_ime, ime_narocnine) { $.ajax({ type : "DELETE", url : "http://url-povezava-testna.si/golob/user/" + up_ime + "/profile?name=" + ime_narocnine, /*crossdomain: true,*/ success : function(xml) { console.log('success'); //Ni potrebe - NaloziOsebe(zaporedje); }, error : function(xhr, ajaxoptions, thrownerror) { console.log(xhr.status); console.log(thrownerror); settimeout(getfile, 5000); console.log("error : " + thrownerror); } }); } Programska koda 6: Prikaz funkcij za spreminjanje stanja naročnin in uporabnikov 33
4. Povzetek Pri izdelavi mobilne aplikacije Kolibri sem naletel na kar nekaj težav že pri osnovnem nameščanju, zato sem tega tudi toliko opisoval, saj dokumentacija, ki je na spletu je zelo skopa in v 90% primerih nastanejo težave vsaj takšne kot sem jih jaz opisal, če še ne večje. Pri urejanju spremenljivk okolja sem imel težave saj spremembe niso bile vidne takoj in sem šele po nekaj poizkusih ugotovil, da moram zapreti CLI in ga ponovno odpreti, da so spremembe uveljavljene. Ker sem vse namestitve izvajal na delovnem računalniku, ki je povezan v TEŠ omrežje in nisem imel pravic za namestitev programske opreme sem velikokrat moral zaprositi za vnos administratorskih pravic za namestitev za vsako programsko opremo, ki je to zahtevala. V celotnem procesu nameščanja tudi 5-10x. Nameščanje pa je bilo samo začetek težav. Ker je tehnologija dokaj nova je na spletu izredno malo informacij, skupnost na stackoverflow in podobnih spletnih straneh pa znatno majhna. Zato sem imel kar nekaj pri samem testiranju aplikacije na testnih napravah, saj je bila ta npr. prestara (stara različica Android) in v dotičnem primeru ni podpirala prikaza SVG slik, ki jih je aplikacija potrebovala. Kasneje so nastale težave, saj je bilo potrebno posodobiti že izdelano aplikacijo na novejšo različico Cordova in je bilo kar nekaj vrstic kode prirediti da se sklada z novimi funkcijami, saj so bile starejše opuščene. Na koncu je bilo težko tudi razhroščevati preko testne naprave, saj ni bilo možno postavljati breakpointe ali ogledovati spremenljivk razen, če so bile prikazane v samem pogledu aplikacije ali preko konzolnih sporočil. Nekaj potencialnih rešitev je bilo na internetu za testirati, vendar preden sem prišel do njih, se je praksa iztekla proti koncu. Kakorkoli sem ob izdelavi oz. nadgradnji aplikacije dodatno spoznal knjižico jquery Mobile, spoznal tudi AJAX klice, osnovne Cordovine funkcije za upravljanje z mobilnimi napravami, IDE Eclipse in še marsikaj, česar nas na faksu niso naučili. 34
5. Zaključek Obvezno študentsko praktično usposabljanje je bila zame res edinstvena izkušnja. Kot že omenjeno sem se naučil v teh dveh mesecih precej, super pa je bil tudi občutek, da sem s svojim osnovnim znanjem, ki sem ga osvojil na faksu pripomogel k izboljšanju mobilne aplikacije, ki jo bodo zaposleni v Termoelektrarni Šoštanj uporabljali in jim bo rešitev pomagala pri njihovem delu. Ob tej priložnosti bi se rad zahvalil g. Juretu Lodrantu za ponujeno delo oz. projekt, ki me je izredno navdušil. Prav tako se zahvaljujem mentorju g. Marku Pečovniku za pomoč in vse informacije, ki sem jih potreboval, kot tudi g. Aleksandru Krücken, ki mi je pomagal skozi nadgradnjo mobilne aplikacije Kolibri in vsem sodelavcem za pomoč pri vsakodnevnih nalogah, ki so se pojavile v storitvenem centru. Najlepša hvala Termoelektrarni Šoštanj, ki mi je omogočila opravljati unikatno praktično izobraževanje. 35