Ejemplo n.º 1
0
    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

        else:
            raise ZWaveIntegrationNotConfiguredError

        return data
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
def test_get_usercodes(lock_schlage_be469):
    """Test get_usercodes utility function."""
    node = lock_schlage_be469
    assert get_usercodes(node) == CODE_SLOTS
Ejemplo n.º 4
0
    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