node-red workshop at iot toulouse

8
IoT Toulouse Workshop: Node-RED - 1 - http://nodered.org An introduction to flow.based programming using Node.RED ! Node.RED is a visual tool for wiring the Internet of Things (IoT). Node&RED is platform&independent, but has been developed with even small computers such as the Raspberry Pi in mind although it also runs in the cloud. ! Traditional IoT development can be very technical: Access to the GPIO and other hardware requires skills in C or assembler, output of data to web services or sending tweets and emails requires the use of complex APIs. Node.RED takes care of the technicalities and lets you concentrate on the logic of your workflow. ! While most programming in Node&RED is done visually using pre&defined functions (“nodes”), any additional functionality can be added in JavaScript. ! Node.RED is a multi.purpose jackknife – use it for any prototyping! WORKSHOP CONTENT: In this workshop, we’re going to use Node&RED to build a basic web server. We are going to build a web site that provides the functionality of an online chat application, i.e. you are going to learn about communication between a web browser and the underlying service. If you’re a seasoned developer, this all is likely going to be very trivial for you!

Upload: boris-adryan

Post on 31-Jul-2015

93 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Node-RED workshop at IoT Toulouse

IoT Toulouse Workshop: Node-RED

! - 1 -

! !

!http://nodered.org

!

An!introduction!to!flow.based!

programming!using!Node.RED!

!

! Node.RED! is! a! visual! tool! for! wiring! the! Internet! of! Things! (IoT).! Node&RED! is!platform&independent,!but!has!been!developed!with!even!small!computers!such!as! the!Raspberry!Pi!in!mind!although!it!also!runs!in!the!cloud.!

!! Traditional! IoT! development! can! be! very! technical:! Access! to! the! GPIO! and! other!hardware! requires! skills! in!C!or! assembler,! output!of!data! to!web! services!or! sending!tweets! and! emails! requires! the! use! of! complex! APIs.! Node.RED! takes! care! of! the!technicalities!and!lets!you!concentrate!on!the!logic!of!your!workflow.!

!! While! most! programming! in! Node&RED! is! done! visually! using! pre&defined! functions!(“nodes”),!any!additional!functionality!can!be!added!in!JavaScript.!

!! Node.RED!is!a!multi.purpose!jackknife!–!use!it!for!any!prototyping!!

!

!

WORKSHOP!CONTENT:!In!this!workshop,!we’re!going!to!use!Node&RED!to!build!a!basic!web!server.! We! are! going! to! build! a! web! site! that! provides! the! functionality! of! an! online! chat!application,!i.e.!you!are!going!to!learn!about!communication!between!a!web!browser!and!the!underlying! service.! If! you’re! a! seasoned! developer,! this! all! is! likely! going! to! be! very!trivial!for!you!!

Page 2: Node-RED workshop at IoT Toulouse

IoT Toulouse Workshop: Node-RED

! - 2 -

Technical!background:! For! this!workshop,!we!hope!you!already!have!node.js! and!npm! installed.!While! the! installation!of! the!Node&RED!software!is!relatively!easy,!but!can!differ!from!system!to!system.!On!a!normal!Linux/OS!X!system,!do!this!to!install!and!run:!

!

Note:! To! leverage! the! power! of! Node&RED,! consider! installing! nodes! for! email! or! hardware! access! as!well.! The! latter! is! described! here:!http://nodered.org/docs/getting2started/adding2nodes.html!

=>!1)!Exercise:!Starting!Node.RED!as!user!

Node&RED!can!be!installed!as!a!service/demon,!i.e.!as!a!program!that’s!always!executed!when!your!computer! is!running.!However,! this! is!only!useful! if!you!want!to!commit!your!machine!for! this! particular! use! as! it! can! consume! considerable! resources.! For! everyone! else,! it’s!recommended!to!start!Node&RED!only!when!needed:!$6node2red!

You!should!now!see!Node&RED!starting!up!–!that!may!take!a!few!seconds:!

!

Congratulations.!You’re!now!ready!for!the!exercises.!

Node&RED!represents!a!server!on!the!basis!of!node.js!and! interacts!with! the!user! through!a!graphical! user! interface.! It! can! be! reached! on! port! 1880.!To! use! Node.RED,! open! a! web!browser!and!direct!it!to!http://localhost:1880!

It’s!useful!to!remember!that!Node&RED!acts!as!a!server!in!your!entire!network.!That!is,!if!your!computers’s!internal!IP!address!is!something!like!192.x.x.x,!every!computer!in!your!network!can!open!the!Node&RED!GUI!through!http://192.x.x.x:1880.!You!can!make!your!system!more!restricted/secure!by!following!the!advice!on!http://nodered.org/docs/configuration.html6and6http://nodered.org/docs/security.html!

=>!2)!Exercise:!Your!first!flow!!

The!best!way!to!explain!“a!flow”!is!by!creating!one.!In!this!mini!flow,!we’re!going!to!inject!a!value!into!our!debug!window!(refer!to!page!1!for!what!the!GUI!elements!are!called).!

1. Open!the!Web!Browser.!

2. In!the!address!line,!enter!localhost:1880.!You!will!then!see!the!Node&RED!GUI.!

Page 3: Node-RED workshop at IoT Toulouse

IoT Toulouse Workshop: Node-RED

! - 3 -

3. Drag! and! drop! an! “inject”! node! from! the! nodes! library! into! the! flow! editor! (once!you’ve! chosen! the! inject! node,! you! should! see! some! general! explanation! about! its!functionality!in!the!info!pane!–!no!need!to!read!that!now).!

4. Drag!and!drop!a!“debug”!node!from!the!nodes!library!into!the!flow!editor.!

5. Create!a!pipe!between!the!inject!and!debug!nodes!by!drawing!a!connection!between!their!small!grey!rounded!rectangles.!

6. Change!from!the!info!pane!to!the!debug!pane!(upper!right).!

7. Deploy!(=start)!your!flow.!

8. Once!deployed,!press! the! left!blue!rectangle! that’s!attached! to! the! inject!node.!Check!what’s!happening!in!the!debug!pane.!

=>!3)!Exercise:!Setting!up!a!static!website!

It!is!very!easy!to!set!up!a!very!basic!web!server!in!Node&RED.!

1. From!the!input!panel,!chose!a!“http”!node.!

2. Change!the!properties!of!your!http!node!so!that!it!will! respond! to! GET! requests! to! /mypage! from! a!browser.!

3. Add!a!“template”!node!(from!the! function!panel),!and!a!“http!response”!node!from!the!output!panel.!!

4. Wire!your!flow!together!as!shown!below:!

!

5. Deploy!your!flow.!

6. Once!deployed,!open!a!separate!browser!window!and!enter!localhost:1880/mypage.!

A!note!on!addresses!and!ports:!Web!servers!have!their!own!numerical!addresses,!e.g.!a!special!table!(called!DNS)!resolves!the!BBC!website!to!212.58.246.103.! Each! address! can! have! thousands! of! communication! channels! (called! ports).! A! standard! webpage! call! uses! port! 80! by!default.!Your!own!machine! is!always!called!“localhost”!and!resolves!to!127.0.0.1.!A!default!Node&RED!server!can!be!opened!on!port!1880.!Does!the!address!http://localhost:1880/mypage!make!more!sense!to!you!now?!

=>!4)!Exercise:!!The!anatomy!and!function!of!a!template!node!

Our!previous!Node&RED!workflow!hides!the!complexity!of!the!client!"!server!communication!via! the! hypertext! transfer! protocol! (“http”)! (which! sits! on! top! of! another! protocol,! TCP/IP,!which!sits!on!top!of…!…you!get!the!gist).!We!don’t!need!to!care!how!the!browser!talks!to!the!server.!

One! technicality! that! we! can’t! fully! get! around! in! this! workshop! is! HTML,! the! hypertext!markup!language.!It’s!the!code!that!describes!how!a!website!is!supposed!to!look.!It’s!beyond!the! scope! of! this! course! to! teach! you! all! goodness! of!HTML,! a! good! entry! point! for! further!

Page 4: Node-RED workshop at IoT Toulouse

IoT Toulouse Workshop: Node-RED

! - 4 -

explorations!is!here:!http://www.w3schools.com/html.!What!you!need!to!remember,!however,!is!that!the!template!node!encapsulates!a!minimal!HTML!page.!So!

!

!indeed!returns!

<!DOCTYPE html> <html> <head> </head> <body> This is the payload: {{payload}} </body> </html>

which!instructs!the!browser!to!show!the!text!you’ve!seen!in!Exercise!3.!

In! the!next!exercise,!we!will!use!additional!HTML!code! to!add!some!styling! to!our!website,!and!we!will!learn!to!use!the!moustache!{{!}}!format!to!add!dynamic!content!to!it.!

1. Drag!and!drop!a!“function”!node! into! the! flow!editor.!Call! it! “where! things!happen”.!Stick!it!in!between!the!http&in!and!the!template!node.!

!

2. Edit!the!function:!Add!msg.payload = "Hello, Pi";!in!the!line!before!return msg;!

3. Change!the!template!into!This is the <b>message</b>: {{payload}}!

4. Deploy!your!flow!and!check!out!localhost:1880/mypage.!

!

Note:!If!you!know!HTML,!have!a!play!with!other!style!tags.!You!can!even!embed!CSS!!

!

=>!5)!Exercise:!Retain!state!

So! far! our! Node&RED! flow! is! strictly! linear:! Once! the! /mypage! is! requested,! the! function!populates! the!variable!payload!with!“Hello,!Pi”,! the! template!node!embeds! this!payload! into!the!HTML!that’s!returned!to!the!server.!

How!can!we!put!other!things!into!the!payload?!

1. Wire!your!inject!node!from!Exercise!1!to!the!function!node.!Modify!the!inject!node!to!send!the!string!“Have!a!nice!day”!as!payload,!with!“new!message”!as!topic.!

Page 5: Node-RED workshop at IoT Toulouse

IoT Toulouse Workshop: Node-RED

! - 5 -

!

2. Edit!the!function!node!to!contain!the!following!JavaScript:!

!

3. Deploy!the!flow.!!

4. Look!at!localhost:1880/mypage!in!your!web!browser.!Note!what!you!see.!

5. Click!on!the!rounded!rectangle!on!the!left!of!your!inject!node.!

6. Reload! localhost:1880/mypage.! Note! what! you! see.! Can! you! make! sense! of! your!observation!in!the!light!of!your!JavaScript!code!from!step!2?!

A!bit!of!background:!

By!default,!most!wires!between!nodes!are!topic/payload!pairs,!a!bit!like!emails!have!subject!and!body.!However,! the!default!msg!variable!can!always!be!extended,!and!in!the!case!of! the!http!nodes!contain!an!entire!http!response!object.!

The!context6variable!is!available!in!the!function!node!to!retain!information!between!different!executions!of! the!node.! In!our!example,! if! the! input!message!msg! arrives! from!the! injection!node!(having!the!topic!“new!message”),!we!populate!context.value!with!the!payload!“Have!a!nice!day”!and! leave! the!node.! If! the! input!arrives! from! the!/mypage! http!node,!we!evaluate!whether!something!is!present!in!the!context!variable.!If!not,!we!deliver!the!payload!“never!got!anything”!for!rendering!in!the!template!node,!otherwise!we!take!it!from!the!context.!

The!special!case!context.global!is!a!variable!that!persist!between!executions!of!a!node!and!are!globally!available!to!all!other!function!nodes.!More!about!messages!and!context!variables!can!be!found!here:!http://nodered.org/docs/writing2functions.html!

=>!6)!Exercise:!Returning!the!result!of!a!web!form!to!Node.RED!

So!far!our!interaction!between!the!server!and!the!client!was!rather!unidirectional.!Following!the!http!request,!us!injecting!or!not!injecting!a!message!determined!the!actual!outcome.!Now,!we!extend!the!example!so!that!the!return!value!is!dependant!on!the!user’s!input.!

1. Drag!and!drop!a!“http”!input!node,!a!“template”!node!and!a!“http“!output!node!into!your! flow.! Set! the! input! node! to! respond! to! GET! request! on! /login.!Wire! the! nodes!together!as!shown!below:!

Page 6: Node-RED workshop at IoT Toulouse

IoT Toulouse Workshop: Node-RED

! - 6 -

!

2. Add!the!following!HTML!to!your!template!node:!

<form action="http://localhost:1880/chat" method="post"> <b>User</b><br> <input type="text" name="user"/><br> <button type="submit">Submit</button> </form>

3. Add!another!set!of!four!nodes!to!your!flow.!Configure!the!http!input!node!to!respond!to! POST! requests! at! /chat.! This! is! how! your! server! is! going! to! react! to! form!submissions:!

!

4. Edit!the!function!node!to!extract!the!content!of!the!incoming!input!field!“user”!(if!not!empty)!and!assign!it!to!our!standard!payload:!

if (msg.req.body["user"] != "") { msg.payload = msg.req.body["user"] } return msg;

5. The!template!node!can!simply!say:!The user’s name is: {{payload}}!

6. Deploy!and!test!your!flow!at!localhost:1880/login.!

Does!it!do!what!you!expect?!If!so:!Congratulations,!you’re!now!seeing!the!key!ingredients!to!a!basic!chat!server.!

=>!Exercise!7:!Putting!it!all!together!

In!the!next!step!we’re!going!to!put!all!of!our!new!skills!together.!To!build!a!basic!chat!server,!all!we!need!is!a!little!more!trickery!with!the!context.global!to!retain!our!conversation!(we’re!going! to! use! context.global.dialog),! some! HTML! concept! called! iframe! to! separate! an! input!field!from!the!conversation,!and!a!bit!of!client&sided!JavaScript!to!auto&update!the!iframe.!

1. Rewrite!the!function!node!following!the!/chat!http!input!like!this:!

if (msg.req.body["user"] != "") { msg.payload = msg.req.body["user"] } if (msg.req.body["message"] != undefined) { context.global.dialog += msg.req.body["user"]+':'+msg.req.body["message"]+"<BR>"; } context.global.dialog = context.global.dialog || ""; return msg;

Page 7: Node-RED workshop at IoT Toulouse

IoT Toulouse Workshop: Node-RED

! - 7 -

2. The!template!node!hides!most!of!the!trickery:!

<iframe src="http://localhost:1880/dialog" name="iframe_a" width="90%" height="70%"></iframe> <form name="frm" action="http://localhost:1880/chat" method="post"> <b>Message from {{payload}}</b><br> <input type="text" name="message" size="90%"/> <input type="hidden" name="user" value="{{payload}}"><br> <button type="submit">Submit</button> </form> <SCRIPT language="JavaScript"> window.setInterval("reloadIFrame();", 1000); function reloadIFrame() { window.frames["iframe_a"].location.reload(); } </SCRIPT>

3. We!need!another!set!of!http!input,!function,!template!and!http!out!nodes.!These!will!represent!the!/dialog!page!that’s!shown!in!the!iframe.!The!code!is!fairly!simple.!

!

4. Add! to! function! node! node! following! the! /dialog! http! input! msg.payload = context.global.dialog;!before!return msg;!

5. The!template!node!just!says:!{{payload}}!

6. Deploy!your!web!server.!!

!

Open!localhost:1880/login!from!two!different!browser!windows!and!login!with!different!identities.! Both! windows! will! update! their! iframe! once! a! second,! showing! /dialog! as! it!continues! to! grow!on! the! server!with! lines! that! are! sent! via! the! form! field! “message”! from!either!client.!

!

Further!explanations!and!suggestions!for!experiments:!

So! far! all! code! refers! to! localhost:1880.! It! is! possible! to! change! the! default! port,! allowing!addresses! without! the! addition! of! :1880! (see! http://nodered.org/docs/configuration.html).!Furthermore,!localhost!is!only!visible!on!your!own!machine.!You!can!change!localhost!to!your!

Page 8: Node-RED workshop at IoT Toulouse

IoT Toulouse Workshop: Node-RED

! - 8 -

computers’s!local!IP!address!(often!something!like!192.168.x.x!or!172.x.x.x)!and!request!your!chat!server!from!any!other!computer!within!your!local!network.!These!changes!would!impact!the!address!that’s!specified!in!the!HTML!form!definitions.!

!

Node&RED!is!an!incredibly!powerful!framework!that!allows!you!to!do!things!in!very!little!time.!The!official! directory! of! flows! donated! to! the! community! is! here!http://flows.nodered.org!and!they!can!easily!be!imported!by!copying!&!pasting!the!JSON&formatted!code.!

!

A!few!suggestions!and!examples!that!I!have!described!over!the!past!months!are!here:!

! Triggering! Node.RED! with! drawings:! The! Aestheticodes!project! uses! a! QR! code! like! method! to! encode! information! in!beautiful!drawings.!Draw!a!picture,!take!a!photograph!with!your!mobile! and! trigger! the! debug! node! doing! that:!http://logic.sysbiol.cam.ac.uk/?p=1514!

!

! Control!Minecraft!with!Node.RED:!The!Minecraft!Pi!Edition!can!be!controlled!through!Python,!but! that!may!not!be!easily!accessible! for!everyone.!With!a!MQTT&to&Minecraft!bridge,! the! Node&RED! inject! nodes! can! be! used! to! control! Steve:!http://logic.sysbiol.cam.ac.uk/?p=1499!

!

! Got! an! AirPi! shield?! Monitor! your! room! climate! with! AirPi! and! Node.RED:!http://logic.sysbiol.cam.ac.uk/?p=1423!

!

! The!first!CamJam!Node.RED!tutorial!that!teaches!radio!communication!through!Ciseco!radio! modules! is! available! here:! http://www.slideshare.net/BorisAdryan/node2red2coursecamjamjuly20146

!

! Last! not! least:! Here’s! a! (now! relatively! old)! IoT! platform! interoperability! test! for!Node.RED:!http://logic.sysbiol.cam.ac.uk/?p=1473!

!