Electric Savings with Solar and Load Control

There are a number of great Energy projects in Home Assistant. I wish to share my project for controlling my heat pumps to limit grid demand and cost. My target is to save > 50% from my historical energy bills.

I. Introduction
Utility-scale management with distributed (solar) power sources is a complex issue. Utility cost, particularly for delivery of peak-power, is a major concern. My utility, Salt River Project (Phoenix, AZ USA) has responded with residential tariff for solar customers with low “volumetric” energy (kWh) rates but high (escalating) charges for on-peak power demand (kW). A detailed explanation with analysis may be found here:

Unfortunately, this pricing plan makes residential solar an unattractive investment for most customers. However, I decided to try to find a way to realize a ~10-year payback period for solar by writing my own “load controller” in HA. (I decided not to install a commercial load controller due to cost and to concerns about cycling appliance power off and on.)

Here I will outline the approach I am taking for demand/load control and home energy management.

This applies to home cooling during summer months.

II. Approach and equipment

My largest electrical loads during the summer are from two air-to-air split heat pumps. We defer other large loads to off-peak (hot water, laundry, oven etc.). Summer peak-tariff periods are from 14:00-20:00 weekdays. The automations control the use of the heat pumps. Rather than turn the HP’s on and off, the automation sets low or high temperature setpoints. This allows each HP to ramp power as designed.

Summary

I use a Sense Home Energy Monitor (Solar model), and I have two inverter heat pumps controlled by two Ecobee thermostats. The larger heat pump is for the downstairs (rated at 5 tons or 17.5 kW), and the smaller for the upstairs (rated at 3 tons or 10.5 kW). Typical power draw is much less than the rated power. The Ecobees are controlled by a Hubitat hub (I started in home automation with Hubitat), and I created two virtual switches that are shared with Home Assistant.
In Home Assistant I am using the Node-Red add-on for automation. I think Node Red greatly facilitated writing the main automation.

III. Automations

a. “Supercool” This is a simple automation that pre-cools the home from 08:00 – 14:00 (off-peak) to a setpoint adjusted based on the high-temperature forecast for the day. For hot days the setpoint is around 70 F (21 C). My wife complains about the “cold,” but pre-cooling is necessary to limit maximum temperature in the home later in the day.

b. Thermostat control. This is an automation that controls Ecobee temperature setpoints based on the state of the two virtual switches. If the “Upstairs Heatpump” switch is “on,” the setpoint on the corresponding Ecobee is set to 70 F (21 C). If it’s off the setpoint is set to 85 F (29.4 C). The same applies to the “Downstairs Thermostat.” This automation runs every 6 minutes to avoid excessive heat pump cycling but allow responsiveness to loss of solar power or to high grid demand. This automation is constrained to run only during peak-rate periods on weekdays.

c. Primary “Switch Automation” in Node Red. In NR, I decided not to create complex objects or arrays containing all the information required to set the switches, opting instead to use message payloads. I created a few global variables that are used several times in the flow. I also created a couple of sub-flows to tidy up the look a bit.

Note that this is my very first Node Red automation, and it’s likely there are more efficient ways of accomplishing the same goals.


Trigger (30 s) and set Global Variables. The automation uses Net Power production (Solar – total power use, minimum 0), the setpoints for the upstairs and downstairs thermostats, and reads in a Demand Limit from a helper. The two change nodes for thermostat setpoints pull the setpoints from the message object and set corresponding global variables. FYI, global variables are used since they are passed to sub-flows.


Main Automation. The green nodes are debug nodes. The blue call-service nodes simply set the states of the two virtual switches. For example:
image
Call service node that turns on both virtual switches.

The logic is set by several switch nodes.

First Power Switch:

This switch takes the rolling-average Net Power Production and evaluates whether there is enough excess power to start both heat pumps (output 1), enough excess power to start one of the two heat pumps (output 2), enough excess power to “do nothing” (if one or both heat pumps are running this is ok), or zero Net Power Production (which requires evaluating how much power is being pulled from the grid).

From here there are several possible combinations of Heat Pump states and grid export/import power levels that are used to set the virtual switches. Explaining the rest would require a very long (and very dull) post. But the idea is to set the switches in such a way as to keep the demand below a threshold (demand_limit).

IV. Performance

So, how well does it work? Here is an example from yesterday.

Power and temperature plots for yesterday. On the power plot, you can see that grid demand fell at 14:00 (the start of the peak-tariff period). Around 16:00 it appeared that the automation was not working – you can see that power was being exported to the grid. I found that the Ecobee thermostats were in “eco+ mode,” and at that time my thermostats were ignoring the automation setpoints. Around 16:54 I turned eco+ off, but it was too late to prevent the home from becoming uncomfortably warm. Lesson learned!
(Apologies for using the Fahrenheit temperature scale – my wife would be unhappy if I set up the thermostats in Celsius.)

Yesterday, my power company reported that my peak demand was 1.2 kW, which occurred after sunset between 19:30 and 20:00. Maximum demand between 14:00 and 18:30 was 1.0 kW, a little below the automation’s demand_limit.

My June electric bill ran around 30% of historical values, and if I stay on-track with demand, July will be about the same. It’s early days, but so far, I am on-track with my goal to pay-back the solar panel investment in < 10 years.

3 Likes

Did you share the code as well?
Would like to have a look of I could use some of it.

HI @jhrath,

Just saw your request. I will be on travel for the next 10 days. I’ll return to your request then.

The primary code as mentioned sets virtual switches for turning heap pumps “on” or “off” (III.c). I’m running thermostat control with another hub (Hubitat), simply because I started with Hubitat and it works well. It would be easy to read the “pseudocode” and port to Home Assistant.

Over the course of a record-hot summer here, I’m saving over 50% on my power bill compared to previous years, and I was aggressive about deferring power use in past years during peak time.

Hello @jhrath,

  1. SuperCool

“Supercool” is the first of the automations. I’m using a simple formula to calculate the setpoint that uses the forecast high temperature. Note that all temperatures here are in Fahrenheit.

This is the first time I am sharing node red code, I hope you can read/import this.

[{"id":"99d206213eaa9807","type":"tab","label":"Supercool","disabled":false,"info":"","env":[]},{"id":"ac0d09d55d98dfde","type":"inject","z":"99d206213eaa9807","name":"Trigger 5:00 PM daily","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"00 17 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":100,"wires":[["8954b9aa2084b424"]]},{"id":"e998a1e7e8892098","type":"api-call-service","z":"99d206213eaa9807","name":"Supercool Setpoint","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"climate","service":"set_temperature","areaId":[],"deviceId":["f657170607213beece37307b2cbb6f4f"],"entityId":["sensor.supercool_setpoint_temperature"],"data":"{\"temperature\": msg.payload}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":230,"y":180,"wires":[["6d477df34c4da067"]]},{"id":"6d477df34c4da067","type":"debug","z":"99d206213eaa9807","name":"Supercool SP","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":600,"y":180,"wires":[]},{"id":"8954b9aa2084b424","type":"api-current-state","z":"99d206213eaa9807","name":"Forecast High","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.weather_tomorrow_max_temp","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"},{"property":"parts","propertyType":"msg","value":"","valueType":"num"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":340,"y":100,"wires":[["e9a4d8b59b33b8fe"]]},{"id":"e9a4d8b59b33b8fe","type":"function","z":"99d206213eaa9807","name":"Adjust Supercool SP","func":"\n// Extract the temperature from the input payload\nvar T = msg.payload;\n\n// Perform the temperature conversion\nvar output = 74 - (T - 94) / 4;\n\n// Set the converted temperature as the output payload\nmsg.payload = output;\n\n// Return the modified message\nreturn msg;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":100,"wires":[["e998a1e7e8892098"]]},{"id":"95cc2380.4ef81","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

I started this project before I began using Home Assistant, and the direct control of the Ecobee Thermostats is with Hubitat Elevation. There is an Ecobee integration for Home Assistant, and If I were starting over I’d simply do everything in Home Assistant. However, I think it’s easy to read Hubitat Automations, so you should have no trouble making equivalent automations in Home Assistant.

Convert the Supercool Setpoint to a Hubitat Local Variable (including this just for completeness):

SuperCool Automation

  1. Thermostat Control (uses settings from the Virtual Switches).
    Virtual Switches were created in Hubitat and shared with Home Assistant.

  1. Heat Pump Switch Automation
    This is the primary automation that sets virtual switches in Node Red (plugin).

(see next message… there is a character limit on posts)

Heat Pump Automation

[{"id":"c51d38339c64c7c7","type":"subflow","name":"Subflow 6","info":"","in":[{"x":40,"y":160,"wires":[{"id":"49c63435c5b13e78"}]}],"out":[{"x":680,"y":80,"wires":[{"id":"44eb78d8c040adb5","port":0}]},{"x":680,"y":80,"wires":[{"id":"44eb78d8c040adb5","port":1}]},{"x":680,"y":240,"wires":[{"id":"0de37c8770e49835","port":0}]},{"x":680,"y":240,"wires":[{"id":"0de37c8770e49835","port":1}]}]},{"id":"49c63435c5b13e78","type":"change","z":"c51d38339c64c7c7","name":"Upstairs SP","rules":[{"t":"set","p":"payload","pt":"msg","to":"Upstairs_SP","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":190,"y":160,"wires":[["b3c7b08dd019d626"]]},{"id":"b3c7b08dd019d626","type":"switch","z":"c51d38339c64c7c7","name":"","property":"payload","propertyType":"msg","rules":[{"t":"lte","v":"75.0","vt":"num"},{"t":"gt","v":"75.0","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":330,"y":160,"wires":[["0bc06ab2f127ce68"],["ad82477ff8c114ae"]]},{"id":"0bc06ab2f127ce68","type":"change","z":"c51d38339c64c7c7","name":"Downstairs SP","rules":[{"t":"set","p":"payload","pt":"msg","to":"Downstairs_SP","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":380,"y":80,"wires":[["44eb78d8c040adb5"]]},{"id":"ad82477ff8c114ae","type":"change","z":"c51d38339c64c7c7","name":"Downstairs SP","rules":[{"t":"set","p":"payload","pt":"msg","to":"Downstairs_SP","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":380,"y":240,"wires":[["0de37c8770e49835"]]},{"id":"44eb78d8c040adb5","type":"switch","z":"c51d38339c64c7c7","name":"","property":"payload","propertyType":"msg","rules":[{"t":"lte","v":"75.0","vt":"num"},{"t":"gt","v":"75.0","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":80,"wires":[[],[]]},{"id":"0de37c8770e49835","type":"switch","z":"c51d38339c64c7c7","name":"","property":"payload","propertyType":"msg","rules":[{"t":"lte","v":"75.0","vt":"num"},{"t":"gt","v":"75.0","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":240,"wires":[[],[]]},{"id":"2c29ba9c617d20a5","type":"tab","label":"Heat Pump Switch Control","disabled":false,"info":"","env":[]},{"id":"03a26ff333137812","type":"inject","z":"2c29ba9c617d20a5","name":"30 s","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"30","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":90,"y":460,"wires":[["22f1ee23a157eb92","a0d7ced3a3422ee9","566c827b3db5d018","9e472044423f83d5"]]},{"id":"22f1ee23a157eb92","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Net Power Production","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.grid_export","state_type":"num","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":180,"y":360,"wires":[["61ad75c805a65727"]]},{"id":"61ad75c805a65727","type":"function","z":"2c29ba9c617d20a5","name":"Average Last 5 Readings","func":"let values = context.get(\"values\") || [];\n\nvalues.push(msg.payload);\n\nif (values.length > 5) {\n    values.shift();\n}\n\nlet sum = values.reduce((acc, curr) => acc + curr, 0);\nlet avg = sum / values.length;\n\ncontext.set(\"values\", values);\n\nmsg.payload = avg;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":210,"y":240,"wires":[["e51b9e29fd504fcc","ca0482e75f9981fc"]]},{"id":"9d480c95dbd7d080","type":"debug","z":"2c29ba9c617d20a5","name":"Avg_Net_Power","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":380,"y":160,"wires":[]},{"id":"e51b9e29fd504fcc","type":"change","z":"2c29ba9c617d20a5","name":"Set Global var","rules":[{"t":"set","p":"Avg_Net_Power","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":200,"y":160,"wires":[["9d480c95dbd7d080"]]},{"id":"a0d7ced3a3422ee9","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Upstairs Thermostat","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"climate.upstairs","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":300,"y":440,"wires":[["85d11aa01bf528c9"]]},{"id":"566c827b3db5d018","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Downstairs Thermostat","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"climate.downstairs","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":310,"y":520,"wires":[["9ad981d54fe56d52"]]},{"id":"9ad981d54fe56d52","type":"change","z":"2c29ba9c617d20a5","name":"Downstairs SP","rules":[{"t":"set","p":"Downstairs_SP","pt":"global","to":"data.attributes.temperature","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"Downstairs_SP","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":520,"wires":[[]]},{"id":"85d11aa01bf528c9","type":"change","z":"2c29ba9c617d20a5","name":"Upstairs SP","rules":[{"t":"set","p":"Upstairs_SP","pt":"global","to":"data.attributes.temperature","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"Upstairs_SP","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":440,"wires":[[]]},{"id":"fd3c17071f287c2e","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"4500","vt":"str"},{"t":"btwn","v":"1000","vt":"num","v2":"4500","v2t":"num"},{"t":"btwn","v":"1","vt":"num","v2":"1000","v2t":"num"},{"t":"lte","v":"1","vt":"num"}],"checkall":"false","repair":false,"outputs":4,"x":710,"y":240,"wires":[["8acd95e8c1e71433"],["3eb4b81076e4b50b"],["355b6c8888271f7c"],["7c6d510aea9edc94"]]},{"id":"8acd95e8c1e71433","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.downstairs_ac_switch","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":680,"y":100,"wires":[["7def42454fc74d14"]]},{"id":"7def42454fc74d14","type":"debug","z":"2c29ba9c617d20a5","name":"Turn Both ON","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":840,"y":100,"wires":[]},{"id":"355b6c8888271f7c","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":990,"y":340,"wires":[]},{"id":"65c15703725b50e6","type":"debug","z":"2c29ba9c617d20a5","name":"Leave Both ON 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1330,"y":20,"wires":[]},{"id":"6e1ba578343538b1","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.downstairs_ac_switch","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1160,"y":20,"wires":[["65c15703725b50e6"]]},{"id":"ea9200101714bd0d","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"1600","vt":"str"},{"t":"lt","v":"1600","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1370,"y":200,"wires":[["a37ee96d98d36c96"],["0c7c392a49746204"]]},{"id":"a39066b187e3fac0","type":"debug","z":"2c29ba9c617d20a5","name":"Leave Upstaris OFF 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1980,"y":220,"wires":[]},{"id":"4e5a7af12709a0fd","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"2000","vt":"str"},{"t":"lt","v":"2000","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":1390,"y":100,"wires":[["071e3996aa243a5c"],["48bd626aab1225f3"]]},{"id":"071e3996aa243a5c","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1570,"y":60,"wires":[["01d216239bf0cb49"]]},{"id":"a6774881f123b7e9","type":"debug","z":"2c29ba9c617d20a5","name":"Leave Upstairs ON 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1980,"y":120,"wires":[]},{"id":"9e0878971e6bae93","type":"debug","z":"2c29ba9c617d20a5","name":"Downstairs (both) ON 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1970,"y":60,"wires":[]},{"id":"d9e9e18df92d2f3a","type":"debug","z":"2c29ba9c617d20a5","name":"Upstairs (both) ON 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1740,"y":180,"wires":[]},{"id":"691ae91051ed72d6","type":"change","z":"2c29ba9c617d20a5","name":"Avg Net Power","rules":[{"t":"set","p":"payload","pt":"msg","to":"Avg_Net_Power","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":1220,"y":200,"wires":[["ea9200101714bd0d"]]},{"id":"b31d9832cf480553","type":"change","z":"2c29ba9c617d20a5","name":"Avg Net Power","rules":[{"t":"set","p":"payload","pt":"msg","to":"Avg_Net_Power","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":1240,"y":100,"wires":[["4e5a7af12709a0fd"]]},{"id":"13e95fe4dd288fc1","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1590,"y":280,"wires":[["d9c024b468254015"]]},{"id":"f84454f6749ecf02","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1580,"y":320,"wires":[["5c35b91d7844278a"]]},{"id":"cf9d42a62a8209c6","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"3500","vt":"str"},{"t":"btwn","v":"1650","vt":"num","v2":"3500","v2t":"num"},{"t":"lt","v":"1650","vt":"num"}],"checkall":"true","repair":false,"outputs":3,"x":1390,"y":300,"wires":[["13e95fe4dd288fc1"],["f84454f6749ecf02"],["81da7da2fe074563"]]},{"id":"fbca3f4b52eb5f10","type":"debug","z":"2c29ba9c617d20a5","name":"Downstairs ON 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1990,"y":280,"wires":[]},{"id":"48632030c817c6a1","type":"debug","z":"2c29ba9c617d20a5","name":"Upstairs ON 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1980,"y":320,"wires":[]},{"id":"8a69ccbd437b9d90","type":"change","z":"2c29ba9c617d20a5","name":"Avg Net Power","rules":[{"t":"set","p":"payload","pt":"msg","to":"Avg_Net_Power","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":1220,"y":300,"wires":[["cf9d42a62a8209c6"]]},{"id":"7f9e1cf59728308b","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing (both off) 9","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1140,"y":860,"wires":[]},{"id":"6ba90db2a08f9343","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1480,"y":440,"wires":[["3f2d597056358ade"]]},{"id":"7fef0a14ccbdf74f","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both AC Units OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1470,"y":380,"wires":[["1264ce4a29e712b0"]]},{"id":"1264ce4a29e712b0","type":"debug","z":"2c29ba9c617d20a5","name":"Both OFF 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1690,"y":380,"wires":[]},{"id":"7bf581b202a40bb8","type":"debug","z":"2c29ba9c617d20a5","name":"Downstairs OFF 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1890,"y":440,"wires":[]},{"id":"44c2deb6dda0eb08","type":"debug","z":"2c29ba9c617d20a5","name":"Upstairs OFF 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1960,"y":500,"wires":[]},{"id":"2be285145ba12967","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac_switch"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1530,"y":500,"wires":[["4ceadd8f67081671"]]},{"id":"f0d030d404740919","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"4000","vt":"str"},{"t":"btwn","v":"3000","vt":"num","v2":"4000","v2t":"num"},{"t":"btwn","v":"demand_limit","vt":"global","v2":"3000","v2t":"num"},{"t":"lte","v":"demand_limit","vt":"global"}],"checkall":"true","repair":false,"outputs":4,"x":1250,"y":440,"wires":[["7fef0a14ccbdf74f"],["6ba90db2a08f9343"],["2be285145ba12967"],["1fa7d6c7eb10cc8a"]]},{"id":"dfb7c9b25bf4a3c4","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing (both on) 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1500,"y":560,"wires":[]},{"id":"e8c602b4718e40df","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Net Power Import","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.grid_import","state_type":"num","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":1050,"y":440,"wires":[["f0d030d404740919"]]},{"id":"65c0de97787a29c1","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Net Power Import","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.grid_import","state_type":"num","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":1070,"y":760,"wires":[["8a354a3078acd45c"]]},{"id":"1c96af46192f7518","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Net Power Import","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.grid_import","state_type":"num","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":1090,"y":680,"wires":[["945fb22e09973617"]]},{"id":"945fb22e09973617","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"demand_limit","vt":"global"},{"t":"lt","v":"demand_limit","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":1270,"y":680,"wires":[["c7b939ad3362e161"],["8bbfbd9a88fb9b7e"]]},{"id":"c7b939ad3362e161","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac_switch"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1090,"y":620,"wires":[["2adbce5bc007ef85"]]},{"id":"be8bbb4264a6dd6a","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing (Upstairs on) 7","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1870,"y":680,"wires":[]},{"id":"95a628eacad485a3","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing (Downstairs on) 8","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1840,"y":800,"wires":[]},{"id":"37bb734d6fc40d50","type":"debug","z":"2c29ba9c617d20a5","name":"Upstairs OFF 7","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1500,"y":620,"wires":[]},{"id":"ca0482e75f9981fc","type":"link out","z":"2c29ba9c617d20a5","name":"link out 1","mode":"link","links":["b5f9d1c3c1f1eafb"],"x":385,"y":280,"wires":[]},{"id":"b5f9d1c3c1f1eafb","type":"link in","z":"2c29ba9c617d20a5","name":"link in 1","links":["ca0482e75f9981fc"],"x":485,"y":260,"wires":[["fd3c17071f287c2e"]]},{"id":"01d216239bf0cb49","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1760,"y":60,"wires":[["9e0878971e6bae93"]]},{"id":"48bd626aab1225f3","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1560,"y":120,"wires":[["9af1b64691a53dd4"]]},{"id":"9af1b64691a53dd4","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1760,"y":120,"wires":[["a6774881f123b7e9"]]},{"id":"0c7c392a49746204","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac_switch"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1570,"y":220,"wires":[["208ee7f495d9991e"]]},{"id":"208ee7f495d9991e","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1770,"y":220,"wires":[["a39066b187e3fac0"]]},{"id":"d9c024b468254015","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac_switch"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1790,"y":280,"wires":[["fbca3f4b52eb5f10"]]},{"id":"5c35b91d7844278a","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1780,"y":320,"wires":[["48632030c817c6a1"]]},{"id":"3f2d597056358ade","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1680,"y":440,"wires":[["7bf581b202a40bb8"]]},{"id":"4ceadd8f67081671","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1750,"y":500,"wires":[["44c2deb6dda0eb08"]]},{"id":"a37ee96d98d36c96","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.downstairs_ac_switch","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1540,"y":180,"wires":[["d9e9e18df92d2f3a"]]},{"id":"2adbce5bc007ef85","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1290,"y":620,"wires":[["37bb734d6fc40d50"]]},{"id":"8bbfbd9a88fb9b7e","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1440,"y":680,"wires":[["ea0323494992ddde"]]},{"id":"ea0323494992ddde","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1640,"y":680,"wires":[["be8bbb4264a6dd6a"]]},{"id":"8a354a3078acd45c","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"demand_limit","vt":"global"},{"t":"lt","v":"demand_limit","vt":"global"}],"checkall":"true","repair":false,"outputs":2,"x":1250,"y":760,"wires":[["fa55d538da2edc42"],["62b9ac1c4936d6a7"]]},{"id":"fa55d538da2edc42","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both AC Units OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1430,"y":740,"wires":[["23d4a79f74811771"]]},{"id":"62b9ac1c4936d6a7","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1410,"y":800,"wires":[["38cd841d87749c5b"]]},{"id":"38cd841d87749c5b","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac_switch"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1610,"y":800,"wires":[["95a628eacad485a3"]]},{"id":"9265ac10fb3d8ecf","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both AC Units OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":910,"y":860,"wires":[["7f9e1cf59728308b"]]},{"id":"3eb4b81076e4b50b","type":"subflow:c51d38339c64c7c7","z":"2c29ba9c617d20a5","name":"HP states","x":960,"y":200,"wires":[["6e1ba578343538b1"],["b31d9832cf480553"],["691ae91051ed72d6"],["8a69ccbd437b9d90"]]},{"id":"7c6d510aea9edc94","type":"subflow:c51d38339c64c7c7","z":"2c29ba9c617d20a5","name":"HP states","x":740,"y":580,"wires":[["e8c602b4718e40df"],["1c96af46192f7518"],["65c0de97787a29c1"],["9265ac10fb3d8ecf"]]},{"id":"acdbff5bfd5659a8","type":"comment","z":"2c29ba9c617d20a5","name":"ON/OFF states","info":"HP states: Upstairs-Downstairs\n1. ON-ON\n2. ON-OFF\n3. OFF-ON\n4. OFF-OFF","x":980,"y":260,"wires":[]},{"id":"43edc27a54494ec6","type":"comment","z":"2c29ba9c617d20a5","name":"ON/OFF states","info":"HP states: Upstairs-Downstairs\n1. ON-ON\n2. ON-OFF\n3. OFF-ON\n4. OFF-OFF","x":720,"y":660,"wires":[]},{"id":"1fa7d6c7eb10cc8a","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.downstairs_ac_switch","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1320,"y":560,"wires":[["dfb7c9b25bf4a3c4"]]},{"id":"23d4a79f74811771","type":"debug","z":"2c29ba9c617d20a5","name":"Both OFF 7","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1630,"y":740,"wires":[]},{"id":"9e472044423f83d5","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Demand Limit (W)","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_number.demand_limit_setpoint","state_type":"num","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":250,"y":600,"wires":[["3e571b961c5013b9"]]},{"id":"3e571b961c5013b9","type":"change","z":"2c29ba9c617d20a5","name":"demand_limit","rules":[{"t":"set","p":"demand_limit","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":600,"wires":[[]]},{"id":"81da7da2fe074563","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1230,"y":360,"wires":[]},{"id":"95cc2380.4ef81","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

I use a couple of subflows to simplify the display. Let me know if you have any trouble importing this.

Best wishes - I hope this is helpful.

Thanks for sharing. I actually took this and converted the Node-Red into just plain home assistant automations. Where I am confused is the logic around pulling ecobee temperature and setting it to 70. However, the subflow is looking for 75. Looking at your pics, it doesnt look like it is set at 70 or 75. Can you elaborate for me please what the subflow is doing with the 75F?

Hi Justin,

Since posting I have changed a few things. But the purpose of the original sub-flow was to ascertain the state of the heat pumps by looking at the set points. I used 75 F as a threshold value; if set point is below threshold then the inferred state is “cooling” which I represent as “On.”

(Side note: storing the two states in an array would have been more elegant, but I don’t know how to do that in NR or HA.)

The idea is to determine actions based on both the power (either excess solar or power from the grid) and the states of the two heat pumps.

This year I’ve converted to using the HomeKit integration for local control of the two Ecobee’s, inside Home Assistant. This allowed me to pull all automations inside Home Assistant.

The HomeKit integration enabled determining the state of each heat pump directly. So the updated sub-flows and nodes “Upstairs Thermostat” and “Downstairs Thermostat” to pull the actual state of each thermostat (either “cooling” or “idle”). Let me know if you wish to see the updated flow itself.

Congratulations on implementing your own automation! I hope it is working well for you. :smile:

Sure, would love to see what you came up with. I would love to see what you learned so I can incorporate those learnings. Didn’t know homekit will bring ecobee into local calls. Gonna make that change now as that is one of my last few remaining cloud based integrations.

OK, here is the Switch Flow, part 1. The entire flow is too large for one message. Copy and paste the following and the contents of the next message into your code editor.

[{"id":"a8e6987e60f0d9b1","type":"subflow","name":"Subflow 7","info":"","in":[{"x":60,"y":120,"wires":[{"id":"706b299d785b1521"}]}],"out":[{"x":1020,"y":80,"wires":[{"id":"ee9da2ec5c7b811d","port":0}]},{"x":1020,"y":80,"wires":[{"id":"ee9da2ec5c7b811d","port":1}]},{"x":1020,"y":140,"wires":[{"id":"0600f3f6c5dd4ec1","port":0}]},{"x":1020,"y":140,"wires":[{"id":"0600f3f6c5dd4ec1","port":1}]}]},{"id":"706b299d785b1521","type":"change","z":"a8e6987e60f0d9b1","name":"Upstairs HVAC Mode","rules":[{"t":"set","p":"payload","pt":"msg","to":"Upstairs_HVAC_Action","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":240,"y":120,"wires":[["fe30de6215106090"]]},{"id":"fe30de6215106090","type":"switch","z":"a8e6987e60f0d9b1","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"cooling","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":450,"y":120,"wires":[["7ddd8b09d309ad07","4af04f5b6d8e1b26"],["fc1f8927f30c85c7","692e45d08216a4d3"]]},{"id":"7ddd8b09d309ad07","type":"change","z":"a8e6987e60f0d9b1","name":"Downstairs HVAC Mode","rules":[{"t":"set","p":"payload","pt":"msg","to":"Downstairs_HVAC_Action","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":80,"wires":[["ee9da2ec5c7b811d"]]},{"id":"fc1f8927f30c85c7","type":"change","z":"a8e6987e60f0d9b1","name":"Downstairs HVAC Mode","rules":[{"t":"set","p":"payload","pt":"msg","to":"Downstairs_HVAC_Action","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":140,"wires":[["0600f3f6c5dd4ec1"]]},{"id":"ee9da2ec5c7b811d","type":"switch","z":"a8e6987e60f0d9b1","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"cooling","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":890,"y":80,"wires":[["502a96574f59a0f0"],["59bbaf53a7757a95"]]},{"id":"0600f3f6c5dd4ec1","type":"switch","z":"a8e6987e60f0d9b1","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"cooling","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":890,"y":140,"wires":[["2f109b1afd8cef46"],["7e56a1d8b16465fb"]]},{"id":"4af04f5b6d8e1b26","type":"debug","z":"a8e6987e60f0d9b1","name":"Upstairs on indicated","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":620,"y":20,"wires":[]},{"id":"692e45d08216a4d3","type":"debug","z":"a8e6987e60f0d9b1","name":"Upstairs off indicated","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":620,"y":240,"wires":[]},{"id":"502a96574f59a0f0","type":"debug","z":"a8e6987e60f0d9b1","name":"Downstairs on (when Upstairs on)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1220,"y":60,"wires":[]},{"id":"59bbaf53a7757a95","type":"debug","z":"a8e6987e60f0d9b1","name":"Downstairs off (when upstairs on)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1220,"y":100,"wires":[]},{"id":"2f109b1afd8cef46","type":"debug","z":"a8e6987e60f0d9b1","name":"Downstairs on (when Upstairs off)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1220,"y":140,"wires":[]},{"id":"7e56a1d8b16465fb","type":"debug","z":"a8e6987e60f0d9b1","name":"Downstairs off (when upstairs off)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1220,"y":180,"wires":[]},{"id":"c51d38339c64c7c7","type":"subflow","name":"Subflow 6","info":"","in":[{"x":40,"y":160,"wires":[{"id":"49c63435c5b13e78"}]}],"out":[{"x":680,"y":80,"wires":[{"id":"44eb78d8c040adb5","port":0}]},{"x":680,"y":80,"wires":[{"id":"44eb78d8c040adb5","port":1}]},{"x":680,"y":240,"wires":[{"id":"0de37c8770e49835","port":0}]},{"x":680,"y":240,"wires":[{"id":"0de37c8770e49835","port":1}]}]},{"id":"49c63435c5b13e78","type":"change","z":"c51d38339c64c7c7","name":"Upstairs SP","rules":[{"t":"set","p":"payload","pt":"msg","to":"Upstairs_SP","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":190,"y":160,"wires":[["b3c7b08dd019d626"]]},{"id":"b3c7b08dd019d626","type":"switch","z":"c51d38339c64c7c7","name":"","property":"payload","propertyType":"msg","rules":[{"t":"lte","v":"75.0","vt":"num"},{"t":"gt","v":"75.0","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":330,"y":160,"wires":[["0bc06ab2f127ce68"],["ad82477ff8c114ae"]]},{"id":"0bc06ab2f127ce68","type":"change","z":"c51d38339c64c7c7","name":"Downstairs SP","rules":[{"t":"set","p":"payload","pt":"msg","to":"Downstairs_SP","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":380,"y":80,"wires":[["44eb78d8c040adb5"]]},{"id":"ad82477ff8c114ae","type":"change","z":"c51d38339c64c7c7","name":"Downstairs SP","rules":[{"t":"set","p":"payload","pt":"msg","to":"Downstairs_SP","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":380,"y":240,"wires":[["0de37c8770e49835"]]},{"id":"44eb78d8c040adb5","type":"switch","z":"c51d38339c64c7c7","name":"","property":"payload","propertyType":"msg","rules":[{"t":"lte","v":"75.0","vt":"num"},{"t":"gt","v":"75.0","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":80,"wires":[[],[]]},{"id":"0de37c8770e49835","type":"switch","z":"c51d38339c64c7c7","name":"","property":"payload","propertyType":"msg","rules":[{"t":"lte","v":"75.0","vt":"num"},{"t":"gt","v":"75.0","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":240,"wires":[[],[]]},{"id":"2c29ba9c617d20a5","type":"tab","label":"Heat Pump Switch Control","disabled":false,"info":"","env":[]},{"id":"22f1ee23a157eb92","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Net Power Production","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.grid_export","state_type":"num","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":180,"y":360,"wires":[["61ad75c805a65727"]]},{"id":"61ad75c805a65727","type":"function","z":"2c29ba9c617d20a5","name":"Average Last 5 Readings","func":"let values = context.get(\"values\") || [];\n\nvalues.push(msg.payload);\n\nif (values.length > 5) {\n    values.shift();\n}\n\nlet sum = values.reduce((acc, curr) => acc + curr, 0);\nlet avg = sum / values.length;\n\ncontext.set(\"values\", values);\n\nmsg.payload = avg;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":210,"y":240,"wires":[["e51b9e29fd504fcc","0b50f5ece69eddf8"]]},{"id":"9d480c95dbd7d080","type":"debug","z":"2c29ba9c617d20a5","name":"Avg_Net_Power","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":380,"y":160,"wires":[]},{"id":"e51b9e29fd504fcc","type":"change","z":"2c29ba9c617d20a5","name":"Set Global var","rules":[{"t":"set","p":"Avg_Net_Power","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":200,"y":160,"wires":[["9d480c95dbd7d080"]]},{"id":"a0d7ced3a3422ee9","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Upstairs Thermostat","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"climate.upstairs_2","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":300,"y":440,"wires":[["85d11aa01bf528c9","2261f510fc3d308e"]]},{"id":"566c827b3db5d018","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Downstairs Thermostat","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"climate.downstairs_3","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":290,"y":580,"wires":[["9ad981d54fe56d52","3503a81d90a82170"]]},{"id":"9ad981d54fe56d52","type":"change","z":"2c29ba9c617d20a5","name":"Downstairs SP","rules":[{"t":"set","p":"Downstairs_SP","pt":"global","to":"data.attributes.temperature","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"Downstairs_SP","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":540,"wires":[[]]},{"id":"85d11aa01bf528c9","type":"change","z":"2c29ba9c617d20a5","name":"Upstairs SP","rules":[{"t":"set","p":"Upstairs_SP","pt":"global","to":"data.attributes.temperature","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"Upstairs_SP","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":400,"wires":[[]]},{"id":"fd3c17071f287c2e","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"Avg_Net_Power","propertyType":"global","rules":[{"t":"gte","v":"4200","vt":"str"},{"t":"btwn","v":"1000","vt":"num","v2":"4200","v2t":"num"},{"t":"btwn","v":"1","vt":"num","v2":"1000","v2t":"num"},{"t":"lte","v":"1","vt":"num"}],"checkall":"false","repair":false,"outputs":4,"x":710,"y":240,"wires":[["8acd95e8c1e71433"],["74c399d4a4e3d6f3"],["355b6c8888271f7c"],["b5cbb02b6fbc5338"]]},{"id":"8acd95e8c1e71433","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.downstairs_ac_switch","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":680,"y":100,"wires":[["7def42454fc74d14"]]},{"id":"7def42454fc74d14","type":"debug","z":"2c29ba9c617d20a5","name":"Turn Both ON","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":840,"y":100,"wires":[]},{"id":"355b6c8888271f7c","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":990,"y":340,"wires":[]},{"id":"65c15703725b50e6","type":"debug","z":"2c29ba9c617d20a5","name":"Leave Both ON 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1330,"y":20,"wires":[]},{"id":"6e1ba578343538b1","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.downstairs_ac_switch","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1160,"y":20,"wires":[["65c15703725b50e6"]]},{"id":"ea9200101714bd0d","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"1600","vt":"str"},{"t":"lt","v":"1600","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1370,"y":200,"wires":[["a37ee96d98d36c96"],["0c7c392a49746204"]]},{"id":"a39066b187e3fac0","type":"debug","z":"2c29ba9c617d20a5","name":"Leave Upstaris OFF 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1980,"y":220,"wires":[]},{"id":"4e5a7af12709a0fd","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"2000","vt":"str"},{"t":"lt","v":"2000","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":1390,"y":100,"wires":[["071e3996aa243a5c"],["48bd626aab1225f3"]]},{"id":"071e3996aa243a5c","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1570,"y":60,"wires":[["01d216239bf0cb49"]]},{"id":"a6774881f123b7e9","type":"debug","z":"2c29ba9c617d20a5","name":"Leave Upstairs ON 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1980,"y":120,"wires":[]},{"id":"9e0878971e6bae93","type":"debug","z":"2c29ba9c617d20a5","name":"Downstairs (both) ON 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1970,"y":60,"wires":[]},{"id":"d9e9e18df92d2f3a","type":"debug","z":"2c29ba9c617d20a5","name":"Upstairs (both) ON 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1740,"y":180,"wires":[]},{"id":"691ae91051ed72d6","type":"change","z":"2c29ba9c617d20a5","name":"Avg Net Power","rules":[{"t":"set","p":"payload","pt":"msg","to":"Avg_Net_Power","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":1220,"y":200,"wires":[["ea9200101714bd0d"]]},{"id":"b31d9832cf480553","type":"change","z":"2c29ba9c617d20a5","name":"Avg Net Power","rules":[{"t":"set","p":"payload","pt":"msg","to":"Avg_Net_Power","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":1240,"y":100,"wires":[["4e5a7af12709a0fd"]]},{"id":"13e95fe4dd288fc1","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1590,"y":280,"wires":[["d9c024b468254015"]]},{"id":"f84454f6749ecf02","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1580,"y":320,"wires":[["5c35b91d7844278a"]]},{"id":"cf9d42a62a8209c6","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"3100","vt":"str"},{"t":"btwn","v":"1650","vt":"num","v2":"3100","v2t":"num"},{"t":"lt","v":"1650","vt":"num"}],"checkall":"true","repair":false,"outputs":3,"x":1390,"y":300,"wires":[["13e95fe4dd288fc1"],["f84454f6749ecf02"],["81da7da2fe074563"]]},{"id":"fbca3f4b52eb5f10","type":"debug","z":"2c29ba9c617d20a5","name":"Downstairs ON 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1990,"y":280,"wires":[]},{"id":"48632030c817c6a1","type":"debug","z":"2c29ba9c617d20a5","name":"Upstairs ON 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1980,"y":320,"wires":[]},{"id":"8a69ccbd437b9d90","type":"change","z":"2c29ba9c617d20a5","name":"Avg Net Power","rules":[{"t":"set","p":"payload","pt":"msg","to":"Avg_Net_Power","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":1220,"y":300,"wires":[["cf9d42a62a8209c6"]]},{"id":"7f9e1cf59728308b","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing (both off) 9","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1160,"y":860,"wires":[]},{"id":"6ba90db2a08f9343","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1480,"y":440,"wires":[["3f2d597056358ade"]]},{"id":"7fef0a14ccbdf74f","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both AC Units OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1470,"y":380,"wires":[["1264ce4a29e712b0"]]},{"id":"1264ce4a29e712b0","type":"debug","z":"2c29ba9c617d20a5","name":"Both OFF 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1690,"y":380,"wires":[]},{"id":"7bf581b202a40bb8","type":"debug","z":"2c29ba9c617d20a5","name":"Downstairs OFF 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1890,"y":440,"wires":[]},{"id":"44c2deb6dda0eb08","type":"debug","z":"2c29ba9c617d20a5","name":"Upstairs OFF 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1960,"y":500,"wires":[]},{"id":"2be285145ba12967","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac_switch"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1530,"y":500,"wires":[["4ceadd8f67081671"]]},{"id":"f0d030d404740919","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"4500","vt":"str"},{"t":"btwn","v":"3500","vt":"num","v2":"4500","v2t":"num"},{"t":"btwn","v":"demand_limit","vt":"global","v2":"3500","v2t":"num"},{"t":"lte","v":"demand_limit","vt":"global"}],"checkall":"true","repair":false,"outputs":4,"x":1250,"y":440,"wires":[["7fef0a14ccbdf74f"],["6ba90db2a08f9343"],["2be285145ba12967"],["1fa7d6c7eb10cc8a"]]},{"id":"dfb7c9b25bf4a3c4","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing (both on) 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1500,"y":560,"wires":[]},{"id":"e8c602b4718e40df","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Net Power Import","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.grid_import","state_type":"num","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":1050,"y":440,"wires":[["f0d030d404740919"]]},{"id":"65c0de97787a29c1","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Net Power Import","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.grid_import","state_type":"num","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":1070,"y":760,"wires":[["8a354a3078acd45c"]]},{"id":"1c96af46192f7518","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Net Power Import","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.grid_import","state_type":"num","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":1090,"y":680,"wires":[["945fb22e09973617"]]},{"id":"945fb22e09973617","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"demand_limit","vt":"global"},{"t":"lt","v":"demand_limit","vt":"global"}],"checkall":"true","repair":false,"outputs":2,"x":1270,"y":680,"wires":[["c7b939ad3362e161"],["8bbfbd9a88fb9b7e"]]},{"id":"c7b939ad3362e161","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac_switch"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1090,"y":620,"wires":[["2adbce5bc007ef85"]]},{"id":"be8bbb4264a6dd6a","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing (Upstairs on) 7","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1870,"y":680,"wires":[]},{"id":"95a628eacad485a3","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing (Downstairs on) 8","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1840,"y":800,"wires":[]},{"id":"37bb734d6fc40d50","type":"debug","z":"2c29ba9c617d20a5","name":"Upstairs OFF 7","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1500,"y":620,"wires":[]},{"id":"01d216239bf0cb49","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1760,"y":60,"wires":[["9e0878971e6bae93"]]},{"id":"48bd626aab1225f3","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1560,"y":120,"wires":[["9af1b64691a53dd4"]]},{"id":"9af1b64691a53dd4","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1760,"y":120,"wires":[["a6774881f123b7e9"]]},{"id":"0c7c392a49746204","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac_switch"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1570,"y":220,"wires":[["208ee7f495d9991e"]]},{"id":"208ee7f495d9991e","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1770,"y":220,"wires":[["a39066b187e3fac0"]]},{"id":"d9c024b468254015","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac_switch"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1790,"y":280,"wires":[["fbca3f4b52eb5f10"]]},{"id":"5c35b91d7844278a","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1780,"y":320,"wires":[["48632030c817c6a1"]]},{"id":"3f2d597056358ade","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1680,"y":440,"wires":[["7bf581b202a40bb8"]]},{"id":"4ceadd8f67081671","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1750,"y":500,"wires":[["44c2deb6dda0eb08"]]},{"id":"a37ee96d98d36c96","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.downstairs_ac_switch","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1540,"y":180,"wires":[["d9e9e18df92d2f3a"]]},{"id":"2adbce5bc007ef85","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":
["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1290,"y":620,"wires":[["37bb734d6fc40d50"]]},{"id":"8bbfbd9a88fb9b7e","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1440,"y":680,"wires":[["ea0323494992ddde"]]},{"id":"ea0323494992ddde","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1640,"y":680,"wires":[["be8bbb4264a6dd6a"]]},{"id":"8a354a3078acd45c","type":"switch","z":"2c29ba9c617d20a5","name":"Power","property":"payload","propertyType":"msg","rules":[{"t":"gte","v":"demand_limit","vt":"global"},{"t":"lt","v":"demand_limit","vt":"global"}],"checkall":"true","repair":false,"outputs":2,"x":1250,"y":760,"wires":[["fa55d538da2edc42"],["62b9ac1c4936d6a7"]]},{"id":"fa55d538da2edc42","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both AC Units OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1430,"y":740,"wires":[["23d4a79f74811771"]]},{"id":"62b9ac1c4936d6a7","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Downstairs AC ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1410,"y":800,"wires":[["38cd841d87749c5b"]]},{"id":"38cd841d87749c5b","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Upstairs AC OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.upstairs_ac_switch"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1610,"y":800,"wires":[["95a628eacad485a3"]]},{"id":"9265ac10fb3d8ecf","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both AC Units OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":950,"y":860,"wires":[["7f9e1cf59728308b"]]},{"id":"3eb4b81076e4b50b","type":"subflow:c51d38339c64c7c7","z":"2c29ba9c617d20a5","name":"HP states","x":1480,"y":1000,"wires":[[],[],[],[]]},{"id":"1fa7d6c7eb10cc8a","type":"api-call-service","z":"2c29ba9c617d20a5","name":"Both ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.downstairs_ac_switch","switch.upstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1320,"y":560,"wires":[["dfb7c9b25bf4a3c4"]]},{"id":"23d4a79f74811771","type":"debug","z":"2c29ba9c617d20a5","name":"Both OFF 7","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1630,"y":740,"wires":[]},{"id":"9e472044423f83d5","type":"api-current-state","z":"2c29ba9c617d20a5","name":"Demand Limit (W)","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_number.demand_limit_setpoint","state_type":"num","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":190,"y":680,"wires":[["3e571b961c5013b9"]]},{"id":"3e571b961c5013b9","type":"change","z":"2c29ba9c617d20a5","name":"demand_limit","rules":[{"t":"set","p":"demand_limit","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":680,"wires":[[]]},{"id":"81da7da2fe074563","type":"debug","z":"2c29ba9c617d20a5","name":"Do nothing 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1230,"y":360,"wires":[]},{"id":"8d93f980e80bd255","type":"inject","z":"2c29ba9c617d20a5","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"30","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":90,"y":440,"wires":[["a0d7ced3a3422ee9","566c827b3db5d018","9e472044423f83d5","22f1ee23a157eb92"]]},{"id":"0b50f5ece69eddf8","type":"delay","z":"2c29ba9c617d20a5","name":"","pauseType":"rate","timeout":"6","timeoutUnits":"minutes","rate":"1","nbRateUnits":"6","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":500,"y":260,"wires":[["fd3c17071f287c2e"]]},{"id":"2261f510fc3d308e","type":"change","z":"2c29ba9c617d20a5","name":"Upstairs HVAC Mode","rules":[{"t":"set","p":"Upstairs_HVAC_Action","pt":"global","to":"data.attributes.hvac_action","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"data.attributes.hvac_action","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":480,"wires":[[]]},{"id":"3503a81d90a82170","type":"change","z":"2c29ba9c617d20a5","name":"Downstairs HVAC Mode","rules":[{"t":"set","p":"Downstairs_HVAC_Action","pt":"global","to":"data.attributes.hvac_action","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"data.attributes.hvac_action","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":620,"wires":[[]]},{"id":"74c399d4a4e3d6f3","type":"subflow:a8e6987e60f0d9b1","z":"2c29ba9c617d20a5","name":"HVAC Modes Up/Down","x":970,"y":200,"wires":[["6e1ba578343538b1"],["b31d9832cf480553"],["691ae91051ed72d6"],["8a69ccbd437b9d90"]]},{"id":"b5cbb02b6fbc5338","type":"subflow:a8e6987e60f0d9b1","z":"2c29ba9c617d20a5","name":"HVAC Modes Up/Down","x":790,"y":460,"wires":[["e8c602b4718e40df"],["1c96af46192f7518"],["65c0de97787a29c1"],["9265ac10fb3d8ecf"]]},{"id":"95cc2380.4ef81","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

Note that I am still using the virtual switches created in Hubitat and shared with HA. But all automations now run in HA. I’ll provide more details below.

I’ll include other automations below. Here are a few elements that are used.

Demand Limit Setpoint - this is an input number helper. I’ve put a Mushroom Number Card on my Overview Dashboard that allows setting this value with a slider. I’m currently using a value of 3000 kW to avoid complaints from my family.

It’s Summer - an input Boolean. I set this using a Dashboard switch.

It’s Hot - A binary sensor that looks at current outdoor temperature (I have a sensor) and determines whether the temperature is over a threshold, which is currently set to 85 F.

Workday Sensor - Another Boolean that determines whether today is a non-holiday weekday. See Workday Sensor Integration.

Here is the primary Heat Pump Control automation that runs during the Peak Electric Rate time period.

My previous automation in Hubitat triggered every 6 minutes, but switch states could change every 30 seconds. This new automation triggers with a change in switch states, so to limit how often it triggers I added a delay node to my NR flow. I still use a rolling average for Net Power prior to the delay that updates every 30 s. Messages are released to the rest of the NR flow every 6 min using the delay node.

alias: Heat Pump Control Summer
description: Use Heat Pumps with excess Solar
trigger:
  - platform: state
    entity_id:
      - switch.upstairs_ac
    from: "off"
    to: "on"
    id: Upstairs ON
  - platform: state
    entity_id:
      - switch.upstairs_ac
    from: "on"
    to: "off"
    id: Upstairs OFF
  - platform: state
    entity_id:
      - switch.hubitat_vdownstairs_ac
    from: "off"
    to: "on"
    id: Downstairs ON
  - platform: state
    entity_id:
      - switch.hubitat_vdownstairs_ac
    from: "on"
    to: "off"
    id: Downstairs OFF
condition:
  - condition: state
    entity_id: input_boolean.it_s_summer
    state: "on"
  - condition: state
    entity_id: binary_sensor.summer_peak_electric_rate
    state: "on"
  - condition: state
    entity_id: binary_sensor.workday_sensor
    state: "on"
  - condition: time
    after: "14:00:00"
    before: "18:15:00"
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - Upstairs ON
        sequence:
          - metadata: {}
            data:
              temperature: 68
              hvac_mode: cool
            target:
              entity_id: climate.upstairs
            action: climate.set_temperature
          - if:
              - condition: state
                entity_id: switch.hubitat_vdownstairs_ac
                state: "on"
            then:
              - data:
                  temperature: 68
                  hvac_mode: cool
                target:
                  entity_id: climate.downstairs_3
                action: climate.set_temperature
            else:
              - target:
                  entity_id: climate.downstairs_3
                data:
                  temperature: 86
                  hvac_mode: cool
                action: climate.set_temperature
      - conditions:
          - condition: trigger
            id:
              - Upstairs OFF
        sequence:
          - metadata: {}
            data:
              temperature: 86
              hvac_mode: cool
            target:
              entity_id: climate.upstairs_2
            action: climate.set_temperature
          - if:
              - condition: state
                entity_id: switch.hubitat_vdownstairs_ac
                state: "on"
            then:
              - data:
                  temperature: 68
                  hvac_mode: cool
                target:
                  entity_id: climate.downstairs_3
                action: climate.set_temperature
            else:
              - target:
                  entity_id: climate.downstairs_3
                data:
                  temperature: 86
                  hvac_mode: cool
                action: climate.set_temperature
      - conditions:
          - condition: trigger
            id:
              - Downstairs ON
        sequence:
          - metadata: {}
            data:
              temperature: 68
              hvac_mode: cool
            target:
              entity_id: climate.downstairs_3
            action: climate.set_temperature
          - if:
              - condition: state
                entity_id: switch.upstairs_ac
                state: "on"
            then:
              - target:
                  entity_id: climate.upstairs_2
                data:
                  temperature: 68
                  hvac_mode: cool
                action: climate.set_temperature
            else:
              - target:
                  entity_id: climate.upstairs_2
                data:
                  temperature: 86
                  hvac_mode: cool
                action: climate.set_temperature
      - conditions:
          - condition: trigger
            id:
              - Downstairs OFF
        sequence:
          - metadata: {}
            data:
              temperature: 86
              hvac_mode: cool
            target:
              entity_id: climate.downstairs_3
            action: climate.set_temperature
          - if:
              - condition: state
                entity_id: switch.upstairs_ac
                state: "on"
            then:
              - target:
                  entity_id: climate.upstairs_2
                data:
                  hvac_mode: cool
                  temperature: 68
                action: climate.set_temperature
            else:
              - data:
                  temperature: 86
                  hvac_mode: cool
                target:
                  entity_id: climate.upstairs_2
                action: climate.set_temperature
mode: single

Here is the “Supercool” Automation that is run to cool the home prior to the Peak rate period. In this climate, it’s vital to pre-cool the home before it gets too hot.

Previously I was using the temperature forecast-high to determine the cooling setpoints, but with the changes to Weather Entities in HA I’ve struggled to regain that capability. So, setpoints are hard-coded.

alias: Summer Supercool
description: Supercool in the summer
trigger:
  - platform: time
    at: "06:01:00"
    id: Start Supercool
  - platform: time
    at: "13:59:00"
    id: End Supercool
  - platform: time
    at: "09:01:00"
    id: Continue Supercool
condition:
  - condition: state
    entity_id: input_boolean.it_s_summer
    state: "on"
  - condition: state
    entity_id: binary_sensor.it_s_hot
    state: "on"
  - condition: state
    entity_id: binary_sensor.workday_sensor
    state: "on"
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - Start Supercool
        sequence:
          - target:
              entity_id:
                - climate.downstairs_3
                - climate.upstairs_2
                - climate.supercool_setpoint
            data:
              hvac_mode: cool
              temperature: 75
            action: climate.set_temperature
          - condition: trigger
            id:
              - End Supercool
          - metadata: {}
            data:
              hvac_mode: cool
              temperature: 86
            target:
              entity_id:
                - climate.downstairs_3
                - climate.upstairs_2
                - climate.supercool_setpoint
            action: climate.set_temperature
      - conditions:
          - condition: trigger
            id:
              - End Supercool
        sequence:
          - target:
              entity_id:
                - climate.downstairs_3
                - climate.upstairs_2
            data:
              temperature: 86
              hvac_mode: cool
            action: climate.set_temperature
      - conditions:
          - condition: trigger
            id:
              - Continue Supercool
        sequence:
          - target:
              entity_id:
                - climate.downstairs_3
                - climate.upstairs_2
                - climate.supercool_setpoint
            data:
              temperature: 71
              hvac_mode: cool
            action: climate.set_temperature
mode: single

And, finally, here are other short automations that are used to address other issues. Two of these could be incorporated into other automations, but I found it easier to have a few short automations than, say, one very complex one. The switch logic alone is complicated enough by itself.

alias: AC switches off at 1:59 PM
description: Setting up for Summer AC control automation
trigger:
  - platform: time
    at: "13:59:00"
condition:
  - condition: state
    entity_id: input_boolean.it_s_summer
    state: "on"
action:
  - target:
      entity_id:
        - switch.hubitat_vdownstairs_ac
        - switch.upstairs_ac
    data: {}
    action: switch.turn_off
mode: single
alias: Summer turn off AC at 6:30 PM
description: ""
trigger:
  - platform: time
    at: "18:30:00"
condition:
  - condition: state
    entity_id: input_boolean.it_s_summer
    state: "on"
  - condition: state
    entity_id: binary_sensor.workday_sensor
    state: "on"
action:
  - metadata: {}
    data:
      temperature: 87
      hvac_mode: "off"
    target:
      entity_id:
        - climate.downstairs_3
        - climate.upstairs_2
    action: climate.set_temperature
mode: single

One more that is new - this helps with downstairs temperature in the evening after the sun goes down but while the demand rates are still in effect. Average demand over each 30 min period is controlled indirectly by simply limiting the duration of the Heat Pump cycles (one “cool” cycle each 1/2 hour). My utility measures average demand once every 1/2-hour during peak periods.

I’m getting fewer complaints about high indoor temperatures in the evening. But there is no direct connection to the “Demand Limit” in the primary automation, other than manually restricting on-cycle time to match expectations. (I could fix this if I knew how to integrate power use over 1/2-hour intervals…)

alias: Evening cool downstairs for heatwave
description: Enable during heatwave
trigger:
  - platform: time
    at: "18:38:00"
    id: 6:40 turn on
  - platform: time
    at: "18:50:00"
    id: 6:50 turn off
  - platform: time
    at: "19:05:00"
    id: 7:10 turn on
  - platform: time
    at: "19:20:00"
    id: 7:20 turn off
  - platform: time
    at: "19:38:00"
    id: 7:40 turn on
  - platform: time
    at: "19:50:00"
    id: 7:50 turn off
condition:
  - condition: state
    entity_id: binary_sensor.workday_sensor
    state: "on"
  - condition: state
    entity_id: input_boolean.it_s_summer
    state: "on"
  - condition: state
    entity_id: binary_sensor.it_s_hot
    state: "on"
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - 6:40 turn on
              - 7:10 turn on
              - 7:40 turn on
        sequence:
          - metadata: {}
            data:
              temperature: 75
              hvac_mode: cool
            target:
              entity_id: climate.downstairs_3
            action: climate.set_temperature
      - conditions:
          - condition: trigger
            id:
              - 6:50 turn off
              - 7:20 turn off
              - 7:50 turn off
        sequence:
          - target:
              entity_id:
                - climate.downstairs_3
            data:
              hvac_mode: "off"
            action: climate.set_hvac_mode
mode: single

This is awesome! Thanks for sharing. Trying to maximize my solar with SRP high rates so thank you for sharing what you came up with.

1 Like

Looking through your code, I had some similar things I have done to your original script. I am already seeing how your script kept the house cooler for the same price I was doing before. I do calculate the cost in HA and had some scripts before but I think your is outperforming my original formula. As for the weather, I recommend you look at pirateweather. Here is my template sensor that would get you your forecast. I have this number recalculating every 30 min during supercool time.

    - name: Supercool Set Temperature
      unit_of_measurement: '°F'
      device_class: temperature
      state: "{{ (74 - (states('sensor.pirateweather_daytime_high_temperature_0d') | round(0) - 94) / 4) | round(0) }}"
1 Like

Thanks @jlkweb12

I’ll look at pirateweather. That one is new to me.

I would be particularly interested in finding a better way to automate “Evening Cool Downstairs.” Maybe something like starting a timer once power use crosses a threshold. Any insights would be appreciated. :grinning:

I would setup a time pattern for x amount of minutes then add a condition last time the automation ran. Not sure if that helps.

Something like this

{{ now() - state_attr('automation.thermostat_sleep', 'last_triggered') > timedelta(minutes=6) }}
platform: time_pattern
minutes: /6
1 Like

@jlkweb12

Wow, PirateWeather is awesome! Just implemented it and added your template sensor.

Very cool! :slightly_smiling_face:

Will think a bit more about the Evening automation.

@jlkweb12

Here is my new Evening Cool flow in NR. I’ve reset the main automation to end at 18:00, which is when this starts.

[{"id":"30a2cf5c9fe2c3d5","type":"tab","label":"Evening Cool Summer","disabled":false,"info":"","env":[]},{"id":"b427a21ffe208968","type":"inject","z":"30a2cf5c9fe2c3d5","name":"Trigger ","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"*/1 18-19 * * 1,2,3,4,5","once":false,"onceDelay":0.1,"topic":"","payload":"object","payloadType":"date","x":160,"y":80,"wires":[["f14a8adbdf28ea64"]]},{"id":"6281ebd1f6aab4af","type":"api-call-service","z":"30a2cf5c9fe2c3d5","name":"Downstairs AC Switch ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1190,"y":280,"wires":[[]]},{"id":"689fd87b34273160","type":"api-call-service","z":"30a2cf5c9fe2c3d5","name":"Downstairs AC Switch OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.hubitat_vdownstairs_ac"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1060,"y":380,"wires":[[]]},{"id":"f14a8adbdf28ea64","type":"api-current-state","z":"30a2cf5c9fe2c3d5","name":"Is it Summer?","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.it_s_summer","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":360,"y":80,"wires":[["142cc85826b5593c"]]},{"id":"142cc85826b5593c","type":"switch","z":"30a2cf5c9fe2c3d5","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"neq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":510,"y":80,"wires":[["648e9d880ca2c443"],[]]},{"id":"648e9d880ca2c443","type":"api-current-state","z":"30a2cf5c9fe2c3d5","name":"Is it Hot?","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"binary_sensor.it_s_hot","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":660,"y":80,"wires":[["7b138e03501da62c"]]},{"id":"7b138e03501da62c","type":"switch","z":"30a2cf5c9fe2c3d5","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"neq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":790,"y":80,"wires":[["047692e81d8df0c0"],[]]},{"id":"047692e81d8df0c0","type":"api-current-state","z":"30a2cf5c9fe2c3d5","name":"Workday?","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"binary_sensor.workday_sensor","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":160,"y":220,"wires":[["23d4fbb422889ba4"]]},{"id":"23d4fbb422889ba4","type":"switch","z":"30a2cf5c9fe2c3d5","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"neq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":310,"y":220,"wires":[["5c4c39a0ea2b758e"],["5c4c39a0ea2b758e"]]},{"id":"e6715b6d4aa5b0f8","type":"api-call-service","z":"30a2cf5c9fe2c3d5","name":"Downstairs to 75 F","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"climate","service":"set_temperature","areaId":["hallway"],"deviceId":[],"entityId":["climate.downstairs_3"],"data":"{\"temperature\": 75}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":890,"y":280,"wires":[["6281ebd1f6aab4af"]]},{"id":"20c7de4f8e02e68f","type":"api-call-service","z":"30a2cf5c9fe2c3d5","name":"Downstairs HVAC_mode ON","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"climate","service":"set_hvac_mode","areaId":[],"deviceId":[],"entityId":["climate.downstairs_3"],"data":"{\"hvac_mode\": \"cool\"}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":980,"y":160,"wires":[["e6715b6d4aa5b0f8"]]},{"id":"c52e77a5439ce200","type":"api-call-service","z":"30a2cf5c9fe2c3d5","name":"Downstairs HVAC_mode OFF","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"climate","service":"set_hvac_mode","areaId":[],"deviceId":[],"entityId":["climate.downstairs_3"],"data":"{\"hvac_mode\": \"off\"}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":750,"y":380,"wires":[["689fd87b34273160"]]},{"id":"5eb66b22.1a4de4","type":"watt2kwh","z":"30a2cf5c9fe2c3d5","format":"wh","maximum":"5","maximumunit":"mins","name":"Convert to watt-hr","x":530,"y":520,"wires":[["92e84adc.45c5e8"]]},{"id":"92e84adc.45c5e8","type":"function","z":"30a2cf5c9fe2c3d5","name":"Accumulate wh","func":"var inputVal = msg.payload;\nif (inputVal == \"reset\"){\n flow.set(\"energyVal\",0); \n } else {\nvar savedVal = flow.get('energyVal')||0;\nsavedVal += inputVal;\nflow.set(\"energyVal\",savedVal);\nmsg.payload = savedVal;\nreturn msg;\n}","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":740,"y":520,"wires":[["dc9cac5d8ad751b4"]]},{"id":"486cc458.d7051c","type":"debug","z":"30a2cf5c9fe2c3d5","name":"Accumulated AVG demand","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1200,"y":440,"wires":[]},{"id":"6a75c8e5.1ee598","type":"inject","z":"30a2cf5c9fe2c3d5","name":"reset","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"*/30 0-23 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"reset","payloadType":"str","x":590,"y":600,"wires":[["92e84adc.45c5e8"]]},{"id":"fac869903fc66c37","type":"inject","z":"30a2cf5c9fe2c3d5","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"30","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":520,"wires":[["eb35cb98d1554e2d"]]},{"id":"eb35cb98d1554e2d","type":"api-current-state","z":"30a2cf5c9fe2c3d5","name":"Net Power Import","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.grid_import","state_type":"num","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":310,"y":520,"wires":[["5eb66b22.1a4de4"]]},{"id":"f3e7e9447566c911","type":"change","z":"30a2cf5c9fe2c3d5","name":"","rules":[{"t":"set","p":"Avg_Demand_30m","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1100,"y":600,"wires":[["7660bd2dbdc7354a"]]},{"id":"dc9cac5d8ad751b4","type":"function","z":"30a2cf5c9fe2c3d5","name":"30-min avg watt accum","func":"// Take msg.payload (a number) from the input\nlet inputNumber = msg.payload;\n\n// Divide the input number by 0.5\nlet outputNumber = inputNumber / 0.5;\n\n// Set this value to msg.payload on the output\nmsg.payload = outputNumber;\n\n// Return the modified message object\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":950,"y":520,"wires":[["486cc458.d7051c","f3e7e9447566c911"]]},{"id":"5c4c39a0ea2b758e","type":"switch","z":"30a2cf5c9fe2c3d5","name":"Demand below limit?","property":"Avg_Demand_30m","propertyType":"global","rules":[{"t":"lt","v":"demand_limit","vt":"global"},{"t":"gte","v":"demand_limit","vt":"global"}],"checkall":"true","repair":false,"outputs":2,"x":500,"y":220,"wires":[["1d4e8c319aefd4ca"],["c52e77a5439ce200"]]},{"id":"1d4e8c319aefd4ca","type":"delay","z":"30a2cf5c9fe2c3d5","name":"","pauseType":"rate","timeout":"6","timeoutUnits":"minutes","rate":"1","nbRateUnits":"6","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":740,"y":180,"wires":[["20c7de4f8e02e68f"]]},{"id":"7660bd2dbdc7354a","type":"api-call-service","z":"30a2cf5c9fe2c3d5","name":"Set Avg Demand Helper","server":"95cc2380.4ef81","version":5,"debugenabled":false,"domain":"input_number","service":"set_value","areaId":[],"deviceId":[],"entityId":["input_number.accumulated_demand"],"data":"{ \"value\": payload }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1070,"y":660,"wires":[["424146385edc23ed"]]},{"id":"424146385edc23ed","type":"api-current-state","z":"30a2cf5c9fe2c3d5","name":"","server":"95cc2380.4ef81","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_number.accumulated_demand","state_type":"num","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":990,"y":740,"wires":[["b1d03794d4d279b9"]]},{"id":"b1d03794d4d279b9","type":"debug","z":"30a2cf5c9fe2c3d5","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1280,"y":740,"wires":[]},{"id":"95cc2380.4ef81","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

The section at the bottom of the flow takes the value of imported grid power, converts to energy using a custom node watt2kwh (units watt-hr) and accumulates those values until it is reset (every 30 min). To convert to accumulating demand the watt-hr energy is divided by 0.5 hr to give a value in watts. SRP calculates demand every 30 minutes as you know.
Then a Global Variable Avg_Demand_30min is set. This is used in the upper section of the flow.

This Accumulated demand may look something like this:

Technically, this Accumulated Demand is simply Grid Energy used during each 30min window, then doubled. The value at the end of each 30-min window should be SRP’s average demand for that period. Fortunately, SRP does not use instantaneous demand!!! Using an average gives a bit of flexibility for automation.

The upper section of the flow triggers initially at 18:00 and continues until 20:00. A few conditions are checked, then the Global Variable Avg_Demand_30 min is compared to the Demand Limit that was defined previously. The Downstairs Heat Pump is turned on to 75F when below the limit, or is tuned off when above the limit.

Once the limit is reached and the HP is turned off, it will not turn on again until the accumulator resets (each 30 min) or until the automation stops.

I need to do more testing, but this should be close to the final automation. I hope! :sweat_smile:

Edit: With this automation, accumulated demand (energy use) continues to increase once the demand limit is reached. It takes about a min for the thermostat to be triggered off, and then it takes a moment for the fan to ramp down. Also, there is other energy use in the home (lights, network, TV etc.).

Last night, with a demand limit of 3000 watts, the home reached a total of 3462 watts accumulated demand at 18:30. SRP reported demand for that period to be 3.5 kW, so the calculation appears to be correct.

I will be reducing the value of the demand helper to obtain lower peak demand going forward.