Add new methods to dump_devinfo

This commit is contained in:
Steven B 2024-12-13 18:35:10 +00:00
parent cd0952543d
commit 099766b9d8
No known key found for this signature in database
GPG Key ID: 6D5B46B3679F2A43
5 changed files with 190 additions and 28 deletions

View File

@ -68,6 +68,10 @@ ENCRYPT_TYPES = [encrypt_type.value for encrypt_type in DeviceEncryptionType]
_LOGGER = logging.getLogger(__name__)
SMART_SINGLE_ONLY_CALLS = {
"getConnectStatus",
}
def _wrap_redactors(redactors: dict[str, Callable[[Any], Any] | None]):
"""Wrap the redactors for dump_devinfo.
@ -233,6 +237,12 @@ async def handle_device(
type=bool,
help="Set flag if the device encryption uses https.",
)
@click.option(
"--timeout",
required=False,
default=15,
help="Timeout for queries.",
)
@click.option("--port", help="Port override", type=int)
async def cli(
host,
@ -250,6 +260,7 @@ async def cli(
device_family,
login_version,
port,
timeout,
):
"""Generate devinfo files for devices.
@ -280,6 +291,7 @@ async def cli(
connection_type=connection_type,
port_override=port,
credentials=credentials,
timeout=timeout,
)
device = await Device.connect(config=dc)
await handle_device(
@ -301,6 +313,7 @@ async def cli(
port_override=port,
credentials=credentials,
connection_type=ctype,
timeout=timeout,
)
if protocol := get_protocol(config):
await handle_device(basedir, autosave, protocol, batch_size=batch_size)
@ -315,11 +328,12 @@ async def cli(
credentials=credentials,
port=port,
discovery_timeout=discovery_timeout,
timeout=timeout,
on_discovered_raw=capture_raw,
)
discovery_info = raw_discovery[device.host]
if decrypted_data := device._discovery_info.get("decrypted_data"):
discovery_info["decrypted_data"] = decrypted_data
discovery_info["result"]["decrypted_data"] = decrypted_data
await handle_device(
basedir,
autosave,
@ -336,13 +350,14 @@ async def cli(
target=target,
credentials=credentials,
discovery_timeout=discovery_timeout,
timeout=timeout,
on_discovered_raw=capture_raw,
)
click.echo(f"Detected {len(devices)} devices")
for dev in devices.values():
discovery_info = raw_discovery[dev.host]
if decrypted_data := dev._discovery_info.get("decrypted_data"):
discovery_info["decrypted_data"] = decrypted_data
discovery_info["result"]["decrypted_data"] = decrypted_data
await handle_device(
basedir,
@ -591,7 +606,11 @@ async def get_smart_camera_test_calls(protocol: SmartProtocol):
request=request,
should_succeed=True,
child_device_id="",
supports_multiple=(method != "get"),
supports_multiple=(
method != "get"
and method[:3] == "get"
and method not in SMART_SINGLE_ONLY_CALLS
),
)
)
@ -925,6 +944,7 @@ async def get_smart_fixtures(
and (child_model := response["get_device_info"].get("model"))
and child_model != parent_model
):
response = redact_data(response, _wrap_redactors(SMART_REDACTORS))
fixture_results.append(get_smart_child_fixture(response))
else:
cd = final.setdefault("child_devices", {})
@ -940,13 +960,16 @@ async def get_smart_fixtures(
child["device_id"] = scrubbed_device_ids[device_id]
# Scrub the device ids in the parent for the smart camera protocol
if gc := final.get("getChildDeviceList"):
for child in gc["child_device_list"]:
if gc := final.get("getChildDeviceComponentList"):
for child in gc["child_component_list"]:
device_id = child["device_id"]
child["device_id"] = scrubbed_device_ids[device_id]
for child in final["getChildDeviceList"]["child_device_list"]:
if device_id := child.get("device_id"):
child["device_id"] = scrubbed_device_ids[device_id]
continue
if device_id := child.get("dev_id"):
child["dev_id"] = scrubbed_device_ids[device_id]
elif dev_id := child.get("dev_id"):
child["dev_id"] = scrubbed_device_ids[dev_id]
continue
_LOGGER.error("Could not find a device for the child device: %s", child)

View File

@ -60,4 +60,7 @@ SMARTCAM_REQUESTS: list[dict] = [
{"get": {"motor": {"name": ["capability"]}}},
{"get": {"audio_capability": {"name": ["device_speaker", "device_microphone"]}}},
{"get": {"audio_config": {"name": ["speaker", "microphone"]}}},
{"getMatterSetupInfo": {"matter": {}}},
{"getConnectStatus": {"onboarding": {"get_connect_status": {}}}},
{"scanApList": {"onboarding": {"scan": {}}}},
]

View File

@ -246,14 +246,18 @@ class SmartProtocol(BaseProtocol):
responses = response_step["result"]["responses"]
for response in responses:
# smartcam devices sometimes do not populate method if there's
# only one item in the request
if (
not (method := response.get("method"))
and "result" in response
and len(requests) == 1
):
# some smartcam devices calls do not populate the method key
# which we can only handle if there's a single request.
if not (method := response.get("method")):
if len(requests) == 1:
method = next(iter(requests))
else:
_LOGGER.debug(
"No method key in response for %s, skipping: %s",
self._host,
response,
)
continue
self._handle_response_error_code(
response, method, raise_on_error=raise_on_error

View File

@ -66,10 +66,10 @@
"category": "subg.trigger.button",
"device_id": "SCRUBBED_CHILD_DEVICE_ID_1",
"fw_ver": "1.11.0 Build 230821 Rel.113553",
"hw_id": "00000000000000000000000000000000",
"hw_id": "9A1EB033BE24834E2A7A6A4E4CF405E8",
"hw_ver": "1.0",
"jamming_rssi": -120,
"jamming_signal_level": 1,
"jamming_rssi": -110,
"jamming_signal_level": 2,
"lastOnboardingTimestamp": 1714016798,
"mac": "202351000000",
"model": "S200B",
@ -78,7 +78,7 @@
"parent_device_id": "0000000000000000000000000000000000000000",
"region": "Europe/London",
"report_interval": 16,
"rssi": -55,
"rssi": -56,
"signal_level": 3,
"specs": "EU",
"status": "online",
@ -99,7 +99,7 @@
},
"get_latest_fw": {
"fw_ver": "1.12.0 Build 231121 Rel.092444",
"hw_id": "00000000000000000000000000000000",
"hw_id": "9A1EB033BE24834E2A7A6A4E4CF405E8",
"need_to_upgrade": true,
"oem_id": "00000000000000000000000000000000",
"release_date": "2024-04-02",

View File

@ -26,6 +26,7 @@
"firmware_version": "1.3.2 Build 20240424 rel.75425",
"hardware_version": "1.0",
"ip": "127.0.0.123",
"isResetWiFi": false,
"is_support_iot_cloud": true,
"mac": "A8-6E-84-00-00-00",
"mgt_encrypt_schm": {
@ -212,9 +213,9 @@
"category": "subg.trigger.button",
"device_id": "SCRUBBED_CHILD_DEVICE_ID_1",
"fw_ver": "1.11.0 Build 230821 Rel.113553",
"hw_id": "00000000000000000000000000000000",
"hw_id": "9A1EB033BE24834E2A7A6A4E4CF405E8",
"hw_ver": "1.0",
"jamming_rssi": -108,
"jamming_rssi": -110,
"jamming_signal_level": 2,
"lastOnboardingTimestamp": 1714016798,
"mac": "202351000000",
@ -224,7 +225,7 @@
"parent_device_id": "0000000000000000000000000000000000000000",
"region": "Europe/London",
"report_interval": 16,
"rssi": -66,
"rssi": -56,
"signal_level": 3,
"specs": "EU",
"status": "online",
@ -245,8 +246,19 @@
"getClockStatus": {
"system": {
"clock_status": {
"local_time": "2024-11-01 13:56:27",
"seconds_from_1970": 1730469387
"local_time": "2024-12-13 18:34:09",
"seconds_from_1970": 1734114849
}
}
},
"getConnectStatus": {
"getConnectStatus": {
"onboarding": {
"get_connect_status": {
"current_ssid": "",
"err_code": 0,
"status": 0
}
}
}
},
@ -266,7 +278,7 @@
"device_name": "#MASKED_NAME#",
"device_type": "SMART.TAPOHUB",
"has_set_location_info": 1,
"hw_id": "00000000000000000000000000000000",
"hw_id": "99A36151C79A3A5D72823C98BC0FDA5F",
"hw_version": "1.0",
"latitude": 0,
"longitude": 0,
@ -289,7 +301,7 @@
"device_name": "#MASKED_NAME#",
"device_type": "SMART.TAPOHUB",
"has_set_location_info": 1,
"hw_id": "00000000000000000000000000000000",
"hw_id": "99A36151C79A3A5D72823C98BC0FDA5F",
"hw_version": "1.0",
"latitude": 0,
"longitude": 0,
@ -329,6 +341,10 @@
}
}
},
"getMatterSetupInfo": {
"setup_code": "00000000000",
"setup_payload": "00:000000-000000000000"
},
"getMediaEncrypt": {
"cet": {
"media_encrypt": {
@ -353,7 +369,7 @@
"getSirenConfig": {
"duration": 300,
"siren_type": "Doorbell Ring 1",
"volume": "6"
"volume": "1"
},
"getSirenStatus": {
"status": "off",
@ -389,5 +405,121 @@
"zone_id": "Europe/London"
}
}
},
"scanApList": {
"scanApList": {
"onboarding": {
"scan": {
"ap_list": [
{
"auth": 3,
"bssid": "000000000000",
"encryption": 2,
"rssi": 2,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 3,
"bssid": "000000000000",
"encryption": 2,
"rssi": 1,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 3,
"bssid": "000000000000",
"encryption": 2,
"rssi": 1,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 0,
"bssid": "000000000000",
"encryption": 0,
"rssi": 1,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 3,
"bssid": "000000000000",
"encryption": 2,
"rssi": 1,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 3,
"bssid": "000000000000",
"encryption": 2,
"rssi": 0,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 3,
"bssid": "000000000000",
"encryption": 2,
"rssi": 3,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 3,
"bssid": "000000000000",
"encryption": 2,
"rssi": 3,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 4,
"bssid": "000000000000",
"encryption": 2,
"rssi": 0,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 0,
"bssid": "000000000000",
"encryption": 0,
"rssi": 0,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 3,
"bssid": "000000000000",
"encryption": 2,
"rssi": 0,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 3,
"bssid": "000000000000",
"encryption": 2,
"rssi": 1,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 4,
"bssid": "000000000000",
"encryption": 3,
"rssi": 2,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 3,
"bssid": "000000000000",
"encryption": 2,
"rssi": 1,
"ssid": "I01BU0tFRF9TU0lEIw=="
},
{
"auth": 3,
"bssid": "000000000000",
"encryption": 2,
"rssi": 1,
"ssid": "I01BU0tFRF9TU0lEIw=="
}
],
"wpa3_supported": "false"
}
}
}
}
}