8000 Use component queries to select smartcamera modules (#1248) · python-kasa/python-kasa@3086aa8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3086aa8

Browse files
authored
Use component queries to select smartcamera modules (#1248)
1 parent 9294845 commit 3086aa8

File tree

3 files changed

+39
-18
lines changed

3 files changed

+39
-18
lines changed

kasa/experimental/modules/childdevice.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
class ChildDevice(SmartCameraModule):
88
"""Implementation for child devices."""
99

10+
REQUIRED_COMPONENT = "childControl"
1011
NAME = "childdevice"
1112
QUERY_GETTER_NAME = "getChildDeviceList"
1213
# This module is unusual in that QUERY_MODULE_NAME in the response is not

kasa/experimental/smartcamera.py

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,16 @@ def _update_children_info(self) -> None:
4343
for info in child_info["child_device_list"]:
4444
self._children[info["device_id"]]._update_internal_state(info)
4545

46-
async def _initialize_smart_child(self, info: dict) -> SmartDevice:
46+
async def _initialize_smart_child(
47+
self, info: dict, child_components: dict
48+
) -> SmartDevice:
4749
"""Initialize a smart child device attached to a smartcamera."""
4850
child_id = info["device_id"]
4951
child_protocol = _ChildCameraProtocolWrapper(child_id, self.protocol)
5052
try:
5153
initial_response = await child_protocol.query(
52-
{"component_nego": None, "get_connect_cloud_state": None}
54+
{"get_connect_cloud_state": None}
5355
)
54-
child_components = {
55-
item["id"]: item["ver_code"]
56-
for item in initial_response["component_nego"]["component_list"]
57-
}
5856
except Exception as ex:
5957
_LOGGER.exception("Error initialising child %s: %s", child_id, ex)
6058

@@ -68,20 +66,28 @@ async def _initialize_smart_child(self, info: dict) -> SmartDevice:
6866

6967
async def _initialize_children(self) -> None:
7068
"""Initialize children for hubs."""
71-
if not (
72-
child_info := self._try_get_response(
73-
self._last_update, "getChildDeviceList", {}
74-
)
75-
):
76-
return
69+
child_info_query = {
70+
"getChildDeviceList": {"childControl": {"start_index": 0}},
71+
"getChildDeviceComponentList": {"childControl": {"start_index": 0}},
72+
}
73+
resp = await self.protocol.query(child_info_query)
74+
self.internal_state.update(resp)
7775

76+
children_components = {
77+
child["device_id"]: {
78+
comp["id"]: int(comp["ver_code"]) for comp in child["component_list"]
79+
}
80+
for child in resp["getChildDeviceComponentList"]["child_component_list"]
81+
}
7882
children = {}
79-
for info in child_info["child_device_list"]:
83+
for info in resp["getChildDeviceList"]["child_device_list"]:
8084
if (
8185
category := info.get("category")
8286
) and category in SmartChildDevice.CHILD_DEVICE_TYPE_MAP:
8387
child_id = info["device_id"]
84-
children[child_id] = await self._initialize_smart_child(info)
88+
children[child_id] = await self._initialize_smart_child(
89+
info, children_components[child_id]
90+
)
8591
else:
8692
_LOGGER.debug("Child device type not supported: %s", info)
8793

@@ -90,6 +96,11 @@ async def _initialize_children(self) -> None:
9096
async def _initialize_modules(self) -> None:
9197
"""Initialize modules based on component negotiation response."""
9298
for mod in SmartCameraModule.REGISTERED_MODULES.values():
99+
if (
100+
mod.REQUIRED_COMPONENT
101+
and mod.REQUIRED_COMPONENT not in self._components
102+
):
103+
continue
93104
module = mod(self, mod._module_name())
94105
if await module._check_supported():
95106
self._modules[module.name] = module
@@ -126,12 +137,21 @@ async def _negotiate(self) -> None:
126137
"""
127138
initial_query = {
128139
"getDeviceInfo": {"device_info": {"name": ["basic_info", "info"]}},
129-
"getChildDeviceList": {"childControl": {"start_index": 0}},
140+
"getAppComponentList": {"app_component": {"name": "app_component_list"}},
130141
}
131142
resp = await self.protocol.query(initial_query)
132143
self._last_update.update(resp)
133144
self._update_internal_info(resp)
134-
await self._initialize_children()
145+
146+
self._components = {
147+
comp["name"]: int(comp["version"])
148+
for comp in resp["getAppComponentList"]["app_component"][
149+
"app_component_list"
150+
629A ]
151+
}
152+
153+
if "childControl" in self._components and not self.children:
154+
await self._initialize_children()
135155

136156
def _map_info(self, device_info: dict) -> dict:
137157
basic_info = device_info["basic_info"]

kasa/experimental/smartcameramodule.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def data(self) -> dict:
7474
if isinstance(query_resp, SmartErrorCode):
7575
raise DeviceError(
7676
f"Error accessing module data in {self._module}",
77-
error_code=SmartErrorCode,
77+
error_code=query_resp,
7878
)
7979

8080
if not query_resp:
@@ -95,6 +95,6 @@ def data(self) -> dict:
9595
if isinstance(found[key], SmartErrorCode):
9696
raise DeviceError(
9797
f"Error accessing module data {key} in {self._module}",
98-
error_code=SmartErrorCode,
98+
error_code=found[key],
9999
)
100100
return found

0 commit comments

Comments
 (0)
0