{"id":383,"date":"2016-02-11T11:17:25","date_gmt":"2016-02-11T11:17:25","guid":{"rendered":"http:\/\/www.xn--nrdoteket-l8a.dk\/?p=383"},"modified":"2017-06-23T10:01:39","modified_gmt":"2017-06-23T10:01:39","slug":"383","status":"publish","type":"post","link":"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/","title":{"rendered":"G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019"},"content":{"rendered":"<blockquote><p>VIGTIGT: L\u00c6S DETTE, f\u00f8r du beslutter dig for at bygge noget i denne retning. Denne enhed forbindes direkte til 230V, hvilket er livsfarligt at rode med! Jeg joker ikke \u2013 Det g\u00f8r i bedste fald p*sseondt at f\u00e5 st\u00f8d, og i v\u00e6rste fald D\u00d8R du af det. Du kan starte en brand og det kan man ogs\u00e5 D\u00d8 af! Du b\u00f8r ikke rode med netsp\u00e6nding uden et minimum af viden&amp;erfaring.<\/p><\/blockquote>\n<p>I de forl\u00f8bne tre klummer har vi specificeret hvad vi vil have at enheden skal kunne g\u00f8re. Vi har foretaget nogle valg, og vi har forberedt vores raspberry pi til at virke i den kontekst som vores produkt skal. Senest har vi loddet noget hardware sammen. Vigtigst af alt: Jeg har overlevet. Ingen st\u00f8d og software-frustrationerne har ikke v\u00e6ret af en s\u00e5 alvorlig karakter at det har kunnet f\u00e5 mig til at hoppe ud af vinduet. Success!<\/p>\n<p>Denne fjerde og sidste del af serien vil handle om selve den software vi skal skrive for at implementere vores API og for at kunne manipulere med GPIO pindene.<\/p>\n<p><!--more Klik HER for at l\u00e6se mere--><\/p>\n<p>Jeg afslutter artiklen med en lille demo.<\/p>\n<p>F\u00f8rst skal vi lige have afklaret cliff-hangeren fra sidste del, og se det f\u00e6rdige produkt. Her er dimsen i al sin glov\u00e6rdighed:<\/p>\n<p><a href=\"http:\/\/www.n\u00f8rdoteket.dk\/wp-content\/uploads\/2016\/02\/dimsen.png\" rel=\"attachment wp-att-350\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-350 aligncenter\" src=\"http:\/\/www.n\u00f8rdoteket.dk\/wp-content\/uploads\/2016\/02\/dimsen.png\" alt=\"dimsen\" width=\"806\" height=\"1075\" srcset=\"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/dimsen.png 806w, https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/dimsen-225x300.png 225w, https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/dimsen-768x1024.png 768w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/a><\/p>\n<p>Ikke det mest sexede design, men som ingeni\u00f8r er jeg fokuseret p\u00e5 funktion frem for design, og det v\u00e6sentligste funktionelle krav, at minimere risikoen for at jeg d\u00f8r af elektrisk st\u00f8d, er opfyldt.<\/p>\n<p><script async src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js\"><\/script>\r\n<!-- wp-inpost-add -->\r\n<ins class=\"adsbygoogle\"\r\n     style=\"display:block\"\r\n     data-ad-client=\"ca-pub-7793103161450012\"\r\n     data-ad-slot=\"1741650889\"\r\n     data-ad-format=\"auto\"><\/ins>\r\n<script>\r\n(adsbygoogle = window.adsbygoogle || []).push({});\r\n<\/script><br \/>\nMen hvad er dog det for to underlige huller i frontpladen? Det er et klassisk eksempel p\u00e5 konsekvensen af at man ikke t\u00e6nker sig om. Jeg skulle montere Raspberry pi\u2019en i kassen og sad og pr\u00f8vede alle mulige kombinationer. Det var p\u00e5 den forkerte side af kl. 23.00 en hverdagsaften, og jeg havde sat mig et m\u00e5l om at kassen skulle v\u00e6re f\u00e6rdigmonteret f\u00f8r jeg gik i seng. Jeg fandt den optimale placering, t\u00e6nkte \u2019Yes!\u2019, greb boremaskinen og borede to huller til skruerne. S\u00e5 vendte jeg boksen om\u2026 og sprang direkte til sidste del af punkt 5 i hardware opskriften fra sidste <a href=\"http:\/\/www.n\u00f8rdoteket.dk\/index.php\/2016\/02\/10\/test-del3\/\" target=\"_blank\" rel=\"noopener\">afsnit<\/a>:<\/p>\n<p>&nbsp;<\/p>\n<p>N\u00e5 heldigvis er skaden ikke s\u00e5 stor, da jeg alligevel har t\u00e6nkt mig at s\u00e6tte en lille rekvalme p\u00e5 fronten af boksen som kommer til at d\u00e6kke over det.<\/p>\n<p><a href=\"http:\/\/www.n\u00f8rdoteket.dk\/wp-content\/uploads\/2016\/02\/final_product.png\" rel=\"attachment wp-att-387\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-387\" src=\"http:\/\/www.n\u00f8rdoteket.dk\/wp-content\/uploads\/2016\/02\/final_product.png\" alt=\"final_product\" width=\"750\" height=\"1000\" srcset=\"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/final_product.png 750w, https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/final_product-225x300.png 225w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/a><\/p>\n<p>Apple, go home!<\/p>\n<p>Nu skal der kodes! F\u00f8rst laver jeg et lille script som skal styre status-LED\u2019en. Som I m\u00e5ske husker s\u00e5 fandt jeg en RGB LED i skuffen, og kan dermed lave masser af farver. Det giver mulighed for at signalere en masse forskellige ting (system ok, men wifi ikke forbundet, forkert wpa key, intern temperatur for h\u00f8j, etc.), men jeg v\u00e6lger at v\u00e6re lidt primitiv og blot implementere r\u00f8d (= fejl\/ikke forbundet til internettet) og gr\u00f8n (=hvad tror du selv?). Mere fancy funktionalitet m\u00e5 skydes til version2.<\/p>\n<p>Scriptet skriver jeg i python (Den komplette kildekode finder du her: <a href=\"http:\/\/www.n\u00f8rdoteket.dk\/index.php\/gds-iot-kildekode-status-py\/\" target=\"_blank\" rel=\"noopener\">http:\/\/www.n\u00f8rdoteket.dk\/index.php\/2016\/02\/06\/gds-iot-kildekode-til\/<\/a>)<\/p>\n<p>Virkem\u00e5den er, at jeg bestemmer netv\u00e6rkets default gateway, som er routerens IP adresse. I et uendeligt loop pinger jeg den IP adresse, og hvis der er svar s\u00e6tter jeg LED til gr\u00f8n, og hvis der ikke er svar s\u00e6tter jeg LED til r\u00f8d.<\/p>\n<p>Koden er ganske simpel og python er dejlig nemt at bruge. I python bruger jeg RPi.GPIO biblioteket til at kontrollere GPIO pins. LED\u2019en er forbundet til GPIO#9, 10 og 11 (Gr\u00f8n, Bl\u00e5, R\u00f8d). GPIO skal initialiseres som enten input eller output pins:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nGPIO.setmode(GPIO.BCM) # Use Broadcom pin numbers\r\nGPIO.setup(9, GPIO.OUT) # Green LED, set as output\r\n<\/pre>\n<p>Og man t\u00e6nder for en pin ved at s\u00e6tte den til HIGH:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nGPIO.output(9, GPIO.HIGH) # LED on\r\nGPIO.output(9, GPIO.LOW) # LED off\r\n<\/pre>\n<p>Det prim\u00e6re loop, hvor jeg pinger ser s\u00e5ledes ud:<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">\r\nwhile True: # infinite loop\r\n    response = os.system(&quot;ping -c 1 &quot; + hostname) # send one ICMP packet to host\r\n    if response == 0: # Reply\r\n        # Network is reachable, LED=Green\r\n        GPIO.output(11, GPIO.LOW)\r\n        GPIO.output(9, GPIO.HIGH)\r\n    else: # No reply\r\n        # Network is NOT reachable, LED=Red\r\n        GPIO.output(11, GPIO.HIGH)\r\n        GPIO.output(9, GPIO.LOW)\r\n<\/pre>\n<p>Dette program skal k\u00f8re automatisk ved boot, og derfor skal det tilf\u00f8jes rc.local:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nrpi_admin@skarpline-iot:~ $ sudo nano \/etc\/rc.local\r\n<\/pre>\n<p>Tilf\u00f8j \u201d \/home\/rpi_admin\/status.py &gt; \/dev\/null\u201d til filen (husk at tilpasse home dir navn til din bruger, eller hvor du nu m\u00e5tte l\u00e6gge status.py filen), s\u00e5 det endelige resultat ser s\u00e5ledes ud:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n#!\/bin\/sh -e\r\n#\r\n# rc.local\r\n#\r\n# This script is executed at the end of each multiuser runlevel.\r\n# Make sure that the script will &quot;exit 0&quot; on success or any other\r\n# value on error.\r\n#\r\n# In order to enable or disable this script just change the execution\r\n# bits.\r\n#\r\n# By default this script does nothing.\r\n\r\n\/home\/rpi_admin\/status.py &gt; \/dev\/null\r\n\r\n# Print the IP address\r\n_IP=$(hostname -I) || true\r\nif &#x5B; &quot;$_IP&quot; ]; then\r\n  printf &quot;My IP address is %s\\n&quot; &quot;$_IP&quot;\r\nfi\r\n\r\nexit 0\r\n <\/pre>\n<p>Med denne metode vil lampen lyse gr\u00f8nt s\u00e5 l\u00e6nge routeren svarer, selv hvis der ikke er forbindelse til internettet. Hvis man udskifter default gateway med noget ude p\u00e5 internettet, f.eks. Google\u2019s DNS server 8.8.8.8, er testen mere retvisende. Det undlader jeg personligt at g\u00f8re, da det ikke er god stil at lave noget der kontinuerligt st\u00e5r og generer trafik mod andre menneskers servere.<br \/>\n<script async src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js\"><\/script>\r\n<!-- wp-inpost-add -->\r\n<ins class=\"adsbygoogle\"\r\n     style=\"display:block\"\r\n     data-ad-client=\"ca-pub-7793103161450012\"\r\n     data-ad-slot=\"1741650889\"\r\n     data-ad-format=\"auto\"><\/ins>\r\n<script>\r\n(adsbygoogle = window.adsbygoogle || []).push({});\r\n<\/script><br \/>\nNu til selve koden der implementerer API\u2019et. Den komplette kildekode finder du her: <a href=\"http:\/\/www.n\u00f8rdoteket.dk\/index.php\/gds-iot-kildekode-control-php\/\" target=\"_blank\" rel=\"noopener\">http:\/\/www.n\u00f8rdoteket.dk\/index.php\/2016\/02\/06\/gds-iot-kildekode\/<\/a>.<\/p>\n<p>Det foreg\u00e5r som en webservice, og derfor er det f\u00f8rste vi skal g\u00f8re, at validere brugeren. Det g\u00f8res med HTTP Digest (RFC-2617), og derfor starter vi med at afvise alle requests til vores server, der ikke har authentication information med i headeren. Vi afviser med en \u201d<a href=\"https:\/\/httpstatuses.com\/401\" target=\"_blank\" rel=\"noopener\">http 401 \/ unauthorized\u201d-header<\/a>, og tilf\u00f8jer en unik v\u00e6rdi, kaldet et \u201dnonce\u201d (L\u00f8st oversat: en engangs-term).<\/p>\n<p><a href=\"http:\/\/www.n\u00f8rdoteket.dk\/wp-content\/uploads\/2016\/02\/digest_process.png\" rel=\"attachment wp-att-349\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-349 aligncenter\" src=\"http:\/\/www.n\u00f8rdoteket.dk\/wp-content\/uploads\/2016\/02\/digest_process.png\" alt=\"digest_process\" width=\"595\" height=\"544\" srcset=\"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/digest_process.png 595w, https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/digest_process-300x274.png 300w\" sizes=\"auto, (max-width: 595px) 85vw, 595px\" \/><\/a><\/p>\n<p>Kigger vi i TCP pakkerne (med wireshark \u2013 hvis du ikke har pr\u00f8vet det endnu, s\u00e5 er det p\u00e5 h\u00f8je tide. Fantastisk og helt uundv\u00e6rligt v\u00e6rkt\u00f8j!) ser det s\u00e5ledes ud:<br \/>\n<script async src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js\"><\/script>\r\n<!-- wp-inpost-add -->\r\n<ins class=\"adsbygoogle\"\r\n     style=\"display:block\"\r\n     data-ad-client=\"ca-pub-7793103161450012\"\r\n     data-ad-slot=\"1741650889\"\r\n     data-ad-format=\"auto\"><\/ins>\r\n<script>\r\n(adsbygoogle = window.adsbygoogle || []).push({});\r\n<\/script><br \/>\n<a href=\"http:\/\/www.n\u00f8rdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_mangler_i_header.png\" rel=\"attachment wp-att-353\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-353\" src=\"http:\/\/www.n\u00f8rdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_mangler_i_header.png\" alt=\"http_digest_mangler_i_header\" width=\"1291\" height=\"994\" srcset=\"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_mangler_i_header.png 1291w, https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_mangler_i_header-300x231.png 300w, https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_mangler_i_header-768x591.png 768w, https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_mangler_i_header-1024x788.png 1024w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/a><\/p>\n<p>R\u00f8d tekst er request fra klient. Bl\u00e5 tekst er svaret fra GDS-IOT dimsen.<br \/>\nOg i koden ser det s\u00e5ledes ud:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nif (empty($_SERVER&#x5B;'PHP_AUTH_DIGEST'])) {\r\n  header('HTTP\/1.1 401 Unauthorized');\r\n    header('WWW-Authenticate: Digest realm=&quot;'.$realm.\r\n     '&quot;,qop=&quot;auth&quot;,nonce=&quot;'.uniqid().'&quot;,opaque=&quot;'.md5($realm).'&quot;');\r\n \r\n  die('UNAUTHORIZED');\r\n  }\r\n<\/pre>\n<p>$_SERVER er php\u2019s reserverede variabel der indeholder al den information som er med i det request der er modtaget (http:\/\/php.net\/manual\/en\/reserved.variables.server.php).<\/p>\n<p>Nonce genereres med php\u2019s uniqid( ) funktion, der genererer en unik streng, baseret p\u00e5 tidspunktet for requestet (hvis man sender det samme hver gang er man s\u00e5rbar for playback-angreb).<\/p>\n<p>Hvis vi nu s\u00f8rger for at sende en request header med korrekt authorization information, kan vi se at vi f\u00e5r det \u00f8nskede svar (og en http 200 \/ ok-header).<\/p>\n<p><a href=\"http:\/\/www.n\u00f8rdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_med_i_header.png\" rel=\"attachment wp-att-354\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-354\" src=\"http:\/\/www.n\u00f8rdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_med_i_header.png\" alt=\"http_digest_med_i_header\" width=\"1309\" height=\"1007\" srcset=\"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_med_i_header.png 1309w, https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_med_i_header-300x231.png 300w, https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_med_i_header-768x591.png 768w, https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/http_digest_med_i_header-1024x788.png 1024w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/a><\/p>\n<p>Der er en del information i det svar, som vi lige skal gennemg\u00e5. F\u00f8rst skal vi sikre, at klienten har sendt alle de n\u00f8dvendige data. Det g\u00f8res ved at parse PHP_AUTH_DIGEST variablen.<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n\/\/ analyze the PHP_AUTH_DIGEST variable\r\nif (!($data = http_digest_parse($_SERVER&#x5B;'PHP_AUTH_DIGEST'])) ||\r\n    !isset($users&#x5B;$data&#x5B;'username']]))\r\n      die('WRONG_CREDENTIALS');\r\n<\/pre>\n<p>Dern\u00e6st beregnes det response som vi forventer at f\u00e5, hvis ellers afsenderen har brugt korrekt brugernavn og password. Det foreg\u00e5r i HTTP Digest ved at tage et MD5 hash af informationerne (som beskrevet i RFC-2617, \u00a73.2.2).<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n\/\/ generate the valid response\r\n$A1 = md5($data&#x5B;'username'] . ':' . $realm . ':' . $users&#x5B;$data&#x5B;'username']]);\r\n$A2 = md5($_SERVER&#x5B;'REQUEST_METHOD'].':'.$data&#x5B;'uri']);\r\n$valid_response = md5($A1.':'.$data&#x5B;'nonce'].':'.$data&#x5B;'nc'].':'.$data&#x5B;'cnonce'].':'.$data&#x5B;'qop'].':'.$A2);\r\n<\/pre>\n<p>Og sluttelig tjekker vi om det modtagne response svarer det det vi selv har beregnet.<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\"> \r\nif ($data&#x5B;'response'] != $valid_response)\r\n  die('WRONG_CREDENTIALS');\r\n <\/pre>\n<p><script async src=\"https:\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js\"><\/script>\r\n<!-- wp-ad-rect -->\r\n<ins class=\"adsbygoogle\"\r\n     style=\"display:block\"\r\n     data-ad-client=\"ca-pub-7793103161450012\"\r\n     data-ad-slot=\"8706514482\"\r\n     data-ad-format=\"auto\"><\/ins>\r\n<script>\r\n     (adsbygoogle = window.adsbygoogle || []).push({});\r\n<\/script><br \/>\nNu er brugeren valideret, og vi skal se hvad der bliver bedt om i requestet. N\u00e5r man skal levere information i et \u201dhttp\/get\u201d g\u00f8res det i URL\u2019en med \u201dparameter=v\u00e6rdi\u201d par. I PHP l\u00e6ses parametrene med $_GET[\u2019parameter\u2019]:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\"> $action = $_GET&#x5B;'action']; $port = $_GET&#x5B;'device']; <\/pre>\n<p>Device skal mappes til den korrekte GPIO port, og vi skal sikre, at der ikke sp\u00f8rges efter et ugyldigt device. Det g\u00f8res med en switch statement:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nswitch ($port)\r\n{\r\ncase 1:\r\n    $portreal=&quot;27&quot;; \/\/ Device#1 maps to GPIO#27\r\n    break;\r\ncase 2:\r\n    $portreal=&quot;17&quot;; \/\/ Device#2 maps to GPIO#17\r\n    break;\r\ndefault:\r\n    die('INVALID_DEVICE');\r\n    break;\r\n}\r\n<\/pre>\n<p>Endelig, efter s\u00e5 megen skriveri, lodderi og koderi, er vi n\u00e5et til kernen i det hele: Bliver vi bedt om at t\u00e6nde eller slukke for et str\u00f8mudtag. Det tjekker vi ogs\u00e5 med en switch statement:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nswitch($action)\r\n{\r\ncase \u2019ON\u2019: \/\/ Vi vil t\u00e6nde\r\n  ..t\u00e6nd for device\r\ncase \u2019OFF\u2019: \/\/ Vi vil slukke\r\n  ..sluk for device\r\ncase \u2019STATUS\u2019:\r\n  ..returner om der er t\u00e6ndt eller slukket\r\n}\r\n<\/pre>\n<p>Selve interaktionen med GPIO pins foretager vi med WiringPi som blev installeret i del2 (link til del2). WiringPi er et lib til shell kommandoer, hvilket vil side, at vi fra PHP skal lave et systemkald. Det kan g\u00f8res med shell_exec kommandoen (hvor $portreal= 17 eller 27):<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n    $gpio_on = shell_exec(&quot;\/usr\/local\/bin\/gpio -g write &quot; . $portreal . &quot; 1&quot;); \/\/ Turn on the desired GPIO\r\n    $gpio_stat = shell_exec(&quot;\/usr\/local\/bin\/gpio -g read &quot; . $portreal); \/\/ Read status of port\r\n<\/pre>\n<p><script async src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js\"><\/script>\r\n<!-- wp-inpost-add -->\r\n<ins class=\"adsbygoogle\"\r\n     style=\"display:block\"\r\n     data-ad-client=\"ca-pub-7793103161450012\"\r\n     data-ad-slot=\"1741650889\"\r\n     data-ad-format=\"auto\"><\/ins>\r\n<script>\r\n(adsbygoogle = window.adsbygoogle || []).push({});\r\n<\/script><br \/>\nHermed er projektet n\u00e5et til sin ende. Egentlig imponerende hvor meget jeg kan skrive om s\u00e5 lidt, og stadig have fornemmelsen af kun lige have ridset overfladen!<\/p>\n<p>Men vi skal da lige have demonstreret dimsen \u2013 ellers tror I bare ikke p\u00e5 at den virker. Det er lidt sv\u00e6rt at g\u00f8re p\u00e5 skrift, s\u00e5 jeg har bikset en lille video sammen til jer.<\/p>\n<p>Med reference til det f\u00f8rste afsnit (link til del 1) s\u00e5 er det elektriske apparat som skal testes selvf\u00f8lgelig den obligatoriske kaffemaskine. Problemet er blot, at min kaffemaskine er en fancy sag, som kr\u00e6ver tryk p\u00e5 en knap for at brygge en kop kaffe.<\/p>\n<p>Hvordan klarer jeg nu det problem? Et helt nyt projekt begynder at forme sig i mit hovede: Et legot\u00e5rn, en servo, en afhugget finger. Argh, stop! Jeg bliver aldrig f\u00e6rdig med at skrive, og Computerworld l\u00f8ber t\u00f8r for anslag, s\u00e5 nu holder jeg mund.<\/p>\n<p>Sig goddag til Steens k\u00e6lderlab, se en demo af GDS-IOT dimsen og ikke mindst, se hvordan jeg l\u00f8ste problemet med at trykke p\u00e5 kaffemaskinens knap <a href=\"https:\/\/youtu.be\/kb91z_gWMWE\" target=\"_blank\" rel=\"noopener\">her<\/a>.<\/p>\n<p>H\u00e5ber I har nydt at l\u00e6se serien. Jeg har lavet og laver mange af denne slags sm\u00e5projekter, men det er f\u00f8rste gang jeg har pr\u00f8vet at beskrive det i detaljer p\u00e5 denne m\u00e5de. Er der interesse for lignende beskrivelser i fremtiden, s\u00e5 skriv det gerne i kommentarfeltet nedenunder.<\/p>\n<p>Al kildekode finder I som sagt her: <a href=\"http:\/\/www.n\u00f8rdoteket.dk\/index.php\/2016\/02\/06\/gds-iot-kildekode\/\" target=\"_blank\" rel=\"noopener\">http:\/\/www.n\u00f8rdoteket.dk\/index.php\/2016\/02\/06\/gds-iot-kildekode\/<\/a> og den st\u00e5r til fri afbenyttelse i henhold til revision 42 af Beer-ware licensen (en af mange geniale ting fra <a href=\"http:\/\/phk.freebsd.dk\/\" target=\"_blank\" rel=\"noopener\">phk\u2019s<\/a> h\u00e5nd).<br \/>\n<script async src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js\"><\/script>\r\n<!-- wp-inpost-add -->\r\n<ins class=\"adsbygoogle\"\r\n     style=\"display:block\"\r\n     data-ad-client=\"ca-pub-7793103161450012\"\r\n     data-ad-slot=\"1741650889\"\r\n     data-ad-format=\"auto\"><\/ins>\r\n<script>\r\n(adsbygoogle = window.adsbygoogle || []).push({});\r\n<\/script><br \/>\n<strong>Hvis jeg havde mere tid<\/strong><br \/>\nHvis nu man ville lege videre med udgangspunkt i denne dims:<br \/>\nHardware:<br \/>\n&#8211; Flere udtag<br \/>\no Det kommer an p\u00e5 dit behov. Det er s\u00e6rdeles nemt at udvide med flere, det koster blot en stikkontakt og et rel\u00e6 samt driver kredsl\u00f8b per stk.<br \/>\n&#8211; M\u00e5ling af effektforbrug per udtag<br \/>\no Det kunne v\u00e6re sjovt at lege med. Kr\u00e6ver en str\u00f8msensor per udtag. Output fra str\u00f8msensorer er typisk analoge, s\u00e5 en ADC (analog til digital konverter) skal bruges per str\u00f8mudtag. Eller man kunne overveje at skifte Raspberry Pi ud med en anden platform der allerede har ADC kanaler.<br \/>\n&#8211; Mulighed for at lysd\u00e6mpe en lampe tilsluttet et udtag<br \/>\no M\u00e5ske ikke s\u00e5 relevant ved en str\u00f8mskinne?<br \/>\n&#8211; Skrumpning af design, s\u00e5 det kan skohornes ind i en str\u00f8mskinne.<br \/>\n&#8211; L\u00e6g print ud og lav det hele fra bunden, bedre, billigere og mindre.<br \/>\n&#8211; Andre forslag?<br \/>\nSoftware:<br \/>\n&#8211; Skriv en app til kontrol. Det er jo s\u00e5 moderne.<br \/>\n&#8211; Timerfunktion<br \/>\no Udvid API, s\u00e5 man kan sige \u201dt\u00e6nd device X, og sluk det automatisk om Y minutter\u201d<br \/>\n&#8211; \u2019Feriemode\u2019<br \/>\no Lav funktion som t\u00e6nder og slukker for de forskellige udtag p\u00e5 tilf\u00e6ldige tidspunkter<br \/>\n&#8211; WPS, s\u00e5 det er nemt at installere<br \/>\n&#8211; UPnP, s\u00e5 det er nemt at installere<br \/>\n&#8211; Andre forslag?<br \/>\n<script async src=\"https:\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js\"><\/script>\r\n<!-- wp-ad-rect -->\r\n<ins class=\"adsbygoogle\"\r\n     style=\"display:block\"\r\n     data-ad-client=\"ca-pub-7793103161450012\"\r\n     data-ad-slot=\"8706514482\"\r\n     data-ad-format=\"auto\"><\/ins>\r\n<script>\r\n     (adsbygoogle = window.adsbygoogle || []).push({});\r\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>VIGTIGT: L\u00c6S DETTE, f\u00f8r du beslutter dig for at bygge noget i denne retning. Denne enhed forbindes direkte til 230V, hvilket er livsfarligt at rode med! Jeg joker ikke \u2013 Det g\u00f8r i bedste fald p*sseondt at f\u00e5 st\u00f8d, og i v\u00e6rste fald D\u00d8R du af det. Du kan starte en brand og det kan &hellip; <a href=\"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/\" class=\"more-link\">L\u00e6s videre<span class=\"screen-reader-text\"> &#8220;G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":522,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[45,127,53],"tags":[],"class_list":["post-383","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-diverse","category-goer-det-selv","category-tipsticks"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019 - N\u00f8rd&#039;o&#039;teket<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/\" \/>\n<meta property=\"og:locale\" content=\"da_DK\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019 - N\u00f8rd&#039;o&#039;teket\" \/>\n<meta property=\"og:description\" content=\"VIGTIGT: L\u00c6S DETTE, f\u00f8r du beslutter dig for at bygge noget i denne retning. Denne enhed forbindes direkte til 230V, hvilket er livsfarligt at rode med! Jeg joker ikke \u2013 Det g\u00f8r i bedste fald p*sseondt at f\u00e5 st\u00f8d, og i v\u00e6rste fald D\u00d8R du af det. Du kan starte en brand og det kan &hellip; L\u00e6s videre &quot;G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019&quot;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/\" \/>\n<meta property=\"og:site_name\" content=\"N\u00f8rd&#039;o&#039;teket\" \/>\n<meta property=\"article:published_time\" content=\"2016-02-11T11:17:25+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-06-23T10:01:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/Internet_of_things_signed_by_the_author.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"768\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Steen Garbers Enevoldsen\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Skrevet af\" \/>\n\t<meta name=\"twitter:data1\" content=\"Steen Garbers Enevoldsen\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimeret l\u00e6setid\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutter\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/\",\"url\":\"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/\",\"name\":\"G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019 - N\u00f8rd&#039;o&#039;teket\",\"isPartOf\":{\"@id\":\"https:\/\/noerdoteket.dk\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/Internet_of_things_signed_by_the_author.jpg\",\"datePublished\":\"2016-02-11T11:17:25+00:00\",\"dateModified\":\"2017-06-23T10:01:39+00:00\",\"author\":{\"@id\":\"https:\/\/noerdoteket.dk\/#\/schema\/person\/8ce5cde334be233f967af616016bb204\"},\"breadcrumb\":{\"@id\":\"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/#breadcrumb\"},\"inLanguage\":\"da-DK\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"da-DK\",\"@id\":\"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/#primaryimage\",\"url\":\"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/Internet_of_things_signed_by_the_author.jpg\",\"contentUrl\":\"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/Internet_of_things_signed_by_the_author.jpg\",\"width\":1024,\"height\":768},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Hjem\",\"item\":\"https:\/\/noerdoteket.dk\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/noerdoteket.dk\/#website\",\"url\":\"https:\/\/noerdoteket.dk\/\",\"name\":\"N\u00f8rd&#039;o&#039;teket\",\"description\":\"L\u00f8st og fast om teknologi og dimser\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/noerdoteket.dk\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"da-DK\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/noerdoteket.dk\/#\/schema\/person\/8ce5cde334be233f967af616016bb204\",\"name\":\"Steen Garbers Enevoldsen\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"da-DK\",\"@id\":\"https:\/\/noerdoteket.dk\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/31c4fda78957be0bba5bc847b437e1a07f9953e3d93973672280800e8c1dcd34?s=96&d=wavatar&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/31c4fda78957be0bba5bc847b437e1a07f9953e3d93973672280800e8c1dcd34?s=96&d=wavatar&r=g\",\"caption\":\"Steen Garbers Enevoldsen\"},\"url\":\"https:\/\/noerdoteket.dk\/index.php\/author\/steenge\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019 - N\u00f8rd&#039;o&#039;teket","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/","og_locale":"da_DK","og_type":"article","og_title":"G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019 - N\u00f8rd&#039;o&#039;teket","og_description":"VIGTIGT: L\u00c6S DETTE, f\u00f8r du beslutter dig for at bygge noget i denne retning. Denne enhed forbindes direkte til 230V, hvilket er livsfarligt at rode med! Jeg joker ikke \u2013 Det g\u00f8r i bedste fald p*sseondt at f\u00e5 st\u00f8d, og i v\u00e6rste fald D\u00d8R du af det. Du kan starte en brand og det kan &hellip; L\u00e6s videre \"G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019\"","og_url":"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/","og_site_name":"N\u00f8rd&#039;o&#039;teket","article_published_time":"2016-02-11T11:17:25+00:00","article_modified_time":"2017-06-23T10:01:39+00:00","og_image":[{"width":1024,"height":768,"url":"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/Internet_of_things_signed_by_the_author.jpg","type":"image\/jpeg"}],"author":"Steen Garbers Enevoldsen","twitter_card":"summary_large_image","twitter_misc":{"Skrevet af":"Steen Garbers Enevoldsen","Estimeret l\u00e6setid":"11 minutter"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/","url":"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/","name":"G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019 - N\u00f8rd&#039;o&#039;teket","isPartOf":{"@id":"https:\/\/noerdoteket.dk\/#website"},"primaryImageOfPage":{"@id":"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/#primaryimage"},"image":{"@id":"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/#primaryimage"},"thumbnailUrl":"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/Internet_of_things_signed_by_the_author.jpg","datePublished":"2016-02-11T11:17:25+00:00","dateModified":"2017-06-23T10:01:39+00:00","author":{"@id":"https:\/\/noerdoteket.dk\/#\/schema\/person\/8ce5cde334be233f967af616016bb204"},"breadcrumb":{"@id":"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/#breadcrumb"},"inLanguage":"da-DK","potentialAction":[{"@type":"ReadAction","target":["https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/"]}]},{"@type":"ImageObject","inLanguage":"da-DK","@id":"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/#primaryimage","url":"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/Internet_of_things_signed_by_the_author.jpg","contentUrl":"https:\/\/noerdoteket.dk\/wp-content\/uploads\/2016\/02\/Internet_of_things_signed_by_the_author.jpg","width":1024,"height":768},{"@type":"BreadcrumbList","@id":"https:\/\/noerdoteket.dk\/index.php\/2016\/02\/11\/383\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Hjem","item":"https:\/\/noerdoteket.dk\/"},{"@type":"ListItem","position":2,"name":"G\u00f8r det selv-IOT: S\u00e5dan bygger du en dims der kan t\u00e6nde\/slukke for andre dimser over internettet \u2013 Del 4\/4: Softwaren og test af det endelige \u2019produkt\u2019"}]},{"@type":"WebSite","@id":"https:\/\/noerdoteket.dk\/#website","url":"https:\/\/noerdoteket.dk\/","name":"N\u00f8rd&#039;o&#039;teket","description":"L\u00f8st og fast om teknologi og dimser","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/noerdoteket.dk\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"da-DK"},{"@type":"Person","@id":"https:\/\/noerdoteket.dk\/#\/schema\/person\/8ce5cde334be233f967af616016bb204","name":"Steen Garbers Enevoldsen","image":{"@type":"ImageObject","inLanguage":"da-DK","@id":"https:\/\/noerdoteket.dk\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/31c4fda78957be0bba5bc847b437e1a07f9953e3d93973672280800e8c1dcd34?s=96&d=wavatar&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/31c4fda78957be0bba5bc847b437e1a07f9953e3d93973672280800e8c1dcd34?s=96&d=wavatar&r=g","caption":"Steen Garbers Enevoldsen"},"url":"https:\/\/noerdoteket.dk\/index.php\/author\/steenge\/"}]}},"_links":{"self":[{"href":"https:\/\/noerdoteket.dk\/index.php\/wp-json\/wp\/v2\/posts\/383","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/noerdoteket.dk\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/noerdoteket.dk\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/noerdoteket.dk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/noerdoteket.dk\/index.php\/wp-json\/wp\/v2\/comments?post=383"}],"version-history":[{"count":14,"href":"https:\/\/noerdoteket.dk\/index.php\/wp-json\/wp\/v2\/posts\/383\/revisions"}],"predecessor-version":[{"id":1387,"href":"https:\/\/noerdoteket.dk\/index.php\/wp-json\/wp\/v2\/posts\/383\/revisions\/1387"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/noerdoteket.dk\/index.php\/wp-json\/wp\/v2\/media\/522"}],"wp:attachment":[{"href":"https:\/\/noerdoteket.dk\/index.php\/wp-json\/wp\/v2\/media?parent=383"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/noerdoteket.dk\/index.php\/wp-json\/wp\/v2\/categories?post=383"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/noerdoteket.dk\/index.php\/wp-json\/wp\/v2\/tags?post=383"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}