Advanced Thermostat Adjustment

The basic thermostat wiki page describes a simple way to change your thermostat settings at various times of day. This will help to reduce your energy consumption considerably. However, as you add more control over your home, you may find that the sheer number of time/date actions grows quickly. Consider this: if you want behavior that's different when you're on vacation or when you have the windows open in your house, you now potentially have to add complex conditionals and perhaps many more trigger or time/date events to compensate. Now, add another thermostat to the mix (many houses have 2 HVAC units) and the complexity really goes up.

In this article we'll talk about a script that can be used in conjunction with some variables, triggers, and action groups that makes creating complex thermostat schedules easier. You can even use this technique for controlling other environmental aspects of your house as well. The How-to level of difficulty is Moderate and because it uses AppleScript requires Indigo Pro.

Let's start with a scenario that I have in my home. I have two HVAC units: one that controls the master bedroom/bath, the media room, and part of the open kitchen/living room/game room, and the other controls the other part of the open area, the utility room, my office, and a spare bedroom/bath. I work at home in my home office, so spend most of the week day there, but we spend most of the weekend days in the other side of the house if we're at home. We spend most of our evening time in the media room.

After thinking a lot about what parts of the house are lived in at various times, I put together a spreadsheet that let me visualize what I thought would be the best set points for my HVAC system to keep the various sides of my house comfortable when occupied:

So, as you can see from the charts above, I have 4 different times of day when I'd like my set points to be changed during the week, and on the weekend during the day I need some different set points since we live in a different part of the house on the weekends during the day. Not shown in these tables are a couple of other scenarios: 1) when I'm on vacation, 2) when I have the windows open, and 3) when we have company. For each of these situations, I want to have a separate set of set points that don't change based on time of day - in other words, they stay the same regardless of time of day or weekend/weekday differences.

Now, I could do this with a LOT of time/date actions, some variables, some complex conditionals, etc. Managing all those parts may or may not be too much trouble. Instead, I've come up with a better way of managing it. Using a single variable as a starting point, houseMode (you can make it anything you want), I can have a script (don't worry, you don't have to change it at all if you don't want to) that will help me manage everything I need.

So, to summarize my houseMode states, I have: home, vacation, open, and company. Let's take the easiest scenarios first: vacation, company, and open. These scenarios are simple because I only need a single change to the two HVAC system set points and they're good until houseMode changes to another value.

At this point, you're going to need to make a choice - there are two different version of the script, one in Python and one in AppleScript. If you're running Indigo 4, skip down to the AppleScript Version section. Otherwise, just continue reading.

The first thing you need to do is download the script that's necessary to run this solution. Follow the directions on the library page to complete the installation.

Next, let's create a trigger that fires whenever houseMode changes:

  1. Make sure TRIGGERS or one of it's subfolders is selected in the outline view.
  2. Click on the New… button above the trigger action list
  3. Name the trigger something like “houseMode change”
  4. Set the Type: to Variable Changed
  5. Select the Variable: that you want to use
  6. Select the changes radio button
  7. Skip the Conditions tab since we always want this trigger to fire, and select the Actions tab
  8. Select Server Actions→Script and File Actions→Execute Script from the Type: popup
  9. In the text area below the Embedded radio button, paste in the following:
from variable_watcher import processVariable
processVariable("houseMode")
  1. Click the OK button

OK, so now, when the variable you specified changes, the processing method is going to fire. Right now, however, it's not going to do much - the script is going to look at the value of the variable and try and find a variable or action group with the same name (or ID) to execute. If it doesn't find one, it's gonna put a message in your error log. So, let's say that you change the value of “houseMode” to “vacation” - when you do, you'll get a message in the log that looks something like this:

Variable Watcher action group execution error

When you see that, you know you need to do something. In this case, we're gonna create an action group called “vacation” - using the exact same spelling (and capitalization) as the value we enter in the houseMode variable.

  1. Make sure ACTION GROUPS or one of it's subfolders is selected in the outline view.
  2. Click on the New… button above the action group list
  3. Name the action group “vacation” - this is important - it has to be exactly the same as the value you'll enter in “houseMode”
  4. Select Control Thermostat from the Type: popup
  5. Select Set Cool Setpoint from the Action: menu
  6. Select one of your thermostats
  7. Enter the set point value in the To: field
  8. Click the Add New button to add another action step
  9. repeat steps 4-8 for the heat set point, and then set the mode for the thermostat to Auto Heat/Cool
  10. if you have more than one thermostat, repeat steps 4-8 for the other thermostat as well
  11. Click the OK button

Now, you have your “vacation” action group. Whenever you change the “houseMode” variable to vacation, this action group will be executed and your thermostat(s) will be set to save you $$ while you're gone! As you might guess, you can repeat this process for “company” and “open”. Another thing you might notice here: the action steps don't necessarily have to only contain thermostat commands. For instance, you might also want to enable/disable other triggers or time/date actions while you're on vacation for instance.

OK, so, now you've taken care of the easy ones - where it just needs to execute once. Now we get to the more interesting houseMode: “home”. When houseMode is home, we want to adjust set points 4 times a day according to our chart above. So how the heck do we do that? Well, the script that looks for action groups that have the same name as the houseMode variable value also does another trick: before it looks for an action group by that name, it looks for another variable by that name. So, when houseMode is set to “home”, it first looks for a variable named “home” - if it doesn't find one, then it looks for an action group named “home”.

Why is this useful? Because the script is recursive. This means that it calls itself. If the script finds a variable called “home”, then it calls itself with the value of the “home” variable. This allows us to create a variable called “home” which will have the following options: morning, work day, weekend day, evening, night. Then, we can create action groups with those names, and the right action group will be executed when the “home” variable is set to one of those values.

Next, create the “home” variable:

  1. In the Variable List window, click on the New… button
  2. Name the variable “home”
  3. Set it's value to “morning” (or any of the above options)

Now, create a trigger that will execute whenever the “home” variable changes:

  1. Make sure TRIGGERS or one of it's subfolders is selected in the outline view.
  2. Click on the New… button above the trigger action list
  3. Name the trigger something like “home change”
  4. Set the Type: to Variable Changed
  5. Select the Variable: that you want to use
  6. Select the changes radio button
  7. Select the Conditions tab. While this step isn't necessary, it will keep the script from running when it doesn't need to.
  8. Select If variable and select houseMode from the popup
  9. Select equals and enter “home” - so, to recap, this says that trigger will run only if houseMode is equal to “home”
  10. Select the Actions tab
  11. Select Server Actions→Script and File Actions→Execute Script from the Type: popup
  12. In the text area below the Embedded radio button, paste in the following:
from variable_watcher import processVariable
processVariable("home")
  1. Click the OK button

Now, when houseMode is equal to “home” and the “home” variable is changed, it will execute an action group whose name is the value of the “home” variable. Set the variable to “work day” and the “work day” action group will get executed. The last step is to create the following action groups: morning, work day, weekend day, evening, night. I won't go through each of those, but the steps are similar as the steps above to create the “vacation” action group.

The final thing is to actually change these variables automatically. For houseMode (home, open, company, vacation), you'll probably want to change those manually, although you could certainly create a button on a keypad somewhere that set the value - so, for instance, you could have a button on a KeypadLinc or remote that toggles houseMode between vacation and home.

The more interesting changes are the daily changes to the “home” variable. I have 5 Schedules: one each for morning, work day, weekend day, evening, night. Very simple and straight-forward. Here's the Schedule for work day (since it's more complicated than morning, evening, and night since they all run every day):

  1. Make sure Schedules or one of it's subfolders is selected in the outline view.
  2. Click on the New… button above the trigger action list
  3. Name the trigger something like “set work day”
  4. Set the Time: section so that the first radio button is selected and the time is set to 8:30am
  5. Set the Date: section so that “Days of week” is selected and M, Tu, W, Th, F are highlighted (dark)
  6. Skip the Conditions tab and select the Actions tab
  7. Select Modify Variable from the Type: popup
  8. Select home from the Variable: popup
  9. Click on the Set to: radio button and enter “work day” into the text box next to it
  10. Click the OK button

Repeat this for the other potential variable values as appropriate. There you go! You now have a pretty manageable way of fine-tuning your thermostat settings based on some pretty complex logic - all without having to write a line of AppleScript. What you have done, in fact, is create a logic tree. We can represent the tree like this:

houseMode  -  vacation    -  execute "vacation" action group
           -  company     -  execute "company" action group
           -  open        -  execute "open" action group
           -  home        -  morning     -  execute "morning" action group
                          -  work day    -  execute "work day" action group
                          -  weekend day -  execute "weekend day" action group
                          -  evening     -  execute "evening" action group
                          -  night       -  execute "night" action group

To add a new value to houseMode, you'll first need to decide if it has sub-states. If not, then just create an action group with the same value as the new value that you'll be entering in “houseMode”. If you're adding a new daytime breakdown to the “home” variable, the same applies.

If you want to add a new houseMode value that has sub-states, just follow the pattern for “home” from above, You'll obviously need to figure out what things cause the variables to change, and that will be very specific to your problem domain. But I think it will end up more manageable in the end!

I've created a forum thread for discussions, questions, comments, etc. about this solution.

AppleScript Version

If you're using Indigo 4 (note, AppleScript will be deprecated in Indigo 7.2 so we highly recommend you use the Python version above), continue reading. The first thing you need to do is download the AppleScript that's necessary to run this solution. It may already be in the scripts folder (it's called “ThermostatProcessor.scpt”). If you need the script, you can download it here. You may need to unzip if your browser doesn't do it for you. I like to keep all my Indigo scripts in the Scripts directory in the Indigo preferences, but you can put it anywhere you like.

If you are OK with Indigo using “houseMode” as the variable for this solution, you don't need to do anything else. If you want to use a different variable, just edit the script and change the “theHouseModeVar” property to the name of the variable you want to use. The script will create the variable if it doesn't exist the first time it's run, but you'll probably want to go ahead and create the variable now and give it a reasonable value.

Next, let's create a trigger that fires whenever houseMode changes:

  1. Make sure TRIGGERS or one of it's subfolders is selected in the outline view.
  2. Click on the New… button above the trigger action list
  3. Name the trigger something like “houseMode change”
  4. Set the Type: to Variable Changed
  5. Select the Variable: that you want to use
  6. Select the changes radio button
  7. Skip the Conditions tab since we always want this trigger to fire, and select the Actions tab
  8. Select Execute AppleScript from the Type: popup
  9. Click on the Choose… button and select the “Thermostat Processor.scpt” file as described above.
  10. Click the OK button

OK, so now, when “houseMode” (or whatever variable name you're using) changes, the processing script is going to fire. Right now, however, it's not going to do much - the script is going to look at the value of the variable and try and find an action group with the same name to execute. If it doesn't find one, it's gonna put a message in your error log. So, let's say that you change the value of “houseMode” to “vacation” - when you do, you'll get a message in the log that looks like this:

ThermoProcessor Unknown variable value: vacation

When you see that, you know you need to do something. In this case, we're gonna create an action group called “vacation” - using the exact same spelling (and capitalization) as the value we enter in the houseMode variable.

  1. Make sure ACTION GROUPS or one of it's subfolders is selected in the outline view.
  2. Click on the New… button above the action group list
  3. Name the action group “vacation” - this is important - it has to be exactly the same as the value you'll enter in “houseMode”
  4. Select Control Thermostat from the Type: popup
  5. Select Set Cool Setpoint from the Action: menu
  6. Select one of your thermostats
  7. Enter the set point value in the To: field
  8. Click the Add New button to add another action step
  9. repeat steps 4-8 for the heat set point, and then set the mode for the thermostat to Auto Heat/Cool
  10. if you have more than one thermostat, repeat steps 4-8 for the other thermostat as well
  11. Click the OK button

Now, you have your “vacation” action group. Whenever you change the “houseMode” variable to vacation, this action group will be executed and your thermostat(s) will be set to save you $$ while you're gone! As you might guess, you can repeat this process for “company” and “open”. Another thing you might notice here: the action steps don't necessarily have to only contain thermostat commands. For instance, you might also want to enable/disable other triggers or time/date actions while you're on vacation for instance.

OK, so, now you've taken care of the easy ones - where it just needs to executes once. Now we get to the more interesting houseMode: “home”. When houseMode is home, we want to adjust set points 4 times a day according to our chart above. So how the heck do we do that? Well, the script that looks for action steps that have the same name as the houseMode variable value also does another trick: before it looks for an action group by that name, it looks for another variable by that name. So, when houseMode is set to “home”, it first looks for a variable named “home” - if it doesn't find one, then it looks for an action group named “home”.

Why is this useful? Because the script is recursive. This means that it calls itself. If the script finds a variable called “home”, then it calls itself with the value of the “home” variable. This allows us to create a variable called “home” which will have the following options: morning, work day, weekend day, evening, night. Then, we can create action groups with those names, and the right action group will be executed when the “home” variable is set to one of those values.

Next, create the “home” variable:

  1. In the Variable List window, click on the New… button
  2. Name the variable “home”
  3. Set it's value to “morning” (or any of the above options)

Now, create a trigger that will execute whenever the “home” variable changes:

  1. Make sure TRIGGERS or one of it's subfolders is selected in the outline view.
  2. Click on the New… button above the trigger action list
  3. Name the trigger something like “home change”
  4. Set the Type: to Variable Changed
  5. Select the Variable: that you want to use
  6. Select the changes radio button
  7. Select the Conditions tab. While this step isn't necessary, it will keep the script from running when it doesn't need to.
  8. Select If variable and select houseMode from the popup
  9. Select equals and enter “home” - so, to recap, this says that trigger will run only if houseMode is equal to “home”
  10. Select the Actions tab
  11. Select Execute AppleScript from the Type: popup
  12. Click on the Choose… button and select the “Thermostat Processor.scpt” file as described above.
  13. Click the OK button

Now, when houseMode is equal to “home” and the “home” variable is changed, it will execute an action group whose name is the value of the “home” variable. Set the variable to “work day” and the “work day” action group will get executed. The last step is to create the following action groups: morning, work day, weekend day, evening, night. I won't go through each of those, but the steps are similar as the steps above to create the “vacation” action group.

The final thing is to actually change these variables automatically. For houseMode (home, open, company, vacation), you'll probably want to change those manually, although you could certainly create a button on a KPL somewhere that set the value - so, for instance, you could have a button on a KPL or remote that toggles houseMode between vacation and home.

The more interesting changes are the daily changes to the “home” variable. I have 5 time/date actions: one each for morning, work day, weekend day, evening, night. Very simple and straight-forward. Here's the t/d action for work day (since it's more complicated than morning, evening, and night since they all run every day):

  1. Make sure TIME/DATE ACTIONS or one of it's subfolders is selected in the outline view.
  2. Click on the New… button above the trigger action list
  3. Name the trigger something like “set work day”
  4. Set the Time: section so that the first radio button is selected and the time is set to 8:30am
  5. Set the Date: section so that “Days of week” is selected and M, Tu, W, Th, F are highlighted (dark)
  6. Skip the Conditions tab and select the Actions tab
  7. Select Modify Variable from the Type: popup
  8. Select home from the Variable: popup
  9. Click on the Set to: radio button and enter “work day” into the text box next to it
  10. Click the OK button

Repeat this for the other potential variable values as appropriate. There you go! You now have a pretty manageable way of fine-tuning your thermostat settings based on some pretty complex logic - all without having to write a line of AppleScript. What you have done, in fact, is create a logic tree. We can represent the tree like this:

houseMode  -  vacation    -  execute "vacation" action group
           -  company     -  execute "company" action group
           -  open        -  execute "open" action group
           -  home        -  morning     -  execute "morning" action group
                          -  work day    -  execute "work day" action group
                          -  weekend day -  execute "weekend day" action group
                          -  evening     -  execute "evening" action group
                          -  night       -  execute "night" action group

To add a new value to houseMode, you'll first need to decide if it has sub-states. If not, then just create an action group with the same value as the new value that you'll be entering in “houseMode”. If you're adding a new daytime breakdown to the “home” variable, the same applies.

If you want to add a new houseMode value that has sub-states, just follow the pattern for “home” from above, You'll obviously need to figure out what things cause the variables to change, and that will be very specific to your problem domain. But I think it will end up more manageable in the end!

I've created a forum thread for discussions, questions, comments, etc. about this solution.

advanced_thermo.txt · Last modified: 2017/09/27 03:18 by jay
 

© Perceptive Automation, LLC. · Privacy