Skip to content
This repository has been archived by the owner on Dec 12, 2021. It is now read-only.

Commit

Permalink
Added occupancy checks, as well as weather checks to automatically se…
Browse files Browse the repository at this point in the history
…t hvac mode to heat or cool
  • Loading branch information
billykwooten committed Jul 15, 2017
1 parent dcd7bd5 commit bd42497
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 18 deletions.
3 changes: 0 additions & 3 deletions ecobee/data/ecobee_authentication.json
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
{
"apikey": ""
}
3 changes: 3 additions & 0 deletions ecobee/data/ecobee_secret.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"apikey": ""
}
19 changes: 16 additions & 3 deletions ecobee/ecobee.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import requests
import logging

logging.basicConfig(filename='log/hydrogen.log', level=logging.DEBUG)
logging.basicConfig(filename='log/hydrogen.log', level=logging.INFO)

with open('ecobee/data/ecobee_secret.json') as data_file:
data = json.load(data_file)
Expand Down Expand Up @@ -62,6 +62,7 @@ def get_thermostats():
'"includeSensors":"true",'
'"includeProgram":"true",'
'"includeEquipmentStatus":"true",'
'"includeWeather":"true",'
'"includeEvents":"true",'
'"includeSettings":"true"}}')}
request = requests.get(url, headers=header, params=params)
Expand Down Expand Up @@ -110,7 +111,19 @@ def get_weather(index):
header = {'Content-Type': 'application/json;charset=UTF-8', 'Authorization': 'Bearer ' + accesstoken}
params = {'format': 'json'}
body = ('{"selection":{"selectionType":"thermostats","selectionMatch":'
'"' + thermostats[index]['identifier'] +
'"},"thermostat":{"weatherforecast":{"temperature":"}}}')
'"' + thermostats[index] +
'"},"thermostat":{"weather":{"forecast":"}}}')
request = requests.post(url, headers=header, params=params, data=body)
print request.json()


def get_remote_sensors(index):
''' Return remote sensors based on index '''
thermostats = get_thermostats()
return thermostats[index]['remoteSensors']


def get_current_climate_setting(index):
''' Return sleep, away, or home '''
thermostats = get_thermostats()
return thermostats[index]['program']['currentClimateRef']
1 change: 1 addition & 0 deletions hydrogen/cache/occupancy.cache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
6 changes: 3 additions & 3 deletions hydrogen/hydrogen.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ def check_gmail():
service = discovery.build('gmail', 'v1', http=http)
today = str(datetime.date.today())
yesterday = str(datetime.date.fromordinal(datetime.date.today().toordinal() - 1))
todayhours = int(datetime.datetime.now().strftime("%H")) #Hour of the day in 24 hour format
todayhours = int(datetime.datetime.now().strftime("%H")) # Hour of the day in 24 hour format

if todayhours not in range(14, 19): #Check if it is peak hours for CobbEMC
if todayhours not in range(14, 19): # Check if it is peak hours for CobbEMC
return 2

#Check Gmail messages with label 41(CobbEMC Peak Hours)
# Check Gmail messages with label 41(CobbEMC Peak Hours)
messages = service.users().messages().list(userId='me', labelIds='Label_41').execute().get('messages', [])
for message in messages:
tdata = service.users().messages().get(userId='me', id=message['id']).execute()
Expand Down
60 changes: 51 additions & 9 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,73 @@

from ecobee import ecobee
from hydrogen import hydrogen
from wunderground import wunderground

logging.basicConfig(filename='log/hydrogen.log', level=logging.DEBUG)
now = datetime.datetime.now()
logging.info("Hydrogen ran at " + str(now))

# Set your ecobee index list
thermostatlist = [0, 1]


def main():
now = datetime.datetime.now()
logging.info("Hydrogen ran at " + str(now))

""" Check for occupancy and act accordingly """
program = ecobee.get_current_climate_setting(1)
occupancy = ecobee.get_remote_sensors(0)[1]['capability'][2]['value'] # Check if someone is home via proximity
if program == "sleep":
logging.info("Ecobee is reporting sleep program, setting result to 2")
result = 2
elif program != "sleep":
occupancy = ecobee.get_remote_sensors(0)[1]['capability'][2]['value'] # Check if someone is home via proximity
if occupancy == "true":
with open('hydrogen/cache/occupancy.cache', 'w') as outfile:
outfile.write("0")
logging.info("Someone is home, setting result to 2")
result = 2
elif occupancy == "false":
with open('hydrogen/cache/occupancy.cache', 'r') as infile:
occupancyint = infile.read()
with open('hydrogen/cache/occupancy.cache', 'w') as outfile:
occupancyint += 1
outfile.write(occupancyint)
with open('hydrogen/cache/occupancy.cache', 'r') as infile:
occupancyint = infile.read()
if occupancyint >= 5:
logging.log("Looks like nobody is home, turning to off hvac mode to save power")
result = 4
elif occupancyint <= 4:
result = hydrogen.check_gmail()

""" Check for results of test and act accordingly """
""" Result of 1 means that the ecobees need to be turned off to avoid peak hours """
result = hydrogen.check_gmail()
if result == 1:
if result == 1: # Peak hours!
logging.info("Gmail check has come back with peak hours, setting ecobees to off hvac mode")
for i in thermostatlist:
requesthvacset = ecobee.set_hvac_mode(i, 'off')
if requesthvacset.status_code == requests.codes.ok:
logging.info("Successfully set thermostat index " + str(i) + " to off hvac mode")
elif result == 2:
logging.info("It's not peak hours right now, setting ecobees to cool")
elif result == 2: # Someone is home or asleep, and/or not peak hours
ctemp = wunderground.get_current_temperature()
if ctemp >= 66:
hvacmode = 'cool'
elif ctemp <= 65:
hvacmode = 'heat'

if occupancy == "false":
logging.info("It's not peak hours right now, setting ecobees to " + hvacmode)

for i in thermostatlist:
requesthvacset = ecobee.set_hvac_mode(i, 'cool')
requesthvacset = ecobee.set_hvac_mode(i, hvacmode)
if requesthvacset.status_code == requests.codes.ok:
logging.info("Successfully set thermostat index " + str(i) + " to cool hvac mode")
elif result == 0:
logging.info("Successfully set thermostat index " + str(i) + " to " + hvacmode + " hvac mode")
elif result == 4: # Nobody is home
for i in thermostatlist:
requesthvacset = ecobee.set_hvac_mode(i, 'off')
if requesthvacset.status_code == requests.codes.ok:
logging.info("Successfully set thermostat index " + str(i) + " to off hvac mode")
elif result == 0: # Not peak hours
logging.info("No Peak Hours have been set by CobbEMC, we're good!")
sys.exit(0)

Expand Down
3 changes: 3 additions & 0 deletions version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Current version 0.1

0.1 *) @Cryson, Initial version release
Empty file added wunderground/__init__.py
Empty file.
20 changes: 20 additions & 0 deletions wunderground/config/config.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# INI file for weather settings. Modify this file to change weather output
#
# Example INI file
#
# user_apiid: 83jd324asjc0f5a
# user_city: New_York
# user_state: NY
# cachefile: /opt/test/Scripts/weather.data
#

[weather_settings]
#APIID/Key from weatherunderground
user_apiid:

#City, e.g. New_York
user_city:

#State e.g. MN, FL, CA
user_state:
47 changes: 47 additions & 0 deletions wunderground/wunderground.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import json
import urllib2
import ConfigParser

Config = ConfigParser.ConfigParser()
Config.read('wunderground/config/config.ini')

user_apiid = Config.get('weather_settings', 'user_apiid')
user_city = Config.get('weather_settings', 'user_city')
user_state = Config.get('weather_settings', 'user_state')


def getWeatherCondition():
try:
url = "http://api.wunderground.com/api/"
url += "%s/conditions/q/%s/" % (user_apiid, user_state)
url += "%s.json" % user_city
req = urllib2.Request(url)
response = urllib2.urlopen(req)
jsondata = response.read()
return jsondata
except Exception as e:
print("Could not get weather data")
return e


def pull_weather_json():
weather = getWeatherCondition()
w = json.loads(weather)

# Grab Weather Data
currenttemp = float(w['current_observation']['temp_f'])
atmospressure = float(w['current_observation']['pressure_in'])
windspeed = float(w['current_observation']['wind_mph'])
humidity = w['current_observation']['relative_humidity']
humidity = humidity[:-1]
humidity = float(humidity)
feels_like = float(w['current_observation']['feelslike_f'])
dewpoint = float(w['current_observation']['dewpoint_f'])

return currenttemp


def get_current_temperature():
return pull_weather_json()


0 comments on commit bd42497

Please sign in to comment.