mirror of
https://github.com/XiaoMi/ha_xiaomi_home.git
synced 2025-04-01 23:35:30 +08:00
feat: thermostat preset mode (#833)
Some checks are pending
Some checks are pending
This commit is contained in:
parent
4482d257dc
commit
97d89b3a04
@ -189,7 +189,7 @@ class FeaturePresetMode(MIoTServiceEntity, ClimateEntity):
|
|||||||
for prop in self.entity_data.props:
|
for prop in self.entity_data.props:
|
||||||
if prop.name == prop_name and prop.service.name == service_name:
|
if prop.name == prop_name and prop.service.name == service_name:
|
||||||
if not prop.value_list:
|
if not prop.value_list:
|
||||||
_LOGGER.error('invalid %s %s value_list, %s',service_name,
|
_LOGGER.error('invalid %s %s value_list, %s', service_name,
|
||||||
prop_name, self.entity_id)
|
prop_name, self.entity_id)
|
||||||
continue
|
continue
|
||||||
self._mode_map = prop.value_list.to_map()
|
self._mode_map = prop.value_list.to_map()
|
||||||
@ -229,7 +229,9 @@ class FeatureFanMode(MIoTServiceEntity, ClimateEntity):
|
|||||||
super().__init__(miot_device=miot_device, entity_data=entity_data)
|
super().__init__(miot_device=miot_device, entity_data=entity_data)
|
||||||
# properties
|
# properties
|
||||||
for prop in entity_data.props:
|
for prop in entity_data.props:
|
||||||
if prop.name == 'fan-level' and prop.service.name == 'fan-control':
|
if (prop.name == 'fan-level' and
|
||||||
|
(prop.service.name == 'fan-control' or
|
||||||
|
prop.service.name == 'thermostat')):
|
||||||
if not prop.value_list:
|
if not prop.value_list:
|
||||||
_LOGGER.error('invalid fan-level value_list, %s',
|
_LOGGER.error('invalid fan-level value_list, %s',
|
||||||
self.entity_id)
|
self.entity_id)
|
||||||
@ -665,78 +667,31 @@ class PtcBathHeater(FeatureTargetTemperature, FeatureTemperature,
|
|||||||
|
|
||||||
|
|
||||||
class Thermostat(FeatureOnOff, FeatureTargetTemperature, FeatureTemperature,
|
class Thermostat(FeatureOnOff, FeatureTargetTemperature, FeatureTemperature,
|
||||||
FeatureHumidity, FeatureFanMode):
|
FeatureHumidity, FeatureFanMode, FeaturePresetMode):
|
||||||
"""Thermostat"""
|
"""Thermostat"""
|
||||||
_prop_mode: Optional[MIoTSpecProperty]
|
|
||||||
_hvac_mode_map: Optional[dict[int, HVACMode]]
|
|
||||||
|
|
||||||
def __init__(self, miot_device: MIoTDevice,
|
def __init__(self, miot_device: MIoTDevice,
|
||||||
entity_data: MIoTEntityData) -> None:
|
entity_data: MIoTEntityData) -> None:
|
||||||
"""Initialize the thermostat."""
|
"""Initialize the thermostat."""
|
||||||
self._prop_mode = None
|
|
||||||
self._hvac_mode_map = None
|
|
||||||
|
|
||||||
super().__init__(miot_device=miot_device, entity_data=entity_data)
|
super().__init__(miot_device=miot_device, entity_data=entity_data)
|
||||||
|
|
||||||
self._attr_icon = 'mdi:thermostat'
|
self._attr_icon = 'mdi:thermostat'
|
||||||
# hvac modes
|
# hvac modes
|
||||||
self._attr_hvac_modes = None
|
self._attr_hvac_modes = [HVACMode.AUTO, HVACMode.OFF]
|
||||||
for prop in entity_data.props:
|
# preset modes
|
||||||
if prop.name == 'mode':
|
self._init_preset_modes('thermostat', 'mode')
|
||||||
if not prop.value_list:
|
|
||||||
_LOGGER.error('invalid mode value_list, %s', self.entity_id)
|
|
||||||
continue
|
|
||||||
self._hvac_mode_map = {}
|
|
||||||
for item in prop.value_list.items:
|
|
||||||
if item.name in {'off', 'idle'}:
|
|
||||||
self._hvac_mode_map[item.value] = HVACMode.OFF
|
|
||||||
elif item.name in {'auto'}:
|
|
||||||
self._hvac_mode_map[item.value] = HVACMode.AUTO
|
|
||||||
elif item.name in {'cool'}:
|
|
||||||
self._hvac_mode_map[item.value] = HVACMode.COOL
|
|
||||||
elif item.name in {'heat'}:
|
|
||||||
self._hvac_mode_map[item.value] = HVACMode.HEAT
|
|
||||||
elif item.name in {'dry'}:
|
|
||||||
self._hvac_mode_map[item.value] = HVACMode.DRY
|
|
||||||
elif item.name in {'fan'}:
|
|
||||||
self._hvac_mode_map[item.value] = HVACMode.FAN_ONLY
|
|
||||||
self._attr_hvac_modes = list(self._hvac_mode_map.values())
|
|
||||||
self._prop_mode = prop
|
|
||||||
|
|
||||||
if self._attr_hvac_modes is None:
|
|
||||||
self._attr_hvac_modes = [HVACMode.OFF, HVACMode.AUTO]
|
|
||||||
elif HVACMode.OFF not in self._attr_hvac_modes:
|
|
||||||
self._attr_hvac_modes.insert(0, HVACMode.OFF)
|
|
||||||
|
|
||||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||||
"""Set the target hvac mode."""
|
"""Set the target hvac mode."""
|
||||||
# set the device off
|
await self.set_property_async(
|
||||||
if hvac_mode == HVACMode.OFF:
|
prop=self._prop_on,
|
||||||
if not await self.set_property_async(prop=self._prop_on,
|
value=False if hvac_mode == HVACMode.OFF else True)
|
||||||
value=False):
|
|
||||||
raise RuntimeError(f'set climate prop.on failed, {hvac_mode}, '
|
|
||||||
f'{self.entity_id}')
|
|
||||||
return
|
|
||||||
# set the device on
|
|
||||||
elif self.get_prop_value(prop=self._prop_on) is False:
|
|
||||||
await self.set_property_async(prop=self._prop_on, value=True)
|
|
||||||
# set mode
|
|
||||||
if self._prop_mode is None:
|
|
||||||
return
|
|
||||||
mode_value = self.get_map_key(map_=self._hvac_mode_map, value=hvac_mode)
|
|
||||||
if mode_value is None or not await self.set_property_async(
|
|
||||||
prop=self._prop_mode, value=mode_value):
|
|
||||||
raise RuntimeError(
|
|
||||||
f'set climate prop.mode failed, {hvac_mode}, {self.entity_id}')
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hvac_mode(self) -> Optional[HVACMode]:
|
def hvac_mode(self) -> Optional[HVACMode]:
|
||||||
"""The current hvac mode."""
|
"""The current hvac mode."""
|
||||||
if self.get_prop_value(prop=self._prop_on) is False:
|
return (HVACMode.AUTO if self.get_prop_value(
|
||||||
return HVACMode.OFF
|
prop=self._prop_on) else HVACMode.OFF)
|
||||||
return (self.get_map_value(map_=self._hvac_mode_map,
|
|
||||||
key=self.get_prop_value(
|
|
||||||
prop=self._prop_mode))
|
|
||||||
if self._prop_mode else None)
|
|
||||||
|
|
||||||
|
|
||||||
class ElectricBlanket(FeatureOnOff, FeatureTargetTemperature,
|
class ElectricBlanket(FeatureOnOff, FeatureTargetTemperature,
|
||||||
|
@ -1473,10 +1473,12 @@ class MIoTSpecParser:
|
|||||||
key=':'.join(p_type_strs[:5]))
|
key=':'.join(p_type_strs[:5]))
|
||||||
or property_['description']
|
or property_['description']
|
||||||
or spec_prop.name)
|
or spec_prop.name)
|
||||||
if 'value-range' in property_:
|
# Modify value-list before translation
|
||||||
spec_prop.value_range = property_['value-range']
|
v_list: list[dict] = self._spec_modify.get_prop_value_list(
|
||||||
elif 'value-list' in property_:
|
siid=service['iid'], piid=property_['iid'])
|
||||||
v_list: list[dict] = property_['value-list']
|
if (v_list is None) and ('value-list' in property_):
|
||||||
|
v_list = property_['value-list']
|
||||||
|
if v_list is not None:
|
||||||
for index, v in enumerate(v_list):
|
for index, v in enumerate(v_list):
|
||||||
if v['description'].strip() == '':
|
if v['description'].strip() == '':
|
||||||
v['description'] = f'v_{v["value"]}'
|
v['description'] = f'v_{v["value"]}'
|
||||||
@ -1490,6 +1492,8 @@ class MIoTSpecParser:
|
|||||||
f'{v["description"]}')
|
f'{v["description"]}')
|
||||||
or v['name'])
|
or v['name'])
|
||||||
spec_prop.value_list = MIoTSpecValueList.from_spec(v_list)
|
spec_prop.value_list = MIoTSpecValueList.from_spec(v_list)
|
||||||
|
if 'value-range' in property_:
|
||||||
|
spec_prop.value_range = property_['value-range']
|
||||||
elif property_['format'] == 'bool':
|
elif property_['format'] == 'bool':
|
||||||
v_tag = ':'.join(p_type_strs[:5])
|
v_tag = ':'.join(p_type_strs[:5])
|
||||||
v_descriptions = (
|
v_descriptions = (
|
||||||
@ -1514,10 +1518,6 @@ class MIoTSpecParser:
|
|||||||
siid=service['iid'], piid=property_['iid'])
|
siid=service['iid'], piid=property_['iid'])
|
||||||
if custom_range:
|
if custom_range:
|
||||||
spec_prop.value_range = custom_range
|
spec_prop.value_range = custom_range
|
||||||
custom_list = self._spec_modify.get_prop_value_list(
|
|
||||||
siid=service['iid'], piid=property_['iid'])
|
|
||||||
if custom_list:
|
|
||||||
spec_prop.value_list = custom_list
|
|
||||||
# Parse service event
|
# Parse service event
|
||||||
for event in service.get('events', []):
|
for event in service.get('events', []):
|
||||||
if (
|
if (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user