wyzeapy.services.thermostat_service

  1#  Copyright (c) 2021. Mulliken, LLC - All Rights Reserved
  2#  You may use, distribute and modify this code under the terms
  3#  of the attached license. You should have received a copy of
  4#  the license with this file. If not, please write to:
  5#  katie@mulliken.net to receive a copy
  6import logging
  7from enum import Enum
  8from typing import Any, Dict, List
  9
 10from .base_service import BaseService
 11from ..types import Device, ThermostatProps, DeviceTypes
 12
 13_LOGGER = logging.getLogger(__name__)
 14
 15
 16class HVACMode(Enum):
 17    AUTO = "auto"
 18    HEAT = "heat"
 19    COOL = "cool"
 20    OFF = "off"
 21
 22
 23class FanMode(Enum):  # auto, on
 24    AUTO = "auto"
 25    ON = "on"
 26
 27
 28class TemperatureUnit(Enum):
 29    FAHRENHEIT = "F"
 30    CELSIUS = "C"
 31
 32
 33class Preset(Enum):
 34    HOME = "home"
 35    AWAY = "away"
 36    SLEEP = "sleep"
 37
 38
 39class HVACState(Enum):
 40    COOLING = 'cooling'
 41    HEATING = 'heating'
 42    IDLE = 'idle'
 43
 44
 45class Thermostat(Device):
 46    def __init__(self, dictionary: Dict[Any, Any]):
 47        super().__init__(dictionary)
 48
 49        self.temp_unit: TemperatureUnit = TemperatureUnit.FAHRENHEIT
 50        self.cool_set_point: int = 74
 51        self.heat_set_point: int = 64
 52        self.fan_mode: FanMode = FanMode.AUTO
 53        self.hvac_mode: HVACMode = HVACMode.AUTO
 54        self.preset: Preset = Preset.HOME
 55        self.temperature: float = 71
 56        self.available: bool = True
 57        self.humidity: int = 50
 58        self.hvac_state: HVACState = HVACState.IDLE
 59
 60
 61class ThermostatService(BaseService):
 62    async def update(self, thermostat: Thermostat) -> Thermostat:
 63        properties = (await self._thermostat_get_iot_prop(thermostat))['data']['props']
 64
 65        device_props = []
 66        for property in properties:
 67            try:
 68                prop = ThermostatProps(property)
 69                device_props.append((prop, properties[property]))
 70            except ValueError as e:
 71                _LOGGER.debug(f"{e} with value {properties[property]}")
 72
 73        thermostat_props = device_props
 74        for prop, value in thermostat_props:
 75            if prop == ThermostatProps.TEMP_UNIT:
 76                thermostat.temp_unit = TemperatureUnit(value)
 77            elif prop == ThermostatProps.COOL_SP:
 78                thermostat.cool_set_point = int(value)
 79            elif prop == ThermostatProps.HEAT_SP:
 80                thermostat.heat_set_point = int(value)
 81            elif prop == ThermostatProps.FAN_MODE:
 82                thermostat.fan_mode = FanMode(value)
 83            elif prop == ThermostatProps.MODE_SYS:
 84                thermostat.hvac_mode = HVACMode(value)
 85            elif prop == ThermostatProps.CURRENT_SCENARIO:
 86                thermostat.preset = Preset(value)
 87            elif prop == ThermostatProps.TEMPERATURE:
 88                thermostat.temperature = float(value)
 89            elif prop == ThermostatProps.IOT_STATE:
 90                thermostat.available = value == 'connected'
 91            elif prop == ThermostatProps.HUMIDITY:
 92                thermostat.humidity = int(value)
 93            elif prop == ThermostatProps.WORKING_STATE:
 94                thermostat.hvac_state = HVACState(value)
 95
 96        return thermostat
 97
 98    async def get_thermostats(self) -> List[Thermostat]:
 99        if self._devices is None:
100            self._devices = await self.get_object_list()
101
102        thermostats = [device for device in self._devices if device.type is DeviceTypes.THERMOSTAT]
103
104        return [Thermostat(thermostat.raw_dict) for thermostat in thermostats]
105
106    async def set_cool_point(self, thermostat: Device, temp: int):
107        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.COOL_SP, temp)
108
109    async def set_heat_point(self, thermostat: Device, temp: int):
110        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.HEAT_SP, temp)
111
112    async def set_hvac_mode(self, thermostat: Device, hvac_mode: HVACMode):
113        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.MODE_SYS, hvac_mode.value)
114
115    async def set_fan_mode(self, thermostat: Device, fan_mode: FanMode):
116        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.FAN_MODE, fan_mode.value)
117
118    async def set_preset(self, thermostat: Thermostat, preset: Preset):
119        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.CURRENT_SCENARIO, preset.value)
120
121    async def _thermostat_get_iot_prop(self, device: Device) -> Dict[Any, Any]:
122        url = "https://wyze-earth-service.wyzecam.com/plugin/earth/get_iot_prop"
123        keys = 'trigger_off_val,emheat,temperature,humidity,time2temp_val,protect_time,mode_sys,heat_sp,cool_sp,' \
124                'current_scenario,config_scenario,temp_unit,fan_mode,iot_state,w_city_id,w_lat,w_lon,working_state,' \
125                'dev_hold,dev_holdtime,asw_hold,app_version,setup_state,wiring_logic_id,save_comfort_balance,' \
126                'kid_lock,calibrate_humidity,calibrate_temperature,fancirc_time,query_schedule'
127        return await self._get_iot_prop(url, device, keys)
128
129    async def _thermostat_set_iot_prop(self, device: Device, prop: ThermostatProps, value: Any) -> None:
130        url = "https://wyze-earth-service.wyzecam.com/plugin/earth/set_iot_prop_by_topic"
131        return await self._set_iot_prop(url, device, prop.value, value)
class HVACMode(enum.Enum):
17class HVACMode(Enum):
18    AUTO = "auto"
19    HEAT = "heat"
20    COOL = "cool"
21    OFF = "off"
AUTO = <HVACMode.AUTO: 'auto'>
HEAT = <HVACMode.HEAT: 'heat'>
COOL = <HVACMode.COOL: 'cool'>
OFF = <HVACMode.OFF: 'off'>
class FanMode(enum.Enum):
24class FanMode(Enum):  # auto, on
25    AUTO = "auto"
26    ON = "on"
AUTO = <FanMode.AUTO: 'auto'>
ON = <FanMode.ON: 'on'>
class TemperatureUnit(enum.Enum):
29class TemperatureUnit(Enum):
30    FAHRENHEIT = "F"
31    CELSIUS = "C"
FAHRENHEIT = <TemperatureUnit.FAHRENHEIT: 'F'>
CELSIUS = <TemperatureUnit.CELSIUS: 'C'>
class Preset(enum.Enum):
34class Preset(Enum):
35    HOME = "home"
36    AWAY = "away"
37    SLEEP = "sleep"
HOME = <Preset.HOME: 'home'>
AWAY = <Preset.AWAY: 'away'>
SLEEP = <Preset.SLEEP: 'sleep'>
class HVACState(enum.Enum):
40class HVACState(Enum):
41    COOLING = 'cooling'
42    HEATING = 'heating'
43    IDLE = 'idle'
COOLING = <HVACState.COOLING: 'cooling'>
HEATING = <HVACState.HEATING: 'heating'>
IDLE = <HVACState.IDLE: 'idle'>
class Thermostat(wyzeapy.types.Device):
46class Thermostat(Device):
47    def __init__(self, dictionary: Dict[Any, Any]):
48        super().__init__(dictionary)
49
50        self.temp_unit: TemperatureUnit = TemperatureUnit.FAHRENHEIT
51        self.cool_set_point: int = 74
52        self.heat_set_point: int = 64
53        self.fan_mode: FanMode = FanMode.AUTO
54        self.hvac_mode: HVACMode = HVACMode.AUTO
55        self.preset: Preset = Preset.HOME
56        self.temperature: float = 71
57        self.available: bool = True
58        self.humidity: int = 50
59        self.hvac_state: HVACState = HVACState.IDLE
Thermostat(dictionary: Dict[Any, Any])
47    def __init__(self, dictionary: Dict[Any, Any]):
48        super().__init__(dictionary)
49
50        self.temp_unit: TemperatureUnit = TemperatureUnit.FAHRENHEIT
51        self.cool_set_point: int = 74
52        self.heat_set_point: int = 64
53        self.fan_mode: FanMode = FanMode.AUTO
54        self.hvac_mode: HVACMode = HVACMode.AUTO
55        self.preset: Preset = Preset.HOME
56        self.temperature: float = 71
57        self.available: bool = True
58        self.humidity: int = 50
59        self.hvac_state: HVACState = HVACState.IDLE
temp_unit: TemperatureUnit
cool_set_point: int
heat_set_point: int
fan_mode: FanMode
hvac_mode: HVACMode
preset: Preset
temperature: float
available: bool
humidity: int
hvac_state: HVACState
class ThermostatService(wyzeapy.services.base_service.BaseService):
 62class ThermostatService(BaseService):
 63    async def update(self, thermostat: Thermostat) -> Thermostat:
 64        properties = (await self._thermostat_get_iot_prop(thermostat))['data']['props']
 65
 66        device_props = []
 67        for property in properties:
 68            try:
 69                prop = ThermostatProps(property)
 70                device_props.append((prop, properties[property]))
 71            except ValueError as e:
 72                _LOGGER.debug(f"{e} with value {properties[property]}")
 73
 74        thermostat_props = device_props
 75        for prop, value in thermostat_props:
 76            if prop == ThermostatProps.TEMP_UNIT:
 77                thermostat.temp_unit = TemperatureUnit(value)
 78            elif prop == ThermostatProps.COOL_SP:
 79                thermostat.cool_set_point = int(value)
 80            elif prop == ThermostatProps.HEAT_SP:
 81                thermostat.heat_set_point = int(value)
 82            elif prop == ThermostatProps.FAN_MODE:
 83                thermostat.fan_mode = FanMode(value)
 84            elif prop == ThermostatProps.MODE_SYS:
 85                thermostat.hvac_mode = HVACMode(value)
 86            elif prop == ThermostatProps.CURRENT_SCENARIO:
 87                thermostat.preset = Preset(value)
 88            elif prop == ThermostatProps.TEMPERATURE:
 89                thermostat.temperature = float(value)
 90            elif prop == ThermostatProps.IOT_STATE:
 91                thermostat.available = value == 'connected'
 92            elif prop == ThermostatProps.HUMIDITY:
 93                thermostat.humidity = int(value)
 94            elif prop == ThermostatProps.WORKING_STATE:
 95                thermostat.hvac_state = HVACState(value)
 96
 97        return thermostat
 98
 99    async def get_thermostats(self) -> List[Thermostat]:
100        if self._devices is None:
101            self._devices = await self.get_object_list()
102
103        thermostats = [device for device in self._devices if device.type is DeviceTypes.THERMOSTAT]
104
105        return [Thermostat(thermostat.raw_dict) for thermostat in thermostats]
106
107    async def set_cool_point(self, thermostat: Device, temp: int):
108        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.COOL_SP, temp)
109
110    async def set_heat_point(self, thermostat: Device, temp: int):
111        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.HEAT_SP, temp)
112
113    async def set_hvac_mode(self, thermostat: Device, hvac_mode: HVACMode):
114        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.MODE_SYS, hvac_mode.value)
115
116    async def set_fan_mode(self, thermostat: Device, fan_mode: FanMode):
117        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.FAN_MODE, fan_mode.value)
118
119    async def set_preset(self, thermostat: Thermostat, preset: Preset):
120        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.CURRENT_SCENARIO, preset.value)
121
122    async def _thermostat_get_iot_prop(self, device: Device) -> Dict[Any, Any]:
123        url = "https://wyze-earth-service.wyzecam.com/plugin/earth/get_iot_prop"
124        keys = 'trigger_off_val,emheat,temperature,humidity,time2temp_val,protect_time,mode_sys,heat_sp,cool_sp,' \
125                'current_scenario,config_scenario,temp_unit,fan_mode,iot_state,w_city_id,w_lat,w_lon,working_state,' \
126                'dev_hold,dev_holdtime,asw_hold,app_version,setup_state,wiring_logic_id,save_comfort_balance,' \
127                'kid_lock,calibrate_humidity,calibrate_temperature,fancirc_time,query_schedule'
128        return await self._get_iot_prop(url, device, keys)
129
130    async def _thermostat_set_iot_prop(self, device: Device, prop: ThermostatProps, value: Any) -> None:
131        url = "https://wyze-earth-service.wyzecam.com/plugin/earth/set_iot_prop_by_topic"
132        return await self._set_iot_prop(url, device, prop.value, value)

Base service class for interacting with Wyze devices.

async def update( self, thermostat: Thermostat) -> Thermostat:
63    async def update(self, thermostat: Thermostat) -> Thermostat:
64        properties = (await self._thermostat_get_iot_prop(thermostat))['data']['props']
65
66        device_props = []
67        for property in properties:
68            try:
69                prop = ThermostatProps(property)
70                device_props.append((prop, properties[property]))
71            except ValueError as e:
72                _LOGGER.debug(f"{e} with value {properties[property]}")
73
74        thermostat_props = device_props
75        for prop, value in thermostat_props:
76            if prop == ThermostatProps.TEMP_UNIT:
77                thermostat.temp_unit = TemperatureUnit(value)
78            elif prop == ThermostatProps.COOL_SP:
79                thermostat.cool_set_point = int(value)
80            elif prop == ThermostatProps.HEAT_SP:
81                thermostat.heat_set_point = int(value)
82            elif prop == ThermostatProps.FAN_MODE:
83                thermostat.fan_mode = FanMode(value)
84            elif prop == ThermostatProps.MODE_SYS:
85                thermostat.hvac_mode = HVACMode(value)
86            elif prop == ThermostatProps.CURRENT_SCENARIO:
87                thermostat.preset = Preset(value)
88            elif prop == ThermostatProps.TEMPERATURE:
89                thermostat.temperature = float(value)
90            elif prop == ThermostatProps.IOT_STATE:
91                thermostat.available = value == 'connected'
92            elif prop == ThermostatProps.HUMIDITY:
93                thermostat.humidity = int(value)
94            elif prop == ThermostatProps.WORKING_STATE:
95                thermostat.hvac_state = HVACState(value)
96
97        return thermostat
async def get_thermostats(self) -> List[Thermostat]:
 99    async def get_thermostats(self) -> List[Thermostat]:
100        if self._devices is None:
101            self._devices = await self.get_object_list()
102
103        thermostats = [device for device in self._devices if device.type is DeviceTypes.THERMOSTAT]
104
105        return [Thermostat(thermostat.raw_dict) for thermostat in thermostats]
async def set_cool_point(self, thermostat: wyzeapy.types.Device, temp: int):
107    async def set_cool_point(self, thermostat: Device, temp: int):
108        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.COOL_SP, temp)
async def set_heat_point(self, thermostat: wyzeapy.types.Device, temp: int):
110    async def set_heat_point(self, thermostat: Device, temp: int):
111        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.HEAT_SP, temp)
async def set_hvac_mode( self, thermostat: wyzeapy.types.Device, hvac_mode: HVACMode):
113    async def set_hvac_mode(self, thermostat: Device, hvac_mode: HVACMode):
114        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.MODE_SYS, hvac_mode.value)
async def set_fan_mode( self, thermostat: wyzeapy.types.Device, fan_mode: FanMode):
116    async def set_fan_mode(self, thermostat: Device, fan_mode: FanMode):
117        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.FAN_MODE, fan_mode.value)
async def set_preset( self, thermostat: Thermostat, preset: Preset):
119    async def set_preset(self, thermostat: Thermostat, preset: Preset):
120        await self._thermostat_set_iot_prop(thermostat, ThermostatProps.CURRENT_SCENARIO, preset.value)