JSONATA rocks!!
The date issue sounds weird but is good to know - I'm sure you tried reformatting the incoming field to something else?
JSONATA rocks!!
The date issue sounds weird but is good to know - I'm sure you tried reformatting the incoming field to something else?
It was weird - I'm not sure if it is just the mySQL node or it will have the same issue with other databases. The strange thing is that if I copy the payload and send it via the inject node, it works perfectly. The $$.payload.[..name..] worked for me, so I stopped looking at why $spread was not working. I did create a Github issue for this but the person maintaining that node said this would be unlikely to be fixed since other folks may be relying on the data type of a TIMESTAMP columns.
For anyone interested, node-red 2.2.0 was released a few days ago:
It has some nice enhancements to the editor. I've only been running it for a few hours, and haven't noticed any issues with sequences that use @fblackburn's Hubitat nodes.
@aaiyar, @kuzenkohome - so I realized that my screencap was an older version of the the toggle subflow.. My newer one looks like this... and also I agree with your assessment about having 2 outputs! Sorry for the confusion..
This advanced toggle subflow allows you to define your output via JSON. You can either specify a "command" (see "off") or a set of "commands" defined as an array of objects under "_actions"... For the input you specify which property to check and what the 2 states are - on/off, open/close etc..
In this example turning a light "on" (msg.payload.value = "on") would set level and temp. You can also invert the process as well - which is the default, because, well, you know it's a "toggle" function.. 
edit: I'm going to tweak the output parameter a little bit - don't like my current format.
So here is the updated Advanced Toggle.. simplified the output - now there are 2 outputs corresponding to the binary events like "on/off" - "output1"/ "output2"
you can define either a single object that will populate the specified property usually "msg.command" + "msg.attributes" (possibly others) or an array of such objects (edit: which will generate a separate message for each element in the array). Note "msg." is implied and not used.
[{"id":"049dd7eab1551ac1","type":"subflow","name":"AdvancedToggle","info":"","category":"","in":[{"x":60,"y":60,"wires":[{"id":"c11d7711d06a4d51"}]}],"out":[{"x":640,"y":80,"wires":[{"id":"c11d7711d06a4d51","port":0}]}],"env":[{"name":"INPUT","type":"json","value":"{\"payload.value\":\"on/off\"}"},{"name":"OUTPUT1","type":"json","value":"[{\"command\":\"setLevel\",\"arguments\":\"100\"},{\"command\":\"setTemperature\",\"arguments\":\"2800\"}]"},{"name":"OUTPUT2","type":"json","value":"{ \"command\": \"off\" }"},{"name":"INVERT","type":"bool","value":"true"}],"meta":{},"color":"#FDF0C2","icon":"node-red-contrib-sun-position/inputTypeRandomNumber.svg","status":{"x":640,"y":200,"wires":[{"id":"c11d7711d06a4d51","port":0}]}},{"id":"c11d7711d06a4d51","type":"function","z":"049dd7eab1551ac1","name":"Based on Input and \"invert\" convert to Output","func":"\nvar input = env.get(\"INPUT\");\n//var output = env.get(\"OUTPUT\");\nvar output1 = env.get(\"OUTPUT1\");\nvar output2 = env.get(\"OUTPUT2\");\n\nvar output = [];\n\n\nvar invert = env.get(\"INVERT\");\n\n\nvar retMsg;\nvar inputProp = Object.keys(input)[0];\nvar inputTypes = input[inputProp].split(\"/\");\nvar inputVal = getVal(msg,inputProp);\nvar valIndex = inputTypes.findIndex(type => type === inputVal.toString());\nvar val;\nif (valIndex != -1) {\n //retMsg = msg;\n var newIndex = (invert ? (valIndex == 0 ? 1 : 0) : valIndex );\n \n \n if (newIndex == 0) {\n if (Array.isArray(output1)){\n output = output1\n } else {\n output.push(output1);\n }\n } else {\n if (Array.isArray(output2)){\n output = output1\n } else {\n output.push(output2);\n }\n }\n\n var outputActions = output;\n\n for (var i=0;i<outputActions.length;i++) {\n retMsg = {};\n oAction = outputActions[i];\n keys = Object.keys(oAction);\n for (var j=0;j<keys.length;j++) {\n val = oAction[keys[j]];\n setVal(retMsg,keys[j],val);\n }\n //node.warn(retMsg);\n node.send(retMsg);\n }\n \n node.done();\n\n}\n\n//return retMsg;\nreturn;\n\nfunction getVal(obj,propName) {\n\n var retVal;\n var props = propName.split(\".\");\n var name = props[0];\n \n if (props.length > 1) {\n if (obj.hasOwnProperty(name)) {\n props.shift();\n var newProps = props.join(\".\");\n retVal = getVal(obj[name],newProps)\n }\n } else {\n retVal = obj[name];\n }\n \n return retVal;\n\n}\n\n\nfunction setVal(obj,propName,val) {\n var props = propName.split(\".\");\n var name = props[0];\n\n if (props.length > 1) {\n if (!obj.hasOwnProperty(name)) {\n obj[name] = {};\n }\n \n props.shift();\n var newProps = props.join(\".\");\n setVal(obj[name],newProps,val)\n } else {\n obj[name] = val;\n }\n \n return;\n\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":140,"wires":[[]]},{"id":"8718e43bfa9eb921","type":"inject","z":"38a24d1b8c9ddb0f","name":"on","props":[{"p":"payload.value","v":"on","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1510,"y":100,"wires":[["aef00f486d7ace86"]]},{"id":"88b4e89f761f8078","type":"debug","z":"38a24d1b8c9ddb0f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1950,"y":120,"wires":[]},{"id":"c1d79180d6369b6c","type":"inject","z":"38a24d1b8c9ddb0f","name":"off","props":[{"p":"payload.value","v":"off","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1510,"y":160,"wires":[["aef00f486d7ace86"]]},{"id":"aef00f486d7ace86","type":"subflow:049dd7eab1551ac1","z":"38a24d1b8c9ddb0f","name":"","env":[{"name":"OUTPUT","value":"{\"output1\":[{\"command\":\"setLevel\",\"arguments\":\"100\"},{\"command\":\"setTemperature\",\"arguments\":\"2800\"}],\"output2\":{\"command\":\"off\"}}","type":"json"}],"x":1740,"y":120,"wires":[["88b4e89f761f8078"]]}]
NOTE: of course had small bug with "invert" not inverting, now fixed.
Okay another update, last one - pinky swear... 
This adds multiple inputs, basic status and maybe a bug fix or two... also note my previous screen cap mentions "setTemperature" which is wrong wrong wrong - use "setColorTemperature" and yes you can setLevel by passing additional parameters to setColorTemperature but where is the fun in that?
[{"id":"049dd7eab1551ac1","type":"subflow","name":"AdvancedToggle","info":"","category":"","in":[{"x":60,"y":60,"wires":[{"id":"c11d7711d06a4d51"}]}],"out":[{"x":640,"y":80,"wires":[{"id":"c11d7711d06a4d51","port":0}]}],"env":[{"name":"INPUT","type":"json","value":"{\"payload.value\":\"on/off\"}"},{"name":"OUTPUT1","type":"json","value":"[{\"command\":\"setLevel\",\"arguments\":\"100\"},{\"command\":\"setTemperature\",\"arguments\":\"2800\"}]"},{"name":"OUTPUT2","type":"json","value":"{ \"command\": \"off\" }"},{"name":"INVERT","type":"bool","value":"true"}],"meta":{},"color":"#FDF0C2","icon":"node-red-contrib-sun-position/inputTypeRandomNumber.svg","status":{"x":640,"y":200,"wires":[{"id":"c11d7711d06a4d51","port":1}]}},{"id":"c11d7711d06a4d51","type":"function","z":"049dd7eab1551ac1","name":"Based on Input and \"invert\" convert to Output","func":"\nvar inputParm = env.get(\"INPUT\");\n//var output = env.get(\"OUTPUT\");\nvar output1 = env.get(\"OUTPUT1\");\nvar output2 = env.get(\"OUTPUT2\");\n\nvar input = [];\nvar invert = env.get(\"INVERT\");\nvar retMsg;\n\nif (Array.isArray(inputParm)){\n input = inputParm;\n} else {\n input.push(inputParm);\n}\n\n/*\nvar inputProp = Object.keys(input)[0];\nvar inputTypes = input[inputProp].split(\"/\");\nvar inputVal = getVal(msg,inputProp);\nvar valIndex = inputTypes.findIndex(type => type === inputVal.toString());\n\nvar val;\n\nif (valIndex != -1) {\n*/\n\nfor (var k=0;k<input.length;k++) {\n\n var inputProp = Object.keys(input[k])[0];\n var inputTypes = input[k][inputProp].split(\"/\");\n var inputVal = getVal(msg,inputProp).toString();\n var valIndex = inputTypes.indexOf(inputVal);\n\n var val;\n var output = [];\n \n\n if (valIndex != -1) {\n var newIndex = (invert ? (valIndex == 0 ? 1 : 0) : valIndex );\n \n \n if (newIndex == 0) {\n if (Array.isArray(output1)){\n output = output1\n } else {\n output.push(output1);\n }\n } else {\n if (Array.isArray(output2)){\n output = output2\n } else {\n output.push(output2);\n }\n }\n\n for (var i=0;i<output.length;i++) {\n retMsg = {\"topic\":msg.topic,\"payload\":\"\"};\n var oAction = output[i];\n var actionVal = Object.keys(oAction);\n var keys =[];\n\n if(Array.isArray(actionVal)) {\n keys = actionVal;\n } else {\n keys.push(actionVal);\n }\n //node.warn(\"keys: \" + keys.length);\n for (var j=0;j<keys.length;j++) {\n val = oAction[keys[j]];\n setVal(retMsg,keys[j],val);\n node.send([undefined,{\"payload\":inputTypes[valIndex] + \" => \" + keys[j] + \"/\" + val}]);\n node.done();\n }\n node.send([retMsg,undefined]);\n node.done();\n }\n \n }\n\n}\n\n//return retMsg;\nreturn;\n\nfunction getVal(obj,propName) {\n\n var retVal;\n var props = propName.split(\".\");\n var name = props[0];\n \n if (props.length > 1) {\n if (obj.hasOwnProperty(name)) {\n props.shift();\n var newProps = props.join(\".\");\n retVal = getVal(obj[name],newProps)\n }\n } else {\n retVal = obj[name];\n }\n \n return retVal;\n\n}\n\n\nfunction setVal(obj,propName,val) {\n var props = propName.split(\".\");\n var name = props[0];\n\n if (props.length > 1) {\n if (!obj.hasOwnProperty(name)) {\n obj[name] = {};\n }\n \n props.shift();\n var newProps = props.join(\".\");\n setVal(obj[name],newProps,val)\n } else {\n obj[name] = val;\n }\n \n return;\n\n}\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":140,"wires":[[],[]]},{"id":"cf50f7f2ae7a2cb6","type":"subflow:049dd7eab1551ac1","z":"e6807da71ee5477b","name":"","env":[{"name":"INPUT","value":"[{\"payload.value\":\"1/2\"},{\"payload.value\":\"3/4\"}]","type":"json"},{"name":"OUTPUT1","value":"[{\"command\":\"setLevel\",\"arguments\":\"100\"},{\"command\":\"setColorTemperature\",\"arguments\":\"2900\"}]","type":"json"},{"name":"INVERT","value":"false","type":"bool"}],"x":1490,"y":160,"wires":[["688dccfb3250f01f"]]},{"id":"8c6e50277564290c","type":"inject","z":"e6807da71ee5477b","name":"payload.value = 1","props":[{"p":"payload.value","v":"1","vt":"num"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1180,"y":80,"wires":[["cf50f7f2ae7a2cb6"]]},{"id":"fd881a58b0a25f3f","type":"inject","z":"e6807da71ee5477b","name":"payload.value = 2","props":[{"p":"payload.value","v":"2","vt":"num"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1180,"y":120,"wires":[["cf50f7f2ae7a2cb6"]]},{"id":"a2b804cb8750dc53","type":"inject","z":"e6807da71ee5477b","name":"payload.value = 3","props":[{"p":"payload.value","v":"3","vt":"num"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1180,"y":200,"wires":[["cf50f7f2ae7a2cb6"]]},{"id":"09b0f48ac933414e","type":"inject","z":"e6807da71ee5477b","name":"payload.value = 4","props":[{"p":"payload.value","v":"4","vt":"num"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1180,"y":240,"wires":[["cf50f7f2ae7a2cb6"]]},{"id":"688dccfb3250f01f","type":"debug","z":"e6807da71ee5477b","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1670,"y":160,"wires":[]}]
So this is an update NOT related to the "Advanced Toggle"... Whilst adding AT to my sequences discovered a bug in my Button Tap subflow which can mess up the "held" action.. fixed and all is well.. Below is an example. For this I have button 3 "held" set to 5 taps.
[{"id":"d0e305e1.7ad558","type":"subflow","name":"Button Taps","info":"","category":"","in":[{"x":50,"y":70,"wires":[{"id":"dceb31cb.fb78f"}]}],"out":[{"x":1230,"y":60,"wires":[{"id":"959b5260.c1c1c","port":0}]},{"x":1230,"y":120,"wires":[{"id":"959b5260.c1c1c","port":1}]},{"x":1220,"y":180,"wires":[{"id":"959b5260.c1c1c","port":2}]},{"x":1230,"y":240,"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":320,"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":950,"y":140,"wires":[[],[],[],[]]},{"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":970,"y":240,"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 node.done();\n}\n\nflow.set(\"held\",true);\n\nreturn;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":200,"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":80,"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,"outputs":1,"x":390,"y":160,"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,"outputs":1,"x":390,"y":120,"wires":[["4e584c74.8f1724"]]},{"id":"4b49418ef2d1a440","type":"change","z":"d0e305e1.7ad558","name":"","rules":[{"t":"set","p":"count","pt":"msg","to":"$flowContext(\"held\") ? $env(\"HELD_TAPS\") : count","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":680,"y":140,"wires":[["b4ba35d5.020018","959b5260.c1c1c"]]},{"id":"4e584c74.8f1724","type":"timed-counter","z":"d0e305e1.7ad558","name":"","timelimit":"${TIME_LIMIT_MS}","timeunit":1,"withhold":true,"fixedtimeout":true,"pertopic":false,"x":640,"y":80,"wires":[["4b49418ef2d1a440"]]},{"id":"320f82a042c8d0ac","type":"inject","z":"e6807da71ee5477b","name":"pushed: Button 1","props":[{"p":"payload.value","v":"1","vt":"num"},{"p":"payload.name","v":"pushed","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1320,"y":80,"wires":[["68997bcf.fda874"]]},{"id":"68997bcf.fda874","type":"subflow:d0e305e1.7ad558","z":"e6807da71ee5477b","name":"","env":[{"name":"TIME_LIMIT_MS","value":"600","type":"num"},{"name":"HELD_TAPS","value":"5","type":"num"}],"x":1790,"y":240,"wires":[["cea029c1cf0e527b"],["cea029c1cf0e527b"],["cea029c1cf0e527b"],["cea029c1cf0e527b"]]},{"id":"4272e3f528e50cef","type":"inject","z":"e6807da71ee5477b","name":"doubleTapped: Button 2","props":[{"p":"payload.value","v":"2","vt":"num"},{"p":"payload.name","v":"doubleTapped","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1340,"y":140,"wires":[["68997bcf.fda874"]]},{"id":"a4e3de48fc1a4958","type":"inject","z":"e6807da71ee5477b","name":"pushed: Button 1","props":[{"p":"payload.value","v":"1","vt":"num"},{"p":"payload.name","v":"pushed","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1320,"y":400,"wires":[["387831eff3200d23","2fa651dff3acf9bb","ec54009e600c3a89"]]},{"id":"c46c398899cb4555","type":"inject","z":"e6807da71ee5477b","name":"held: Button 3","props":[{"p":"payload.value","v":"3","vt":"num"},{"p":"payload.name","v":"held","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1310,"y":200,"wires":[["68997bcf.fda874"]]},{"id":"387831eff3200d23","type":"delay","z":"e6807da71ee5477b","name":"","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1570,"y":360,"wires":[["68997bcf.fda874"]]},{"id":"2fa651dff3acf9bb","type":"delay","z":"e6807da71ee5477b","name":"","pauseType":"delay","timeout":"200","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1570,"y":400,"wires":[["68997bcf.fda874"]]},{"id":"ec54009e600c3a89","type":"delay","z":"e6807da71ee5477b","name":"","pauseType":"delay","timeout":"300","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1570,"y":440,"wires":[["68997bcf.fda874"]]},{"id":"cea029c1cf0e527b","type":"debug","z":"e6807da71ee5477b","name":"Number Of Taps","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"count & \" Tap / Button \" & payload.value","targetType":"jsonata","statusVal":"","statusType":"auto","x":2020,"y":240,"wires":[]},{"id":"8e7008e187d2ae7c","type":"inject","z":"e6807da71ee5477b","name":"pushed: Button 1","props":[{"p":"payload.value","v":"1","vt":"num"},{"p":"payload.name","v":"pushed","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1320,"y":280,"wires":[["a59bb37df1ed0c6b","713799729224c346"]]},{"id":"a59bb37df1ed0c6b","type":"delay","z":"e6807da71ee5477b","name":"","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1570,"y":260,"wires":[["68997bcf.fda874"]]},{"id":"141b87b130e692ba","type":"inject","z":"e6807da71ee5477b","name":"pushed: Button 1","props":[{"p":"payload.value","v":"1","vt":"num"},{"p":"payload.name","v":"pushed","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1320,"y":540,"wires":[["bb369ec8a67d202e","1d86df1979f825bb","5e7ee91208d956b5","648c5b29defdf580"]]},{"id":"bb369ec8a67d202e","type":"delay","z":"e6807da71ee5477b","name":"","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1570,"y":500,"wires":[["68997bcf.fda874"]]},{"id":"1d86df1979f825bb","type":"delay","z":"e6807da71ee5477b","name":"","pauseType":"delay","timeout":"200","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1570,"y":540,"wires":[["68997bcf.fda874"]]},{"id":"5e7ee91208d956b5","type":"delay","z":"e6807da71ee5477b","name":"","pauseType":"delay","timeout":"300","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1570,"y":580,"wires":[["68997bcf.fda874"]]},{"id":"648c5b29defdf580","type":"delay","z":"e6807da71ee5477b","name":"","pauseType":"delay","timeout":"400","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1570,"y":620,"wires":[["68997bcf.fda874"]]},{"id":"713799729224c346","type":"delay","z":"e6807da71ee5477b","name":"","pauseType":"delay","timeout":"200","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1570,"y":300,"wires":[["68997bcf.fda874"]]}]
Note: You need to install the node-red-contrib-timed-counter node for this to work.
... and here is an in-production example for thems that are curious how I'm using..
Archiving System-Wide Sensor Data for long term trend analysis:
Here's something I've been enjoying. I slurp up all events from Hubitat and dump them into a metrics table in Postgres. Then a Graphana instance can render dashboards which allow me to scroll back through time, build helpful visualizations, etc.
I used a link-out/in pair between the even receiver and the postgres node because I also manually dispatch events from elsewhere through the same postgres node.
That looks great, thanks for posting! I am always interested in how this kind of data can be used effectively..
We moved last yea, and the home is not at all efficient. Lots of insulation and other upgrades coming, and I would like to be able to prove that it works. The first step in that is visualizing what needs work and collecting data about it!
I haven’t yet found a good source for weather data, so I don’t have reference temperature for outside temperatures during the winter.
It did just occur to me that I can dump my spreadsheet of information about utility bills into this metrics DB too…
Question for anyone using Tasmota based switches with NR & Hubitat. Have some switches using the driver Marcus wrote. But since it is no longer supported I want to try and integrate them through NR.
I am testing a flow but have encountered a race condition where the switch will cycle on/off rapidly for 10-15 seconds then stop and function correctly. I suspect it has to due with timing between the HE status node and the command node. I can't duplicate it but the race happened twice in testing.
Anyone have any insite or a better flow. The flow allows control and maintains status from a HE virtual switch and locally from the switch itself.
Can you split them into 2 sequences maybe? First 3 nodes for the first + Last three nodes for the second. Providing the "wifiplug99" node sends on/off events of course...
I can split them I just don't see what that would accomplish. The wifiplug99 node does send events when the switch changes state either physically or digitally.
I went down the same path, but then decided I didnt need the tasmota switches on Hubitat. All of my logic is now in Node Red. Sorry, I cant be of much help.
Well my thought is if it's a timing thing with the "wifiplug99" then splitting them might smooth things out..
@erktrek I'll give it a try, now if I can get them to act up to determine if it fixes the issue.
@mike I'm kind of thinking that in the back of my mind as I'm moving my logic to NR also
Cool - was wondering if setting the Wifi99 switch just did a pass-through event message rather than waiting for the actual event to trigger.. In my mind that's the difference. Now whether or not it has any impact ![]()
I do this as well and it works great... some people do not like the visual flow style but I find it to be very intuitive and logical. Add in some subflows for sequence encapsulation and it is very easy to maintain and have consistent behavior across flows & sequences..
New task. I want to insert a hubitat variable into a string for alexa to speak. "The variable you asked for has a value of [variable value]. The variable in this case is a number, and it is exposed to NodeRed. My thought is to use a change node to set my speech variable to the new string with the variable value inserted, but I don't have any direction on how to actually do that. I assume it would be easiest with json or a jsonata expression? But I honestly have no idea. Any tips?
JSONATA...
"this message has this " & payload & " value for a payload."
You can also use template nodes as well ..
edit: You can even use "Inline If" statements:
payload.value = "on" ? "switch is on" : "switch is off"
"The " & topic & " switch is " & (payload.value = "on" ? "on" : "off") & "."
(yes I know you could just use "payload.value" here but this is an example to show possibilities)
That I'm not 100% sure of, I believe it does. The node generates true/false msgs for events. Whether physical at the device or digitally.
Part of the reason for eliminating some of this older stuff is I'm getting random hub reboots that " occur within minutes of my sunrise/sunset times. My automations for those events are triggered from NR. These reboots have just started in the last few weeks as I moved more logic into NR and removed the logic and apps from the hub.
I have a email into support, waiting for a response.