Compare commits

..

No commits in common. "ace8adbf6b40605e38836b8bced005d50a4d5a48" and "900160658488233f726f19acef00a06f6e20e45c" have entirely different histories.

6 changed files with 38 additions and 100 deletions

View File

@ -101,11 +101,7 @@ class Cover(MIoTServiceEntity, CoverEntity):
_prop_status_closed: Optional[list[int]]
_prop_current_position: Optional[MIoTSpecProperty]
_prop_target_position: Optional[MIoTSpecProperty]
_prop_position_value_min: Optional[int]
_prop_position_value_max: Optional[int]
_prop_position_value_range: Optional[int]
_prop_pos_closing: bool
_prop_pos_opening: bool
def __init__(self, miot_device: MIoTDevice,
entity_data: MIoTEntityData) -> None:
@ -126,11 +122,7 @@ class Cover(MIoTServiceEntity, CoverEntity):
self._prop_status_closed = []
self._prop_current_position = None
self._prop_target_position = None
self._prop_position_value_min = None
self._prop_position_value_max = None
self._prop_position_value_range = None
self._prop_pos_closing = False
self._prop_pos_opening = False
# properties
for prop in entity_data.props:
@ -174,8 +166,6 @@ class Cover(MIoTServiceEntity, CoverEntity):
'invalid current-position value_range format, %s',
self.entity_id)
continue
self._prop_position_value_min = prop.value_range.min_
self._prop_position_value_max = prop.value_range.max_
self._prop_position_value_range = (prop.value_range.max_ -
prop.value_range.min_)
self._prop_current_position = prop
@ -185,52 +175,48 @@ class Cover(MIoTServiceEntity, CoverEntity):
'invalid target-position value_range format, %s',
self.entity_id)
continue
self._prop_position_value_min = prop.value_range.min_
self._prop_position_value_max = prop.value_range.max_
self._prop_position_value_range = (prop.value_range.max_ -
prop.value_range.min_)
self._attr_supported_features |= CoverEntityFeature.SET_POSITION
self._prop_target_position = prop
# For the device that has the current position property but no status
# property, the current position property will be used to determine the
# opening and the closing status.
if (self._prop_status is None) and (self._prop_current_position
is not None):
self.sub_prop_changed(self._prop_current_position,
self._position_changed_handler)
def _position_changed_handler(self, prop: MIoTSpecProperty,
ctx: Any) -> None:
self._prop_pos_closing = False
self._prop_pos_opening = False
self.async_write_ha_state()
if (
self._prop_status is None
and self._prop_current_position is not None
):
self.sub_prop_changed(prop=self._prop_current_position,
handler=self.__current_position_changed)
def __current_position_changed(
self, prop: MIoTSpecProperty, ctx: Any
) -> None:
if self._attr_is_opening or self._attr_is_closing:
self._attr_is_opening = False
self._attr_is_closing = False
self.async_write_ha_state()
async def async_open_cover(self, **kwargs) -> None:
"""Open the cover."""
current = None if (self._prop_current_position
is None) else self.get_prop_value(
prop=self._prop_current_position)
if (current is not None) and (current < self._prop_position_value_max):
self._prop_pos_opening = True
self._prop_pos_closing = False
current = self.get_prop_value(prop=self._prop_current_position)
if current is not None and current < 100:
self._attr_is_opening = True
self._attr_is_closing = False
await self.set_property_async(self._prop_motor_control,
self._prop_motor_value_open)
async def async_close_cover(self, **kwargs) -> None:
"""Close the cover."""
current = None if (self._prop_current_position
is None) else self.get_prop_value(
prop=self._prop_current_position)
if (current is not None) and (current > self._prop_position_value_min):
self._prop_pos_opening = False
self._prop_pos_closing = True
current = self.get_prop_value(prop=self._prop_current_position)
if current is not None and current > 0:
self._attr_is_opening = False
self._attr_is_closing = True
await self.set_property_async(self._prop_motor_control,
self._prop_motor_value_close)
async def async_stop_cover(self, **kwargs) -> None:
"""Stop the cover."""
self._prop_pos_opening = False
self._prop_pos_closing = False
self._attr_is_opening = False
self._attr_is_closing = False
await self.set_property_async(self._prop_motor_control,
self._prop_motor_value_pause)
@ -239,11 +225,11 @@ class Cover(MIoTServiceEntity, CoverEntity):
pos = kwargs.get(ATTR_POSITION, None)
if pos is None:
return None
current = self.current_cover_position
if current is not None:
self._prop_pos_opening = pos > current
self._prop_pos_closing = pos < current
pos = round(pos * self._prop_position_value_range / 100)
current = self.get_prop_value(prop=self._prop_current_position)
if current is not None:
self._attr_is_opening = pos > current
self._attr_is_closing = pos < current
await self.set_property_async(prop=self._prop_target_position,
value=pos)
@ -257,11 +243,9 @@ class Cover(MIoTServiceEntity, CoverEntity):
# Assume that the current position is the same as the target
# position when the current position is not defined in the device's
# MIoT-Spec-V2.
if self._prop_target_position is None:
return None
self._prop_pos_opening = False
self._prop_pos_closing = False
return self.get_prop_value(prop=self._prop_target_position)
return None if (self._prop_target_position
is None) else self.get_prop_value(
prop=self._prop_target_position)
pos = self.get_prop_value(prop=self._prop_current_position)
return None if pos is None else round(pos * 100 /
self._prop_position_value_range)
@ -272,9 +256,7 @@ class Cover(MIoTServiceEntity, CoverEntity):
if self._prop_status and self._prop_status_opening:
return (self.get_prop_value(prop=self._prop_status)
in self._prop_status_opening)
# The status has higher priority when determining whether the cover
# is opening.
return self._prop_pos_opening
return self._attr_is_opening
@property
def is_closing(self) -> Optional[bool]:
@ -282,9 +264,7 @@ class Cover(MIoTServiceEntity, CoverEntity):
if self._prop_status and self._prop_status_closing:
return (self.get_prop_value(prop=self._prop_status)
in self._prop_status_closing)
# The status has higher priority when determining whether the cover
# is closing.
return self._prop_pos_closing
return self._attr_is_closing
@property
def is_closed(self) -> Optional[bool]:

View File

@ -172,7 +172,7 @@ class Fan(MIoTServiceEntity, FanEntity):
self._attr_supported_features |= FanEntityFeature.OSCILLATE
self._prop_horizontal_swing = prop
elif prop.name == 'wind-reverse':
if prop.format_ == bool:
if prop.format_ == 'bool':
self._prop_wind_reverse_forward = False
self._prop_wind_reverse_reverse = True
elif prop.value_list:
@ -186,7 +186,7 @@ class Fan(MIoTServiceEntity, FanEntity):
or self._prop_wind_reverse_reverse is None
):
# NOTICE: Value may be 0 or False
_LOGGER.error(
_LOGGER.info(
'invalid wind-reverse, %s', self.entity_id)
continue
self._attr_supported_features |= FanEntityFeature.DIRECTION

View File

@ -549,10 +549,6 @@ class MIoTDevice:
# Optional actions
# Optional events
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
def parse_miot_property_entity(self, miot_prop: MIoTSpecProperty) -> bool:
@ -903,7 +899,6 @@ class MIoTServiceEntity(Entity):
self._attr_name = (
f'{"* "if self.entity_data.spec.proprietary else " "}'
f'{self.entity_data.spec.description_trans}')
self._attr_entity_category = entity_data.spec.entity_category
# Set entity attr
self._attr_unique_id = self.entity_id
self._attr_should_poll = False

View File

@ -465,7 +465,7 @@ class _MIoTSpecBase:
iid: int
type_: str
description: str
description_trans: Optional[str]
description_trans: str
proprietary: bool
need_filter: bool
name: str
@ -476,7 +476,6 @@ class _MIoTSpecBase:
device_class: Any
state_class: Any
external_unit: Any
entity_category: Optional[str]
spec_id: int
@ -495,7 +494,6 @@ class _MIoTSpecBase:
self.device_class = None
self.state_class = None
self.external_unit = None
self.entity_category = None
self.spec_id = hash(f'{self.type_}.{self.iid}')
@ -1207,13 +1205,6 @@ class _SpecModify:
return None
return value_range
def get_prop_value_list(self, siid: int, piid: int) -> Optional[list]:
value_list = self.__get_prop_item(siid=siid, piid=piid,
key='value-list')
if not isinstance(value_list, list):
return None
return value_list
def __get_prop_item(self, siid: int, piid: int, key: str) -> Optional[str]:
if not self._selected:
return None
@ -1494,10 +1485,6 @@ class MIoTSpecParser:
siid=service['iid'], piid=property_['iid'])
if 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
for event in service.get('events', []):
if (

View File

@ -49,12 +49,3 @@ urn:miot-spec-v2:device:airer:0000A00D:hyd-znlyj5:1:
- 1
- 1
urn:miot-spec-v2:device:airer:0000A00D:hyd-znlyj5:2: urn:miot-spec-v2:device:airer:0000A00D:hyd-znlyj5:1
urn:miot-spec-v2:device:bath-heater:0000A028:opple-acmoto:1:
prop.5.2:
value-list:
- value: 1
description: low
- value: 128
description: medium
- value: 255
description: high

View File

@ -51,7 +51,6 @@ from homeassistant.components.event import EventDeviceClass
from homeassistant.const import (
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
EntityCategory,
LIGHT_LUX,
UnitOfEnergy,
UnitOfPower,
@ -331,8 +330,7 @@ SPEC_DEVICE_TRANS_MAP: dict = {
'events': set<event instance name: str>,
'actions': set<action instance name: str>
},
'entity': str,
'entity_category'?: str
'entity': str
}
}
"""
@ -350,23 +348,10 @@ SPEC_SERVICE_TRANS_MAP: dict = {
},
'entity': 'light'
},
'indicator-light': 'light',
'ambient-light': 'light',
'night-light': 'light',
'white-light': 'light',
'indicator-light': {
'required': {
'properties': {
'on': {'read', 'write'}
}
},
'optional': {
'properties': {
'mode', 'brightness',
}
},
'entity': 'light',
'entity_category': EntityCategory.CONFIG
},
'fan': {
'required': {
'properties': {