初始化config文件
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
"""Support for Xiaomi water heaters."""
|
||||
import logging
|
||||
import math
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_TEMPERATURE,
|
||||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.components.water_heater import (
|
||||
DOMAIN as ENTITY_DOMAIN,
|
||||
WaterHeaterEntity,
|
||||
WaterHeaterEntityFeature, # v2022.5
|
||||
)
|
||||
|
||||
from . import (
|
||||
DOMAIN,
|
||||
CONF_MODEL,
|
||||
XIAOMI_CONFIG_SCHEMA as PLATFORM_SCHEMA, # noqa: F401
|
||||
HassEntry,
|
||||
MiotToggleEntity,
|
||||
async_setup_config_entry,
|
||||
bind_services_to_entries,
|
||||
)
|
||||
from .core.miot_spec import (
|
||||
MiotSpec,
|
||||
MiotService,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
DATA_KEY = f'{ENTITY_DOMAIN}.{DOMAIN}'
|
||||
|
||||
DEFAULT_MIN_TEMP = 40
|
||||
DEFAULT_MAX_TEMP = 65
|
||||
|
||||
SERVICE_TO_METHOD = {}
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
HassEntry.init(hass, config_entry).new_adder(ENTITY_DOMAIN, async_add_entities)
|
||||
await async_setup_config_entry(hass, config_entry, async_setup_platform, async_add_entities, ENTITY_DOMAIN)
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||
hass.data.setdefault(DATA_KEY, {})
|
||||
hass.data[DOMAIN]['add_entities'][ENTITY_DOMAIN] = async_add_entities
|
||||
config['hass'] = hass
|
||||
model = str(config.get(CONF_MODEL) or '')
|
||||
spec = hass.data[DOMAIN]['miot_specs'].get(model)
|
||||
entities = []
|
||||
if isinstance(spec, MiotSpec):
|
||||
for srv in spec.get_services(ENTITY_DOMAIN, 'kettle', 'water_dispenser'):
|
||||
if not srv.get_property('mode', 'target_temperature'):
|
||||
continue
|
||||
entities.append(MiotWaterHeaterEntity(config, srv))
|
||||
for entity in entities:
|
||||
hass.data[DOMAIN]['entities'][entity.unique_id] = entity
|
||||
async_add_entities(entities, update_before_add=True)
|
||||
bind_services_to_entries(hass, SERVICE_TO_METHOD)
|
||||
|
||||
|
||||
class MiotWaterHeaterEntity(MiotToggleEntity, WaterHeaterEntity):
|
||||
def __init__(self, config, miot_service: MiotService):
|
||||
super().__init__(miot_service, config=config, logger=_LOGGER)
|
||||
|
||||
self._prop_status = miot_service.get_property('status')
|
||||
self._prop_mode = miot_service.get_property('mode')
|
||||
self._prop_modes = []
|
||||
if self._prop_mode:
|
||||
self._prop_modes.append(self._prop_mode)
|
||||
self._prop_modes.extend(miot_service.get_properties('water_level'))
|
||||
self._prop_temperature = miot_service.get_property('temperature', 'indoor_temperature')
|
||||
self._prop_target_temp = miot_service.get_property('target_temperature')
|
||||
self._prev_target_temp = None
|
||||
|
||||
if self._prop_target_temp:
|
||||
self._supported_features |= WaterHeaterEntityFeature.TARGET_TEMPERATURE
|
||||
if self._prop_modes:
|
||||
self._supported_features |= WaterHeaterEntityFeature.OPERATION_MODE
|
||||
|
||||
async def async_update(self):
|
||||
await super().async_update()
|
||||
if not self._available:
|
||||
return
|
||||
if self._prop_power:
|
||||
if not self._prop_power.readable and self._prop_status:
|
||||
# https://github.com/al-one/hass-xiaomi-miot/issues/30
|
||||
val = self._prop_status.from_device(self.device)
|
||||
if val is not None:
|
||||
off = val in self._prop_status.list_search('Off')
|
||||
await self.async_update_attrs({
|
||||
self._prop_power.full_name: not off,
|
||||
})
|
||||
|
||||
@property
|
||||
def current_operation(self):
|
||||
"""Return current operation ie. eco, electric, performance, ..."""
|
||||
for p in self._prop_modes:
|
||||
val = p.from_device(self.device)
|
||||
if val is not None:
|
||||
return p.list_description(val)
|
||||
return None
|
||||
|
||||
@property
|
||||
def operation_list(self):
|
||||
"""Return the list of available operation modes."""
|
||||
for p in self._prop_modes:
|
||||
return p.list_descriptions() or []
|
||||
return None
|
||||
|
||||
async def async_set_operation_mode(self, mode):
|
||||
"""Set new target operation mode."""
|
||||
for p in self._prop_modes:
|
||||
val = p.list_value(mode)
|
||||
return await self.async_set_property(p, val)
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def current_temperature(self):
|
||||
"""Return the current temperature."""
|
||||
if self._prop_temperature:
|
||||
return round(self._prop_temperature.from_device(self.device) or 0, 2)
|
||||
return None
|
||||
|
||||
@property
|
||||
def temperature_unit(self):
|
||||
prop = self._prop_temperature or self._prop_target_temp
|
||||
if prop:
|
||||
if prop.unit in ['celsius', UnitOfTemperature.CELSIUS]:
|
||||
return UnitOfTemperature.CELSIUS
|
||||
if prop.unit in ['fahrenheit', UnitOfTemperature.FAHRENHEIT]:
|
||||
return UnitOfTemperature.FAHRENHEIT
|
||||
if prop.unit in ['kelvin', UnitOfTemperature.KELVIN]:
|
||||
return UnitOfTemperature.KELVIN
|
||||
return UnitOfTemperature.CELSIUS
|
||||
|
||||
async def async_set_temperature(self, **kwargs):
|
||||
"""Set new target temperature."""
|
||||
if self._prop_target_temp:
|
||||
val = kwargs.get(ATTR_TEMPERATURE) or 0
|
||||
stp = self._prop_target_temp.range_step()
|
||||
if stp and stp > 1:
|
||||
val = round(val / stp) * stp
|
||||
elif self._prev_target_temp is None:
|
||||
val = round(val)
|
||||
elif val >= self._prev_target_temp:
|
||||
val = math.ceil(val)
|
||||
else:
|
||||
val = int(val)
|
||||
ret = await self.async_set_property(self._prop_target_temp, val)
|
||||
if ret:
|
||||
self._prev_target_temp = val
|
||||
return ret
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
"""Return the temperature we try to reach."""
|
||||
if self._prop_target_temp:
|
||||
val = round(self._prop_target_temp.from_device(self.device) or 0, 2)
|
||||
if val:
|
||||
self._prev_target_temp = val
|
||||
elif self._prev_target_temp:
|
||||
val = self._prev_target_temp
|
||||
return val
|
||||
return None
|
||||
|
||||
@property
|
||||
def target_temperature_high(self):
|
||||
"""Return the highbound target temperature we try to reach."""
|
||||
if self._prop_target_temp:
|
||||
return self._prop_target_temp.range_max()
|
||||
return None
|
||||
|
||||
@property
|
||||
def target_temperature_low(self):
|
||||
"""Return the lowbound target temperature we try to reach."""
|
||||
if self._prop_target_temp:
|
||||
return self._prop_target_temp.range_min()
|
||||
return None
|
||||
|
||||
@property
|
||||
def min_temp(self):
|
||||
"""Return the minimum temperature."""
|
||||
return self.target_temperature_low or DEFAULT_MIN_TEMP
|
||||
|
||||
@property
|
||||
def max_temp(self):
|
||||
"""Return the maximum temperature."""
|
||||
return self.target_temperature_high or DEFAULT_MAX_TEMP
|
||||
|
||||
@property
|
||||
def is_away_mode_on(self):
|
||||
"""Return true if away mode is on."""
|
||||
return None
|
||||
|
||||
def turn_away_mode_on(self):
|
||||
"""Turn away mode on."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def turn_away_mode_off(self):
|
||||
"""Turn away mode off."""
|
||||
raise NotImplementedError()
|
||||
Reference in New Issue
Block a user