mirror of
https://github.com/XiaoMi/ha_xiaomi_home.git
synced 2026-01-15 22:10:43 +08:00
feat: update prop.format_ logic
This commit is contained in:
parent
d25d3f6a93
commit
93f04b1aee
@ -96,7 +96,7 @@ class Light(MIoTServiceEntity, LightEntity):
|
||||
"""Light entities for Xiaomi Home."""
|
||||
# pylint: disable=unused-argument
|
||||
_VALUE_RANGE_MODE_COUNT_MAX = 30
|
||||
_prop_on: Optional[MIoTSpecProperty]
|
||||
_prop_on: MIoTSpecProperty
|
||||
_prop_brightness: Optional[MIoTSpecProperty]
|
||||
_prop_color_temp: Optional[MIoTSpecProperty]
|
||||
_prop_color: Optional[MIoTSpecProperty]
|
||||
@ -253,7 +253,7 @@ class Light(MIoTServiceEntity, LightEntity):
|
||||
result: bool = False
|
||||
# on
|
||||
# Dirty logic for lumi.gateway.mgl03 indicator light
|
||||
value_on = True if self._prop_on.format_ == 'bool' else 1
|
||||
value_on = True if self._prop_on.format_ == bool else 1
|
||||
result = await self.set_property_async(
|
||||
prop=self._prop_on, value=value_on)
|
||||
# brightness
|
||||
@ -288,5 +288,5 @@ class Light(MIoTServiceEntity, LightEntity):
|
||||
async def async_turn_off(self, **kwargs) -> None:
|
||||
"""Turn the light off."""
|
||||
# Dirty logic for lumi.gateway.mgl03 indicator light
|
||||
value_on = False if self._prop_on.format_ == 'bool' else 0
|
||||
value_on = False if self._prop_on.format_ == bool else 0
|
||||
return await self.set_property_async(prop=self._prop_on, value=value_on)
|
||||
|
||||
@ -513,7 +513,7 @@ class MIoTDevice:
|
||||
if prop_access != (SPEC_PROP_TRANS_MAP[
|
||||
'entities'][platform]['access']):
|
||||
return None
|
||||
if prop.format_ not in SPEC_PROP_TRANS_MAP[
|
||||
if prop.format_.__name__ not in SPEC_PROP_TRANS_MAP[
|
||||
'entities'][platform]['format']:
|
||||
return None
|
||||
if prop.unit:
|
||||
@ -566,9 +566,9 @@ class MIoTDevice:
|
||||
# general conversion
|
||||
if not prop.platform:
|
||||
if prop.writable:
|
||||
if prop.format_ == 'str':
|
||||
if prop.format_ == str:
|
||||
prop.platform = 'text'
|
||||
elif prop.format_ == 'bool':
|
||||
elif prop.format_ == bool:
|
||||
prop.platform = 'switch'
|
||||
prop.device_class = SwitchDeviceClass.SWITCH
|
||||
elif prop.value_list:
|
||||
|
||||
@ -48,7 +48,7 @@ MIoT-Spec-V2 parser.
|
||||
import asyncio
|
||||
import platform
|
||||
import time
|
||||
from typing import Any, Optional, Union
|
||||
from typing import Any, Optional, Type, Union
|
||||
import logging
|
||||
from slugify import slugify
|
||||
|
||||
@ -506,10 +506,10 @@ class _MIoTSpecBase:
|
||||
|
||||
class MIoTSpecProperty(_MIoTSpecBase):
|
||||
"""MIoT SPEC property class."""
|
||||
format_: str
|
||||
unit: Optional[str]
|
||||
precision: int
|
||||
|
||||
_format_: Type
|
||||
_value_range: Optional[MIoTSpecValueRange]
|
||||
_value_list: Optional[MIoTSpecValueList]
|
||||
|
||||
@ -543,6 +543,19 @@ class MIoTSpecProperty(_MIoTSpecBase):
|
||||
self.spec_id = hash(
|
||||
f'p.{self.name}.{self.service.iid}.{self.iid}')
|
||||
|
||||
@property
|
||||
def format_(self) -> Type:
|
||||
return self._format_
|
||||
|
||||
@format_.setter
|
||||
def format_(self, value: str) -> None:
|
||||
self._format_ = {
|
||||
'string': str,
|
||||
'str': str,
|
||||
'bool': bool,
|
||||
'float': float}.get(
|
||||
value, int)
|
||||
|
||||
@property
|
||||
def access(self) -> list:
|
||||
return self._access
|
||||
@ -601,11 +614,11 @@ class MIoTSpecProperty(_MIoTSpecBase):
|
||||
def value_format(self, value: Any) -> Any:
|
||||
if value is None:
|
||||
return None
|
||||
if self.format_ == 'int':
|
||||
if self.format_ == int:
|
||||
return int(value)
|
||||
if self.format_ == 'float':
|
||||
if self.format_ == float:
|
||||
return round(value, self.precision)
|
||||
if self.format_ == 'bool':
|
||||
if self.format_ == bool:
|
||||
return bool(value in [True, 1, 'True', 'true', '1'])
|
||||
return value
|
||||
|
||||
@ -618,7 +631,7 @@ class MIoTSpecProperty(_MIoTSpecBase):
|
||||
'description_trans': self.description_trans,
|
||||
'proprietary': self.proprietary,
|
||||
'need_filter': self.need_filter,
|
||||
'format': self.format_,
|
||||
'format': self.format_.__name__,
|
||||
'access': self._access,
|
||||
'unit': self.unit,
|
||||
'value_range': (
|
||||
@ -1048,12 +1061,6 @@ class MIoTSpecParser:
|
||||
return await self._storage.save_async(
|
||||
domain=self._DOMAIN, name=f'{urn}_{self._lang}', data=data)
|
||||
|
||||
def __spec_format2dtype(self, format_: str) -> str:
|
||||
# 'string'|'bool'|'uint8'|'uint16'|'uint32'|
|
||||
# 'int8'|'int16'|'int32'|'int64'|'float'
|
||||
return {'string': 'str', 'bool': 'bool', 'float': 'float'}.get(
|
||||
format_, 'int')
|
||||
|
||||
async def __get_instance(self, urn: str) -> Optional[dict]:
|
||||
return await MIoTHttp.get_json_async(
|
||||
url='https://miot-spec.org/miot-spec-v2/instance',
|
||||
@ -1124,7 +1131,7 @@ class MIoTSpecParser:
|
||||
spec_prop: MIoTSpecProperty = MIoTSpecProperty(
|
||||
spec=property_,
|
||||
service=spec_service,
|
||||
format_=self.__spec_format2dtype(property_['format']),
|
||||
format_=property_['format'],
|
||||
access=property_['access'],
|
||||
unit=property_.get('unit', None))
|
||||
spec_prop.name = p_type_strs[3]
|
||||
|
||||
@ -90,7 +90,7 @@ class Notify(MIoTActionEntity, NotifyEntity):
|
||||
super().__init__(miot_device=miot_device, spec=spec)
|
||||
self._attr_extra_state_attributes = {}
|
||||
action_in: str = ', '.join([
|
||||
f'{prop.description_trans}({prop.format_})'
|
||||
f'{prop.description_trans}({prop.format_.__name__})'
|
||||
for prop in self.spec.in_])
|
||||
self._attr_extra_state_attributes['action params'] = f'[{action_in}]'
|
||||
|
||||
@ -122,24 +122,24 @@ class Notify(MIoTActionEntity, NotifyEntity):
|
||||
return
|
||||
in_value: list[dict] = []
|
||||
for index, prop in enumerate(self.spec.in_):
|
||||
if prop.format_ == 'str':
|
||||
if prop.format_ == str:
|
||||
if isinstance(in_list[index], (bool, int, float, str)):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': str(in_list[index])})
|
||||
continue
|
||||
elif prop.format_ == 'bool':
|
||||
elif prop.format_ == bool:
|
||||
if isinstance(in_list[index], (bool, int)):
|
||||
# yes, no, on, off, true, false and other bool types
|
||||
# will also be parsed as 0 and 1 of int.
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': bool(in_list[index])})
|
||||
continue
|
||||
elif prop.format_ == 'float':
|
||||
elif prop.format_ == float:
|
||||
if isinstance(in_list[index], (int, float)):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': in_list[index]})
|
||||
continue
|
||||
elif prop.format_ == 'int':
|
||||
elif prop.format_ == int:
|
||||
if isinstance(in_list[index], int):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': in_list[index]})
|
||||
|
||||
@ -111,7 +111,7 @@ class ActionText(MIoTActionEntity, TextEntity):
|
||||
self._attr_extra_state_attributes = {}
|
||||
self._attr_native_value = ''
|
||||
action_in: str = ', '.join([
|
||||
f'{prop.description_trans}({prop.format_})'
|
||||
f'{prop.description_trans}({prop.format_.__name__})'
|
||||
for prop in self.spec.in_])
|
||||
self._attr_extra_state_attributes['action params'] = f'[{action_in}]'
|
||||
# For action debug
|
||||
@ -141,24 +141,24 @@ class ActionText(MIoTActionEntity, TextEntity):
|
||||
f'invalid action params, {value}')
|
||||
in_value: list[dict] = []
|
||||
for index, prop in enumerate(self.spec.in_):
|
||||
if prop.format_ == 'str':
|
||||
if prop.format_ == str:
|
||||
if isinstance(in_list[index], (bool, int, float, str)):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': str(in_list[index])})
|
||||
continue
|
||||
elif prop.format_ == 'bool':
|
||||
elif prop.format_ == bool:
|
||||
if isinstance(in_list[index], (bool, int)):
|
||||
# yes, no, on, off, true, false and other bool types
|
||||
# will also be parsed as 0 and 1 of int.
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': bool(in_list[index])})
|
||||
continue
|
||||
elif prop.format_ == 'float':
|
||||
elif prop.format_ == float:
|
||||
if isinstance(in_list[index], (int, float)):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': in_list[index]})
|
||||
continue
|
||||
elif prop.format_ == 'int':
|
||||
elif prop.format_ == int:
|
||||
if isinstance(in_list[index], int):
|
||||
in_value.append(
|
||||
{'piid': prop.iid, 'value': in_list[index]})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user