Source code for libdeye.device_state

"""Utilities for device state parsing"""

from enum import IntFlag, auto

from .cloud_api import DeyeApiResponseFogPlatformDeviceProperties
from .const import (
    DeyeDeviceMode,
    DeyeFanSpeed,
)
from .device_command import DeyeDeviceCommand


[docs] class DeyeDeviceState: """A class to store the device state.""" def __init__(self, state: str | DeyeApiResponseFogPlatformDeviceProperties) -> None: self.anion_switch: bool = False self.water_pump_switch: bool = False self.power_switch: bool = False self.oscillating_switch: bool = False self.child_lock_switch: bool = False self.defrosting: bool = False self.water_tank_full: bool = False self.fan_running: bool = False self.fan_speed: DeyeFanSpeed = DeyeFanSpeed.STOPPED self.mode: DeyeDeviceMode = DeyeDeviceMode.SLEEP_MODE self.target_humidity: int = 60 self.environment_temperature: int = 27 self.environment_humidity: int = 27 # Unused attributes self._electromagnetic_state: bool = False self._press_state: bool = False self._environment_degree: bool = False self._poweroff_switch: bool = False self._poweron_switch: bool = False self._coil_temperature: int = 27 self._exhaust_temperature: int = 27 if isinstance(state, str): self._parse_state_classic(state) else: self._parse_state_fog(state) def _parse_state_classic(self, state: str) -> None: state_hex = bytes.fromhex(state) state_flag = int.from_bytes(state_hex[2:4], byteorder="big") self.anion_switch = (state_flag & DeyeDeviceStateFlag.ANION_SWITCH) > 0 self.water_pump_switch = ( state_flag & DeyeDeviceStateFlag.WATER_PUMP_SWITCH ) > 0 self.power_switch = (state_flag & DeyeDeviceStateFlag.POWER_SWITCH) > 0 self.oscillating_switch = ( state_flag & DeyeDeviceStateFlag.OSCILLATING_SWITCH ) > 0 self.child_lock_switch = ( state_flag & DeyeDeviceStateFlag.CHILD_LOCK_SWITCH ) > 0 self.defrosting = (state_flag & DeyeDeviceStateFlag.DEFROSTING_STATE) > 0 self.water_tank_full = ( state_flag & DeyeDeviceStateFlag.WATER_TANK_FULL_STATE ) > 0 self.fan_running = (state_flag & DeyeDeviceStateFlag.FAN_RUNNING_STATE) > 0 self.fan_speed = DeyeFanSpeed(int(state[8], 16)) self.mode = DeyeDeviceMode(int(state[9], 16)) self.target_humidity = state_hex[5] self.environment_temperature = state_hex[15] - 40 self.environment_humidity = state_hex[16] # Unused attributes self._electromagnetic_state = ( state_flag & DeyeDeviceStateFlag.ELECTROMAGNETIC_STATE ) > 0 self._press_state = (state_flag & DeyeDeviceStateFlag.PRESS_STATE) > 0 self._environment_degree = ( state_flag & DeyeDeviceStateFlag.ENVIRONMENT_DEGREE ) > 0 self._poweroff_switch = (state_flag & DeyeDeviceStateFlag.POWEROFF_SWITCH) > 0 self._poweron_switch = (state_flag & DeyeDeviceStateFlag.POWERON_SWITCH) > 0 self._coil_temperature = state_hex[14] - 40 self._exhaust_temperature = state_hex[17] - 40 def _parse_state_fog( self, state: DeyeApiResponseFogPlatformDeviceProperties ) -> None: self.anion_switch = bool(state["NegativeIon"]) self.water_pump_switch = bool(state["WaterPump"]) self.power_switch = bool(state["Power"]) self.oscillating_switch = bool(state["SwingingWind"]) self.child_lock_switch = bool(state["KeyLock"]) self.defrosting = bool(state["Demisting"]) self.water_tank_full = bool(state["WaterTank"]) self.fan_running = bool(state["Fan"]) self.fan_speed = DeyeFanSpeed(state.get("WindSpeed", DeyeFanSpeed.STOPPED)) self.mode = DeyeDeviceMode(state.get("Mode", DeyeDeviceMode.SLEEP_MODE)) self.target_humidity = state.get("SetHumidity", 60) self.environment_temperature = state.get("CurrentAmbientTemperature", 27) self.environment_humidity = state.get("CurrentEnvironmentalHumidity", 27) # Unused attributes self._coil_temperature = state.get("CurrentCoilTemperature", 27) self._exhaust_temperature = state.get("CurrentExhaustTemperature", 27)
[docs] def copy(self) -> "DeyeDeviceState": """Return an independent copy of this state.""" copied = DeyeDeviceState.__new__(DeyeDeviceState) copied.__dict__.update(self.__dict__) return copied
[docs] def to_command(self) -> DeyeDeviceCommand: """Convert to a command that can be used to let the device get into this state""" return DeyeDeviceCommand( self.anion_switch, self.water_pump_switch, self.power_switch, self.oscillating_switch, self.child_lock_switch, self.fan_speed, self.mode, self.target_humidity, )
def __eq__(self, other: object) -> bool: """Check if two device states are equal. Only compares public attributes that represent the actual device state. """ if not isinstance(other, DeyeDeviceState): return False return ( self.anion_switch == other.anion_switch and self.water_pump_switch == other.water_pump_switch and self.power_switch == other.power_switch and self.oscillating_switch == other.oscillating_switch and self.child_lock_switch == other.child_lock_switch and self.defrosting == other.defrosting and self.water_tank_full == other.water_tank_full and self.fan_running == other.fan_running and self.fan_speed == other.fan_speed and self.mode == other.mode and self.target_humidity == other.target_humidity and self.environment_temperature == other.environment_temperature and self.environment_humidity == other.environment_humidity )
[docs] class DeyeDeviceStateFlag(IntFlag): """Bit flags used in the state string""" ANION_SWITCH = auto() WATER_PUMP_SWITCH = auto() ELECTROMAGNETIC_STATE = auto() PRESS_STATE = auto() ENVIRONMENT_DEGREE = auto() _5 = auto() _6 = auto() _7 = auto() POWER_SWITCH = auto() OSCILLATING_SWITCH = auto() CHILD_LOCK_SWITCH = auto() POWEROFF_SWITCH = auto() # Do not use this flag to check power off state POWERON_SWITCH = auto() # Do not use this flag to check power on state DEFROSTING_STATE = auto() WATER_TANK_FULL_STATE = auto() FAN_RUNNING_STATE = auto()