Node-RED nodes for hubitat

Well you can now pass "setColor" to HE via the Maker API using a map so that's handy..

On the receiving side you can set the device node to grab all attributes and parse them in a function node as needed.

I started down that path but got distracted by other stuff..

1 Like

Anyone have a better way of handling a switch using the Node Red UI?

Something like this which is similar but combines things into change nodes..

Note: I added the jsonata into the node names so you could see what I am doing. you can also convert directly to msg.command in the dashboard node...

edit: I don't think you need check for the light being on/off before sending the command. Not sure it really helps anything.

I probably don't need to check, but I figured not sending extraneous commands was a good thing. Glad I don't seem to be missing something obvious.

1 Like

@fblackburn

Newbie to Node-Red, seasoned on Hubitat. Trying to tie them together. I went through the tutorial and built the 2 new floods and reviewed the User Guide, but I can't seem how to launch the Hubitat config node.

Your help is invaluable.
Alan

The hubitat config node is abstract, you cannot add it to your flow like other nodes. It's only a configuration shared between nodes. When you add a node (ex: device node) then you have a server field and this server is the config node. It is automatically deployed when it exists
Peek 2020-07-14 06-40

You can view all configuration nodes with the following menu:
Screenshot from 2020-07-14 06-36-50

Did you look this tutorial too?

4 Likes

I can reiterate that. OwnTracks has worked perfectly for me for the last 3-4 months. Still haven't removed Life360, but am no longer using it.

1 Like

look into "node-red-contrib-arp".

.
:: sigh of relief ::

I am now completely off the alexa2 palette (in fact it's uninstalled). Used the Alexa Media Player integration in Home Assistant (HACS) instead and reworked my flows.

Of course this method says it uses the "experimental and unofficial Alexa API" so at some point this will break too lol

It breaks regularly, and requires regular updates which is why I Was just starting to look at the alexa2 palette when I saw your post. I have a flow that makes a random announcement based on who gets home. I'll get home, sit on the couch and start watching tv then it clues in that I didn't hear Alexa greet me. Hop on to HA and there's an update for the integration. Update it and all works again, it's just a little annoying. I'd say it's about 95% reliable which is around 4% too low for my likings.

Does anyone know of a method to backup the Hubitat nightly backup to a network share. I can backup to a directory on the Node Red device (pi/Odriod), but seem unable to backup to my NAS/network share.

1 Like

While I'm not a fan of his actual javascript coding style, you could definitely apply what he talks about in his post using the flow you got off me

Lots of factors though, first and foremost: "what OS is the target for saving?". Obviously if it's Windows or Mac you'll need to set up the permissions differently. And secondly, what/where NR is running (inside Docker? out?) is a factor as well to set up the mount

This sounds like somebody should make an app to automatically send these backups to google drive. If the files are accessible on the hub then it shouldn't be too dificult.

A couple of months ago, I found someone that posted a flow that will backup files to a Dropbox folder. I don't know how it works in the Function Node. I can share the flow if anyone is interested. I would assume that someone smarter than me could figure out how to tweak it to upload to a Google Drive instead.

5 Likes

Nope, missed that one, but it's a great video and has gotten over that hurdle! Now on to my first real flow!

Alan

1 Like

Please do!

1 Like

How are folks "running RM actions" via node-red? My thought was to make virtual switches for the actions and continue to have RM do the work but via a subscription to a virtual switch vs. being called from another RM action; perhaps I'm looking at it all wrong. Things I'm doing in actions that I can't do through MakerAPI (at least I don't think I can): running setFollowSchedule() for thermostats, also doing some custom HTTP calls to run the vacuum (with a charge action that cancels the clean action). I guess I could probably do the vacuum calls with http get nodes, but the cancelling actions would be new in node.

I am going to go out on a limb and say you can do anything in Node Red that you can do in RM; probably without adding virtual switches. If setFollowSchedule() is a command available to your thermostat, then you can do it in Node Red. Also, there is an HTTP Request Node in Node Red.

I am not sure what you mean by

Post one of your rules and one of us can probably help.

1 Like

FWIW Here's a screen cap of the settings of one of my Pearl thermostats.. I don't have setFollowSchedule() available to me but I do have other stuff.

And for some things yeah a virtual switch can do the trick. Still activating my Ring Doorbell that way. Echo->vswitch->NR->Bell

1 Like

See if this will import:

[{"id":"562a8ab2.b11ba4","type":"http request","z":"9035aa0c.21e758","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"http://192.168.68.XXX/hub/backup","tls":"","persist":false,"proxy":"","authType":"","x":190,"y":460,"wires":[["8fe80bc3.8d8f18"]]},{"id":"8fe80bc3.8d8f18","type":"cheerio-function","z":"9035aa0c.21e758","name":"parse html cheerio","func":"const tableSelector = '#backup-table'\n\n//const cheerio = global.get('cheerio')\n//const $ = cheerio.load(msg.payload)\nconst options = {\n    rowForHeadings: 0,  // extract th cells from this row for column headings (zero-based)\n    ignoreHeadingRow: true, // Don't tread the heading row as data\n    ignoreRows: [],\n}\nconst rowEntries = []\nconst columnHeadings = []\n\n\n$(tableSelector).each(function(i, table) {\n    node.log(\"Something happened\");\n\n    var trs = $(table).find('tr')\n    \n    // Set up the column heading names\n    getColHeadings( $(trs[options.rowForHeadings]) )\n\n    // Process rows for data\n    $(table).find('tr').each(processRow)\n})\n\nif (rowEntries.length === 0)\n    return null;\n\nmsg.payload = {\n    fileName: rowEntries[rowEntries.length-1].Name\n}\n\nreturn msg\n\nfunction getColHeadings(headingRow) {\n    const alreadySeen = {}\n    \n    $(headingRow).find('th').each(function(j, cell) {\n        let tr = $(cell).text().trim()\n        \n        if ( alreadySeen[tr] ) {\n            let suffix = ++alreadySeen[tr]\n            tr = `${tr}_${suffix}`\n        } else {\n            alreadySeen[tr] = 1\n        }\n        \n        columnHeadings.push(tr)\n    })\n}\n\nfunction processRow(i, row) {\n    const rowJson = {}\n    \n    if ( options.ignoreHeadingRow && i === options.rowForHeadings ) return\n    // TODO: Process options.ignoreRows\n    \n    $(row).find('td').each(function(j, cell) {\n        rowJson[ columnHeadings[j] ] = $(cell).text().trim()\n    })\n    \n    // Skip blank rows\n    if (JSON.stringify(rowJson) !== '{}') rowEntries.push(rowJson)\n}\n","outputs":1,"noerr":0,"x":410,"y":460,"wires":[["1fb51151.02e45f"]]},{"id":"a72d2620.9c98f8","type":"cronplus","z":"9035aa0c.21e758","name":"Run Backup","outputField":"payload","timeZone":"","outputs":1,"options":[{"topic":"AT115","payload":"","type":"date","expression":"0 15 4 * * *","name":"AT115"}],"x":130,"y":380,"wires":[["562a8ab2.b11ba4"]]},{"id":"1fb51151.02e45f","type":"http request","z":"9035aa0c.21e758","name":"","method":"GET","ret":"bin","paytoqs":true,"url":"http://192.168.68.XXX/hub/backupDB?","tls":"","persist":false,"proxy":"","authType":"basic","x":450,"y":380,"wires":[["416921.3835c6e","27560d30.1f5e42"]]},{"id":"416921.3835c6e","type":"string","z":"9035aa0c.21e758","name":"","methods":[{"name":"strip","params":[{"type":"str","value":"attachment; filename="}]},{"name":"prepend","params":[{"type":"str","value":"/home/pi/Shared/Hubitat/BackupDBs/"}]}],"prop":"headers.content-disposition","propout":"filename","object":"msg","objectout":"msg","x":630,"y":380,"wires":[["9e414f03.cc2fc"]]},{"id":"27560d30.1f5e42","type":"string","z":"9035aa0c.21e758","name":"","methods":[{"name":"strip","params":[{"type":"str","value":"attachment; filename="}]},{"name":"prepend","params":[{"type":"str","value":"/home/pi/Shared/Hubitat/BackupDBs/"}]}],"prop":"headers.content-disposition","propout":"filename","object":"msg","objectout":"msg","x":690,"y":480,"wires":[[]]},{"id":"9e414f03.cc2fc","type":"file","z":"9035aa0c.21e758","name":"","filename":"","appendNewline":false,"createDir":true,"overwriteFile":"true","encoding":"binary","x":770,"y":380,"wires":[["352e4f2a.5d889","fb1b02ca.3bbc9"]]},{"id":"352e4f2a.5d889","type":"string","z":"9035aa0c.21e758","name":"","methods":[{"name":"strip","params":[{"type":"str","value":"attachment; filename="}]},{"name":"strip","params":[{"type":"str","value":"/home/pi/shared"}]}],"prop":"headers.content-disposition","propout":"filename","object":"msg","objectout":"msg","x":970,"y":460,"wires":[["46ed5a9b.0abf94"]]},{"id":"fb1b02ca.3bbc9","type":"join-message","z":"9035aa0c.21e758","name":"","text":"The Hubitat Database was successfully backed up.","title":"HUBITAT DB BACKUP","url":"","notificationicon":"","joinConfig":"a9299c99.7096","x":1110,"y":300,"wires":[[]]},{"id":"46ed5a9b.0abf94","type":"dropbox out","z":"9035aa0c.21e758","dropbox":"","filename":"","localFilename":"","name":"Upload","x":1190,"y":460,"wires":[]},{"id":"a9299c99.7096","type":"join-config","z":"","name":"Stephens Cell Phone","register":true}]
2 Likes