zwave-js-server-python/zwave_js_server/const/command_class/lock.py

200 lines
6.6 KiB
Python

"""
Constants for lock related CCs.
Includes Door Lock and Lock CCs.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from enum import Enum, IntEnum
from typing import TypedDict
from .. import CommandClass
class DoorLockMode(IntEnum):
"""Enum with all (known/used) Z-Wave lock states for CommandClass.DOOR_LOCK."""
# https://github.com/zwave-js/node-zwave-js/blob/master/packages/zwave-js/src/lib/commandclass/DoorLockCC.ts#L56-L65
UNSECURED = 0
UNSECURED_WITH_TIMEOUT = 1
INSIDE_UNSECURED = 2
INSIDE_UNSECURED_WITH_TIMEOUT = 3
OUTSIDE_UNSECURED = 4
OUTSIDE_UNSECURED_WITH_TIMEOUT = 5
UNKNOWN = 254
SECURED = 255
class OperationType(IntEnum):
"""Enum with all (known/used) Z-Wave lock operation types."""
# https://github.com/zwave-js/node-zwave-js/blob/master/packages/cc/src/lib/_Types.ts#L496
CONSTANT = 1
TIMED = 2
DOOR_LOCK_CC_UNSECURED_MAP = {
OperationType.CONSTANT: {
DoorLockMode.UNSECURED,
DoorLockMode.INSIDE_UNSECURED,
DoorLockMode.OUTSIDE_UNSECURED,
},
OperationType.TIMED: {
DoorLockMode.UNSECURED_WITH_TIMEOUT,
DoorLockMode.INSIDE_UNSECURED_WITH_TIMEOUT,
DoorLockMode.OUTSIDE_UNSECURED_WITH_TIMEOUT,
},
}
class LatchStatus(str, Enum):
"""Enum with all (known/used) Z-Wave latch statuses."""
# https://github.com/zwave-js/node-zwave-js/blob/master/packages/cc/src/cc/DoorLockCC.ts#L854
OPEN = "open"
CLOSED = "closed"
class BoltStatus(str, Enum):
"""Enum with all (known/used) Z-Wave bolt statuses."""
# https://github.com/zwave-js/node-zwave-js/blob/master/packages/cc/src/cc/DoorLockCC.ts#L854
LOCKED = "locked"
UNLOCKED = "unlocked"
class DoorStatus(str, Enum):
"""Enum with all (known/used) Z-Wave door statuses."""
# https://github.com/zwave-js/node-zwave-js/blob/master/packages/cc/src/cc/DoorLockCC.ts#L854
OPEN = "open"
CLOSED = "closed"
class CodeSlotStatus(IntEnum):
"""Enum with all (known/used) Z-Wave code slot statuses."""
AVAILABLE = 0
ENABLED = 1
DISABLED = 2
# Depending on the Command Class being used by the lock, the lock state is
# different so we need a map to track it
LOCK_CMD_CLASS_TO_LOCKED_STATE_MAP = {
CommandClass.DOOR_LOCK: DoorLockMode.SECURED,
CommandClass.LOCK: True,
}
# Door Lock CC value constants
BOLT_STATUS_PROPERTY = "boltStatus"
CURRENT_AUTO_RELOCK_TIME_PROPERTY = "autoRelockTime"
CURRENT_BLOCK_TO_BLOCK_PROPERTY = "blockToBlock"
CURRENT_HOLD_AND_RELEASE_TIME_PROPERTY = "holdAndReleaseTime"
CURRENT_INSIDE_HANDLES_CAN_OPEN_DOOR_PROPERTY = "insideHandlesCanOpenDoor"
CURRENT_LOCK_TIMEOUT_PROPERTY = "lockTimeout"
CURRENT_MODE_PROPERTY = "currentMode"
CURRENT_OPERATION_TYPE_PROPERTY = "operationType"
CURRENT_OUTSIDE_HANDLES_CAN_OPEN_DOOR_PROPERTY = "outsideHandlesCanOpenDoor"
CURRENT_TWIST_ASSIST_PROPERTY = "twistAssist"
DOOR_STATUS_PROPERTY = "doorStatus"
LATCH_STATUS_PROPERTY = "latchStatus"
TARGET_MODE_PROPERTY = "targetMode"
# Door Lock CC configuration constants
TARGET_AUTO_RELOCK_TIME_PROPERTY = CURRENT_AUTO_RELOCK_TIME_PROPERTY
TARGET_BLOCK_TO_BLOCK_PROPERTY = CURRENT_BLOCK_TO_BLOCK_PROPERTY
TARGET_HOLD_AND_RELEASE_TIME_PROPERTY = CURRENT_HOLD_AND_RELEASE_TIME_PROPERTY
TARGET_INSIDE_HANDLES_CAN_OPEN_DOOR_PROPERTY = "insideHandlesCanOpenDoorConfiguration"
TARGET_LOCK_TIMEOUT_PROPERTY = "lockTimeoutConfiguration"
TARGET_OPERATION_TYPE_PROPERTY = CURRENT_OPERATION_TYPE_PROPERTY
TARGET_OUTSIDE_HANDLES_CAN_OPEN_DOOR_PROPERTY = "outsideHandlesCanOpenDoorConfiguration"
TARGET_TWIST_ASSIST_PROPERTY = CURRENT_TWIST_ASSIST_PROPERTY
# Lock CC constants
LOCKED_PROPERTY = "locked"
# User Code CC constants
LOCK_USERCODE_PROPERTY = "userCode"
LOCK_USERCODE_ID_PROPERTY = "userId"
LOCK_USERCODE_STATUS_PROPERTY = "userIdStatus"
ATTR_CODE_SLOT = "code_slot"
ATTR_IN_USE = "in_use"
ATTR_NAME = "name"
ATTR_USERCODE = "usercode"
# Depending on the Command Class being used by the lock, the locked state property
# is different so we need a map to track it
LOCK_CMD_CLASS_TO_PROPERTY_MAP = {
CommandClass.DOOR_LOCK: TARGET_MODE_PROPERTY,
CommandClass.LOCK: LOCKED_PROPERTY,
}
class DoorLockCCConfigurationSetOptionsDataType(TypedDict, total=False):
"""Door Lock CC Configuration Set command options."""
# https://github.com/zwave-js/node-zwave-js/blob/master/packages/cc/src/cc/DoorLockCC.ts#L1156
operationType: int # required
lockTimeoutConfiguration: int
outsideHandlesCanOpenDoorConfiguration: list[bool] # required when from device
insideHandlesCanOpenDoorConfiguration: list[bool] # required when from device
autoRelockTime: int
holdAndReleaseTime: int
twistAssist: bool
blockToBlock: bool
DEFAULT_HANDLE_CONFIGURATION = [True, True, True, True]
@dataclass
class DoorLockCCConfigurationSetOptions:
"""Door Lock CC Configuration Set command options."""
operation_type: OperationType
lock_timeout_configuration: int | None = None
outside_handles_can_open_door_configuration: list[bool] = field(
default_factory=list
)
inside_handles_can_open_door_configuration: list[bool] = field(default_factory=list)
auto_relock_time: int | None = None
hold_and_release_time: int | None = None
twist_assist: bool | None = None
block_to_block: bool | None = None
def __post_init__(self) -> None:
"""Post initialization."""
for attr_name in (
"inside_handles_can_open_door_configuration",
"outside_handles_can_open_door_configuration",
):
if not getattr(self, attr_name):
setattr(self, attr_name, DEFAULT_HANDLE_CONFIGURATION)
def to_dict(self) -> DoorLockCCConfigurationSetOptionsDataType:
"""Convert command options to dict."""
data = DoorLockCCConfigurationSetOptionsDataType(
operationType=self.operation_type,
outsideHandlesCanOpenDoorConfiguration=(
self.outside_handles_can_open_door_configuration
),
insideHandlesCanOpenDoorConfiguration=(
self.inside_handles_can_open_door_configuration
),
)
for prop_name, val in (
(TARGET_LOCK_TIMEOUT_PROPERTY, self.lock_timeout_configuration),
(TARGET_AUTO_RELOCK_TIME_PROPERTY, self.auto_relock_time),
(TARGET_HOLD_AND_RELEASE_TIME_PROPERTY, self.hold_and_release_time),
(TARGET_TWIST_ASSIST_PROPERTY, self.twist_assist),
(TARGET_BLOCK_TO_BLOCK_PROPERTY, self.block_to_block),
):
if val is not None:
data[prop_name] = val # type: ignore[literal-required]
return data