This flow will search every 7 days if there is a new online version of Node-Red on https://nodered.org/.
If that is the case, [EDIT] : In this new version :
1. Indicates whether a new online version is available. Click on it to start the update :
2. A wheel that turns to make you wait :
3. When the update is complete, you can select:
- either an automatic restart of NR
- or (by default) a popup which proposes if you want to restart (or not) in addition to indicating the time taken for the update.
4. After the restart indicates NR is up to date :
[{"id":"d250cd6a.e727d","type":"inject","z":"79bfee6e.39e9e","name":"all 7 Days","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"604800","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":150,"y":760,"wires":[["2468d13e.5c86ae"]],"info":"360h = 15days\n168h = 7 days"},{"id":"2468d13e.5c86ae","type":"http request","z":"79bfee6e.39e9e","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.54:1880/settings","tls":"","persist":false,"proxy":"","authType":"","x":320,"y":790,"wires":[["cf72a672.c60fb8"]]},{"id":"cf72a672.c60fb8","type":"function","z":"79bfee6e.39e9e","name":"substring","func":"str = msg.payload;\n\nlet actualVersion = str.substring(31,36);\nmsg.actualVersion = \"v\"+actualVersion;\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","x":700,"y":790,"wires":[["b6255cba.c8973"]]},{"id":"b6255cba.c8973","type":"http request","z":"79bfee6e.39e9e","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"https://nodered.org","tls":"","proxy":"","x":840,"y":790,"wires":[["f800a102.b6cdf"]]},{"id":"f800a102.b6cdf","type":"html","z":"79bfee6e.39e9e","name":"","property":"","outproperty":"","tag":".node-red-latest-version","ret":"text","as":"single","x":1030,"y":790,"wires":[["107f52bd.a490fd"]]},{"id":"107f52bd.a490fd","type":"change","z":"79bfee6e.39e9e","name":"array to online","rules":[{"t":"move","p":"payload[0]","pt":"msg","to":"onlineVersion","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1230,"y":790,"wires":[["bfde3c7.f8ca9c","6e583ccd.96f144"]]},{"id":"bfde3c7.f8ca9c","type":"function","z":"79bfee6e.39e9e","name":"switch","func":"let onlineVersion = msg.onlineVersion;//\"v1.1.0\";//\nlet actualVersion = msg.actualVersion;//\"v1.1.0\";//\n//let topic=msg.topic;\n//let text=\" \";\n//let color=\"white\";\n\nif(msg.topic==\"updateNR\") {\nmsg.ui_control = {\"onicon\":\"fa-spinner fa-pulse fa-2x fa-fw\",\"oncolor\":\"yellow\"};\nmsg.payload=true;\nmsg.topic=\"<font color=orange>Wait...</font>\";\nmsg.enabled=false;\nnode.status({fill:\"yellow\",shape:\"ring\",text:\"Updating...\"});\nreturn msg;\n}\nif(msg.updateResult===true) {\nmsg.ui_control = {\"onicon\":\"fa-exclamation fa-2x\",\"oncolor\":\"yellow\"};\nmsg.payload=true;\nmsg.topic=\"<font color=orange>Please restart</font>\";\nmsg.enabled=false;\nnode.status({fill:\"yellow\",shape:\"ring\",text:\"Please restart !\"});\nreturn msg;\n}\nif(msg.updateResult===false) {\nmsg.ui_control = {\"onicon\":\"fa-exclamation fa-2x\",\"oncolor\":\"red\"};\n//msg.payload=true;\nmsg.topic=\"<font color=orange>Update Error !</font>\";\nmsg.enabled=false;\nnode.status({fill:\"red\",shape:\"ring\",text:\"Error !\"});\nreturn msg;\n}\nif(onlineVersion == actualVersion){\nmsg.ui_control = {\"onicon\":\"fa-thumbs-o-up fa-2x\",\"oncolor\":\"grey\"};\nmsg.payload=true;\nmsg.topic=\"<font color=grey>\"+actualVersion+\"</font>\";//\"<font color=grey>v1.1.0</font>\";//\nmsg.enabled=false;\nnode.status({fill:\"grey\",shape:\"ring\",text:\"ok\"});\nreturn msg;\n}\nif(onlineVersion != actualVersion){\nmsg.ui_control = {\"onicon\":\"fa-download fa-2x\",\"oncolor\":\"orange\"};\nmsg.payload=true;\nmsg.topic=\"<font color=orange>New \"+onlineVersion+\"</font>\";//\"<font color=orange>New v1.1.2</font>\";//\nmsg.enabled=true;\nnode.status({fill:\"orange\",shape:\"ring\",text:\"New update\"});\nreturn msg;\n}\n/*\nlet onlineVersion = msg.onlineVersion;//\"v1.1.0\";//\nlet actualVersion = msg.actualVersion;//\"v1.1.0\";//\nlet text=\" \";\nlet color=\"white\";\n\nif(onlineVersion == actualVersion){ text = onlineVersion;color='grey';}\nif(onlineVersion != actualVersion){ text = \"New \"+ onlineVersion;color='orange';}\nif(msg.topic==\"update NR\") {text = \"Wait updating...\";color=\"red\";}\nif(msg.updateResult===true) {text = \"Pls restart NR !\";color=\"orange\";}\nif(msg.updateResult===false) {text = \"Update ERROR !\";color=\"red\";}\n\nnode.send({text:text, color:color});\n*/\n/*\nmsg.ui_control = {\"onicon\":\"fa-thumbs-o-up fa-2x\",\"oncolor\":\"grey\"};\nmsg.payload=true;\nmsg.topic=\"<font color=grey>v1.1.0</font>\";\nmsg.enabled=false;\nreturn msg\n*/","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1130,"y":870,"wires":[["97d17eaa.5084"]]},{"id":"4cc082af.37bb9c","type":"switch","z":"79bfee6e.39e9e","name":"error?","property":"rc.code","propertyType":"msg","rules":[{"t":"neq","v":"0","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":740,"y":910,"wires":[["4100c25f.e14c8c"]]},{"id":"b7caf1e2.379b1","type":"switch","z":"79bfee6e.39e9e","name":"updated?","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"updated","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":750,"y":950,"wires":[["8225f7b3.33f9f8"]]},{"id":"ecb4242f.8fa168","type":"exec","z":"79bfee6e.39e9e","command":"","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"exec","x":580,"y":940,"wires":[["b7caf1e2.379b1","4cc082af.37bb9c"],[],[]],"info":"error 127 : command not found\n\nsudo node-red-restart\n-----------------------\npayload: object\n code: \"EPERM\"\n message: \"kill EPERM\""},{"id":"8225f7b3.33f9f8","type":"function","z":"79bfee6e.39e9e","name":"substring","func":"str = msg.payload;\nlet messageLength = str.length;\n\nlet updateTime= str.substring(messageLength-8,messageLength);// get updateTime\n\nmsg.updateTime = updateTime;\nmsg.messageLength=messageLength;\n//msg.updateResult=true;\nnode.send({payload: updateTime+\" . Do you want to restart Node Red ?\",updateResult:true});\n\n/* output 1 :\n/usr/bin/node-red -> /usr/lib/node_modules/node-red/red.js\n/usr/bin/node-red-pi -> /usr/lib/node_modules/node-red/bin/node-red-pi\n+ node-red@1.1.2\nupdated 7 packages in 40.421s\n\n\n\n*/\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":890,"y":950,"wires":[["bfde3c7.f8ca9c","39bcfa1e.417406"]]},{"id":"4100c25f.e14c8c","type":"function","z":"79bfee6e.39e9e","name":"error","func":"node.send({updateResult:false});\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":890,"y":910,"wires":[["bfde3c7.f8ca9c"]]},{"id":"97d17eaa.5084","type":"ui_switch","z":"79bfee6e.39e9e","name":"DASHversion","label":"{{msg.topic}}","tooltip":"","group":"cf6208c7.847328","order":18,"width":2,"height":1,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"{{msg.ui_control.onicon}}","oncolor":"{{msg.ui_control.oncolor}}","offvalue":"false","offvalueType":"bool","officon":"{{msg.ui_control.officon}}","offcolor":"{{msg.ui_control.offcolor}}","x":1270,"y":870,"wires":[["ad145af7.de0638"]],"info":"fa-refresh fa-spin fa-2x\nfa-download fa-2x"},{"id":"ad145af7.de0638","type":"switch","z":"79bfee6e.39e9e","name":"restart?","property":"payload","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":1420,"y":870,"wires":[[],["2c5ed02e.0b73a"]]},{"id":"2c5ed02e.0b73a","type":"change","z":"79bfee6e.39e9e","name":"update+topic","rules":[{"t":"set","p":"payload","pt":"msg","to":"sudo npm install -g --unsafe-perm node-red","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"updateNR","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1430,"y":930,"wires":[["ecb4242f.8fa168","bfde3c7.f8ca9c"]]},{"id":"1b5fa935.0f66d7","type":"switch","z":"79bfee6e.39e9e","name":"restart?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"OK","vt":"str"},{"t":"eq","v":"Cancel","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1200,"y":1070,"wires":[["9af57370.916cd"],[]]},{"id":"39bcfa1e.417406","type":"ui_toast","z":"79bfee6e.39e9e","position":"dialog","displayTime":"5","highlight":"blue","sendall":true,"outputs":1,"ok":"OK","cancel":"Cancel","raw":false,"topic":"Update finished in : ","name":"notif updated","x":1050,"y":1070,"wires":[["1b5fa935.0f66d7"]]},{"id":"9af57370.916cd","type":"ui_button","z":"79bfee6e.39e9e","name":"dash NRrestart","group":"cf6208c7.847328","order":6,"width":1,"height":1,"passthru":true,"label":"","tooltip":"Restart NR","color":"","bgcolor":"grey","icon":"loop","payload":"sudo node-red-restart","payloadType":"str","topic":"restart button pushed","x":1390,"y":1010,"wires":[["ecb4242f.8fa168"]]},{"id":"d15ea4e4.5d9968","type":"ui_button","z":"79bfee6e.39e9e","d":true,"name":"NR downgrade","group":"cf6208c7.847328","order":12,"width":3,"height":1,"passthru":true,"label":"downgrade NR","tooltip":"","color":"","bgcolor":"lime","icon":"system_update_alt","payload":"sudo npm install -g --unsafe-perm node-red@v1.1.1","payloadType":"str","topic":"updateNR","x":420,"y":870,"wires":[["ecb4242f.8fa168","bfde3c7.f8ca9c"]],"info":" error:127\nupdate-nodejs-and-nodered\nsudo update-nodejs && update-nodered\n\n error:1\nsudo update-nodered\nsudo update-nodejs && update-nodered\nsudo update-nodejs && nodered\n\n error:100\napt-get install nodered"},{"id":"1c73b6b0.9415f9","type":"delay","z":"79bfee6e.39e9e","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1040,"y":1010,"wires":[["9af57370.916cd"]]},{"id":"e54e0c50.e1a3","type":"comment","z":"79bfee6e.39e9e","name":"Restart AUTOMATICALY after update finished ->","info":"","x":770,"y":1010,"wires":[]},{"id":"20f96db4.685e62","type":"comment","z":"79bfee6e.39e9e","name":"display a popup to MANUALY Restart (if you want) ->","info":"","x":760,"y":1070,"wires":[]},{"id":"2823f1dc.01c1de","type":"comment","z":"79bfee6e.39e9e","name":"or","info":"","x":1050,"y":1040,"wires":[]},{"id":"6e583ccd.96f144","type":"debug","z":"79bfee6e.39e9e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1420,"y":790,"wires":[]},{"id":"8fa67394.2b94d","type":"comment","z":"79bfee6e.39e9e","name":"http request Internal version MANUALY : put your Node Red server IP ","info":"","x":310,"y":830,"wires":[]},{"id":"e06fa803.42bf58","type":"comment","z":"79bfee6e.39e9e","name":"http request : Online version","info":"","x":890,"y":830,"wires":[]},{"id":"d3cc42cb.5b16c","type":"ip","z":"79bfee6e.39e9e","name":"NR ip","https":false,"timeout":"5000","internalIPv4":true,"internalIPv6":true,"publicIPv4":true,"publicIPv6":false,"x":300,"y":710,"wires":[["47adc985.626618"]]},{"id":"47adc985.626618","type":"change","z":"79bfee6e.39e9e","name":"internalIPv4 to myIp","rules":[{"t":"move","p":"payload.internalIPv4","pt":"msg","to":"myIp","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":710,"wires":[["510d1b8b.88a8a4"]]},{"id":"510d1b8b.88a8a4","type":"http request","z":"79bfee6e.39e9e","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://{{myIp}}:1880/settings","tls":"","persist":false,"proxy":"","authType":"","x":640,"y":710,"wires":[["cf72a672.c60fb8"]],"info":"http://192.168.1.54:1880/settings"},{"id":"8c7c498c.142528","type":"comment","z":"79bfee6e.39e9e","name":"http request Internal version AUTOMATICALY = Add node-red-contrib-ip from palette","info":"","x":350,"y":680,"wires":[]},{"id":"406d48eb.9ffbe8","type":"comment","z":"79bfee6e.39e9e","name":"or","info":"","x":310,"y":750,"wires":[]},{"id":"cf6208c7.847328","type":"ui_group","z":"","name":"RPI","tab":"250de740.57ee78","order":12,"disp":false,"width":6,"collapse":false},{"id":"250de740.57ee78","type":"ui_tab","z":"","name":"Dashboard","icon":"dashboard","order":1,"disabled":false,"hidden":false}]
New: to know the internal version of Node Red, you have the choice between manually entering the IP address of the NR server OR let it do it automatically by adding the node-red-contrib-ip node from the Manager palette.
The output of the array to online
node, send :
msg.actualVersion
is the running NR version
msg.onlineVersion
is the online NR version on https://nodered.org/
Are there in addition:
- A RESTART button : if you want to restart NR for any reason :
- A hidden DOWNGRADE button : if you want to test with a previous version of NR
Tested on raspbian RPI 3B, RPI zero ...
Enjoy
Chris