Skip to content

Commit

Permalink
add better support for motion sensors in V2 api
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusmotea committed Aug 22, 2022
1 parent 9ac772f commit f2e3841
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 44 deletions.
129 changes: 87 additions & 42 deletions BridgeEmulator/HueObjects/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

eventstream = []


def v1StateToV2(v1State):
v2State = {}
if "on" in v1State:
Expand All @@ -24,9 +25,11 @@ def v1StateToV2(v1State):
if "ct" in v1State:
v2State["color_temperature"] = {"mirek": v1State["ct"]}
if "xy" in v1State:
v2State["color"] = {"xy": {"x": v1State["xy"][0], "y": v1State["xy"][1]}}
v2State["color"] = {
"xy": {"x": v1State["xy"][0], "y": v1State["xy"][1]}}
return v2State


def v2StateToV1(v2State):
v1State = {}
if "dimming" in v2State:
Expand All @@ -45,6 +48,7 @@ def v2StateToV1(v2State):
v1State["transitiontime"] = v2State["transitiontime"]
return v1State


def genV2Uuid():
return str(uuid.uuid4())

Expand Down Expand Up @@ -404,16 +408,14 @@ def setV1State(self, state, advertise=True):
v2State = v1StateToV2(state)
self.genStreamEvent(v2State)



def setV2State(self, state):
v1State = v2StateToV1(state)
if "effects" in state:
v1State["effect"] = state["effects"]["effect"]
self.effect = v1State["effect"]
if "dynamics" in state and "speed" in state["dynamics"]:
self.dynamics["speed"] = state["dynamics"]["speed"]
self.setV1State(v1State,advertise=False)
self.setV1State(v1State, advertise=False)
self.genStreamEvent(state)

def genStreamEvent(self, v2State):
Expand All @@ -424,7 +426,8 @@ def genStreamEvent(self, v2State):
}
streamMessage["id_v1"] = "/lights/" + self.id_v1
streamMessage["data"][0].update(v2State)
streamMessage["data"][0].update({"owner": {"rid": self.getDevice()["id"],"rtype": "device"}})
streamMessage["data"][0].update(
{"owner": {"rid": self.getDevice()["id"], "rtype": "device"}})
eventstream.append(streamMessage)

def getDevice(self):
Expand Down Expand Up @@ -859,16 +862,21 @@ def getV2Api(self):
]
}
if light().modelid in ["LCX001", "LCX002", "LCX003"]:
channel["position"] = {"x": gradienStripPositions[x]["x"], "y": gradienStripPositions[x]["y"], "z": gradienStripPositions[x]["z"]}
channel["position"] = {"x": gradienStripPositions[x]["x"],
"y": gradienStripPositions[x]["y"], "z": gradienStripPositions[x]["z"]}
elif light().modelid in ["915005987201", "LCX004"]:
if x == 0:
channel["position"] = {"x": self.locations[light()][0]["x"], "y": self.locations[light()][0]["y"], "z": self.locations[light()][0]["z"]}
channel["position"] = {"x": self.locations[light(
)][0]["x"], "y": self.locations[light()][0]["y"], "z": self.locations[light()][0]["z"]}
elif x == 2:
channel["position"] = {"x": self.locations[light()][1]["x"], "y": self.locations[light()][1]["y"], "z": self.locations[light()][1]["z"]}
channel["position"] = {"x": self.locations[light(
)][1]["x"], "y": self.locations[light()][1]["y"], "z": self.locations[light()][1]["z"]}
else:
channel["position"] = {"x": (self.locations[light()][0]["x"] + self.locations[light()][1]["x"]) / 2, "y": (self.locations[light()][0]["y"] + self.locations[light()][1]["y"]) / 2, "z": (self.locations[light()][0]["z"] + self.locations[light()][1]["z"]) / 2}
channel["position"] = {"x": (self.locations[light()][0]["x"] + self.locations[light()][1]["x"]) / 2, "y": (self.locations[light(
)][0]["y"] + self.locations[light()][1]["y"]) / 2, "z": (self.locations[light()][0]["z"] + self.locations[light()][1]["z"]) / 2}
else:
channel["position"] = {"x": self.locations[light()][0]["x"], "y": self.locations[light()][0]["y"], "z": self.locations[light()][0]["z"]}
channel["position"] = {"x": self.locations[light(
)][0]["x"], "y": self.locations[light()][0]["y"], "z": self.locations[light()][0]["z"]}

result["channels"].append(channel)
channel_id += 1
Expand All @@ -880,8 +888,6 @@ def setV2Action(self, state):
setGroupAction(self, v1State)
self.genStreamEvent(state)



def setV1Action(self, state, scene=None):
setGroupAction(self, state, scene)
v2State = v1StateToV2(state)
Expand Down Expand Up @@ -1023,13 +1029,13 @@ def update_attr(self, newdata):

streamMessage = {"creationtime": datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ"),
"data": [self.getV2Room() if self.type == "Room" else self.getV2Zone()],
"owner":{
"rid":self.getV2Room()["id"] if self.type == "Room" else self.getV2Zone()["id"],
"rtype": "room" if self.type == "Room" else "zone"
},
"id": str(uuid.uuid4()),
"type": "update"
}
"owner": {
"rid": self.getV2Room()["id"] if self.type == "Room" else self.getV2Zone()["id"],
"rtype": "room" if self.type == "Room" else "zone"
},
"id": str(uuid.uuid4()),
"type": "update"
}
eventstream.append(streamMessage)

def update_state(self):
Expand Down Expand Up @@ -1067,11 +1073,11 @@ def genStreamEvent(self, v2State):
eventstream.append(streamMessage)
streamMessage = {"creationtime": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
"data": [{"id": self.id_v2, "type": "grouped_light",
"owner":{
"rid":self.getV2Room()["id"] if self.type == "Room" else self.getV2Zone()["id"],
"rtype": "room" if self.type == "Room" else "zone"
}
}],
"owner": {
"rid": self.getV2Room()["id"] if self.type == "Room" else self.getV2Zone()["id"],
"rtype": "room" if self.type == "Room" else "zone"
}
}],
"id": str(uuid.uuid4()),
"type": "update"
}
Expand Down Expand Up @@ -1715,8 +1721,8 @@ def getDevice(self):
"rtype": "motion"
},
{
"rid": str(uuid.uuid5(uuid.NAMESPACE_URL, self.id_v2 + 'battery')),
"rtype": "battery"
"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')),
Expand All @@ -1733,6 +1739,25 @@ def getDevice(self):
]
return result

def getMotion(self):
result = None
if self.modelid == "SML001" and self.type == "ZLLPresence":
result = {"enabled": self.config["on"],
"id": str(uuid.uuid5(
uuid.NAMESPACE_URL, self.id_v2 + 'motion')),
"id_v1": "/sensors/" + self.id_v1,
"motion": {
"motion": True if self.state["presence"] else False,
"motion_valid": True
},
"owner": {
"rid": str(uuid.uuid5(
uuid.NAMESPACE_URL, self.id_v2 + 'device')),
"rtype": "device"
},
"type": "motion"}
return result

def getZigBee(self):
result = None
if self.modelid == "SML001" and self.type == "ZLLPresence":
Expand All @@ -1745,33 +1770,53 @@ def getZigBee(self):
result["type"] = "zigbee_connectivity"
return result

def getDevicePower(self):
result = False
if "battery" in self.config:
result = {
"id": str(uuid.uuid5(
uuid.NAMESPACE_URL, self.id_v2 + 'device_power')),
"id_v1": "/sensors/" + self.id_v1,
"owner": {
"rid": str(uuid.uuid5(
uuid.NAMESPACE_URL, self.id_v2 + 'device')),
"rtype": "device"
},
"power_state": {
"battery_level": self.config["battery"],
"battery_state": "normal"
},
"type": "device_power"
}
return result

def update_attr(self, newdata):
if self.id_v1 == "1" and "config" in newdata: # manage daylight sensor
if "long" in newdata["config"] and "lat" in newdata["config"]:
self.config["configured"] = True
self.protocol_cfg = {"long": float(
self.config["configured"]=True
self.protocol_cfg={"long": float(
newdata["config"]["long"][:-1]), "lat": float(newdata["config"]["lat"][:-1])}
return
for key, value in newdata.items():
updateAttribute = getattr(self, key)
updateAttribute=getattr(self, key)
if isinstance(updateAttribute, dict):
updateAttribute.update(value)
setattr(self, key, updateAttribute)
else:
setattr(self, key, value)

def save(self):
result = {}
result["name"] = self.name
result["id_v1"] = self.id_v1
result["id_v2"] = self.id_v2
result["state"] = self.state
result["config"] = self.config
result["type"] = self.type
result["modelid"] = self.modelid
result["manufacturername"] = self.manufacturername
result["uniqueid"] = self.uniqueid
result["swversion"] = self.swversion
result["protocol"] = self.protocol
result["protocol_cfg"] = self.protocol_cfg
result={}
result["name"]=self.name
result["id_v1"]=self.id_v1
result["id_v2"]=self.id_v2
result["state"]=self.state
result["config"]=self.config
result["type"]=self.type
result["modelid"]=self.modelid
result["manufacturername"]=self.manufacturername
result["uniqueid"]=self.uniqueid
result["swversion"]=self.swversion
result["protocol"]=self.protocol
result["protocol_cfg"]=self.protocol_cfg
return result
23 changes: 21 additions & 2 deletions BridgeEmulator/flaskUI/v2restapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
bridgeConfig = configManager.bridgeConfig.yaml_config

v2Resources = {"light": {}, "scene": {}, "grouped_light": {}, "room": {}, "zone": {
}, "entertainment": {}, "entertainment_configuration": {}, "zigbee_connectivity": {}, "device": {}}
}, "entertainment": {}, "entertainment_configuration": {}, "zigbee_connectivity": {}, "device": {}, "device_power": {}}


def getObject(element, v2uuid):
Expand Down Expand Up @@ -252,6 +252,15 @@ def get(self):
data.append(v2GeofenceClient())
for script in behaviorScripts():
data.append(script)
for key, sensor in bridgeConfig["sensors"].items():
motion = sensor.getMotion()
if motion != None:
data.append(motion)
#for key, sensor in bridgeConfig["sensors"].items():
# power = sensor.getDevicePower()
# if power != None:
# data.append(power)

return {"errors": [], "data": data}


Expand Down Expand Up @@ -322,7 +331,15 @@ def get(self, resource):
for script in behaviorScripts():
response["data"].append(script)
elif resource == "motion":
response["data"] = []
for key, sensor in bridgeConfig["sensors"].items():
motion = sensor.getMotion()
if motion != None:
response["data"].append(motion)
elif resource == "device_power":
for key, sensor in bridgeConfig["sensors"].items():
power = sensor.getDevicePower()
if power != None:
response["data"].append(power)
else:
response["errors"].append({"description": "Not Found"})
del response["data"]
Expand Down Expand Up @@ -456,6 +473,8 @@ def get(self, resource, resourceid):
return {"errors": [], "data": [object.getV2Api()]}
elif resource == "bridge":
return {"errors": [], "data": [v2Bridge()]}
elif resource == "device_power":
return {"errors": [], "data": [object.getDevicePower()]}

def put(self, resource, resourceid):
logging.debug(request.headers)
Expand Down

0 comments on commit f2e3841

Please sign in to comment.