def scanDeconz(): deconz_ip = configManager.runtimeConfig.arg["DECONZ"] if not bridge_config["deconz"]["enabled"]: if "username" not in bridge_config["deconz"]: try: registration = json.loads( sendRequest( "http://" + deconz_ip + ":" + str(bridge_config["deconz"]["port"]) + "/api", "POST", "{\"username\": \"283145a4e198cc6535\", \"devicetype\":\"Hue Emulator\"}" )) except: logging.info("registration fail, is the link button pressed?") return if "success" in registration[0]: bridge_config["deconz"]["username"] = registration[0][ "success"]["username"] bridge_config["deconz"]["enabled"] = True if "username" in bridge_config["deconz"]: deconz_config = json.loads( sendRequest( "http://" + deconz_ip + ":" + str(bridge_config["deconz"]["port"]) + "/api/" + bridge_config["deconz"]["username"] + "/config", "GET", "{}")) bridge_config["deconz"]["websocketport"] = deconz_config[ "websocketport"] #lights deconz_lights = json.loads( sendRequest( "http://" + deconz_ip + ":" + str(bridge_config["deconz"]["port"]) + "/api/" + bridge_config["deconz"]["username"] + "/lights", "GET", "{}")) for light in deconz_lights: if light not in bridge_config["deconz"][ "lights"] and "modelid" in deconz_lights[light]: new_light_id = nextFreeId(bridge_config, "lights") logging.info("register new light " + new_light_id) bridge_config["lights"][new_light_id] = deconz_lights[light] bridge_config["lights_address"][new_light_id] = { "username": bridge_config["deconz"]["username"], "light_id": light, "ip": deconz_ip + ":" + str(bridge_config["deconz"]["port"]), "protocol": "deconz" } bridge_config["deconz"]["lights"][light] = { "bridgeid": new_light_id, "modelid": deconz_lights[light]["modelid"], "type": deconz_lights[light]["type"] } #sensors deconz_sensors = json.loads( sendRequest( "http://" + deconz_ip + ":" + str(bridge_config["deconz"]["port"]) + "/api/" + bridge_config["deconz"]["username"] + "/sensors", "GET", "{}")) for sensor in deconz_sensors: if sensor not in bridge_config["deconz"][ "sensors"] and "modelid" in deconz_sensors[sensor]: new_sensor_id = nextFreeId(bridge_config, "sensors") if deconz_sensors[sensor]["modelid"] in [ "TRADFRI remote control", "TRADFRI wireless dimmer" ]: logging.info("register new " + deconz_sensors[sensor]["modelid"]) bridge_config["sensors"][new_sensor_id] = { "config": deconz_sensors[sensor]["config"], "manufacturername": deconz_sensors[sensor]["manufacturername"], "modelid": deconz_sensors[sensor]["modelid"], "name": deconz_sensors[sensor]["name"], "state": deconz_sensors[sensor]["state"], "type": deconz_sensors[sensor]["type"], "uniqueid": deconz_sensors[sensor]["uniqueid"] } if "swversion" in deconz_sensors[sensor]: bridge_config["sensors"][new_sensor_id][ "swversion"] = deconz_sensors[sensor]["swversion"] bridge_config["deconz"]["sensors"][sensor] = { "bridgeid": new_sensor_id, "modelid": deconz_sensors[sensor]["modelid"], "type": deconz_sensors[sensor]["type"] } elif deconz_sensors[sensor][ "modelid"] == "TRADFRI motion sensor": logging.info( "register TRADFRI motion sensor as Philips Motion Sensor" ) newMotionSensorId = addHueMotionSensor( "", deconz_sensors[sensor]["name"]) bridge_config["deconz"]["sensors"][sensor] = { "bridgeid": newMotionSensorId, "triggered": False, "modelid": deconz_sensors[sensor]["modelid"], "type": deconz_sensors[sensor]["type"], "lightsensor": "internal" } elif deconz_sensors[sensor]["modelid"] == "lumi.vibration.aq1": logging.info( "register Xiaomi Vibration sensor as Philips Motion Sensor" ) newMotionSensorId = addHueMotionSensor( "", deconz_sensors[sensor]["name"]) bridge_config["deconz"]["sensors"][sensor] = { "bridgeid": newMotionSensorId, "triggered": False, "modelid": deconz_sensors[sensor]["modelid"], "type": deconz_sensors[sensor]["type"], "lightsensor": "astral" } elif deconz_sensors[sensor][ "modelid"] == "lumi.sensor_motion.aq2": if deconz_sensors[sensor]["type"] == "ZHALightLevel": logging.info("register new Xiaomi light sensor") bridge_config["sensors"][new_sensor_id] = { "name": "Hue ambient light sensor 1", "uniqueid": "00:17:88:01:02:" + deconz_sensors[sensor]["uniqueid"][12:], "type": "ZLLLightLevel", "swversion": "6.1.0.18912", "state": { "dark": True, "daylight": False, "lightlevel": 6000, "lastupdated": "none" }, "manufacturername": "Philips", "config": { "on": False, "battery": 100, "reachable": True, "alert": "none", "tholddark": 21597, "tholdoffset": 7000, "ledindication": False, "usertest": False, "pending": [] }, "modelid": "SML001" } bridge_config["sensors"][nextFreeId( bridge_config, "sensors")] = { "name": "Hue temperature sensor 1", "uniqueid": "00:17:88:01:02:" + deconz_sensors[sensor]["uniqueid"][12:-1] + "2", "type": "ZLLTemperature", "swversion": "6.1.0.18912", "state": { "temperature": None, "lastupdated": "none" }, "manufacturername": "Philips", "config": { "on": False, "battery": 100, "reachable": True, "alert": "none", "ledindication": False, "usertest": False, "pending": [] }, "modelid": "SML001" } bridge_config["deconz"]["sensors"][sensor] = { "bridgeid": new_sensor_id, "modelid": deconz_sensors[sensor]["modelid"], "type": deconz_sensors[sensor]["type"] } elif deconz_sensors[sensor]["type"] == "ZHAPresence": logging.info("register new Xiaomi motion sensor") bridge_config["sensors"][new_sensor_id] = { "name": deconz_sensors[sensor]["name"], "uniqueid": "00:17:88:01:02:" + deconz_sensors[sensor]["uniqueid"][12:], "type": "ZLLPresence", "swversion": "6.1.0.18912", "state": { "lastupdated": "none", "presence": None }, "manufacturername": "Philips", "config": { "on": False, "battery": 100, "reachable": True, "alert": "lselect", "ledindication": False, "usertest": False, "sensitivity": 2, "sensitivitymax": 2, "pending": [] }, "modelid": "SML001" } bridge_config["deconz"]["sensors"][sensor] = { "bridgeid": new_sensor_id, "modelid": deconz_sensors[sensor]["modelid"], "type": deconz_sensors[sensor]["type"] } elif deconz_sensors[sensor]["modelid"] == "lumi.sensor_motion": logging.info( "register Xiaomi Motion sensor w/o light sensor") newMotionSensorId = addHueMotionSensor( "", deconz_sensors[sensor]["name"]) bridge_config["deconz"]["sensors"][sensor] = { "bridgeid": newMotionSensorId, "triggered": False, "modelid": deconz_sensors[sensor]["modelid"], "type": deconz_sensors[sensor]["type"] } else: bridge_config["sensors"][new_sensor_id] = deconz_sensors[ sensor] bridge_config["deconz"]["sensors"][sensor] = { "bridgeid": new_sensor_id, "modelid": deconz_sensors[sensor]["modelid"], "type": deconz_sensors[sensor]["type"] } else: #temporary patch for config compatibility with new release bridge_config["deconz"]["sensors"][sensor][ "modelid"] = deconz_sensors[sensor]["modelid"] bridge_config["deconz"]["sensors"][sensor][ "type"] = deconz_sensors[sensor]["type"] generateDxState() if "websocketport" in bridge_config["deconz"]: logging.info("Starting deconz websocket") Thread(target=websocketClient).start()
def addHueMotionSensor(uniqueid, name="Hue motion sensor"): new_sensor_id = nextFreeId(bridge_config, "sensors") if uniqueid == "": uniqueid = "00:17:88:01:02:" if len(new_sensor_id) == 1: uniqueid += "0" + new_sensor_id else: uniqueid += new_sensor_id bridge_config["sensors"][nextFreeId(bridge_config, "sensors")] = { "name": "Hue temperature sensor 1", "uniqueid": uniqueid + ":d0:5b-02-0402", "type": "ZLLTemperature", "swversion": "6.1.0.18912", "state": { "temperature": None, "lastupdated": "none" }, "manufacturername": "Philips", "config": { "on": False, "battery": 100, "reachable": True, "alert": "none", "ledindication": False, "usertest": False, "pending": [] }, "modelid": "SML001" } motion_sensor = nextFreeId(bridge_config, "sensors") bridge_config["sensors"][motion_sensor] = { "name": name, "uniqueid": uniqueid + ":d0:5b-02-0406", "type": "ZLLPresence", "swversion": "6.1.0.18912", "state": { "lastupdated": "none", "presence": None }, "manufacturername": "Philips", "config": { "on": False, "battery": 100, "reachable": True, "alert": "lselect", "ledindication": False, "usertest": False, "sensitivity": 2, "sensitivitymax": 2, "pending": [] }, "modelid": "SML001" } bridge_config["sensors"][nextFreeId(bridge_config, "sensors")] = { "name": "Hue ambient light sensor", "uniqueid": uniqueid + ":d0:5b-02-0400", "type": "ZLLLightLevel", "swversion": "6.1.0.18912", "state": { "dark": True, "daylight": False, "lightlevel": 6000, "lastupdated": "none" }, "manufacturername": "Philips", "config": { "on": False, "battery": 100, "reachable": True, "alert": "none", "tholddark": 21597, "tholdoffset": 7000, "ledindication": False, "usertest": False, "pending": [] }, "modelid": "SML001" } return (motion_sensor)
def discover(bridge_config, new_lights): logging.debug("ESPHome: <discover> invoked!") device_ips = check_output("nmap " + getIpAddress() + "/24 -p80 --open -n | grep report | cut -d ' ' -f5", shell=True).decode('utf-8').rstrip("\n").split("\n") del device_ips[-1] # delete last empty element in list for ip in device_ips: try: logging.debug("ESPHome: probing ip " + ip) response = requests.get( "http://" + ip + "/text_sensor/light_id", timeout=3) device = json.loads(response.text)[ 'state'].split(';') # get device data mac = device[1] device_name = device[2] ct_boost = device[3] rgb_boost = device[4] if response.status_code == 200 and device[0] == "esphome_diyhue_light": logging.debug("ESPHome: Found " + device_name + " at ip " + ip) white_response = requests.get( "http://" + ip + "/light/white_led", timeout=3) color_response = requests.get( "http://" + ip + "/light/color_led", timeout=3) dim_response = requests.get( "http://" + ip + "/light/dimmable_led", timeout=3) toggle_response = requests.get( "http://" + ip + "/light/toggle_led", timeout=3) if (white_response.status_code != 200 and color_response.status_code != 200 and dim_response != 200 and toggle_response != 200): logging.debug( "ESPHome: Device has improper configuration! Exiting.") raise elif (white_response.status_code == 200 and color_response.status_code == 200): logging.debug("ESPHome: " + device_name + " is a RGBW ESPHome device") white_device_data = json.loads(white_response.text) color_device_data = json.loads(color_response.text) properties = {"rgb": True, "ct": True, "ip": ip, "name": device_name, "id": mac, "mac": mac, "ct_boost": ct_boost, "rgb_boost": rgb_boost} esphome_model = "ESPHome-RGBW" modelid = "LCT015" elif (white_response.status_code == 200): logging.debug("ESPHome: " + device_name + " is a CT ESPHome device") white_device_data = json.loads(white_response.text) properties = {"rgb": False, "ct": True, "ip": ip, "name": device_name, "id": mac, "mac": mac, "ct_boost": ct_boost, "rgb_boost": rgb_boost} esphome_model = "ESPHome-CT" modelid = "LWB010" elif (color_response.status_code == 200): logging.debug("ESPHome: " + device_name + " is a RGB ESPHome device") color_device_data = json.loads(color_response.text) properties = {"rgb": True, "ct": False, "ip": ip, "name": device_name, "id": mac, "mac": mac, "ct_boost": ct_boost, "rgb_boost": rgb_boost} esphome_model = "ESPHome-RGB" modelid = "ESPHome-RGB" elif (dim_response.status_code == 200): logging.debug("ESPHome: " + device_name + " is a Dimmable ESPHome device") dim_device_data = json.loads(dim_response.text) properties = {"rgb": False, "ct": False, "ip": ip, "name": device_name, "id": mac, "mac": mac, "ct_boost": ct_boost, "rgb_boost": rgb_boost} esphome_model = "ESPHome-Dimmable" modelid = "ESPHome-Dimmable" elif (toggle_response.status_code == 200): logging.debug("ESPHome: " + device_name + " is a Toggle ESPHome device") toggle_device_data = json.loads(toggle_response.text) properties = {"rgb": False, "ct": False, "ip": ip, "name": device_name, "id": mac, "mac": mac, "ct_boost": ct_boost, "rgb_boost": rgb_boost} esphome_model = "ESPHome-Toggle" modelid = "ESPHome-Toggle" device_exist = False for light in bridge_config["lights_address"].keys(): if bridge_config["lights_address"][light]["protocol"] == "esphome" and bridge_config["lights_address"][light]["id"].split('.')[0] == properties["id"].split('.')[0]: device_exist = True bridge_config["lights_address"][light]["ip"] = properties["ip"] bridge_config["lights_address"][light]["ct_boost"] = properties["ct_boost"] bridge_config["lights_address"][light]["rgb_boost"] = properties["rgb_boost"] logging.debug( "ESPHome: light id " + properties["id"] + " already exists, updating device data...") break if (not device_exist): light_name = "ESPHome id " + \ properties["id"][-8:] if properties["name"] == "" else properties["name"] logging.debug("ESPHome: Adding ESPHome " + properties["id"]) new_light_id = nextFreeId(bridge_config, "lights") bridge_config["lights"][new_light_id] = {} bridge_config["lights"][new_light_id]["state"] = light_types[modelid]["state"] bridge_config["lights"][new_light_id]["type"] = light_types[modelid]["type"] bridge_config["lights"][new_light_id]["name"] = light_name bridge_config["lights"][new_light_id]["modelid"] = modelid bridge_config["lights"][new_light_id]["manufacturername"] = light_types[modelid]["manufacturername"] bridge_config["lights"][new_light_id]["swversion"] = light_types[modelid]["swversion"] bridge_config["lights"][new_light_id]["config"] = light_types[modelid]["config"] bridge_config["lights"][new_light_id]["uniqueid"] = mac if modelid == "LCT015": bridge_config["lights"][new_light_id]["capabilities"] = light_types[modelid]["capabilities"] bridge_config["lights"][new_light_id]["streaming"] = light_types[modelid]["streaming"] #new_lights.update({new_light_id: {"name": light_name}}) bridge_config["lights_address"][new_light_id] = {} bridge_config["lights_address"][new_light_id]["ip"] = properties["ip"] bridge_config["lights_address"][new_light_id]["id"] = properties["id"] bridge_config["lights_address"][new_light_id]["protocol"] = "esphome" bridge_config["lights_address"][new_light_id]["rgb_boost"] = rgb_boost bridge_config["lights_address"][new_light_id]["ct_boost"] = ct_boost bridge_config["lights_address"][new_light_id]["esphome_model"] = esphome_model except Exception as e: logging.debug("ESPHome: ip " + ip + " is unknown device, " + str(e))
def discover(bridge_config, new_lights): logging.debug("tasmota: <discover> invoked!") device_ips = check_output( "nmap " + getIpAddress() + "/24 -p80 --open -n | grep report | cut -d ' ' -f5", shell=True).decode('utf-8').rstrip("\n").split("\n") del device_ips[-1] #delete last empty element in list for ip in device_ips: try: logging.debug("tasmota: probing ip " + ip) response = requests.get("http://" + ip + "/cm?cmnd=Status%200", timeout=3) if response.status_code == 200: device_data = json.loads(response.text) #logging.debug(pretty_json(device_data)) if ("StatusSTS" in device_data): logging.debug("tasmota: " + ip + " is a Tasmota device ") logging.debug("tasmota: Hostname: " + device_data["StatusNET"]["Hostname"]) logging.debug("tasmota: Mac: " + device_data["StatusNET"]["Mac"]) properties = { "rgb": True, "ct": False, "ip": ip, "name": device_data["StatusNET"]["Hostname"], "id": device_data["StatusNET"]["Mac"], "mac": device_data["StatusNET"]["Mac"] } device_exist = False for light in bridge_config["lights_address"].keys(): if bridge_config["lights_address"][light][ "protocol"] == "tasmota" and bridge_config[ "lights_address"][light][ "id"] == properties["id"]: device_exist = True bridge_config["lights_address"][light][ "ip"] = properties["ip"] logging.debug("tasmota: light id " + properties["id"] + " already exist, updating ip...") break if (not device_exist): light_name = "Tasmota id " + properties["id"][ -8:] if properties["name"] == "" else properties[ "name"] logging.debug("tasmota: Add Tasmota: " + properties["id"]) modelid = "Tasmota" new_light_id = nextFreeId(bridge_config, "lights") bridge_config["lights"][new_light_id] = { "state": light_types[modelid]["state"], "type": light_types[modelid]["type"], "name": light_name, "uniqueid": "4a:e0:ad:7f:cf:" + str(random.randrange(0, 99)) + "-1", "modelid": modelid, "manufacturername": "Tasmota", "swversion": light_types[modelid]["swversion"] } new_lights.update({new_light_id: {"name": light_name}}) bridge_config["lights_address"][new_light_id] = { "ip": properties["ip"], "id": properties["id"], "protocol": "tasmota" } except Exception as e: logging.debug("tasmota: ip " + ip + " is unknow device, " + str(e))