Skip to content

Commit 4cbe976

Browse files
authored
Merge pull request #631 from brentru/pyportal-hue
Add PyPortal Philips Hue Controller Code
2 parents bb2e6d1 + 60e6a80 commit 4cbe976

2 files changed

Lines changed: 1709 additions & 0 deletions

File tree

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
"""
2+
PyPortal Philips Hue Lighting Controller
3+
4+
Brent Rubell for Adafruit Industries, 2019
5+
"""
6+
import board
7+
import displayio
8+
from adafruit_bitmap_font import bitmap_font
9+
from adafruit_button import Button
10+
import adafruit_touchscreen
11+
from digitalio import DigitalInOut
12+
import busio
13+
import neopixel
14+
from adafruit_esp32spi import adafruit_esp32spi
15+
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
16+
17+
# Import Philips Hue Bridge
18+
from adafruit_hue import Bridge
19+
20+
# Get wifi details and more from a secrets.py file
21+
try:
22+
from secrets import secrets
23+
except ImportError:
24+
print("WiFi secrets are kept in secrets.py, please add them there!")
25+
raise
26+
27+
# ESP32 SPI
28+
esp32_cs = DigitalInOut(board.ESP_CS)
29+
esp32_ready = DigitalInOut(board.ESP_BUSY)
30+
esp32_reset = DigitalInOut(board.ESP_RESET)
31+
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
32+
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
33+
status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2)
34+
wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets, status_light)
35+
36+
# Attempt to load bridge username and IP address from secrets.py
37+
try:
38+
username = secrets['hue_username']
39+
bridge_ip = secrets['bridge_ip']
40+
my_bridge = Bridge(wifi, bridge_ip, username)
41+
except:
42+
# Perform first-time bridge setup
43+
my_bridge = Bridge(wifi)
44+
print('Finding bridge address...')
45+
ip = my_bridge.discover_bridge()
46+
print('Attempting to register username, press the link button on your Hue Bridge now!')
47+
username = my_bridge.register_username()
48+
print('ADD THESE VALUES TO SECRETS.PY: \
49+
\n\t"bridge_ip":"{0}", \
50+
\n\t"hue_username":"{1}"'.format(ip, username))
51+
raise
52+
53+
# These pins are used as both analog and digital! XL, XR and YU must be analog
54+
# and digital capable. YD just need to be digital
55+
ts = adafruit_touchscreen.Touchscreen(board.TOUCH_XL, board.TOUCH_XR,
56+
board.TOUCH_YD, board.TOUCH_YU,
57+
calibration=((5200, 59000), (5800, 57000)),
58+
size=(320, 240))
59+
60+
61+
# Make the display context
62+
button_group = displayio.Group(max_size=20)
63+
board.DISPLAY.show(button_group)
64+
# preload the font
65+
print('loading font...')
66+
font = bitmap_font.load_font("/fonts/Arial-12.bdf")
67+
glyphs = b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,.: '
68+
font.load_glyphs(glyphs)
69+
# button properties
70+
BUTTON_WIDTH = 60
71+
BUTTON_HEIGHT = 60
72+
buttons = []
73+
74+
print('loading colors...')
75+
# color conversions (RGB to Philips Hue-compatible HSB)
76+
red = my_bridge.rgb_to_hsb([255, 0, 0])
77+
white = my_bridge.rgb_to_hsb([255, 255, 255])
78+
orange = my_bridge.rgb_to_hsb([255, 165, 0])
79+
yellow = my_bridge.rgb_to_hsb([255, 255, 0])
80+
green = my_bridge.rgb_to_hsb([0, 255, 0])
81+
blue = my_bridge.rgb_to_hsb([0, 0, 255])
82+
purple = my_bridge.rgb_to_hsb([128, 0, 128])
83+
pink = my_bridge.rgb_to_hsb([255, 192, 203])
84+
85+
hue_hsb = {'red': red, 'white': white, 'orange': orange,
86+
'yellow': yellow, 'green': green, 'blue': blue,
87+
'purple': purple, 'pink': pink}
88+
89+
print('loading buttons...')
90+
# button fill colors
91+
button_colors = {'red':0xFF0000, 'white':0xFFFFFF,
92+
'orange':0xFF9900, 'yellow':0xFFFF00,
93+
'green':0x00FF00, 'blue':0x0000FF,
94+
'purple':0x9900FF, 'pink': 0xFF00FF}
95+
# list of color buttons and their properties
96+
color_btn = [
97+
{'name':'red', 'pos':(15, 80), 'color':button_colors['red']},
98+
{'name':'white', 'pos':(85, 80), 'color':button_colors['white']},
99+
{'name':'orange', 'pos':(155, 80), 'color':button_colors['orange']},
100+
{'name':'yellow', 'pos':(225, 80), 'color':button_colors['yellow']},
101+
{'name':'pink', 'pos':(15, 155), 'color':button_colors['pink']},
102+
{'name':'green', 'pos':(85, 155), 'color':button_colors['green']},
103+
{'name':'blue', 'pos':(155, 155), 'color':button_colors['blue']},
104+
{'name':'purple', 'pos':(225, 155), 'color':button_colors['purple']}
105+
]
106+
107+
# generate color buttons from color_btn list
108+
for i in color_btn:
109+
button = Button(x=i['pos'][0], y=i['pos'][1],
110+
width=BUTTON_WIDTH, height=BUTTON_HEIGHT, name=i['name'],
111+
fill_color=i['color'], style=Button.ROUNDRECT)
112+
buttons.append(button)
113+
114+
# light property buttons and their properties
115+
prop_btn = [
116+
{'name':'onoff', 'pos':(15, 15), 'label':'on/off'},
117+
{'name':'up', 'pos':(75, 15), 'label':'+'},
118+
{'name':'down', 'pos':(135, 15), 'label':'-'},
119+
{'name':'room', 'pos':(195, 15), 'label':'room'},
120+
{'name':'lamp', 'pos':(255, 15), 'label':'lamp'}
121+
]
122+
123+
# generate property buttons from prop_btn list
124+
for i in prop_btn:
125+
button = Button(name=i['name'], x=i['pos'][0], y=i['pos'][1],
126+
width=55, height=40, label=i['label'],
127+
label_font=font, style=Button.SHADOWROUNDRECT)
128+
buttons.append(button)
129+
130+
# add buttons to the group
131+
for b in buttons:
132+
button_group.append(b.group)
133+
134+
# Hue Light/Group Identifiers
135+
hue_lights={'lamp': 1, 'livingroom': 2}
136+
hue_selector = hue_lights['lamp']
137+
138+
# Default to 25% brightness
139+
current_brightness = 25
140+
141+
while True:
142+
touch = ts.touch_point
143+
if touch:
144+
for i, button in enumerate(buttons):
145+
if button.contains(touch):
146+
button.selected = True
147+
if button.name == 'room':
148+
hue_selector = hue_lights['livingroom']
149+
print('Switching to ', hue_selector)
150+
elif button.name == 'lamp':
151+
hue_selector = hue_lights['lamp']
152+
print('Switching to ', hue_selector)
153+
elif button.name == 'onoff':
154+
print('Toggling {0}...'.format(hue_selector))
155+
my_bridge.toggle_light(int(hue_selector))
156+
elif button.name == 'up':
157+
current_brightness += 25
158+
print('Setting {0} brightness to {1}'.format(hue_selector, current_brightness))
159+
my_bridge.set_light(int(hue_selector), bri=current_brightness)
160+
elif button.name == 'down':
161+
current_brightness -= 25
162+
print('Setting {0} brightness to {1}'.format(hue_selector, current_brightness))
163+
my_bridge.set_light(int(hue_selector), bri=current_brightness)
164+
else:
165+
print('Setting {0} color to {1}'.format(hue_selector, button.name))
166+
my_bridge.set_light(light_id=int(hue_selector),
167+
hue=int(hue_hsb[button.name][0]),
168+
sat=int(hue_hsb[button.name][1]),
169+
bri=int(hue_hsb[button.name][2]))
170+
button.selected = False
171+
else:
172+
button.selected = False

0 commit comments

Comments
 (0)