Muiden sovellusten kopioiminen Power Appsilla on mainio tapa oppia. Olemme aiemmin toteuttaneet osia Viking Linen ja Finnairin mobiilisovelluksista Power Appsilla. Tällä kertaa tehdään riisuttu versio Sensibon mobiilisovelluksesta.
Lisätään kuitenkin vaikeuskerrointa. Käytetään ainoastaan
- Power Appsin vakiokontrolleja
- CSS muotoiluja (html-kontrollin avulla)
- Vektorigrafiikkaa (SVG-kuvia kuva-kontrollin avulla)
Ei käytetä kuvakaappauksia alkuperäisestä sovelluksesta.
Sensibo App
Sensibo -sovelluksella kontrolloidaan kodin ilmalämpöpumppuja. Aloitussivulla on lista lämpöpumpuista. Pumpun valitsemalla sitä pääsee ohjaamaan.


Meillä on yksi ilmalämpöpumppu, joten tehdään sovelluksesta samalla hieman yksinkertaisempi. Se käynnistyy suoraan pumpun ohjausnäkymään. Siivotaan samalla pois kaikki arkikäytössä tarpeettomat ominaisuudet.
Pyrimme siis toteuttamaan jotain tämännäköistä.

Aloitetaan!
Otsikkopalkki
Luodaan aluksi rakenne käyttöliittymän eri osille. Elementit tulevat yhden responsiivisen säilön (container) sisään (cntMain). Kukin osio toteutetaan omana säilönään.
Näytön taustaväriksi asetetaan harmahtava valkoinen (#FAFAFA).
Aloitetaan yläosan otsikkopalkista, jolle luodaan oma säilö (cntHeader).

Otsikkopalkki on vihreä (#20C1A2) laatikko, jossa on kevyt varjostus. Kuvakaappaus oikeasta sovelluksesta:

Toteutetaan tämä CSS:n avulla. Lisätään säilöön HtmlText-kontrolli, jonka sisältönä on seuraava koodi.
<div style='margin:0px;padding:0px; width:" & Parent.Width & "px;height:137px;background-color:#26BEA2;box-shadow:0 3px 10px 3px #ccc; border-radius:0px'></div>

Riittävän hyvä.
Mutta mistä saamme Sensibon logon (ja kaikki muut ikonit)? Kirjaudutaan selaimella home.sensibo.com/beta -palveluun, joka on käytännössä sama kuin mobiilisovellus. Selaimen kehittäjätyökaluilla (developer tools) saadaan kaivettua esiin sivustolla käytetyt kuvakkeet.

Kuvakkeet ovat SVG-formaatissa. Esimerkiksi näytön sulkemis-kuvake (close) näyttää tältä.
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="14">
<g fill="none" stroke="#FFF" stroke-linecap="round" stroke-width="2">
<path d="M1.547 1.62l5.15 5.308 5.152-5.309M1.547 12.502l5.151-5.308 5.151 5.308"/>
</g>
</svg>
Kuvana

SVG:tä voi käyttää Power Appsin kuva-kontrollissa, kunhan sen ensin muuttaa kuvaksi. Se tehdään näin.
data:image/svg+xml;utf8, "&EncodeUrl("%
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="14">
<g fill="none" stroke="#FFF" stroke-linecap="round" stroke-width="2">
<path d="M1.547 1.62l5.15 5.308 5.152-5.309M1.547 12.502l5.151-5.308 5.151 5.308"/>
</g>
</svg>
")
SVG-kuvien käytöstä on kaksi etua:
- Kuvat ovat vektorigrafiikkaa, eli ne ovat aina tarkkoja
- Kuvat ovat selkokielistä koodia, jota voidaan muokata Power Appsissa
Sensibon logo löytyy sivustolta SVG-muodossa ja näin lisäämme sen oikeaan kohtaan otsikkopalkkia.

Laitteen tilatiedot
Otsikon alla näytetään seuraavat tiedot
- Pumpun sijaintia kuvaava ikoni (SVG-kuvake)
- Laitteen nimi
- Huoneen lämpötila
- Laitteen käyttöasetus (Heat, Cool…)
- Puhallusteho (Low, Medium, High..)
- Pumpun pyyntilämpötila
- Huoneen ilmankosteus

Kuvakeen SVG-koodin saa poimittua selaimella. Suurin työ on löytää oikeat fonttikoot ja -tyypit. Identtiseen lopputulokseen ei päästä, sillä Power Appsista ei löydy vastaavaa fonttia.
Riittävän lähelle kuitenkin

Lisätään tietojen alle vielä viiva. Jälleen html- kontrollia ja CSS:ää hyödyntäen.

Lämpötila-asetus
Sitten päästäänkin harjoituksen työläimpään osuuteen. Rakennamme vektorigrafiikkaa käyttäen seuraavan kokonaisuuden.

Ympyrä lämpötilan lisäämiseen / poistamiseen
Aloitetaan pienestä ympyrästä, jolla muutetaan lämpötilaa.
Lyhyen googlettamisen ja kokeilujen jälkeen, päädytään seuraavaanlaiseen SVG-koodiin.
<svg viewBox='-3 -1 115 115' xmlns='http://www.w3.org/2000/svg' fill='white' stroke='#F3F3F3' stroke-width='1'>
<defs>
<filter id='shadow' color-interpolation-filters='sRGB'>
<feDropShadow dx='0' dy='5' stdDeviation='4' flood-opacity='0.2'/>
</filter>
</defs>
<circle cx='50' cy='50' r='50' filter='url(#shadow)'/>
</svg>
Riittävän hyvä.

Miinusmerkki on perinteinen teksti-kontrolli (label). Lisätään se ja tehdään toinen samanlainen painike lämpötilan nostamiselle.

Seuraavaksi luodaan punareunainen ympyrä, jonka sisällä esitetään nykyinen lämpötila-asetus sekä ”TURN OFF” -teksti.
Lyhyen kokeilun jälkeen päädytään seuraavaan.
<svg viewBox='-7 -15 115 115' xmlns='http://www.w3.org/2000/svg' fill='white' stroke='#EBDCE1' stroke-width='1'>
<defs>
<filter id='shadow' color-interpolation-filters='sRGB'>
<feDropShadow dx='0' dy='0' stdDeviation='1' flood-opacity='0.3'/>
</filter>
</defs>
<circle cx='50' cy='50' r='48' filter='url(#shadow)'/>
</svg>
Olisin halunnut varjostuksen punaisella, mutten vain osannut. Riittävän hyvä silti.

Tekstit
Lisätään ympyrän sisään tektikentät lämpötila-asetukselle, sekä virran pois kytkemiselle. Jälleen meni hetki löytää oikea fonttikoko.

Lämpötila-asetuksen visualisointi
Lopuksi teemme ympyrän ympärille kehän, jolla visualisoidaan nykyistä lämpötila-asetusta. Tietenkin vektorigrafiikkana.
Google auttaa jälleen ja löydämme toimivan pohjan.
<svg viewBox='11 -3 80 80' xmlns='http://www.w3.org/2000/svg'>
<path d='M20,60a35,35 0 1,1 60,0' stroke='#F5F5F5' stroke-width='6' fill='none' stroke-linecap='round'></path>
<path d='M20,60a35,35 0 1,1 60,0' stroke='rgb(69,204,206)' stroke-width='6' pathLength='100' fill='none' stroke-linecap='round' stroke-dasharray='60,100'></path>
</svg>
Koodi tuottaa seuraavan lopputuloksen.

Lisätään esikuvan mukainen liukuväri.
<svg viewBox='11 -3 80 80' xmlns='http://www.w3.org/2000/svg'>
<defs>
<linearGradient id='linear-gradient' x1='1.5' x2='0' y2='0.9' gradientUnits='objectBoundingBox'>
<stop offset='0' stop-color='#29BCA1'/>
<stop offset='1' stop-color='#C4E6E0'/>
</linearGradient>
</defs>
<path d='M20,60a35,35 0 1,1 60,0' stroke='#F5F5F5' stroke-width='6' fill='none' stroke-linecap='round'></path>
<path d='M20,60a35,35 0 1,1 60,0' stroke='url(#linear-gradient)' stroke-width='6' pathLength='100' fill='none' stroke-linecap='round' stroke-dasharray='60,100'></path>
</svg>
Nyt visualisointi näyttää tältä.

Lisätään vielä ympyrä kuvaamaan nykyistä arvoa.
<svg viewBox='11 -3 80 80' xmlns='http://www.w3.org/2000/svg'>
<defs>
<linearGradient id='linear-gradient' x1='1.5' x2='0' y2='0.9' gradientUnits='objectBoundingBox'>
<stop offset='0' stop-color='#29BCA1'/>
<stop offset='1' stop-color='#C4E6E0'/>
</linearGradient>
</defs>
<path d='M20,60a35,35 0 1,1 60,0' stroke='#F5F5F5' stroke-width='6' fill='none' stroke-linecap='round'></path>
<path d='M20,60a35,35 0 1,1 60,0' stroke='url(#linear-gradient)' stroke-width='6' pathLength='100' fill='none' stroke-linecap='round' stroke-dasharray='60,100'></path>
<circle bcx='0' cy='0' r='3 stroke-width='0.3' fill='#FFFFFF'>
<animateMotion keyPoints='0.6;1' keyTimes='0;1' calcMode='linear' path='M20,60a35,35 0 1,1 60,0'>
</animateMotion>
</circle>
</svg>
Lopputulos näyttää seuraavalta.

Asetellaan luotu kuva oikealle paikalleen.

Asetukset
Lämpötilan alta näkee laitteen muut asetukset. Teksti kertoo asetuksen (esim Mode) ja kuvake sen nykyisen tilan (aurinko = lämmitys).

Luodaan (näytön OnVisible -tapahtumassa) kokoelma, jossa on kaikki asetukset. Kustakin asetuksesta tallennetaan
- Mistä asetuksesta on kyse (Area) sekä käyttöliittymässä näytettävä lyhyt nimi (AreaShortName)
- Asetuksen nimi (Setting)
- Asetuksen käyttöliittymässä näytettävä nimi (DisplayName)
- Onko asetus aktiivinen (isCurrentValue)
- Asetusta kuvaava symboli (SVG)
- Asetusta kuvaava symboli valkoisena (SVGforSettings)
ClearCollect(
colDeviceSettings,
{
Area: "Mode",
AreaShortName: "Mode",
Setting: "Cool",
DisplayName: "Cool",
isCurrentValue: false,
SVG:"<svg xmlns='http://www.w3.org/2000/svg' height='24'...</svg",
SVGforSettings:"<svg xmlns='http://www.w3.org/2000/svg' height='24'...</svg"
},..)
Lisätään näytölle vaakasuuntainen galleria, jossa näytetään nykyisiä asetuksia (isCurrentValue) edustavat kokoelman rivit.
Filter(colDeviceSettings, isCurrentValue)
Viimeistellään galleria asettelemalla kuva (SVG) ja teksti (AreaShortName) kohdilleen.

Asetusten muuttaminen
Asetusten muokkaamisen pitäisi näyttää seuraavalta.

Asetetaan muuttujan (locShowModeSettings) arvoksi true, aina kun päänäytöltä klikataan asetusta.
UpdateContext({locShowModeSettings:true})

Lisätään sovellukseen uusi säilö (container), joka näkyy (visible) ainoastan mikäli muuttujan locShowModeSettings arvo on true. Säilön taustaväri on hieman läpikuultava tumman harmaa

Lisätään säilöön tekstikenttä, jossa näytetään valitun asetuksen otsikk, sekä kuvake säilön piilottamiseksi.

Lopuksi lisätään säilöön galleria, jossa näytetään asetuskokoelmasta rivit, joiden Area on sama kuin päänäytöltä valitun asetuksen.
Filter(colDeviceSettings, Area = galCurrentSettings.Selected.Area)

Galleria sisältää
- Asetuksen kuvakkeen (SVGforSettings)
- Asetuksen nimen (DisplayName)
- Painikkeen, joka korostaa nykyistä valintaa (läpinäkyvä, harmaat reunat)
Lisäämme päänäytölle vielä viivan asetusten alle ja olemme valmiit.
"<div style='margin:0px;padding:0px; width:"& Parent.Width &"px;height:1px;background-color:#;box-shadow:0 1px 1px 1px #ccc; border-radius:0px'></div>"

Valmista!
Yhteenveto
Mielestäni pääsimme kohtuullisen lähelle alkuperäistä sovellusta. Suurin ero tulee fonteista. Elementit ovat hieman eri kokoisia ja eri paikoilla, mutta lopetin hieromisen kun sain kaiken suurinpiirtein kohdilleen.


Seuraavassa jutussa laitamme tämän Power Appsin ohjaamaan oikeasti meidän ilmalämpöpumppua.