Compare commits

...

4 Commits

Author SHA1 Message Date
GavinIves
c1a6c7e6d2 fix bug 2025-07-09 05:36:50 +00:00
GavinIves
ed76ae9cd1 fix bug 2025-07-09 03:42:05 +00:00
GavinIves
99ddf9bbc0 fix bug 2025-07-09 03:08:08 +00:00
GavinIves
052428febb Remove set_property_async and convert all to set_properties_async to keep the code concise 2025-07-09 02:46:57 +00:00
4 changed files with 116 additions and 105 deletions

View File

@ -48,7 +48,6 @@ Light entities for Xiaomi Home.
from __future__ import annotations from __future__ import annotations
import logging import logging
from tkinter import N
from typing import Any, Optional, List, Dict from typing import Any, Optional, List, Dict
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry

View File

@ -636,79 +636,79 @@ class MIoTClient:
traceback.format_exc()) traceback.format_exc())
return False return False
async def set_prop_async(self, did: str, siid: int, piid: int, # async def set_prop_async(self, did: str, siid: int, piid: int,
value: Any) -> bool: # value: Any) -> bool:
if did not in self._device_list_cache: # if did not in self._device_list_cache:
raise MIoTClientError(f"did not exist, {did}") # raise MIoTClientError(f"did not exist, {did}")
# Priority local control # # Priority local control
if self._ctrl_mode == CtrlMode.AUTO: # if self._ctrl_mode == CtrlMode.AUTO:
# Gateway control # # Gateway control
device_gw = self._device_list_gateway.get(did, None) # device_gw = self._device_list_gateway.get(did, None)
if (device_gw and device_gw.get("online", False) and # if (device_gw and device_gw.get("online", False) and
device_gw.get("specv2_access", False) and # device_gw.get("specv2_access", False) and
"group_id" in device_gw): # "group_id" in device_gw):
mips = self._mips_local.get(device_gw["group_id"], None) # mips = self._mips_local.get(device_gw["group_id"], None)
if mips is None: # if mips is None:
_LOGGER.error( # _LOGGER.error(
'no gateway route, %s, try control through cloud', # 'no gateway route, %s, try control through cloud',
device_gw) # device_gw)
else: # else:
result = await mips.set_prop_async(did=did, # result = await mips.set_prop_async(did=did,
siid=siid, # siid=siid,
piid=piid, # piid=piid,
value=value) # value=value)
_LOGGER.debug('gateway set prop, %s.%d.%d, %s -> %s', did, # _LOGGER.debug('gateway set prop, %s.%d.%d, %s -> %s', did,
siid, piid, value, result) # siid, piid, value, result)
rc = (result or # rc = (result or
{}).get('code', # {}).get('code',
MIoTErrorCode.CODE_MIPS_INVALID_RESULT.value) # MIoTErrorCode.CODE_MIPS_INVALID_RESULT.value)
if rc in [0, 1]: # if rc in [0, 1]:
return True # return True
raise MIoTClientError(self.__get_exec_error_with_rc(rc=rc)) # raise MIoTClientError(self.__get_exec_error_with_rc(rc=rc))
# Lan control # # Lan control
device_lan = self._device_list_lan.get(did, None) # device_lan = self._device_list_lan.get(did, None)
if device_lan and device_lan.get("online", False): # if device_lan and device_lan.get("online", False):
result = await self._miot_lan.set_prop_async(did=did, # result = await self._miot_lan.set_prop_async(did=did,
siid=siid, # siid=siid,
piid=piid, # piid=piid,
value=value) # value=value)
_LOGGER.debug("lan set prop, %s.%d.%d, %s -> %s", did, siid, # _LOGGER.debug("lan set prop, %s.%d.%d, %s -> %s", did, siid,
piid, value, result) # piid, value, result)
rc = (result or # rc = (result or
{}).get("code", # {}).get("code",
MIoTErrorCode.CODE_MIPS_INVALID_RESULT.value) # MIoTErrorCode.CODE_MIPS_INVALID_RESULT.value)
if rc in [0, 1]: # if rc in [0, 1]:
return True # return True
raise MIoTClientError(self.__get_exec_error_with_rc(rc=rc)) # raise MIoTClientError(self.__get_exec_error_with_rc(rc=rc))
# Cloud control # # Cloud control
device_cloud = self._device_list_cloud.get(did, None) # device_cloud = self._device_list_cloud.get(did, None)
if device_cloud and device_cloud.get("online", False): # if device_cloud and device_cloud.get("online", False):
result = await self._http.set_prop_async(params=[{ # result = await self._http.set_prop_async(params=[{
"did": did, # "did": did,
"siid": siid, # "siid": siid,
"piid": piid, # "piid": piid,
"value": value # "value": value
}]) # }])
_LOGGER.debug('cloud set prop, %s.%d.%d, %s -> %s', did, siid, piid, # _LOGGER.debug('cloud set prop, %s.%d.%d, %s -> %s', did, siid, piid,
value, result) # value, result)
if result and len(result) == 1: # if result and len(result) == 1:
rc = result[0].get("code", # rc = result[0].get("code",
MIoTErrorCode.CODE_MIPS_INVALID_RESULT.value) # MIoTErrorCode.CODE_MIPS_INVALID_RESULT.value)
if rc in [0, 1]: # if rc in [0, 1]:
return True # return True
if rc in [-704010000, -704042011]: # if rc in [-704010000, -704042011]:
# Device remove or offline # # Device remove or offline
_LOGGER.error("device may be removed or offline, %s", did) # _LOGGER.error("device may be removed or offline, %s", did)
self._main_loop.create_task( # self._main_loop.create_task(
await # await
self.__refresh_cloud_device_with_dids_async(dids=[did])) # self.__refresh_cloud_device_with_dids_async(dids=[did]))
raise MIoTClientError(self.__get_exec_error_with_rc(rc=rc)) # raise MIoTClientError(self.__get_exec_error_with_rc(rc=rc))
# Show error message # # Show error message
raise MIoTClientError( # raise MIoTClientError(
f"{self._i18n.translate('miot.client.device_exec_error')}, " # f"{self._i18n.translate('miot.client.device_exec_error')}, "
f"{self._i18n.translate('error.common.-10007')}") # f"{self._i18n.translate('error.common.-10007')}")
async def set_props_async( async def set_props_async(
self, self,

View File

@ -1027,32 +1027,35 @@ class MIoTServiceEntity(Entity):
update_value: bool = True, update_value: bool = True,
write_ha_state: bool = True, write_ha_state: bool = True,
) -> bool: ) -> bool:
if not prop: set_properties_list = [{"prop": prop, "value": value}]
raise RuntimeError( return await self.set_properties_async(set_properties_list,
f"set property failed, property is None, {self.entity_id}, {self.name}" update_value, write_ha_state)
) # if not prop:
value = prop.value_format(value) # raise RuntimeError(
if prop not in self.entity_data.props: # f"set property failed, property is None, {self.entity_id}, {self.name}"
raise RuntimeError(f"set property failed, unknown property, " # )
f"{self.entity_id}, {self.name}, {prop.name}") # value = prop.value_format(value)
if not prop.writable: # if prop not in self.entity_data.props:
raise RuntimeError(f"set property failed, not writable, " # raise RuntimeError(f"set property failed, unknown property, "
f"{self.entity_id}, {self.name}, {prop.name}") # f"{self.entity_id}, {self.name}, {prop.name}")
try: # if not prop.writable:
await self.miot_device.miot_client.set_prop_async( # raise RuntimeError(f"set property failed, not writable, "
did=self.miot_device.did, # f"{self.entity_id}, {self.name}, {prop.name}")
siid=prop.service.iid, # try:
piid=prop.iid, # await self.miot_device.miot_client.set_prop_async(
value=value, # did=self.miot_device.did,
) # siid=prop.service.iid,
except MIoTClientError as e: # piid=prop.iid,
raise RuntimeError( # value=value,
f"{e}, {self.entity_id}, {self.name}, {prop.name}") from e # )
if update_value: # except MIoTClientError as e:
self._prop_value_map[prop] = value # raise RuntimeError(
if write_ha_state: # f"{e}, {self.entity_id}, {self.name}, {prop.name}") from e
self.async_write_ha_state() # if update_value:
return True # self._prop_value_map[prop] = value
# if write_ha_state:
# self.async_write_ha_state()
# return True
async def set_properties_async( async def set_properties_async(
self, self,
@ -1301,12 +1304,19 @@ class MIoTPropertyEntity(Entity):
) )
value = self.spec.value_format(value) value = self.spec.value_format(value)
try: try:
await self.miot_device.miot_client.set_prop_async( await self.miot_device.miot_client.set_props_async([{
did=self.miot_device.did, "did": self.miot_device.did,
siid=self.spec.service.iid, "siid": self.spec.service.iid,
piid=self.spec.iid, "piid": self.spec.iid,
value=value, "value": value,
) }])
# await self.miot_device.miot_client.set_prop_async(
# did=self.miot_device.did,
# siid=self.spec.service.iid,
# piid=self.spec.iid,
# value=value,
# )
except MIoTClientError as e: except MIoTClientError as e:
raise RuntimeError(f"{e}, {self.entity_id}, {self.name}") from e raise RuntimeError(f"{e}, {self.entity_id}, {self.name}") from e
self._value = value self._value = value

View File

@ -125,7 +125,9 @@ class LightCommandSendMode(SelectEntity, RestoreEntity):
self.hass = hass self.hass = hass
self._device_id = device_id self._device_id = device_id
self._attr_name = "Command Send Mode" self._attr_name = "Command Send Mode"
self._attr_unique_id = f"{DOMAIN}.light_{device_id}_command_send_mode" self.entity_id = f"select.light_{device_id}_command_send_mode"
self._attr_unique_id = self.entity_id
self._attr_options = [ self._attr_options = [
"Send One by One", "Send Turn On First", "Send Together" "Send One by One", "Send Turn On First", "Send Together"
] ]