· 5 years ago · Jan 11, 2021, 07:46 PM
1import json
2import math
3import pygame
4import requests
5import sys
6import multiprocessing as mp
7import PySimpleGUI as sg
8import time
9global static_color
10global response
11global first
12
13auth_token = "super secret auth token"
14url = f"http://ip:16021/api/v1/{auth_token}/"
15
16# Get default values from API
17response = eval(requests.get(url).text.replace("true", "True").replace("false", "False"))
18
19layout_info = response["panelLayout"]["layout"]
20panel_lst = [panel["panelId"] for panel in layout_info["positionData"]]
21effects_list = response['effects']['effectsList']
22panel_count = str(int(layout_info["numPanels"]))
23delay = 100
24
25static_color = False
26first = True
27
28
29# Changes the light colors
30def change_lights():
31 global static_color
32 while True:
33 if static_color:
34 try:
35 RGB_value_R = str(int(values['-RGB_CHANGED_R']))
36 RGB_value_G = str(int(values['-RGB_CHANGED_G']))
37 RGB_value_B = str(int(values['-RGB_CHANGED_B']))
38 lst_data = " ".join([f' {panel} 1 {RGB_value_R} {RGB_value_G} {RGB_value_B} 0 1' for panel in panel_lst])
39
40 data_ = '{"write": {"command": "display", "animType": "static", "animData": "' + panel_count + lst_data + '", "loop": false, "palette":[]}}'
41 requests.put(url + 'effects', data=data_, headers={'content-type': 'application/json'})
42 time.sleep(0.001 * delay)
43 except Exception as e:
44 print(e)
45 else:
46 print(static_color)
47
48
49# Don't touch!!
50# Maps the light panels
51def draw_window(info):
52 panels = info["panelLayout"]["layout"]["positionData"]
53 pi2 = 2 * 3.14
54 size = 42
55 coord_decrease = 1.6
56 max_val_y = max([abs(panel['y'] // coord_decrease) + size for panel in panels])
57 max_val_x = max([abs(panel['x'] // coord_decrease) + size for panel in panels])
58
59 pygame.init() # Start the pygame sequence
60 clock = pygame.time.Clock() # Create pygame clock
61 fps = 10 # Set FPS (Not necessary)
62 bg = [255, 255, 255] # Bg (Not necessary)
63
64 screen = pygame.display.set_mode([int(max_val_x), int(max_val_y)])
65
66 pygame.display.set_caption(info['name'])
67
68 while True:
69 screen.fill(bg)
70 for panel in panels:
71 x = panel['x'] // coord_decrease
72 y = abs(panel['y'] // coord_decrease - max_val_y)
73
74 if panel['shapeType'] == 7:
75 pygame.draw.lines(screen, [0, 0, 0], True,
76 [(math.cos(i / 6 * pi2) * size + x, math.sin(i / 6 * pi2) * size + y) for i in
77 range(0, 6)])
78
79 for event in pygame.event.get():
80 if event.type == pygame.QUIT:
81 pygame.quit()
82 sys.exit
83 return False
84
85 pygame.display.flip()
86 clock.tick(fps / 2)
87
88
89if __name__ == '__main__':
90 # Check And Change the light colors
91 process_cac_color = mp.Process(target=change_lights)
92 process_cac_color.start()
93
94 # ======================================================================================================
95 # ============================================== Make GUI ==============================================
96 # ======================================================================================================
97 # Set default color values
98 sg.SetOptions(background_color='#F0F0F0', element_background_color='#F0F0F0', text_color='#000000')
99
100 # Function to collapse the down part of the screens
101 def collapse(layout, key):
102 return sg.pin(sg.Column(layout, key=key))
103
104 # Declaring static color mode
105 section1 = [
106 [sg.Text('RGB Values', font=("Helvetica", 18), background_color='#F0F0F0', size=(10, 1)),
107 sg.Text(' ', background_color='#F0F0F0')],
108
109 [sg.Slider(range=(0, 255), default_value=0, size=(10, 20), orientation='vertical', font=("Helvetica", 15), enable_events=True, key='-RGB_CHANGED_R', text_color='#000000'),
110 sg.Text(' ' * 3, background_color='#F0F0F0'),
111 sg.Slider(range=(0, 255), default_value=0, size=(10, 20), orientation='vertical', font=("Helvetica", 15), enable_events=True, key='-RGB_CHANGED_G', text_color='#000000'),
112 sg.Text(' ' * 3, background_color='#F0F0F0'),
113 sg.Slider(range=(0, 255), default_value=0, size=(10, 20), orientation='vertical', font=("Helvetica", 15), enable_events=True, key='-RGB_CHANGED_B', text_color='#000000')],
114
115 [sg.Text(' Red', font=("Helvetica", 17), size=(6, 1), background_color='#F0F0F0'),
116 sg.Text(' ' * 1, background_color='#F0F0F0'),
117 sg.Text('Green', font=("Helvetica", 17), size=(5, 1), background_color='#F0F0F0'),
118 sg.Text(' ' * 3, background_color='#F0F0F0'),
119 sg.Text('Blue', font=("Helvetica", 17), size=(4, 1), background_color='#F0F0F0')]]
120
121 # Declaring effects color mode
122 section2 = [
123 [sg.Text('Effects', font=("Helvetica", 18), background_color='#F0F0F0', size=(10, 1)),
124 sg.Text(' ', background_color='#F0F0F0')],
125
126 [sg.Listbox(values=[x for x in effects_list], select_mode=sg.LISTBOX_SELECT_MODE_SINGLE, size=(43, 8), enable_events=True, key='-EFFECT_SELECTED', font=("Helvetica", 9))]]
127
128 # Upper screen buttons etc.
129 layout = [[sg.Text('NanoLeaf Control Panel', size=(19, 1), font=("Helvetica", 22), background_color='#00F0FF')],
130 [sg.Checkbox('Enable NanoLeafs', enable_events=True, key='-NL_ENABLED', default=response['state']['on']['value'], font=("Helvetica", 18))],
131 [sg.Checkbox('Static Color', enable_events=True, key='-SWITCH_COLOR_MODE', font=("Helvetica", 18))],
132 [sg.Text('Brightness', font=("Helvetica", 18), background_color='#F0F0F0'),
133 sg.Slider(range=(0, 100), default_value=response['state']['brightness']['value'], size=(10, 20), orientation='horizontal', font=("Helvetica", 0), enable_events=True, key='-BRIGHTNESS_CHANGED', disable_number_display=True)],
134
135 # Collapse bottom sections
136 [collapse(section1, '-SEC1-')],
137 [collapse(section2, '-SEC2-')],
138
139 # Unnecessary footer
140 [sg.Text(' ', font=("Helvetica", 1), background_color='#F0F0F0')]]
141
142 # Initiate GUI
143 window = sg.Window('NanoLeaf Control Panel', layout, default_element_size=(20, 1), font=("Helvetica", 25))
144
145 # Check for events
146 while True:
147 event, values = window.read(timeout=delay)
148
149 if event == 'Exit' or event == sg.WIN_CLOSED:
150 break
151
152 # Disable and enable lights
153 elif event.startswith('-NL_ENABLED'):
154 state_on = values['-NL_ENABLED']
155 response = str(requests.put(url + 'state', data='{"on": {"value": ' + str(bool(state_on)).lower() + '}}', headers={'content-type': 'application/json'}))
156 print(response)
157
158 # Color mode switch
159 elif event.startswith('-SWITCH_COLOR_MODE') or first:
160 static_color = not static_color
161 window['-SEC1-'].update(visible=not static_color)
162 window['-SEC2-'].update(visible=static_color)
163 first = False
164
165 # Change effects
166 elif event.startswith('-EFFECT_SELECTED'):
167 response = requests.put(url + 'effects', data='{"select": "' + values['-EFFECT_SELECTED'][0] + '"}', headers={'content-type': 'application/json'})
168 print(response)
169
170 # Change brightness
171 elif event.startswith('-BRIGHTNESS_CHANGED'):
172 response = requests.put(url + 'state', data='{"brightness" : {"value": ' + str(int(values['-BRIGHTNESS_CHANGED'])) + '}}', headers={'content-type': 'application/json'})
173 print(response)
174
175 # Map the lights
176 elif event.startswith('-MAP_PRESSED'):
177 process_map_light = mp.Process(target=draw_window, args=[json.loads(requests.get(url).text)])
178 process_map_light.start()
179