Internet of Things/Protocollen/Opdrachten

Uit Lab
Naar navigatie springen Naar zoeken springen

Voorbeeld-toepassing

Het uitgangspunt voor de onderstaande opdrachten is een voorbeeld-toepassing, met de volgende onderdelen:

Sensorscontrol.png

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.