A handy flow for remote shutdown/reboot or NR backups

Hi folks.

This is a flow (two parts) that you can put on machines.

The idea is that if you are modifying the flow often, it is sometimes possible you destroy something.

This (these) flows allow you to back up your node-red flow.
As well as shut down or restart a remote machine.

In this example I have used the LINK to join the two parts, only for simplicity and leave HOW you connect them to yourself. Though MQTT is probably the best way to go.

Also!

It needs a script which is in a comment node at the bottom with instructions.

So: there are three nodes - I didn’t bother with buttons as they would only complicate the layout - you press one to SHUT DOWN the remote machine, another to REBOOT it, and the third to back up the flows.

I know it isn’t the best written, but I am new to NR and have got this little thing working.
It is handy for working on remote machines.

I hope you can work out what I mean in the somewhat attempt at writing the instructions both here and in the flow.

Oh, and in the two nodes: SHUTDOWN and REBOOT you will have to enter the name of the machine. Sorry I didn’t delete my names before posting.

But I am sure you will get the idea.

Likewise you will also have to edit the SHUTDOWN, REBOOT and BACKUP injection points with the machine’s name.

Flow below.

[Edited by @knolleary to format the flow]

[{"id":"60d2283e.91611","type":"mqtt in","z":"69359cf8.ff51cc","name":"Shutdown","topic":"SHUTDOWN","qos":"2","broker":"34004a3c.38c68e","x":120,"y":1120,"wires":[["eddda8c.65748d8"]]},{"id":"eddda8c.65748d8","type":"json","z":"69359cf8.ff51cc","name":"","property":"payload","action":"","pretty":false,"x":250,"y":1120,"wires":[["cf2395fa.532298"]]},{"id":"cf2395fa.532298","type":"switch","z":"69359cf8.ff51cc","name":"","property":"payload.DEVICE","propertyType":"msg","rules":[{"t":"eq","v":"MUSICPI","vt":"str"},{"t":"eq","v":"BEDPI","vt":"str"},{"t":"eq","v":"PIFACE","vt":"str"},{"t":"eq","v":"CAMERAPI","vt":"str"},{"t":"eq","v":"PORTAPI","vt":"str"},{"t":"eq","v":"TELEPI","vt":"str"},{"t":"eq","v":"BEEFPI","vt":"str"}],"checkall":"true","repair":false,"outputs":7,"x":390,"y":1160,"wires":[[],[],[],[],[],[],[]]},{"id":"175fdbe1.596cc4","type":"debug","z":"69359cf8.ff51cc","name":"Final command","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":600,"y":1120,"wires":[]},{"id":"4a10d7ab.a7f84","type":"switch","z":"69359cf8.ff51cc","name":"","property":"payload.COMMAND","propertyType":"msg","rules":[{"t":"eq","v":"Shutdown","vt":"str"},{"t":"eq","v":"Reboot","vt":"str"},{"t":"eq","v":"Backup","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":570,"y":1160,"wires":[["c3fd89f5.33d79"],["2785aa5b.dd0766"],["8ce88c60.0bebb8"]]},{"id":"c3fd89f5.33d79","type":"exec","z":"69359cf8.ff51cc","command":"sudo shutdown -h now","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Shut down","x":750,"y":1160,"wires":[[],[],[]]},{"id":"2785aa5b.dd0766","type":"exec","z":"69359cf8.ff51cc","command":"sudo reboot","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Reboot","x":740,"y":1220,"wires":[[],[],[]]},{"id":"a3396d85.46cd","type":"comment","z":"69359cf8.ff51cc","name":"Allow remote shutdown/restart or NR backup","info":"","x":470,"y":1060,"wires":[]},{"id":"aebc0b22.6c81d8","type":"inject","z":"69359cf8.ff51cc","name":"Shutdown","topic":"","payload":"{\"DEVICE\":\"<enter device name here>\", \"COMMAND\":\"Shutdown\"}","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":880,"wires":[["e3e96f06.cd5c08","744552c0.d3ce74"]]},{"id":"4ce44c06.29cda4","type":"inject","z":"69359cf8.ff51cc","name":"Restart","topic":"","payload":"{\"DEVICE\":\"<enter device name here>\", \"COMMAND\":\"Shutdown\"}","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":132,"y":957,"wires":[["e3e96f06.cd5c08","744552c0.d3ce74"]]},{"id":"87a8ba50.e38e6","type":"inject","z":"69359cf8.ff51cc","name":"Back up","topic":"","payload":"{\"DEVICE\":\"<enter device name here>\", \"COMMAND\":\"Shutdown\"}","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1040,"wires":[["e3e96f06.cd5c08","744552c0.d3ce74"]]},{"id":"95ffafab.12d7b8","type":"comment","z":"69359cf8.ff51cc","name":"SHUT DOWN","info":"","x":150,"y":840,"wires":[]},{"id":"cbf81125.a98bf","type":"comment","z":"69359cf8.ff51cc","name":"RESTART","info":"","x":140,"y":920,"wires":[]},{"id":"6e6e741c.2fcdfc","type":"comment","z":"69359cf8.ff51cc","name":"BACKUP","info":"","x":140,"y":1000,"wires":[]},{"id":"e3e96f06.cd5c08","type":"debug","z":"69359cf8.ff51cc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":470,"y":880,"wires":[]},{"id":"216f0f4c.ed6758","type":"link in","z":"69359cf8.ff51cc","name":"","links":[],"x":120,"y":1180,"wires":[["eddda8c.65748d8"]]},{"id":"744552c0.d3ce74","type":"link out","z":"69359cf8.ff51cc","name":"","links":[],"x":415,"y":940,"wires":[]},{"id":"8ce88c60.0bebb8","type":"exec","z":"69359cf8.ff51cc","command":"bash /home/pi/Mine/NR_Backup.sh","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"Backup","x":740,"y":1280,"wires":[[],[],[]]},{"id":"8e93cf6.3a3a83","type":"comment","z":"69359cf8.ff51cc","name":"This is the backup bash script","info":"This is given that the directory ~/Backups/NR\nalready exists.\n\nAlso you will have to put the script somewhere,\nand you will have to change the path to the file\nas well.\n\nScript below\n------------------------\ncd ~/Backups/NR\nmkdir `date \"+%Y-%m-%d\"`\ncd `date \"+%Y-%m-%d\"`\ncp ~/.node-red/*.j* .\n","x":430,"y":1300,"wires":[]},{"id":"34004a3c.38c68e","type":"mqtt-broker","z":"","broker":"192.168.0.99","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"20","cleansession":true,"willTopic":"EOM","willQos":"2","willPayload":"'MusicPi telemetry failure'","birthTopic":"SOM","birthQos":"2","birthPayload":"'Awaiting Music Pi'"}]

Thanks for sharing this here. Though for the sake of longevity, you may wish to post this as a flow on the flows site.

Oh, (see, I goofed)…

In the second block that you put on the remote machine, there are two SWITCH nodes.

The first one (which has nothing connected to the outputs) needs also to be edited to contain a list of all the machines you wish to use. That way it is easier you just copy the WHOLE flow, rather than editing it for each new machine.

Then you select the output for that machine.

You could skip that part and filter it if you want to. Your call.

I am doing it that way so you can see the WHOLE picture of what is going on.

I hope I don’t realise there are any more things missing.

I was going to but I am not set up with github just yet.

:frowning: Yeah, sorry.

No worries, you’ve not done anything wrong :smile:

Life is a journey. Great to see people contributing, I just wanted you to get the most from it.

Hi

Quick question - Is there not a back up option built in to Node Red ?

Looking around I can’t seem to see anything, but considering the time i’m spending building flows, how are people ensuring they have appropriate back ups ?

Now admittedly I’m trying out Node Red on a docker container, running on a QNAP NAS - so I actually have no idea where all the data is stored, it’s all sort of hidden away.

Is there a nice export (to file) back up option available - so I don’t have to worry about the folder/file structure i can do full exports and restores via the UI ?

They use the projects feature so everything is stored in a git repo.

Plus those using Pis generally make an image backup of the card occasionally so they don't have to back in time too far.

Thanks @Colin

This looks to be what you are referring to, ill take a look

https://nodered.org/docs/user-guide/projects/

A quick looks suggests I have to edit a file on my QNAP/docker , which will be fun to try and find :slight_smile:

also - while hardly a solid solution - every time you hit deploy we save the existing flow file to a hidden file (usually .flowfilename.json.backup - a) note the initial . and the flowfilename is whatever your current flowfile is called.

So that is a one level backup in place, which can get you out of a hole as long as you don't re-deploy twice of course.