Presence based on Uptime Kuma

We were discussing some reliable ways to help with presence. CORE uses Uptime Kuma for monitoring things and it fits the bill perfectly. Set up a monitor for your cell phones and run it through node red to go with presence.

The minimum ping is 20 seconds.

It is VERY important that you don’t have more than one https node. Connect subsequent devices to it or it tends to break things. Filter from there.

Open Uptime Kuma on the CORE desktop.
If it does not open - enable it using putty

sudo oll-uptime-kuma --enable

It’s an easy to understand interface.

Presence can be possible in this way on CORE if you’re looking for a second verification.

Open Uptime Kuma on CORE Desktop
Go to settings in the upper right corner.
Click Notifications
Set up notification
(See Screenshot)
The test will fail at this point. Don’t worry about that.
Click Save

Next go to the main screen and click Add new monitor in the upper left hand corner.
Set up the ping to your phone. Use your IP address.

Go to node red and import this flow. You can adjust for your use case
Hostname is the device IP you’re monitoring. 1 per device.

[{"id":"e5eea344c20c87aa","type":"http in","z":"7ea61b2d.ccb734","name":"uptime kuma","url":"/webhook/uptime-kuma","method":"post","upload":false,"swaggerDoc":"","x":150,"y":200,"wires":[["0763fe5659fce5ec","12e505fd45c94bfb","bea96740494af949"]]},{"id":"0763fe5659fce5ec","type":"debug","z":"7ea61b2d.ccb734","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":430,"y":200,"wires":[]},{"id":"12e505fd45c94bfb","type":"http response","z":"7ea61b2d.ccb734","name":"","statusCode":"200","headers":{},"x":420,"y":160,"wires":[]},{"id":"f9809cfedf8fb309","type":"switch","z":"7ea61b2d.ccb734","name":"Up/Down?","property":"payload.heartbeat.status","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":370,"y":360,"wires":[["974e3a6b3d9b4d5a"],["9b391ef52bd3fab9"]]},{"id":"ee79225bc8ec2528","type":"switch","z":"7ea61b2d.ccb734","name":"Hostname?","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"192.168.9.37","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":350,"y":300,"wires":[["f9809cfedf8fb309"]]},{"id":"974e3a6b3d9b4d5a","type":"change","z":"7ea61b2d.ccb734","name":"Down","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":340,"wires":[["04146cfcaefc7e17"]]},{"id":"9b391ef52bd3fab9","type":"change","z":"7ea61b2d.ccb734","name":"Up","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":380,"wires":[["04146cfcaefc7e17"]]},{"id":"04146cfcaefc7e17","type":"debug","z":"7ea61b2d.ccb734","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":730,"y":360,"wires":[]},{"id":"bea96740494af949","type":"change","z":"7ea61b2d.ccb734","name":"Hostname as topic","rules":[{"t":"set","p":"topic","pt":"msg","to":"payload.monitor.hostname","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":250,"y":260,"wires":[["ee79225bc8ec2528"]]}]
4 Likes

How to enable Uptime Kuma. Mine is disabled, and I looked through the notes.

sudo oll-uptime-kuma --enable
sudo oll-uptime-kuma --start

A post was split to a new topic: Terminal in CORE

To be difficult, but the example flow sets up to false instead of true :stuck_out_tongue:

1 Like

Well we need to throw a corkscrew in somewhere!
:rofl:

1 Like

Great little sequence @april.brandt as always, got one simple improvement to make this data more easily accessible and scalable.

I adjusted some of the nodes around so that the “hostname” check is after the up/down check (actually thinking about it further this check could be removed altogether, but I digress) and then added a function node (very simple function, but I could not find a way to manipulate the switch node to do what I wanted) that generates a global variable with the boolean payload as the value and named the topic (in your flow the hostname, but I adjusted it to the monitor.name value which is the friendly name inside kuma.

NOTE: friendly name inside Kuma cannot have any spaces in it otherwise the global context variable fails to create.


Note: this version I just removed the name check at the end so that all new monitors added to kuma will appear immediately as global variables.

function node:
global.set(msg.topic,msg.payload,“file”);

[{"id":"e5eea344c20c87aa","type":"http in","z":"95de14ceabf28b50","name":"uptime kuma","url":"/webhook/uptime-kuma","method":"post","upload":false,"swaggerDoc":"","x":110,"y":200,"wires":[["0763fe5659fce5ec","12e505fd45c94bfb","bea96740494af949"]]},{"id":"0763fe5659fce5ec","type":"debug","z":"95de14ceabf28b50","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":270,"y":200,"wires":[]},{"id":"12e505fd45c94bfb","type":"http response","z":"95de14ceabf28b50","name":"","statusCode":"200","headers":{},"x":120,"y":160,"wires":[]},{"id":"f9809cfedf8fb309","type":"switch","z":"95de14ceabf28b50","name":"Up/Down?","property":"payload.heartbeat.status","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":310,"y":240,"wires":[["974e3a6b3d9b4d5a"],["9b391ef52bd3fab9"]]},{"id":"974e3a6b3d9b4d5a","type":"change","z":"95de14ceabf28b50","name":"Down","rules":[{"t":"set","p":"payload","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":220,"wires":[["04146cfcaefc7e17","b4981e51fdc3543d"]]},{"id":"9b391ef52bd3fab9","type":"change","z":"95de14ceabf28b50","name":"Up","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":260,"wires":[["04146cfcaefc7e17","b4981e51fdc3543d"]]},{"id":"04146cfcaefc7e17","type":"debug","z":"95de14ceabf28b50","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":590,"y":220,"wires":[]},{"id":"bea96740494af949","type":"change","z":"95de14ceabf28b50","name":"Name as topic","rules":[{"t":"set","p":"topic","pt":"msg","to":"payload.monitor.name","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":140,"y":240,"wires":[["f9809cfedf8fb309"]]},{"id":"b4981e51fdc3543d","type":"function","z":"95de14ceabf28b50","name":"Update Global","func":"global.set(msg.topic,msg.payload,\"file\");","outputs":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":620,"y":260,"wires":[]}]

image
image

1 Like

“.replaceAll(’ ', ‘_’)” could help with that :wink:
EDIT: changed to replaceAll

1 Like

like this?
global.set(msg.topic.replace(’ ', ‘_’),msg.payload,“file”);

yes, like that, but with replaceAll, too many different languages lately…

1 Like

just .replace seemed to work fine for me, does that only do the first instance or something?

yes, when doing string replace, in order to do all, replaceAll is needed. replace can replace all when using a regex replace.

1 Like

Interestingly, when I add a new monitor it does not seem to create a global variable, but when I manually cycle it to be down and then back up (putting an invalid IP) it works fine and a new one is created and updated. Any thoughts? Like enough time and storing on the disk will sort this out 99/100 times but still.

Additionally, while these variables could be used as conditions (for presence as the title hints at), I wonder if they could be used for triggers as well (like for a internet status and restoration sequence) or if there would be a better method to do this. It seems like using context variables as a trigger is non-trivial, so I was thinking using every post from the uptime kuma http in node as a link out trigger and then look at the variable you care about from there. I definitely see issues with this method though as there is a lot of extra checks if I have multiple sequences using it.

Not beyond the fact that I’ve never seen anything like that, is the message getting all the way to the function node?

Putting a link out node at the end and connecting to from wherever you need the trigger is a common model for that. @april.brandt is using that extensively.

1 Like

Nope, just made a new monitor pinging a valid address and nothing came out of the http in node. Trying an invalid now.

Update: Interesting, an invalid one gets pushed out immediately.
image
image

Uptime Kuma doesn’t send valid if it already was valid, it needs to be a change from invalid to valid.

Yeah I just assumed that it would initially send something out on a new monitor to initialize.


Figured out a dirty workaround using the PING function at least, you can turn Upside Down Mode for initial creation, then turn it off immediately.

Advanced

Upside Down Mode

Flip the status upside down. If the service is reachable, it is DOWN.


If there was a way to pull the status of all monitors that would be great, that way we can just use RAM storage versus file and then on boot of CORE pull the current status once and any old monitors would automatically get cleaned up.

This is some interesting math that Uptime Kuma is doing :rofl:
image

2 Likes

Uptime Kuma is trying to predict the future, 0.15% of the future based on the time monitoring has been running, the device/service is also going to be online :stuck_out_tongue: Advanced modern AI…

1 Like