Mekelweg 4, 2628 CD Delft The Netherlands http://www.tudelft.nl/ B.Sc. Thesis Ontwerpproces van een grafische gebruikersinterface voor home automation Erik Roeling & Robert Lodder Begeleider: Prof.dr.ir. A.J. van der Veen Technisch begeleider: Ir. A.C. de Graaf Faculty of Electrical Engineering, Mathematics and Computer Science Ontwerpproces van een grafische gebruikersinterface voor home automation De Controller Thesis Ten behoeve van het afstuderen voor het diploma Bachelor of Science in Electrical Engineering door Erik Roeling & Robert Lodder 1365959 & 1377914 Deze thesis is gemaakt in opdracht van: De vakgroep Circuits and Systems In de faculteit Electrical Engineering, Mathematics and Computer Science Delft University of Technology Delft University of Technology c 2010 Copyright All rights reserved. Voorwoord Deze thesis is geschreven in het kader van het Bachelor afstudeerproject van de opleiding Elektrotechniek aan de TU Delft. Voorafgaand aan het Bachelor afstudeerproject, is met nog vier anderen een businessplan geschreven voor het vak High Tech Startups. Hierin wordt het op de markt brengen van het home automation systeem iNow beschreven. Voor iNow bestond nog geen gebruikersinterface en voorafgaand aan het ontwerp hiervan, moest een implementatie gekozen worden. In deze thesis vindt u het onderzoek naar de verschillende mogelijke implementaties van de interface en een vergelijking hiertussen. Als laatste wordt er een webinterface geı̈mplementeerd. Lezers die vooral geı̈nteresseerd zijn in de mogelijke implementaties van een gebruikersinterface, kunnen die vinden in hoofdstuk 4. De afweging van deze verschillende implementaties kan gevonden worden in hoofdstuk 5. Het implementeren van de interface is te vinden in hoofdstuk 7. Graag willen we de volgende personen bedanken voor hun hulp bij dit project: - Alle-Jan van der Veen voor het mogelijk maken van dit project. - Alexander de Graaf voor zijn ondersteuning bij dit bachelor eindproject. - Maaike Kaasenbrood, Maarten Kastelein, René van der Meij en Vinay Niddha voor de gezellige werksfeer bij de uitvoering van dit project. Robert Lodder & Erik Roeling Delft, 10 juni 2010. iii iv Samenvatting In deze thesis vindt u het ondezoek naar de beste implementatie van een op afstand te benaderen grafische gebruikersinterface, die hardware kan aansturen. Om de juiste keuze te kunnen maken, moet er onderzoek gedaan worden naar de verschillende mogelijke implementaties. Dit onderzoek is gedaan op basis van een literatuurstudie. Op basis van dit onderzoek is er een afweging gemaakt aan de hand van criteria. Hieruit is gekomen dat de beste implementatie een embedded systeem is waarop embedded Linux draait. Op dit besturingsysteem worden Apache, MySQL en PHP geı̈nstalleerd om te zorgen voor de benadering op afstand. Vervolgens dient een in C# geschreven programma voor de communicatie met de hardware, dit programma communiceert ook met PHP. In de toekomst kan dit onderzoek gebruikt worden om een afweging te maken voor een andere grafische gebruikersinterfaces. Eisen De interface dient voor het volgende: • schakelen van eindpunten en groepen • instellen van tijdschema’s die, eventueel op basis van sensor informatie, eindpunten of groepen in of uitschakelen • het engergieverbruik per eindpunt of groep weer geven • meerdere eindpunten in een groep plaatsen Implementaties Bij het onderzoek is er gekeken naar een hardwarematige oplossing, hieruit bleek dat hardware onvoldoende scoort op de mogelijkheid om te updaten, ook is een hardware oplossing niet goed online te benaderen. Een hardwarematige oplossing scoort wel erg goed op veiligheid. Ook is gekeken naar een oplossing met C#, deze scoort onvoldoende op de mogelijkheid om het via het internet te benaderen, wel wordt er goed gescoord op de ondersteuning. Daarnaast is er gekeken naar Java. Java scoort onvoldoende op de mogelijkheid om het te embedden, wel scoort Java net als C# erg goed op de ondersteuning. Als laatste is er gekeken naar webbased oplossingen en dan expliciet naar .NET, Java Web Start en PHP. Deze scoorden allemaal erg goed op de mogelijkheid tot updaten. Echter scoorden ze slecht op de mogelijkheid om het te embedden. Combineren van implementaties Uiteindelijk is er gekeken naar de mogelijkheid om meerdere implementaties te combineren. Zodat de zwakke punten van de ene implementatie worden opgevangen door de andere. Er is gekozen om C#, die het beste scoorde, te combineren met een webbased taal. Omdat het relatief moeilijk was op .NET op een andere besturingssysteem dan windows te draaien is er gekozen voor PHP. Ook is er gekozen om het totale systeem op embedded Linux te draaien omdat dit betrouwbaar is en niet meer kost als de alternatieven. Nadat deze implementatie gekozen was, is deze implemenatie ook daadwerkelijk gebruikt om een interface te ontwerpen voor het iNow systeem. Er zijn een aantal functies geschreven v die de communicatie tussen de webinterface en de in C# geschreven controller verzorgen. Dit blijkt goed te werken, al is de snelheid nog niet hoog genoeg voor dagelijks gebruik. vi Inhoud Voorwoord iii Samenvatting v 1 Inleiding 1 2 Doel van de interface 3 3 Programma van Eisen 3.1 Eisen vanuit het beoogde gebruik . . . . . . . . . . . . . . . . . . . . . . 3.2 Eisen vanuit de ecologische situering van het systeem in de omgeving . . 3.3 Eisen met betrekking tot het te ontwerpen systeem zelf . . . . . . . . . 3.4 Eisen met betrekking tot het eventueel te ontwikkelen productiesysteem 3.5 Eisen met betrekking tot het te ontwikkelen liquidatiesysteem . . . . . . . . . . . 5 5 5 5 6 6 4 Verschillende implementaties 4.1 Hardwarematig . . . . . . . 4.2 C# . . . . . . . . . . . . . . 4.3 Java . . . . . . . . . . . . . 4.4 Webinterface . . . . . . . . 4.4.1 .NET . . . . . . . . 4.4.2 Java Web Start . . . 4.4.3 PHP . . . . . . . . . van de interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Afweging van de implementaties 5.1 Criteria voor gebruikersinterface 5.2 Hardwarematige implementatie . 5.3 C# . . . . . . . . . . . . . . . . . 5.4 Java . . . . . . . . . . . . . . . . 5.5 Webbased . . . . . . . . . . . . . 5.6 Conclusie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Combineren van verschillende implementaties 6.1 Beste kandidaat . . . . . . . . . . . . . . . . . . 6.1.1 .NET . . . . . . . . . . . . . . . . . . . 6.1.2 PHP . . . . . . . . . . . . . . . . . . . . 6.1.3 Conclusie . . . . . . . . . . . . . . . . . 6.2 Mogelijkheden tot combineren . . . . . . . . . . 6.2.1 Eigen webserver . . . . . . . . . . . . . 6.2.2 Embedded Linux . . . . . . . . . . . . . 6.2.3 Conclusie . . . . . . . . . . . . . . . . . vii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 8 8 9 9 10 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 13 14 15 16 16 17 . . . . . . . . 19 19 19 19 19 20 20 20 20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Het Systeem 7.1 Structuur van het systeem . . . 7.2 Functies van de webinterface en 7.2.1 De webinterface . . . . . 7.2.2 De controller . . . . . . . . . . 21 21 21 21 22 8 Conclusies en aanbevelingen 8.1 Conclusie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2 Aanbevelingen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 25 25 Literatuur 27 A Code van de webinterface A.1 Actions.php . . . . . . . A.2 C.php . . . . . . . . . . A.3 Class.Zigbee.php . . . . A.4 Config.php . . . . . . . A.5 Cron.php . . . . . . . . A.6 Index.php . . . . . . . . 29 29 29 29 32 33 34 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . de conrtoller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B Code van de controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 viii 1 Inleiding Domatic is een beginnend bedrijf dat het home automation systeem iNow op de markt gaat brengen. Dit systeem moet gemak en besparing bij mensen thuis brengen. Met behulp van het systeem kunnen apparaten thuis makkelijk geschakeld worden en kan het energieverbruik van alle aangesloten apparaten in de gaten worden gehouden. Door slim op basis van het energieverbruik te schakelen, kan energie, en daarmee op de energierekening, bespaard worden. Voor dit systeem is nog geen gebruikersinterface ontworpen. Voordat de interface ontworpen kan worden, moet gekozen worden voor een geschikte implementatie zodat aan alle eisen van de interface voldaan kan worden. Om de juiste keuze te kunnen maken, moet er onderzoek gedaan worden naar de verschillende mogelijke implementaties. In de toekomst kan dit onderzoek gebruikt worden om een afweging te maken voor nieuwe grafische gebruikersinterfaces. Het doel van deze thesis is het afwegen van verschillende implementaties van de gebruikersinterface en daarnaast het implementeren er van. De hoofdvraag van deze thesis is dan ook: Wat is de beste implementatie van een op afstand te benaderen grafische gebruikersinterface die hardware aanstuurt? Bij de afweging wordt gekeken naar hoe de verschillende implementaties op een goede en flexibele manier kunnen voldoen aan de gewenste mogelijkheden van de interface. Op basis van literatuuronderzoek worden de criteria opgesteld en worden er per mogelijke implementatie punten aan de criteria toegekend. Naar aanleiding van deze punten zal er een conclusie worden getrokken. Om het voor een brede doelgroep toegankelijk te houden, moet de prijs van het systeem laag genoeg liggen en moet de gebruikersinterface simpel, duidelijk en intuı̈tief werken. Daarentegen moet de interface wel uitgebreide mogelijkheden bieden, om het systeem zich te laten onderscheiden van de concurrenten. Verder moet de interface, voor latere uitbreidingen en verbeteringen, ook door de gebruiker zelf thuis te updaten zijn. Hier ligt dan ook de uitdaging, om al deze aspecten doelgericht te integreren in één enkele gebruikersinterface. De opbouw van deze thesis is als volgt. In hoofdstuk 2 wordt het doel van de interface en de daaruit voortvloeiende gewenste functionaliteiten beschreven. Aan de hand hiervan wordt in hoofdstuk 3 het programma van eisen opgesteld. Vervolgens worden in hoofdstuk 4 de verschillende implementaties besproken, waarbij onderscheid gemaakt wordt tussen hardwarematige en softwarematige implementaties. Daarna wordt in hoofdstuk 5 op basis van het programma van eisen een afweging gemaakt tussen de verschillende implementaties. In hoofdstuk 6 wordt er gekeken naar de mogelijkheid om implementaties te combinieren. Waarna er in hoofdstuk 7 het ontwerptraject van de interface wordt besproken. Ten slotte worden in hoofdstuk 8 de conclusies gepresenteerd en worden aanbevelingen gedaan voor toekomstige verbeteringen van de gebruikersinterface. 1 2 2 Doel van de interface Om het iNow systeem kunnen bedienen is het noodzakelijk om een gebruikersinterface te maken. Deze interface heeft een viertal functies: 1. Schakelen van eindpunten en groepen. 2. Instellen van tijdschema’s die, eventueel op basis van sensor informatie, eindpunten of groepen in of uitschakelen 3. Het ergergieverbruik per eindpunt of groep weergeven. 4. Meerdere eindpunten in een groep plaatsen. Naast dit doel zijn er ook nog een aantal voorwaarden aan het eindproduct verbonden: Zo moet het eindproduct door iedereen bediend kunnen worden. Dit wil zeggen dat er geen technische kennis noodzakelijk mag zijn. Het is immers een product dat het leven makkelijker dient te maken en dat in ieder huishouden toegepast kan worden. Daarnaast moet de interface intuı̈tief zijn, zodat men niet genoodzaakt is de handleiding te lezen voordat men om kan gaan met het product. Hierdoor kan eenvoudig gebruik gemaakt van alle gemakken die het product met zich mee brengt. Het komt er dus op neer dat er op een eenvoudige intuı̈tieve manier opdrachten aan de hardware gegeven moet kunnen worden. Om dit probleem op te kunnen lossen is er begonnen met het opstellen van een Programma van Eisen. Deze lijst met eisen is te vinden in het volgende hoofdstuk. 3 4 Programma van Eisen 3 Voor het nieuwe home automation systeem iNow is het van belang dat er een duidelijke en intuı̈tieve gebruikersinterface ontworpen wordt. Het systeem is gericht op consumenten die een systeem wensen dat het schakelen van apparaten gemakkelijker maakt. Om dit te voor elkaar te krijgen is het belangrijk om eisen aan de te ontwikkelen interface te stellen. Deze eisen zijn hieronder in categorieën weergegeven in het programma van eisen. 3.1 Eisen vanuit het beoogde gebruik [1.1] De gebruiker moet makkelijk een apparaat kunnen schakelen. [1.2] De gebruiker moet makkelijk een tijdschema in kunnen voeren. [1.3] Het systeem moet duidelijk en overzichtelijk sensorinformatie weergeven. [1.4] Het moet makkelijk zijn modules toe te voegen. [1.5] De modules moeten makkelijk aan groepen toegekend kunnen worden. 3.2 Eisen vanuit de ecologische situering van het systeem in de omgeving [2.1] Het systeem mag niet meer dan 30 Watt gebruiken in rusttoestand. [2.2] Het systeem moet het gemeten energieverbruik per module weer kunnen geven. 3.3 Eisen met betrekking tot het te ontwerpen systeem zelf Sectie 1: Gebruikskenmerken [3.1.1] De gebruikersinterface moet door de gebruiker zelf te updaten zijn. [3.1.2] De hardware waar het systeem op draait moet minimaal 5 jaar meegaan. [3.1.3] De leverancier moet tot minmaal 10 jaar na aankoop onderhoud kunnen leveren. [3.1.4] Het systeem moet niet door anderen benaderd kunnen worden. Sectie 2: Productiekenmerken [3.2.1] Het systeem moet direct in gebruik genomen kunnen worden door de gebruiker. 5 Sectie 3: Liquidatiekenmerken [3.3.1] De hardware moet demonteerbaar zijn. [3.3.2] Alle gegevens moeten gewist kunnen worden. [3.3.3] De behuizing moet gerecycled kunnen worden. 3.4 Eisen met betrekking tot het eventueel te ontwikkelen productiesysteem [4.1] De gebruikersinterface moet op standaard embedded hardware kunnen draaien. 3.5 Eisen met betrekking tot het te ontwikkelen liquidatiesysteem [5.1] De hardware moet comform de regels voor klein huishoudelijke elektronica kunnen worden verwerkt. 6 Verschillende implementaties van de interface 4.1 4 Hardwarematig Een van de mogelijke implementatievormen is een implementatie in hardware. De kosten voor speciaal geproduceerde geı̈ntegreerde circuits zijn bij kleine aantallen relatief hoog.[1] Het is hierdoor niet geschikt voor de implementatie van de gebruikersinterface, daarom is deze optie niet meegenomen. Een andere veelgebruikte vorm voor een hardwarematige implementatie, FPGA’s, is wel toepasbaar als implementatie voor de interface en wordt daarom besproken als optie. Een FPGA is een geı̈ntegreerd circuit dat bestaat uit programmeerbare logische eenheden, waarmee logische funcies geprogrammeerd kunnen worden. Door het op een bepaalde manier programmeren van de logische functies kan de gewenste functionaliteit verkregen worden.[2] Deze taal heeft een aantal sterke punten maar ook een aantal zwakke punten. Deze zullen nu worden besproken. Sterke punten FPGA’s kunnen toegespitst worden op de taak die ze moeten uitvoeren, waardoor alle rekencapaciteit daarvoor gebruikt kan worden. [3] Bij processoren is dat niet het geval, omdat die veelzijdig moeten zijn om veel verschillende taken uit te kunnen voeren. Daarnaast kunnen FPGA’s een hoge parallelle verwerkingsgraad halen, wat een snellere verwerking oplevert.[4] Ook dit is bij processoren anders, die hebben een veelal seriële verwerking. Door deze eigenschappen kunnen met een FPGA hoge prestaties gehaald worden, wat voor efficiëntere en minder dure hardware kan zorgen. Het toepassen van een FPGA kan goedkoop. Voor de benodigde hardware is niet veel meer nodig dan een printplaat met daarop een FPGA, een geheugenchip en wat regelelectronica daaromheen. Bovendien zijn de energievereisten laag, zodat de benodigde voeding klein en goedkoop gehouden kan worden. Vergeleken met een simpele computer waar een softwareimplementatie op kan draaien, kan de prijs een aantal maal lager komen te liggen. Dit zorgt er ook voor dat het eventueel vervangen van defecte hardware minder financiële consequenties heeft. Zwakke punten Een hardware ontwerp is vaak gericht op een bepaalde, specifieke taak. Voor een ontwerp op een abstracter niveau, kan het gebruik van een FPGA moeilijker zijn. Voor bijvoorbeeld een dynamisch ontwerp dat sterk van een database afhangt, kan een FPGA minder geschikt zijn. Dit omdat een hardware ontwerp maar in beperkte mate flexibel kan zijn in een sterk data afhankelijk ontwerp. Hoewel een FPGA meerdere malen geprogrammeerd kan worden, is daarvoor bepaalde hardware, software en kennis voor nodig. Een gebruiker die het product met het uiteindelijke ontwerp heeft gekocht, heeft daar over het algemeen geen toegang toe. Dit zorgt ervoor dat de gebruiker niet zelf een update kan toepassen op het product. Hierdoor zou het ontwerp dus volledig af moeten zijn en kan er later geen nieuwe functionaliteit worden toegevoegd. Dit 7 maakt nieuwere versies incompatible met een oudere versie. Eventueel kan een medewerker met de benodigde hardware en software naar de gebruiker toe kunnen gaan om een nieuwe versie te programmeren, maar dat is een zeer kostbare aangelegenheid. Zeker in een productsoort waarvan verwacht kan worden dat er later nieuwe en extra mogelijkheden zullen komen, kan dit een zwaarwegend nadeel zijn. 4.2 C# C en C++ zijn de meest gebruikte talen als het gaat om de ontwikkeling van nieuwe software. Het grote voordeel van C# is dat het de voordelen van C en C++ combineert en de nadelen achterwege laat. Een van de mogelijkheden van de implementatie is dan ook een implementatie in C#. C# is net als C++ object georiënteerd.[5] Deze taal heeft een aantal sterke punten maar ook een aantal zwakke punten. Deze zullen nu worden besproken. Sterke punten De ondersteuning van C# is erg goed, in de MSDN1 library worden alle functies netjes uitgelegd en door de bekendheid is het nooit moeilijk om iemand te vinden die hulp kan bieden. Ook is C# een stabiele programmeertaal, hierdoor veranderen functies niet zomaar en blijft een programma dus door de jaren heen werken. Daarnaast bestaan er compilers voor bijna alle processoren, hierdoor is het mogelijk C# op vrijwel alle hardware te draaien. Net als C ligt C# dicht bij de hardware, hierdoor is het eenvoudig om hardware aan te sturen. Dit is erg handig als je te maken hebt met een ontwerp dat zowel hardware als software omvat. Omdat C# dicht bij de hardware ligt is het mogelijk om C# te synthetiseren. Dit voorkomt dat je de code moet schrijven in een taal die nog dichter bij de hardware ligt, bijvoorbeeld VHDL. Hierdoor is het mogelijk om snel een nieuw product te ontwikkelen. Hoewel nog niet de volledige functionaliteit van C/C++ gebruikt kan worden bij het synthetiseren, is het al goed mogelijk om het programma in hardware om te zetten mits er rekening gehouden wordt met de limitaties van het synthetiseren.[6][7] Door de mogelijkheid tot synthetiseren kan men grote snelheden behalen. Door gebruik te maken van Co-Synthetisatie kan er zelfs gebruik worden gemaakt van de flexibiliteit van software met de snelheid van hardware. Hierdoor is het vrijwel altijd mogelijk om aan de snelheidsvereisten te voldoen.[8] Zwakke punten Een mogelijk nadeel kan zijn dat C# voor verschillende processor architecturen apart gecompileerd moet worden waardoor het niet mogelijk is een versie voor iedereen uit te brengen. Er moeten dan ook nieuwe versies worden uitgebracht als er nieuwe processorarchitecturen op de markt worden gebracht. Dit is niet onmogelijk maar wel een kostbare aangelegenheid. 4.3 Java Een andere mogelijke softwarematige implementatie van de gebruikersinterface is om gebruik te maken van de programmeertaal Java. Dit is een relatief nieuwe programmeertaal en 1 Microsoft Developer Network 8 is object georiënteerd. Java heeft een aantal voordelen ten opzichte van andere programmeertalen, waardoor Java mogelijk een goede keus is voor de implementatie van de interface.[9] Sterke punten Een sterk punt van Java is dat het platform onafhankelijk is. In Java geschreven code wordt gecompileerd naar Java bytecode. Deze bytecode kan op elk besturingssysteem uitgevoerd worden waar een Java Virtual Machine voor beschikbaar is. Een Java Virtual Machine is een virtuele computer die de Java bytecode kan uitvoeren, door deze naar de specifieke benodigde machinetaal te vertalen. De Java Virtual Machine is dus de koppeling tussen de niet specifieke Java code en het speciefieke gebruikte besturingssysteem. Java heeft een automatisch geheugenmanagement. Geheugen wordt toebedeeld als er een nieuw object wordt aangemaakt. Als er geen verwijzingen naar een geheugenadres meer zijn, dan kan de inhoud niet meer benaderd worden en is het onbruikbaar geworden. Door een automatisch proces, de garbage collector, wordt het niet meer bruikbare geheugen vrijgegeven, zodat het geheugen weer voor andere data gebruikt kan worden. Op deze manier hoeft de programmeur zich niet bezig te houden met het geheugenbeheer, zoals dit in bijvoorbeeld C en C++ wel gedaan moet worden door de programmeur met behulp van pointers. Indien de programmeur dit wel zelf moet doen, kan er snel een foutje insluipen, wat kan leiden tot bugs en een niet correcte werking van het programma. Door het automatische geheugenbeheer van Java is de kans op deze fouten zeer klein, wat dus tijd scheelt in het debuggen. Bij de ontwikkeling van Java is speciaal aandacht besteed aan veiligheid in een netwerkomgeving. Zo kan bijvoorbeeld mogelijk onveilige code in een zogenaamde ”sandbox” uitgevoerd worden. De code kan hierbinnen draaien, zonder dat het andere Java code kan beı̈nvloeden.[10] Door de beveiligingsmogelijkheden kan Java gebruikt worden op internet, zonder dat kwaadaardige code het systeem kan binnendringen. Zwakke punten Doordat Java draait op een Java Virual Machine is het trager dan een vergelijkbaar programma geschreven in een taal die wel gecompileerd wordt tot machine taal. Dit komt door de extra vertaalslag die pas wordt gemaakt bij het draaien van het programma. Dit kost niet alleen snelheid, maar ook geheugen. 4.4 Webinterface Er zijn verschillende mogelijkheden om een webinterface te maken. Hieronder zullen .NET, Java Web Start en PHP worden besproken. Er is gekozen voor deze drie mogelijkheden omdat .NET goed te combineren is met C# en Java Web Start de webinterface is voor Java. Voor PHP is gekozen omdat dit een losstaande taal is die met bijna alles te combineren is. 4.4.1 .NET .NET is een framework van Microsoft, speciaal ontwikkeld om veelvoorkomende programmeerproblemen op te kunnen lossen. Het framework ondersteunt meerdere programmeertalen waaronder C#. Ook aan .NET zijn een aantal voordelen en nadelen verbonden. Deze zullen 9 hier worden besproken. Sterke punten Door gebruikt te maken van .NET is het relatief eenvoudig om een webinterface te schijven voor C# code. Hierdoor wordt het eenvoudig om vanaf een centrale locatie gebruik te maken van het product. Doordat .NET ook op is opgenomen in de MSDN libary is er van elke functie te vinden hoe die gebruikt moet worden. Ook is .NET ondanks zijn relatief korte bestaan al een taal die door veel mensen wordt gebruikt. Zodoende is het nooit moeilijk om iemand te vinden die hulp kan bieden. Zwakke punten Een groot nadeel van .NET is dat het alleen bedoeld voor het besturingssysteem Windows. Desalniettemin zijn er opensource-alternatieven die het mogelijk maken op linux te werken met .NET, dit is mogelijk doordat het net als Java niet direct naar marchinecode wordt gecompileerd maar tot een tussencode. Deze code wordt vervolgens door een runtime engine (CLR2 ) uitgevoerd. Hierdoor vergt het vrij veel van de hardware en is het relatief traag.[11] 4.4.2 Java Web Start Java Web Start is voor Java wat .NET is voor C# en is dus speciaal ontwikkeld om een webinterface voor Java te maken. Zodoende is het makkelijk om hiermee een webinterface te maken. Sterke punten Het grote voordeel van Java Web Start is dat het op meerdere besturingssystemen kan draaien. Dit omdat het zelf ook een Java-programma is en dus op de Java Virtual Marchine draait. Zwakke punten Een nadeel is dat Java Web Start alles lokaal draait in plaats van op de server. Bij het opstarten wordt de laatste versie op de computer geı̈nstalleerd. Hierdoor moet de computer Java ondersteunen om hier gebruik van te kunnen maken. Het is wel zo dat het eenvoudig is om Java te installeren op de computer omdat er bij het starten wordt gevraagd of men Java wil installeren tenzij dit al op de computer geı̈nstalleerd is.[12] 4.4.3 PHP PHP is een taal speciaal om websites dynamisch te kunnen maken. PHP staat voor PHP: Hypertext Preprocessor. Oorspronkelijk stond het voor Personal Home Page Tools, maar de PHP community heeft een betere naam voorgedragen die later is aangenomen. PHP is toe aan zijn vijfde versie.[13] Meestal wordt PHP in combinatie met Linux, Apache en MySQL gebruikt (LAMP3 ). Apache is hierbij de webserver en MySQL een database. Sterke punten 2 3 Common Language Runtime Linux, Apache, MySQL en PHP 10 PHP is in staat commando’s op de server uit te voeren en draait op de meeste besturingssystemen. Daarnaast is PHP net als Java Web Start gratis te gebruiken. Bij normaal gebruik is PHP niet bijzonder snel, maar het is mogelijk de PHP-code te compileren, hierdoor wordt het een stuk sneller. Verder is het mogelijk om Object georiënteerd te programmeren. PHP komt bijzonder goed tot zijn recht in combinatie met een database als MySQL. Doordat PHP gebaseerd is op Perl en C is het relatief eenvoudig om PHP te leren. Verder is de ondersteuning erg goed, op de website (www.php.net) worden alle functies netjes uitgelegd. Ook wordt PHP gebruikt door een grote groep mensen en is het dus nooit moeilijk iemand te vinden die hulp kan bieden.[14] Zwakke punten PHP is minder sterk in het sturen van hardware op de server, dit gezien het gemaakt is om niet langer achter elkaar draaien dan een aantal seconden. Dit is voldoende om een pagina te genereren, maar niet om een stuk hardware te monitoren op veranderingen. 11 12 5 Afweging van de implementaties Nu het literatuuronderzoek gedaan is, is het tijd om te kijken wat nu de beste implementatie gaat bieden voor de interface. Hiervoor moet er eerst een lijst worden opgesteld met criteria waaraan de interface zou moeten voldoen. Deze worden besproken in paragraaf 5.1. In de volgende paragraven worden de verschillende implementaties, die in hoofdstuk 4 besproken zijn, onderworpen aan de criteria. De uitkomst staat in tabel 5.1. 5.1 Criteria voor gebruikersinterface Hieronder staan de criteria waarop de implementaties worden beoordeeld. Er wordt een cijfer toegekend op een schaal van één tot tien, waarbij een één totaal niet toereikend is en een tien perfect is. Met behulp van een weegfactor, die aan elk criterium wordt toegekend, wordt er gezorgd dat de belangrijke criteria zwaarder meetellen. Het systeem moet door de gebruiker te updaten zijn Deze eis is van belang omdat er na het uitbrengen van het initiële systeem nieuwe modules ontwikkeld zullen worden. Het is niet onwaarschijnlijk dat er een update nodig zal zijn om van deze modules gebruik te kunnen maken. Als het product hiervoor vervangen zou moeten worden dan is het voor de consument niet aantrekkelijk de nieuwe module aan te schaffen. Verder is het mogelijk om met deze update eventuele (veiligheids)fouten die pas later aan het licht komen te verbeteren. Deze eis is van groot belang, aangezien dit de toekomst van het product betreft, er is dan ook een weegfactor 3 toegekend. Het systeem moet veilig zijn Deze eis is van belang omdat het een systeem betreft wat het mogelijk maakt het gehele huis te bedienen. Het is daarom van groot belang dat niemand het systeem kan kraken. Hierdoor is veiligheid een van de belangrijkste aspecten van het systeem. Zeker als het later mogelijk moet worden een alarmsysteem aan de interface te hangen. Dit alles in ogenschouw genomen is er een weegfactor 3 toegekend. Het systeem moet draaien op een embedded systeem Deze eis is van belang omdat de interface uiteindelijk moet draaien op een kastje ter grote van een ethernet hub. Een computer is te duur in aanschaf en neemt te veel ruimte in beslag. Verder is een embedded systeem meestal energiezuiniger dan een gewone computer. Omdat dit vooral een kostenaspect is; is er een weegfactor 2 toegekend. Het systeem moet via het internet te benaderen zijn Deze eis is van belang omdat de gebruiker ook op de bank in huis zijn lichten aan en uit moet kunnen zetten. Door te zorgen dat de gebruiker via zijn eigen mobiele telefoon het systeem kan bedienen hoeven er geen afstandsbedieningen en dergelijke geproduceerd te worden. Ook 13 nemen op deze manier de kosten voor de consument af. Omdat deze eis alleen extra gebruiksgemak geeft en geen direct negatief gevolg heeft voor het product is er een weegfactor 1 toegekend. Er moet een goede ondersteuning voor de gekozen taal zijn Deze eis is van belang omdat het de productie goedkoper maakt. Als de ondersteuning van een taal van hoog niveau is dan is het niet altijd noodzakelijk dure specialisten in te huren om het product te ontwikkelen. Omdat het product zo goedkoop mogelijk moet worden is het van belang dat de productie ook zo goedkoop mogelijk is, het is daarom een voordeel als je de ontwikkeling in eigen handen kan houden. Omdat deze eis geen invloed heeft op het eindproduct is er een weegfactor 1 toegekend. Tabel 5.1: Beoordeling van de verschillende criteria Updaten Veiligheid Embedded Mobiel Ondersteuning Totaal 5.2 (3x) (3x) (2x) (1x) (1x) Hardware 3 8 10 4 7 5,6 C# 6 7 8 4 8 6,7 Java 6 7 5 6 8 6,3 Webbased 8 6 4 9 7 6,6 Hardwarematige implementatie Het systeem moet door de gebruiker te updaten zijn Wat updaten betreft is hardware niet goed, in de meeste gevallen zal het erop neerkomen dat de hardware vervangen moet worden. Dit zorgt ervoor dat hardware een 3 krijgt voor de mogelijkheid tot updaten. Het systeem moet veilig zijn Wat veiligheid betreft is hardware uitstekend, doordat hardware zelf niet te veranderen is, is het vrij moeilijk tot onmogelijk ongewilde acties uit te laten voerenu. Verder moet men al snel fysieke toegang hebben tot het apparaat, hierdoor is het goed te beveiligen. Er is dan ook een cijfer 8 toegekend aan de veiligheid. Het systeem moet draaien op een embedded systeem Hardware is embedded, dus veel beter dan dit zul je het niet vinden. Het is dan ook vrij simpel en de hardware implementatie krijgt hiervoor een 10. Het systeem moet via het internet te benaderen zijn Dit is eventueel mogelijk, maar zal niet eenvoudig zijn. Doordat alles op een FPGA moet kunnen draaien is het vrijwel ondoenlijk hiervoor een geavanceerde website te maken. Wel is het mogelijk op een kleine website te draaien waar alleen de actuele status te vinden is. Deze data kan vervolgens gebruikt worden om het geheel ergens mooi opgemaakt weer te geven. Ook is het mogelijk de FPGA via een website aan te sturen. Omdat dit het allemaal niet gemakkelijk is kan er niet meer dan een 4 worden toegekend. 14 Er moet een goede ondersteuning voor de gekozen taal zijn De ondersteuning van hardware is niet goed te noemen, er zijn niet heel veel mensen die op deze manier een interface maken, daarom zul je vaak zelf dingen moeten uitvinden. Verder is VHDL een taal voor de specialisten en hiervan zijn er niet heel veel. Wel zijn er goede boeken waarin VHDL duidelijk wordt uitgelegd. Hierdoor is het cijfer 6 toegekend. Conclusie Door de weging toe te passen, is het cijfer 5,6 verkregen, het is een voldoende maar ook maar net. Het is jammer dat hardware slecht te updaten is, daarnaast is het moeilijk te zorgen dat hardware via het internet te bereiken is. 5.3 C# Het systeem moet door de gebruiker te updaten zijn Wat updaten betreft is C# niet bijzonder sterk maar ook niet zwak te noemen. Doordat het wel gecompileerd moet worden voor de hardware van de eindgebruiker is het net een stukje moeilijker. Echter is dit zonder al te veel moeite te doen, eventueel via het internet. Het is echter niet mogelijk om hardware die op basis van C# is gemaakt te updaten zonder deze te hoeven vervangen. Doordat het updaten iets meer moeite kost is er een 6 toegekend voor het updaten. Het systeem moet veilig zijn Wat betreft de veiligheid is C# best goed. Je kunt niet zomaar de code aanpassen. Een minder onderdeel aan de veiligheid is de vereiste om het uitvoeren zelf te beveiligen en de data-overdacht veilig te doen. Hiervoor zijn geen standaard tools en deze moeten dus zelf geschreven worden. Zodoende is C# net zo veilig als je het zelf maakt. Hierom krijgt C# een 7 voor de veiligheid. Het systeem moet draaien op een embedded systeem Wat embedded betreft is C# best aardig. Het is een lage programmeertaal en ligt dus dicht bij de hardware. Er zijn ook de nodige tools om C# code te synthetiseren, echter werken deze tools niet heel erg goed, zodoende moet er goed nagedacht worden over hoe men de code schrijft. Als dit is gedaan dan is C# goed te synthetiseren. Hierdoor heeft C# voor embedded een 8 gekregen. Het systeem moet via het internet te benaderen zijn Mobiel is C# niet erg goed, wil je C# mobiel krijgen dan zul je zelf opnieuw het wiel uit moeten vinden. Er zijn geen standaard programma’s die C# internet capaciteiten kunnen geven. Omdat dit toch wel een groot nadeel is krijgt C# hiervoor een 4. Er moet een goede ondersteuning voor de gekozen taal zijn De ondersteuning van C# is erg goed. Doordat C# is opgenomen in de MSDN library kan elke functie plus een toepassing worden terug gevonden. Ook is het een bekende programmeertaal, dus is het goed mogelijk mensen om hulp te vragen, al met al reden genoeg om C# hiervoor een 8 te geven. 15 Conclusie Als we de weging toepassen op het voorgaande komen we op een 6,7 voor C#. Hiermee heeft C# dus een nette voldoende weten te halen. Het is vooral erg jammer dat C# niet goed via het internet bereikbaar gemaakt kan worden. 5.4 Java Het systeem moet door de gebruiker te updaten zijn Java scoort op het gebied van updaten gemiddeld. Hoewel een Java programma niet voor elke architectuur apart gecompileerd te worden, is het updaten van een bestaand programma niet makkelijk te doen. Het gehele originele bestand zal dus waarschijnlijk vervangen worden door een nieuwe versie. Daarom krijgt Java een 6 voor het updaten. Het systeem moet veilig zijn Op het gebied van veiligheid is Java best goed. Er zijn speciale veiligheidsmogelijkheden en het kan via internet worden gebruikt. Er worden voor Java geregeld updates uitgebracht. Naast nieuwe functionaliteit, wordt ook de veiligheid verbeterd. Als gebruikers Java niet updaten en een oudere versie blijven draaien, lopen ze wel veiligheidsrisico’s. Voor de veiligheid krijgt Java een 7. Het systeem moet draaien op een embedded systeem De Java Virtual Machine is in eerste instantie bedoeld voor computers. Er zijn wel versies voor embedded producten zoals mobiele telefoons, maar deze zijn dan vaak traag en missen functionaliteit. Het embedded draaien van een interface kan daardoor resulteren in een trage en niet responsieve interface. Hoewel het mogelijk is, krijgt Java daarom voor embedded een 5. Het systeem moet via het internet te benaderen zijn Veel mobiele telfoons ondersteunen Java, maar daarmee kan er geen hardware op afstand worden bediend. Om dit wel voor elkaar te krijgen zal er een soort van webserver ontworpen moeten worden. Omdat dit niet eenvoudig is krijgt Java voor de mobiele toegang een 6. Er moet een goede ondersteuning voor de gekozen taal zijn Java is een zeer veel gebruikte programmeertaal, en mede daardoor is de ondersteuning erg goed. Ook is er altijd iemand in de buurt te vinden die hulp kan bieden. Voor de ondersteuning krijgt Java een 8. Conclusie Na de toegekende cijfers vermenigvuldigd te hebben met de weegfactor en te delen door tien, is het resultaat voor Java een 6,3. Een ruime voldoende dus voor Java. 5.5 Webbased Het systeem moet door de gebruiker te updaten zijn Het update van een webbased systeem gaat meestal erg goed. Gezien dat het al via het 16 internet te bereiken is, is het alleen nog maar nodig op de nieuwe versie over te zenden. Gezien dit niet echt een probleem is krijgt webbased hiervoor een 8. Het systeem moet veilig zijn De veiligheid van een webbased systeem is vrijwel altijd minder. Dit is omdat het te bereiken is via het internet, hierdoor kan iedereen potentieel op het systeem komen. Het is dan ook van groot belang dat er niet te licht wordt gedacht over de veiligheid. Met de juiste certificaten en protocollen is het echter goed mogelijk een webbased systeem veilig te krijgen. Hierdoor krijgt webbased een 6 voor veiligheid. Het systeem moet draaien op een embedded systeem Een webbased systeem is minder op het embedded vlak. Een webbased systeem is een hoge programmeertaal en communiceert moeilijk met hardware. Voor zover bekend is het niet mogelijk een webbased systeem te synthetiseren, hierdoor moet het dus altijd op een processor draaien, dit kan een embedded systeem zijn. Al met al is het embedden van een webbased taal niet eenvoudig, hierdoor is er een 4 gegeven voor Embedded aan de webbased optie. Het systeem moet via het internet te benaderen zijn Mobiel is een webbased taal natuurlijk de beste. Het is bedoeld om op een correcte manier online te benaderen te zijn. Wat dit punt betreft is het duidelijk en webbased krijgt hiervoor een 9. Er is geen 10 toegekend omdat het niet altijd even toegankelijk is door alle browsers. Er moet een goede ondersteuning voor de gekozen taal zijn De ondersteuning is erg afhankelijk van de gekozen manier van webbased programmeren. Desalniettemin is deze over het algemeen vrij goed, zeker als we praten over .NET, Java Web Start en PHP. Deze drie hebben alle drie een goede ondesteuning vanaf de ontwikkelaar. Verder worden ze alle drie veel gebruikt en is het dus makkelijk hulp te vinden op het internet. Hierdoor krijgt webbased hiervoor een 7. Conclusie Als we dit alles weer samen nemen komen we uit op een 6,6 al met al ruim voldoende. Het is echter jammer dat het geen goede embedded kwaliteiten heeft. 5.6 Conclusie Als eerste is er een literatuuronderzoek gedaan, op basis van dit onderzoek zijn er een aantal criteria opgesteld en zijn er per mogelijke implementatie punten aan de criteria toegekend. Eigenlijk zou er nu al een keuze zijn, maar dit is niet het geval. Omdat alle implementaties qua punten dicht bij elkaar liggen is er gekeken naar de mogelijkheid om meerdere implementaties samen te nemen en hier een nieuwe implementatie van te maken. De implementatie met het hoogste cijfer is C#, echter scoort C# niet al te best op de onderdelen updaten en mobiele benadering. Deze onderdelen worden juist heel goed beoordeeld bij webbased. Het is daarom ook niet meer dan logisch om te kijken of deze onderdelen te combineren zijn. Dit wordt besproken in het volgende hoofdstuk. 17 18 Combineren van verschillende implementaties 6 De beoordeling van de verschillende implementaties liggen dicht bij elkaar. Geen van alle implementaties is op alle criteria goed beoordeeld. Een combinatie van implementaties levert wellicht een betere interface op. In dit hoofdstuk wordt er gekeken naar de combinatie van C#, die het beste scoorde, samen met een webbassed implementatie. Dit is gedaan in een tweetal stappen, eerst is er gekeken naar wat de beste kandidaat is voor een webbased systeem; er is immers naar drie kandidaten gekeken, vervolgens is er gekeken naar de mogelijkheden die er zijn om deze twee onderdelen te combineren en wat de haalbaarheid hiervan is. 6.1 Beste kandidaat Voor webbased zijn er eigenlijk twee kandidaten als er gekeken wordt naar de mogelijkheid om C# te combineren met een webbased taal. Er kan gekozen worden uit .NET, dit is de ietwat standaard kandidaat. Er is echter ook de mogelijkheid dit te combineren met PHP. Deze tweede optie heeft veel potentie maar is zeker niet de standaard keuze. 6.1.1 .NET Aan .NET zijn een aantal voordelen verbonden, het is speciaal gemaakt om te combineren met C# en de aansluiting zal dus naadloos zijn. Verder zitten zowel C# als .NET in de MSDN libary en is er dus voldoende ondersteuning voor deze samenwerking. Een groot nadeel van .NET is dat het bedoeld is om op windows te draaien. Er zijn wel mogelijkheden om het te laten werken op Linux maar daarvoor moet een apart programma worden gebruikt. 6.1.2 PHP De keuze voor PHP is onverwacht te noemen. Het is bedoeld voor dynamische websites. Het wordt echter het veelal gebruikt voor embedded toepassingen als een router en een NAS. PHP is in staat programma’s op de server uit te voeren en de response van deze programma’s te gebruiken om actie te ondernemen. Zoals in paragraaf 4.4.3 is vermeld is ook de ondersteuning van PHP goed. Een nadeel van de keuze voor PHP is dat er een aparte webserver nodig is om het ook beschikbaar te maken via het internet. 6.1.3 Conclusie Omdat .NET bedoeld is voor windows en er dus geen ondersteuning is voor Linux is er gekozen voor PHP. PHP wordt al succesvol toegepast op embedded systemen zoals routers, hierdoor is de stap naar een gebruikersinterface niet heel groot. Echter moet er nog wel gekeken worden hoe ze te combineren zijn. Dit zal hieronder besproken worden. 19 6.2 Mogelijkheden tot combineren Er is gekeken naar twee mogelijkheden om het geheel te combineren. De eerste mogelijkheid is zelf een webserver maken in C#. De tweede optie is C# en PHP op embedded Linux draaien. 6.2.1 Eigen webserver Het zelf maken van een webserver is natuurlijk niet eenvoudig te noemen, maar het is wel mogelijk hem volledig aan de eisen te laten voldoen. Hierdoor is het mogelijk snelheidswinst en extra veiligheid te creëren. Er zijn echter de nodige eisen waaraan de webserver zal moeten voldoen, waardoor er eigenlijk een soort van besturingssysteem geschreven wordt; dit is ietwat te hoog gegrepen. Tevens zijn er voldoende alternatieven. 6.2.2 Embedded Linux De tweede optie is een optie die op het eerste oog een stuk haalbaarder lijkt. Er is een versie van Linux speciaal bedoeld om te draaien op embedded systemen. Hierbij is rekening gehouden met de gelimiteerde processor en geheugen cappaciteit. Op deze versie van Linux kan men Apache, MySQL en PHP draaien. Deze combinatie is samen bijzonder sterk en wordt dan ook toegepast. Het blijkt betrouwbaar te zijn en de kosten zijn niet meer dan de alternatieven.[15] 6.2.3 Conclusie Er kan dan ook geconcludeerd worden dat deze tweede optie de beste keuze is, vooral omdat de ontwikkeldtijd op deze manier verkort kan worden doordat het wiel niet opnieuw uitgevonden hoeft te worden. 20 7 Het Systeem Het is nu duidelijk wat de beste manier is om een gebruikersinterface te maken. Op basis van deze ondervindingen is er ook daadwerkelijk een gebruikersinterface ontworpen om het iNow systeem te bedienen. 7.1 Structuur van het systeem Het iNow systeem bestaat uit een willekeurig aantal modules die een aantal functionaliteiten kunnen hebben. Al deze modules kunnen de energie die een aparaat verbruikt meten, ook kunnen deze modules het aparaat in en uitschakkelen. Daarnaast kunnen sommige modules ook extra dingen meten zoals: lichtintensiteit, beweging en temperatuur. Alles wat deze modules meten wordt via Zigbee verzonden naar een centrale controller. De controller zendt ook de commando’s ”aan” en ”uit” naar de modules om deze hun apparaat in of uit te laten schakelen. Verder bevat de controller de gebruikersinterface. Figuur 7.1: Blokschema van het iNow Systeem 7.2 Functies van de webinterface en de conrtoller De gebruikersinterface bestaat uit de webinterface en de conrtoller. Deze hebben beide eigen functies. Hieronder worden de functies besproken. 7.2.1 De webinterface Hier volgen de vier functies van de webinterface. 21 Modules toevoegen en in groepen indelen De webinterface geeft de gebruiker de mogelijkheid makkelijk modules toe te voegen aan het iNow netwerk. Hiervoor hoeft alleen het unieke modulenummer en een naam voor de module ingevoerd worden. Bovendien kan een module toegevoegd worden aan een groep. Op die manier kan met een enkele klik een hele groep van aangesloten modules in- of uitgeschakeld worden. Alle modulenummers en groepen worden bijgehouden in de database. Schakelen van modules De webinterface toont een overzicht van alle aangesloten modules. Van elke module wordt weergegeven of die in- of uitgeschakeld is. Bij elke module zit een knop waarmee een module geschakeld kan worden. Als hierop wordt gedrukt, geeft de webinterface aan de controller door dat er geschakeld moet worden. De controller stuurt vervolgens een schakelsignaal naar de betreffende module. De ontvangen data van modules weergeven Alle schakelmodules kunnen naast de aangesloten apparaten schakelen, ook het energieverbruik meten. Het gemeten energieverbruik wordt periodiek door de modules naar de controller gestuurd. De controller haalt de informatie over het energieverbruik uit de ontvangen data en stuurt die door naar de webinterface. In de webinterface wordt het energieverbruik weergegeven in een grafiek, zodat duidelijk te zien is hoeveel energie een aangesloten module in de afgelopen tijd verbruikt heeft. Een deel van de modules bevat ook één of meerdere sensoren. Deze modules sturen naast het energieverbruik ook de sensorinformatie door. Deze sensorinformatie is ook apart zichtbaar in de webinterface. Schakelactiviteiten invoeren Naast het direct schakelen van modules, kan het schakelen ook ingepland worden om op bepaalde tijden te schakelen. Er kan gekozen worden of een enkele module of een groep geschakeld moet worden op het geplande tijdstip. Het is ook mogelijk om een module voor een bepaalde tijd in of uit te schakelen. Hiervoor kan naast een begintijd ook een eindtijd ingevoerd worden. Bij deze schakelmomenten kan verder een herhaling worden aangegeven. Op deze manier kan een veel voorkomende schakelactiviteit elke dag, of bepaalde dagen van de week, automatisch uitgevoerd worden zonder dat het voor elke dag apart ingevoerd dient te worden. Al deze schakelmomenten worden opgeslagen in de database. Deze wordt elke vijf minuten gecontroleerd of er geschakeld moet worden. Code De code die is geschreven voor de webinterface is te vinden in bijlage A. 7.2.2 De controller De controller heeft de volgende twee functies. Data versturen en ontvangen De controller is de koppeling tussen de gebruiker en de aangesloten modules. De controller stuurt de schakelsignalen naar de modules en ontvangt de sensorinformatie van de modules. Dit gebeurt allemaal draadloos met behulp van Zigbee. De controller is te benaderen via de webinterface. Hier wordt de ontvangen data getoond en worden de schakelsignalen ingevoerd. 22 Data decoderen De modules versturen de data naar de controller. De controller haalt de gewenste informatie uit de ontvangen data, dit zijn: de afzender, de tijd van ontvangst en de sensordata. Deze informatie wordt vervolgens in de database opgeslagen en kan vanaf daar gebruikt worden door de webinterface. Code De code die is geschreven voor de controller is te vinden in bijlage B. 23 24 Conclusies en aanbevelingen 8.1 8 Conclusie Op de vraag wat de beste implementatie is van een op afstand te benaderen grafische gebruikersinterface die hardware aanstuurt, kan het volgende antwoord worden gegeven: Een embedded systeem waarop embedded linux draait. Op dit besturingsysteem worden Apache, MySQL en PHP geı̈nstalleerd om te zorgen voor de benadering op afstand. Vervolgens dient een in C# geschreven programma voor de communicatie met de hardware, dit programma communiceert ook met PHP. Deze implementatie is het beste omdat bleek dat C# en Java zelf niet goed zijn om een op afstand te benaderen grafische gebruikersinterface te maken. Hierin is PHP juist heel sterk; dat is ook waarom er is gekeken naar de mogelijkheid om C# te combineren met een webinterface als PHP. Hieruit kwam dat er het beste gebruik gemaakt kan worden van Embedded Linux, omdat dit even duur is als menig andere toepassing maar wel sneller in de ontwikkeling. Dit is dan ook het totaal plaatje geworden er zijn echter nog wel wat op en aanmerkingen die genoemd moeten worden. 8.2 Aanbevelingen Bij dit onderzoek is er alleen gekeken naar een oplossing met een FPGA, C#, Java, .NET, Java Web Start en PHP. Er zijn echter nog veel meer andere mogelijkheden die wellicht een beter resultaat opleveren. Dit is dan ook iets dat in aanmerking komt voor verder onderzoek. Daarnaast is er voor een deel gebruik gemaakt van de ervaringen van gebruikers, het blijft natuurlijk de vraag of dit een correcte represenatie van alle gebruikers was. Het zou zeker de moeite waard zijn om uit te zoeken of deze ervaringen voor alle gebruikers gelden. Ook is er nog niet specifiek gekeken naar de snelheden die bereikt kunnen worden. En dan juist naar wat er gebeurt als men van C# naar PHP gaat en vice-versa. Het blijkt dan ook dat deze snelheid nog niet optimaal is. Ook is de interface nog niet mooi vorm gegeven, hier moet dan ook nog aandacht aan worden besteed. Het schakelen op sensor informatie werkt nog niet naar behoren, dit zal verder uitgewerkt moeten worden. 25 26 Literatuur [1] J. M. Rabaey, A. Chandrakasan, and B. Nikolic, Digital Integrated Circuits A Design Perspective. Prentice-Hall, 2 ed., 1996. [2] R. K. Gupta and G. D. Micheli, “The roles of fpga’s in reprogrammable system,” Proceedings of the IEEE, vol. 86, pp. 615–639, april 1998. [3] Underwood and Keith, “Fpgas vs. cpus: trends in peak floating-point performance,” in FPGA ’04: Proceedings of the 2004 ACM/SIGDA 12th international symposium on Field programmable gate arrays, (New York, NY, USA), pp. 171–180, ACM, 2004. [4] A. DeHon and J. Wawrzynek, “Reconfigurable computing: what, why, and implications for design automation,” in DAC ’99: Proceedings of the 36th annual ACM/IEEE Design Automation Conference, (New York, NY, USA), pp. 610–615, ACM, 1999. [5] C. H. Pappasa and W. H. Murray, C# Essentials. Prentice Hall, 1 ed., 2001. [6] G. D. Micheli, “Hardware synthesis from c/c++ models,” Design, Automation, and Test in Europe, p. 80, 1999. [7] A. Ghosh, J. Kunkel, and S. Liao, “Hardware synthesis from c/c++,” Design, Automation, and Test in Europe, p. 82, 1999. [8] R. K. Guptaa and G. D. Micheli, “Hardware-software co-synthesis for digital systems,” IEEE Design & Test, vol. 10, pp. 29–41, 1993. [9] C. Horstmann, Big Java. Wiley, 3 ed., 2008. [10] A. Herzog and N. Shahmehri, “Performance of the java security manager,” Computers and Security, vol. 24, pp. 192–207, 2005. [11] “.net framework.” [Online]. Available: http://en.wikipedia.org/wiki/.NET Framework, Mei 2010. [12] “Java web start.” [Online]. Available: http://en.wikipedia.org/wiki/Java Web Start, Mei 2010. [13] L. Welling and L. Thomson, PHP and MySQL Web Development. Sams, 3 ed., 2004. [14] “Php.” [Online]. Available: http://en.wikipedia.org/wiki/PHP, Mei 2010. [15] J. R. Williams, “Embedding linux in a commercial product: A look at embedded systems and what it takes to build one,” Linux Journal, October 1999. 27 28 Code van de webinterface A.1 A Actions.php 1 <?PHP include ( "config . php" ) ; 6 $sql = " SELECT * FROM actions ORDER BY id ASC LIMIT 0,1" ; $res = mysql_query ( $sql ) ; if ( mysql_num_rows ( $res )==1) { $row = mysql_fetch_array ( $res ) ; $sql = " DELETE FROM actions WHERE id = ’" . $row [ ’id ’ ] . "’" ; mysql_query ( $sql ) ; 11 echo $row [ 1 ] . ";" . $row [ 2 ] ; } ?> A.2 C.php 1 <?PHP include ( "config . php" ) ; $source=(int ) ( isset ( $_GET [ ’source ’ ] ) ? $_GET [ ’source ’ ] : − 1 ) ; $signaal_type=(isset ( $_GET [ ’ signaal_type’ ] ) ? $_GET [ ’signaal_type’ ] : ’’ ) ; $signaal_type = ( ( strtoupper ( $signaal_type )==’A’ ) ? ’A’ : ’D’ ) ; 6 if ( $signaal_type==’A’ ) { $deel=(int ) ( isset ( $_GET [ ’deel ’ ] ) ? $_GET [ ’deel’ ] : − 1 ) ; $value=hexdec ( ( isset ( $_GET [ ’value ’ ] ) ? $_GET [ ’value ’ ] : ’’ ) ) ; } 11 else { $deel=−1; $value=decbin ( hexdec ( ( isset ( $_GET [ ’value ’ ] ) ? $_GET [ ’value ’ ] : ’’ ) ) ) ; $value = str_pad ( $value , 1 6 , "0" , STR_PAD_LEFT ) ; 16 } $sql = " INSERT INTO data VALUES (’’,’" . time ( ) . " ’,’" . $source . " ’,’" . $value . " ’,’" . $deel . " ’)" ; mysql_query ( $sql ) ; ?> A.3 Class.Zigbee.php 29 <?PHP class Zigbee { function Zigbee ( ) 5 { } 10 15 function IsLogin ( ) { if ( isset ( $_SESSION [ ’login ’ ] ) ) { return $_SESSION [ ’login ’ ] ; } else { return false ; } } 20 25 30 35 40 45 50 function DoLogin ( ) { if ( isset ( $_SERVER [ ’ PHP_AUTH_USER’ ] ) ) { if ( $this−>Login ( $_SERVER [ ’ PHP_AUTH_USER’ ] , $_SERVER [ ’ PHP_AUTH_PW’ ] ) ) { $_SESSION [ ’login ’]= true ; } else { header ( ’WWW - Authenticate: Basic realm =" Zigbee "’ ) ; header ( ’HTTP /1.0 401 Unauthorized’ ) ; echo " Canceled by user\n" ; exit ; } } header ( ’WWW - Authenticate: Basic realm =" Zigbee "’ ) ; header ( ’HTTP /1.0 401 Unauthorized’ ) ; echo " Canceled by user\n" ; exit ; } function Login ( $uname , $pword ) { $sql = " Select * from Users where Username = ’" . $uname . "’ and Password = ’" . md5 ( $pword ) . "’" ; $res = mysql_query ( $sql ) ; if ( mysql_num_rows ( $res ) ==1) { return true ; } else 30 { return true ; } 55 60 65 70 75 80 85 90 95 100 } function getModules ( $id=−1) { if ( $id==−1) { $sql = " Select * from modules " ; $res = mysql_query ( $sql ) ; $data = array ( ) ; if ( mysql_num_rows ( $res ) >0) { while ( $row = mysql_fetch_array ( $res ) ) { $data [ ] = $row ; } } } else { $id = ( int ) $id ; $sql = " Select * from modules where Id = ’$id’" ; $res = mysql_query ( $sql ) ; if ( mysql_num_rows ( $res ) >0) { $data = mysql_fetch_array ( $res ) ; } } return $data ; } function getGroups ( ) { $sql = " Select * from groups " ; $res = mysql_query ( $sql ) ; $data = array ( ) ; if ( mysql_num_rows ( $res ) >0) { while ( $row = mysql_fetch_array ( $res ) ) { $data [ ] = $row ; } } return $data ; } function getGroupMembers ( $id ) { $id = ( int ) $id ; $sql = " select modules .Name as Name , groupmembers.id as Id from groupmembers , modules where groupmembers. Mid = 31 modules .id && groupmembers. Gid=’ $id’" ; $res = mysql_query ( $sql ) ; $data = array ( ) ; if ( mysql_num_rows ( $res ) >0) { while ( $row = mysql_fetch_array ( $res ) ) { $data [ ] = $row ; } } return $data ; 105 110 } 115 function getData ( $id=−1) { if ( $id==−1) { $sql = " Select * from data" ; $res = mysql_query ( $sql ) ; $data = array ( ) ; if ( mysql_num_rows ( $res ) >0) { while ( $row = mysql_fetch_array ( $res ) ) { $data [ ] = $row ; } } } else { $id = ( int ) $id ; $sql = " Select * from data where Id = ’$id’" ; $res = mysql_query ( $sql ) ; if ( mysql_num_rows ( $res ) >0) { $data = mysql_fetch_array ( $res ) ; } } return $data ; } 120 125 130 135 140 } ?> A.4 Config.php 1 <?PHP $db_user = " Zigbee " ; $db_pass = " Zigbee " ; $db_name = " Zigbee " ; $db_host = " Localhost" ; 6 $db = mysql_connect ( $db_host , $db_user , $db_pass) ; mysql_select_db ( $db_name ) ; 32 11 ?> A.5 4 9 14 19 Cron.php <?PHP include ( dirname ( __FILE__ ) . "/ config . php" ) ; $uur = ( int ) date ( "H" ) ; $min = ( int ) date ( "i" ) ; $min = ( int ) round ( $min / 5 ) ∗ 5 ; $tijd = $uur . ":" . $min ; $sql = " SELECT * FROM schedule WHERE time = ’" . $tijd . "’ && ( Recursion LIKE ’%" . date ( "w" ) . " ,%’ || Recursion=’" . date ( ’d-m-Y’ ) . " ’)" ; $res = mysql_query ( $sql ) ; while ( $row = mysql_fetch_array ( $res ) ) { echo $action = ( ( $row [ ’ToState ’]==1)? ’AAN’ : ’UIT’ ) ; $state = $row [ ’ToState ’ ] ; if ( $row [ ’Type’]==0) // ophalen alle modules in de group { echo "<br />G<br />" ; $sql2 = " SELECT modules . Address as address FROM groupmembers , modules WHERE groupmembers. Mid = modules .Id && groupmembers.Gid = ’" . $row [ ’Target ’ ] . "’" ; $res2 = mysql_query ( $sql2 ) ; while ( $row2 = mysql_fetch_array ( $res2 ) ) { $sql3 = "INSERT INTO actions VALUES(’’,’" . $action . " ’,’" . $row2 [ ’address ’ ] . " ’)" ; mysql_query ( $sql3 ) ; } 24 $sql4 = " UPDATE groupmembers , modules , groups SET modules . state =’" . $state . "’, groups . state =’" . $state . "’ WHERE groupmembers.Mid = modules .Id && groupmembers. Gid = groups .Id && groupmembers. Gid = ’" . $row [ ’Target ’ ] . "’" ; mysql_query ( $sql4 ) ; 29 34 } else { echo "<br />M<br />" ; $sql2 = " SELECT Address from modules Where Id=’" . $row [ ’Target ’ ] . "’" ; $res2 = mysql_query ( $sql2 ) ; $row2 = mysql_fetch_array ( $res2 ) ; $sql3 = " INSERT INTO actions VALUES (’’,’" . $action . " ’,’" . $row2 [ ’Address ’ ] . " ’)" ; mysql_query ( $sql3 ) ; $sql4 = " UPDATE modules SET state =’" . $state . "’ Where Id=’" . $row [ ’Target ’ ] . "’" ; 33 mysql_query ( $sql4 ) ; 39 } if ( $row [ ’ Recursion’ ] == date ( ’d-m-Y’ ) ) { echo "DEL <br />" ; $sql5 = " DELETE FROM schedule WHERE id = ’" . $row [ ’Id ’ ] . "’" ; mysql_query ( $sql5 ) ; } 44 } 49 ?> A.6 Index.php 1 <?PHP session_start ( ) ; include ( dirname ( __FILE__ ) . "/ config . php" ) ; include ( dirname ( __FILE__ ) . "/ Class. Zigbee . php" ) ; 6 $zigbee = new Zigbee ( ) ; if ( ! $zigbee−>IsLogin ( ) ) { $zigbee−>DoLogin ( ) ; } 11 16 21 26 31 if ( isset ( $_REQUEST [ ’what’ ] ) && $_REQUEST [ ’what ’]==’module ’ ) { $Name = mysql_escape_string ( $_REQUEST [ ’Name’ ] ) ; $Location = mysql_escape_string ( $_REQUEST [ ’Location’ ] ) ; $ModuleType = ( int ) $_REQUEST [ ’ ModuleType’ ] ; $Address = mysql_escape_string ( $_REQUEST [ ’Address ’ ] ) ; if ( $_REQUEST [ ’submit ’ ] ==’Edit’ ) { $Id = ( int ) $_REQUEST [ ’Id ’ ] ; $sql = " UPDATE modules Set Name=’" . $Name . " ’, Location=’" . $Location . " ’, ModuleType=’" . $ModuleType . " ’, Address =’" . $Address . "’ where Id = ’$Id’" ; mysql_query ( $sql ) ; } else { $sql = " Insert Into modules (‘Id ‘,‘Name ‘,‘ Location ‘,‘ ModuleType ‘,‘Address ‘) VALUES (’’,’" . $Name . " ’,’" . $Location . " ’,’" . $ModuleType . "’,’" . $Address . " ’)" ; mysql_query ( $sql ) ; } } if ( isset ( $_REQUEST [ ’what’ ] ) && $_REQUEST [ ’what ’]==’ membership’ ) { $Module = ( int ) $_REQUEST [ ’Module ’ ] ; 34 36 $Group = ( int ) $_REQUEST [ ’Group ’ ] ; if ( $Group==−1) { $Name = mysql_escape_string ( $_REQUEST [ ’Name ’ ] ) ; $Location = mysql_escape_string ( $_REQUEST [ ’ Location’ ] ) ; 41 $sql = " Insert Into groups (‘Id ‘,‘Name ‘,‘Location ‘) VALUES (’’,’" . $Name . " ’,’" . $Location . " ’)" ; mysql_query ( $sql ) ; $Group = mysql_insert_id ( ) ; } 46 $sql = " Insert Into groupmembers (‘Id ‘,‘Gid ‘,‘Mid ‘) VALUES (’’,’" . $Group . " ’,’" . $Module . " ’)" ; mysql_query ( $sql ) ; 51 56 } if ( isset ( $_REQUEST [ ’what’ ] ) && $_REQUEST [ ’what ’]==’time’ ) { print_r ( $_REQUEST ) ; $MG = ( isset ( $_REQUEST [ ’MG ’ ] ) ? ( ( $_REQUEST [ ’MG ’]==’G’ ) ? ’G’ : ’M’ ) : ’M ’) ; $Welke = ( int ) isset ( $_REQUEST [ ’Welke ’ ] ) ? $_REQUEST [ ’Welke ’ ] : 0 ; $aan_Aan = ( int ) isset ( $_REQUEST [ ’aan_Aan ’ ] ) ? $_REQUEST [ ’aan_Aan ’ ]:0; $aan_H = ( int ) isset ( $_REQUEST [ ’aan_H ’ ] ) ? $_REQUEST [ ’aan_H ’ ] : 0 ; $aan_M = ( int ) isset ( $_REQUEST [ ’aan_M ’ ] ) ? $_REQUEST [ ’aan_M ’ ] : 0 ; $uit_Aan = ( int ) isset ( $_REQUEST [ ’uit_Aan ’ ] ) ? $_REQUEST [ ’uit_Aan ’ ]:0; $uit_H = ( int ) isset ( $_REQUEST [ ’uit_H ’ ] ) ? $_REQUEST [ ’uit_H ’ ] : 0 ; $uit_M = ( int ) isset ( $_REQUEST [ ’uit_M ’ ] ) ? $_REQUEST [ ’uit_M ’ ] : 0 ; 61 66 71 76 81 $dag = isset ( $_REQUEST [ ’Dag’ ] ) ? $_REQUEST [ ’Dag’ ] : array ( ) ; $uitNaAan = false ; if ( $aan_Aan==1 && $uit_Aan==1) { if ( $aan_H>$uit_H ) { $uitNaAan=true ; } elseif ( $aan_H==$uit_H ) { if ( $aan_M>$uit_M ) { $uitNaAan=true ; } elseif ( $aan_M==$uit_M ) { $aan_Aan=0; $uit_Aan=0; } } } 35 86 91 96 101 106 111 116 121 126 131 $dagen_Aan = ’’ ; $dagen_Uit = ’’ ; if ( is_array ( $dag ) ) { foreach ( $dag as $nr=>$waarde ) { if ( $waarde == 1 ) { $dagen_Aan .= $nr . "," ; if ( $uitNaAan ) { $nr++; if ( $nr==7) { $nr =0; } $dagen_Uit .= $nr . "," ; } else { $dagen_Uit .= $nr . "," ; } } } } if ( $dagen_Aan == "" ) { $dagLater = 0 ; if ( $uitNaAan ) { if ( $uit_H<date ( "G" ) ) { $dagLater=1; } elseif ( $uit_H==date ( "G" ) ) { if ( $uit_M <= ( ( int ) date ( "i" ) ) ) { $dagLater=1; } } } else { if ( $aan_H<date ( "G" ) ) { $dagLater=1; } elseif ( $aan_H==date ( "G" ) ) { if ( $aan_M <= ( ( int ) date ( "i" ) ) ) { $dagLater=1; 36 136 } } 141 146 151 156 161 } $dagen_Aan = date ( "d-m-Y" , time ( ) +(3600∗24∗ $dagLater ) ) ; if ( $uitNaAan ) { $dagen_Uit = date ( "d-m-Y" , time ( ) +(3600∗24∗( $dagLater+1) ) ) ; } else { $dagen_Uit = date ( "d-m-Y" , time ( ) +(3600∗24∗ $dagLater ) ) ; } } if ( $aan_Aan==1) { $sql = " Insert INTO schedule VALUES (’’,’" . $aan_H . ":" . $aan_M . " ’,’" . ( ( $MG=="M" ) ? 1 : 0 ) . " ’,’" . $Welke . " ’,’" . $dagen_Aan . " ’,’1’);" ; mysql_query ( $sql ) ; } if ( $uit_Aan==1) { $sql = " Insert INTO schedule VALUES (’’,’" . $uit_H . ":" . $uit_M . " ’,’" . ( ( $MG=="M" ) ? 1 : 0 ) . " ’,’" . $Welke . " ’,’" . $dagen_Uit . " ’,’0’);" ; mysql_query ( $sql ) ; } } if ( isset ( $_REQUEST [ ’what’ ] ) && $_REQUEST [ ’what ’]==’delete ’ ) { if ( isset ( $_REQUEST [ ’where ’ ] ) && $_REQUEST [ ’where ’]==’module ’ ) { $id = ( int ) $_REQUEST [ ’id ’ ] ; 166 $sql = " Delete from modules where Id = ’" . $id . "’" ; mysql_query ( $sql ) ; 171 } if ( isset ( $_REQUEST [ ’where ’ ] ) && $_REQUEST [ ’where ’]==’groups ’ ) { $id = ( int ) $_REQUEST [ ’mid’ ] ; $sql = " Delete from groupmembers where Id = ’" . $id . "’" ; mysql_query ( $sql ) ; 176 181 $sql = " Select Gid from groupmembers" ; $res = mysql_query ( $sql ) ; $ids = array ( ) ; while ( $row = mysql_fetch_array ( $res ) ) { $ids [ ] = $row [ ’Gid’ ] ; } 37 $ids = array_unique ( $ids ) ; $sql = " Delete from groups where Id NOT IN(" . implode ( $ids , "," ) . ")" ; mysql_query ( $sql ) ; 186 } } ?> 191 196 201 206 211 216 221 226 <h1>Add Module</h1> <form method="post" action=" index. php"> <input type=" hidden" name=" what" value=" module" /><br /> <?PHP if ( isset ( $_REQUEST [ ’what ’ ] ) && $_REQUEST [ ’what’]==’edit ’ && isset ( $_REQUEST [ ’where ’ ] ) && $_REQUEST [ ’where ’]==’module ’ ) { $id = ( int ) $_REQUEST [ ’id ’ ] ; $data = $zigbee−>getModules ( $id ) ; echo ’<input type=" hidden " name=" Id" value =" ’ . $id . ’" />’ ; $module_edit = true ; } else { $module_edit = false ; } ?> <table> <tr> <td>Name :</td> <td><input type=" text" name=" Name" value=" <? PHP if( $module_edit){ echo $data[’ Name ’];}? >" /></td> </tr> <tr> <td>Location:</td> <td><input type=" text" name=" Location" value=" <?PHP if( $module_edit){ echo $data[’ Location ’];}? >" /></td> </tr> <tr> <td>ModuleType:</td> <td><input type=" text" name=" ModuleType" value=" <? PHP if( $module_edit ){ echo $data[’ ModuleType’];}? >" /></td> </tr> <tr> <td>Address :</td> <td><input type=" text" name=" Address " value=" <?PHP if( $module_edit){ echo $data[’ Address ’];}? >" /></td> </tr> <tr> <td></td> <td><input type=" submit " name="submit " value=" Add" /> <?PHP if ( $module_edit ) { echo ’<input type =" submit " name=" submit" value =" Edit " />’;}?></td> 38 </tr> </table> 231 </form> 236 241 246 251 256 261 266 271 276 <h1>Group memberschip</h1> <form method="post" action=" index. php"> <input type=" hidden" name=" what" value=" membership" /> <table> <tr> <td>Module :</td> <td> <select name=" Module "> <?PHP $modules = $zigbee−>getModules ( ) ; foreach ( $modules as $module ) { echo "<option value=’" . $module [ ’Id’ ] . " ’>" . $module [ ’Name ’ ] . " & lt;" . $module [ ’ Location’ ] . "&gt;</ option >" ; } ?> </select> </td> </tr> <tr> <td>Group :</td> <td> <select name=" Group"> <option value=" -1">New</option> <?PHP $groups = $zigbee−>getGroups ( ) ; foreach ( $groups as $group ) { echo "<option value=’" . $group [ ’Id ’ ] . " ’>" . $group [ ’Name’ ] . " &lt ;" . $group [ ’ Location’ ] . "&gt ;</option >" ; } ?> </select> </td> </tr> <tr> <td>Name :</td> <td><input type=" text" name=" Name" value="" /></td> </tr> <tr> <td>Location:</td> <td><input type=" text" name=" Location" value="" /></td> </tr> <tr> <td></td> <td><input type=" submit " name="submit " value=" Add" /></td> </tr> </table> </form> 39 281 <h1>Modules</h1> <table width="500px"> <tr> <td>Id</td> <td>Name</td> 286 <td>Location</td> <td>ModuleType</td> <td>Address</td> <td>State</td> <td>Edit</td> 291 <td>Delete</td> </tr> <?PHP $modules = $zigbee−>getModules ( ) ; foreach ( $modules as $row ) 296 { echo "<tr > <td >" . $row [ ’Id’ ] . " </td > <td >" . $row [ ’Name’ ] . " </td > <td >" . $row [ ’ Location’ ] . " </td > 301 <td >" . $row [ ’ ModuleType’ ] . " </td > <td >" . $row [ ’Address ’ ] . " </td > <td >" . $row [ ’State ’ ] . " </td > <td ><a href=’ index.php? what= edit& where= module &id=" . $row [ ’ Id ’ ] . " ’>EDIT </a ></td > <td ><a href=’ index.php? what= delete &where =module &id=" . $row [ ’Id’ ] . " ’>DEL </a ></td > 306 </tr >" ; } ?> </table> 311 <h1>Groups</h1> <table width="500px"> <tr> <td>Id</td> <td valign=" top">Name</td> 316 <td>Location</td> <td>State</td> <td>Members</td> <td>Edit</td> <td>Delete</td> 321 </tr> <?PHP $groups = $zigbee−>getGroups ( ) ; foreach ( $groups as $row ) { 326 $members = $zigbee−>getGroupMembers ( $row [ ’Id ’ ] ) ; $first = true ; foreach ( $members as $member ) { 40 331 if ( $first ) { $first = false ; echo "<tr > <td valign =’top ’>" . $row [ ’Id’ ] . " </td > <td valign =’top ’>" . $row [ ’Name’ ] . " </td > <td valign =’top ’>" . $row [ ’ Location’ ] . " </td > <td valign =’top ’>" . $row [ ’State ’ ] . " </td > <td valign =’top ’>" . $member [ ’Name ’ ] . " </td > <td valign =’top ’><a href=’ index. php? what= edit& where=groups & mid=" . $member [ ’Id ’ ] . " ’>EDIT </a ></ td > <td valign =’top ’><a href=’ index. php? what= delete & where=groups & mid=" . $member [ ’Id ’ ] . " ’>DEL </a ></ td > </tr >" ; } else { echo "<tr > <td valign =’top ’>&nbsp;</td > <td valign =’top ’>&nbsp;</td > <td valign =’top ’>&nbsp;</td > <td valign =’top ’>&nbsp;</td > <td valign =’top ’>" . $member [ ’Name ’ ] . " </td > <td valign =’top ’><a href=’ index. php? what= edit& where=groups & mid=" . $member [ ’Id ’ ] . " ’>EDIT </a ></ td > <td valign =’top ’><a href=’ index. php? what= delete & where=groups & mid=" . $member [ ’Id ’ ] . " ’>DEL </a ></ td > </tr >" ; } 336 341 346 351 356 } } ?> </table> <script language=" javascript" type=" text/ javascript"> 361 var M_array = new Array ( ) ; <?PHP $modules = $zigbee−>getModules ( ) ; foreach ( $modules as $row ) { echo " M_array [’" . $row [ ’Id ’ ] . " ’] = ’" . $row [ ’Name’ ] . " <" . $row [ ’ 366 Location’ ] . " >’;\n" ; } ?> var G_array = new Array ( ) ; <?PHP 371 $groups = $zigbee−>getGroups ( ) ; foreach ( $groups as $row ) { echo " G_array [’" . $row [ ’Id ’ ] . " ’] = ’" . $row [ ’Name’ ] . " <" . $row [ ’ 41 Location’ ] . " >’;\n" ; } 376 ?> 381 386 391 396 401 406 411 416 421 function change_MG ( box ) { var index = box . selectedIndex ; var value = box . options [ index ] . value ; var welke = document . getElementById ( "welke" ) ; if ( value == "M" ) { welke . options . length = 0 ; for ( index in M_array ) { welke . options [ welke . options . length ] = new Option ( M_array [ index ] , index ) ; } } else { welke . options . length = 0 ; for ( index in G_array ) { welke . options [ welke . options . length ] = new Option ( G_array [ index ] , index ) ; } } } function change_uit ( ding ) { if ( ding . checked ) { document . getElementById ( " uit_time" ) . style . visibility="visible " ; document . getElementById ( " aan_Aan " ) . disabled=false ; } else { document . getElementById ( " uit_time" ) . style . visibility="hidden " ; document . getElementById ( " aan_Aan " ) . disabled=true ; } } function change_aan ( ding ) { if ( ding . checked ) { document . getElementById ( " aan_time" ) . style . visibility="visible " ; document . getElementById ( " uit_Aan " ) . disabled=false ; } else { document . getElementById ( " aan_time" ) . style . visibility="hidden " ; document . getElementById ( " uit_Aan " ) . disabled=true ; } 42 } 426 </script> <h1>Tijdschema</h1> <form action="index. php" method=" post" name=" time"> <input type=" hidden" name=" what" value=" time" /> <table width="500"> 431 <tr> <td>Module / Group :</td> <td>Welke :</td> <td colspan="2">&nbsp;</td> </tr> 436 <tr> <td rowspan="4" valign=" top"><select id="MG" name="MG" onchange=’ change_MG(this. form.MG);’> <option value="M">Module</option> <option value="G">Group</option> </select> 441 </td> <td rowspan="4" valign=" top"><select name=" Welke" id=" welke"> </select><script language=" javascript" type=" text/ javascript"> change_MG ( document . getElementById ( "MG" ) ) ;</ script></td> 446 451 456 461 466 <td colspan="2">Aan:</td> <td colspan="5"><input type=" checkbox" checked=" checked " value="1" name=" aan_Aan " id=" aan_Aan " onchange=" change_aan( this. form. aan_Aan )" />&nbsp;& nbsp;& nbsp;< span id=" aan_time"><select id=" aan_H" name =" aan_H"> <?PHP for ( $i =0;$i <24;$i++) { if ( str_pad ( $i , 2 , "0" , STR_PAD_LEFT ) == date ( "H" ) ) { echo "<option value=’" . $i . "’ selected=’ selected’>" . str_pad ( $i , 2 , "0" , STR_PAD_LEFT ) . " </option >" ; } else { echo "<option value=’" . $i . " ’>" . str_pad ( $i , 2 , "0" , STR_PAD_LEFT ) . " </ option >" ; } } ?> </select>&nbsp ;& nbsp ; : & nbsp;& nbsp;< select id=" aan_M" name=" aan_M"> <?PHP for ( $i =0;$i <60;$i+=5) { if ( $i == round ( ( ( int ) date ( "i" ) ) / 5 ) ∗ 5 ) { echo "<option value=’" . $i . "’ selected=’ selected’>" . str_pad ( $i , 2 , "0" , STR_PAD_LEFT ) . " </option >" ; } else 43 { echo "<option value=’" . $i . " ’>" . str_pad ( $i , 2 , "0" , STR_PAD_LEFT ) . " </ option >" ; 471 } } 476 481 486 491 496 501 506 511 ?> </select></span></td> </tr> <tr> <td colspan="2">Uit:</td> <td colspan="5"><input type=" checkbox" checked=" checked " value="1" name=" uit_Aan " id=" uit_Aan " onchange=" change_uit( this. form. uit_Aan )" />&nbsp;& nbsp;& nbsp;< span id=" uit_time"><select id=" uit_H" name =" uit_H"> <?PHP for ( $i =0;$i <24;$i++) { if ( str_pad ( $i , 2 , "0" , STR_PAD_LEFT ) == date ( "H" ) ) { echo "<option value=’" . $i . "’ selected=’ selected’>" . str_pad ( $i , 2 , "0" , STR_PAD_LEFT ) . " </option >" ; } else { echo "<option value=’" . $i . " ’>" . str_pad ( $i , 2 , "0" , STR_PAD_LEFT ) . " </ option >" ; } } ?> </select>&nbsp ;& nbsp ; : & nbsp;& nbsp;< select id=" uit_M" name=" uit_M"> <?PHP for ( $i =0;$i <60;$i+=5) { if ( $i == round ( ( ( int ) date ( "i" ) ) / 5 ) ∗ 5 ) { echo "<option value=’" . $i . "’ selected=’ selected’>" . str_pad ( $i , 2 , "0" , STR_PAD_LEFT ) . " </option >" ; } else { echo "<option value=’" . $i . " ’>" . str_pad ( $i , 2 , "0" , STR_PAD_LEFT ) . " </ option >" ; } } ?> </select></span></td> </tr> <tr> <td align=" center ">M</td> <td align=" center ">D</td> <td align=" center ">W</td> <td align=" center ">D</td> <td align=" center ">V</td> 44 <td align=" center ">Z</td> 516 <td align=" center ">Z</td> </tr> <tr> <td align=" center "><input type=" checkbox" value="1" name=" Dag [1]" /></td> <td align=" center "><input type=" checkbox" value="1" name=" Dag [2]" /></td> 521 <td align=" center "><input type=" checkbox" value="1" name=" Dag [3]" /></td> <td align=" center "><input type=" checkbox" value="1" name=" Dag [4]" /></td> <td align=" center "><input type=" checkbox" value="1" name=" Dag [5]" /></td> <td align=" center "><input type=" checkbox" value="1" name=" Dag [6]" /></td> <td align=" center "><input type=" checkbox" value="1" name=" Dag [0]" /></td> 526 </tr> <tr> <td colspan="2"></td> <td colspan="7"><input type=" submit " name=" submit " value="Add" /></td > </tr> 531 </table> </form> 45 46 Code van de controller 3 8 13 18 B using System ; using System . IO . Ports ; using System . Threading ; using System . Collections ; using System . Text ; using System . Net ; using System . IO ; using System . Data ; using System . Diagnostics ; namespace Zigbee_Driver { public class PortChat { static void Main ( string [ ] args ) { PortChat classe = new PortChat ( ) ; classe . hoofd ( ) ; } static bool _continue ; static SerialPort _serialPort ; string [ ] bytes_rec ; Boolean toggle ; 23 public void hoofd ( ) { StringComparer stringComparer = StringComparer . OrdinalIgnoreCase ; // Thread readThread = new Thread ( Read); 28 // Create a new SerialPort object with default settings. _serialPort = new SerialPort ( ) ; 38 // Allow the user to set the appropriate properties. _serialPort . PortName = " COM2" ; _serialPort . BaudRate = 9 6 0 0 ; _serialPort . Parity = Parity . None ; _serialPort . DataBits = 8 ; _serialPort . StopBits = StopBits . One ; _serialPort . Handshake = Handshake . None ; ; 43 // Set the read/ write timeouts _serialPort . ReadTimeout = 1 0 0 0 ; _serialPort . WriteTimeout = 1 0 0 0 ; _serialPort . DataReceived += new 33 47 SerialDataReceivedEventHandler ( port_DataReceived ) ; _serialPort . Open ( ) ; _continue = true ; 48 53 58 63 68 73 78 83 88 while ( _continue ) { actions ( ) ; } _serialPort . Close ( ) ; } public void actions ( ) { System . Diagnostics . ProcessStartInfo oInfo = new System . Diagnostics . ProcessStartInfo ( "c:/ wamp/ bin/ php/ php5 .3.0/ php . exe" , "c:/ wamp/ www/ actions . php" ) ; oInfo . UseShellExecute = false ; oInfo . ErrorDialog = false ; oInfo . CreateNoWindow = true ; oInfo . RedirectStandardOutput = true ; try { Process p = System . Diagnostics . Process . Start ( oInfo ) ; System . IO . StreamReader oReader2 = p . StandardOutput ; string sRes = oReader2 . ReadToEnd ( ) ; // split in lines: if ( sRes . IndexOf ( ";" ) >1) { String [ ] arguments = sRes . Split ( ";" . ToCharArray ( ) ) ; if ( arguments . Length == 2 ) { Console . WriteLine ( arguments [ 0 ] ) ; Console . WriteLine ( arguments [ 1 ] ) ; int module = Convert . ToInt32 ( arguments [ 1 ] ) ; if ( arguments [ 0 ] == " AAN" ) { send_aan ( module ) ; } else if ( arguments [ 0 ] == " UIT" ) { send_uit ( module ) ; } } } oReader2 . Close ( ) ; p . Close ( ) ; // All the external programs output is now in sRes // do what we want with it - calling fake function AnalyzeResult } catch ( Exception ex ) { 48 93 // Console . WriteLine(ex. Message ); } } 98 103 108 113 118 private void port_DataReceived ( object sender , SerialDataReceivedEventArgs e ) { // Show all the incoming data in the port’s buffer int bytes = _serialPort . BytesToRead ; byte [ ] buffer = new byte [ bytes ] ; _serialPort . Read ( buffer , 0 , bytes ) ; String [ ] output = ByteToHex( buffer ) ; process ( output ) ; check_oke ( output ) ; } private void check_oke ( String [ ] output ) { bytes_rec = output ; toggle = true ; } public Boolean rec_oke ( int loops = −1) { int status = 0 ; int i = 0 ; while ( true ) { while ( loops != i ) { 123 if ( toggle ) { foreach ( String data in bytes_rec ) { 128 133 138 143 if ( status == 0 ) { if ( data == "4F" ) { status = 1 ; } } else if ( status == 1 ) { if ( data == "4F" ) { status = 1 ; } else if ( data == "4B" ) { status = 2 ; 49 } else { 148 status = 0 ; } } else { 153 status = 0 ; toggle = false ; return true ; } } bytes_rec = null ; toggle = false ; 158 } i++; } return false ; 163 } } 168 173 178 int status = 0 ; string length = "" ; int aantal ; int sourceaddress ; int aantalSamples ; char [ ] actieveKanalen = null ; Boolean A0 ; Boolean A1 ; Boolean A2 ; Boolean A3 ; Boolean A4 ; Boolean A5 ; Boolean D ; int regelspersample ; int i ; Boolean byteTypeIsMsb ; 183 private void process ( String [ ] input ) { foreach ( String bytje in input ) { 188 193 switch ( status ) { case 0 : // start byte if ( bytje == "7E" ) { status++; } break ; case 1 : // lengte in bytes msb 50 198 203 208 213 218 223 228 233 238 243 248 length = bytje ; status++; break ; case 2 : // lengte in bytes lsb length = length+bytje ; aantal = Convert . ToInt32 ( length , 1 6 ) ; status++; break ; case 3 : // api start if ( bytje == "83" ) { status++; } else { status = 0 ; } break ; case 4 : // source in bytes msb aantal−−; length = bytje ; status++; break ; case 5 : // source in bytes lsb aantal−−; length = length + bytje ; sourceaddress = Convert . ToInt32 ( length , 1 6 ) ; status++; break ; case 6 : // RSSI aantal−−; status++; break ; case 7 : // option byte aantal−−; status++; break ; case 8 : // aantal samples aantal−−; aantalSamples = Convert . ToInt32 ( bytje , 1 6 ) ; status++; break ; case 9 : // active kanalen in bytes msb aantal−−; length = bytje ; status++; break ; case 1 0 : // active kanalen in bytes lsb aantal−−; length = length + bytje ; int tmp2 = Convert . ToInt32 ( length , 1 6 ) ; String tmp = Convert . ToString ( tmp2 , 2 ) ; tmp = tmp . PadLeft ( 1 6 , Convert . ToChar ( "0" ) ) ; 51 253 258 263 268 273 278 283 288 293 298 303 actieveKanalen = tmp . ToCharArray ( ) ; regelspersample = 0 ; if ( actieveKanalen [ 1 ] == Convert . ToChar ( "1" ) ) { A5 = true ; regelspersample++; } else { A5 = false ; } if ( actieveKanalen [ 2 ] == Convert . ToChar ( "1" ) ) { A4 = true ; regelspersample++; } else { A4 = false ; } if ( actieveKanalen [ 3 ] == Convert . ToChar ( "1" ) ) { A3 = true ; regelspersample++; } else { A3 = false ; } if ( actieveKanalen [ 4 ] == Convert . ToChar ( "1" ) ) { A2 = true ; regelspersample++; } else { A2 = false ; } if ( actieveKanalen [ 5 ] == Convert . ToChar ( "1" ) ) { A1 = true ; regelspersample++; } else { A1 = false ; } if ( actieveKanalen[6]== Convert . ToChar ( "1" ) ) { A0 = true ; 52 regelspersample++; } else { 308 A0 = false ; } 313 318 323 328 333 338 343 348 regelspersample++; if ( actieveKanalen [ 7 ] == Convert . ToChar ( "1" ) ) { D = true ; } else if ( actieveKanalen [ 8 ] == Convert . ToChar ( "1" ) ) { D = true ; } else if ( actieveKanalen [ 9 ] == Convert . ToChar ( "1" ) ) { D = true ; } else if ( actieveKanalen [ 1 0 ] == Convert . ToChar ( "1" )) { D = true ; } else if ( actieveKanalen [ 1 1 ] == Convert . ToChar ( "1" )) { D = true ; } else if ( actieveKanalen [ 1 2 ] == Convert . ToChar ( "1" )) { D = true ; } else if ( actieveKanalen [ 1 3 ] == Convert . ToChar ( "1" )) { D = true ; } else if ( actieveKanalen [ 1 4 ] == Convert . ToChar ( "1" )) { D = true ; } else if ( actieveKanalen [ 1 5 ] == Convert . ToChar ( "1" )) { D = true ; } else 53 { D = false ; regelspersample −−; } 353 status++; byteTypeIsMsb = true ; i = regelspersample ; break ; case 1 1 : if ( i == 0 ) { i = regelspersample ; aantalSamples −−; } if ( aantalSamples != 0 ) { Console . WriteLine ( " aantalSamples: " + aantalSamples + " - regelspersample: " + regelspersample + " i: " + i + " byteTypeIsMsb: " + byteTypeIsMsb + " length : " + length ) ; if ( byteTypeIsMsb ) { length = bytje ; byteTypeIsMsb = false ; } else { length = length + bytje ; Send_data_to_php ( length , i , sourceaddress ); byteTypeIsMsb = true ; i−−; } } else { status++; } break ; default : status = 0 ; break ; 358 363 368 373 378 383 388 } } 393 } private void excute_php ( string text ) { System . Diagnostics . ProcessStartInfo oInfo = new System . Diagnostics . ProcessStartInfo ( "c:/ wamp/ bin/ php/ php5 .3.0/ php . exe" , "-f c:/ wamp/www/"+text ) ; 54 oInfo . UseShellExecute = false ; oInfo . ErrorDialog = false ; oInfo . CreateNoWindow = true ; oInfo . RedirectStandardOutput = true ; 398 try { Process p = System . Diagnostics . Process . Start ( oInfo ) ; p . Close ( ) ; 403 } catch ( Exception x ) { 408 } } 413 418 423 428 433 438 private void Send_data_to_php ( string text , int j , int source ) { if ( D ) { if ( j == regelspersample ) { // Console .Write (" Digitaal: "); excute_php ( "c. php source =" + source + " signaal_type= D value=" + text ) ; } else { // Console .Write (" Analoog " + ( regelspersample -j -1) + ": "); excute_php ( "c. php source =" + source + " signaal_type= A deel=" + ( regelspersample − j − 1 ) + " value=" + text ) ; } } else { // Console . Write (" Analoog " + ( regelspersample - j) + ": "); excute_php ( "c.php source =" + source + " signaal_type=A deel=" + ( regelspersample − j ) + " value=" + text ) ; } // Console . WriteLine( text); } public void send_aan ( int destination ) { int j = 0 ; do 55 { _serialPort . Write ( "+++" ) ; j++; 443 } while ( ! rec_oke ( 9 9 9 9 9 9 9 9 9 ) && j < 2 ) ; 448 do { _serialPort . Write ( "ATDL " + destination + Convert . ToString ( ( char ) 1 3 ) ) ; j++; } while ( ! rec_oke ( 9 9 9 9 9 9 9 9 9 ) ) ; 453 do { _serialPort . Write ( "ATCN" + Convert . ToString ( ( char ) 1 3 ) ) ; 458 } while ( ! rec_oke ( 9 9 9 9 9 9 9 9 9 ) ) ; _serialPort . Write ( Convert . ToString ( ( char ) ( byte ) 1 0 2 ) ) ; 463 Console . WriteLine ( " AAN"+destination ) ; } 468 473 478 public void send_uit ( int destination ) { int j = 0 ; do { _serialPort . Write ( "+++" ) ; j++; } while ( ! rec_oke ( 9 9 9 9 9 9 9 9 9 ) && j < 2 ) ; do {; _serialPort . Write ( "ATDL " + destination + Convert . ToString ( ( char ) 1 3 ) ) ; j++; 483 } while ( ! rec_oke ( 9 9 9 9 9 9 9 9 9 ) ) ; do { _serialPort . Write ( "ATCN" + Convert . ToString ( ( char ) 1 3 ) ) ; 488 } while ( ! rec_oke ( 9 9 9 9 9 9 9 9 9 ) ) ; _serialPort . Write ( Convert . ToString ( ( char ) ( byte ) 2 4 ) ) ; 56 493 Console . WriteLine ( " UIT" + destination ) ; } private String [ ] ByteToHex ( byte [ ] comByte ) { // create a new StringBuilder object // StringBuilder builder = new StringBuilder( comByte . Length * 3); // loop through each byte in the array String [ ] output = new String [ comByte . Length ] ; int i = 0 ; foreach ( byte data in comByte ) { // convert the byte to a string and add to the stringbuilder output [ i ] = Convert . ToString ( data , 1 6 ) . PadLeft ( 2 , ’0’ ) . ToUpper ( ) ; 498 503 508 i++; } return output ; } 513 } } 57