Internet of Things/Protocollen/Opdrachten
Voorbeeld-toepassing
Het uitgangspunt voor de onderstaande opdrachten is een voorbeeld-toepassing, met de volgende onderdelen:
- Arduino: schakeling
- Arduino: software, zie: https://github.com/eelcodijkstra/iot2016/blob/master/arduinonode.ino - hierin aanpassen:
- naam van de MQTT-broker
- MAC-adres van het Ethernetshield
- NodeRed: zie de flow hieronder
- html-code voor templatenode
sensorcontrol
hierin: https://github.com/eelcodijkstra/iot2016/blob/master/sensorscontrol.html
- html-code voor templatenode
Code voor deze flow:
[{"id":"457bec38.889bc4","type":"http in","z":"6cc53a32.fd1454","name":"","url":"/sensorscontrol","method":"get","swaggerDoc":"","x":171,"y":80,"wires":[["760e2295.ab9bcc"]]}, {"id":"ed0ee5d0.c3bbd8","type":"http response","z":"6cc53a32.fd1454","name":"","x":585,"y":80,"wires":[]}, {"id":"760e2295.ab9bcc","type":"template","z":"6cc53a32.fd1454","name":"sensorscontrol","field":"payload","fieldType":"msg", "format":"handlebars","syntax":"mustache","template":"<!DOCTYPE html>\n<html>\n \n</html>","x":387,"y":80,"wires":[["ed0ee5d0.c3bbd8"]]}, {"id":"a6d179b1.25bf28","type":"websocket out","z":"6cc53a32.fd1454","name":"","server":"f496747.1a74188","client":"","x":713,"y":280,"wires":[]}, {"id":"3aafbac.5dff346","type":"websocket in","z":"6cc53a32.fd1454","name":"","server":"f496747.1a74188","client":"","x":178,"y":179,"wires":[["16ad9889.2ca387"]]}, {"id":"30678e55.b75c22","type":"mqtt in","z":"6cc53a32.fd1454","name":"","topic":"+/+/sensors","qos":"2","broker":"2c053731.014188","x":147,"y":281,"wires":[["69dbb0da.d6f07"]]}, {"id":"3d1afd79.14efb2","type":"mqtt out","z":"6cc53a32.fd1454","name":"","topic":"","qos":"","retain":"","broker":"2c053731.014188","x":725.5,"y":179,"wires":[]}, {"id":"69dbb0da.d6f07","type":"json","z":"6cc53a32.fd1454","name":"","x":334.5,"y":281,"wires":[["e3c32a0e.68a4f8"]]}, {"id":"e3c32a0e.68a4f8","type":"function","z":"6cc53a32.fd1454","name":"","func":"msg.payload.topic = msg.topic;\nreturn msg;","outputs":1,"noerr":0,"x":488.5,"y":281,"wires":[["a6d179b1.25bf28"]]}, {"id":"16ad9889.2ca387","type":"json","z":"6cc53a32.fd1454","name":"","x":401.5,"y":179,"wires":[["8eb60768.ece558"]]}, {"id":"8eb60768.ece558","type":"function","z":"6cc53a32.fd1454","name":"","func":"if (msg.payload.hasOwnProperty(\"topic\")) {\n msg.topic = msg.payload.topic;\n}\nreturn msg;","outputs":1,"noerr":0,"x":563.5,"y":179,"wires":[["3d1afd79.14efb2"]]}, {"id":"f496747.1a74188","type":"websocket-listener","z":"6cc53a32.fd1454","path":"/ws/sensorscontrol","wholemsg":"false"}, {"id":"2c053731.014188","type":"mqtt-broker","z":"6cc53a32.fd1454","broker":"infvoplein.nl","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60", "cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}]
De inhoud van de template-node sensorscontrol in deze flow moet vervangen worden door de code van: https://github.com/eelcodijkstra/iot2016/blob/master/sensorscontrol.html
Bouw deze toepassing
Maak deze toepassing, met de gegeven onderdelen.
- Programmeer de Arduino
- Bouw (kopieer) de flow in NodeRed
- en voeg de html-code voor de template-node toe.
- voeg in NodeRed de nodige debug-nodes toe
Test deze toepassing, via de URL <<mynodered>>:1880/sensorscontrol
- vul op de webpagina de identificatie van je Arduino-node in (laatste 4 cijfers van het MAC-adres, in kleine letters).
- controleer of de sensordata binnenkomen; ook als je de button op het Arduino-bord indrukt
- controleer of je de LED (led0) aan- en uit kunt zetten.
Als het niet naar voldoening werkt, kun je de volgende extra stappen nemen:
- voeg inject-flows aan NodeRed toe, voor het aan- en uitzetten van de led (welk MQTT-bericht? met welk topic?)
- voeg een debug-node toe voor de binnenkomende sensor-data (via MQTT).
Oefenen met MQTT
Probeer de berichten die via MQTT overgestuurd worden te volgen. Dit kan op verschillende plekken, probeer hiervan enkele uit:
- in het venster van de webtoepasssing (sensorscontrol).
- via de commandline, via mosquitto_sub
- via NodeRed (bijvoorbeeld door een extra flow, met een MQTT input-node met een wildcard-patroon)
- via een programma als MQTTbox (http://workswithweb.com/mqttbox.html)
Probeer met deze middelen ook MQTT-berichten te versturen, om je eigen LED aan- en uit te schakelen (en die van andere nodes).
Voeg een extra button toe
Op het Arduino-bord is een tweede button gemonteerd, maar deze is nog niet aangesloten, en in de software zijn hiervoor nog geen voorzieningen.
- sluit deze tweede button aan op een digitale input;
- pas de Arduino-software aan:
- detecteren van indrukken van deze button
- versturen van de sensor-data van deze button(s)
- Suggestie: stuur in de functie
sensor0Publish
de toestand van beide buttons mee. (Waarom kan dat handig zijn?)
Controleer of je de button-data ook binnenkrijgt in de webpagina.
Koppel de buttons aan de LED van een andere node
De volgende opdracht is om de beide buttons te gebruiken voor het aan- en uitschakelen van een LED, bij voorkeur een LED van een andere node. Je kunt dit eventueel eerst met je eigen node uittesten.
- We gebruiken twee verschillende knoppen, in plaats van een enkele "omschakelaar", om een "idempotent" interface te krijgen. Het maakt dan niet uit of je eenzelfde knop meerdere keren achter elkaar gebruikt: dit geeft hetzelfde resultaat. Het gewenste resultaat is dan altijd duidelijk, ongeacht de actuele toestand.
- Een "omschakelaar" heeft de volgende problemen: (i) er kan een vertraging zitten tussen het bedienen van de knop en het zichtbare resultaat. Als deze vertraging te groot is, gaan mensen twijfelen, en bedienen ze de knop nog een keer. Voor een omschakelaar is dat een probleem, voor aparte aan- en uitschakelaars niet. (ii) dezelfde actuator (LED) kan vanuit verschillende bronnen aangestuurd worden, voor een deel kan dit gelijktijdig gebeuren. Voor een omschakelaar is dan niet duidelijk wat het uiteindelijke resultaat zou moeten zijn, bij aparte aan- en uitschakelaars geeft de laatst bediende knop het uiteindelijke resultaat.
- Een dergelijk "idempotent" interface kennen we ook uit het web: het HTTP GET-request is idempotent. Dit betekent dat je altijd op de "reload" knop van de browser kunt klikken, bijvoorbeeld als er iets mis gegaan is. Voor het POST-request, zoals gebruikt door formulieren, geldt dit niet: je krijgt dan meestal een vraag van de browser of je dat echt wilt.
Deze koppeling tussen het knop-sensordata-bericht en het bericht voor de led-actuator kun je op verschillende plaatsen aanbrengen:
- in NodeRed
- in de webtoepassing (de html-code voor
sensorcontrols
)
Probeer beide mogelijkheden.
Interpreteren van sensor-data
Breid de webtoepassing uit: voeg een (input)-element toe dat de laatste waarde van de analoge sensor van de "eigen" node weergeeft (de node waarvan je de id invoert naast de buttons op het scherm).
Toestand van de LED
Breid de webtoepassing (sensorcontrols
) uit met de toestand van de LED van de node die aan de knoppen gekoppeld is.
Hiervoor moet je de Arduino-code uitbreiden:
- houd de toestand van de LED bij in een extra globale variabele;
- publiceer de status van de LED als deze veranderd is;
- en publiceer deze samen met de andere (analoge) sensoren.
E-mail versturen bij bepaalde voorwaarde
Voeg een NodeRed flow toe voor het versturen van een e-mail (of een twitter-bericht) als aan een bepaalde voorwaarde voldaan is, bijvoorbeeld bij het indrukken van een button, of bij een bepaalde sensorwaarde.
Raadplegen van een andere website
Als een bepaalde website niet beschikbaar is, moet de beheerder gewaarschuwd worden:
- via een LED
- via een mail
Maak me behulp van een http-request-node
hiervoor een flow in NodeRed.