mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 19:23:34 +00:00
Use component queries to select smartcamera modules (#1248)
This commit is contained in:
parent
9294845384
commit
3086aa8a20
@ -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
|
||||||
|
@ -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"]
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user