feat: improve notify, action-text trans logic

This commit is contained in:
topsworld 2024-12-31 15:13:19 +08:00
parent 8726c75c85
commit 7b7553c5f8
2 changed files with 92 additions and 32 deletions

View File

@ -47,7 +47,7 @@ Notify entities for Xiaomi Home.
"""
from __future__ import annotations
import logging
from typing import Optional
from typing import Any, Optional
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
@ -83,6 +83,7 @@ async def async_setup_entry(
class Notify(MIoTActionEntity, NotifyEntity):
"""Notify entities for Xiaomi Home."""
# pylint: disable=unused-argument
def __init__(self, miot_device: MIoTDevice, spec: MIoTSpecAction) -> None:
"""Initialize the Notify."""
@ -97,37 +98,66 @@ class Notify(MIoTActionEntity, NotifyEntity):
self, message: str, title: Optional[str] = None
) -> None:
"""Send a message."""
del title
if not message:
_LOGGER.error(
'action exec failed, %s(%s), empty action params',
self.name, self.entity_id)
return
in_list: Any = None
try:
in_list: list = yaml.parse_yaml(message)
# YAML will convert yes, no, on, off, true, false to the bool type,
# and if it is a string, quotation marks need to be added.
in_list = yaml.parse_yaml(content=message)
except HomeAssistantError:
_LOGGER.error(
'action exec failed, %s(%s), invalid action params format, %s',
self.name, self.entity_id, message)
return
if not isinstance(in_list, list):
if len(self.spec.in_) == 1 and not isinstance(in_list, list):
in_list = [in_list]
if not isinstance(in_list, list) or len(in_list) != len(self.spec.in_):
_LOGGER.error(
'action exec failed, %s(%s), invalid action params, %s',
self.name, self.entity_id, message)
return
in_value: list[dict] = []
for index, prop in enumerate(self.spec.in_):
if type(in_list[index]).__name__ != prop.format_:
_LOGGER.error(
'action exec failed, %s(%s), invalid params item, '
'which item(%s) in the list must be %s, %s',
self.name, self.entity_id, prop.description_trans,
prop.format_, message)
return
in_value.append({'piid': prop.iid, 'value': in_list[index]})
return await self.action_async(in_list=in_value)
if (
prop.format_ == 'str'
and isinstance(in_list[index], (bool, int, float, str))
):
in_value.append(
{'piid': prop.iid, 'value': str(in_list[index])})
continue
if (
prop.format_ == 'bool'
and 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
if (
prop.format_ == 'float'
and isinstance(in_list[index], (int, float))
):
in_value.append(
{'piid': prop.iid, 'value': in_list[index]})
continue
if (
prop.format_ == 'int'
and isinstance(in_list[index], int)
):
in_value.append(
{'piid': prop.iid, 'value': in_list[index]})
continue
# Invalid params type, raise error.
_LOGGER.error(
'action exec failed, %s(%s), invalid params item, '
'which item(%s) in the list must be %s, %s type was %s, %s',
self.name, self.entity_id, prop.description_trans,
prop.format_, in_list[index], type(
in_list[index]).__name__, message)
return
await self.action_async(in_list=in_value)

View File

@ -47,7 +47,7 @@ Text entities for Xiaomi Home.
"""
from __future__ import annotations
import logging
from typing import Optional
from typing import Any, Optional
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
@ -120,9 +120,9 @@ class ActionText(MIoTActionEntity, TextEntity):
async def async_set_value(self, value: str) -> None:
if not value:
return
in_list: list = None
in_list: Any = None
try:
in_list = yaml.parse_yaml(value)
in_list = yaml.parse_yaml(content=value)
except HomeAssistantError as e:
_LOGGER.error(
'action exec failed, %s(%s), invalid action params format, %s',
@ -130,10 +130,8 @@ class ActionText(MIoTActionEntity, TextEntity):
raise ValueError(
f'action exec failed, {self.name}({self.entity_id}), '
f'invalid action params format, {value}') from e
if not isinstance(in_list, list):
if len(self.spec.in_) == 1 and not isinstance(in_list, list):
in_list = [in_list]
if not isinstance(in_list, list) or len(in_list) != len(self.spec.in_):
_LOGGER.error(
'action exec failed, %s(%s), invalid action params, %s',
@ -143,16 +141,48 @@ class ActionText(MIoTActionEntity, TextEntity):
f'invalid action params, {value}')
in_value: list[dict] = []
for index, prop in enumerate(self.spec.in_):
if type(in_list[index]).__name__ != prop.format_:
logging.error(
'action exec failed, %s(%s), invalid params item, which '
'item(%s) in the list must be %s, %s', self.name,
self.entity_id, prop.description_trans, prop.format_, value)
raise ValueError(
f'action exec failed, {self.name}({self.entity_id}), '
f'invalid params item, which item({prop.description_trans})'
f' in the list must be {prop.format_}, {value}')
in_value.append({'piid': prop.iid, 'value': in_list[index]})
if (
prop.format_ == 'str'
and isinstance(in_list[index], (bool, int, float, str))
):
in_value.append(
{'piid': prop.iid, 'value': str(in_list[index])})
continue
if (
prop.format_ == 'bool'
and 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
if (
prop.format_ == 'float'
and isinstance(in_list[index], (int, float))
):
in_value.append(
{'piid': prop.iid, 'value': in_list[index]})
continue
if (
prop.format_ == 'int'
and isinstance(in_list[index], int)
):
in_value.append(
{'piid': prop.iid, 'value': in_list[index]})
continue
# Invalid params type, raise error.
_LOGGER.error(
'action exec failed, %s(%s), invalid params item, '
'which item(%s) in the list must be %s, %s type was %s, %s',
self.name, self.entity_id, prop.description_trans,
prop.format_, in_list[index], type(
in_list[index]).__name__, value)
raise ValueError(
f'action exec failed, {self.name}({self.entity_id}), '
f'invalid params item, which item({prop.description_trans}) '
f'in the list must be {prop.format_}, {in_list[index]} type '
f'was {type(in_list[index]).__name__}, {value}')
self._attr_native_value = value
if await self.action_async(in_list=in_value):