www.homeseer.com    
 

Go Back   HomeSeer Message Board > Developer Support > Scripts & Plug-Ins:Development and Libraries > Script & Plug-In Library

Script & Plug-In Library If you have a script for HomeSeer that you would like to share, please post it here. This forum is for scripts only, and no replies are allowed here. You may discuss these scripts in the Scripts Discussion forum.

Reply
 
Thread Tools Display Modes
  #1  
Old July 13th, 2018, 12:53 AM
ACiDGRiM ACiDGRiM is offline
Seer
 
Join Date: Jun 2018
Location: AZ
Posts: 15
[C#] Occupancy based multizone HVAC control

Hello,

I didn't quite want to spend $30+ on any of the plugins because none of them really seemed impressive, and I thought I could get the basic functionality myself along with a feature none of them provided. Below is a simple C# script I wrote that will take the value of several counters that expect a value of 0 or 1 which act as switches and performs some logic based on the occupancy status of the building or the floor.

My Condo has 3 stories and is controlled by 2 zone HVAC, and my electricity is tiered, so any use between 3-8pm is really expensive. I found myself wondering how much it was costing me to keep my living room at 80 degrees while I'm spending all day in my Office, and the Nest units I had frequently would be cooling my house down while I was out of town because the presence detection was broken with some update.

My Goal with this script is to combine my requirements of detecting if I'm home or not and setting the "Away" temperature, but also increasing the thermostat set points a few degrees up when no-one is in a particular zone.
All of the lifting for managing the scheduling, and changing devices is done by the HomeSeer engine to keep the script simple, so adding more rooms, floors, and schedule triggers is as easy as copy/paste.

I'll detail some examples of the room triggers and schedule triggers in the next post, but I'd imagine the test points could be re-worked to validate against device strings. I hate any GPS or 3rd party cloud services often used for arrival, so I'm working with motion detectors and Z-wave thermostats (alarm.com t2000 /Building36 T10)

Code:
using System;

public object Main(object[] Parms) {
    //Temp Schedule
    Double thermostatDay = hs.CounterValue("ThermostatDay");
    Double thermostatEvening = hs.CounterValue("ThermostatEvening");
    Double thermostatNight = hs.CounterValue("ThermostatNight");
    Double thermostatPeakDay = hs.CounterValue("ThermostatPeakDay");

    //Room Occupancy
    Double occupancyF1Hallway = hs.CounterValue("OccupancyF1Hallway");
    Double occupancyF1Garage = hs.CounterValue("OccupancyF1Garage");
    Double occupancyF1GuestRoom = hs.CounterValue("OccupancyF1GuestRoom");
    Double occupancyF2Atrium = hs.CounterValue("OccupancyF2Atrium");
    Double occupancyF3MasterRoom = hs.CounterValue("OccupancyF3MasterRoom");
    Double occupancyF3LeftRoom = hs.CounterValue("OccupancyF3LeftRoom");
    Double occupancyF3RightRoom = hs.CounterValue("OccupancyF3RightRoom");
    Double occupancyPingable = hs.CounterValue("OccupancyPing");

    //Floor Occupancy
    Boolean occupancyF1 = false;
    Boolean occupancyF2 = false;
    Boolean occupancyF3 = false;

    //hs.WriteLog("HVAC Script Debug", "occupancyF1Hallway " + occupancyF1Hallway);
    //hs.WriteLog("HVAC Script Debug", "occupancyF1Garage " + occupancyF1Garage);
    //hs.WriteLog("HVAC Script Debug", "occupancyF1GuestRoom " + occupancyF1GuestRoom);
    if ( occupancyF1Hallway == 1 || occupancyF1Garage == 1 || occupancyF1GuestRoom == 1 ) {
        occupancyF1 = true;
    } else {
        occupancyF1 = false;
    }
    //hs.WriteLog("HVAC Script Debug", "occupancyF1 " + occupancyF1);
    
    //hs.WriteLog("HVAC Script Debug", "occupancyF2Atrium " + occupancyF2Atrium);
    if ( occupancyF2Atrium == 1 ) {
        occupancyF2 = true;
    } else {
        occupancyF2 = false;
    }
    //hs.WriteLog("HVAC Script Debug", "occupancyF2 " + occupancyF2);


    //hs.WriteLog("HVAC Script Debug", "occupancyF3MasterRoom " + occupancyF3MasterRoom);
    //hs.WriteLog("HVAC Script Debug", "occupancyF3LeftBedroom " + occupancyF3LeftRoom);
    //hs.WriteLog("HVAC Script Debug", "occupancyF3RightBedroom " + occupancyF3RightRoom);
    if ( occupancyF3MasterRoom == 1 || occupancyF3LeftRoom == 1 || occupancyF3RightRoom == 1 ) {
        occupancyF3 = true;
    } else {
        occupancyF3 = false;
    }
    //hs.WriteLog("HVAC Script Debug", "occupancyF3 " + occupancyF3);

    
    //PingOccupancy
    Boolean occupancyPing = false;
    //hs.WriteLog("HVAC Script Debug", "occupancyPingable " + occupancyPingable);
    if ( occupancyPingable == 1 ) {
        occupancyPing = true;
    } else {
        occupancyPing = false;
    }
    //hs.WriteLog("HVAC Script Debug", "occupancyPing " + occupancyPing);

    //Building Occupancy    
    Boolean occupancyBuilding = false;
    if ( occupancyF1 || occupancyF2 || occupancyF3 || occupancyPing) {
        occupancyBuilding = true;
    } else if ( !occupancyF1 && !occupancyF2 && !occupancyF3 && !occupancyPing ) {
        occupancyBuilding = false;
    }
    //hs.WriteLog("HVAC Script Debug", "occupancyBuilding " + occupancyBuilding);

    //Away Schedule
    if ( !occupancyBuilding ) {
        hs.WriteLog("HVAC Script", "Trigger Away Temperature");
        hs.TriggerEvent("Thermostat Control AwayTemperature");
        return 0;
    }

    //Floor 1/2 Schedule
    if ( (occupancyF1 || occupancyF2) && occupancyBuilding ) {
        //hs.WriteLog("HVAC Script Debug", "F1_F2 occupied, Building occupied");
        if ( thermostatDay == 1 && thermostatPeakDay != 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F1/2 Day Temperature");
            hs.TriggerEvent("Thermostat Control F1_2-DayTemperature");
        } else if ( thermostatDay == 1 && thermostatPeakDay == 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F1/2 PeakDay Temperature");
            hs.TriggerEvent("Thermostat Control F1_2-PeakDayTemperature");
        } else if ( thermostatEvening == 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F1/2 Evening Temperature");
            hs.TriggerEvent("Thermostat Control F1_2-EveningTemperature");
        } else if  ( thermostatNight == 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F1/2 Night Temperature");
            hs.TriggerEvent("Thermostat Control F1_2-NightTemperature");
        } else {
            hs.WriteLog("HVAC Script", "Trigger F1/2 Failsafe Temperature");
            hs.TriggerEvent("Thermostat Control AwayTemperature");
        }
    } else if ( (!occupancyF1 && !occupancyF2) && occupancyBuilding ) {
        //hs.WriteLog("HVAC Script Debug", "F1_F2 unoccupied, Building occupied");
        if ( thermostatPeakDay != 1 && thermostatEvening != 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F1_2 Hold Temperature");
            hs.TriggerEvent("Thermostat Control F1_2-HoldTemperature");
        } else if ( thermostatEvening == 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F1_2 Evening Temperature");
            hs.TriggerEvent("Thermostat Control F1_2-EveningTemperature");
        } else {
            hs.WriteLog("HVAC Script", "Trigger F1_2 PeakDay Temperature");
            hs.TriggerEvent("Thermostat Control F1_2-PeakDayTemperature");
        }
    } else {
        hs.WriteLog("HVAC Script", "Trigger F1/2 Failsafe Temperature");
        hs.TriggerEvent("Thermostat Control AwayTemperature");
    }

    //Floor 3 Schedule
    if ( occupancyF3 && occupancyBuilding ) {
        //hs.WriteLog("HVAC Script Debug", "F3 occupied, Building occupied");
        if ( thermostatDay == 1 && thermostatPeakDay != 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F3 Day Temperature");
            hs.TriggerEvent("Thermostat Control F3-DayTemperature");
        } else if ( thermostatDay == 1 && thermostatPeakDay == 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F3 PeakDay Temperature");
            hs.TriggerEvent("Thermostat Control F3-PeakDayTemperature");
        } else if ( thermostatEvening == 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F3 Evening Temperature");
            hs.TriggerEvent("Thermostat Control F3-EveningTemperature");
        } else if  ( thermostatNight == 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F3 Night Temperature");
            hs.TriggerEvent("Thermostat Control F3-NightTemperature");
        } else {
            hs.WriteLog("HVAC Script", "Trigger F3 Failsafe Temperature");
            hs.TriggerEvent("Thermostat Control AwayTemperature");
        }
    } else if ( !occupancyF3 && occupancyBuilding ) {
        //hs.WriteLog("HVAC Script Debug", "F3 unoccupied, Building occupied");
        if ( thermostatPeakDay != 1 && thermostatEvening != 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F3 Hold Temperature");
            hs.TriggerEvent("Thermostat Control F3-HoldTemperature");
        } else if ( thermostatEvening == 1 ) {
            hs.WriteLog("HVAC Script", "Trigger F3 Evening Temperature");
            hs.TriggerEvent("Thermostat Control F3-EveningTemperature");
        } else {
            hs.WriteLog("HVAC Script", "Trigger F3 PeakDay Temperature");
            hs.TriggerEvent("Thermostat Control F3-PeakDayTemperature");
        }
    } else {
        hs.WriteLog("HVAC Script", "Trigger F3 Failsafe Temperature");
        hs.TriggerEvent("Thermostat Control AwayTemperature");
    }

    return 0;
}
The basic functionality:
  • Floor Boolean values are true if at least 1 room in each floor is occupied and false if all rooms are occupied
  • A building Boolean is true if at least one floor is true, and false if all rooms are false
  • I added a Ping occupancy into the building occupancy test as an example of testing if a device is online and on the network. This doesn't work well for Phones, as the wifi sleep prevents this from being reliable.
  • Several schedule conditions are considered depending if the zone is occupied, or the zone is unoccupied while another is occupied Failsafe sets the Away temperature to prevent any value combinations from accidentally cooling the house during peak hours.

I have my schedule broken into several time frames:
  • Day time, which is during standard rate hours, including all day weekends.
  • PeakDay, peak rate hours from 3p-8p. Typically I'm not home, but if I am I want a compromise between cost and comfort.
  • Evening, starts 1 hour from the end of the peak rate. This is when I'm typically coming home so another compromise
  • Night, when I'm usually getting ready for bed and want a cooler temperature
  • Hold, I've personally determined that allowing the temperature to rise 2 degrees if a zone should reduce costs without being self defeating
  • Away, I set the temperatures as high as possible without causing issues. I also set one zone a bit more reasonable for the cat.

Let me know what you think, I'll appreciate any feedback or criticism as this is my first attempt at c#, or any programming language.
My ADD has taken over so I won't be actively supporting this if there are bugs, I'm just hoping it helps someone and welcome any input to consider when I revisit this.

I have some other ideas for schedules to add to the logic such as an over-ride for when guests are visiting, but I'm probably going to make them suffer with the PeakDay schedule. >
Also, I would like to get some Z-Wave controlled Vents, like the discontinued EcoNet EV100, and further expand on the Hold temp/occupied temp concept by room. The EV200 is apparently going to be available in 2019, so if I can get my C#/VB.NET by then, I may make a plugin that opens and closes vents depending on room temperature.

The alarm.com thermostats I have are awesome, I highly recommend if you're familiar with reading the zwave alliance documentation on the parameters and are willing to take a bit of a risk (they're unsupported if you aren't a subscriber). They can be highly tuned via the parameters and work just fine with and without batteries.
Supposedly there's a parameter to control if either the onboard thermostat is used to monitor the temperature or if a remote device is used which is a static 0 value. I'm trying to identify if any of the undocumented parameters are linked to that device. I'll update this script if that turns out to be possible.

====

Since it appears i can't make a followup post, here's some info on how I setup my occupancy triggers, schedules, and thermostat events

Occupancy trigger:
One set of is created for each room. Some tuning on the end time is needed to keep the occupancy consistent. 30 minutes seems to be good for rooms, and 10 minutes is good for hallways and in this case, the garage.
I also link to lights and zwave outlets, but you know how to do that
I've also found that setting the motion sensors to use the most sensitive is needed.
The trigger will keep resetting the counter every-time motion is re-detected.
I've found that setting the "re-detect" time to the max of 60 seconds to save battery is sufficient in my case with the Zooz multi sensor



Schedule:
These are pretty simple and self explanatory. I found that the HomeSeer event engine is buggy when it comes to triggers and order, so the time must be before the day condition
I'd like to be able to use a csv to set schedules wider than 7 days, but for now this works well


Thermostat Events:
A separate Event is needed for each thermostat for each schedule time.
The Away event sets the away setpoints for both thermostats since they aren't independent in my case
Don't mind the heating setpoints, I'm not sure what they should be yet.
I have circulate tasks to start and stop the auto circulation around the peak times, these are specific to my thermostat models


Script Trigger:
I currently run the trigger every minute. Also eliminates the need to lock the thermostat because the temps will get enforced with the correct value every run. Some handling of temporary overrides could be in the future

Last edited by ACiDGRiM; July 13th, 2018 at 01:32 AM.
Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
HVAC Control mikaluch Thermostat / HVAC Discussion 0 April 25th, 2016 08:15 PM
Event Help - Occupancy based announcement kideon HomeSeer General Discussion Area 2 December 16th, 2014 12:12 AM
Occupancy Control kensmith HS2 / HSPRO 6 February 15th, 2011 04:44 AM
Occupancy based Announcements. travisdh Audio / Video and Infra-red (IR) Discussion 1 March 15th, 2010 02:22 AM
Control heating and cooling based on occupancy nk89 ZWave 6 September 24th, 2009 12:18 AM


All times are GMT -4. The time now is 11:30 AM.


Copyright HomeSeer Technologies, LLC