def convert_xy_to_rgb(self, color): converter = Converter(GamutC) x = color[0] y = color[1] _rgb = [0, 0, 0, 255] rgb = converter.xy_to_rgb(x, y) for i in range(len(rgb)): _rgb[i] = rgb[i] / 255 return _rgb
async def run(self): """Called when the Accessory should start doing its thing. Called when HAP server is running, advertising is set, etc. Can be overridden with a normal or async method. """ uri = f"ws://127.0.0.1:8000/things/{self.thing_id}" print(f"{self.category}:{self.thing_id}") self.sleep_time = 5 while True: # outer loop restarted every time the connection fails print(f"Creating new connection to {uri}") try: async with websockets.connect(uri) as ws: while True: try: rep = await ws.recv() except websockets.exceptions.ConnectionClosed: print(f"Ping error - retrying connection in {self.sleep_time} sec (Ctrl-C to quit)") await asyncio.sleep(self.sleep_time) break recv_data = json.loads(rep) if recv_data.get("messageType") == "propertyStatus": value = recv_data.get("data") if value.get('contact') is not None and hasattr(self, 'char_contact'): self.char_contact.set_value(value.get('contact')) if value.get('temperature') and hasattr(self, 'char_temp'): self.char_temp.set_value(value.get('temperature')) if value.get('state') is not None and hasattr(self, 'char_on'): self.char_on.set_value(True if value.get('state') == 1 else False) if value.get('brightness') and hasattr(self, 'char_brightness'): self.char_brightness.set_value(int((value.get('brightness') / 254) * 100)) if value.get('color') and hasattr(self, 'char_brightness') and hasattr(self, 'char_saturation'): x = value.get('color').get('x') y = value.get('color').get('y') converter = Converter() print(value) rgb = converter.xy_to_rgb(x, y, value.get('brightness')) import colorsys hsv = colorsys.rgb_to_hsv(rgb[0], rgb[1], rgb[2]) self.char_on.set_value(hsv[0]*60) self.char_saturation.set_value(hsv[1]*100) self.char_brightness.set_value(hsv[2]*100) print(f"data push from ws:{value}") except socket.gaierror: print( f"Socket error - retrying connection in {self.sleep_time} sec (Ctrl-C to quit)") await asyncio.sleep(self.sleep_time) continue except (websockets.exceptions.InvalidStatusCode, ConnectionRefusedError): print('Nobody seems to listen to this endpoint. Please check the URL.') print(f"Retrying connection in {self.sleep_time} sec (Ctrl-C to quit)") await asyncio.sleep(self.sleep_time) continue
def sin_rainbow(radius=1): converter = Converter() r0, g0, b0 = (0, 0, 0) while (1): for rad in np.arange(0, math.pi * 2, 0.01): time.sleep(0.05) #rad = (math.sin(counter * math.pi * 1.5) / 2) x = radius * math.cos(rad) y = radius * math.sin(rad) r1, g1, b1 = converter.xy_to_rgb(x, y) if (r1 != r0): pi.set_PWM_dutycycle(LED_RED, r1) if (g1 != g0): pi.set_PWM_dutycycle(LED_GREEN, g1) if (b1 != b0): pi.set_PWM_dutycycle(LED_BLUE, b1) r0, g0, b0 = (r1, g1, b1)
def colourLogger(): if verbose == True: print(" ") print("colourLogger called") url = "http://" + hub_ip + "/api/" + api_key + "/lights/" lightsOn = 0 colours = [] for light in lights: endpoint = url + light if verbose == True: print("getting light state from: " + str(endpoint)) status = requests.get(endpoint) if status.json()['state']['on'] == True: if verbose == True: print("that light is on") lightsOn += 1 xy = status.json()['state']['xy'] colours.append(xy) if verbose == True: print("added colour " + str(xy) + " to colours") con = Converter(GamutC) rough = con.xy_to_rgb(xy[0], xy[1]) r = rough[0] g = rough[1] b = rough[2] print("that's roughly r=" + str(r) + " g=" + str(g) + " b=" + str(b)) else: if verbose == True: print("that light is not on") else: pass if verbose == True: print(" ") return colours, lightsOn
def lightCalculator(lights, lightsOn): if verbose == True: print(" ") print("lightCalculator called") print("lights monitored:") print(lights) print("number of lights on: " + str(lightsOn)) print(" ") print("converting colours:") colours = [] con = Converter(GamutC) # Get each bulb's hue and append to the colours list for index in range(lightsOn): if verbose == True: print("colour " + str(index)) print(lights[index][0], lights[index][1]) rgb = con.xy_to_rgb(lights[index][0], lights[index][1]) hsv = rgb_to_hsv(rgb[0] / 255.0, rgb[1] / 255.0, rgb[2] / 255.0) h = int((hsv[0] * 360)) % 360 colours.append(h) if verbose == True: print("Hue calculated as " + str(h) + " and added to list") print(" ") colours.sort() no_of_colours = len(colours) if no_of_colours == 0: return elif no_of_colours == 1: if verbose == True: print( "only one light detected. Creating two neighbouring colours and going clockwise" ) colour1 = colours[0] - 45 colour2 = colours[0] colour3 = colours[0] + 45 add_direction = True colours = [] colours.append(colour1) colours.append(colour2) colours.append(colour3) no_of_colours = 3 else: if ((colours[1] - colours[0] + 360) % 360 < (360 / no_of_colours)): if verbose == True: print("going clockwise (1)") add_direction = True elif ((colours[0] + 360 - colours[-1] % 360) < (360 / no_of_colours)): if verbose == True: print("2 going anticlockwise (2)") add_direction = False elif ((colours[1] - colours[0] + 360) % 360 < (2 * (360 / no_of_colours))): if verbose == True: print("3 going clockwise (3)") add_direction = True elif ((colours[0] + 360 - colours[-1] % 360) < (2 * (360 / no_of_colours))): if verbose == True: print("4 going anticlockwise (4)") add_direction = False else: if verbose == True: print( "couldn't find an efficient path: going clockwise, anyway (5)" ) output = [] if verbose == True: print(" ") print("doing maths to calculate fades!") print(" ") for x in range(no_of_colours): this_colour = colours[x] try: next_colour = colours[x + 1] except: next_colour = colours[0] add_direction = not add_direction if add_direction == True: if this_colour > next_colour: distance = (360 - this_colour + next_colour) elif this_colour < next_colour: distance = next_colour - this_colour else: distance = 0 else: if this_colour < next_colour: distance = (360 + this_colour) - next_colour elif this_colour > next_colour: distance = this_colour - next_colour else: distance = 0 output.append( [this_colour, next_colour, (distance / 64.0), add_direction]) if verbose == True: print("lightCalculator has finished, output is: ") print(output) return output
class Lamp(object): """A wrapper for the Philips Hue BLE protocol""" def __init__(self, address): self.address = address self.client = None @property def is_connected(self): return self.client and self.client.is_connected async def connect(self): # reinitialize BleakClient for every connection to avoid errors self.client = BleakClient(self.address) await self.client.connect() model = await self.get_model() try: self.converter = Converter(get_light_gamut(model)) except ValueError: self.converter = Converter(GamutC) async def disconnect(self): await self.client.disconnect() self.client = None async def get_model(self): """Returns the model string""" model = await self.client.read_gatt_char(CHAR_MODEL) return model.decode('ascii') async def get_power(self): """Gets the current power state""" power = await self.client.read_gatt_char(CHAR_POWER) return bool(power[0]) async def set_power(self, on): """Sets the power state""" await self.client.write_gatt_char(CHAR_POWER, bytes([1 if on else 0]), response=True) async def get_brightness(self): """Gets the current brightness as a float between 0.0 and 1.0""" brightness = await self.client.read_gatt_char(CHAR_BRIGHTNESS) return brightness[0] / 255 async def set_brightness(self, brightness): """Sets the brightness from a float between 0.0 and 1.0""" await self.client.write_gatt_char( CHAR_BRIGHTNESS, bytes([max(min(int(brightness * 255), 254), 1)]), response=True) async def get_color_xy(self): """Gets the current XY color coordinates as floats between 0.0 and 1.0""" buf = await self.client.read_gatt_char(CHAR_COLOR) x, y = unpack('<HH', buf) return x / 0xFFFF, y / 0xFFFF async def set_color_xy(self, x, y): """Sets the XY color coordinates from floats between 0.0 and 1.0""" buf = pack('<HH', int(x * 0xFFFF), int(y * 0xFFFF)) await self.client.write_gatt_char(CHAR_COLOR, buf, response=True) async def get_color_rgb(self): """Gets the RGB color as floats between 0.0 and 1.0""" x, y = await self.get_color_xy() return self.converter.xy_to_rgb(x, y) async def set_color_rgb(self, r, g, b): """Sets the RGB color from floats between 0.0 and 1.0""" x, y = self.converter.rgb_to_xy(r, g, b) await self.set_color_xy(x, y)
def loop(): lastColor = "" while True: uri = "http://" + HUE_BRIDGE_IP + "/api/gBy8DB7KImW4A4KTOZFMndlc1Cqq3Fvgr13MSLpH/lights/13" response = requests.get(uri) if response: data = response.json() converter = Converter(gamut=GamutC) print(data) # Hard-code the brightness since it looks better bri = data["state"]["bri"] / 255 rgb = converter.xy_to_rgb(data["state"]["xy"][0], data["state"]["xy"][1], bri=bri) if str(rgb) != lastColor: # Cache last value lastColor = str(rgb) # Update liquidctl hex_adjusted = converter.xy_to_hex(data["state"]["xy"][0], data["state"]["xy"][1], bri=LED_BRI) liquidctlpath = "C:\\Users\\Alex\\Documents\\GitHub\\hue_poll\\liquidctl-1.1.0-bin-windows-x86_64\\liquidctl.exe" # subprocess.Popen([liquidctlpath, "set", "sync", "color", "fixed", hex_adjusted], shell=True) subprocess.Popen([ liquidctlpath, "set", "sync", "color", "fixed", hex_adjusted ], shell=True) # Update MSIRBG # (r, g, b) = converter.xy_to_rgb(data["state"]["xy"][0],data["state"]["xy"][1], bri=led_bri) # r = adjust(r, 100) # g = adjust(g, 100) # b = adjust(b, 100) # print(r, g, b) # huepollmsipath = "C:\\Users\\Alex\\Documents\\GitHub\\HuePollMSIRGB\\HuePollMSIRGB\\bin\\x64\\Debug\\HuePollMSIRGB.exe" # subprocess.Popen([huepollmsipath, str(r), str(g), str(b)], shell=True) # Update Arduino (r, g, b) = converter.xy_to_rgb(data["state"]["xy"][0], data["state"]["xy"][1], bri=LED_BRI) sendRGB(r, g, b) # Update windows background processImages() (r, g, b) = converter.xy_to_rgb(data["state"]["xy"][0], data["state"]["xy"][1], bri=DESKTOP_BRI) bestImg = getClosestImg([r, g, b]) if bestImg is not None: print('setting bg to:' + bestImg) ctypes.windll.user32.SystemParametersInfoW( 20, 0, bestImg, 0) print('Success: ' + str(rgb)) else: print('Request failed') time.sleep(POLL_INTERVAL)