| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 | """Library to handle connection with Switchbot."""from __future__ import annotationsimport loggingfrom typing import Anyfrom .device import DEVICE_SET_EXTENDED_KEY, DEVICE_SET_MODE_KEY, SwitchbotDevice# Bot keysPRESS_KEY = "570100"ON_KEY = "570101"OFF_KEY = "570102"DOWN_KEY = "570103"UP_KEY = "570104"_LOGGER = logging.getLogger(__name__)class Switchbot(SwitchbotDevice):    """Representation of a Switchbot."""    def __init__(self, *args: Any, **kwargs: Any) -> None:        """Switchbot Bot/WoHand constructor."""        super().__init__(*args, **kwargs)        self._inverse: bool = kwargs.pop("inverse_mode", False)        self._settings: dict[str, Any] = {}    async def update(self, interface: int | None = None) -> None:        """Update mode, battery percent and state of device."""        await self.get_device_data(retry=self._retry_count, interface=interface)    async def turn_on(self) -> bool:        """Turn device on."""        result = await self._sendcommand(ON_KEY, self._retry_count)        if result[0] == 1:            return True        if result[0] == 5:            _LOGGER.debug(                "%s: Bot is in press mode and doesn't have on state", self.name            )            return True        return False    async def turn_off(self) -> bool:        """Turn device off."""        result = await self._sendcommand(OFF_KEY, self._retry_count)        if result[0] == 1:            return True        if result[0] == 5:            _LOGGER.debug(                "%s: Bot is in press mode and doesn't have off state", self.name            )            return True        return False    async def hand_up(self) -> bool:        """Raise device arm."""        result = await self._sendcommand(UP_KEY, self._retry_count)        if result[0] == 1:            return True        if result[0] == 5:            _LOGGER.debug("%s: Bot is in press mode", self.name)            return True        return False    async def hand_down(self) -> bool:        """Lower device arm."""        result = await self._sendcommand(DOWN_KEY, self._retry_count)        if result[0] == 1:            return True        if result[0] == 5:            _LOGGER.debug("%s: Bot is in press mode", self.name)            return True        return False    async def press(self) -> bool:        """Press command to device."""        result = await self._sendcommand(PRESS_KEY, self._retry_count)        if result[0] == 1:            return True        if result[0] == 5:            _LOGGER.debug("%s: Bot is in switch mode", self.name)            return True        return False    async def set_switch_mode(        self, switch_mode: bool = False, strength: int = 100, inverse: bool = False    ) -> bool:        """Change bot mode."""        mode_key = format(switch_mode, "b") + format(inverse, "b")        strength_key = f"{strength:0{2}x}"  # to hex with padding to double digit        result = await self._sendcommand(            DEVICE_SET_MODE_KEY + strength_key + mode_key, self._retry_count        )        if result[0] == 1:            return True        return False    async def set_long_press(self, duration: int = 0) -> bool:        """Set bot long press duration."""        duration_key = f"{duration:0{2}x}"  # to hex with padding to double digit        result = await self._sendcommand(            DEVICE_SET_EXTENDED_KEY + "08" + duration_key, self._retry_count        )        if result[0] == 1:            return True        return False    async def get_basic_info(self) -> dict[str, Any] | None:        """Get device basic settings."""        if not (_data := await self._get_basic_info()):            return None        return {            "battery": _data[1],            "firmware": _data[2] / 10.0,            "strength": _data[3],            "timers": _data[8],            "switchMode": bool(_data[9] & 16),            "inverseDirection": bool(_data[9] & 1),            "holdSeconds": _data[10],        }    def switch_mode(self) -> Any:        """Return true or false from cache."""        # To get actual position call update() first.        return self._get_adv_value("switchMode")    def is_on(self) -> Any:        """Return switch state from cache."""        # To get actual position call update() first.        value = self._get_adv_value("isOn")        if value is None:            return None        if self._inverse:            return not value        return value
 |