Compare commits

...

18 Commits

Author SHA1 Message Date
ted
50279d73c0
Merge ade18deb7e into 0ef8cb6370 2025-03-13 18:47:13 +08:00
Li Shuzhen
0ef8cb6370
fix: xiaomi.aircondition.m9 humidity-range unit (#878)
Some checks are pending
Tests / check-rule-format (push) Waiting to run
Validate / validate-hassfest (push) Waiting to run
Validate / validate-hacs (push) Waiting to run
Validate / validate-lint (push) Waiting to run
Validate / validate-setup (push) Waiting to run
2025-03-13 17:41:02 +08:00
Li Shuzhen
8f0a69c611
feat: convert the mode of the ptc bath heater to the preset mode (#874) 2025-03-13 17:37:44 +08:00
ted
ade18deb7e
Merge branch 'XiaoMi:main' into main 2025-03-13 14:47:08 +08:00
ted
4e1185f4e5
Merge branch 'XiaoMi:main' into main 2025-02-28 20:20:55 +08:00
ted
6ad8da42be
Merge branch 'XiaoMi:main' into main 2025-02-25 10:45:50 +08:00
ted
4aa6bb579f
Merge branch 'XiaoMi:main' into main 2025-02-19 14:05:50 +08:00
ted
e83aa9367e
Merge branch 'XiaoMi:main' into main 2025-01-31 15:25:58 +08:00
tedwang
04c44f36b1 Merge branch 'main' of https://github.com/zghnwsq/fork_ha_xiaomi_home into fix_vacuum_warn 2025-01-23 11:01:23 +08:00
ted
a40363d3e6
Merge branch 'XiaoMi:main' into main 2025-01-23 10:17:55 +08:00
tedwang
13e6863678 fix: Fix the HA warning in the logs related to vacuum state setting
Adapt to new vacuum state property, set the activity property instead of directly setting the state property.
2025-01-23 10:09:15 +08:00
ted
b0d0d6b107
Merge branch 'XiaoMi:main' into main 2025-01-21 16:27:32 +08:00
ted
085caff660
Merge branch 'XiaoMi:main' into main 2025-01-18 16:34:16 +08:00
ted
fe3756db9b
Merge branch 'XiaoMi:main' into main 2025-01-16 09:18:40 +08:00
ted
bf33f0c60d
Merge branch 'XiaoMi:main' into main 2025-01-13 13:58:58 +08:00
ted
72f3a5df3e
Merge branch 'XiaoMi:main' into main 2025-01-11 20:35:24 +08:00
ted
f452611b87
Merge branch 'XiaoMi:main' into main 2025-01-08 11:43:20 +08:00
tedwang
36d5a3e4de docs: fix table header misplacement
fix table header misplacement
2025-01-03 10:54:41 +08:00
5 changed files with 101 additions and 44 deletions

View File

@ -605,7 +605,7 @@ class AirConditioner(FeatureOnOff, FeatureTargetTemperature,
class PtcBathHeater(FeatureTargetTemperature, FeatureTemperature,
FeatureFanMode, FeatureSwingMode):
FeatureFanMode, FeatureSwingMode, FeaturePresetMode):
"""Ptc bath heater"""
_prop_mode: Optional[MIoTSpecProperty]
_hvac_mode_map: Optional[dict[int, HVACMode]]
@ -626,26 +626,20 @@ class PtcBathHeater(FeatureTargetTemperature, FeatureTemperature,
continue
self._hvac_mode_map = {}
for item in prop.value_list.items:
if item.name in {'off', 'idle'
} and (HVACMode.OFF not in list(
self._hvac_mode_map.values())):
self._hvac_mode_map[item.value] = HVACMode.OFF
elif item.name in {'auto'}:
if item.name in {'off', 'idle'}:
if (HVACMode.OFF
not in list(self._hvac_mode_map.values())):
self._hvac_mode_map[item.value] = HVACMode.OFF
elif (HVACMode.AUTO
not in list(self._hvac_mode_map.values())):
self._hvac_mode_map[item.value] = HVACMode.AUTO
elif item.name in {'ventilate'}:
self._hvac_mode_map[item.value] = HVACMode.COOL
elif item.name in {'heat', 'quick_heat'
} and (HVACMode.HEAT not in list(
self._hvac_mode_map.values())):
self._hvac_mode_map[item.value] = HVACMode.HEAT
elif item.name in {'defog'}:
self._hvac_mode_map[item.value] = HVACMode.HEAT_COOL
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 HVACMode.OFF in self._attr_hvac_modes:
self._prop_mode = prop
else:
_LOGGER.error('no idle mode, %s', self.entity_id)
# preset modes
self._init_preset_modes('ptc-bath-heater', 'mode')
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set the target hvac mode."""
@ -655,15 +649,20 @@ class PtcBathHeater(FeatureTargetTemperature, FeatureTemperature,
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}')
f'set ptc-bath-heater {hvac_mode} failed, {self.entity_id}')
@property
def hvac_mode(self) -> Optional[HVACMode]:
"""The current hvac mode."""
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)
if self._prop_mode is None:
return None
mode_value = self.get_map_value(
map_=self._hvac_mode_map,
key=self.get_prop_value(prop=self._prop_mode))
if mode_value == HVACMode.OFF or mode_value is None:
return mode_value
return HVACMode.AUTO if (HVACMode.AUTO
in self._attr_hvac_modes) else None
class Thermostat(FeatureOnOff, FeatureTargetTemperature, FeatureTemperature,

View File

@ -213,6 +213,12 @@ class MIoTSpecValueList:
return item.description
return None
def get_name_by_value(self, value: Any) -> Optional[str]:
for item in self.items:
if item.value == value:
return item.name
return None
def dump(self) -> list:
return [item.dump() for item in self.items]

View File

@ -68,3 +68,11 @@ urn:miot-spec-v2:device:bath-heater:0000A028:mike-2:1:
urn:miot-spec-v2:device:fan:0000A005:xiaomi-p51:1:
prop.2.2:
name: fan-level-a
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:6:
prop.10.6:
unit: none
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:1: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:6
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:6
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:3: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:6
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:4: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:6
urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:5: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:6

View File

@ -138,7 +138,7 @@ SPEC_DEVICE_TRANS_MAP: dict = {
'optional': {
'properties': {'mode', 'target-humidity'}
}
},
}
},
'optional': {
'environment': {
@ -164,8 +164,7 @@ SPEC_DEVICE_TRANS_MAP: dict = {
'continue-sweep',
'stop-and-gocharge'
}
},
}
}
},
'optional': {
@ -178,9 +177,9 @@ SPEC_DEVICE_TRANS_MAP: dict = {
'required': {
'properties': {
'battery-level': {'read'}
},
}
}
},
}
},
'entity': 'vacuum'
},
@ -196,7 +195,7 @@ SPEC_DEVICE_TRANS_MAP: dict = {
},
'optional': {
'properties': {'target-humidity'}
},
}
}
},
'optional': {
@ -237,7 +236,7 @@ SPEC_DEVICE_TRANS_MAP: dict = {
'properties': {
'target-temperature', 'mode', 'fan-level',
'temperature'}
},
}
}
},
'optional': {
@ -246,7 +245,7 @@ SPEC_DEVICE_TRANS_MAP: dict = {
'optional': {
'properties': {'temperature', 'relative-humidity'}
}
},
}
},
'entity': 'thermostat'
},
@ -260,7 +259,7 @@ SPEC_DEVICE_TRANS_MAP: dict = {
},
'optional': {
'properties': {'target-temperature', 'heat-level'}
},
}
}
},
'optional': {
@ -269,20 +268,21 @@ SPEC_DEVICE_TRANS_MAP: dict = {
'optional': {
'properties': {'temperature', 'relative-humidity'}
}
},
}
},
'entity': 'heater'
},
'bath-heater': {
'required': {
'ptc-bath-heater': {
'required': {},
'optional': {
'required': {
'properties': {
'target-temperature', 'heat-level',
'temperature', 'mode'
'mode':{'read', 'write'}
}
},
'optional': {
'properties': {'target-temperature', 'temperature'}
}
}
},
'optional': {
@ -292,7 +292,13 @@ SPEC_DEVICE_TRANS_MAP: dict = {
'properties': {
'on', 'fan-level', 'horizontal-swing', 'vertical-swing'
}
},
}
},
'environment': {
'required': {},
'optional': {
'properties': {'temperature'}
}
}
},
'entity': 'bath-heater',
@ -308,7 +314,7 @@ SPEC_DEVICE_TRANS_MAP: dict = {
},
'optional': {
'properties': {'mode', 'temperature'}
},
}
}
},
'optional': {},
@ -400,7 +406,7 @@ SPEC_SERVICE_TRANS_MAP: dict = {
},
'optional': {
'properties': {
'motor-control', 'status', 'current-position', 'target-position'
'status', 'current-position', 'target-position'
}
},
'entity': 'cover'

View File

@ -54,7 +54,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.vacuum import (
StateVacuumEntity,
VacuumEntityFeature
VacuumEntityFeature,
VacuumActivity
)
from .miot.const import DOMAIN
@ -191,10 +192,47 @@ class Vacuum(MIoTServiceEntity, StateVacuumEntity):
@property
def state(self) -> Optional[str]:
"""Return the current state of the vacuum cleaner."""
"""Return the current state of the vacuum cleaner.
To fix the HA warning below:
Detected that custom integration 'xiaomi_home' is setting state
directly.Entity XXX(<class 'custom_components.xiaomi_home.vacuum
.Vacuum'>)should implement the 'activity' property and return
its state using the VacuumActivity enum.This will stop working in
Home Assistant 2026.1.
Refer to
https://developers.home-assistant.io/blog/2024/12/08/new-vacuum-state-property
There are only 6 states in VacuumActivity enum. To be compatible with
more constants, try get matching VacuumActivity enum first, return state
string as before if there is no match. In Home Assistant 2026.1, every
state should map to a VacuumActivity enum.
"""
if (activity := self.activity) is not None:
return activity
return self.get_map_value(
map_=self._status_map,
key=self.get_prop_value(prop=self._prop_status))
key=self.get_prop_value(prop=self._prop_status)
)
@property
def activity(self) -> VacuumActivity | None:
"""Return the current vacuum activity."""
state_trans_map = {
'Sleep': VacuumActivity.IDLE,
'Idle': VacuumActivity.IDLE,
'Paused': VacuumActivity.PAUSED,
'Go Charging': VacuumActivity.RETURNING,
'Charging': VacuumActivity.DOCKED,
'Sweeping': VacuumActivity.CLEANING,
'Sweeping and Mopping': VacuumActivity.CLEANING,
'Mopping': VacuumActivity.CLEANING,
'Error': VacuumActivity.ERROR,
}
prop_value = self.get_prop_value(prop=self._prop_status)
state_name = self._prop_status.value_list.get_name_by_value(prop_value)
return state_trans_map.get(state_name)
@property
def battery_level(self) -> Optional[int]: