diff --git a/kasa/cli/device.py b/kasa/cli/device.py index 4a933b87..9814108c 100644 --- a/kasa/cli/device.py +++ b/kasa/cli/device.py @@ -193,3 +193,13 @@ async def update_credentials(dev, username, password): click.confirm("Do you really want to replace the existing credentials?", abort=True) return await dev.update_credentials(username, password) + + +@device.command(name="logs") +@pass_dev_or_child +async def child_logs(dev): + """Print child device trigger logs.""" + if logs := dev.modules.get(Module.TriggerLogs): + await dev.update(update_children=True) + for entry in logs.logs: + print(entry) diff --git a/kasa/module.py b/kasa/module.py index e10b2d63..646755e5 100644 --- a/kasa/module.py +++ b/kasa/module.py @@ -127,6 +127,7 @@ class Module(ABC): WaterleakSensor: Final[ModuleName[smart.WaterleakSensor]] = ModuleName( "WaterleakSensor" ) + TriggerLogs: Final[ModuleName[smart.TriggerLogs]] = ModuleName("TriggerLogs") # SMARTCAMERA only modules Camera: Final[ModuleName[experimental.Camera]] = ModuleName("Camera") diff --git a/kasa/smart/modules/__init__.py b/kasa/smart/modules/__init__.py index 24d5749e..d1b8dc0b 100644 --- a/kasa/smart/modules/__init__.py +++ b/kasa/smart/modules/__init__.py @@ -27,6 +27,7 @@ from .reportmode import ReportMode from .temperaturecontrol import TemperatureControl from .temperaturesensor import TemperatureSensor from .time import Time +from .triggerlogs import TriggerLogs from .waterleaksensor import WaterleakSensor __all__ = [ @@ -56,6 +57,7 @@ __all__ = [ "WaterleakSensor", "ContactSensor", "MotionSensor", + "TriggerLogs", "FrostProtection", "SmartLightEffect", ] diff --git a/kasa/smart/modules/triggerlogs.py b/kasa/smart/modules/triggerlogs.py new file mode 100644 index 00000000..480c72f5 --- /dev/null +++ b/kasa/smart/modules/triggerlogs.py @@ -0,0 +1,34 @@ +"""Implementation of trigger logs module.""" + +from __future__ import annotations + +from datetime import datetime + +from pydantic.v1 import BaseModel, Field, parse_obj_as + +from ..smartmodule import SmartModule + + +class LogEntry(BaseModel): + """Presentation of a single log entry.""" + + id: int + event_id: str = Field(alias="eventId") + timestamp: datetime + event: str + + +class TriggerLogs(SmartModule): + """Implementation of trigger logs.""" + + REQUIRED_COMPONENT = "trigger_log" + MINIMUM_UPDATE_INTERVAL_SECS = 60 * 60 + + def query(self) -> dict: + """Query to execute during the update cycle.""" + return {"get_trigger_logs": {"start_id": 0}} + + @property + def logs(self) -> list[LogEntry]: + """Return logs.""" + return parse_obj_as(list[LogEntry], self.data["logs"]) diff --git a/kasa/tests/fixtures/smart/child/S200B(US)_1.0_1.12.0.json b/kasa/tests/fixtures/smart/child/S200B(US)_1.0_1.12.0.json index 1efd7742..fa3b7c13 100644 --- a/kasa/tests/fixtures/smart/child/S200B(US)_1.0_1.12.0.json +++ b/kasa/tests/fixtures/smart/child/S200B(US)_1.0_1.12.0.json @@ -68,8 +68,8 @@ "fw_ver": "1.12.0 Build 231121 Rel.092508", "hw_id": "00000000000000000000000000000000", "hw_ver": "1.0", - "jamming_rssi": -104, - "jamming_signal_level": 2, + "jamming_rssi": -113, + "jamming_signal_level": 1, "lastOnboardingTimestamp": 1724636886, "mac": "98254A000000", "model": "S200B", @@ -78,7 +78,7 @@ "parent_device_id": "0000000000000000000000000000000000000000", "region": "Australia/Canberra", "report_interval": 16, - "rssi": -36, + "rssi": -56, "signal_level": 3, "specs": "US", "status": "online", @@ -87,6 +87,9 @@ }, "get_device_time": -1001, "get_device_usage": -1001, + "get_double_click_info": { + "enable": false + }, "get_fw_download_state": { "cloud_cache_seconds": 1, "download_progress": 0, @@ -104,5 +107,10 @@ "release_note": "", "type": 0 }, + "get_trigger_logs": { + "logs": [], + "start_id": 0, + "sum": 0 + }, "qs_component_nego": -1001 } diff --git a/kasa/tests/fixtures/smart/child/T110(US)_1.0_1.9.0.json b/kasa/tests/fixtures/smart/child/T110(US)_1.0_1.9.0.json index 73aeeb1a..43dbf731 100644 --- a/kasa/tests/fixtures/smart/child/T110(US)_1.0_1.9.0.json +++ b/kasa/tests/fixtures/smart/child/T110(US)_1.0_1.9.0.json @@ -64,7 +64,7 @@ "fw_ver": "1.9.0 Build 230704 Rel.154559", "hw_id": "00000000000000000000000000000000", "hw_ver": "1.0", - "jamming_rssi": -116, + "jamming_rssi": -113, "jamming_signal_level": 1, "lastOnboardingTimestamp": 1724635267, "mac": "A86E84000000", @@ -75,7 +75,7 @@ "parent_device_id": "0000000000000000000000000000000000000000", "region": "Australia/Canberra", "report_interval": 16, - "rssi": -55, + "rssi": -56, "signal_level": 3, "specs": "US", "status": "online", @@ -101,5 +101,10 @@ "release_note": "", "type": 0 }, + "get_trigger_logs": { + "logs": [], + "start_id": 0, + "sum": 0 + }, "qs_component_nego": -1001 } diff --git a/kasa/tests/fixtures/smart/child/T310(US)_1.0_1.5.0.json b/kasa/tests/fixtures/smart/child/T310(US)_1.0_1.5.0.json index 518e4eb7..bdc4eef6 100644 --- a/kasa/tests/fixtures/smart/child/T310(US)_1.0_1.5.0.json +++ b/kasa/tests/fixtures/smart/child/T310(US)_1.0_1.5.0.json @@ -84,15 +84,15 @@ "avatar": "sensor_t310", "bind_count": 1, "category": "subg.trigger.temp-hmdt-sensor", - "current_humidity": 51, + "current_humidity": 49, "current_humidity_exception": 0, - "current_temp": 19.4, - "current_temp_exception": -0.6, + "current_temp": 21.7, + "current_temp_exception": 0, "device_id": "SCRUBBED_CHILD_DEVICE_ID_1", "fw_ver": "1.5.0 Build 230105 Rel.180832", "hw_id": "00000000000000000000000000000000", "hw_ver": "1.0", - "jamming_rssi": -113, + "jamming_rssi": -111, "jamming_signal_level": 1, "lastOnboardingTimestamp": 1724637745, "mac": "F0A731000000", @@ -102,7 +102,7 @@ "parent_device_id": "0000000000000000000000000000000000000000", "region": "Australia/Canberra", "report_interval": 16, - "rssi": -36, + "rssi": -46, "signal_level": 3, "specs": "US", "status": "online", @@ -129,5 +129,10 @@ "release_note": "", "type": 0 }, + "get_trigger_logs": { + "logs": [], + "start_id": 0, + "sum": 0 + }, "qs_component_nego": -1001 } diff --git a/kasa/tests/fixtures/smart/child/T315(US)_1.0_1.8.0.json b/kasa/tests/fixtures/smart/child/T315(US)_1.0_1.8.0.json index 33438bb2..7a557b8c 100644 --- a/kasa/tests/fixtures/smart/child/T315(US)_1.0_1.8.0.json +++ b/kasa/tests/fixtures/smart/child/T315(US)_1.0_1.8.0.json @@ -85,15 +85,15 @@ "battery_percentage": 100, "bind_count": 1, "category": "subg.trigger.temp-hmdt-sensor", - "current_humidity": 53, + "current_humidity": 51, "current_humidity_exception": 0, - "current_temp": 18.3, - "current_temp_exception": -0.7, + "current_temp": 21.5, + "current_temp_exception": 0, "device_id": "SCRUBBED_CHILD_DEVICE_ID_2", "fw_ver": "1.8.0 Build 230921 Rel.091519", "hw_id": "00000000000000000000000000000000", "hw_ver": "1.0", - "jamming_rssi": -114, + "jamming_rssi": -113, "jamming_signal_level": 1, "lastOnboardingTimestamp": 1724637369, "mac": "202351000000", @@ -103,7 +103,7 @@ "parent_device_id": "0000000000000000000000000000000000000000", "region": "Australia/Canberra", "report_interval": 16, - "rssi": -50, + "rssi": -44, "signal_level": 3, "specs": "US", "status": "online", @@ -130,5 +130,10 @@ "release_note": "", "type": 0 }, + "get_trigger_logs": { + "logs": [], + "start_id": 0, + "sum": 0 + }, "qs_component_nego": -1001 } diff --git a/kasa/tests/fixtures/smartcamera/H200(US)_1.0_1.3.6.json b/kasa/tests/fixtures/smartcamera/H200(US)_1.0_1.3.6.json index 544ab267..dda7ade8 100644 --- a/kasa/tests/fixtures/smartcamera/H200(US)_1.0_1.3.6.json +++ b/kasa/tests/fixtures/smartcamera/H200(US)_1.0_1.3.6.json @@ -1,4 +1,35 @@ { + "discovery_result": { + "decrypted_data": { + "connect_ssid": "", + "connect_type": "wired", + "device_id": "0000000000000000000000000000000000000000", + "http_port": 443, + "owner": "00000000000000000000000000000000", + "sd_status": "offline" + }, + "device_id": "00000000000000000000000000000000", + "device_model": "H200", + "device_name": "#MASKED_NAME#", + "device_type": "SMART.TAPOHUB", + "encrypt_info": { + "data": "", + "key": "", + "sym_schm": "AES" + }, + "encrypt_type": [ + "3" + ], + "factory_default": false, + "firmware_version": "1.3.6 Build 20240829 rel.71119", + "hardware_version": "1.0", + "ip": "127.0.0.123", + "is_support_iot_cloud": true, + "mac": "24-2F-D0-00-00-00", + "mgt_encrypt_schm": { + "is_support_https": true + } + }, "getAlertConfig": {}, "getChildDeviceList": { "child_device_list": [ @@ -7,15 +38,15 @@ "avatar": "sensor_t310", "bind_count": 1, "category": "subg.trigger.temp-hmdt-sensor", - "current_humidity": 51, + "current_humidity": 49, "current_humidity_exception": 0, - "current_temp": 19.4, - "current_temp_exception": -0.6, + "current_temp": 21.7, + "current_temp_exception": 0, "device_id": "SCRUBBED_CHILD_DEVICE_ID_1", "fw_ver": "1.5.0 Build 230105 Rel.180832", "hw_id": "00000000000000000000000000000000", "hw_ver": "1.0", - "jamming_rssi": -113, + "jamming_rssi": -111, "jamming_signal_level": 1, "lastOnboardingTimestamp": 1724637745, "mac": "F0A731000000", @@ -25,7 +56,7 @@ "parent_device_id": "0000000000000000000000000000000000000000", "region": "Australia/Canberra", "report_interval": 16, - "rssi": -36, + "rssi": -46, "signal_level": 3, "specs": "US", "status": "online", @@ -39,15 +70,15 @@ "battery_percentage": 100, "bind_count": 1, "category": "subg.trigger.temp-hmdt-sensor", - "current_humidity": 53, + "current_humidity": 51, "current_humidity_exception": 0, - "current_temp": 18.3, - "current_temp_exception": -0.7, + "current_temp": 21.5, + "current_temp_exception": 0, "device_id": "SCRUBBED_CHILD_DEVICE_ID_2", "fw_ver": "1.8.0 Build 230921 Rel.091519", "hw_id": "00000000000000000000000000000000", "hw_ver": "1.0", - "jamming_rssi": -114, + "jamming_rssi": -113, "jamming_signal_level": 1, "lastOnboardingTimestamp": 1724637369, "mac": "202351000000", @@ -57,7 +88,7 @@ "parent_device_id": "0000000000000000000000000000000000000000", "region": "Australia/Canberra", "report_interval": 16, - "rssi": -50, + "rssi": -44, "signal_level": 3, "specs": "US", "status": "online", @@ -74,7 +105,7 @@ "fw_ver": "1.9.0 Build 230704 Rel.154559", "hw_id": "00000000000000000000000000000000", "hw_ver": "1.0", - "jamming_rssi": -116, + "jamming_rssi": -113, "jamming_signal_level": 1, "lastOnboardingTimestamp": 1724635267, "mac": "A86E84000000", @@ -85,7 +116,7 @@ "parent_device_id": "0000000000000000000000000000000000000000", "region": "Australia/Canberra", "report_interval": 16, - "rssi": -55, + "rssi": -56, "signal_level": 3, "specs": "US", "status": "online", @@ -101,7 +132,7 @@ "fw_ver": "1.12.0 Build 231121 Rel.092508", "hw_id": "00000000000000000000000000000000", "hw_ver": "1.0", - "jamming_rssi": -114, + "jamming_rssi": -112, "jamming_signal_level": 1, "lastOnboardingTimestamp": 1724636047, "mac": "3C52A1000000", @@ -111,7 +142,7 @@ "parent_device_id": "0000000000000000000000000000000000000000", "region": "Australia/Canberra", "report_interval": 16, - "rssi": -38, + "rssi": -36, "signal_level": 3, "specs": "US", "status": "online", @@ -127,8 +158,8 @@ "fw_ver": "1.12.0 Build 231121 Rel.092508", "hw_id": "00000000000000000000000000000000", "hw_ver": "1.0", - "jamming_rssi": -104, - "jamming_signal_level": 2, + "jamming_rssi": -113, + "jamming_signal_level": 1, "lastOnboardingTimestamp": 1724636886, "mac": "98254A000000", "model": "S200B", @@ -137,7 +168,7 @@ "parent_device_id": "0000000000000000000000000000000000000000", "region": "Australia/Canberra", "report_interval": 16, - "rssi": -36, + "rssi": -56, "signal_level": 3, "specs": "US", "status": "online", @@ -155,6 +186,14 @@ } } }, + "getClockStatus": { + "system": { + "clock_status": { + "local_time": "2024-11-01 22:16:12", + "seconds_from_1970": 1730459772 + } + } + }, "getConnectionType": { "link_type": "ethernet" }, @@ -168,7 +207,7 @@ "device_alias": "#MASKED_NAME#", "device_info": "H200 1.0", "device_model": "H200", - "device_name": "0000 0.0", + "device_name": "#MASKED_NAME#", "device_type": "SMART.TAPOHUB", "has_set_location_info": 1, "hw_id": "00000000000000000000000000000000", @@ -192,7 +231,7 @@ "device_alias": "#MASKED_NAME#", "device_info": "H200 1.0", "device_model": "H200", - "device_name": "0000 0.0", + "device_name": "#MASKED_NAME#", "device_type": "SMART.TAPOHUB", "has_set_location_info": 1, "hw_id": "00000000000000000000000000000000", @@ -210,22 +249,6 @@ } } }, - "getTimezone": { - "system": { - "basic": { - "zone_id": "Australia/Canberra", - "timezone": "UTC+10:00" - } - } - }, - "getClockStatus": { - "system": { - "clock_status": { - "seconds_from_1970": 1729509322, - "local_time": "2024-10-21 22:15:22" - } - } - }, "getFirmwareAutoUpgradeConfig": { "auto_upgrade": { "common": { @@ -304,5 +327,13 @@ "Connection 1", "Connection 2" ] + }, + "getTimezone": { + "system": { + "basic": { + "timezone": "UTC+10:00", + "zone_id": "Australia/Canberra" + } + } } } diff --git a/kasa/tests/fixtures/smartcamera/TC65_1.0_1.3.9.json b/kasa/tests/fixtures/smartcamera/TC65_1.0_1.3.9.json index 04f5354d..5b05a1b3 100644 --- a/kasa/tests/fixtures/smartcamera/TC65_1.0_1.3.9.json +++ b/kasa/tests/fixtures/smartcamera/TC65_1.0_1.3.9.json @@ -5,6 +5,8 @@ "connect_type": "wireless", "device_id": "0000000000000000000000000000000000000000", "http_port": 443, + "last_alarm_time": "1698149810", + "last_alarm_type": "motion", "owner": "00000000000000000000000000000000", "sd_status": "offline" }, @@ -40,6 +42,132 @@ } } }, + "getAppComponentList": { + "app_component": { + "app_component_list": [ + { + "name": "sdCard", + "version": 1 + }, + { + "name": "timezone", + "version": 1 + }, + { + "name": "system", + "version": 4 + }, + { + "name": "led", + "version": 1 + }, + { + "name": "playback", + "version": 4 + }, + { + "name": "detection", + "version": 3 + }, + { + "name": "alert", + "version": 1 + }, + { + "name": "firmware", + "version": 2 + }, + { + "name": "account", + "version": 1 + }, + { + "name": "quickSetup", + "version": 1 + }, + { + "name": "video", + "version": 2 + }, + { + "name": "lensMask", + "version": 2 + }, + { + "name": "lightFrequency", + "version": 1 + }, + { + "name": "dayNightMode", + "version": 1 + }, + { + "name": "osd", + "version": 2 + }, + { + "name": "record", + "version": 1 + }, + { + "name": "videoRotation", + "version": 1 + }, + { + "name": "audio", + "version": 2 + }, + { + "name": "diagnose", + "version": 1 + }, + { + "name": "msgPush", + "version": 3 + }, + { + "name": "intrusionDetection", + "version": 2 + }, + { + "name": "linecrossingDetection", + "version": 2 + }, + { + "name": "deviceShare", + "version": 1 + }, + { + "name": "tamperDetection", + "version": 1 + }, + { + "name": "tapoCare", + "version": 1 + }, + { + "name": "blockZone", + "version": 1 + }, + { + "name": "personDetection", + "version": 2 + }, + { + "name": "needSubscriptionServiceList", + "version": 1 + }, + { + "name": "iotCloud", + "version": 1 + }, + { + "name": "recordDownload", + "version": 1 + } + ] + } + }, "getAudioConfig": { "audio_config": { "microphone": { @@ -71,15 +199,15 @@ "getClockStatus": { "system": { "clock_status": { - "local_time": "2024-10-27 16:56:20", - "seconds_from_1970": 1730044580 + "local_time": "2024-11-01 16:10:28", + "seconds_from_1970": 1730473828 } } }, "getConnectionType": { "link_type": "wifi", "rssi": "3", - "rssiValue": -57, + "rssiValue": -58, "ssid": "I01BU0tFRF9TU0lEIw==" }, "getDetectionConfig": { @@ -96,7 +224,7 @@ "getDeviceInfo": { "device_info": { "basic_info": { - "avatar": "Baby room", + "avatar": "room", "barcode": "", "dev_id": "0000000000000000000000000000000000000000", "device_alias": "#MASKED_NAME#", @@ -140,8 +268,8 @@ "getLastAlarmInfo": { "system": { "last_alarm_info": { - "last_alarm_time": "", - "last_alarm_type": "" + "last_alarm_time": "1698149810", + "last_alarm_type": "motion" } } }, @@ -275,7 +403,7 @@ "chn1_msg_push_info": { ".name": "chn1_msg_push_info", ".type": "on_off", - "notification_enabled": "off", + "notification_enabled": "on", "rich_notification_enabled": "off" } }