Great work everyone. Thought I’d add my quirk handler and automation experience to this thread.
I have two locks setup. Both work without issue as long as I checked for their unique values at index 41 and 52. The locks did not share values at either index. I did not have to do anything to identify which lock was being acted upon by the quirk.
There is a random event broadcasting without the lock physically changing. Once every hour, the event would cause HA to become out of sync. I was able to identify them by letting my logs run while I was buying groceries. Looking at index 0 helped me filter them. The value appears to be 117 for both locks. Maybe this is constant for all locks? Perhaps it is some weird check-in? Not sure.
def handle_message(self, hdr, args):
"""Handle a message on this cluster."""
self.debug("ZCL request 0x%04x: %s", hdr.command_id, args)
i = 0
for arg in args:
self.info("index: %s value: %s", i, arg)
i += 1
self.warning("argument: %s", ",".join(map(str, args)))
if len(args) < 70:
return
self.info(
"Interesting attributes - 52: %s, 41: %s, 56: %s, 57: %s, 0: %s",
args[52],
args[41],
args[56],
args[57],
args[0],
)
# Values we care about
manual_unlocked_vals = [9,43]
manual_locked_vals = [14,44]
lock_state_identfiers = [50, 58, 62, 54, 51, 57, 53]
open_state_identfiers = [196, 200]
open_vals = [63, 29]
closed_vals = [60, 30]
# Note sure if these are updates but seem to appear without the lock actually changing
fakes = [117]
if args[0] in fakes:
return
if args[52] == 180 and args[41] == 165:
self.warning("the lock is unlocked via the app")
self.endpoint.device.lock_bus.listener_event("lock_event", 2)
elif args[52] == 180 and args[41] == 162:
self.warning("the lock is locked via the app")
self.endpoint.device.lock_bus.listener_event("lock_event", 1)
elif args[52] in lock_state_identfiers and args[41] in manual_unlocked_vals:
self.warning("the lock is unlocked manually")
self.endpoint.device.lock_bus.listener_event("lock_event", 2)
elif args[52] in lock_state_identfiers and args[41] in manual_locked_vals:
self.warning("the lock is locked manually")
self.endpoint.device.lock_bus.listener_event("lock_event", 1)
elif args[52] == 189 and args[41] == 162:
self.warning("the lock is locked via auto lock")
self.endpoint.device.lock_bus.listener_event("lock_event", 1)
if args[52] in open_state_identfiers and args[41] in open_vals:
self.warning("the door is open")
self.endpoint.device.motion_bus.listener_event("motion_event", ON)
elif args[52] in open_state_identfiers and args[41] in closed_vals:
self.warning("the door is closed")
self.endpoint.device.motion_bus.listener_event("motion_event", OFF)
Automation
Sometimes when the lock changes, the event gets broadcasted 2-3 times over 5 seconds. My automation would trigger multiple times as a result. Setting the mode to single and adding a delay of ~5 seconds to ensure the runs don’t overlap worked for me. I assume adding both a from and a to state in my triggers would also resolve this.
Still trying to figure out
Now, if someone could figure out how to get the battery reading to work, I would be forever thankful. I see the battery listed as an entity, but it is always at 100% and never matches what I see within the Wyze app.