Skip to content

Instantly share code, notes, and snippets.

@fpgaminer
Created June 24, 2019 15:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fpgaminer/7840a6f2fb2d3a3be83625d7acfd12b3 to your computer and use it in GitHub Desktop.
Save fpgaminer/7840a6f2fb2d3a3be83625d7acfd12b3 to your computer and use it in GitHub Desktop.
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"
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