def set_light(address, light, data): logging.debug("tasmota: <set_light> invoked! IP=" + address["ip"]) logging.debug("setting light with the following payload:\n" + json.dumps(data, indent=4)) for key, value in data.items(): #logging.debug("tasmota: key " + key) if key == "on": if value: sendRequest("http://" + address["ip"] + "/cm?cmnd=Power%20on") else: sendRequest("http://" + address["ip"] + "/cm?cmnd=Power%20off") elif key == "bri": brightness = int(100.0 * (value / 254.0)) sendRequest("http://" + address["ip"] + "/cm?cmnd=Dimmer%20" + str(brightness)) elif key == "ct": sendRequest("http://" + ip + "/cm?cmnd=CT%20" + str(value)) elif key == "xy": color = convert_xy(value[0], value[1], light["state"]["bri"]) sendRequest("http://" + address["ip"] + "/cm?cmnd=Color%20" + str(color[0]) + "," + str(color[1]) + "," + str(color[2])) elif key == "alert": if value == "select": sendRequest("http://" + address["ip"] + "/cm?cmnd=dimmer%20100")
def set_light(address, light, data): ip = address["ip"] if ip in Connections: c = Connections[ip] else: c = HyperionConnection(ip, address["jss_port"]) Connections[ip] = c if "on" in data and data["on"] == False: request_data = {"command": "clear", "priority": PRIORITY} else: request_data = { "command": "color", "origin": "diyHue", "priority": PRIORITY } if light["state"]["colormode"] == "hs": if "hue" in data and "sat" in data: color = hsv_to_rgb(data["hue"], data["sat"], light["state"]["bri"]) else: color = hsv_to_rgb(light["state"]["hue"], light["state"]["sat"], light["state"]["bri"]) else: color = convert_xy(light["state"]["xy"][0], light["state"]["xy"][1], light["state"]["bri"]) request_data["color"] = color c.command(request_data)
def set_light(address, light, data, rgb=None): for key, value in data.items(): light["state"][key] = value on = light["state"]["on"] if on: sendOnCmd(address) colormode = light["state"]["colormode"] if colormode == "xy": xy = light["state"]["xy"] if rgb: r, g, b = rgbBrightness(rgb, light["state"]["bri"]) else: r, g, b = convert_xy(xy[0], xy[1], light["state"]["bri"]) (hue, saturation, value) = colorsys.rgb_to_hsv(r, g, b) sendHueCmd(address, hue * 255) sendSaturationCmd(address, (1 - saturation) * 100) elif colormode == "ct": ct = light["state"]["ct"] ct01 = (ct - 153) / (500 - 153 ) #map color temperature from 153-500 to 0-1 sendKelvinCmd(address, (1 - ct01) * 100) sendBrightnessCmd(address, (light["state"]["bri"] / 255) * 100) if not on: sendOffCmd(address)
def set_light(address, light, data, rgb=None): logging.debug("tasmota: <set_light> invoked! IP=" + address["ip"]) for key, value in data.items(): logging.debug("tasmota: key " + key) if key == "on": if value: sendRequest("http://" + address["ip"] + "/cm?cmnd=Power%20on") else: sendRequest("http://" + address["ip"] + "/cm?cmnd=Power%20off") elif key == "bri": brightness = int(100.0 * (value / 254.0)) sendRequest("http://" + address["ip"] + "/cm?cmnd=Dimmer%20" + str(brightness)) elif key == "ct": color = {} elif key == "xy": if rgb: color = rgbBrightness(rgb, light["state"]["bri"]) else: color = convert_xy(value[0], value[1], light["state"]["bri"]) sendRequest("http://" + address["ip"] + "/cm?cmnd=Color%20" + str(color[0]) + "," + str(color[1]) + "," + str(color[2])) elif key == "alert": if value == "select": sendRequest("http://" + address["ip"] + "/cm?cmnd=dimmer%20100")
def set_light(address, light, data): method = 'TCP' payload = {} transitiontime = 400 if "transitiontime" in data: transitiontime = data["transitiontime"] * 100 for key, value in data.items(): if key == "on": if value: payload["set_power"] = ["on", "smooth", transitiontime] else: payload["set_power"] = ["off", "smooth", transitiontime] elif key == "bri": payload["set_bright"] = [int(value / 2.55) + 1, "smooth", transitiontime] elif key == "ct": #if ip[:-3] == "201" or ip[:-3] == "202": if light["name"].find("desklamp") > 0: if value > 369: value = 369 payload["set_ct_abx"] = [int((-4800/347) * value + 2989900/347), "smooth", transitiontime] elif key == "hue": payload["set_hsv"] = [int(value / 182), int(light["state"]["sat"] / 2.54), "smooth", transitiontime] elif key == "sat": payload["set_hsv"] = [int(light["state"]["hue"] / 182), int(value / 2.54), "smooth", transitiontime] elif key == "xy": color = convert_xy(value[0], value[1], light["state"]["bri"]) payload["set_rgb"] = [(color[0] * 65536) + (color[1] * 256) + color[2], "smooth", transitiontime] #according to docs, yeelight needs this to set rgb. its r * 65536 + g * 256 + b elif key == "alert" and value != "none": payload["start_cf"] = [ 4, 0, "1000, 2, 5500, 100, 1000, 2, 5500, 1, 1000, 2, 5500, 100, 1000, 2, 5500, 1"] # yeelight uses different functions for each action, so it has to check for each function # see page 9 http://www.yeelight.com/download/Yeelight_Inter-Operation_Spec.pdf # check if hue wants to change brightness for key, value in payload.items(): command(address["ip"], key, value)
def set_light(light, data): ip = light.protocol_cfg["ip"] payload = {} transitiontime = 400 if "transitiontime" in data: transitiontime = int(data["transitiontime"] * 100) for key, value in data.items(): if key == "on": payload["state"] = value elif key == "bri": payload["dimming"] = int(value / 2.83) + 10 elif key == "ct": payload["temp"] = round(translateRange(value, 153, 500, 6500, 2700)) elif key == "hue": rgb = hsv_to_rgb(value, light.state["sat"], light.state["bri"]) payload["r"] = rgb[0] payload["g"] = rgb[1] payload["b"] = rgb[2] elif key == "sat": rgb = hsv_to_rgb(light.state["hue"], value, light.state["bri"]) payload["r"] = rgb[0] payload["g"] = rgb[1] payload["b"] = rgb[2] elif key == "xy": rgb = convert_xy(value[0], value[1], light.state["bri"]) payload["r"] = rgb[0] payload["g"] = rgb[1] payload["b"] = rgb[2] elif key == "alert" and value != "none": payload["dimming"] = 100 logging.debug(json.dumps({"method": "setPilot", "params": payload})) udpmsg = bytes(json.dumps({"method": "setPilot", "params": payload}), "utf8") sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP sock.sendto(udpmsg, (ip, 38899))
def send_light_data(c, light, data): state = {} # Always turn on the segment and handle the on/off at light level seg = {"id": light.protocol_cfg['segmentId'], "on": True} for k, v in data.items(): if k == "on": # Handle on/off at light level if v: state["on"] = True else: state["on"] = False elif k == "bri": seg["bri"] = v + 1 elif k == "ct": kelvin = round(translateRange(v, 153, 500, 6500, 2000)) color = kelvinToRgb(kelvin) seg["col"] = [[color[0], color[1], color[2]]] elif k == "xy": color = convert_xy(v[0], v[1], 255) seg["col"] = [[color[0], color[1], color[2]]] elif k == "alert" and v != "none": state = c.getSegState(light.protocol_cfg['segmentId']) c.setBriSeg(0, light.protocol_cfg['segmentId']) sleep(0.6) c.setBriSeg(state["bri"], light.protocol_cfg['segmentId']) return state["seg"] = [seg] c.sendJson(state)
def set_light(light, data): url = "http://" + light.protocol_cfg[ "ip"] + "/gateways/" + light.protocol_cfg[ "miID"] + "/" + light.protocol_cfg["miModes"] + "/" + str( light.protocol_cfg["miGroups"]) payload = {} for key, value in data.items(): if key == "on": payload["status"] = value elif key == "bri": payload["brightness"] = value elif key == "ct": payload["color_temp"] = int(value / 1.6 + 153) elif key == "hue": payload["hue"] = value / 180 elif key == "sat": payload["saturation"] = value * 100 / 255 elif key == "xy": payload["color"] = {} # # The following if is throwing an error, because rgb does not exist in data. I commented this, becaus I didn't know, if there are any requests with "rgb" when using options that I don't know. # if rgb: # payload["color"]["r"], payload["color"]["g"], payload["color"]["b"] = rgbBrightness(rgb, lights[light]["state"]["bri"]) # else: # payload["color"]["r"], payload["color"]["g"], payload["color"]["b"] = convert_xy(value[0], value[1], lights[light]["state"]["bri"]) payload["color"]["r"], payload["color"]["g"], payload["color"][ "b"] = convert_xy(value[0], value[1], light.state["bri"]) logging.debug(json.dumps(payload)) requests.put(url, json=payload, timeout=3)
def set_light(light, data): c = connect(light) for key, value in data.items(): if key == "on": c.set_power(value) if key == "bri": c.set_brightness(value / 254) if key == "xy": color = convert_xy(value[0], value[1], light.state["bri"]) c.set_color_rgb(color[0] / 254, color[1] / 254, color[2] / 254)
def set_light(address, light, data, rgb = None): ip = address["ip"] if ip in Connections: c = Connections[ip] else: c = YeelightConnection(ip) Connections[ip] = c method = 'TCP' payload = {} transitiontime = 400 cmdPrefix = '' if "backlight" in address and address["backlight"]: cmdPrefix = "bg_" if "transitiontime" in data: transitiontime = int(data["transitiontime"] * 100) for key, value in data.items(): if key == "on": if value: payload[cmdPrefix + "set_power"] = ["on", "smooth", transitiontime] else: payload[cmdPrefix + "set_power"] = ["off", "smooth", transitiontime] elif key == "bri": payload[cmdPrefix + "set_bright"] = [int(value / 2.55) + 1, "smooth", transitiontime] elif key == "ct": #if ip[:-3] == "201" or ip[:-3] == "202": if light["name"].find("desklamp") > 0: if value > 369: value = 369 payload[cmdPrefix + "set_ct_abx"] = [int((-4800/347) * value + 2989900/347), "smooth", transitiontime] elif key == "hue": payload[cmdPrefix + "set_hsv"] = [int(value / 182), int(light["state"]["sat"] / 2.54), "smooth", transitiontime] elif key == "sat": payload[cmdPrefix + "set_hsv"] = [int(light["state"]["hue"] / 182), int(value / 2.54), "smooth", transitiontime] elif key == "xy": bri = light["state"]["bri"] if rgb: color = rgbBrightness(rgb, bri) else: color = convert_xy(value[0], value[1], bri) payload[cmdPrefix + "set_rgb"] = [(color[0] * 65536) + (color[1] * 256) + color[2], "smooth", transitiontime] #according to docs, yeelight needs this to set rgb. its r * 65536 + g * 256 + b elif key == "alert" and value != "none": payload[cmdPrefix + "start_cf"] = [ 4, 0, "1000, 2, 5500, 100, 1000, 2, 5500, 1, 1000, 2, 5500, 100, 1000, 2, 5500, 1"] # yeelight uses different functions for each action, so it has to check for each function # see page 9 http://www.yeelight.com/download/Yeelight_Inter-Operation_Spec.pdf # check if hue wants to change brightness for key, value in payload.items(): try: c.command(key, value) except Exception as e: if not c._music and c._connected: c.disconnect() raise e if not c._music and c._connected: c.disconnect()
def set_light(light, data): url = "http://" + str(light["ip"]) method = 'TCP' payload = {} transitiontime = 400 if "transitiontime" in data: transitiontime = data["transitiontime"] * 100 for key, value in data.items(): if key == "on": if value: payload["set_power"] = ["on", "smooth", transitiontime] else: payload["set_power"] = ["off", "smooth", transitiontime] elif key == "bri": payload["set_bright"] = [ int(value / 2.55) + 1, "smooth", transitiontime ] elif key == "ct": payload["set_ct_abx"] = [ int(1000000 / value), "smooth", transitiontime ] elif key == "hue": payload["set_hsv"] = [ int(value / 182), int(light["state"]["sat"] / 2.54), "smooth", transitiontime ] elif key == "sat": payload["set_hsv"] = [ int(value / 2.54), int(light["state"]["hue"] / 2.54), "smooth", transitiontime ] elif key == "xy": color = convert_xy(value[0], value[1], light["state"]["bri"]) payload["set_rgb"] = [ (color[0] * 65536) + (color[1] * 256) + color[2], "smooth", transitiontime ] #according to docs, yeelight needs this to set rgb. its r * 65536 + g * 256 + b elif key == "alert" and value != "none": payload["start_cf"] = [ 4, 0, "1000, 2, 5500, 100, 1000, 2, 5500, 1, 1000, 2, 5500, 100, 1000, 2, 5500, 1" ] if "//" in url: # cutting out the http:// http, url = url.split("//", 1) # yeelight uses different functions for each action, so it has to check for each function # see page 9 http://www.yeelight.com/download/Yeelight_Inter-Operation_Spec.pdf # check if hue wants to change brightness for key, value in payload.items(): command(url, key, value) return get_light(light)
def set_light(address, light, data, rgb=None): global prevOn # Assign all data elements to the "Object" light. for key, value in data.items(): light["state"][key] = value on = light["state"]["on"] colormode = light["state"]["colormode"] if (on != prevOn): sendOnCmd(address) if (('xy' in data) or ('ct' in data) or rgb): if (colormode == "xy"): if rgb: # this one is more performant than the "else" block r, g, b = rgbBrightness(rgb, light["state"]["bri"]) else: xy = light["state"]["xy"] r, g, b = convert_xy(xy[0], xy[1], light["state"]["bri"]) (hue, saturation, value) = colorsys.rgb_to_hsv(r, g, b) sendHueCmd(address, hue * 255) sendSaturationCmd(address, (1 - saturation) * 100) elif colormode == "ct": ct = light["state"]["ct"] ct01 = (ct - 153) / (500 - 153 ) # map color temperature from 153-500 to 0-1 sendKelvinCmd(address, (1 - ct01) * 100) if ("bri" in data): sendBrightnessCmd(address, (light["state"]["bri"] / 255) * 100) if not on: sendOffCmd(address) prevOn = on
def set_light(light, data): global is_gradient, old_gradient, was_off strip = KL430LightStrip(light.protocol_cfg["ip"]) gradient = data.get("gradient") # strip.send_debug(1,json.dumps({"data":data}).encode()) # strip.send_debug(1, json.dumps({"light": light.state}).encode()) if gradient: if was_off: # strip.send_debug(1,json.dumps({"old_gra":old_gradient}).encode()) payload = strip.build_request("set_light_state", {"hue": 0, "saturation": 0, "color_temp": 0, "brightness": 0, "on_off": 1, "ignore_default": 1}) strip.send_request(strip.host, payload) was_off = False is_gradient = True colors = [] point = gradient["points"] for i in [0, 1, 2, 3, 4]: xy = point[i]["color"]["xy"] color = convert_xy(xy["x"], xy["y"], 255) hsv = rgb_to_hsv(color[0], color[1], color[2]) colors.append(hsv) if light.state["bri"]: strip.create_gradient(colors, int(light.state["bri"] / 2.55)) else: strip.create_gradient(colors, 75) payload = strip.get_gradiant_state() payload["on_off"] = 1 old_gradient = payload payload = strip.build_request("set_light_state", payload) strip.send_request(strip.host, payload) return payload = { "on_off": 1, } # should work with other Kasa Bulbs to for key, value in data.items(): if key == "on": # Saves that's is off if not value: was_off = True # Turns on to the old state if value is True and was_off: # strip.send_debug(1,json.dumps({"old_gra":old_gradient}).encode()) payload = strip.build_request("set_light_state", {"hue": 0, "saturation": 0, "color_temp": 0, "brightness": 0, "on_off": 1, "ignore_default": 1}) strip.send_request(strip.host, payload) payload = strip.build_request("set_light_state", old_gradient) strip.send_request(strip.host, payload) was_off = False return payload["on_off"] = value elif key == "bri": payload["brightness"] = int(value / 2.55) if is_gradient: strip.set_bri(payload["brightness"]) return elif key == "ct": is_gradient = False # color temp == 2501 indicates colorMode (found no other way) payload["color_temp"] = round(translateRange(value, 500, 153, 2500, 6500)) payload["hue"] = 0 payload["brightness"] = int(light.state["bri"] / 2.55) elif key == "alert" and value != "none": payload["brightness"] = 100 data = strip.build_request("set_light_state", payload) strip.send_request(strip.host, data)
def entertainmentService(group, user): logging.debug("User: "******"Key: " + user.client_key) lights_v2 = [] lights_v1 = {} hueGroup = -1 hueGroupLights = {} for light in group.lights: lights_v1[int(light().id_v1)] = light() if light().protocol == "hue" and get_hue_entertainment_group(light(), group.name) != -1: # If the lights' Hue bridge has an entertainment group with the same name as this current group, we use it to sync the lights. hueGroup = get_hue_entertainment_group(light(), group.name) hueGroupLights[int(light().protocol_cfg["id"])] = [] # Add light id to list bridgeConfig["lights"][light().id_v1].state["mode"] = "streaming" v2LightNr = {} for channel in group.getV2Api()["channels"]: lightObj = getObject(channel["members"][0]["service"]["rid"]) if lightObj.id_v1 not in v2LightNr: v2LightNr[lightObj.id_v1] = 0 else: v2LightNr[lightObj.id_v1] += 1 lights_v2.append({"light": lightObj, "lightNr": v2LightNr[lightObj.id_v1]}) logging.debug(lights_v1) logging.debug(lights_v2) opensslCmd = ['openssl', 's_server', '-dtls', '-psk', user.client_key, '-psk_identity', user.username, '-nocert', '-accept', '2100', '-quiet'] p = Popen(opensslCmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) if hueGroup != -1: # If we have found a hue Brige containing a suitable entertainment group for at least one Lamp, we connect to it h = HueConnection(bridgeConfig["config"]["hue"]["ip"]) h.connect(hueGroup, hueGroupLights) if h._connected == False: hueGroupLights = {} # on a failed connection, empty the list init = False frameBites = 10 frameID = 1 initMatchBytes = 0 host_ip = bridgeConfig["config"]["ipaddress"] p.stdout.read(1) # read one byte so the init function will correctly detect the frameBites try: while bridgeConfig["groups"][group.id_v1].stream["active"]: if not init: readByte = p.stdout.read(1) logging.debug(readByte) if readByte in b'\x48\x75\x65\x53\x74\x72\x65\x61\x6d': initMatchBytes += 1 else: initMatchBytes = 0 if initMatchBytes == 9: frameBites = frameID - 8 logging.debug("frameBites: " + str(frameBites)) p.stdout.read(frameBites - 9) # sync streaming bytes init = True frameID += 1 else: data = p.stdout.read(frameBites) logging.debug(",".join('{:02x}'.format(x) for x in data)) nativeLights = {} esphomeLights = {} mqttLights = [] wledLights = {} if data[:9].decode('utf-8') == "HueStream": i = 0 apiVersion = 0 counter = 0 if data[9] == 1: #api version 1 i = 16 apiVersion = 1 counter = len(data) elif data[9] == 2: #api version 1 i = 52 apiVersion = 2 counter = len(group.getV2Api()["channels"]) * 7 + 52 channels = {} while (i < counter): light = None r,g,b = 0,0,0 if apiVersion == 1: if (data[i+1] * 256 + data[i+2]) in channels: channels[data[i+1] * 256 + data[i+2]] += 1 else: channels[data[i+1] * 256 + data[i+2]] = 0 if data[i] == 0: # Type of device 0x00 = Light if data[i+1] * 256 + data[i+2] == 0: break light = lights_v1[data[i+1] * 256 + data[i+2]] elif data[i] == 1: # Type of device Gradient Strip light = findGradientStrip(group) if data[14] == 0: #rgb colorspace r = int((data[i+3] * 256 + data[i+4]) / 256) g = int((data[i+5] * 256 + data[i+6]) / 256) b = int((data[i+7] * 256 + data[i+8]) / 256) elif data[14] == 1: #cie colorspace x = (data[i+3] * 256 + data[i+4]) / 65535 y = (data[i+5] * 256 + data[i+6]) / 65535 bri = int((data[i+7] * 256 + data[i+8]) / 256) r, g, b = convert_xy(x, y, bri) elif apiVersion == 2: light = lights_v2[data[i]]["light"] if data[14] == 0: #rgb colorspace r = int((data[i+1] * 256 + data[i+2]) / 256) g = int((data[i+3] * 256 + data[i+4]) / 256) b = int((data[i+5] * 256 + data[i+6]) / 256) elif data[14] == 1: #cie colorspace x = (data[i+1] * 256 + data[i+2]) / 65535 y = (data[i+3] * 256 + data[i+4]) / 65535 bri = int((data[i+5] * 256 + data[i+6]) / 256) r, g, b = convert_xy(x, y, bri) if light == None: logging.info("error in light identification") break logging.debug("Light:" + str(light.name) + " RED: " + str(r) + ", GREEN: " + str(g) + ", BLUE: " + str(b) ) proto = light.protocol if r == 0 and g == 0 and b == 0: light.state["on"] = False else: light.state.update({"on": True, "bri": int((r + g + b) / 3), "xy": convert_rgb_xy(r, g, b), "colormode": "xy"}) if proto in ["native", "native_multi", "native_single"]: if light.protocol_cfg["ip"] not in nativeLights: nativeLights[light.protocol_cfg["ip"]] = {} if apiVersion == 1: if light.modelid in ["LCX001", "LCX002", "LCX003", "915005987201", "LCX004"]: if data[i] == 1: # individual strip address nativeLights[light.protocol_cfg["ip"]][data[i+1] * 256 + data[i+2]] = [r, g, b] elif data[i] == 0: # individual strip address for x in range(7): nativeLights[light.protocol_cfg["ip"]][x] = [r, g, b] else: nativeLights[light.protocol_cfg["ip"]][light.protocol_cfg["light_nr"] - 1] = [r, g, b] elif apiVersion == 2: if light.modelid in ["LCX001", "LCX002", "LCX003", "915005987201", "LCX004"]: nativeLights[light.protocol_cfg["ip"]][lights_v2[data[i]]["lightNr"]] = [r, g, b] else: nativeLights[light.protocol_cfg["ip"]][light.protocol_cfg["light_nr"] - 1] = [r, g, b] elif proto == "esphome": if light.protocol_cfg["ip"] not in esphomeLights: esphomeLights[light.protocol_cfg["ip"]] = {} bri = int(max(r,g,b)) esphomeLights[light.protocol_cfg["ip"]]["color"] = [r, g, b, bri] elif proto == "mqtt": operation = skipSimilarFrames(light.id_v1, light.state["xy"], light.state["bri"]) if operation == 1: mqttLights.append({"topic": light.protocol_cfg["command_topic"], "payload": json.dumps({"brightness": light.state["bri"], "transition": 0.2})}) elif operation == 2: mqttLights.append({"topic": light.protocol_cfg["command_topic"], "payload": json.dumps({"color": {"x": light.state["xy"][0], "y": light.state["xy"][1]}, "transition": 0.15})}) elif proto == "yeelight": enableMusic(light.protocol_cfg["ip"], host_ip) c = YeelightConnections[light.protocol_cfg["ip"]] operation = skipSimilarFrames(light.id_v1, light.state["xy"], light.state["bri"]) if operation == 1: c.command("set_bright", [int(light.state["bri"] / 2.55), "smooth", 200]) #c.command("set_bright", [int(bridgeConfig["lights"][str(lightId)]["state"]["bri"] / 2.55), "sudden", 0]) elif operation == 2: c.command("set_rgb", [(r * 65536) + (g * 256) + b, "smooth", 200]) #c.command("set_rgb", [(r * 65536) + (g * 256) + b, "sudden", 0]) elif proto == "wled": if light.protocol_cfg["ip"] not in wledLights: wledLights[light.protocol_cfg["ip"]] = {} wledLights[light.protocol_cfg["ip"] ]["ledCount"] = light.protocol_cfg["ledCount"] wledLights[light.protocol_cfg["ip"] ]["color"] = [r, g, b] elif proto == "hue" and int(light.protocol_cfg["id"]) in hueGroupLights: hueGroupLights[int(light.protocol_cfg["id"])] = [r,g,b] else: if frameID % 4 == 0: # can use 2, 4, 6, 8, 12 => increase in case the destination device is overloaded operation = skipSimilarFrames(light.id_v1, light.state["xy"], light.state["bri"]) if operation == 1: light.setV1State({"bri": light.state["bri"], "transitiontime": 3}) elif operation == 2: light.setV1State({"xy": light.state["xy"], "transitiontime": 3}) frameID += 1 if frameID == 25: frameID = 1 if apiVersion == 1: i = i + 9 elif apiVersion == 2: i = i + 7 if len(nativeLights) != 0: for ip in nativeLights.keys(): udpmsg = bytearray() for light in nativeLights[ip].keys(): udpmsg += bytes([light]) + bytes([nativeLights[ip][light][0]]) + bytes([nativeLights[ip][light][1]]) + bytes([nativeLights[ip][light][2]]) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP sock.sendto(udpmsg, (ip.split(":")[0], 2100)) if len(esphomeLights) != 0: for ip in esphomeLights.keys(): udpmsg = bytearray() udpmsg += bytes([0]) + bytes([esphomeLights[ip]["color"][0]]) + bytes([esphomeLights[ip]["color"][1]]) + bytes([esphomeLights[ip]["color"][2]]) + bytes([esphomeLights[ip]["color"][3]]) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP sock.sendto(udpmsg, (ip.split(":")[0], 2100)) if len(mqttLights) != 0: auth = None if bridgeConfig["config"]["mqtt"]["mqttUser"] != "" and bridgeConfig["config"]["mqtt"]["mqttPassword"] != "": auth = {'username':bridgeConfig["config"]["mqtt"]["mqttUser"], 'password':bridgeConfig["config"]["mqtt"]["mqttPassword"]} publish.multiple(mqttLights, hostname=bridgeConfig["config"]["mqtt"]["mqttServer"], port=bridgeConfig["config"]["mqtt"]["mqttPort"], auth=auth) if len(wledLights) != 0: wled_udpmode = 2 wled_secstowait = 2 for ip in wledLights.keys(): udphead = [wled_udpmode, wled_secstowait] color = wledLights[ip]["color"] * int(wledLights[ip]["ledCount"]) udpdata = bytes(udphead+color) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(udpdata, (ip.split(":")[0], 21324)) if len(hueGroupLights) != 0: h.send(hueGroupLights, hueGroup) else: logging.info("HueStream was missing in the frame") p.kill() try: h.disconnect() except UnboundLocalError: pass except Exception as e: #Assuming the only exception is a network timeout, please don't scream at me logging.info("Entertainment Service was syncing and has timed out, stopping server and clearing state" + str(e)) p.kill() try: h.disconnect() except UnboundLocalError: pass bridgeConfig["groups"][group.id_v1].stream["active"] = False for light in group.lights: bridgeConfig["lights"][light().id_v1].state["mode"] = "homeautomation" logging.info("Entertainment service stopped")
def entertainmentService(lights, addresses, groups, host_ip): serverSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) serverSocket.settimeout(3) #Set a packet timeout that we catch later serverSocket.bind(('127.0.0.1', 2101)) frameID = 0 lightStatus = {} syncing = False #Flag to check whether or not we had been syncing when a timeout occurs while True: try: data = serverSocket.recvfrom(106)[0] nativeLights = {} esphomeLights = {} if data[:9].decode('utf-8') == "HueStream": syncing = True #Set sync flag when receiving valid data if data[14] == 0: #rgb colorspace i = 16 while i < len(data): if data[i] == 0: #Type of device 0x00 = Light lightId = data[i+1] * 256 + data[i+2] if lightId != 0: r = int((data[i+3] * 256 + data[i+4]) / 256) g = int((data[i+5] * 256 + data[i+6]) / 256) b = int((data[i+7] * 256 + data[i+8]) / 256) proto = addresses[str(lightId)]["protocol"] if lightId not in lightStatus: lightStatus[lightId] = {"on": False, "bri": 1} if r == 0 and g == 0 and b == 0: lights[str(lightId)]["state"]["on"] = False else: lights[str(lightId)]["state"].update({"on": True, "bri": int((r + g + b) / 3), "xy": convert_rgb_xy(r, g, b), "colormode": "xy"}) if proto in ["native", "native_multi", "native_single"]: if addresses[str(lightId)]["ip"] not in nativeLights: nativeLights[addresses[str(lightId)]["ip"]] = {} nativeLights[addresses[str(lightId)]["ip"]][addresses[str(lightId)]["light_nr"] - 1] = [r, g, b] elif proto == "esphome": if addresses[str(lightId)]["ip"] not in esphomeLights: esphomeLights[addresses[str(lightId)]["ip"]] = {} bri = int(max(r,g,b)) esphomeLights[addresses[str(lightId)]["ip"]]["color"] = [r, g, b, bri] else: if frameID == 24: # => every seconds, increase in case the destination device is overloaded gottaSend = False yee = proto == "yeelight" brABS = abs(int((r + b + g) / 3) - lightStatus[lightId]["bri"]) if r == 0 and g == 0 and b == 0: #Turn off if color is black if lightStatus[lightId]["on"]: sendLightRequest(str(lightId), {"on": False, "transitiontime": 3}, lights, addresses, None, host_ip) lightStatus[lightId]["on"] = False else: if lightStatus[lightId]["on"] == False: #Turn on if color is not black sendLightRequest(str(lightId), {"on": True, "transitiontime": 3}, lights, addresses, None, host_ip) lightStatus[lightId]["on"] = True elif brABS > 50: # to optimize, send brightness only if difference is bigger than this value sendLightRequest(str(lightId), {"bri": int((r + b + g) / 3), "transitiontime": 150 / brABS}, lights, addresses, None, host_ip) lightStatus[lightId]["bri"] = int((r + b + g) / 3) else: gottaSend = True if gottaSend or yee: sendLightRequest(str(lightId), {"xy": convert_rgb_xy(r, g, b), "transitiontime": 3}, lights, addresses, [r, g, b], host_ip) frameID += 1 if frameID == 25: frameID = 0 i = i + 9 elif data[14] == 1: #cie colorspace i = 16 while i < len(data): if data[i] == 0: #Type of device 0x00 = Light lightId = data[i+1] * 256 + data[i+2] if lightId != 0: x = (data[i+3] * 256 + data[i+4]) / 65535 y = (data[i+5] * 256 + data[i+6]) / 65535 bri = int((data[i+7] * 256 + data[i+8]) / 256) if bri == 0: lights[str(lightId)]["state"]["on"] = False else: lights[str(lightId)]["state"].update({"on": True, "bri": bri, "xy": [x,y], "colormode": "xy"}) if addresses[str(lightId)]["protocol"] in ["native", "native_multi", "native_single"]: if addresses[str(lightId)]["ip"] not in nativeLights: nativeLights[addresses[str(lightId)]["ip"]] = {} nativeLights[addresses[str(lightId)]["ip"]][addresses[str(lightId)]["light_nr"] - 1] = convert_xy(x, y, bri) elif addresses[str(lightId)]["protocol"] == "esphome": if addresses[str(lightId)]["ip"] not in esphomeLights: esphomeLights[addresses[str(lightId)]["ip"]] = {} r, g, b = convert_xy(x, y, bri) esphomeLights[addresses[str(lightId)]["ip"]]["color"] = [r, g, b, bri] else: frameID += 1 if frameID == 24 : #24 = every seconds, increase in case the destination device is overloaded sendLightRequest(str(lightId), {"xy": [x,y]}, lights, addresses, None, host_ip) frameID = 0 i = i + 9 if len(nativeLights) != 0: for ip in nativeLights.keys(): udpmsg = bytearray() for light in nativeLights[ip].keys(): udpmsg += bytes([light]) + bytes([nativeLights[ip][light][0]]) + bytes([nativeLights[ip][light][1]]) + bytes([nativeLights[ip][light][2]]) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP sock.sendto(udpmsg, (ip.split(":")[0], 2100)) if len(esphomeLights) != 0: for ip in esphomeLights.keys(): udpmsg = bytearray() udpmsg += bytes([0]) + bytes([esphomeLights[ip]["color"][0]]) + bytes([esphomeLights[ip]["color"][1]]) + bytes([esphomeLights[ip]["color"][2]]) + bytes([esphomeLights[ip]["color"][3]]) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP sock.sendto(udpmsg, (ip.split(":")[0], 2100)) except Exception: #Assuming the only exception is a network timeout, please don't scream at me if syncing: #Reset sync status and kill relay service logging.info("Entertainment Service was syncing and has timed out, stopping server and clearing state") Popen(["killall", "entertain-srv"]) for group in groups.keys(): if "type" in groups[group] and groups[group]["type"] == "Entertainment": groups[group]["stream"].update({"active": False, "owner": None}) syncing = False
def sendLightRequest(light, data, lights, addresses): payload = {} if light in addresses: protocol_name = addresses[light]["protocol"] for protocol in protocols: if "protocols." + protocol_name == protocol.__name__: try: light_state = protocol.set_light(addresses[light], lights[light], data) except Exception as e: lights[light]["state"]["reachable"] = False logging.warning(lights[light]["name"] + " light not reachable: %s", e) return if addresses[light]["protocol"] == "native": #ESP8266 light or strip url = "http://" + addresses[light]["ip"] + "/set?light=" + str(addresses[light]["light_nr"]) method = 'GET' for key, value in data.items(): if key == "xy": url += "&x=" + str(value[0]) + "&y=" + str(value[1]) else: url += "&" + key + "=" + str(value) elif addresses[light]["protocol"] in ["hue","deconz"]: #Original Hue light or Deconz light url = "http://" + addresses[light]["ip"] + "/api/" + addresses[light]["username"] + "/lights/" + addresses[light]["light_id"] + "/state" method = 'PUT' payload.update(data) elif addresses[light]["protocol"] == "domoticz": #Domoticz protocol url = "http://" + addresses[light]["ip"] + "/json.htm?type=command&idx=" + addresses[light]["light_id"] method = 'GET' if "on" in data and not "bri" in data and not "ct" in data and not "xy" in data: for key, value in data.items(): url += "¶m=switchlight" if key == "on": if value: url += "&switchcmd=On" else: url += "&switchcmd=Off" else: url += "¶m=setcolbrightnessvalue" color_data = {} old_light_state = lights[light]["state"] colormode = old_light_state["colormode"] ct = old_light_state["ct"] bri = old_light_state["bri"] xy = old_light_state["xy"] if "bri" in data: bri = data["bri"] if "ct" in data: ct = data["ct"] if "xy" in data: xy = data["xy"] bri = int(bri) color_data["m"] = 1 #0: invalid, 1: white, 2: color temp, 3: rgb, 4: custom if colormode == "ct": color_data["m"] = 2 ct01 = (ct - 153) / (500 - 153) #map color temperature from 153-500 to 0-1 ct255 = ct01 * 255 #map color temperature from 0-1 to 0-255 color_data["t"] = ct255 elif colormode == "xy": color_data["m"] = 3 (color_data["r"], color_data["g"], color_data["b"]) = convert_xy(xy[0], xy[1], 255) url += "&color="+json.dumps(color_data) url += "&brightness=" + str(round(float(bri)/255*100)) urlObj = {} urlObj["url"] = url elif addresses[light]["protocol"] == "jeedom": #Jeedom protocol url = "http://" + addresses[light]["ip"] + "/core/api/jeeApi.php?apikey=" + addresses[light]["light_api"] + "&type=cmd&id=" method = 'GET' for key, value in data.items(): if key == "on": if value: url += addresses[light]["light_on"] else: url += addresses[light]["light_off"] elif key == "bri": url += addresses[light]["light_slider"] + "&slider=" + str(round(float(value)/255*100)) # jeedom range from 0 to 100 (for zwave devices) instead of 0-255 of bridge elif addresses[light]["protocol"] == "milight": #MiLight bulb url = "http://" + addresses[light]["ip"] + "/gateways/" + addresses[light]["device_id"] + "/" + addresses[light]["mode"] + "/" + str(addresses[light]["group"]) method = 'PUT' for key, value in data.items(): if key == "on": payload["status"] = value elif key == "bri": payload["brightness"] = value elif key == "ct": payload["color_temp"] = int(value / 1.6 + 153) elif key == "hue": payload["hue"] = value / 180 elif key == "sat": payload["saturation"] = value * 100 / 255 elif key == "xy": payload["color"] = {} (payload["color"]["r"], payload["color"]["g"], payload["color"]["b"]) = convert_xy(value[0], value[1], lights[light]["state"]["bri"]) logging.info(json.dumps(payload)) elif addresses[light]["protocol"] == "ikea_tradfri": #IKEA Tradfri bulb url = "coaps://" + addresses[light]["ip"] + ":5684/15001/" + str(addresses[light]["device_id"]) for key, value in data.items(): if key == "on": payload["5850"] = int(value) elif key == "transitiontime": payload["5712"] = value elif key == "bri": payload["5851"] = value elif key == "ct": if value < 270: payload["5706"] = "f5faf6" elif value < 385: payload["5706"] = "f1e0b5" else: payload["5706"] = "efd275" elif key == "xy": payload["5709"] = int(value[0] * 65535) payload["5710"] = int(value[1] * 65535) if "hue" in data or "sat" in data: if("hue" in data): hue = data["hue"] else: hue = lights[light]["state"]["hue"] if("sat" in data): sat = data["sat"] else: sat = lights[light]["state"]["sat"] if("bri" in data): bri = data["bri"] else: bri = lights[light]["state"]["bri"] rgbValue = hsv_to_rgb(hue, sat, bri) xyValue = convert_rgb_xy(rgbValue[0], rgbValue[1], rgbValue[2]) payload["5709"] = int(xyValue[0] * 65535) payload["5710"] = int(xyValue[1] * 65535) if "5850" in payload and payload["5850"] == 0: payload.clear() #setting brightnes will turn on the ligh even if there was a request to power off payload["5850"] = 0 elif "5850" in payload and "5851" in payload: #when setting brightness don't send also power on command del payload["5850"] elif addresses[light]["protocol"] == "flex": msg = bytearray() if "on" in data: if data["on"]: msg = bytearray([0x71, 0x23, 0x8a, 0x0f]) else: msg = bytearray([0x71, 0x24, 0x8a, 0x0f]) checksum = sum(msg) & 0xFF msg.append(checksum) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP sock.sendto(msg, (addresses[light]["ip"], 48899)) if ("bri" in data and lights[light]["state"]["colormode"] == "xy") or "xy" in data: logging.info(pretty_json(data)) bri = data["bri"] if "bri" in data else lights[light]["state"]["bri"] xy = data["xy"] if "xy" in data else lights[light]["state"]["xy"] rgb = convert_xy(xy[0], xy[1], bri) msg = bytearray([0x41, rgb[0], rgb[1], rgb[2], 0x00, 0xf0, 0x0f]) checksum = sum(msg) & 0xFF msg.append(checksum) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP sock.sendto(msg, (addresses[light]["ip"], 48899)) elif ("bri" in data and lights[light]["state"]["colormode"] == "ct") or "ct" in data: bri = data["bri"] if "bri" in data else lights[light]["state"]["bri"] msg = bytearray([0x41, 0x00, 0x00, 0x00, bri, 0x0f, 0x0f]) checksum = sum(msg) & 0xFF msg.append(checksum) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP sock.sendto(msg, (addresses[light]["ip"], 48899)) try: if addresses[light]["protocol"] == "ikea_tradfri": if "5712" not in payload: payload["5712"] = 4 #If no transition add one, might also add check to prevent large transitiontimes check_output("./coap-client-linux -m put -u \"" + addresses[light]["identity"] + "\" -k \"" + addresses[light]["preshared_key"] + "\" -e '{ \"3311\": [" + json.dumps(payload) + "] }' \"" + url + "\"", shell=True) elif addresses[light]["protocol"] in ["hue", "deconz"]: color = {} if "xy" in payload: color["xy"] = payload["xy"] del(payload["xy"]) elif "ct" in payload: color["ct"] = payload["ct"] del(payload["ct"]) elif "hue" in payload: color["hue"] = payload["hue"] del(payload["hue"]) elif "sat" in payload: color["sat"] = payload["sat"] del(payload["sat"]) if len(payload) != 0: sendRequest(url, method, json.dumps(payload)) if addresses[light]["protocol"] == "deconz": sleep(0.7) if len(color) != 0: sendRequest(url, method, json.dumps(color)) else: sendRequest(url, method, json.dumps(payload)) except: lights[light]["state"]["reachable"] = False logging.info("request error") else: lights[light]["state"]["reachable"] = True logging.info("LightRequest: " + url)
def set_light(address, light, data, rgb=None): logging.debug("ESPHome: <set_light> invoked! IP=" + address["ip"]) logging.debug(light["modelid"]) logging.debug(data) ct_boost = int(address["ct_boost"]) rgb_boost = int(address["rgb_boost"]) request_data = "" # one breath cycle, temporary for now until breath implemented in esphome firmware if ("alert" in data) and (data['alert'] == "select"): request_data = request_data + "/switch/alert/turn_on" # elif ("alert" in data) and (data['alert'] == "lselect"): #15 second breath cycle # request_data = request_data + "/switch/alert/turn_on" # elif ("alert" in data) and (data['alert'] == "none"): # request_data = request_data + "/switch/alert/turn_off" else: request_data = request_data + getLightType(light, address, data) if "white_led" in request_data: postRequest(address["ip"], "/light/color_led/turn_off") else: postRequest(address["ip"], "/light/white_led/turn_off") if "on" in data: if not (data['on']): request_data = request_data + "/turn_off" else: request_data = request_data + "/turn_on" else: request_data = request_data + "/turn_on" if address["esphome_model"] != "ESPHome-Toggle": if "bri" in data: brightness = int(data['bri']) if address["esphome_model"] == "ESPHome-RGBW": if light["state"]["colormode"] == "ct": brightness = ct_boost + brightness elif light["state"]["colormode"] == "xy": brightness = rgb_boost + brightness elif address["esphome_model"] == "ESPHome-CT": brightness = ct_boost + brightness elif address["esphome_model"] == "ESPHome-RGB": brightness = rgb_boost + brightness elif address["esphome_model"] == "ESPHome-Dimmable": brightness = ct_boost + brightness if brightness > 255: # do not send brightness values over 255 brightness = 255 request_data = addRequest(request_data, "brightness", brightness) if address["esphome_model"] in [ "ESPHome-RGBW", "ESPHome-RGB", "ESPHome-CT" ]: if ("xy" in data) and (address["esphome_model"] in ["ESPHome-RGBW", "ESPHome-RGB"]): if rgb: color = rgbBrightness(rgb, light["state"]["bri"]) else: color = convert_xy(data['xy'][0], data['xy'][1], light["state"]["bri"]) request_data = addRequest(request_data, "r", color[0]) request_data = addRequest(request_data, "g", color[1]) request_data = addRequest(request_data, "b", color[2]) elif "ct" in data and (address["esphome_model"] in ["ESPHome-RGBW", "ESPHome-CT"]): request_data = addRequest(request_data, "color_temp", data['ct']) elif (("hue" in data) or ("sat" in data)) and (address["esphome_model"] in [ "ESPHome-RGBW", "ESPHome-RGB" ]): if (("hue" in data) and ("sat" in data)): hue = data['hue'] sat = data['sat'] elif "hue" in data: hue = data['hue'] sat = light["state"]["sat"] elif "sat" in data: hue = light["state"]["hue"] sat = data['sat'] if "bri" not in data: bri = light["state"]["bri"] else: bri = data['bri'] color = hsv_to_rgb(hue, sat, bri) request_data = addRequest(request_data, "r", color[0]) request_data = addRequest(request_data, "g", color[1]) request_data = addRequest(request_data, "b", color[2]) if "transitiontime" in data: request_data = addRequest(request_data, "transition", data['transitiontime'] / 10) else: # Utilize default interval of 0.4 request_data = addRequest(request_data, "transition", 0.4) postRequest(address["ip"], request_data)
def set_light(address, light, data): logging.debug("ESPHome: <set_light> invoked! IP=" + address["ip"]) logging.debug(light["modelid"]) logging.debug(data) ct_boost = int(address["ct_boost"]) rgb_boost = int(address["rgb_boost"]) request_data = "" if ("alert" in data) and ( data['alert'] == "select" ): #one breath cycle, temporary for now until breath implemented in esphome firmware request_data = request_data + "/switch/alert/turn_on" # elif ("alert" in data) and (data['alert'] == "lselect"): #15 second breath cycle # request_data = request_data + "/switch/alert/turn_on" # elif ("alert" in data) and (data['alert'] == "none"): # request_data = request_data + "/switch/alert/turn_off" else: request_data = request_data + getLightType(light, address, data) if "white_led" in request_data: postRequest(address["ip"], "/light/color_led/turn_off") else: postRequest(address["ip"], "/light/white_led/turn_off") if "on" in data: if not (data['on']): request_data = request_data + "/turn_off" else: request_data = request_data + "/turn_on" else: request_data = request_data + "/turn_on" if address["esphome_model"] is not "ESPHome-Toggle": if "bri" in data: brightness = int(data['bri']) if address["esphome_model"] == "ESPHome-RGBW": if light["state"]["colormode"] == "ct": brightness = ct_boost + brightness elif light["state"]["colormode"] == "xy": brightness = rgb_boost + brightness elif address["esphome_model"] == "ESPHome-CT": brightness = ct_boost + brightness elif address["esphome_model"] == "ESPHome-RGB": brightness = rgb_boost + brightness elif address["esphome_model"] == "ESPHome-Dimmable": brightness = ct_boost + brightness if brightness > 255: # do not send brightness values over 255 brightness = 255 brightness = str(brightness) if ("?" in request_data): request_data = request_data + "&brightness=" + brightness else: request_data = request_data + "?brightness=" + brightness if address["esphome_model"] in [ "ESPHome-RGBW", "ESPHome-RGB", "ESPHome-CT" ]: if ("xy" in data) and (address["esphome_model"] in ["ESPHome-RGBW", "ESPHome-RGB"]): color = convert_xy(data['xy'][0], data['xy'][1], 255) red = str(color[0]) green = str(color[1]) blue = str(color[2]) if ("?" in request_data): request_data = request_data + "&r=" + red + "&g=" + green + "&b=" + blue else: request_data = request_data + "?r=" + red + "&g=" + green + "&b=" + blue elif "ct" in data and (address["esphome_model"] in ["ESPHome-RGBW", "ESPHome-CT"]): if ("?" in request_data): request_data = request_data + "&color_temp=" + str( data['ct']) else: request_data = request_data + "?color_temp=" + str( data['ct']) elif (("hue" in data) or ("sat" in data)) and (address["esphome_model"] in [ "ESPHome-RGBW", "ESPHome-RGB" ]): if (("hue" in data) and ("sat" in data)): hue = data['hue'] sat = data['sat'] elif "hue" in data: hue = data['hue'] sat = light["state"]["sat"] elif "sat" in data: hue = light["state"]["hue"] sat = data['sat'] if "bri" not in data: bri = light["state"]["bri"] else: bri = data['bri'] color = hsv_to_rgb(hue, sat, bri) red = str(color[0]) green = str(color[1]) blue = str(color[2]) if ("?" in request_data): request_data = request_data + "&r=" + red + "&g=" + green + "&b=" + blue else: request_data = request_data + "?r=" + red + "&g=" + green + "&b=" + blue if "transitiontime" in data: if ("?" in request_data): request_data = request_data + "&transition=" + str( int(data['transitiontime'] / 10)) else: request_data = request_data + "?transition=" + str( int(data['transitiontime'] / 10)) postRequest(address["ip"], request_data)
def set_light(address, light, data): logging.debug("ESPHome: <set_light> invoked! IP=" + address["ip"]) logging.debug(light["modelid"]) logging.debug(data) ct_boost = int(address["ct_boost"]) rgb_boost = int(address["rgb_boost"]) request_data = "" #logging.debug("tasmota: key " + key) if address["esphome_model"] == "ESPHome-RGBW": if "ct" in data: postRequest(address["ip"], "/light/color_led/turn_off") if "xy" in data: postRequest(address["ip"], "/light/white_led/turn_off") if ("alert" in data) and (data['alert'] == "select"): request_data = request_data + "/switch/alert/turn_on" else: request_data = request_data + getLightType(light, address, data) try: if not (data['on']): request_data = request_data + "/turn_off" else: request_data = request_data + "/turn_on" if "bri" in data: brightness = int(data['bri']) if address["esphome_model"] == "ESPHome-RGBW": if light["state"]["colormode"] == "ct": brightness = ct_boost + brightness elif light["state"]["colormode"] == "xy": brightness = rgb_boost + brightness elif address["esphome_model"] == "ESPHome-CT": brightness = ct_boost + brightness elif address["esphome_model"] == "ESPHome-RGB": brightness = rgb_boost + brightness elif address["esphome_model"] == "ESPHome-Dimmable": brightness = ct_boost + brightness brightness = str(brightness) if ("?" in request_data): request_data = request_data + "&brightness=" + brightness else: request_data = request_data + "?brightness=" + brightness if address["esphome_model"] in ["ESPHome-RGBW", "ESPHome-CT"]: if "ct" in data: if ("?" in request_data): request_data = request_data + "&color_temp=" + str( data['ct']) else: request_data = request_data + "?color_temp=" + str( data['ct']) if address["esphome_model"] in ["ESPHome-RGBW", "ESPHome-RGB"]: if "xy" in data: color = convert_xy(data['xy'][0], data['xy'][1], 255) red = str(color[0]) green = str(color[1]) blue = str(color[2]) if ("?" in request_data): request_data = request_data + "&r=" + red + "&g=" + green + "&b=" + blue else: request_data = request_data + "?r=" + red + "&g=" + green + "&b=" + blue if "transitiontime" in data: if ("?" in request_data): request_data = request_data + "&transition=" + str( data['transitiontime']) else: request_data = request_data + "?transition=" + str( data['transitiontime']) except: #entertainment mode if address["esphome_model"] == "ESPHome-RGBW": #only for RGBW request_data = request_data + "/turn_on" if "bri" in data: brightness = int(data['bri']) if light["state"]["colormode"] == "ct": brightness = ct_boost + brightness elif light["state"]["colormode"] == "xy": brightness = rgb_boost + brightness brightness = str(brightness) if ("?" in request_data): request_data = request_data + "&brightness=" + brightness else: request_data = request_data + "?brightness=" + brightness if "ct" in data: if ("?" in request_data): request_data = request_data + "&color_temp=" + str( data['ct']) else: request_data = request_data + "?color_temp=" + str( data['ct']) if "xy" in data: color = convert_xy(data['xy'][0], data['xy'][1], 255) red = str(color[0]) green = str(color[1]) blue = str(color[2]) if ("?" in request_data): request_data = request_data + "&r=" + red + "&g=" + green + "&b=" + blue else: request_data = request_data + "?r=" + red + "&g=" + green + "&b=" + blue if "transitiontime" in data: if ("?" in request_data): request_data = request_data + "&transition=" + str( "0.7") #lower transition time for entertainment else: request_data = request_data + "?transition=" + str( "0.7") postRequest(address["ip"], request_data)