def websocket_node_status(hass, connection, msg): """Get the status for a Z-Wave node.""" try: node = get_node_from_manager(hass.data[DOMAIN][MANAGER], msg[OZW_INSTANCE], msg[NODE_ID]) except NotFoundError as err: connection.send_error( msg[ID], websocket_api.const.ERR_NOT_FOUND, err.args[0], ) return connection.send_result( msg[ID], { ATTR_NODE_QUERY_STAGE: node.node_query_stage, NODE_ID: node.node_id, ATTR_IS_ZWAVE_PLUS: node.is_zwave_plus, ATTR_IS_AWAKE: node.is_awake, ATTR_IS_FAILED: node.is_failed, ATTR_NODE_BAUD_RATE: node.node_baud_rate, ATTR_IS_BEAMING: node.is_beaming, ATTR_IS_FLIRS: node.is_flirs, ATTR_IS_ROUTING: node.is_routing, ATTR_IS_SECURITYV1: node.is_securityv1, ATTR_NODE_BASIC_STRING: node.node_basic_string, ATTR_NODE_GENERIC_STRING: node.node_generic_string, ATTR_NODE_SPECIFIC_STRING: node.node_specific_string, ATTR_NODE_MANUFACTURER_NAME: node.node_manufacturer_name, ATTR_NODE_PRODUCT_NAME: node.node_product_name, ATTR_NEIGHBORS: node.neighbors, OZW_INSTANCE: msg[OZW_INSTANCE], }, )
def async_set_config_parameter(self, service): """Set a config parameter to a node.""" instance_id = service.data[const.ATTR_INSTANCE_ID] node_id = service.data[const.ATTR_NODE_ID] param = service.data[const.ATTR_CONFIG_PARAMETER] selection = service.data[const.ATTR_CONFIG_VALUE] # These function calls may raise an exception but that's ok because # the exception will show in the UI to the user node = get_node_from_manager(self._manager, instance_id, node_id) payload = set_config_parameter(node, param, selection) _LOGGER.info( "Setting configuration parameter %s on Node %s with value %s", param, node_id, payload, )
def websocket_node_metadata(hass, connection, msg): """Get the metadata for a Z-Wave node.""" try: node = get_node_from_manager(hass.data[DOMAIN][MANAGER], msg[OZW_INSTANCE], msg[NODE_ID]) except NotFoundError as err: connection.send_error( msg[ID], websocket_api.const.ERR_NOT_FOUND, err.args[0], ) return connection.send_result( msg[ID], { "metadata": node.meta_data, NODE_ID: node.node_id, OZW_INSTANCE: msg[OZW_INSTANCE], }, )
def _call_util_function(hass, connection, msg, send_result, function, *args): """Call an openzwavemqtt.util function.""" try: node = get_node_from_manager( hass.data[DOMAIN][MANAGER], msg[OZW_INSTANCE], msg[NODE_ID] ) except NotFoundError as err: connection.send_error( msg[ID], websocket_api.const.ERR_NOT_FOUND, err.args[0], ) return try: payload = function(node, *args) except NotFoundError as err: connection.send_error( msg[ID], websocket_api.const.ERR_NOT_FOUND, err.args[0], ) return except NotSupportedError as err: connection.send_error( msg[ID], websocket_api.const.ERR_NOT_SUPPORTED, err.args[0], ) return if send_result: connection.send_result( msg[ID], payload, ) return connection.send_result(msg[ID])
async def _async_update(self) -> Dict[Union[str, int], Any]: """Update usercodes.""" # loop to get user code data from entity_id node instance_id = 1 # default data = {CONF_LOCK_ENTITY_ID: self._primary_lock.lock_entity_id} # # make button call # servicedata = {"entity_id": self._entity_id} # await self.hass.services.async_call( # DOMAIN, SERVICE_REFRESH_CODES, servicedata # ) if async_using_zwave_js(lock=self._primary_lock): node: ZwaveJSNode = self._primary_lock.zwave_js_lock_node if node is None: raise NativeNotFoundError code_slot = 1 for slot in get_usercodes(node): code_slot = int(slot[ATTR_CODE_SLOT]) usercode: Optional[str] = slot[ATTR_USERCODE] in_use: Optional[bool] = slot[ATTR_IN_USE] # Retrieve code slots that haven't been populated yet if in_use is None and code_slot in self.slots: usercode_resp = await get_usercode_from_node( node, code_slot) usercode = slot[ATTR_USERCODE] = usercode_resp[ ATTR_USERCODE] in_use = slot[ATTR_IN_USE] = usercode_resp[ATTR_IN_USE] if not in_use: _LOGGER.debug("DEBUG: Code slot %s not enabled", code_slot) data[code_slot] = "" elif usercode and "*" in str(usercode): _LOGGER.debug( "DEBUG: Ignoring code slot with * in value for code slot %s", code_slot, ) data[code_slot] = self._invalid_code(code_slot) else: _LOGGER.debug("DEBUG: Code slot %s value: %s", code_slot, usercode) data[code_slot] = usercode # pull the codes for ozw elif async_using_ozw(lock=self._primary_lock): node_id = get_node_id(self.hass, self._primary_lock.lock_entity_id) if node_id is None: return data data[ATTR_NODE_ID] = node_id if data[ATTR_NODE_ID] is None: raise NoNodeSpecifiedError # Raises exception when node not found try: node = get_node_from_manager( self.hass.data[OZW_DOMAIN][MANAGER], instance_id, data[ATTR_NODE_ID], ) except NotFoundError: raise NativeNotFoundError from None command_class = node.get_command_class(CommandClass.USER_CODE) if not command_class: raise NativeNotSupportedError("Node doesn't have code slots") for value in command_class.values(): # type: ignore code_slot = int(value.index) _LOGGER.debug("DEBUG: Code slot %s value: %s", code_slot, str(value.value)) if value.value and "*" in str(value.value): _LOGGER.debug("DEBUG: Ignoring code slot with * in value.") data[code_slot] = self._invalid_code(code_slot) else: data[code_slot] = value.value # pull codes for zwave elif async_using_zwave(lock=self._primary_lock): node_id = get_node_id(self.hass, self._primary_lock.lock_entity_id) if node_id is None: return data data[ATTR_NODE_ID] = node_id if data[ATTR_NODE_ID] is None: raise NoNodeSpecifiedError network = self.hass.data[ZWAVE_NETWORK] node = network.nodes.get(data[ATTR_NODE_ID]) if not node: raise NativeNotFoundError lock_values = node.get_values( class_id=CommandClass.USER_CODE).values() for value in lock_values: _LOGGER.debug( "DEBUG: Code slot %s value: %s", str(value.index), str(value.data), ) # do not update if the code contains *s code = str(value.data) # Remove \x00 if found code = code.replace("\x00", "") # Check for * in lock data and use workaround code if exist if "*" in code: _LOGGER.debug("DEBUG: Ignoring code slot with * in value.") code = self._invalid_code(value.index) # Build data from entities active_binary_sensor = ( f"binary_sensor.active_{self._primary_lock.lock_name}_{value.index}" ) active = self.hass.states.get(active_binary_sensor) # Report blank slot if occupied by random code if active is not None: if active.state == "off": _LOGGER.debug( "DEBUG: Utilizing Zwave clear_usercode work around code" ) code = "" data[int(value.index)] = code else: raise ZWaveIntegrationNotConfiguredError return data
def update_usercodes(self) -> Dict[str, Any]: """Update usercodes.""" # loop to get user code data from entity_id node instance_id = 1 # default data = {} data[CONF_LOCK_ENTITY_ID] = self._lock.lock_entity_id node_id = get_node_id(self.hass, self._lock.lock_entity_id) if node_id is None: return data data[ATTR_NODE_ID] = node_id if data[ATTR_NODE_ID] is None: raise NoNodeSpecifiedError # # make button call # servicedata = {"entity_id": self._entity_id} # await self.hass.services.async_call(DOMAIN, SERVICE_REFRESH_CODES, servicedata) # pull the codes for ozw if using_ozw(self.hass): # Raises exception when node not found try: node = get_node_from_manager( self.hass.data[OZW_DOMAIN][MANAGER], instance_id, data[ATTR_NODE_ID], ) except NotFoundError: return data command_class = node.get_command_class(CommandClass.USER_CODE) if not command_class: raise NotSupportedError("Node doesn't have code slots") for value in command_class.values(): # type: ignore code_slot = int(value.index) _LOGGER.debug("DEBUG: Code slot %s value: %s", code_slot, str(value.value)) if value.value and "*" in str(value.value): _LOGGER.debug("DEBUG: Ignoring code slot with * in value.") data[code_slot] = self._invalid_code(code_slot) else: data[code_slot] = value.value return data # pull codes for zwave elif using_zwave(self.hass): network = self.hass.data[ZWAVE_NETWORK] node = network.nodes.get(data[ATTR_NODE_ID]) if not node: raise NotFoundError lock_values = node.get_values( class_id=CommandClass.USER_CODE).values() for value in lock_values: _LOGGER.debug( "DEBUG: Code slot %s value: %s", str(value.index), str(value.data), ) # do not update if the code contains *s code = str(value.data) # Remove \x00 if found code = code.replace("\x00", "") # Check for * in lock data and use workaround code if exist if "*" in code: _LOGGER.debug("DEBUG: Ignoring code slot with * in value.") code = self._invalid_code(value.index) # Build data from entities enabled_bool = ( f"input_boolean.{self._lock.lock_name}_enabled_{value.index}" ) enabled = self.hass.states.get(enabled_bool) # Report blank slot if occupied by random code if enabled is not None: if enabled.state == "off": _LOGGER.debug( "DEBUG: Utilizing Zwave clear_usercode work around code." ) code = "" data[int(value.index)] = code return data else: raise ZWaveIntegrationNotConfiguredError
async def _async_update(self) -> Dict[str, Any]: """Update usercodes.""" # loop to get user code data from entity_id node instance_id = 1 # default data = {CONF_LOCK_ENTITY_ID: self._primary_lock.lock_entity_id} # # make button call # servicedata = {"entity_id": self._entity_id} # await self.hass.services.async_call( # DOMAIN, SERVICE_REFRESH_CODES, servicedata # ) if async_using_zwave_js(lock=self._primary_lock): node = self._primary_lock.zwave_js_lock_node if node is None: raise NativeNotFoundError code_slot = 1 for slot in get_usercodes(node): code_slot = int(slot[ATTR_CODE_SLOT]) usercode = slot[ATTR_USERCODE] if not slot[ATTR_IN_USE]: _LOGGER.debug("DEBUG: Code slot %s not enabled", code_slot) data[code_slot] = "" elif usercode and "*" in str(usercode): _LOGGER.debug( "DEBUG: Ignoring code slot with * in value for code slot %s", code_slot, ) data[code_slot] = self._invalid_code(code_slot) else: _LOGGER.debug("DEBUG: Code slot %s value: %s", code_slot, usercode) data[code_slot] = usercode return data # pull codes for zha elif async_using_zha(lock=self._primary_lock): _LOGGER.debug('asking for update for zha') zha_lock_entity = self._primary_lock.zha_lock_entity _LOGGER.debug(self.hass.data[DATA_ZHA]) _LOGGER.debug(self.hass.data[ZHA_DOMAIN]) locks = [ object_type(*instance) for object_type, instance in self.hass.data[DATA_ZHA][LOCK_DOMAIN] ] _LOGGER.debug(locks) lock = next( (x for x in locks if x.unique_id == zha_lock_entity.unique_id), None) _LOGGER.debug(lock) if lock is None: raise NativeNotFoundError start_from = self.config_entry.data.get(CONF_START, 1) code_slots = self.config_entry.data.get(CONF_SLOTS, 1) # return for the number of slots we have configured # TODO: figure out how to actually get the max number of slots # TODO: figure out how to get codes at a time other than startup for code_slot in range(start_from, start_from + code_slots): index, userstatus, usertype, usercode = await lock._doorlock_channel.async_get_user_code( code_slot) if userstatus != DoorLock.UserStatus.Enabled: _LOGGER.debug("DEBUG: Code slot %s not enabled", code_slot) data[code_slot] = "" else: _LOGGER.debug("DEBUG: Code slot %s value: %s", code_slot, usercode) data[code_slot] = usercode return data # pull the codes for ozw elif async_using_ozw(lock=self._primary_lock): node_id = get_node_id(self.hass, self._primary_lock.lock_entity_id) if node_id is None: return data data[ATTR_NODE_ID] = node_id if data[ATTR_NODE_ID] is None: raise NoNodeSpecifiedError # Raises exception when node not found try: node = get_node_from_manager( self.hass.data[OZW_DOMAIN][MANAGER], instance_id, data[ATTR_NODE_ID], ) except NotFoundError: raise NativeNotFoundError from None command_class = node.get_command_class(CommandClass.USER_CODE) if not command_class: raise NativeNotSupportedError("Node doesn't have code slots") for value in command_class.values(): # type: ignore code_slot = int(value.index) _LOGGER.debug("DEBUG: Code slot %s value: %s", code_slot, str(value.value)) if value.value and "*" in str(value.value): _LOGGER.debug("DEBUG: Ignoring code slot with * in value.") data[code_slot] = self._invalid_code(code_slot) else: data[code_slot] = value.value return data # pull codes for zwave elif async_using_zwave(lock=self._primary_lock): node_id = get_node_id(self.hass, self._primary_lock.lock_entity_id) if node_id is None: return data data[ATTR_NODE_ID] = node_id if data[ATTR_NODE_ID] is None: raise NoNodeSpecifiedError network = self.hass.data[ZWAVE_NETWORK] node = network.nodes.get(data[ATTR_NODE_ID]) if not node: raise NativeNotFoundError lock_values = node.get_values( class_id=CommandClass.USER_CODE).values() for value in lock_values: _LOGGER.debug( "DEBUG: Code slot %s value: %s", str(value.index), str(value.data), ) # do not update if the code contains *s code = str(value.data) # Remove \x00 if found code = code.replace("\x00", "") # Check for * in lock data and use workaround code if exist if "*" in code: _LOGGER.debug("DEBUG: Ignoring code slot with * in value.") code = self._invalid_code(value.index) # Build data from entities active_binary_sensor = ( f"binary_sensor.active_{self._primary_lock.lock_name}_{value.index}" ) active = self.hass.states.get(active_binary_sensor) # Report blank slot if occupied by random code if active is not None: if active.state == "off": _LOGGER.debug( "DEBUG: Utilizing Zwave clear_usercode work around code" ) code = "" data[int(value.index)] = code return data else: raise ZWaveIntegrationNotConfiguredError