Skip to content

Commit 4168e1c

Browse files
committed
Create code.py
1 parent f49f34f commit 4168e1c

1 file changed

Lines changed: 242 additions & 0 deletions

File tree

  • Elgato_WiFi_Light_Controller
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import time
6+
import os
7+
import ipaddress
8+
import wifi
9+
import ssl
10+
import socketpool
11+
import board
12+
import digitalio
13+
import displayio
14+
import vectorio
15+
import adafruit_requests
16+
from adafruit_bitmap_font import bitmap_font
17+
from adafruit_display_text import bitmap_label
18+
import adafruit_imageload
19+
from adafruit_seesaw import seesaw, rotaryio, digitalio as seesaw_digitalio, neopixel
20+
from adafruit_display_shapes.circle import Circle
21+
from adafruit_ticks import ticks_ms, ticks_add, ticks_diff
22+
23+
num_lights = 1
24+
light = os.getenv('ELGATO_LIGHT')
25+
clock_clock = ticks_ms()
26+
clock_timer = 3 * 1000
27+
28+
i2c = board.I2C() # uses board.SCL and board.SDA
29+
seesaw = seesaw.Seesaw(i2c, addr=0x36)
30+
encoder = rotaryio.IncrementalEncoder(seesaw)
31+
seesaw.pin_mode(24, seesaw.INPUT_PULLUP)
32+
switch = seesaw_digitalio.DigitalIO(seesaw, 24)
33+
switch_state = False
34+
pixel = neopixel.NeoPixel(seesaw, 6, 1)
35+
pixel.brightness = 0.2
36+
pixel.fill((255, 0, 0))
37+
print()
38+
print("Connecting to WiFi")
39+
# connect to your SSID
40+
try:
41+
wifi.radio.connect(os.getenv('CIRCUITPY_WIFI_SSID'), os.getenv('CIRCUITPY_WIFI_PASSWORD'))
42+
except Exception:
43+
wifi.radio.connect(os.getenv('WIFI_SSID'), os.getenv('WIFI_PASSWORD'))
44+
print("Connected to WiFi")
45+
pixel.fill((0, 0, 255))
46+
47+
pool = socketpool.SocketPool(wifi.radio)
48+
requests = adafruit_requests.Session(pool, ssl.create_default_context())
49+
50+
# buttons
51+
button0 = digitalio.DigitalInOut(board.D0)
52+
button0.direction = digitalio.Direction.INPUT
53+
button0.pull = digitalio.Pull.UP
54+
button0_state = False
55+
button1 = digitalio.DigitalInOut(board.D1)
56+
button1.direction = digitalio.Direction.INPUT
57+
button1.pull = digitalio.Pull.DOWN
58+
button1_state = False
59+
button2 = digitalio.DigitalInOut(board.D2)
60+
button2.direction = digitalio.Direction.INPUT
61+
button2.pull = digitalio.Pull.DOWN
62+
button2_state = False
63+
64+
group = displayio.Group()
65+
board.DISPLAY.root_group = group
66+
67+
# font for graphics
68+
sm_file = "/roundedHeavy-26.bdf"
69+
sm_font = bitmap_font.load_font(sm_file)
70+
# font for text only
71+
lg_file = "/roundedHeavy-46.bdf"
72+
lg_font = bitmap_font.load_font(lg_file)
73+
http_text = bitmap_label.Label(sm_font, text=" ")
74+
http_text.anchor_point = (1.0, 0.0)
75+
http_text.anchored_position = (board.DISPLAY.width, 0)
76+
group.append(http_text)
77+
status_text = bitmap_label.Label(sm_font, text=" ")
78+
status_text.anchor_point = (0.0, 0.5)
79+
status_text.anchored_position = (0, board.DISPLAY.height / 2)
80+
group.append(status_text)
81+
temp_text = bitmap_label.Label(lg_font, text=" K")
82+
temp_text.anchor_point = (1.0, 0.5)
83+
temp_text.anchored_position = (board.DISPLAY.width, board.DISPLAY.height / 2)
84+
group.append(temp_text)
85+
bright_text = bitmap_label.Label(lg_font, text=" %", x=board.DISPLAY.width//2, y=90)
86+
bright_text.anchor_point = (1.0, 1.0)
87+
bright_text.anchored_position = (board.DISPLAY.width, board.DISPLAY.height - 15)
88+
group.append(bright_text)
89+
onOff_circ = Circle(12, 12, 10, fill=None, stroke = 2, outline = 0xcccc00)
90+
group.append(onOff_circ)
91+
92+
def kelvin_to_elgato(value):
93+
t = value * 0.05
94+
t = max(min(344, int(t)), 143)
95+
return t
96+
97+
def elgato_to_kelvin(value):
98+
t = value / 0.05
99+
return t
100+
101+
def ctrl_light(b, t, onOff):
102+
url = f"http://{light}:9123/elgato/lights"
103+
json = {"numberOfLights":num_lights,"lights":[{"on":onOff,"brightness":b,"temperature":t}]}
104+
print(f"PUTting data to {url}: {json}")
105+
status_text.text = "sending.."
106+
for i in range(5):
107+
try:
108+
pixel.fill((0, 255, 0))
109+
r = requests.request(method="PUT", url=url, data=None, json=json, headers = {'Content-Type': 'application/json'}, timeout=10)
110+
print("-" * 40)
111+
print(r.status_code)
112+
# if PUT fails, try again
113+
if r.status_code != 200:
114+
status_text.text = "..sending.."
115+
pixel.fill((255, 255, 0))
116+
time.sleep(2)
117+
r = requests.request(method="PUT", url=url, data=None, json=json, headers = {'Content-Type': 'application/json'}, timeout=10)
118+
if r.status_code != 200:
119+
pixel.fill((255, 0, 0))
120+
except Exception:
121+
pixel.fill((255, 0, 0))
122+
time.sleep(2)
123+
if i < 5 - 1:
124+
continue
125+
raise
126+
break
127+
status_text.text = "sent!"
128+
light_indicator(onOff)
129+
pixel.fill((255, 0, 255))
130+
131+
def read_light():
132+
status_text.text = "reading.."
133+
for i in range(5):
134+
try:
135+
pixel.fill((0, 255, 0))
136+
r = requests.get(f"http://{light}:9123/elgato/lights")
137+
j = r.json()
138+
if r.status_code != 200:
139+
status_text.text = "..reading.."
140+
pixel.fill((255, 255, 0))
141+
time.sleep(2)
142+
r = requests.get(f"http://{light}:9123/elgato/lights")
143+
j = r.json()
144+
if r.status_code != 200:
145+
pixel.fill((255, 0, 0))
146+
raise
147+
except Exception:
148+
pixel.fill((255, 0, 0))
149+
time.sleep(2)
150+
if i < 5 - 1:
151+
continue
152+
raise
153+
break
154+
status_text.text = "read!"
155+
pixel.fill((255, 0, 255))
156+
onOff = j['lights'][0]['on']
157+
light_indicator(onOff)
158+
b = round(j['lights'][0]['brightness'] / 10) * 10
159+
bright_text.text = f"{b}%"
160+
t = j['lights'][0]['temperature']
161+
color_t = round(elgato_to_kelvin(t) / 100) * 100
162+
temp_text.text = f"{color_t}K"
163+
return b, color_t, t, onOff
164+
165+
def light_indicator(onOff):
166+
if onOff:
167+
onOff_circ.fill = 0xcccc00
168+
else:
169+
onOff_circ.fill = None
170+
171+
selected_light = 0
172+
adjust_temp = True
173+
last_position = 0
174+
175+
http_text.text = f"{light}"
176+
# get on/off state of light on start-up
177+
try:
178+
brightness, color_temp, temp, light_on = read_light()
179+
except Exception:
180+
print()
181+
print("Could not find your Elgato light on the network..")
182+
print("Make sure it is powered on and that its IP address is correct in settings.toml.")
183+
print()
184+
raise
185+
186+
while True:
187+
position = encoder.position
188+
# reset button state on release
189+
if not switch.value and switch_state:
190+
switch_state = False
191+
if button0.value and button0_state:
192+
button0_state = False
193+
if not button1.value and button1_state:
194+
button1_state = False
195+
if not button2.value and button2_state:
196+
button2_state = False
197+
198+
if position != last_position:
199+
if position > last_position:
200+
if adjust_temp:
201+
color_temp = color_temp + 100
202+
color_temp = max(min(7000, color_temp), 2900)
203+
temp_text.text = f"{color_temp}K"
204+
else:
205+
brightness = brightness + 10
206+
brightness = max(min(100, brightness), 10)
207+
bright_text.text = f"{brightness}%"
208+
else:
209+
if adjust_temp:
210+
color_temp = color_temp - 100
211+
color_temp = max(min(7000, color_temp), 2900)
212+
temp_text.text = f"{color_temp}K"
213+
else:
214+
brightness = brightness - 10
215+
brightness = max(min(100, brightness), 10)
216+
bright_text.text = f"{brightness}%"
217+
temp = kelvin_to_elgato(color_temp)
218+
last_position = position
219+
# switch between adjusting color temp or brightness
220+
if switch.value and not switch_state:
221+
switch_state = True
222+
adjust_temp = not adjust_temp
223+
# toggle light on/off
224+
if not button0.value and not button0_state:
225+
button0_state = True
226+
light_on = not light_on
227+
ctrl_light(brightness, temp, light_on)
228+
clock_clock = ticks_add(clock_clock, clock_timer)
229+
# update brightness/temp
230+
if button1.value and not button1_state:
231+
button1_state = True
232+
light_on = True
233+
ctrl_light(brightness, temp, light_on)
234+
clock_clock = ticks_add(clock_clock, clock_timer)
235+
# check values
236+
if button2.value and not button2_state:
237+
button2_state = True
238+
brightness, color_temp, temp, light_on = read_light()
239+
clock_clock = ticks_add(clock_clock, clock_timer)
240+
if ticks_diff(ticks_ms(), clock_clock) >= clock_timer:
241+
status_text.text = "Connected"
242+
clock_clock = ticks_add(clock_clock, clock_timer)

0 commit comments

Comments
 (0)