diff --git a/BridgeEmulator/HueObjects/__init__.py b/BridgeEmulator/HueObjects/__init__.py index 1821256e1..acfd13645 100644 --- a/BridgeEmulator/HueObjects/__init__.py +++ b/BridgeEmulator/HueObjects/__init__.py @@ -1871,6 +1871,68 @@ def getDevice(self): "rtype": "zigbee_connectivity" }] result["type"] = "device" + elif self.modelid == "RDM002" and self.type != "ZLLRelativeRotary": + result = {"id": self.id_v2, "id_v1": "/sensors/" + self.id_v1, "type": "device"} + result["product_data"] = {"model_id": self.modelid, + "manufacturer_name": "Signify Netherlands B.V.", + "product_name": "Hue tap dial switch", + "product_archetype": "unknown_archetype", + "certified": True, + "software_version": "2.59.25", + "hardware_platform_type": "100b-119" + } + result["metadata"] = { + "archetype": "unknown_archetype", + "name": self.name + } + result["services"] = [{ + "rid": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'button1')), + "rtype": "button" + }, { + "rid": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'button2')), + "rtype": "button" + }, { + "rid": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'button3')), + "rtype": "button" + }, { + "rid": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'button4')), + "rtype": "button" + }, { + "rid": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'device_power')), + "rtype": "device_power" + }, { + "rid": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'zigbee_connectivity')), + "rtype": "zigbee_connectivity" + }] + result["type"] = "device" + elif self.modelid == "RDM002" and self.type == "ZLLRelativeRotary": + result = {"id": self.id_v2, "id_v1": "/sensors/" + self.id_v1, "type": "device"} + result["product_data"] = {"model_id": self.modelid, + "manufacturer_name": "Signify Netherlands B.V.", + "product_name": "Hue tap dial switch", + "product_archetype": "unknown_archetype", + "certified": True, + "software_version": "2.59.25", + "hardware_platform_type": "100b-119" + } + result["metadata"] = { + "archetype": "unknown_archetype", + "name": self.name + } + result["services"] = [{ + "rid": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'button3')), + "rtype": "button" + }, { + "rid": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'button4')), + "rtype": "button" + }, { + "rid": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'device_power')), + "rtype": "device_power" + }, { + "rid": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'zigbee_connectivity')), + "rtype": "zigbee_connectivity" + }] + result["type"] = "device" return result def getMotion(self): @@ -1910,9 +1972,10 @@ def getZigBee(self): result["mac_address"] = self.uniqueid[:23] result["status"] = "connected" return result + def getButtons(self): result = [] - if self.modelid == "RWL022" or self.modelid == "RWL021" or self.modelid == "RWL020": + if self.modelid == "RWL022" or self.modelid == "RWL021" or self.modelid == "RWL020" or self.modelid == "RDM002" and self.type != "ZLLRelativeRotary": for button in range(4): result.append({ "id": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'button' + str(button + 1))), @@ -1927,6 +1990,20 @@ def getButtons(self): "type": "button" }) return result + + def getRotary(self): + result = [] + if self.modelid == "RDM002" and self.type == "ZLLRelativeRotary": + result.append({ + "id": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'relative_rotary')), + "id_v1": "/sensors/" + self.id_v1, + "owner": { + "rid": self.id_v2, + "rtype": "device" + }, + "type": "relative_rotary" + }) + return result def getDevicePower(self): result = None diff --git a/BridgeEmulator/configManager/configHandler.py b/BridgeEmulator/configManager/configHandler.py index 22c2d8717..f6bccab37 100644 --- a/BridgeEmulator/configManager/configHandler.py +++ b/BridgeEmulator/configManager/configHandler.py @@ -92,7 +92,7 @@ def load_config(self): if int(config["swversion"]) < 1958077010: config["swversion"] = "1962154010" if float(config["apiversion"][:3]) < 1.56: - config["apiversion"] = "1.62_SR4" + config["apiversion"] = "1.62.0" self.yaml_config["config"] = config else: @@ -105,7 +105,7 @@ def load_config(self): "alarm":{"enabled": False,"lasttriggered": 0}, "port":{"enabled": False,"ports": [80]}, "apiUsers":{}, - "apiversion":"1.62_SR4", + "apiversion":"1.62.0", "name":"DiyHue Bridge", "netmask":"255.255.255.0", "swversion":"1962154010", diff --git a/BridgeEmulator/flaskUI/espDevices.py b/BridgeEmulator/flaskUI/espDevices.py index 9ab32e0e8..4f28adc0f 100644 --- a/BridgeEmulator/flaskUI/espDevices.py +++ b/BridgeEmulator/flaskUI/espDevices.py @@ -5,7 +5,7 @@ from flask_restful import Resource from flask import request from functions.rules import rulesProcessor -from sensors.discover import addHueMotionSensor, addHueSwitch +from sensors.discover import addHueMotionSensor, addHueSwitch, addHueRotarySwitch from datetime import datetime from threading import Thread from time import sleep @@ -49,6 +49,9 @@ def get(self): sensor = addHueMotionSensor("Hue Motion Sensor", "native", { "mac": mac, "threaded": False}) return {"success": "device registered"} + elif args["devicetype"] == "ZLLRelativeRotary": + sensor = addHueRotarySwitch({"mac": mac}) + return {"success": "device registered"} else: return {"fail": "unknown device"} else: @@ -92,6 +95,14 @@ def get(self): obj.dxState["buttonevent"] = current_time if "battery" in args: obj.config["battery"] = int(args["battery"]) + elif obj.type == "ZLLRelativeRotary": + if "rotary" in args: + obj.state["rotaryevent"] = int(args["rotary"]) + obj.state["expectedrotation"] = int(args["rotation"]) + obj.state["expectedeventduration"] = int(args["duration"]) + obj.dxState["rotaryevent"] = current_time + if "battery" in args: + obj.config["battery"] = int(args["battery"]) else: result = {"fail": "unknown device"} obj.dxState["lastupdated"] = current_time diff --git a/BridgeEmulator/flaskUI/v2restapi.py b/BridgeEmulator/flaskUI/v2restapi.py index 647d41b1c..b1975d9b4 100644 --- a/BridgeEmulator/flaskUI/v2restapi.py +++ b/BridgeEmulator/flaskUI/v2restapi.py @@ -276,6 +276,11 @@ def get(self): power = sensor.getDevicePower() if power != None: data.append(power) + for key, sensor in bridgeConfig["sensors"].items(): + rotarys = sensor.getRotary() + if len(rotarys) != 0: + for rotary in rotarys: + data.append(rotary) return {"errors": [], "data": data} @@ -364,6 +369,12 @@ def get(self, resource): if len(buttons) != 0: for button in buttons: response["data"].append(button) + elif resource == "relative_rotary": + for key, sensor in bridgeConfig["sensors"].items(): + rotarys = sensor.getRotary() + if len(rotarys) != 0: + for rotary in rotarys: + response["data"].append(rotary) else: response["errors"].append({"description": "Not Found"}) del response["data"] diff --git a/BridgeEmulator/functions/core.py b/BridgeEmulator/functions/core.py index 29ec9aa00..5f9760e7c 100644 --- a/BridgeEmulator/functions/core.py +++ b/BridgeEmulator/functions/core.py @@ -57,7 +57,7 @@ def staticConfig(): }, "checkforupdate": False, "lastchange": "2020-12-13T10:30:15", - "state": "unknown" + "state": "noupdates" }, "zigbeechannel": 25 } diff --git a/BridgeEmulator/sensors/discover.py b/BridgeEmulator/sensors/discover.py index ffd59f9d0..51f715521 100644 --- a/BridgeEmulator/sensors/discover.py +++ b/BridgeEmulator/sensors/discover.py @@ -38,3 +38,14 @@ def addHueSwitch(uniqueid, sensorsType): deviceData = {"id_v1": new_sensor_id, "state": {"buttonevent": 0, "lastupdated": "none"}, "config": {"on": True, "battery": 100, "reachable": True}, "name": "Dimmer Switch" if sensorsType == "ZLLSwitch" else "Tap Switch", "type": sensorsType, "modelid": "RWL021" if sensorsType == "ZLLSwitch" else "ZGPSWITCH", "manufacturername": "Philips", "swversion": "5.45.1.17846" if sensorsType == "ZLLSwitch" else "", "uniqueid": uniqueid} bridgeConfig["sensors"][new_sensor_id] = HueObjects.Sensor(deviceData) return(bridgeConfig["sensors"][new_sensor_id]) + +def addHueRotarySwitch(protocol_cfg): + uniqueid = generate_unique_id() + button_id = nextFreeId(bridgeConfig, "sensors") + button = {"name": "Hue tap dial switch", "id_v1": button_id, "modelid": "RDM002", "type": "ZLLSwitch", "protocol_cfg": protocol_cfg, "uniqueid": uniqueid + "-02-0406"} + bridgeConfig["sensors"][button_id] = HueObjects.Sensor(button) + + rotary_id = nextFreeId(bridgeConfig, "sensors") + rotary = {"name": "Hue tap dial switch", "id_v1": rotary_id, "modelid": "RDM002", "type": "ZLLRelativeRotary", "protocol_cfg": protocol_cfg, "uniqueid": uniqueid + "-02-0406"} + bridgeConfig["sensors"][rotary_id] = HueObjects.Sensor(rotary) + return diff --git a/BridgeEmulator/sensors/sensor_types.py b/BridgeEmulator/sensors/sensor_types.py index a73cd9756..112bf9e53 100644 --- a/BridgeEmulator/sensors/sensor_types.py +++ b/BridgeEmulator/sensors/sensor_types.py @@ -15,8 +15,9 @@ sensorTypes["TRADFRI on/off switch"] = {"ZHASwitch": {"state": {"buttonevent": 1002, "lastupdated": "none"}, "config": {"alert": "none", "battery": 90, "on": True, "reachable": True}, "static": {"swversion": "2.2.008", "manufacturername": "IKEA of Sweden"}}} sensorTypes["TRADFRI wireless dimmer"] = {"ZHASwitch": {"state": {"buttonevent": 1002, "lastupdated": "none"}, "config": {"alert": "none", "battery": 90, "on": True, "reachable": True}, "static": {"swversion": "1.2.248", "manufacturername": "IKEA of Sweden"}}} # Fix Deconz types -sensorTypes["RWL020"]["ZHASwitch"] = sensorTypes["RWL020"]["ZLLSwitch"] -sensorTypes["RWL022"]["ZHASwitch"] = sensorTypes["RWL022"]["ZLLSwitch"] -sensorTypes["SML001"]["ZHATemperature"] = sensorTypes["SML001"]["ZLLTemperature"] -sensorTypes["SML001"]["ZHAPresence"] = sensorTypes["SML001"]["ZLLPresence"] -sensorTypes["SML001"]["ZHALightLevel"] = sensorTypes["SML001"]["ZLLLightLevel"] +# not used anymore? +#sensorTypes["RWL020"]["ZHASwitch"] = sensorTypes["RWL020"]["ZLLSwitch"] +#sensorTypes["RWL022"]["ZHASwitch"] = sensorTypes["RWL022"]["ZLLSwitch"] +#sensorTypes["SML001"]["ZHATemperature"] = sensorTypes["SML001"]["ZLLTemperature"] +#sensorTypes["SML001"]["ZHAPresence"] = sensorTypes["SML001"]["ZLLPresence"] +#sensorTypes["SML001"]["ZHALightLevel"] = sensorTypes["SML001"]["ZLLLightLevel"] diff --git a/BridgeEmulator/services/mqtt.py b/BridgeEmulator/services/mqtt.py index 83a06fb42..59f9b0f30 100644 --- a/BridgeEmulator/services/mqtt.py +++ b/BridgeEmulator/services/mqtt.py @@ -157,6 +157,24 @@ "dial_rotate_right_fast": {"rotaryevent": 2}, } }, + "PTM 215Z": { + "dataConversion": { + "rootKey": "action", + "press_1": {"buttonevent": 1000}, + "release_1": {"buttonevent": 1002}, + "press_2": {"buttonevent": 2000}, + "release_2": {"buttonevent": 2002}, + "press_3": {"buttonevent": 3000}, + "release_3": {"buttonevent": 3002}, + "press_4": {"buttonevent": 4000}, + "release_4": {"buttonevent": 4002}, + "press_1_and_3": {"buttonevent": 1010}, + "release_1_and_3": {"buttonevent": 1003}, + "press_2_and_4": {"buttonevent": 2010}, + "release_2_and_4": {"buttonevent": 2003}, + "press_energy_bar": {"buttonevent": 5000}, + } + }, } @@ -283,11 +301,12 @@ def on_message(client, userdata, msg): if getObject(key["friendly_name"]) == False: ## Add the new sensor logging.info("MQTT: Add new mqtt sensor " + key["friendly_name"]) if key["model_id"] in standardSensors: - new_sensor_id = nextFreeId(bridgeConfig, "sensors") - sensor_type = list(sensorTypes[key["model_id"]].keys())[0] - uniqueid = convertHexToMac(key["ieee_address"]) + "-01-1000" - sensorData = {"name": key["friendly_name"], "protocol": "mqtt", "modelid": key["model_id"], "type": sensor_type, "uniqueid": uniqueid,"protocol_cfg": {"friendly_name": key["friendly_name"], "ieeeAddr": key["ieee_address"], "model": key["definition"]["model"]}, "id_v1": new_sensor_id} - bridgeConfig["sensors"][new_sensor_id] = HueObjects.Sensor(sensorData) + for sensor in sensorTypes[key["model_id"]].keys(): + new_sensor_id = nextFreeId(bridgeConfig, "sensors") + sensor_type = sensorTypes[key["model_id"]][sensor] + uniqueid = convertHexToMac(key["ieee_address"]) + "-01-1000" + sensorData = {"name": key["friendly_name"], "protocol": "mqtt", "modelid": key["model_id"], "type": sensor_type, "uniqueid": uniqueid,"protocol_cfg": {"friendly_name": key["friendly_name"], "ieeeAddr": key["ieee_address"], "model": key["definition"]["model"]}, "id_v1": new_sensor_id} + bridgeConfig["sensors"][new_sensor_id] = HueObjects.Sensor(sensorData) ### TRADFRI Motion Sensor, Xiaomi motion sensor, etc elif key["model_id"] in motionSensors: logging.info("MQTT: add new motion sensor " + key["model_id"]) diff --git a/BridgeEmulator/services/updateManager.py b/BridgeEmulator/services/updateManager.py index fcf5b37aa..cfb6478f1 100644 --- a/BridgeEmulator/services/updateManager.py +++ b/BridgeEmulator/services/updateManager.py @@ -112,4 +112,5 @@ def startupCheck(): bridgeConfig["config"]["swupdate2"]["install"] = False bridgeConfig["config"]["swupdate2"]["lastchange"] = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S") bridgeConfig["config"]["swupdate2"]["bridge"]["lastinstall"] = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S") + versionCheck() githubCheck()