By: Isak Engvall
2014-04-04
Home hacking – utveckling och systemintegration i hemmet, Del 2
Det här är fortsättingen på ett tidigare blogginlägg om “Home hacking”. Senast beskrev jag hårdvaran som jag använder till min version av det intelligenta hemmet. Du kan läsa inlägget här: (Home hacking – utveckling och systemintegration i hemmet, Del 1). I den här andra och avslutande delen går vi igenom mjukvaran i systemet.
## Mjukvaran
(Python, PHP, Javascript/jQuery, HTML, CSS, XML)
**Registrera trådlösa enheter**
Innan man kan börja styra en strömbrytare med Tellstick NET måste den registreras i Tellsticks webb-gränssnitt (http://live.telldus.com/). Där väljer man fabrikat (i mitt fall Nexa) och modell, och sedan parkopplar man varje enhet genom att trycka på dess sync-knapp. Det är något knepigare med projektorduken. Den saknar sync-knapp och serienumret måste hårdkodas efter hur kretskortet är lött. Man skruvar loss bakstycket på kontrollen och tittar precis ovanför batterihållaren. Inringat i rött till vänster finns åtta lödpunkter. Om punkten är ihoplödd med kontakten ovanför innebär det en etta i serienumret. Om den är ihoplödd nere är det en nolla, och ingen ihoplödning alls motsvarar ett streck. Serienumret vi ser här till vänster är: ”-0-1-111?. Numret matar man in med hjälp av radioknappar i Tellsticks gränssnitt.
**Backend**
Eftersom valet av hårdvara på server-fronten landade på en Raspberry Pi och jag tycker om Python använder jag Tellsticks Python-implementation (https://developer.telldus.com/blog/new-python-example-for-telldus-live). Det finns även andra implementationer i olika språk så hitta det som passar din plattform bäst. När man fyllt i sina användaruppgifter i koden kan man via terminalen på Raspberryn styra de enheter man har registrerat. För att tända en lampa skriver man
`raspberrypi$ python telldus.py –on
och för att dimma en dimbar lampa kör man
`raspberrypi$ python telldus.py –dimlevel <0-255> –dim
Den valda lampan kommer att tändas/dimmas. För att ta reda på vilka serienummer man har registrerat kan man köra –list.
`raspberrypi$ python telldus.py –list`
Alla enheter skrivs då ut med namn och serienummer.
Projektorduken stöder kommandona –up, –down samt –stop.
Nu kan vi styra elen och projektorduken med Python genom terminal. För en homogen kodbas bestämde jag mig för att koda även Yamaha-föstärkarens kontroll i Python. Pythons requests.post(url, XMLdata, headers) används för att posta XML över HTTP. Förstärkaren stöder GET för att monitorera inställningar och PUT för att ändra inställningar. Om jag kör kommandot
`raspberrypi$ python yamaha.py –volumeup 75`
skickas två XML-strängar till förstärkaren. Först GET
“`
“`
vilket returnerar nuvarande volymnivå. Den används sedan för att adderas med den volymsiffran som jag ville höja med
“`
“`
Volymen kommer höjas med 7,5 dB när den andra strängen skickats. I samma skript har jag implementerat så förstärkaren kan sättas på, stängas av och byta HDMI-ingång. Dokumentationen över förstärkarens funktioner är spretig och kräver mycket googlande. Yamaha själva erbjuder inte mycket hjälp. Ett tips är att använda sig av Yamahas inbyggda webb-gränssnitt och köra det i Chrome. Då kan man monitorera nätverkstrafiken i inspect-konsollen och se vilka XML-strängar som skickas när man matar in olika kommandon.
Projektorn styrs via ett seriellt gränssnitt och till Raspberryn har jag därför en USB till RS-232-adapter. För att den ska kunna användas för datakommunikation måste den först monteras. Man finner enhetens namn under /Dev i Linux. För att kunna använda sig utav seriell kommunikation i Python måste man importera ’serial’-biblioteket. Sedan initierar man seriekommunikationen innan man kan skicka ett kommando.
“`
import serial
seriedata = serial.Serial(port=’/dev/
seriedata.write(
“`
Det finns bra dokumentation över vilka kommandon som Epson-projektorer stöder (ftp://download.epson-europe.com/pub/download/3737/epson373739eu.pdf).
Kommandot i Epsons fall kan vara ”PWR ON\n” för att sätta på projektorn. Kommandot måste skickas hexadecimalt så det måste översättas först till \x50\x57\x52\x20\x4F\x4E\x0D\x0A. De två sista tecknen är en radbrytning vilket är mycket viktigt för att kommandot ska köras.
Nu har vi tre olika pythonscript som klarar av olika kommandon. Målet är att kunna integrera systemen så ett alla enheter styrs på ett enhetligt sätt. Till det har jag använt PHP som backend-lösning för webb-gränssnittet. Målet för mig var att användaren ska kunna skicka ”projektor on” och ”förstärkare on” och sedan förvänta sig att backend tar hand om kommandot så man slipper jobba med långa XML-strängar och anpassa sig till vad bakomliggande system efterfrågar. PHP lösningen tar emot post-data från frontend och hanterar det olika beroende på vilka get-parametrat som är satta. Ett bash-kommando konkatineras ihop av get-parametrana som skickats från frontend och exekveras genom ”php exec()”.
“`
$exec = “python telldus.py –“.$_GET[‘action’]. ” ” . $_GET[‘device’];
exec($exec);
“`
Det är viktigt att användaren ”WEB-USER” i Linux har fått exekveringsrättigheter för Python och för scriptet för att det ska kunna köras.
**Frontend**
Frontend består av en lista med knappar som postar formulär. För att slippa ladda om sidan vid varje knapptryck används AJAX till alla anrop mot bakomliggande PHP-kod. För alla dimmrar används ”input type=range”. Då får man, i en HTML 5-kompatibel browser, en slider. När man trycker på knappen ”DIM” postas det aktuella värdet på slidern till backend och lampan dimmas till önskad nivå.
När man laddar in sidan anropas ”telldus.py –list” genom backend vilket returnerar samtliga registrerade komponenter. Med den datan byggs sedan sidan upp med hjälp av foreach i Javascript. Ett div-block per enhet skapas upp och motsvarande formulär initieras. Det innebär att frontend blir helt dynamisk och anpassar sig efter installerade enheter.
En mycket positiv effekt av ett frontend som man kan påverka själv är tydligheten på knapparna. Förstärkarens otydliga 1-8 inputs ser nu ut på den här formen istället:
## Schemaläggningar
Ett problem jag länge stört mig på är att olika apparater har väldigt stor variation i ljudnivå. Slår jag över från TV till WiiU måste jag kraftigt sänka volymen för att inte få en chock i Call of Duty. Detta problem löses enkelt med detta system då jag kan bygga in att volymen justeras till en lagom förutbestämd nivå beroende på vilken apparat jag väljer.
När allting fungerar kan man införa automatisering och schemaläggning. Kommandon kan placeras i kö och köras sekventiellt. En knapp som släcker alla lampor är väldigt bekväm när man går hemifrån eller ska gå och lägga sig. En knapp som förbereder vardagsrummet för filmvisning är obligatorisk. Den kan slå på projektorn, hissa ner projektorduken och sedan dimma ner lamporna. Eller varför inte en knapp som dimmar ner och sätter på romantisk musik?
## Vidareutvecklingar
Det finns givetvis tusen möjligheter till vidareutveckling. Sedan jag gjorde det här systemet har ”Tellstick duo” kommit ut på marknaden. Den klarar även att ta emot signaler från Nexa-sändare vilket ger ytterligare en dimension. En magnetkontakt på brevinkastet kan skicka ett mejl och tala om att posten kommit. En trådlös brandvarnare kan ringa ett förutbestämt nummer vid larm. Golvvärmen kan slås på om temperaturen i lägenheten understiger viss nivå osv. Man kan också tänka bredare och lägga till röst/ljud-styrning för vissa funktioner, eller vad sägs om en webbkamera i kylskåpet som kan visa om det finns mjölk hemma?
Målet med mitt system är att ta fram en surfplatteanpassad kontrollpanel som komplement till mobilgränssnittet. Där ska det finnas flera flikar som tillsammans ska underlätta vardagen och fullända det intelligenta hemmet. Under en flik finns all kontrollering av hemmet. Under en annan finns hushållets alla google-kalendrar synkade. En flik med inköpslista som synkas med mobilen vore väldigt praktiskt och en flik som presenterar SLs realtidsinformation för de närmaste hållplatserna och avgångarna vore guld. Har du fler idéer så låt mig gärna få veta det. Dela gärna med dig av egna erfarenheter och lösningar i kommentarsfältet.