mirror of
https://github.com/XiaoMi/ha_xiaomi_home.git
synced 2026-01-18 16:10:44 +08:00
Compare commits
16 Commits
f33bc75d7f
...
e22d95a293
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e22d95a293 | ||
|
|
e69448f2eb | ||
|
|
4e1185f4e5 | ||
|
|
6ad8da42be | ||
|
|
4aa6bb579f | ||
|
|
e83aa9367e | ||
|
|
04c44f36b1 | ||
|
|
a40363d3e6 | ||
|
|
13e6863678 | ||
|
|
b0d0d6b107 | ||
|
|
085caff660 | ||
|
|
fe3756db9b | ||
|
|
bf33f0c60d | ||
|
|
72f3a5df3e | ||
|
|
f452611b87 | ||
|
|
36d5a3e4de |
@ -549,6 +549,10 @@ class MIoTDevice:
|
|||||||
# Optional actions
|
# Optional actions
|
||||||
# Optional events
|
# Optional events
|
||||||
miot_service.platform = platform
|
miot_service.platform = platform
|
||||||
|
# entity_category
|
||||||
|
if entity_category := SPEC_SERVICE_TRANS_MAP[service_name].get(
|
||||||
|
'entity_category', None):
|
||||||
|
miot_service.entity_category = entity_category
|
||||||
return entity_data
|
return entity_data
|
||||||
|
|
||||||
def parse_miot_property_entity(self, miot_prop: MIoTSpecProperty) -> bool:
|
def parse_miot_property_entity(self, miot_prop: MIoTSpecProperty) -> bool:
|
||||||
@ -899,6 +903,7 @@ class MIoTServiceEntity(Entity):
|
|||||||
self._attr_name = (
|
self._attr_name = (
|
||||||
f'{"* "if self.entity_data.spec.proprietary else " "}'
|
f'{"* "if self.entity_data.spec.proprietary else " "}'
|
||||||
f'{self.entity_data.spec.description_trans}')
|
f'{self.entity_data.spec.description_trans}')
|
||||||
|
self._attr_entity_category = entity_data.spec.entity_category
|
||||||
# Set entity attr
|
# Set entity attr
|
||||||
self._attr_unique_id = self.entity_id
|
self._attr_unique_id = self.entity_id
|
||||||
self._attr_should_poll = False
|
self._attr_should_poll = False
|
||||||
|
|||||||
@ -213,6 +213,12 @@ class MIoTSpecValueList:
|
|||||||
return item.description
|
return item.description
|
||||||
return None
|
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:
|
def dump(self) -> list:
|
||||||
return [item.dump() for item in self.items]
|
return [item.dump() for item in self.items]
|
||||||
|
|
||||||
@ -465,7 +471,7 @@ class _MIoTSpecBase:
|
|||||||
iid: int
|
iid: int
|
||||||
type_: str
|
type_: str
|
||||||
description: str
|
description: str
|
||||||
description_trans: str
|
description_trans: Optional[str]
|
||||||
proprietary: bool
|
proprietary: bool
|
||||||
need_filter: bool
|
need_filter: bool
|
||||||
name: str
|
name: str
|
||||||
@ -476,6 +482,7 @@ class _MIoTSpecBase:
|
|||||||
device_class: Any
|
device_class: Any
|
||||||
state_class: Any
|
state_class: Any
|
||||||
external_unit: Any
|
external_unit: Any
|
||||||
|
entity_category: Optional[str]
|
||||||
|
|
||||||
spec_id: int
|
spec_id: int
|
||||||
|
|
||||||
@ -494,6 +501,7 @@ class _MIoTSpecBase:
|
|||||||
self.device_class = None
|
self.device_class = None
|
||||||
self.state_class = None
|
self.state_class = None
|
||||||
self.external_unit = None
|
self.external_unit = None
|
||||||
|
self.entity_category = None
|
||||||
|
|
||||||
self.spec_id = hash(f'{self.type_}.{self.iid}')
|
self.spec_id = hash(f'{self.type_}.{self.iid}')
|
||||||
|
|
||||||
|
|||||||
@ -51,6 +51,7 @@ from homeassistant.components.event import EventDeviceClass
|
|||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
EntityCategory,
|
||||||
LIGHT_LUX,
|
LIGHT_LUX,
|
||||||
UnitOfEnergy,
|
UnitOfEnergy,
|
||||||
UnitOfPower,
|
UnitOfPower,
|
||||||
@ -330,7 +331,8 @@ SPEC_DEVICE_TRANS_MAP: dict = {
|
|||||||
'events': set<event instance name: str>,
|
'events': set<event instance name: str>,
|
||||||
'actions': set<action instance name: str>
|
'actions': set<action instance name: str>
|
||||||
},
|
},
|
||||||
'entity': str
|
'entity': str,
|
||||||
|
'entity_category'?: str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -348,10 +350,23 @@ SPEC_SERVICE_TRANS_MAP: dict = {
|
|||||||
},
|
},
|
||||||
'entity': 'light'
|
'entity': 'light'
|
||||||
},
|
},
|
||||||
'indicator-light': 'light',
|
|
||||||
'ambient-light': 'light',
|
'ambient-light': 'light',
|
||||||
'night-light': 'light',
|
'night-light': 'light',
|
||||||
'white-light': 'light',
|
'white-light': 'light',
|
||||||
|
'indicator-light': {
|
||||||
|
'required': {
|
||||||
|
'properties': {
|
||||||
|
'on': {'read', 'write'}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'optional': {
|
||||||
|
'properties': {
|
||||||
|
'mode', 'brightness',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'entity': 'light',
|
||||||
|
'entity_category': EntityCategory.CONFIG
|
||||||
|
},
|
||||||
'fan': {
|
'fan': {
|
||||||
'required': {
|
'required': {
|
||||||
'properties': {
|
'properties': {
|
||||||
|
|||||||
@ -54,7 +54,8 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.components.vacuum import (
|
from homeassistant.components.vacuum import (
|
||||||
StateVacuumEntity,
|
StateVacuumEntity,
|
||||||
VacuumEntityFeature
|
VacuumEntityFeature,
|
||||||
|
VacuumActivity
|
||||||
)
|
)
|
||||||
|
|
||||||
from .miot.const import DOMAIN
|
from .miot.const import DOMAIN
|
||||||
@ -191,10 +192,47 @@ class Vacuum(MIoTServiceEntity, StateVacuumEntity):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self) -> Optional[str]:
|
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(
|
return self.get_map_value(
|
||||||
map_=self._status_map,
|
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
|
@property
|
||||||
def battery_level(self) -> Optional[int]:
|
def battery_level(self) -> Optional[int]:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user