Yes, sorry for the delay I was out of town. I restated those techniques in my previous comment. I do not get any “Interesting” numbers in my log. I do not have events reported when I manually on lock, unlock, or open my door. I am looking in the logs, and looking in the ZHA Add Device > Show Logs section. Here is my logging config:
logger:
default: info
logs:
asyncio: debug
homeassistant.core: debug
homeassistant.components.zha: debug
zigpy: debug
bellows: debug
zigpy_xbee: debug
zigpy_deconz: debug
zigpy_zigate: debug
zigpy_cc: debug
bellows.zigbee.application: debug
bellows.ezsp: debug
zigpy_deconz.zigbee.application: debug
zigpy_deconz.api: debug
zigpy_xbee.ap: debug
zigpy_znp: debug
zhaquirks: debug
and here is my lock.py:
"""Support for the Wyze lock."""
import logging
from typing import Any, List, Optional, Union
from zigpy.profiles import zha
from zigpy.quirks import CustomCluster, CustomDevice
import zigpy.types as t
from zigpy.zcl import foundation
from zigpy.zcl.clusters.closures import DoorLock
from zigpy.zcl.clusters.general import (
Basic,
Identify,
Ota,
PollControl,
PowerConfiguration,
Time,
)
from zigpy.zcl.clusters.homeautomation import Diagnostic
from zigpy.zcl.clusters.security import IasZone
from . import YUNDING
from zhaquirks import Bus, LocalDataCluster
from zhaquirks.const import (
CLUSTER_COMMAND,
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OFF,
ON,
OUTPUT_CLUSTERS,
PROFILE_ID,
ZONE_STATE,
)
WYZE_CLUSTER_ID = 0xFC00
ZONE_TYPE = 0x0001
_LOGGER = logging.getLogger(__name__)
class DoorLockCluster(CustomCluster, DoorLock):
"""DoorLockCluster cluster."""
cluster_id = DoorLock.cluster_id
def __init__(self, *args, **kwargs):
"""Init."""
super().__init__(*args, **kwargs)
self.endpoint.device.lock_bus.add_listener(self)
def lock_event(self, locked):
"""Motion event."""
self._update_attribute(0x0000, locked)
class MotionCluster(LocalDataCluster, IasZone):
"""Motion cluster."""
cluster_id = IasZone.cluster_id
def __init__(self, *args, **kwargs):
"""Init."""
super().__init__(*args, **kwargs)
self.endpoint.device.motion_bus.add_listener(self)
super()._update_attribute(ZONE_TYPE, IasZone.ZoneType.Contact_Switch)
def motion_event(self, zone_state):
"""Motion event."""
super().listener_event(CLUSTER_COMMAND, None, ZONE_STATE, [zone_state])
_LOGGER.debug("%s - Received motion event message", self.endpoint.device.ieee)
class WyzeCluster(CustomCluster, Basic):
"""Wyze manufacturer specific cluster implementation."""
cluster_id = WYZE_CLUSTER_ID
ep_attribute = "wyze_lock_cluster"
attributes = {}
server_commands = {}
client_commands = {}
def handle_message(
self,
hdr: foundation.ZCLHeader,
args: List[Any],
*,
dst_addressing: Optional[
Union[t.Addressing.Group, t.Addressing.IEEE, t.Addressing.NWK]
] = None,
):
"""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",
args[52],
args[41],
args[56],
args[57],
args[0],
)
manual_unlocked_vals = [9,243]
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]
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] == 176 and args[41] == 165:
self.warning("the lock is unlocked manually")
self.endpoint.device.lock_bus.listener_event("lock_event", 2)
elif args[52] == 176 and args[41] == 162:
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] == 74 and args[41] == 177:
self.warning("the door is open")
self.endpoint.device.motion_bus.listener_event("motion_event", ON)
elif args[52] == 74 and args[41] == 178:
self.warning("the door is closed")
self.endpoint.device.motion_bus.listener_event("motion_event", OFF)
class WyzeLock(CustomDevice):
"""Wyze lock device."""
def __init__(self, *args, **kwargs):
"""Init."""
self.lock_bus = Bus()
self.motion_bus = Bus()
super().__init__(*args, **kwargs)
signature = {
# <SimpleDescriptor endpoint=1 profile=260 device_type=10
# device_version=1
# input_clusters=[0, 1, 3, 32, 257, 2821, 64512]
# output_clusters=[10, 25, 64512]>
MODELS_INFO: [(YUNDING, "Ford")],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.DOOR_LOCK,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
PollControl.cluster_id,
DoorLock.cluster_id,
Diagnostic.cluster_id,
WYZE_CLUSTER_ID,
],
OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id, WYZE_CLUSTER_ID],
}
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.DOOR_LOCK,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
PollControl.cluster_id,
DoorLockCluster,
Diagnostic.cluster_id,
WyzeCluster,
MotionCluster,
],
OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id, WyzeCluster],
}
}
}
I have an hours worth of logs, with me attempting to lock and unlock and open the door somewhere near the beginning. I am unsure how to send them to you, I don’t see a private message option on this site.