-
Notifications
You must be signed in to change notification settings - Fork 15
Architecture Overview
piekstra edited this page Feb 7, 2026
·
1 revision
TPLinkDeviceManager # High-level manager - login, device discovery, caching
├── TPLinkApi (client.py) # Sync HTTP client - login, device listing (uses requests)
├── TPLinkDeviceClient # Async HTTP client - device passthrough commands (uses aiohttp)
│
├── TPLinkDevice # Base device class - generic passthrough
│ ├── HS100 # Smart plug
│ ├── HS103 # Smart plug lite
│ ├── HS105 # Smart plug mini
│ ├── HS110 # Smart plug with energy monitoring
│ │ └── EmeterDevice # Mixin for energy monitoring
│ ├── HS300 # Smart power strip (6 outlets)
│ │ └── HS300Child # Individual outlet
│ ├── KP115 # Smart plug with energy monitoring
│ ├── KP125 # Smart plug with energy monitoring
│ ├── KP303 # Smart power strip (3 outlets)
│ │ └── KP303Child # Individual outlet
│ └── EP40 # Smart outdoor plug
│ └── EP40Child # Individual outlet
│
├── TPLinkDeviceInfo # Device metadata (model, alias, MAC, firmware)
├── TPLinkApiResponse # API response wrapper
├── TPLinkDeviceScheduleRules # Schedule rule parsing
└── TPLinkDeviceScheduleRuleBuilder # Schedule rule construction
User Code
│
▼
TPLinkDeviceManager.get_devices()
│
├── TPLinkApi._request_post() [sync, requests library]
│ POST https://wap.tplinkcloud.com/?token=xxx&appName=Kasa_Android
│ Body: {"method": "getDeviceList", "params": {}}
│
└── For each device:
TPLinkDeviceClient._request_post() [async, aiohttp library]
POST https://wap.tplinkcloud.com/?token=xxx&appName=Kasa_Android
Body: {"method": "passthrough", "params": {"deviceId": "...", "requestData": "..."}}
-
TPLinkApi(login, device listing) uses synchronousrequestslibrary -
TPLinkDeviceClient(device commands) uses asynchronousaiohttp - This means login happens in the constructor (sync), but device operations are async
- Each device gets its own
TPLinkDeviceClientinstance - This is because devices can have different
app_server_urlvalues (regional servers) - The token is shared across all clients
-
TPLinkDeviceManager._construct_device()uses if/elif chain on model prefix - Unrecognized models fall back to generic
TPLinkDevice
Standalone HMAC-SHA1 signing logic used by both sync and async clients.
- V2 login flow (regional discovery -> login -> token)
- MFA support via callback
- Refresh token management
- Updated default params (appType, appVer, etc.)
- HMAC signing on all requests
- Updated query parameters
- SSL handling for TP-Link's private CA
Custom exception hierarchy:
-
TPLinkCloudError(base) TPLinkAuthErrorTPLinkMFARequiredErrorTPLinkTokenExpiredErrorTPLinkDeviceOfflineError
-
KP200,KP400- Outdoor plugs with child outlets -
HS200- Light switch -
KL420L5,KL430- Smart light strips (SMARTBULB type)
tplinkcloud/
├── __init__.py # Package exports
├── client.py # TPLinkApi - sync auth client
├── device_client.py # TPLinkDeviceClient - async device client
├── signing.py # NEW: HMAC-SHA1 signing
├── exceptions.py # NEW: Custom exceptions
├── api_response.py # Response wrapper
├── device_manager.py # High-level device manager
├── device_manager_power_tools.py # Bulk device operations
├── device_info.py # Device metadata
├── device.py # Base device class
├── device_type.py # Device type enum
├── device_net_info.py # Network info
├── device_time.py # Time info
├── device_timezone.py # Timezone info
├── device_schedule_rules.py # Schedule rules
├── device_schedule_rule_builder.py # Schedule rule builder
├── emeter_device.py # Energy monitoring mixin
├── hs100.py # HS100 device
├── hs103.py # HS103 device
├── hs105.py # HS105 device
├── hs110.py # HS110 device
├── hs200.py # NEW: HS200 light switch
├── hs300.py # HS300 power strip
├── hs300_child.py # HS300 outlet
├── kl420l5.py # NEW: KL420L5 light strip
├── kl430.py # NEW: KL430 light strip
├── kp115.py # KP115 device
├── kp125.py # KP125 device
├── kp200.py # NEW: KP200 outdoor plug
├── kp303.py # KP303 power strip
├── kp303_child.py # KP303 outlet
├── kp400.py # NEW: KP400 outdoor plug
└── ep40.py # EP40 outdoor plug