Use component queries to select smartcamera modules (#1248)

This commit is contained in:
Steven B. 2024-11-13 10:21:12 +00:00 committed by GitHub
parent 9294845384
commit 3086aa8a20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 39 additions and 18 deletions

View File

@ -7,6 +7,7 @@ from ..smartcameramodule import SmartCameraModule
class ChildDevice(SmartCameraModule): class ChildDevice(SmartCameraModule):
"""Implementation for child devices.""" """Implementation for child devices."""
REQUIRED_COMPONENT = "childControl"
NAME = "childdevice" NAME = "childdevice"
QUERY_GETTER_NAME = "getChildDeviceList" QUERY_GETTER_NAME = "getChildDeviceList"
# This module is unusual in that QUERY_MODULE_NAME in the response is not # This module is unusual in that QUERY_MODULE_NAME in the response is not

View File

@ -43,18 +43,16 @@ class SmartCamera(SmartDevice):
for info in child_info["child_device_list"]: for info in child_info["child_device_list"]:
self._children[info["device_id"]]._update_internal_state(info) self._children[info["device_id"]]._update_internal_state(info)
async def _initialize_smart_child(self, info: dict) -> SmartDevice: async def _initialize_smart_child(
self, info: dict, child_components: dict
) -> SmartDevice:
"""Initialize a smart child device attached to a smartcamera.""" """Initialize a smart child device attached to a smartcamera."""
child_id = info["device_id"] child_id = info["device_id"]
child_protocol = _ChildCameraProtocolWrapper(child_id, self.protocol) child_protocol = _ChildCameraProtocolWrapper(child_id, self.protocol)
try: try:
initial_response = await child_protocol.query( initial_response = await child_protocol.query(
{"component_nego": None, "get_connect_cloud_state": None} {"get_connect_cloud_state": None}
) )
child_components = {
item["id"]: item["ver_code"]
for item in initial_response["component_nego"]["component_list"]
}
except Exception as ex: except Exception as ex:
_LOGGER.exception("Error initialising child %s: %s", child_id, ex) _LOGGER.exception("Error initialising child %s: %s", child_id, ex)
@ -68,20 +66,28 @@ class SmartCamera(SmartDevice):
async def _initialize_children(self) -> None: async def _initialize_children(self) -> None:
"""Initialize children for hubs.""" """Initialize children for hubs."""
if not ( child_info_query = {
child_info := self._try_get_response( "getChildDeviceList": {"childControl": {"start_index": 0}},
self._last_update, "getChildDeviceList", {} "getChildDeviceComponentList": {"childControl": {"start_index": 0}},
) }
): resp = await self.protocol.query(child_info_query)
return self.internal_state.update(resp)
children_components = {
child["device_id"]: {
comp["id"]: int(comp["ver_code"]) for comp in child["component_list"]
}
for child in resp["getChildDeviceComponentList"]["child_component_list"]
}
children = {} children = {}
for info in child_info["child_device_list"]: for info in resp["getChildDeviceList"]["child_device_list"]:
if ( if (
category := info.get("category") category := info.get("category")
) and category in SmartChildDevice.CHILD_DEVICE_TYPE_MAP: ) and category in SmartChildDevice.CHILD_DEVICE_TYPE_MAP:
child_id = info["device_id"] child_id = info["device_id"]
children[child_id] = await self._initialize_smart_child(info) children[child_id] = await self._initialize_smart_child(
info, children_components[child_id]
)
else: else:
_LOGGER.debug("Child device type not supported: %s", info) _LOGGER.debug("Child device type not supported: %s", info)
@ -90,6 +96,11 @@ class SmartCamera(SmartDevice):
async def _initialize_modules(self) -> None: async def _initialize_modules(self) -> None:
"""Initialize modules based on component negotiation response.""" """Initialize modules based on component negotiation response."""
for mod in SmartCameraModule.REGISTERED_MODULES.values(): for mod in SmartCameraModule.REGISTERED_MODULES.values():
if (
mod.REQUIRED_COMPONENT
and mod.REQUIRED_COMPONENT not in self._components
):
continue
module = mod(self, mod._module_name()) module = mod(self, mod._module_name())
if await module._check_supported(): if await module._check_supported():
self._modules[module.name] = module self._modules[module.name] = module
@ -126,12 +137,21 @@ class SmartCamera(SmartDevice):
""" """
initial_query = { initial_query = {
"getDeviceInfo": {"device_info": {"name": ["basic_info", "info"]}}, "getDeviceInfo": {"device_info": {"name": ["basic_info", "info"]}},
"getChildDeviceList": {"childControl": {"start_index": 0}}, "getAppComponentList": {"app_component": {"name": "app_component_list"}},
} }
resp = await self.protocol.query(initial_query) resp = await self.protocol.query(initial_query)
self._last_update.update(resp) self._last_update.update(resp)
self._update_internal_info(resp) self._update_internal_info(resp)
await self._initialize_children()
self._components = {
comp["name"]: int(comp["version"])
for comp in resp["getAppComponentList"]["app_component"][
"app_component_list"
]
}
if "childControl" in self._components and not self.children:
await self._initialize_children()
def _map_info(self, device_info: dict) -> dict: def _map_info(self, device_info: dict) -> dict:
basic_info = device_info["basic_info"] basic_info = device_info["basic_info"]

View File

@ -74,7 +74,7 @@ class SmartCameraModule(SmartModule):
if isinstance(query_resp, SmartErrorCode): if isinstance(query_resp, SmartErrorCode):
raise DeviceError( raise DeviceError(
f"Error accessing module data in {self._module}", f"Error accessing module data in {self._module}",
error_code=SmartErrorCode, error_code=query_resp,
) )
if not query_resp: if not query_resp:
@ -95,6 +95,6 @@ class SmartCameraModule(SmartModule):
if isinstance(found[key], SmartErrorCode): if isinstance(found[key], SmartErrorCode):
raise DeviceError( raise DeviceError(
f"Error accessing module data {key} in {self._module}", f"Error accessing module data {key} in {self._module}",
error_code=SmartErrorCode, error_code=found[key],
) )
return found return found