Node-Red Flow Samples/Sharing

Restart Homebridge on HE reboot/power cycle

I was having an issue with Homebridge log showing errors if HE was restarted and Homebridge was not

The errors appear to be harmless but I was looking for a way to automatically restart Homebridge process when HE was restarted. It turns out that the Homebridge UI plug-in has an API that can be accessed from Node-RED.

The following flow automatically restarts Homebridge if HE is restarted.

It uses standard nodes (Change, Delay, Function, HTTP Request) and the node-red-contrib-credentials (node-red-contrib-credentials (node) - Node-RED) for username, password and the IP address/port of the Homebridge server.

The flow is triggered by the link-in from the Hub systemStart location event on another flow. The flow execution is delayed for 2 minutes to ensure that HE has finished rebooting. It then logs into Homebridge and calls the restart API (similar to the user selecting the "restart" button in the Homebridge UI)

Below is the flow if anyone wants it.

NOTE: The log errors seem to be only with the MakerAPI Homebridge plug-in

[{"id":"b4ab3d8b.fdbf5","type":"group","z":"934f1005.6e02","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["f4c6b858.26b3e8","166fcda7.a1102a","695cbfba.6f73a","acf9ac7f.7b6e7","122304c7.f7beeb","e7ca8e9a.de2618","4012e6a2.c3064","e603b57e.6c9968","1122835a.5ff315","bd279032.bec948","8576170d.ec4a38","d98d244.6275758"],"x":43.33332824707031,"y":2490.0000381469727,"w":1339.6667022705078,"h":323.99996185302734},{"id":"f4c6b858.26b3e8","type":"link in","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"","links":["d22ba984.19a1e"],"x":97.33332824707031,"y":2583.0000381469727,"wires":[["166fcda7.a1102a"]]},{"id":"166fcda7.a1102a","type":"change","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"Delete Payload","rules":[{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":236.33334350585938,"y":2582,"wires":[["695cbfba.6f73a"]]},{"id":"695cbfba.6f73a","type":"delay","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"Delay 2 Mins","pauseType":"delay","timeout":"2","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":431.3333435058594,"y":2583,"wires":[["acf9ac7f.7b6e7"]]},{"id":"acf9ac7f.7b6e7","type":"credentials","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"","props":[{"value":"payload.username","type":"msg"},{"value":"payload.password","type":"msg"},{"value":"HB_IP","type":"msg"}],"x":177,"y":2652.33349609375,"wires":[["e7ca8e9a.de2618"]]},{"id":"122304c7.f7beeb","type":"inject","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"Manual Restart","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":186,"y":2709.33349609375,"wires":[["acf9ac7f.7b6e7"]]},{"id":"e7ca8e9a.de2618","type":"function","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"Set Login URL and Headers","func":"//Set URL for Homebrdige login and header for Content Type\n\nmsg.url = msg.HB_IP+'/api/auth/login'\nmsg.headers = 'Content-Type: application/json'\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":401.333251953125,"y":2653.0002365112305,"wires":[["4012e6a2.c3064"]]},{"id":"4012e6a2.c3064","type":"http request","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"Login and get Token","method":"POST","ret":"obj","paytoqs":"body","url":"","tls":"","persist":false,"proxy":"","authType":"","x":654.9999542236328,"y":2652.0002059936523,"wires":[["e603b57e.6c9968"]]},{"id":"e603b57e.6c9968","type":"function","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"Set Restart URL and Headers","func":"var token = msg.payload.access_token;\nmsg.headers = {\n     Authorization: \"Bearer \"+token\n}\nmsg.url = msg.HB_IP+'/api/server/restart'\n\n//Delete unneeded messager parts\ndelete msg.HB_IP\ndelete msg.payload.access_token\ndelete msg.payload.token_type\ndelete msg.payload.expires_in\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":912.3333129882812,"y":2651.0002059936523,"wires":[["1122835a.5ff315"]]},{"id":"1122835a.5ff315","type":"http request","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"Restart Homebridge","method":"PUT","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":1172.0000381469727,"y":2650.6669921875,"wires":[["bd279032.bec948"]]},{"id":"bd279032.bec948","type":"debug","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"RESTART RETURN","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1237.0000305175781,"y":2704.33349609375,"wires":[]},{"id":"8576170d.ec4a38","type":"comment","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"Restart Homebridge on HE reboot","info":"","x":213.3333282470703,"y":2531.0000381469727,"wires":[]},{"id":"d98d244.6275758","type":"comment","z":"934f1005.6e02","g":"b4ab3d8b.fdbf5","name":"Change Log","info":"2021-05-23: Created","x":139.3333282470703,"y":2773,"wires":[]}]

Hope this helps someone!

1 Like

Wanted to post this here as well in case anyone is interested - this is a very simple example of a Finite State Machine aggregating a "motion sensor" and a "contact sensor" and putting the results in a switch node for fun and easy processing:

1 Like

Putting this here in in case anyone's been experiencing issues with casting TTS to Chromecast groups. I battled with this for months. Basically, the IP/Port for Cast Groups can change from time to time and are therefore super annoying all the time. This flow browses _googlecast._tcp nodes and uses the output to generate the most up to date IP/port for the chosen cast group before sending the TTS request.

Note: I implemented this on an Ubuntu box. You will need to install the avahi-utils package prior to running. For a Windows node-red installation, I'm sure it can be done, but this certainly won't work out of the box without modifications.

[{"id":"ce1430ad.2794e","type":"cast-to-client","z":"7b31a85e.379d78","name":"Google Home - Non-specific","url":"","contentType":"","message":"","language":"en","ip":"","port":"","volume":"","x":1420,"y":420,"wires":[[]],"icon":"node-red-contrib-cast/google-home1.svg"},{"id":"c15ad04f.c266c","type":"looptimer2","z":"7b31a85e.379d78","duration":"2","units":"Second","maxloops":"100","maxtimeout":"1","maxtimeoutunits":"Hour","name":"","x":260,"y":420,"wires":[["d6fbebd5.7edfa8"],[]]},{"id":"84e21e46.de69a","type":"change","z":"7b31a85e.379d78","name":"Prepare Message","rules":[{"t":"move","p":"strArray[7]","pt":"msg","to":"ip","tot":"msg"},{"t":"move","p":"strArray[7]","pt":"msg","to":"port","tot":"msg"},{"t":"delete","p":"payload","pt":"msg"},{"t":"delete","p":"rc","pt":"msg"},{"t":"delete","p":"parts","pt":"msg"},{"t":"delete","p":"strArray","pt":"msg"},{"t":"delete","p":"castTarget","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1170,"y":420,"wires":[["8d038b77.ebe8e8","ce1430ad.2794e"]]},{"id":"bac40b3f.e56ac8","type":"inject","z":"7b31a85e.379d78","name":"","props":[{"p":"message","v":"This is a test cast.","vt":"str"},{"p":"topic","vt":"str"},{"p":"castTarget","v":"Study Display","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"Test Message","payloadType":"str","x":180,"y":480,"wires":[["c15ad04f.c266c"]]},{"id":"dac0804a.613e6","type":"split","z":"7b31a85e.379d78","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":610,"y":420,"wires":[["b69ff338.2498b"]]},{"id":"b69ff338.2498b","type":"change","z":"7b31a85e.379d78","name":"","rules":[{"t":"set","p":"strArray","pt":"msg","to":"$split(payload, ';')\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":420,"wires":[["8f82c7c8.2b82a8"]]},{"id":"8f82c7c8.2b82a8","type":"switch","z":"7b31a85e.379d78","name":"Cast Targets","property":"strArray[9]","propertyType":"msg","rules":[{"t":"cont","v":"'fn='&castTarget","vt":"jsonata"}],"checkall":"true","repair":false,"outputs":1,"x":970,"y":420,"wires":[["dc03a87a.71e0f8","8d038b77.ebe8e8","84e21e46.de69a"]]},{"id":"8d038b77.ebe8e8","type":"debug","z":"7b31a85e.379d78","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1130,"y":460,"wires":[]},{"id":"d6fbebd5.7edfa8","type":"exec","z":"7b31a85e.379d78","command":"avahi-browse","addpay":false,"append":"_googlecast._tcp -rtp","useSpawn":"false","timer":"","oldrc":false,"name":"","x":450,"y":420,"wires":[["dac0804a.613e6"],[],[]]}]

Also note: The process is wrapped in a 2 second loop because sometimes the cast group doesn't show up in the avahi-browse command the first time. It'll just keep retrying until it finds the castTarget you are looking for.

1 Like

That is cool - never considered using NR to search the network for services like that. Usually I provide reserved DHCP's to everything but a residential client of mine has an ISP that does not allow this feature so something like this might be very useful.

Have you tried the node-red-node-discovery node? Seems a little dated but maybe okay.

Yeah, I tried that and attempted to keep a variable up to date. Unfortunately, either the mdns broadcasts didn't happen or the node didn't catch them so I figured a on-demand browse might help. I haven't figured out how to do an mdns resolution for a specific cast group so this'll have to do.

If anyone knows how to do that on cast groups, I'm all ears!

1 Like

Flow for writing HE logs to a DB and sending an alert if the log level is not "info" or "debug"

I created a small flow to write Hubitat logs to a database as I was finding it hard to delve through the native logs. I tacked on the ability to send an SMS/Email based on the log "level".

Below is the basic flow. I am including the code for the nodes outlined in red but PM me if you need the entire flow.

Flow:

[{"id":"36966e59.07b402","type":"websocket in","z":"7b994e31.f24a6","g":"717554fa.f8ae14","name":"Hubitat Log Socket","server":"96044230.8127a","client":"","x":197.6666259765625,"y":2119.333251953125,"wires":[["57aaa540.2a5b84","4cac1755.deddd","9fdfa8df.0fde48"]]},{"id":"57aaa540.2a5b84","type":"function","z":"7b994e31.f24a6","g":"717554fa.f8ae14","name":"Log SQL","func":"var sqlString = 'INSERT INTO LOGS (NAME,MSG,ID,TIME,TYPE, LEVEL)VALUE ('\nvar quote = \"'\"\nvar comma = \",\"\nsqlString +=quote+msg.name+quote+comma\nsqlString +=quote+msg.msg+quote+comma\nsqlString +=msg.id+comma\nsqlString +=quote+msg.time+quote+comma\nsqlString +=quote+msg.type+quote+comma\nsqlString +=quote+msg.level+quote+\")\"\n\n//sqlString = sqlString+quote+msg.name+quote+comma+quote+msg.msg+quote+\",\"+msg.id+\",\"+msg.time+\",\"+msg.type+\",\"+msg.level+\")\"\nmsg.topic = sqlString\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":431.99993896484375,"y":2119.333381652832,"wires":[["c0a6c5c4.10901"]]},{"id":"4cac1755.deddd","type":"debug","z":"7b994e31.f24a6","g":"717554fa.f8ae14","name":"Log Socket Debug","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":238.33331298828125,"y":2185,"wires":[]},{"id":"9fdfa8df.0fde48","type":"switch","z":"7b994e31.f24a6","g":"717554fa.f8ae14","name":"Not Info or Debug","property":"level in [\"info\",\"debug\"]","propertyType":"jsonata","rules":[{"t":"false"}],"checkall":"true","repair":false,"outputs":1,"x":474.33331298828125,"y":2181,"wires":[["97cb985e.2d933"]]},{"id":"97cb985e.2d933","type":"change","z":"7b994e31.f24a6","g":"717554fa.f8ae14","name":"Format for SMS/Email","rules":[{"t":"set","p":"message","pt":"msg","to":"msg","tot":"msg"},{"t":"delete","p":"msg","pt":"msg"},{"t":"set","p":"topic","pt":"msg","to":"\"Log: \"&level&\" - \"&name","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"\"Date/Time: \"&time&\"\\n\"&\"Message: \"&message","tot":"jsonata"},{"t":"set","p":"to","pt":"msg","to":"$globalContext(\"rakeshSMS\")&\",\"&$globalContext(\"rakeshEmail\")","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":721.3333435058594,"y":2181.999885559082,"wires":[["8c34dafb.a6673"]]},{"id":"96044230.8127a","type":"websocket-listener","path":"ws://192.168.1.113/logsocket","wholemsg":"true"}]

Hope this helps someone.

5 Likes

Does anyone have any flows that capture the time stamp? I'm not quite sure how to capture this. I'm looking to capture the timestamp each time my thermostat changes state and put this timestamp into a variable for each "cooling" and "idle" the use the two variables to subtract from one another so that it gives me the last run cycle time.

I am going by memory when I needed to do the same but I think this would work for you to create a Change Node:
image

I don't use it currently.

3 Likes

You can also use node-red-contrib-moment (node) - Node-RED if you want to get the time stamp to be timezone specific. The JSONATA expression also gives the current date/time but it is in UTC.

Here is an example of how the node is configured:

3 Likes

That's the one I use

2 Likes

Is it possible to have that output format just have the time, leaving out the date? Would it work if I remove the date format in it?

I will play with this after my next hvac cycle to see if what I have right now will work or not.

1 Like

Yes - just remove the date part and the output will look like this.

Screen Shot 2021-06-11 at 9.31.38 AM

2 Likes

Me too!

Example of using DS Audio to cast random music to a music player and turn on the amp using a Smartthings button. Doubletap to go to the next song.

code

[{"id":"d5542f72.ae62d","type":"change","z":"41d8ca49.8ee574","name":"","rules":[{"t":"set","p":"payload.songs","pt":"msg","to":"payload.songs.id","tot":"jsonata"},{"t":"set","p":"payload.id","pt":"msg","to":"uuid:f76642ae-27bc-945b-ffff-ffff81f74f04","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":940,"y":360,"wires":[["7f559795.ef6888"]]},{"id":"786e29ee.1bdf58","type":"change","z":"41d8ca49.8ee574","name":"","rules":[{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload.limit","pt":"msg","to":"$count(payload.songs.id)","tot":"jsonata"},{"t":"set","p":"payload.songs","pt":"msg","to":"[]","tot":"json"},{"t":"set","p":"payload.offset","pt":"msg","to":"0","tot":"num"},{"t":"set","p":"payload.library","pt":"msg","to":"shared","tot":"str"},{"t":"set","p":"payload.id","pt":"msg","to":"uuid:f76642ae-27bc-945b-ffff-ffff81f74f04","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":960,"y":440,"wires":[["64d4440f.d5a51c"]]},{"id":"19f16f6a.7c8d71","type":"change","z":"41d8ca49.8ee574","name":"","rules":[{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload.action","pt":"msg","to":"play","tot":"str"},{"t":"set","p":"payload.id","pt":"msg","to":"uuid:f76642ae-27bc-945b-ffff-ffff81f74f04","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1260,"y":360,"wires":[["1c1cde8d.9c90f1"]]},{"id":"d34dd165.d2008","type":"change","z":"41d8ca49.8ee574","name":"","rules":[{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload.sort_by","pt":"msg","to":"random","tot":"str"},{"t":"set","p":"payload.limit","pt":"msg","to":"100","tot":"num"},{"t":"set","p":"payload.id","pt":"msg","to":"uuid:f76642ae-27bc-945b-ffff-ffff81f74f04","tot":"str"},{"t":"set","p":"payload.library","pt":"msg","to":"shared","tot":"str"},{"t":"delete","p":"topic","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":620,"y":360,"wires":[["251532ce.39b08e"]]},{"id":"90f7a0b5.06","type":"change","z":"41d8ca49.8ee574","name":"","rules":[{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload.id","pt":"msg","to":"uuid:f76642ae-27bc-945b-ffff-ffff81f74f04","tot":"str"},{"t":"set","p":"payload.action","pt":"msg","to":"stop","tot":"str"},{"t":"delete","p":"topic","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":630,"y":440,"wires":[["b4f97b98.aec148"]]},{"id":"251532ce.39b08e","type":"DS Audio","z":"41d8ca49.8ee574","dsm":"944d5151.862c6","name":"","topic":"listSongs","payload":"","x":780,"y":360,"wires":[["d5542f72.ae62d"]]},{"id":"7f559795.ef6888","type":"DS Audio","z":"41d8ca49.8ee574","dsm":"944d5151.862c6","name":"","topic":"updatePlayListRemotePlayer","payload":"","x":1100,"y":360,"wires":[["19f16f6a.7c8d71"]]},{"id":"1c1cde8d.9c90f1","type":"DS Audio","z":"41d8ca49.8ee574","dsm":"944d5151.862c6","name":"","topic":"controlRemotePlayer","payload":"","x":1440,"y":360,"wires":[[]]},{"id":"64d4440f.d5a51c","type":"DS Audio","z":"41d8ca49.8ee574","dsm":"944d5151.862c6","name":"","topic":"updatePlayListRemotePlayer","payload":"","x":1120,"y":440,"wires":[[]]},{"id":"b4f97b98.aec148","type":"DS Audio","z":"41d8ca49.8ee574","dsm":"944d5151.862c6","name":"","topic":"controlRemotePlayer","payload":"","x":800,"y":440,"wires":[["786e29ee.1bdf58"]]},{"id":"51f54ce8.9eb8e4","type":"hubitat device","z":"41d8ca49.8ee574","deviceLabel":"Audio: Craig","name":"","server":"b5eb352.57bc6c8","deviceId":"136","attribute":"switch","sendEvent":false,"x":310,"y":400,"wires":[["e20a6905.8ef968"]]},{"id":"e20a6905.8ef968","type":"switch","z":"41d8ca49.8ee574","name":"Off?","property":"payload.value","propertyType":"msg","rules":[{"t":"eq","v":"off","vt":"str"},{"t":"neq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":450,"y":400,"wires":[["d34dd165.d2008","b66b24a6.f6eec8"],["90f7a0b5.06","6956695a.1832a8"]]},{"id":"b66b24a6.f6eec8","type":"hubitat command","z":"41d8ca49.8ee574","deviceLabel":"Audio: Craig","name":"","server":"b5eb352.57bc6c8","deviceId":"136","command":"on","commandArgs":"","x":570,"y":300,"wires":[[]]},{"id":"6956695a.1832a8","type":"hubitat command","z":"41d8ca49.8ee574","deviceLabel":"Audio: Craig","name":"","server":"b5eb352.57bc6c8","deviceId":"136","command":"off","commandArgs":"","x":550,"y":500,"wires":[[]]},{"id":"92909fe9.55e1b","type":"DS Audio","z":"41d8ca49.8ee574","dsm":"944d5151.862c6","name":"","topic":"controlRemotePlayer","payload":"","x":480,"y":200,"wires":[[]]},{"id":"63da3e79.05d71","type":"change","z":"41d8ca49.8ee574","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"controlRemotePlayer","tot":"str"},{"t":"set","p":"payload.id","pt":"msg","to":"uuid:f76642ae-27bc-945b-ffff-ffff81f74f04","tot":"str"},{"t":"set","p":"payload.action","pt":"msg","to":"next","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":200,"wires":[["92909fe9.55e1b"]]},{"id":"eefd01bb.ba5ba","type":"hubitat device","z":"41d8ca49.8ee574","deviceLabel":"Audio: Craig Button","name":"","server":"b5eb352.57bc6c8","deviceId":"192","attribute":"doubleTapped","sendEvent":true,"x":110,"y":200,"wires":[["63da3e79.05d71"]]},{"id":"4b269378.8a970c","type":"hubitat device","z":"41d8ca49.8ee574","deviceLabel":"Audio: Craig Button","name":"","server":"b5eb352.57bc6c8","deviceId":"192","attribute":"pushed","sendEvent":true,"x":110,"y":400,"wires":[["51f54ce8.9eb8e4"]]},{"id":"944d5151.862c6","type":"DS Config","name":"","protocol":"http","apiVersion":"6.0.2"},{"id":"b5eb352.57bc6c8","type":"hubitat config","name":"","usetls":false,"host":"192.168.1.52","port":"80","appId":"79","nodeRedServer":"http://192.168.1.53:1880","webhookPath":"/hubitat/webhook","autoRefresh":true,"useWebsocket":false}]

1 Like

Imported this one to today, I needed to escape the quotation marks in the functions to overcome the errors others reported. ie "Welcome Home" to \"Welcome Home\"
I have not converted to Hubitat yet, but happy I worked this out in first days of using Node-Red.

Example turns ON my pool named "Pool Pump" then OFF after a delay (hours) as set by the dim level of a Virtual Dimmer named "Skimmer". Dim Level (hours of pool pump run) is restricted between 1 to 6 in the flow, over 6% dim reverts to 6 (just my choice - change for your needs). Includes HH:MM:SS countdown timer until OFF and Pool Pump switch status in UI. The Skimmer is set to OFF and Dim Level 0 to 'reset' it for the next time. Requesting a dimmer in HE to turn ON at the last dimmed level does not send a Dim Level command, so it's not available to Node Red. Flow requires both ON and Dim Level to execute to hinder miss-operation.

Usage: "Alexa, set the Skimmer to 4" - pool runs for 4 hours
Required Paletts: node-red-dashboard, node-red-contrib-countdown
Pool Pump Z-Wave Relay: NuTone NFS20Z

Code

[{"id":"d4321234.393ba","type":"tab","label":"Pool AI","disabled":false,"info":""},{"id":"3bd8dbb7.cfe7f4","type":"hubitat device","z":"d4321234.393ba","deviceLabel":"Skimmer","name":"","server":"a16ac10e.d53f2","deviceId":"847","attribute":"","sendEvent":true,"x":80,"y":80,"wires":[["d33b0435.a4aaf8"]]},{"id":"d33b0435.a4aaf8","type":"switch","z":"d4321234.393ba","name":"","property":"payload.value","propertyType":"msg","rules":[{"t":"btwn","v":"1","vt":"num","v2":"100","v2t":"num"},{"t":"eq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":210,"y":80,"wires":[["7c8f120c.3955ac"],["98917233.8107d"]]},{"id":"7c8f120c.3955ac","type":"change","z":"d4321234.393ba","name":"Delay","rules":[{"t":"set","p":"delay","pt":"msg","to":"payload.value","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"Delay","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":60,"wires":[["3e4d52ab.625ace"]]},{"id":"a03a00da.98a01","type":"function","z":"d4321234.393ba","name":"Seconds","func":"var delay = 1;\nif (msg.payload.Delay.value > 0) {\n delay = msg.payload.Delay.value;\n}\nif (delay > 6) delay = 6;\nmsg.delay = (delay * 3600);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":80,"wires":[["b09d3114.368b2"]]},{"id":"31c921a8.e58b4e","type":"hubitat command","z":"d4321234.393ba","deviceLabel":"Pool Pump","name":"","server":"a16ac10e.d53f2","deviceId":"149","command":"on","commandArgs":"","x":1190,"y":40,"wires":[["c35539d3.eb4c08"]]},{"id":"5154c4a1.41378c","type":"hubitat command","z":"d4321234.393ba","deviceLabel":"Pool Pump","name":"","server":"a16ac10e.d53f2","deviceId":"149","command":"off","commandArgs":"","x":1190,"y":100,"wires":[["c35539d3.eb4c08"]]},{"id":"c35539d3.eb4c08","type":"hubitat command","z":"d4321234.393ba","deviceLabel":"Skimmer","name":"","server":"a16ac10e.d53f2","deviceId":"847","command":"off","commandArgs":"","x":1340,"y":60,"wires":[["08b72e7f9a6c75b8"]]},{"id":"98917233.8107d","type":"change","z":"d4321234.393ba","name":"Switch","rules":[{"t":"set","p":"switch","pt":"msg","to":"payload.value","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"Switch","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":100,"wires":[["3e4d52ab.625ace"]]},{"id":"3e4d52ab.625ace","type":"join","z":"d4321234.393ba","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":450,"y":80,"wires":[["a03a00da.98a01"]]},{"id":"b09d3114.368b2","type":"change","z":"d4321234.393ba","name":"Delay","rules":[{"t":"set","p":"payload","pt":"msg","to":"delay","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"},{"t":"delete","p":"delay","pt":"msg"},{"t":"delete","p":"switch","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":710,"y":80,"wires":[["aa8804ca.299348"]]},{"id":"aa8804ca.299348","type":"countdown","z":"d4321234.393ba","name":"","topic":"","payloadTimerStart":"true","payloadTimerStartType":"str","payloadTimerStop":"false","payloadTimerStopType":"str","timer":"30","resetWhileRunning":true,"setTimeToNewWhileRunning":true,"startCountdownOnControlMessage":true,"x":870,"y":80,"wires":[["eec2288c547d307a"],["b0ede13d.94b71"]]},{"id":"5d84d31d.7fa3dc","type":"ui_text","z":"d4321234.393ba","group":"72fc319.cc425d","order":9,"width":"6","height":"1","name":"","label":"Pool Timer","format":"{{msg.payload}}","layout":"row-spread","x":1210,"y":200,"wires":[]},{"id":"b0ede13d.94b71","type":"function","z":"d4321234.393ba","name":"","func":"// Time HH:MM:SS from number\n\n// Hours\nvar Hours = ((msg.payload)/3600);\nHours = Math.floor(Hours);\n\n// Minutes\nvar Minutes = (msg.payload-(Hours3600))/60;\nMinutes = Math.floor(Minutes);\n\n// Seconds\nvar Seconds = (msg.payload-(Hours3600)-(Minutes*60));\n\n// Concatenate\nvar Time = Hours+':'+('0' +Minutes).slice(-2)+':'+('0' +Seconds).slice(-2);\n\nmsg.payload = Time;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1060,"y":200,"wires":[["5d84d31d.7fa3dc"]]},{"id":"0ff9446f4e2b45c8","type":"hubitat device","z":"d4321234.393ba","deviceLabel":"Pool Pump","name":"","server":"a16ac10e.d53f2","deviceId":"149","attribute":"switch","sendEvent":true,"x":430,"y":140,"wires":[["3054609e5d8601c1","3ef714c47ba61f23"]]},{"id":"3054609e5d8601c1","type":"switch","z":"d4321234.393ba","name":"Off?","property":"payload.value","propertyType":"msg","rules":[{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":590,"y":140,"wires":[["69a2c38666e5e97e"]]},{"id":"69a2c38666e5e97e","type":"change","z":"d4321234.393ba","name":"Stop","rules":[{"t":"set","p":"payload","pt":"msg","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":710,"y":140,"wires":[["aa8804ca.299348"]]},{"id":"eec2288c547d307a","type":"switch","z":"d4321234.393ba","name":"On/Off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"true","vt":"str"},{"t":"eq","v":"false","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1010,"y":60,"wires":[["31c921a8.e58b4e"],["5154c4a1.41378c"]]},{"id":"3ef714c47ba61f23","type":"ui_text","z":"d4321234.393ba","group":"72fc319.cc425d","order":8,"width":0,"height":0,"name":"","label":"Pool Pump","format":"{{msg.payload.value.toUpperCase()}}","layout":"row-spread","x":610,"y":200,"wires":[]},{"id":"ad54a028efbff556","type":"inject","z":"d4321234.393ba","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":230,"y":180,"wires":[["0ff9446f4e2b45c8"]]},{"id":"08b72e7f9a6c75b8","type":"hubitat command","z":"d4321234.393ba","deviceLabel":"Skimmer","name":"","server":"a16ac10e.d53f2","deviceId":"847","command":"setLevel","commandArgs":"0","x":1440,"y":120,"wires":[[]]},{"id":"a16ac10e.d53f2","type":"hubitat config","name":"Hubitat Evolution","usetls":false,"host":"192.168.1.40","port":"80","appId":"145","nodeRedServer":"http://192.168.1.25:1880","webhookPath":"/hubitat/webhook","autoRefresh":true,"useWebsocket":false,"colorEnabled":false,"color":"#000000"},{"id":"72fc319.cc425d","type":"ui_group","name":"Group 3","tab":"383da647.2a662a","order":3,"disp":false,"width":"6","collapse":false},{"id":"383da647.2a662a","type":"ui_tab","name":"MurnControl","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

Title - Manage the buttons on a button controller with just 3 nodes.

Summary - I started out by connecting several node (switch, change, devices, commands, etc...), which in my opinion was pretty complex. So, I decided to go back and simplify it by using only 3 nodes (1 device node, 1 function node, and one command node) for 8 actions.
image

The button controller I'm using is a Hank four-key scene controller with PUSHED and HELD functions. The function node is comprised of simple IF statements:


if (msg.payload.value === 1 && msg.payload.name === "pushed") {
 msg.deviceId = "31";
 msg.command = "on";
} 

if (msg.payload.value === 1 && msg.payload.name === "held") {
 msg.deviceId = "31"; 
 msg.command = "off";
}

if (msg.payload.value === 4 && msg.payload.name === "pushed") {
 msg.deviceId = "278";
 msg.command = "on";
} 

if (msg.payload.value === 4 && msg.payload.name === "held") {
 msg.deviceId = "278"; 
 msg.command = "off";
}

return msg

msg.payload.value is the button that was pressed and msg.payload.name represents a pushed or held action, the matching of those two items sends a command of either on/off to the specified deviceId.

The command node can be anything since you are passing along the deviceId and command, it just serves as a shell if you will, msg.arguments can also be send in this manner.

This is what the edit properties look like:

Hank button
image

Function node

Command node
image

Hope this helps reduce some of your clutter as well.

6 Likes

@william2 - To turn things up to "11" you could add an "environment variable" to your subflow called "ButtonMap" (or whatever) and make it a JSON string then in your function node compare it against the input..

In your example when you place the subflow node you would edit the "ButtonMap" entry to look something like this:

[
	{"button":1,"deviceId":"31"},
	{"button":4,"deviceId":"278"}
]

Just a way of abstracting things and allowing you to reuse the subflow for other stuff if necessary...

Also on a semi-related note - Heres a repost of a subflow I wrote called "Button Taps" that allows you to handle multi-tapping events even on buttons that don't have that capability. Works with Lutron Picos using both fast and regular drivers... You can have single, double, triple, quadruple or N+ taps and set the length of tap detection time. Will trap "doubleTap" and "held" events if the button/driver supports it.

The "Office Button" in the above sequence is a Samsung SmartThings Button.

It does require the timed-counter node though..

node-red-contrib-timed-counter

@erktreks Button Taps - 210828

[{"id":"d0e305e1.7ad558","type":"subflow","name":"Button Taps","info":"","category":"adsavia dev","in":[{"x":50,"y":30,"wires":[{"id":"dceb31cb.fb78f"}]}],"out":[{"x":1180,"y":40,"wires":[{"id":"959b5260.c1c1c","port":0}]},{"x":1180,"y":100,"wires":[{"id":"959b5260.c1c1c","port":1}]},{"x":1180,"y":160,"wires":[{"id":"959b5260.c1c1c","port":2}]},{"x":1180,"y":220,"wires":[{"id":"959b5260.c1c1c","port":3}]}],"env":[{"name":"TIME_LIMIT_MS","type":"num","value":"450"},{"name":"HELD_TAPS","type":"num","value":"0"}],"meta":{"module":"adsavia-button-taps","version":"1.0","license":"GPL-3.0"},"color":"#E2D96E","inputLabels":["Button Press"],"outputLabels":["Single Tap","Double Tap","Triple Tap","Quad+ Tap"],"icon":"node-red-dashboard/ui_button.png","status":{"x":1180,"y":280,"wires":[{"id":"b4ba35d5.020018","port":0}]}},{"id":"959b5260.c1c1c","type":"switch","z":"d0e305e1.7ad558","name":"Single Tap \\n Double Tap \\n Triple Tap \\n Quad+ Tap","property":"count","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"eq","v":"3","vt":"str"},{"t":"gte","v":"4","vt":"str"}],"checkall":"true","repair":false,"outputs":4,"x":930,"y":120,"wires":[[],[],[],[]]},{"id":"4e584c74.8f1724","type":"timed-counter","z":"d0e305e1.7ad558","name":"","timelimit":"${TIME_LIMIT_MS}","timeunit":1,"withhold":true,"fixedtimeout":false,"pertopic":false,"x":680,"y":40,"wires":[["959b5260.c1c1c","b4ba35d5.020018"]]},{"id":"b4ba35d5.020018","type":"function","z":"d0e305e1.7ad558","name":"set status payload","func":"\nvar payload = {\n\"fill\": \"green\",\n\"shape\":\"dot\",\n\"text\": (flow.get(\"held\")!==undefined?\"Held/\":\"\") + ( msg.count == 1 ? \"Single\" : (msg.count == 2 ? \"Double\": (msg.count == 3 ? \"Triple\": (msg.count == 4 ? \"Quadruple\": msg.count.toString() )))) + \" Tap\"\n};\n\nflow.set(\"held\",undefined);\n\nmsg.payload = payload;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":950,"y":280,"wires":[[]]},{"id":"dbeab83f.200be8","type":"function","z":"d0e305e1.7ad558","name":"Gnerate \"Held\" Taps","func":"var iterate = env.get(\"HELD_TAPS\");\nfor (var i = 0; i < iterate; i++){\n    node.send(msg);\n}\n\nflow.set(\"held\",true);\n\nreturn;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":160,"wires":[["4e584c74.8f1724"]]},{"id":"dceb31cb.fb78f","type":"switch","z":"d0e305e1.7ad558","name":"","property":"payload.name","propertyType":"msg","rules":[{"t":"eq","v":"pushed","vt":"str"},{"t":"eq","v":"doubleTapped","vt":"str"},{"t":"eq","v":"held","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":190,"y":40,"wires":[["4e584c74.8f1724"],["b6af3007.c57de","3eafdc18.33b6e4"],["dbeab83f.200be8"]]},{"id":"b6af3007.c57de","type":"delay","z":"d0e305e1.7ad558","name":"","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":390,"y":120,"wires":[["4e584c74.8f1724"]]},{"id":"3eafdc18.33b6e4","type":"delay","z":"d0e305e1.7ad558","name":"","pauseType":"delay","timeout":"50","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":390,"y":80,"wires":[["4e584c74.8f1724"]]},{"id":"d7fed3e.1c61a3","type":"subflow:d0e305e1.7ad558","z":"841da7a7.4fb908","name":"","env":[{"name":"TIME_LIMIT_MS","value":"800","type":"num"},{"name":"HELD_TAPS","value":"4","type":"num"},{"name":"DETECT_DOUBLETAP","value":"true","type":"bool"}],"x":410,"y":1200,"wires":[["e7780ce3.1c5a9"],["11e1341.245cacc"],["92dcbe4e.55989"],["6a54cf31.df644"]]}]

4 Likes

@erktrek - thanks for the advice, never thought of using it as an environment variable, I'm going to have to give this a try. Also, my jaw dropped when you mentioned your Button Taps and the ability to create additional taps that are not part of the button configuration. I'm definitely going to play around with this!

2 Likes

Title: Universal Pico Controller

Here is my attempt at a universal Pico Controller Subflow — for my use cases anyway. The top output sends out all commands and the next five are per button commands for easy integration.

Flow
[{"id":"f303a7d09980af88","type":"subflow","name":"Pico Controller","info":"# **Pico Controller**\n\nThis subflow is an attempt to create a universal pico controller for use with hubitat. Placing it inline with a pico and a dimmer connected through the first output will use defaults of:\n\n100%,up,50%,down,off\n\nfor each button. \n\nThis can be customized as follows:\n\n\n## **Bulb Groups**\nIf the Group environmental variable is selected, then the up and down buttons will increase or decrease the dimmer percentage by 10%. You must also additionally set two additional device nodes for the bulb group that is being acted on. One should be for level commands and it should be titled \"currentlevel\", the other is for switch commands and should be titled \"currentswitch\". Both of these device nodes should be set to send events. This allows the subflow to track the level and switch state of the bulb.","category":"","in":[{"x":148,"y":464,"wires":[{"id":"63141a3d8a75e016"}]}],"out":[{"x":2660,"y":448,"wires":[{"id":"40374c2adb2f601a","port":0},{"id":"759e361417e760fe","port":0},{"id":"1b7e741f075a025a","port":0},{"id":"05849239ecb42d74","port":0},{"id":"da9e8ddd803e5f5c","port":0},{"id":"781021b7c0141623","port":0},{"id":"4c6b7ddf5aaf8c33","port":0},{"id":"8fac24ddda39adfb","port":0},{"id":"b51e8b1b05fba6b3","port":0},{"id":"c4b95f6d92f10bb3","port":0},{"id":"78e8e815a0418aed","port":0},{"id":"778f3cb9bd70477a","port":0},{"id":"579155c6728b1ee2","port":0}]},{"x":2388,"y":192,"wires":[{"id":"40374c2adb2f601a","port":0},{"id":"c4b95f6d92f10bb3","port":0},{"id":"78e8e815a0418aed","port":0},{"id":"778f3cb9bd70477a","port":0},{"id":"579155c6728b1ee2","port":0}]},{"x":2388,"y":384,"wires":[{"id":"759e361417e760fe","port":0},{"id":"1b7e741f075a025a","port":0},{"id":"8fac24ddda39adfb","port":0},{"id":"b51e8b1b05fba6b3","port":0}]},{"x":2388,"y":528,"wires":[{"id":"05849239ecb42d74","port":0}]},{"x":2388,"y":624,"wires":[{"id":"da9e8ddd803e5f5c","port":0},{"id":"781021b7c0141623","port":0},{"id":"8fac24ddda39adfb","port":0}]},{"x":2388,"y":704,"wires":[{"id":"4c6b7ddf5aaf8c33","port":0}]}],"env":[{"name":"Command","type":"str","value":"setLevel","ui":{"label":{"en-US":"Top Command"},"type":"select","opts":{"opts":[{"l":{"en-US":"setLevel"},"v":"setLevel"},{"l":{"en-US":"setColorTemperature"},"v":"setColorTemperature"}]}}},{"name":"CT","type":"str","value":"","ui":{"type":"select","opts":{"opts":[{"l":{"en-US":"circadian2200"},"v":"circadian2200"},{"l":{"en-US":"circadian2700"},"v":"circadian2700"},{"l":{"en-US":"circadianhack2200"},"v":"circadianhack2200"},{"l":{"en-US":"circadianhack2700"},"v":"circadianhack2700"}]}}},{"name":"Top","type":"str","value":"100,1","ui":{"label":{"en-US":"Top Level"}}},{"name":"Favorite","type":"str","value":"50,1","ui":{"label":{"en-US":"Favorite Level"}}},{"name":"Group","type":"bool","value":"false","ui":{"icon":"font-awesome/fa-th","type":"checkbox"}}],"meta":{},"color":"#C7E9C0","inputLabels":["Pico"],"outputLabels":["All","On","Up","Favorite","Down","Off"],"icon":"node-red-dashboard/ui_button.png"},{"id":"b23c6197b2cea3b9","type":"switch","z":"f303a7d09980af88","name":"Button 1-5","property":"payload.value","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"eq","v":"3","vt":"num"},{"t":"eq","v":"4","vt":"num"},{"t":"eq","v":"5","vt":"num"}],"checkall":"true","repair":false,"outputs":5,"x":838,"y":496,"wires":[["259b2bf717ab9ad7"],["df2904f4c414d285"],["d5b59dcb81333328"],["70eac538866490d7"],["a3b58046d1ef5a35"]]},{"id":"259b2bf717ab9ad7","type":"switch","z":"f303a7d09980af88","name":"pushed\\n released","property":"payload.name","propertyType":"msg","rules":[{"t":"eq","v":"pushed","vt":"str"},{"t":"eq","v":"released","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1084,"y":272,"wires":[["775c19797c8e1fd6"],[]]},{"id":"759e361417e760fe","type":"change","z":"f303a7d09980af88","name":"Up","rules":[{"t":"set","p":"command","pt":"msg","to":"startLevelChange","tot":"str"},{"t":"set","p":"arguments","pt":"msg","to":"up","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2002,"y":400,"wires":[[]]},{"id":"da9e8ddd803e5f5c","type":"change","z":"f303a7d09980af88","name":"Down","rules":[{"t":"set","p":"command","pt":"msg","to":"startLevelChange","tot":"str"},{"t":"set","p":"arguments","pt":"msg","to":"down","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2002,"y":624,"wires":[[]]},{"id":"1b7e741f075a025a","type":"change","z":"f303a7d09980af88","name":"Stop Change","rules":[{"t":"set","p":"command","pt":"msg","to":"stopLevelChange","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2022,"y":432,"wires":[[]]},{"id":"4c6b7ddf5aaf8c33","type":"change","z":"f303a7d09980af88","name":"off","rules":[{"t":"set","p":"command","pt":"msg","to":"off","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2002,"y":704,"wires":[[]]},{"id":"df2904f4c414d285","type":"switch","z":"f303a7d09980af88","name":"pushed\\n released","property":"payload.name","propertyType":"msg","rules":[{"t":"eq","v":"pushed","vt":"str"},{"t":"eq","v":"released","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1084,"y":416,"wires":[["669b3e985b1e3b46"],["334576d2c8ee49f2"]]},{"id":"d5b59dcb81333328","type":"switch","z":"f303a7d09980af88","name":"pushed\\n released","property":"payload.name","propertyType":"msg","rules":[{"t":"eq","v":"pushed","vt":"str"},{"t":"eq","v":"released","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1084,"y":496,"wires":[["05849239ecb42d74"],[]]},{"id":"70eac538866490d7","type":"switch","z":"f303a7d09980af88","name":"pushed\\n released","property":"payload.name","propertyType":"msg","rules":[{"t":"eq","v":"pushed","vt":"str"},{"t":"eq","v":"released","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1084,"y":640,"wires":[["631830a6de09d2d9"],["a60feb41043ace07"]]},{"id":"a3b58046d1ef5a35","type":"switch","z":"f303a7d09980af88","name":"pushed\\n released","property":"payload.name","propertyType":"msg","rules":[{"t":"eq","v":"pushed","vt":"str"},{"t":"eq","v":"released","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1084,"y":704,"wires":[["4c6b7ddf5aaf8c33"],[]]},{"id":"40374c2adb2f601a","type":"change","z":"f303a7d09980af88","name":"Top","rules":[{"t":"set","p":"command","pt":"msg","to":"Command","tot":"env"},{"t":"set","p":"arguments","pt":"msg","to":"Top","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":2002,"y":112,"wires":[[]]},{"id":"05849239ecb42d74","type":"change","z":"f303a7d09980af88","name":"Favorite","rules":[{"t":"set","p":"command","pt":"msg","to":"setLevel","tot":"str"},{"t":"set","p":"arguments","pt":"msg","to":"Favorite","tot":"env"}],"action":"","property":"","from":"","to":"","reg":false,"x":2012,"y":528,"wires":[[]]},{"id":"781021b7c0141623","type":"change","z":"f303a7d09980af88","name":"Stop Change","rules":[{"t":"set","p":"command","pt":"msg","to":"stopLevelChange","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2022,"y":656,"wires":[[]]},{"id":"4f1114b9da9670b6","type":"change","z":"f303a7d09980af88","name":"set topic pico","rules":[{"t":"set","p":"topic","pt":"msg","to":"pico","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":624,"y":496,"wires":[["b23c6197b2cea3b9"]]},{"id":"669b3e985b1e3b46","type":"switch","z":"f303a7d09980af88","name":"env.group","property":"Group","propertyType":"env","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":1276,"y":400,"wires":[["3c055e94195a2284"],["759e361417e760fe"]]},{"id":"631830a6de09d2d9","type":"switch","z":"f303a7d09980af88","name":"env.group","property":"Group","propertyType":"env","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":1276,"y":624,"wires":[["3a54497853ac3109"],["da9e8ddd803e5f5c"]]},{"id":"63141a3d8a75e016","type":"switch","z":"f303a7d09980af88","name":"topic","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"currentlevel","vt":"str"},{"t":"eq","v":"currentswitch","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":3,"x":338,"y":464,"wires":[["9cd955ea440c31cb"],["765e19f2b0c58239"],["4f1114b9da9670b6"]]},{"id":"3c055e94195a2284","type":"switch","z":"f303a7d09980af88","name":"switch on/off","property":"switch","propertyType":"flow","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1478,"y":352,"wires":[["45feb05ae438710e","e238d6dc09ae6825"],["b51e8b1b05fba6b3"]]},{"id":"8fac24ddda39adfb","type":"change","z":"f303a7d09980af88","name":"setLevel","rules":[{"t":"set","p":"command","pt":"msg","to":"setLevel","tot":"str"},{"t":"set","p":"arguments","pt":"msg","to":"payload & \",0\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":2012,"y":480,"wires":[[]]},{"id":"e3c744b8744f7001","type":"counter","z":"f303a7d09980af88","name":"","init":"0","step":"10","lower":"0","upper":"100","mode":"increment","outputs":2,"x":1788,"y":480,"wires":[["8fac24ddda39adfb"],[]]},{"id":"c716835a66d2f1e5","type":"change","z":"f303a7d09980af88","name":"+10","rules":[{"t":"set","p":"increment","pt":"msg","to":"10","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1826,"y":336,"wires":[["e3c744b8744f7001"]]},{"id":"922f20cf87e5cfcb","type":"change","z":"f303a7d09980af88","name":"-10","rules":[{"t":"set","p":"decrement","pt":"msg","to":"10","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1826,"y":592,"wires":[["e3c744b8744f7001"]]},{"id":"b51e8b1b05fba6b3","type":"change","z":"f303a7d09980af88","name":"10%","rules":[{"t":"set","p":"command","pt":"msg","to":"setLevel","tot":"str"},{"t":"set","p":"arguments","pt":"msg","to":"10","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":2002,"y":352,"wires":[[]]},{"id":"334576d2c8ee49f2","type":"switch","z":"f303a7d09980af88","name":"env.group","property":"Group","propertyType":"env","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":1276,"y":432,"wires":[[],["1b7e741f075a025a"]]},{"id":"a60feb41043ace07","type":"switch","z":"f303a7d09980af88","name":"env.group","property":"Group","propertyType":"env","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":1276,"y":656,"wires":[[],["781021b7c0141623"]]},{"id":"9cd955ea440c31cb","type":"change","z":"f303a7d09980af88","name":"","rules":[{"t":"set","p":"level","pt":"flow","to":"payload.value","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":614,"y":416,"wires":[[]]},{"id":"45feb05ae438710e","type":"delay","z":"f303a7d09980af88","name":"","pauseType":"delay","timeout":"50","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"x":1670,"y":336,"wires":[["c716835a66d2f1e5"]]},{"id":"e238d6dc09ae6825","type":"change","z":"f303a7d09980af88","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"level","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":1504,"y":480,"wires":[["e3c744b8744f7001"]]},{"id":"f01c28fca710af98","type":"delay","z":"f303a7d09980af88","name":"","pauseType":"delay","timeout":"50","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"x":1670,"y":592,"wires":[["922f20cf87e5cfcb"]]},{"id":"765e19f2b0c58239","type":"change","z":"f303a7d09980af88","name":"","rules":[{"t":"set","p":"switch","pt":"flow","to":"payload.value","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":624,"y":448,"wires":[[]]},{"id":"3a54497853ac3109","type":"switch","z":"f303a7d09980af88","name":"switch on/off","property":"switch","propertyType":"flow","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1478,"y":592,"wires":[["f01c28fca710af98","e238d6dc09ae6825"],[]]},{"id":"775c19797c8e1fd6","type":"switch","z":"f303a7d09980af88","name":"env.command","property":"Command","propertyType":"env","rules":[{"t":"eq","v":"setLevel","vt":"str"},{"t":"eq","v":"setColorTemperature","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1296,"y":272,"wires":[["40374c2adb2f601a"],["6bf65029ff099fc4"]]},{"id":"c4b95f6d92f10bb3","type":"change","z":"f303a7d09980af88","name":"circadian2200,Top","rules":[{"t":"set","p":"command","pt":"msg","to":"Command","tot":"env"},{"t":"set","p":"arguments","pt":"msg","to":"$globalContext(\"circadian2200\") & $env('Top')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":2042,"y":176,"wires":[[]]},{"id":"6bf65029ff099fc4","type":"switch","z":"f303a7d09980af88","name":"env.CT","property":"CT","propertyType":"env","rules":[{"t":"eq","v":"circadian2200","vt":"str"},{"t":"eq","v":"circadian2700","vt":"str"},{"t":"eq","v":"circadianhack2200","vt":"str"},{"t":"eq","v":"circadianhack2700","vt":"str"}],"checkall":"true","repair":false,"outputs":4,"x":1650,"y":272,"wires":[["c4b95f6d92f10bb3"],["78e8e815a0418aed"],["778f3cb9bd70477a"],["579155c6728b1ee2"]]},{"id":"78e8e815a0418aed","type":"change","z":"f303a7d09980af88","name":"circadian2700,Top","rules":[{"t":"set","p":"command","pt":"msg","to":"Command","tot":"env"},{"t":"set","p":"arguments","pt":"msg","to":"$globalContext(\"circadian2700\") & \",\" & $env('Top')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":2042,"y":208,"wires":[[]]},{"id":"778f3cb9bd70477a","type":"change","z":"f303a7d09980af88","name":"circadianhack2200,Top","rules":[{"t":"set","p":"command","pt":"msg","to":"Command","tot":"env"},{"t":"set","p":"arguments","pt":"msg","to":"$globalContext(\"circadianhack2200\") & $env('Top')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":2062,"y":240,"wires":[[]]},{"id":"579155c6728b1ee2","type":"change","z":"f303a7d09980af88","name":"circadianhack2700,Top","rules":[{"t":"set","p":"command","pt":"msg","to":"Command","tot":"env"},{"t":"set","p":"arguments","pt":"msg","to":"$globalContext(\"circadianhack2700\") & $env('Top')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":2062,"y":272,"wires":[[]]}]

this makes for an easy drop in pico controller for different bulbs. For simple dimmer bulbs it can simply be placed between the pico device node and the dimmer command node:

The level of the top button and the center “favorite” button can be set as environmental variables. The default is 100% and 50%:

For color temperature bulbs, I can select the setColorTemperature command as an environmental variable, and then I’ve hard coded my global variable color temps into the flow.

The toughest part was trying to get the up and down dimmer buttons working with bulb groups as hubitat does not support the “startraising” and startlowering” commands for bulb groups. When the “Group” env variable is selected each up or down button press will increase or decrease the level by 10%. The problem is tracking the current state of the bulb, which may be turned on/off and have its level set by many other automations. Ultimately, I ended up using two device nodes set to send level events and switch events. They must be named “currentlevel” and “currentswitch” to be sorted correctly in the subflow. This seems to work relatively reliably.

1 Like