Remote reboot device from node red

I have a device in another building that sits on the network. The building itself has no outside connections, internet, or even to the main house. Occasionally, randomly and without seeming reason the device will lock up. After long talks with the mfg. we are fairly certain it is bad power so there is really little that can be done to fix this, or at least within a reasonable budget. While the device isn't critical, it distributes feed, when it locks up it is annoying. In the winter it will become more urgent to keep running. To fix the issue I unplug the device, let it sit and plug it back in and it usually comes back up. Sometimes it takes a couple of unplugs. The device will respond to pings so I thought about pinging it and if I get no ping back cycle a SSR to reboot. Seemed reasonable to me and I came up with the attached flow. Spent way more time on this than I want but if anyone wants to give me a sanity check on my flow any (as Bart would say) constructive criticism is welcome.

[
    {
        "id": "39704ea55a129980",
        "type": "tab",
        "label": "ping keep alive",
        "disabled": false,
        "info": ""
    },
    {
        "id": "c621807af13fcf6c",
        "type": "inject",
        "z": "39704ea55a129980",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "1",
        "payloadType": "num",
        "x": 490,
        "y": 200,
        "wires": [
            [
                "399030b6831c907f"
            ]
        ]
    },
    {
        "id": "47e86b7096b6cecf",
        "type": "mqtt out",
        "z": "39704ea55a129980",
        "name": "reset controller",
        "topic": "reset_controller",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "18e102c7.a548f5",
        "x": 1920,
        "y": 240,
        "wires": []
    },
    {
        "id": "0856f858ac2df838",
        "type": "rpi-gpio out",
        "z": "39704ea55a129980",
        "name": "",
        "pin": "18",
        "set": true,
        "level": "1",
        "freq": "",
        "out": "out",
        "x": 1900,
        "y": 340,
        "wires": []
    },
    {
        "id": "399030b6831c907f",
        "type": "ping",
        "z": "39704ea55a129980",
        "protocol": "Automatic",
        "mode": "triggered",
        "name": "",
        "host": "192.168.1.22",
        "timer": "20",
        "inputs": 1,
        "x": 680,
        "y": 200,
        "wires": [
            [
                "f141c23acdbf1ae2",
                "394f979fcabf33a8"
            ]
        ]
    },
    {
        "id": "46c9f7a084ad7698",
        "type": "inject",
        "z": "39704ea55a129980",
        "name": "run ping",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "1",
        "payloadType": "num",
        "x": 480,
        "y": 280,
        "wires": [
            [
                "b109925cc3976b4e"
            ]
        ]
    },
    {
        "id": "b109925cc3976b4e",
        "type": "ping",
        "z": "39704ea55a129980",
        "protocol": "Automatic",
        "mode": "triggered",
        "name": "",
        "host": "192.168.1.223",
        "timer": "20",
        "inputs": 1,
        "x": 680,
        "y": 280,
        "wires": [
            [
                "f141c23acdbf1ae2",
                "394f979fcabf33a8"
            ]
        ]
    },
    {
        "id": "f141c23acdbf1ae2",
        "type": "function",
        "z": "39704ea55a129980",
        "name": "set payload",
        "func": "var msg;\nvar msg1;\nvar msg2;\n\n// @ts-ignore\nlet z = msg.payload;\n\nmsg = {\n    payload: 1,\n}\nmsg1 = {\n    payload: 660,\n}\nmsg2 = {\n    payload: 'close',\n}\n\n\n// @ts-ignore\nif (z === false) {\n    node.status({ fill: \"blue\", shape: \"dot\", text: msg1.payload });\n    return [msg1,null];\n}\n\nif (z != 0) {\n    node.status({ fill: \"blue\", shape: \"dot\", text: msg.payload });\n    return [null,msg];\n}\n\n\nnode.status({ fill: \"blue\", shape: \"dot\", text: msg.payload });\n\nreturn [null,null];",
        "outputs": 2,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 890,
        "y": 280,
        "wires": [
            [
                "15f593e0709a84a6"
            ],
            []
        ]
    },
    {
        "id": "388866fbd40fbda5",
        "type": "function",
        "z": "39704ea55a129980",
        "name": "status",
        "func": "var msg;\n\n// @ts-ignore\nmsg.payload = 0;\n\n\n\n\n// @ts-ignore\nnode.status({fill:\"blue\",shape:\"dot\",text:msg.payload});\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1370,
        "y": 280,
        "wires": [
            [
                "284a62078eb523d7"
            ]
        ]
    },
    {
        "id": "15f593e0709a84a6",
        "type": "function",
        "z": "39704ea55a129980",
        "name": "count 3 times",
        "func": "var msg = {};\n\n\nvar count = flow.get(\"counter\");\nnode.warn(count);\nif (typeof count == 'undefined'){\n    count = 0;\n}\n\ncount = (count+1);\n\nflow.set(\"counter\", count);\n\nif(count > 3){\n    node.status({fill:\"blue\",shape:\"dot\",text: 'done'});\n    flow.set(\"counter\",4);\n    return null;\n} \n\n//if (z === 0){\n//    return msg;\n//}\n\nnode.status({fill:\"blue\",shape:\"dot\",text: count});\n\n\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1160,
        "y": 280,
        "wires": [
            [
                "0a3acf5d9432349e",
                "388866fbd40fbda5"
            ]
        ]
    },
    {
        "id": "0a3acf5d9432349e",
        "type": "mytimeout",
        "z": "39704ea55a129980",
        "name": "every 15 minutes",
        "outtopic": "timer",
        "outsafe": "on",
        "outwarning": "",
        "outunsafe": "off",
        "warning": "0",
        "timer": "900",
        "debug": false,
        "ndebug": false,
        "ignoreCase": false,
        "repeat": false,
        "again": false,
        "x": 1090,
        "y": 180,
        "wires": [
            [],
            [
                "352e1fc6a5350757"
            ]
        ]
    },
    {
        "id": "352e1fc6a5350757",
        "type": "function",
        "z": "39704ea55a129980",
        "name": "watch for zero",
        "func": "let z = msg.payload;\n\nif (z === 0){\n    msg = {\n        combat: 'yes'\n    }\n    return msg;\n}\n\nreturn null;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1400,
        "y": 180,
        "wires": [
            [
                "15f593e0709a84a6"
            ]
        ]
    },
    {
        "id": "284a62078eb523d7",
        "type": "trigger",
        "z": "39704ea55a129980",
        "name": "",
        "op1": "0",
        "op2": "1",
        "op1type": "num",
        "op2type": "num",
        "duration": "15",
        "extend": false,
        "overrideDelay": false,
        "units": "s",
        "reset": "",
        "bytopic": "all",
        "topic": "topic",
        "outputs": 1,
        "x": 1590,
        "y": 280,
        "wires": [
            [
                "fd65861102f9eef3"
            ]
        ]
    },
    {
        "id": "fd65861102f9eef3",
        "type": "gate",
        "z": "39704ea55a129980",
        "name": "",
        "controlTopic": "control",
        "defaultState": "open",
        "openCmd": "open",
        "closeCmd": "close",
        "toggleCmd": "toggle",
        "defaultCmd": "default",
        "statusCmd": "status",
        "persist": false,
        "storeName": "default",
        "x": 1750,
        "y": 320,
        "wires": [
            [
                "0856f858ac2df838",
                "47e86b7096b6cecf"
            ]
        ]
    },
    {
        "id": "394f979fcabf33a8",
        "type": "function",
        "z": "39704ea55a129980",
        "name": "gate control",
        "func": "var msg;\nvar msg1;\nvar msg2;\n\n// @ts-ignore\nlet z = msg.payload;\n\nmsg = {\n    payload: 'open',\n    topic: 'control',\n}\nmsg1 = {\n    payload: 'close',\n    topic: 'control',\n}\nmsg2 = {\n    payload: 1,\n}\n\n\n// @ts-ignore\nif (z === false) {\n    node.status({ fill: \"blue\", shape: \"dot\", text: 'no ping' });\n    return msg;\n}\n\nif (z != 0) {\n    node.status({ fill: \"blue\", shape: \"dot\", text: 'good ping'});\n    node.send(msg2);\n    flow.set('counter',0);\n    node.send(msg2);\n    return msg1;\n}\n\nreturn null;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 910,
        "y": 360,
        "wires": [
            [
                "fd65861102f9eef3"
            ]
        ]
    },
    {
        "id": "735e29b7b019122f",
        "type": "inject",
        "z": "39704ea55a129980",
        "name": "bad ping",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "false",
        "payloadType": "bool",
        "x": 530,
        "y": 360,
        "wires": [
            [
                "f141c23acdbf1ae2",
                "394f979fcabf33a8"
            ]
        ]
    },
    {
        "id": "12d381e422f78001",
        "type": "inject",
        "z": "39704ea55a129980",
        "name": "good ping",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "5",
        "payloadType": "num",
        "x": 530,
        "y": 440,
        "wires": [
            [
                "f141c23acdbf1ae2",
                "394f979fcabf33a8"
            ]
        ]
    },
    {
        "id": "18e102c7.a548f5",
        "type": "mqtt-broker",
        "name": "local host",
        "broker": "127.0.0.1",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "sessionExpiry": ""
    }
]

the only non standard nodes are the contrib-simple-gate and mytimeout. The device sits at .223 and I use two inject nodes to test my flow. The other ping node returns a bad ping to check the flow.
The idea is to ping the device and if no ping turn off the pin for 15 seconds turn it back on. Wait 15 minutes and if no good ping turn off pin again, then wait. After three tries give up and leave the pin high. If I get a good ping at any time stop the timer or isolate the timer and leave pin on. I have a MQTT node in there as I haven't decided whether to tie the pin directly to the SSR and if it will be easier to use an ESP to control the SSR.

Hi.

I've read your problem and I have similar problems.

Couple of things I read which I think you need to check a bit more:

This doesn't sound right.
What I suspect is the problem here is that the machine is doing housekeeping and taking longer than normal to get back up and working.
Unplugging it a second time does fix the problem but maybe not in a desired way.

Pinging the machine is also not a good indication of Node-Red's state.
It could be pinged but Node-Red may be dead / unusable.

I have a similar set up, but what I do is send from Node-Red messages so I know Node-Red is alive. Not just that the machine can support being pinged.

What kind of machine is it running on?
(Though as there is a RasPiGPIO node, I'm guessing it is a RasPi)

Alas seeing that it is put down to the power supply causing the problem I would strongly suggest you spend the money and get a good one.
I have (kind of) been through these hoops and the grief and time lost is simply not worth it for the sake of a non-suitable power supply.

On this "suspect" machine, write a flow that sends out a message every.... n minutes.
On another machine.....

The problem here is that if Node-Red is dead, it is rather problematic to reset it.

What I am thinking of doing is making some hardware which will reset the machine.

This hardware won't be quite as simple as you may first think.
You need a timer which if not reset will activate an output which would then reset the RasPi.

That's a quick solution, but it has problems.
Scenario:
Normally the machine boots in......2 minutes and is up and working.
The hardware has a timeout of 3 minutes.

If it isn't reset before the 3 minutes, it reboots the machine.

Bad scenario
The machine takes more than 3 minutes to reboot.
It will then never boot.
Because after 3 minutes it will be given a reboot signal from the hardware.

Solution:
The hardware has TWO inputs.
1 - the I'm alive input which resets the timer.
2 - an ACTIVATE input.
This is crucial to stop runaway resets.
When the machine (finally) gets booted and running, it activates the hardware.
Then after 3 minutes if there is no input from the I'm alive input the output is activated and a reset signal is sent.
Once a reset signal is sent, the timer is disabled and needs the activate input to be set before it starts working again.

Hope that helps.

How about an Uninterruptable Power Supply? One with voltage regulation should work nicely.

Also what is the device voltage anyhow? If low 5v or 12v then just a 12v battery (with optional buck convertor if needed and a trickle charger/maintainer for the battery) bypassing whatever AC adapter it uses.

@Trying_to_learn -- it's not a pi running node red that is the problem, it's an industrial or rather agricultural machine "store bought" with an internet interface on it, I'm using node red to try to interrogate the machine and reset it. @Gunner I could put a UPS on it but the current draw in operation is substantial so buying a UPS while doable is -- not price effective or rather more of a last ditch purchase. At full load it's pulling 110VAC at about 20 amps. The pi is hooked to a lawn tractor battery with a automotive USB port on it and that whole thing is charged by a battery trickle charger. The pi seems to survive quite nicely on this setup and just keeps humming. The pi is hooked to a SSR rated at 480 VAC at 40 amps so is well within operating parameters to handle the machine power. The pi will cycle that SSR to reboot the machine. Hopefully the pi itself never needs to reset.

So... the RPi is NOT the device that tends to lock up, as referenced in this topic?

What IS the device you seem to need to ping and reboot?

An automatic feeder for my goats. As I say right now not critical they eat mostly in the field but when winter sets in the goats will be a little more touchy if they don't get fed.

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.