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