Skip to content

Architecture Overview

piekstra edited this page Feb 7, 2026 · 1 revision

Architecture Overview

Current Architecture (v4.x)

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

Request Flow

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": "..."}}

Key Design Decisions

Sync Login, Async Device Operations

  • TPLinkApi (login, device listing) uses synchronous requests library
  • TPLinkDeviceClient (device commands) uses asynchronous aiohttp
  • This means login happens in the constructor (sync), but device operations are async

One Client Per Device

  • Each device gets its own TPLinkDeviceClient instance
  • This is because devices can have different app_server_url values (regional servers)
  • The token is shared across all clients

Device Model Dispatch

  • TPLinkDeviceManager._construct_device() uses if/elif chain on model prefix
  • Unrecognized models fall back to generic TPLinkDevice

Planned Architecture (v5.0)

New Module: signing.py

Standalone HMAC-SHA1 signing logic used by both sync and async clients.

Updated client.py

  • V2 login flow (regional discovery -> login -> token)
  • MFA support via callback
  • Refresh token management
  • Updated default params (appType, appVer, etc.)

Updated device_client.py

  • HMAC signing on all requests
  • Updated query parameters
  • SSL handling for TP-Link's private CA

New Module: exceptions.py

Custom exception hierarchy:

  • TPLinkCloudError (base)
  • TPLinkAuthError
  • TPLinkMFARequiredError
  • TPLinkTokenExpiredError
  • TPLinkDeviceOfflineError

New Device Classes

  • KP200, KP400 - Outdoor plugs with child outlets
  • HS200 - Light switch
  • KL420L5, KL430 - Smart light strips (SMARTBULB type)

File Structure

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

Clone this wiki locally