On October of 2016 I went forth and created a unique light piece to go above my desk. It was my first Python project and was inspired by the combination of adding more smart lights to my home and to improve my programming knowledge.
I used a popular 3 square shelving unit off of the internet and used Philips Hue light strips to populate the lighting perimeter. I then cut slots into the shelving unit and used electrical tape to black out any portions of the lighting strips I didn’t want to show. I created code using several plugins to make it work using Python 2.7 at the time (I need to update it!)
#!/usr/bin/python
#User Variables
import collections
from datetime import datetime
import json
import logging
import os
from phue import Bridge
import pytz
import rgb_converter
import sys
from time import sleep
def convert(data):
if isinstance(data, basestring):
return str(data)
elif isinstance(data, collections.Mapping):
return dict(map(convert, data.iteritems()))
elif isinstance(data, collections.Iterable):
return type(data)(map(convert, data))
else:
return data
def recurse(d, keys=()):
if type(d)==type({}):
for k in d:
recurse(d[k])
else:
print d
# Represents a CIE 1931 XY coordinate pair.
XYPoint = collections.namedtuple('XYPoint', ['x', 'y'])
ColorHelper = rgb_converter.ColorHelper()
Converter = rgb_converter.Converter()
logging.basicConfig()
configLocal = os.path.dirname(os.path.realpath(sys.argv[0])) + "/config.json"
#Get Config
try:
with open(configLocal) as json_data:
config = json.load(json_data)
json_data.close()
#except IOError as e:
# print "I/O error({0}): {1}".format(e.errono, e.strerror)
#except ValueError:
# print "Could not convert data to an integer."
except:
print "Unexpected error:", sys.exc_info()[0]
print "Configuration file missing"
print "Maybe you didn't install me correctly?"
raise
day = int(config["settings"]["day"]) #bright time (24 hrs 0800)
night = int(config["settings"]["night"]) #dim time (24 hrs 2200)
color = float(config["settings"]["color"]) #color closeness (TBD)
trans = float(config["settings"]["trans"]) #transition time (sec)
groupName = str(config["settings"]["group"]) # Target Hue Group
dimmer = int(config["settings"]["dimmer"])#0-254 Brightness
timezone = config["settings"]["timezone"] #what timezone
bridge = str(config["settings"]["bridge"]) # IP of Bridge
if config["settings"]["enabled"] == False:
print "Disabled!"
exit()
# Ensure connection
b = Bridge(bridge)
b.connect()
#get transition time and light data
date_format='%H%M'
date = datetime.now(tz=pytz.utc)
date = date.astimezone(pytz.timezone(timezone))
sleepy = 0
print "Current time is:", date.strftime(date_format)
if int(date.strftime(date_format)) > day and int(date.strftime(date_format)) < night:
print "It is currently daytime"
sleepy = 0
if int(date.strftime(date_format)) > night or int(date.strftime(date_format)) < day:
print "It is currently nighttime"
sleepy = 1
group = b.get_group_id_by_name(groupName)
#print "Vanity group ID is %s" % group
lights = convert(b.get_group(int(group),'lights'))
# print "Vanity lights are %s" % lights
target = {}
for light in lights:
target.update({int(light):convert(b.get_light(int(light)))})
#print light name, brightness, color
print "Here are the current lights and their critical values:"
for light in target:
RGB = ColorHelper.getRGBFromXYAndBrightness(float(target[light]['state']['xy'][0]), \
float(target[light]['state']['xy'][1]),int(target[light]['state']['bri']))
print "-- Light #: %s -- Name: %s -- Brightness: %s -- XY Value: %s -- RGB Value: %s" % \
(light, target[light]['name'], target[light]['state']['bri'], target[light]['state']['xy'],RGB)
#set daylight
for light in target:
if int(target[light]['state']['on'] == False):
b.set_light(light, 'on', True)
if int(target[light]['state']['bri']) != 254 and sleepy == 0:
b.set_light(light, 'bri', 254)
print "set day"
if int(target[light]['state']['bri']) != dimmer and sleepy == 1:
b.set_light(light, 'bri', dimmer)
print "set night"
for light in target:
target[light]['state'].update({'xynew': XYPoint(0,0)})
xyold = XYPoint(target[light]['state']['xy'][0], target[light]['state']['xy'][1])
while True:
if ColorHelper.getDistanceBetweenTwoPoints(xyold,target[light]['state']['xynew']) < color \
or target[light]['state']['xynew'] == 0:
newxy = Converter.getCIEColor()
target[light]['state'].update({'xynew': XYPoint(newxy[0],newxy[1])})
if ColorHelper.getDistanceBetweenTwoPoints(xyold,target[light]['state']['xynew']) > color \
and target[light]['state']['xynew'] != 0:
break
print "precompare check"
for light in target:
for lightCompare in target:
if light == lightCompare:
continue
if ColorHelper.getDistanceBetweenTwoPoints(target[light]['state']['xynew'], \
target[lightCompare]['state']['xynew']) > color:
print "not similar"
continue
count = 0
while True:
print "%s -- %s vs %s -- similar, looking: %s" % (ColorHelper.getDistanceBetweenTwoPoints( \
target[light]['state']['xynew'], target[lightCompare]['state']['xynew']), \
target[light]['state']['xynew'], target[lightCompare]['state']['xynew'], count)
newxy = Converter.getCIEColor()
target[light]['state']['xynew'] = XYPoint(newxy[0], newxy[1])
if ColorHelper.getDistanceBetweenTwoPoints(target[light]['state']['xynew'], \
target[lightCompare]['state']['xynew']) > color:
print "Success!"
break
if count > 10:
break
count += 1
b.set_light(light, 'xy', target[light]['state']['xynew'],trans*10)
sleep(.2)
#print getattr(target, '18')
#get light colors
#get range
#apply