sync main

This commit is contained in:
GavinIves 2025-12-28 15:10:02 +00:00
parent b95a2c18ee
commit 4c7b6d570d
5 changed files with 75 additions and 80 deletions

View File

@ -1415,8 +1415,9 @@ class MIoTClient:
_LOGGER.error('on event msg error, %s, %s', params, err)
@final
def __check_device_state(self, cloud_state: Optional[bool], gw_state: bool,
lan_state: bool) -> Optional[bool]:
def __check_device_state(
self, cloud_state: Optional[bool], gw_state: bool, lan_state: bool
) -> Optional[bool]:
if cloud_state is None and not gw_state and not lan_state:
# Device remove
return None
@ -1698,10 +1699,9 @@ class MIoTClient:
self.__request_show_devices_changed_notify()
@final
def __request_refresh_gw_devices_by_group_id(self,
group_id: str,
immediately: bool = False
) -> None:
def __request_refresh_gw_devices_by_group_id(
self, group_id: str, immediately: bool = False
) -> None:
"""Request refresh gateway devices by group_id"""
refresh_timer = self._mips_local_state_changed_timers.get(
group_id, None)
@ -1865,9 +1865,11 @@ class MIoTClient:
if not self._refresh_props_list:
return
# Cloud, Central hub gateway, Lan control
if (await self.__refresh_props_from_cloud() or
await self.__refresh_props_from_gw() or
await self.__refresh_props_from_lan()):
if (
await self.__refresh_props_from_cloud()
or await self.__refresh_props_from_gw()
or await self.__refresh_props_from_lan()
):
self._refresh_props_retry_count = 0
if self._refresh_props_list:
self._refresh_props_timer = self._main_loop.call_later(

View File

@ -624,9 +624,9 @@ class MIoTHttpClient:
devices.update(result)
return devices
async def get_devices_async(self,
home_ids: Optional[list[str]] = None
) -> dict[str, dict]:
async def get_devices_async(
self, home_ids: Optional[list[str]] = None
) -> dict[str, dict]:
homeinfos = await self.get_homeinfos_async()
homes: dict[str, dict[str, Any]] = {}
devices: dict[str, dict] = {}
@ -787,11 +787,9 @@ class MIoTHttpClient:
self._get_prop_timer = None
return True
async def get_prop_async(self,
did: str,
siid: int,
piid: int,
immediately: bool = False) -> Any:
async def get_prop_async(
self, did: str, siid: int, piid: int, immediately: bool = False
) -> Any:
if immediately:
return await self.__get_prop_async(did, siid, piid)
key: str = f'{did}.{siid}.{piid}'
@ -843,8 +841,9 @@ class MIoTHttpClient:
return res_obj['result']
async def action_async(self, did: str, siid: int, aiid: int,
in_list: list[dict]) -> dict:
async def action_async(
self, did: str, siid: int, aiid: int, in_list: list[dict]
) -> dict:
"""
params = {"did": "xxxx", "siid": 2, "aiid": 1, "in": []}
"""

View File

@ -78,6 +78,7 @@ from homeassistant.const import (
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.components.switch import SwitchDeviceClass
# pylint: disable=relative-beyond-top-level
from .specs.specv2entity import (
SPEC_ACTION_TRANS_MAP,
@ -242,8 +243,8 @@ class MIoTDevice:
did=self._did, siid=siid, aiid=aiid, in_list=in_list)
def sub_device_state(
self, key: str, handler: Callable[[str, MIoTDeviceState],
None]) -> int:
self, key: str, handler: Callable[[str, MIoTDeviceState], None]
) -> int:
sub_id = self.__gen_sub_id()
if key in self._device_state_sub_list:
self._device_state_sub_list[key][str(sub_id)] = handler
@ -409,7 +410,8 @@ class MIoTDevice:
self._action_list[action.platform].append(action)
def parse_miot_device_entity(
self, spec_instance: MIoTSpecInstance) -> Optional[MIoTEntityData]:
self, spec_instance: MIoTSpecInstance
) -> Optional[MIoTEntityData]:
if spec_instance.name not in SPEC_DEVICE_TRANS_MAP:
return None
spec_name: str = spec_instance.name
@ -866,8 +868,9 @@ class MIoTDevice:
self._sub_id += 1
return self._sub_id
def __on_device_state_changed(self, did: str, state: MIoTDeviceState,
ctx: Any) -> None:
def __on_device_state_changed(
self, did: str, state: MIoTDeviceState, ctx: Any
) -> None:
self._online = state == MIoTDeviceState.ONLINE
for key, sub_list in self._device_state_sub_list.items():
for handler in sub_list.values():
@ -1148,9 +1151,9 @@ class MIoTServiceEntity(Entity):
self.async_write_ha_state()
return result
async def action_async(self,
action: MIoTSpecAction,
in_list: Optional[list] = None) -> bool:
async def action_async(
self, action: MIoTSpecAction, in_list: Optional[list] = None
) -> bool:
if not action:
raise RuntimeError(
f'action failed, action is None, {self.entity_id}, {self.name}')
@ -1449,10 +1452,9 @@ class MIoTEventEntity(Entity):
sub_id=self._value_sub_id)
@abstractmethod
def on_event_occurred(self,
name: str,
arguments: dict[str, Any] | None = None) -> None:
...
def on_event_occurred(
self, name: str, arguments: dict[str, Any] | None = None
) -> None: ...
def __on_event_occurred(self, params: dict, ctx: Any) -> None:
_LOGGER.debug('event occurred, %s', params)

View File

@ -71,6 +71,7 @@ from .miot_mdns import MipsService, MipsServiceState
from .common import (
randomize_float, load_yaml_file, gen_absolute_path, MIoTMatcher)
_LOGGER = logging.getLogger(__name__)
@ -812,11 +813,9 @@ class MIoTLan:
return True
@final
async def get_prop_async(self,
did: str,
siid: int,
piid: int,
timeout_ms: int = 10000) -> Any:
async def get_prop_async(
self, did: str, siid: int, piid: int, timeout_ms: int = 10000
) -> Any:
self.__assert_service_ready()
result_obj = await self.__call_api_async(
did=did, msg={
@ -920,10 +919,9 @@ class MIoTLan:
timeout_ms=timeout_ms))
return await fut
async def __call_api_async(self,
did: str,
msg: dict,
timeout_ms: int = 10000) -> dict:
async def __call_api_async(
self, did: str, msg: dict, timeout_ms: int = 10000
) -> dict:
def call_api_handler(msg: dict, fut: asyncio.Future):
self._main_loop.call_soon_threadsafe(
@ -1026,7 +1024,6 @@ class MIoTLan:
handler_ctx: Any = None,
timeout_ms: Optional[int] = None
) -> None:
def request_timeout_handler(req_data: _MIoTLanRequestData):
self._pending_requests.pop(req_data.msg_id, None)
if req_data and req_data.handler:
@ -1253,8 +1250,9 @@ class MIoTLan:
except Exception as err: # pylint: disable=broad-exception-caught
_LOGGER.error('socket read handler error, %s', err)
def __raw_message_handler(self, data: bytearray, data_len: int, ip: str,
if_name: str) -> None:
def __raw_message_handler(
self, data: bytearray, data_len: int, ip: str, if_name: str
) -> None:
if data[:2] != self.OT_HEADER:
return
# Keep alive message
@ -1278,8 +1276,11 @@ class MIoTLan:
int(data[28]) == self.OT_SUPPORT_WILDCARD_SUB)
sub_ts = struct.unpack('>I', data[20:24])[0]
sub_type = int(data[27])
if (device.supported_wildcard_sub and sub_type in [0, 1, 4] and
sub_ts != device.sub_ts):
if (
device.supported_wildcard_sub
and sub_type in [0, 1, 4]
and sub_ts != device.sub_ts
):
device.subscribed = False
device.subscribe()
if data_len > self.OT_PROBE_LEN:
@ -1357,8 +1358,9 @@ class MIoTLan:
filter_id)
return False
def __sendto(self, if_name: Optional[str], data: bytes, address: str,
port: int) -> None:
def __sendto(
self, if_name: Optional[str], data: bytes, address: str, port: int
) -> None:
if if_name is None:
# Broadcast
for if_n, sock in self._broadcast_socks.items():

View File

@ -415,8 +415,9 @@ class _MipsClient(ABC):
self._mqtt.disable_logger()
@final
def sub_mips_state(self, key: str, handler: Callable[[str, bool],
Coroutine]) -> bool:
def sub_mips_state(
self, key: str, handler: Callable[[str, bool], Coroutine]
) -> bool:
"""Subscribe mips state.
NOTICE: callback to main loop thread
This will be called before the client is connected.
@ -484,12 +485,9 @@ class _MipsClient(ABC):
) -> dict[str, dict]: ...
@abstractmethod
async def get_prop_async(self,
did: str,
siid: int,
piid: int,
timeout_ms: int = 10000) -> Any:
...
async def get_prop_async(
self, did: str, siid: int, piid: int, timeout_ms: int = 10000
) -> Any: ...
@abstractmethod
async def set_prop_async(
@ -504,16 +502,13 @@ class _MipsClient(ABC):
) -> dict: ...
@abstractmethod
def _on_mips_message(self, topic: str, payload: bytes) -> None:
...
def _on_mips_message(self, topic: str, payload: bytes) -> None: ...
@abstractmethod
def _on_mips_connect(self, rc: int, props: dict) -> None:
...
def _on_mips_connect(self, rc: int, props: dict) -> None: ...
@abstractmethod
def _on_mips_disconnect(self, rc: int, props: dict) -> None:
...
def _on_mips_disconnect(self, rc: int, props: dict) -> None: ...
@final
def _mips_sub_internal(self, topic: str) -> None:
@ -1273,11 +1268,9 @@ class MipsLocalClient(_MipsClient):
return self.__unreg_broadcast_external(topic=topic)
@final
async def get_prop_safe_async(self,
did: str,
siid: int,
piid: int,
timeout_ms: int = 10000) -> Any:
async def get_prop_safe_async(
self, did: str, siid: int, piid: int, timeout_ms: int = 10000
) -> Any:
self._get_prop_queue.setdefault(did, [])
fut: asyncio.Future = self.main_loop.create_future()
self._get_prop_queue[did].append({
@ -1297,11 +1290,9 @@ class MipsLocalClient(_MipsClient):
return await fut
@final
async def get_prop_async(self,
did: str,
siid: int,
piid: int,
timeout_ms: int = 10000) -> Any:
async def get_prop_async(
self, did: str, siid: int, piid: int, timeout_ms: int = 10000
) -> Any:
result_obj = await self.__request_async(
topic='proxy/get',
payload=json.dumps({
@ -1457,9 +1448,9 @@ class MipsLocalClient(_MipsClient):
return result_obj['result']
@final
async def exec_action_group_list_async(self,
ag_id: str,
timeout_ms: int = 10000) -> dict:
async def exec_action_group_list_async(
self, ag_id: str, timeout_ms: int = 10000
) -> dict:
result_obj = await self.__request_async(
topic='proxy/execMijiaActionGroup',
payload=f'{{"id":"{ag_id}"}}',
@ -1483,8 +1474,8 @@ class MipsLocalClient(_MipsClient):
@final
@on_dev_list_changed.setter
def on_dev_list_changed(
self, func: Optional[Callable[[Any, list[str]],
Coroutine]]) -> None:
self, func: Optional[Callable[[Any, list[str]], Coroutine]]
) -> None:
"""run in main loop."""
self._on_dev_list_changed = func
@ -1657,10 +1648,9 @@ class MipsLocalClient(_MipsClient):
return True
@final
async def __request_async(self,
topic: str,
payload: str,
timeout_ms: int = 10000) -> dict:
async def __request_async(
self, topic: str, payload: str, timeout_ms: int = 10000
) -> dict:
fut_handler: asyncio.Future = self.main_loop.create_future()
def on_msg_reply(payload: str, ctx: Any):