Midea/midea_ac_lan/water_heater.py
2023-09-22 07:45:40 +02:00

287 lines
8.9 KiB
Python

import logging
from homeassistant.components.water_heater import *
from homeassistant.const import (
Platform,
TEMP_CELSIUS,
PRECISION_WHOLE,
PRECISION_HALVES,
ATTR_TEMPERATURE,
CONF_DEVICE_ID,
CONF_SWITCHES,
STATE_ON,
STATE_OFF,
)
from .const import (
DOMAIN,
DEVICES
)
from .midea.devices.e6.device import DeviceAttributes as E6Attributes
from .midea.devices.c3.device import DeviceAttributes as C3Attributes
from .midea.devices.cd.device import DeviceAttributes as CDAttributes
from .midea_devices import MIDEA_DEVICES
from .midea_entity import MideaEntity
E2_TEMPERATURE_MAX = 75
E2_TEMPERATURE_MIN = 30
E3_TEMPERATURE_MAX = 65
E3_TEMPERATURE_MIN = 35
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities):
device_id = config_entry.data.get(CONF_DEVICE_ID)
device = hass.data[DOMAIN][DEVICES].get(device_id)
extra_switches = config_entry.options.get(
CONF_SWITCHES, []
)
devs = []
for entity_key, config in MIDEA_DEVICES[device.device_type]["entities"].items():
if config["type"] == Platform.WATER_HEATER and (config.get("default") or entity_key in extra_switches):
if device.device_type == 0xE2:
devs.append(MideaE2WaterHeater(device, entity_key))
elif device.device_type == 0xE3:
devs.append(MideaE3WaterHeater(device, entity_key))
elif device.device_type == 0xE6:
devs.append(MideaE6WaterHeater(device, entity_key, config["use"]))
elif device.device_type == 0xC3:
devs.append(MideaC3WaterHeater(device, entity_key))
elif device.device_type == 0xCD:
devs.append(MideaCDWaterHeater(device, entity_key))
async_add_entities(devs)
class MideaWaterHeater(MideaEntity, WaterHeaterEntity):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
self._operations = []
@property
def state(self):
return STATE_ON if self._device.get_attribute("power") else STATE_OFF
@property
def supported_features(self):
return WaterHeaterEntityFeature.TARGET_TEMPERATURE
@property
def extra_state_attributes(self) -> dict:
attrs = self._device.attributes
if hasattr(self._device, "temperature_step"):
attrs["target_temp_step"] = self._device.temperature_step
return attrs
@property
def min_temp(self):
return NotImplementedError
@property
def max_temp(self):
return NotImplementedError
@property
def target_temperature_low(self):
return self.min_temp
@property
def target_temperature_high(self):
return self.max_temp
@property
def precision(self):
return PRECISION_WHOLE
@property
def temperature_unit(self):
return TEMP_CELSIUS
@property
def current_operation(self):
return self._device.get_attribute("mode")
@property
def current_temperature(self):
return self._device.get_attribute("current_temperature")
@property
def target_temperature(self):
return self._device.get_attribute("target_temperature")
def set_temperature(self, **kwargs):
if ATTR_TEMPERATURE not in kwargs:
return
temperature = int(kwargs.get(ATTR_TEMPERATURE))
self._device.set_attribute("target_temperature", temperature)
def set_operation_mode(self, operation_mode):
self._device.set_attribute(attr="mode", value=operation_mode)
@property
def operation_list(self):
return getattr(self._device, "preset_modes")
def turn_on(self):
self._device.set_attribute(attr="power", value=True)
def turn_off(self):
self._device.set_attribute(attr="power", value=False)
async def async_turn_on(self, **kwargs):
await self.hass.async_add_executor_job(ft.partial(self.turn_on, **kwargs))
async def async_turn_off(self, **kwargs):
await self.hass.async_add_executor_job(ft.partial(self.turn_off, **kwargs))
def update_state(self, status):
try:
self.schedule_update_ha_state()
except Exception as e:
_LOGGER.debug(f"Entity {self.entity_id} update_state {repr(e)}, status = {status}")
class MideaE2WaterHeater(MideaWaterHeater):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
@property
def min_temp(self):
return E2_TEMPERATURE_MIN
@property
def max_temp(self):
return E2_TEMPERATURE_MAX
class MideaE3WaterHeater(MideaWaterHeater):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
@property
def min_temp(self):
return E3_TEMPERATURE_MIN
@property
def max_temp(self):
return E3_TEMPERATURE_MAX
@property
def precision(self):
return PRECISION_HALVES if self._device.precision_halves else PRECISION_WHOLE
class MideaC3WaterHeater(MideaWaterHeater):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
@property
def state(self):
return STATE_ON if self._device.get_attribute(C3Attributes.dhw_power) else STATE_OFF
@property
def current_temperature(self):
return self._device.get_attribute(C3Attributes.tank_actual_temperature)
@property
def target_temperature(self):
return self._device.get_attribute(C3Attributes.dhw_target_temp)
def set_temperature(self, **kwargs):
if ATTR_TEMPERATURE not in kwargs:
return
temperature = int(kwargs.get(ATTR_TEMPERATURE))
self._device.set_attribute(C3Attributes.dhw_target_temp, temperature)
@property
def min_temp(self):
return self._device.get_attribute(C3Attributes.dhw_temp_min)
@property
def max_temp(self):
return self._device.get_attribute(C3Attributes.dhw_temp_max)
def turn_on(self):
self._device.set_attribute(attr=C3Attributes.dhw_power, value=True)
def turn_off(self):
self._device.set_attribute(attr=C3Attributes.dhw_power, value=False)
class MideaE6WaterHeater(MideaWaterHeater):
_powers = [
E6Attributes.heating_power,
E6Attributes.main_power,
]
_current_temperatures = [
E6Attributes.heating_leaving_temperature,
E6Attributes.bathing_leaving_temperature,
]
_target_temperatures = [
E6Attributes.heating_temperature,
E6Attributes.bathing_temperature,
]
def __init__(self, device, entity_key, use):
super().__init__(device, entity_key)
self._use = use
self._power_attr = MideaE6WaterHeater._powers[self._use]
self._current_temperature_attr = MideaE6WaterHeater._current_temperatures[self._use]
self._target_temperature_attr = MideaE6WaterHeater._target_temperatures[self._use]
@property
def state(self):
if self._use == 0: # for heating
return STATE_ON if \
self._device.get_attribute(E6Attributes.main_power) and \
self._device.get_attribute(E6Attributes.heating_power) \
else STATE_OFF
else: # for bathing
return STATE_ON if \
self._device.get_attribute(E6Attributes.main_power) \
else STATE_OFF
@property
def current_temperature(self):
return self._device.get_attribute(self._current_temperature_attr)
@property
def target_temperature(self):
return self._device.get_attribute(self._target_temperature_attr)
def set_temperature(self, **kwargs):
if ATTR_TEMPERATURE not in kwargs:
return
temperature = int(kwargs.get(ATTR_TEMPERATURE))
self._device.set_attribute(self._target_temperature_attr, temperature)
@property
def min_temp(self):
return self._device.get_attribute(E6Attributes.min_temperature)[self._use]
@property
def max_temp(self):
return self._device.get_attribute(E6Attributes.max_temperature)[self._use]
def turn_on(self):
self._device.set_attribute(attr=self._power_attr, value=True)
def turn_off(self):
self._device.set_attribute(attr=self._power_attr, value=False)
class MideaCDWaterHeater(MideaWaterHeater):
def __init__(self, device, entity_key):
super().__init__(device, entity_key)
@property
def supported_features(self):
return WaterHeaterEntityFeature.TARGET_TEMPERATURE | \
WaterHeaterEntityFeature.OPERATION_MODE
@property
def min_temp(self):
return self._device.get_attribute(CDAttributes.min_temperature)
@property
def max_temp(self):
return self._device.get_attribute(CDAttributes.max_temperature)