-
-
Save fpgaminer/7840a6f2fb2d3a3be83625d7acfd12b3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import datetime | |
# (time, mired, brightness) | |
TIMES = [ | |
(datetime.time(hour=8, minute=0), 400, 254), | |
(datetime.time(hour=10, minute=0), 200, 254), | |
('PRESUNSET', 400, 254), | |
('SUNSET', 500, 254), | |
] | |
# Latitude and Longitude of where we are (used to calculate sunrise/sunset) | |
LATITUDE = XXX | |
LONGITUDE = XXX | |
# Fingerprint of the Hue hub's SSL certificate (allows us to pin the certificate and thus prevent MITM) | |
FINGERPRINT = "XXX" | |
# Our app's username on the Hue hub | |
APP_USERNAME = "XXX" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
from requests_toolbelt.adapters.fingerprint import FingerprintAdapter | |
import sys | |
from suntime import Sun | |
import datetime | |
import config | |
import time | |
def run(): | |
# Discover the Hue hub's local IP address | |
# Note that Hue doesn't recommend doing it this way; this is just easy and a hack. | |
try: | |
r = requests.get("https://discovery.meethue.com/") | |
ip_address = r.json()[0]["internalipaddress"] | |
except Exception as e: | |
print("WARNING: Unable to talk to discovery.meethue.com:") | |
print(e) | |
print("WARNING: Using default IP") | |
ip_address = "192.168.1.190" | |
while True: | |
update_scenes(ip_address) | |
time.sleep(15*60) | |
def update_scenes(ip_address): | |
# SSL certificate pinning by requiring the fingerprint to match | |
s = requests.Session() | |
s.mount(f'https://{ip_address}', FingerprintAdapter(config.FINGERPRINT)) | |
# Calculate settings for the current time of day | |
now = datetime.datetime.now().time() | |
desired_state = get_state_for_time(now) | |
# Find all Circadian scenes | |
r = s.get(f"https://{ip_address}/api/{config.APP_USERNAME}/scenes", verify=False) | |
circadian_scenes = r.json() | |
circadian_scenes = {k:v for (k,v) in circadian_scenes.items() if v['name'] == 'Circadian'} | |
# Update all Circadian scenes | |
for scene_id, scene in circadian_scenes.items(): | |
states = {} | |
for light in scene['lights']: | |
states[light] = {'ct': desired_state[1], 'on': True, 'bri': desired_state[2]} | |
r = s.put(f"https://{ip_address}/api/{config.APP_USERNAME}/scenes/{scene_id}", verify=False, json={"lightstates": states}) | |
print(r.json()) | |
def get_state_for_time(now): | |
sunset = Sun(config.LATITUDE, config.LONGITUDE).get_local_sunset_time() | |
sunset = datetime.time(hour=sunset.hour, minute=sunset.minute) | |
previous = config.TIMES[-1] | |
for t in config.TIMES: | |
if t[0] == 'PRESUNSET': | |
t_time = datetime.time(hour=(sunset.hour - 2), minute=sunset.minute) | |
elif t[0] == 'SUNSET': | |
t_time = sunset | |
else: | |
t_time = t[0] | |
if now > t_time: | |
previous = t | |
continue | |
break | |
return previous | |
if __name__ == '__main__': | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment