Skip to content

Project History

piekstra edited this page Feb 7, 2026 · 1 revision

Project History

Timeline

October 2020 - Initial Release

  • Created as a Python port of adumont/tplink-cloud-api (Node.js)
  • Initial support for HS300 smart power strip
  • Used TP-Link V1 cloud API (https://wap.tplinkcloud.com)

2020-2021 - Device Expansion

  • Added support for HS100, HS103, HS105, HS110, KP115
  • Added energy monitoring support
  • Added schedule rule management
  • Added Docker-based wiremock tests
  • Added KP303 power strip support

2021-2022 - Refinements

  • Added EP40 outdoor plug support
  • Added KP125 energy monitoring plug
  • Added device runtime capability
  • Various community contributions and bug fixes

2022-2025 - Dormant Period

  • Repository largely inactive
  • TP-Link migrated their API from V1 to V2 during this period
  • Users with 2FA enabled started experiencing authentication failures
  • Several issues opened about connectivity problems

February 2026 - Revival

A comprehensive triage and modernization effort was undertaken:

Issue Triage (Feb 6-7, 2026)

6 open issues were triaged:

  • #76 (blackList error) - Closed as not a library bug (API-side rate limiting)
  • #75 (_auth_token not initialized) - Fixed, PR #77
  • #72 (login/connection issues) - Closed as user's local SSL config issue
  • #71 (deprecated auth) - Identified as V2 API migration needed
  • #68 (P100/P110 compatibility) - Documented as Tapo protocol (different library needed)
  • #65 (TypeError on json.loads) - Fixed, PR #79

CI Fixes (Feb 6, 2026)

  • Fixed broken GitHub Actions workflow (#78, PR #80)
  • Updated $default-branch to main
  • Added pytest-asyncio dependency
  • Updated docker-compose to docker compose
  • Removed Python 3.13 (aiohttp incompatibility)
  • Removed deprecated event_loop fixture
  • Added pytest.ini with asyncio_mode = auto

Release v4.2.1 (Feb 7, 2026)

  • Merged all bug fix PRs
  • Bumped version to 4.2.1
  • Created GitHub release, published to PyPI

V2 API Research (Feb 7, 2026)

  • Connected Android phone via USB, pulled Kasa APK v3.4.451
  • Decompiled with jadx, reverse-engineered the V2 API
  • Discovered:
    • New base URL: n-wap.tplinkcloud.com
    • HMAC-SHA1 request signing on all requests
    • V2 login endpoint with flat JSON body (no wrapper)
    • Regional URL discovery step
    • MFA/2FA support
    • Refresh token support
    • TP-Link private CA for SSL
  • Verified V2 login works end-to-end with real credentials
  • Successfully controlled a device (turned a light on/off) via V2 API
  • Device operations still use V1 JSON format, just with V2 signing

Project Setup (Feb 7, 2026)

  • Created GitHub Project board for v5.0 tracking
  • Created milestone "5.0.0 - V2 API Support"
  • Filed 19 issues covering:
    • V2 auth implementation (#83-#88)
    • New device support (#89-#93)
    • Codebase modernization (#94-#96)
    • Testing (#97-#98)
    • Documentation (#99)
    • Strategy (#100)
  • Set up wiki with comprehensive documentation
  • Created issue labels: v2-migration, breaking-change, auth, new-device, modernization, testing, ssl

Key Technical Discoveries

V1 vs V2 API

The most important discovery was that device operations didn't change - they still use the V1 JSON format ({"method": "getDeviceList", "params": {}}) on the root path. Only authentication moved to V2 endpoints. This means the migration is primarily about the auth layer and adding signing to existing requests, not rewriting device communication.

TP-Link's Private CA

TP-Link uses their own certificate authority for the V2 API servers. This was causing SSL failures that were hard to diagnose. The CA chain needs to be bundled with the library or users need to use the appServerUrlV2 endpoint which uses public certs.

HMAC Keys Are App-Level

The AccessKey and SecretKey used for request signing are hardcoded in the APK and identify the app, not the user. They're the same for everyone. This is a common pattern for mobile app API authentication.

Contributors

See Contributors on GitHub.

Clone this wiki locally