Updating the Vanity Code
So, my server had an uptime of 954 days before it rebooted and entered a read-only state. It’s code to run the Vanity was using Python 2.7. Well, an update to Python 3.9 was needed! This code was completely tested in PyCharm.
main.py
#!/usr/bin/python
# User Variables
import collections.abc
from datetime import datetime
import json
import logging
import os
from phue import Bridge
import pytz
import rgbxy
import sys
from time import sleep
def convert(data):
if isinstance(data, str):
return str(data)
elif isinstance(data, collections.abc.Mapping):
return dict(map(convert, data.items()))
elif isinstance(data, collections.abc.Iterable):
return type(data), (map(convert, data))
else:
return data
def recurse(d, keys=()):
if isinstance(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 = rgbxy.ColorHelper()
Converter = rgbxy.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"] is 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 = b.get_group(int(group), 'lights')
# print("Vanity lights are %s" % lights)
target = {}
for light in lights:
target.update({int(light): 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.get_rgb_from_xy_and_brightness(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'] is 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.get_distance_between_two_points(xyold,target[light]['state']['xynew']) < color \
or target[light]['state']['xynew'] == 0:
newxy = Converter.get_random_xy_color()
target[light]['state'].update({'xynew': XYPoint(newxy[0], newxy[1])})
if ColorHelper.get_distance_between_two_points(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.get_distance_between_two_points(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.get_distance_between_two_points(
target[light]['state']['xynew'],
target[lightCompare]['state']['xynew']),
target[light]['state']['xynew'],
target[lightCompare]['state']['xynew'], count))
newxy = Converter.get_random_xy_color()
target[light]['state']['xynew'] = XYPoint(newxy[0], newxy[1])
if ColorHelper.get_distance_between_two_points(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
{
"settings": {
"enabled": true,
"bridge": "192.168.42.7",
"day": "0900",
"night": "2200",
"color": "0.2",
"trans": "19",
"dimmer": "75",
"group": "Vanity",
"timezone": "US/Pacific"
},
"hub": {
"groupList": [
"Vanity",
"TV",
"Kitchen",
"Living Room",
"Bedroom"
]
}
}