Morning Routine Flow

I’m in the process of moving over from Hubitat and heavily used modes in Hubitat. In an attempt to emulate them, I am using flows in Node-RED that are tied to a switch. I think I’ve figured out most of it, but can’t seem to figure out how to set a high / low set point for my Ecobee thermostat and how to turn ceiling fans on if the outside temperature is above a certain point.

Here is my current flow. It is designed to turn certain lights and switches on, turn certain lights and switches off and to turn certain lights, switches and fans off after one hour. I am brand new to Node-RED, so any tips, tricks or advice regarding my flow would be much appreciated.

Cheers!

Sounds like you can do this with a generic thermostat.
At least the fan, not sure what exactly you are looking for with the Ecobee.

Coming from Smartthings, I heavily used modes as well. To carry that over, I created an “Input Select”, Input Select - Home Assistant with defined modes of Away, Home, and Night. My Node Red automations heavily use these modes, as both conditions and triggers. Other automations change and set those modes based on presence, time of day, etc.

You would do a call service node, and in the data field, choose the {} for JSON in the drop down, and then convert the YAML required by the call service to JSON. The key with Node red is it uses JSON, while Home Assistant uses YAML. You can use a YAML to JSON converter like this - Transform YAML into JSON - Online YAML Tools and it would look like this:

{
    "target_temp_high": 80,
    "target_temp_low": 66,
    "hvac_mode": "heat"
}

Screenshot from 2022-05-03 12-20-24

Probably better ways to do this then the example I’m showing, but I have a similar situation with heat tape that turns on and off in the winter when the temperature falls and goes over 38 degrees:

First, I created an input boolean called input_boolean.above_38

Temperature is updated constantly, and I didn’t want it to keep triggering the automation every time temperature updated. I only wanted to trigger once as it rose and fell under the threashold. To get this to work, I took the continuous input from the sensor.openweathermap_temperature and used it to turning the above_38 boolean on and off as the temperature rises and falls.

Then automations are done off that boolean going on and off.

Flow code

[{"id":"548b3df1d66be332","type":"server-state-changed","z":"b1085131afd3723b","name":"Above 38","server":"ae531ce.a39906","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.openweathermap_temperature","entityidfiltertype":"exact","outputinitially":true,"state_type":"str","haltifstate":"38","halt_if_type":"num","halt_if_compare":"gt","outputs":2,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":true,"ignorePrevStateUnknown":true,"ignorePrevStateUnavailable":true,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":130,"y":1420,"wires":[["1206487dc5b68629"],["df557a296ab67612"]]},{"id":"1206487dc5b68629","type":"api-call-service","z":"b1085131afd3723b","name":"Above 38","server":"ae531ce.a39906","version":3,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.above_38","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":290,"y":1400,"wires":[[]]},{"id":"df557a296ab67612","type":"api-call-service","z":"b1085131afd3723b","name":"Under 38","server":"ae531ce.a39906","version":3,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.above_38","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":290,"y":1460,"wires":[[]]},{"id":"7c46b25b6cb0242f","type":"server-state-changed","z":"b1085131afd3723b","name":"Rise Above 38","server":"ae531ce.a39906","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.above_38","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":true,"ignorePrevStateUnknown":true,"ignorePrevStateUnavailable":true,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":160,"y":1560,"wires":[["341f95164805f740"],["12e38fa95087d944"]]},{"id":"341f95164805f740","type":"api-current-state","z":"b1085131afd3723b","name":"Winter?","server":"ae531ce.a39906","version":2,"outputs":2,"halt_if":"winter","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.season","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":350,"y":1520,"wires":[["8b04e07eb0999c93"],[]]},{"id":"8b04e07eb0999c93","type":"api-current-state","z":"b1085131afd3723b","name":"Heat Tape?","server":"ae531ce.a39906","version":2,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.heat_tape","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":520,"y":1520,"wires":[["edc362bcc3194827"],[]]},{"id":"edc362bcc3194827","type":"api-call-service","z":"b1085131afd3723b","name":"Outdoor Plug Off","server":"ae531ce.a39906","version":3,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.outdoor_plug","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":740,"y":1520,"wires":[[]]},{"id":"fd30d58db7221b77","type":"api-call-service","z":"b1085131afd3723b","name":"Outdoor Plug On","server":"ae531ce.a39906","version":3,"debugenabled":false,"service_domain":"switch","service":"turn_on","entityId":"switch.outdoor_plug","data":"","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":880,"y":1600,"wires":[[]]},{"id":"848ab4b5b1196700","type":"api-current-state","z":"b1085131afd3723b","name":"Heat Tape?","server":"ae531ce.a39906","version":2,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.heat_tape","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":520,"y":1600,"wires":[["3368af4e682a3d40"],[]]},{"id":"12e38fa95087d944","type":"api-current-state","z":"b1085131afd3723b","name":"Winter?","server":"ae531ce.a39906","version":2,"outputs":2,"halt_if":"winter","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.season","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":350,"y":1600,"wires":[["848ab4b5b1196700"],[]]},{"id":"3368af4e682a3d40","type":"time-range-switch","z":"b1085131afd3723b","name":"Daytime","lat":"43.10522","lon":"-78.80427","startTime":"sunrise","endTime":"sunset","startOffset":0,"endOffset":0,"x":690,"y":1600,"wires":[["fd30d58db7221b77"],[]]},{"id":"ae531ce.a39906","type":"server","name":"Home Assistant","version":1,"legacy":false,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]
1 Like

This solved my thermostat question. Thanks!

I’ll take a look at the input select.

So I’m still a bit confused on using a temperate variable… In Hubitat I had a rule that said if temp > 78 at the time that the rule ran, turn on a switch. When my morning routine ran, a rule looked at my thermostat (ecobee) temperature and turned on the ceiling fans if it was above 78.

That’s a little trickier because you actually have to extract an attribute, current temperature, from your thermostat.

You can do that with a “render template” node and then use a “switch node” to compare the temperature. I also use a “morning mode” input boolean to trigger my morning runs.

So it would look like this:

[{"id":"51ac35e75cbcebe2","type":"api-render-template","z":"65d4f7b6aa8e19da","name":"Upper Temperature","server":"ae531ce.a39906","version":0,"template":"{{ state_attr(\"climate.upper_floor_heat\", \"current_temperature\") }}","resultsLocation":"payload","resultsLocationType":"msg","templateLocation":"template","templateLocationType":"msg","x":310,"y":660,"wires":[["74258788a8b74de9"]]},{"id":"74258788a8b74de9","type":"switch","z":"65d4f7b6aa8e19da","name":"Above 78","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"78","vt":"str"}],"checkall":"false","repair":false,"outputs":1,"x":500,"y":660,"wires":[["12fff0036dc5e22e"]]},{"id":"12fff0036dc5e22e","type":"api-call-service","z":"65d4f7b6aa8e19da","name":"Fan On","server":"ae531ce.a39906","version":3,"debugenabled":false,"service_domain":"fan","service":"turn_on","entityId":"fan.bedroom_fan","data":"{\"percentage\":50}","dataType":"jsonata","mergecontext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":660,"y":660,"wires":[[]]},{"id":"c30d69f3452bcc83","type":"server-state-changed","z":"65d4f7b6aa8e19da","name":"Morning Mode","server":"ae531ce.a39906","version":3,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.morning_mode","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":110,"y":660,"wires":[["51ac35e75cbcebe2"],[]]},{"id":"ae531ce.a39906","type":"server","name":"Home Assistant","version":1,"legacy":false,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]
1 Like

Render template always makes a call to Home Assistant. There are other methods that will use a cached value stored in NR to look up the temperature.

Using a current state node
image
image

[{"id":"803ce2101e5ac8b4","type":"server-state-changed","z":"9ce66650da8a41cc","name":"Morning Mode","server":"","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.morning_mode","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":218,"y":256,"wires":[["aa2054447ec8d2ca"],[]]},{"id":"aa2054447ec8d2ca","type":"api-current-state","z":"9ce66650da8a41cc","name":"","server":"","version":3,"outputs":2,"halt_if":"$number($entity().attributes.temperature) > 78","halt_if_type":"jsonata","halt_if_compare":"jsonata","entity_id":"climate.upper_floor_heat","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":496,"y":256,"wires":[["6480112694b3595b"],[]]},{"id":"6480112694b3595b","type":"api-call-service","z":"9ce66650da8a41cc","name":"Fan On","server":"","version":5,"debugenabled":false,"domain":"fan","service":"turn_on","areaId":[],"deviceId":[],"entityId":["fan.bedroom_fan"],"data":"{\"percentage\":50}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":740,"y":256,"wires":[[]]}]

Using a trigger state node

image
image

[{"id":"9c9e0affdae1513a","type":"trigger-state","z":"9ce66650da8a41cc","name":"","server":"","version":2,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"input_boolean.morning_mode","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"targetType":"entity_id","targetValue":"climate.upper_floor_heat","propertyType":"property","propertyValue":"attributes.temperature","comparatorType":">","comparatorValueDatatype":"str","comparatorValue":"75"}],"inputs":0,"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","enableInput":false,"x":304,"y":320,"wires":[["3d716ab10d80e6ec"],[]]},{"id":"3d716ab10d80e6ec","type":"api-call-service","z":"9ce66650da8a41cc","name":"Fan On","server":"","version":5,"debugenabled":false,"domain":"fan","service":"turn_on","areaId":[],"deviceId":[],"entityId":["fan.bedroom_fan"],"data":"{\"percentage\":50}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":564,"y":320,"wires":[[]]}]

Using output properties of the event state node to add the temperature to the msg object.

image


image

[{"id":"74258788a8b74de9","type":"switch","z":"9ce66650da8a41cc","name":"Above 78","property":"currentTemperature","propertyType":"msg","rules":[{"t":"gte","v":"78","vt":"str"}],"checkall":"false","repair":false,"outputs":1,"x":596,"y":160,"wires":[["12fff0036dc5e22e"]]},{"id":"12fff0036dc5e22e","type":"api-call-service","z":"9ce66650da8a41cc","name":"Fan On","server":"","version":5,"debugenabled":false,"domain":"fan","service":"turn_on","areaId":[],"deviceId":[],"entityId":["fan.bedroom_fan"],"data":"{\"percentage\":50}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":756,"y":160,"wires":[[]]},{"id":"c30d69f3452bcc83","type":"server-state-changed","z":"9ce66650da8a41cc","name":"Morning Mode","server":"","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.morning_mode","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"},{"property":"currentTemp","propertyType":"msg","value":"$entities(\"climate.upper_floor_heat\").attributes.current_temperature","valueType":"jsonata"}],"x":438,"y":160,"wires":[["74258788a8b74de9"],[]]}]
1 Like

Thanks, these options look much more efficient. I’ll have to make some updates :slight_smile: