287 lines
8.9 KiB
Python
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)
|