def is_locked(self) -> bool | None: """Return true if the lock is locked.""" if self.info.primary_value.value is None: # guard missing value return None return int(LOCK_CMD_CLASS_TO_LOCKED_STATE_MAP[CommandClass( self.info.primary_value.command_class)]) == int( self.info.primary_value.value)
async def _set_lock_state(self, target_state: str, **kwargs: Any) -> None: """Set the lock state.""" target_value = self.get_zwave_value( LOCK_CMD_CLASS_TO_PROPERTY_MAP[CommandClass( self.info.primary_value.command_class)]) if target_value is not None: await self.info.node.async_set_value( target_value, STATE_TO_ZWAVE_MAP[self.info.primary_value.command_class] [target_state], )
async def async_get_condition_capabilities( hass: HomeAssistant, config: ConfigType) -> dict[str, vol.Schema]: """List condition capabilities.""" device_id = config[CONF_DEVICE_ID] node = async_get_node_from_device_id(hass, device_id) # Add additional fields to the automation trigger UI if config[CONF_TYPE] == CONFIG_PARAMETER_TYPE: value_id = config[CONF_VALUE_ID] value_schema = get_config_parameter_value_schema(node, value_id) if value_schema is None: return {} return { "extra_fields": vol.Schema({vol.Required(ATTR_VALUE): value_schema}) } if config[CONF_TYPE] == VALUE_TYPE: # Only show command classes on this node and exclude Configuration CC since it # is already covered return { "extra_fields": vol.Schema({ vol.Required(ATTR_COMMAND_CLASS): vol.In({ CommandClass(cc.id).value: cc.name for cc in sorted( node.command_classes, key=lambda cc: cc.name) # type: ignore[no-any-return] if cc.id != CommandClass.CONFIGURATION }), vol.Required(ATTR_PROPERTY): cv.string, vol.Optional(ATTR_PROPERTY_KEY): cv.string, vol.Optional(ATTR_ENDPOINT): cv.string, vol.Required(ATTR_VALUE): cv.string, }) } if config[CONF_TYPE] == NODE_STATUS_TYPE: return { "extra_fields": vol.Schema({vol.Required(CONF_STATUS): vol.In(NODE_STATUSES)}) } return {}
def redact_value_of_zwave_value(zwave_value: ValueDataType) -> ValueDataType: """Redact value of a Z-Wave value.""" for value_to_redact in VALUES_TO_REDACT: zwave_value_id = ZwaveValueID( property_=zwave_value["property"], command_class=CommandClass(zwave_value["commandClass"]), endpoint=zwave_value.get("endpoint"), property_key=zwave_value.get("propertyKey"), ) if all(redacted_field_val is None or redacted_field_val == zwave_value_field_val for redacted_field_val, zwave_value_field_val in zip( astuple(value_to_redact), astuple(zwave_value_id))): return {**zwave_value, "value": REDACTED} return zwave_value
async def websocket_refresh_node_cc_values( hass: HomeAssistant, connection: ActiveConnection, msg: dict, node: Node, ) -> None: """Refresh node values for a particular CommandClass.""" command_class_id = msg[COMMAND_CLASS_ID] try: command_class = CommandClass(command_class_id) except ValueError: connection.send_error(msg[ID], ERR_NOT_FOUND, f"Command class {command_class_id} not found") return await node.async_refresh_cc_values(command_class) connection.send_result(msg[ID])
def redact_value_of_zwave_value(zwave_value: ValueDataType) -> ValueDataType: """Redact value of a Z-Wave value.""" for value_to_redact in VALUES_TO_REDACT: command_class = None if "commandClass" in zwave_value: command_class = CommandClass(zwave_value["commandClass"]) zwave_value_id = ZwaveValueMatcher( property_=zwave_value.get("property"), command_class=command_class, endpoint=zwave_value.get("endpoint"), property_key=zwave_value.get("propertyKey"), ) if all(redacted_field_val is None or redacted_field_val == zwave_value_field_val for redacted_field_val, zwave_value_field_val in zip( astuple(value_to_redact), astuple(zwave_value_id))): redacted_value: ValueDataType = deepcopy(zwave_value) redacted_value["value"] = REDACTED return redacted_value return zwave_value
async def async_get_action_capabilities( hass: HomeAssistant, config: ConfigType) -> dict[str, vol.Schema]: """List action capabilities.""" action_type = config[CONF_TYPE] node = async_get_node_from_device_id(hass, config[CONF_DEVICE_ID]) # Add additional fields to the automation action UI if action_type == SERVICE_CLEAR_LOCK_USERCODE: return { "extra_fields": vol.Schema({ vol.Required(ATTR_CODE_SLOT): cv.string, }) } if action_type == SERVICE_SET_LOCK_USERCODE: return { "extra_fields": vol.Schema({ vol.Required(ATTR_CODE_SLOT): cv.string, vol.Required(ATTR_USERCODE): cv.string, }) } if action_type == SERVICE_RESET_METER: return { "extra_fields": vol.Schema({ vol.Optional(ATTR_VALUE): cv.string, }) } if action_type == SERVICE_REFRESH_VALUE: return { "extra_fields": vol.Schema({ vol.Optional(ATTR_REFRESH_ALL_VALUES): cv.boolean, }) } if action_type == SERVICE_SET_VALUE: return { "extra_fields": vol.Schema({ vol.Required(ATTR_COMMAND_CLASS): vol.In({ CommandClass(cc.id).value: cc.name for cc in sorted(node.command_classes, key=lambda cc: cc.name) }), vol.Required(ATTR_PROPERTY): cv.string, vol.Optional(ATTR_PROPERTY_KEY): cv.string, vol.Optional(ATTR_ENDPOINT): cv.string, vol.Required(ATTR_VALUE): cv.string, vol.Optional(ATTR_WAIT_FOR_RESULT): cv.boolean, }) } if action_type == SERVICE_SET_CONFIG_PARAMETER: value_id = get_value_id( node, CommandClass.CONFIGURATION, config[ATTR_CONFIG_PARAMETER], property_key=config[ATTR_CONFIG_PARAMETER_BITMASK], ) value_schema = get_config_parameter_value_schema(node, value_id) if value_schema is None: return {} return { "extra_fields": vol.Schema({vol.Required(ATTR_VALUE): value_schema}) } return {}
async def async_get_trigger_capabilities( hass: HomeAssistant, config: ConfigType) -> dict[str, vol.Schema]: """List trigger capabilities.""" trigger_type = config[CONF_TYPE] node = async_get_node_from_device_id(hass, config[CONF_DEVICE_ID]) # Add additional fields to the automation trigger UI if trigger_type == NOTIFICATION_NOTIFICATION: return { "extra_fields": vol.Schema({ vol.Optional(f"{ATTR_TYPE}."): cv.string, vol.Optional(ATTR_LABEL): cv.string, vol.Optional(ATTR_EVENT): cv.string, vol.Optional(ATTR_EVENT_LABEL): cv.string, }) } if trigger_type == ENTRY_CONTROL_NOTIFICATION: return { "extra_fields": vol.Schema({ vol.Optional(ATTR_EVENT_TYPE): cv.string, vol.Optional(ATTR_DATA_TYPE): cv.string, }) } if trigger_type == NODE_STATUS: return { "extra_fields": vol.Schema({ vol.Optional(state.CONF_FROM): vol.In(NODE_STATUSES), vol.Optional(state.CONF_TO): vol.In(NODE_STATUSES), vol.Optional(state.CONF_FOR): cv.positive_time_period_dict, }) } if trigger_type in ( BASIC_VALUE_NOTIFICATION, CENTRAL_SCENE_VALUE_NOTIFICATION, SCENE_ACTIVATION_VALUE_NOTIFICATION, ): value_schema = get_value_state_schema( get_zwave_value_from_config(node, config)) # We should never get here, but just in case we should add a guard if not value_schema: return {} return { "extra_fields": vol.Schema({vol.Optional(ATTR_VALUE): value_schema}) } if trigger_type == CONFIG_PARAMETER_VALUE_UPDATED: value_schema = get_value_state_schema( get_zwave_value_from_config(node, config)) if not value_schema: return {} return { "extra_fields": vol.Schema({ vol.Optional(ATTR_FROM): value_schema, vol.Optional(ATTR_TO): value_schema, }) } if trigger_type == VALUE_VALUE_UPDATED: # Only show command classes on this node and exclude Configuration CC since it # is already covered return { "extra_fields": vol.Schema({ vol.Required(ATTR_COMMAND_CLASS): vol.In({ CommandClass(cc.id).value: cc.name for cc in sorted( node.command_classes, key=lambda cc: cc.name) # type: ignore[no-any-return] if cc.id != CommandClass.CONFIGURATION }), vol.Required(ATTR_PROPERTY): cv.string, vol.Optional(ATTR_PROPERTY_KEY): cv.string, vol.Optional(ATTR_ENDPOINT): cv.string, vol.Optional(ATTR_FROM): cv.string, vol.Optional(ATTR_TO): cv.string, }) } return {}
def is_locked(self) -> Optional[bool]: """Return true if the lock is locked.""" return int(LOCK_CMD_CLASS_TO_LOCKED_STATE_MAP[CommandClass( self.info.primary_value.command_class)]) == int( self.info.primary_value.value)