Skip to main content

Controller for TP-Link Tapo P100 and other devices

Project description

Plug P100

This is a fork of original work of @K4CZP3R

The purpose of this fork is to provide the library as PyPi package.

How to install

pip install plugp100

Development

uv sync
uv run pytest tests/unit
uv run black --check .

Library Architecture

The library was rewritten by taking inspiration from Component Gaming Design Pattern to achieve better decoupling from device and its capabilities. Each Tapo Device, now, is something like a container of Device Component. A Device Component represent a specific feature, so a Tapo Device can be composed by multiple device component. e.g. EnergyComponent, OverheatComponent, OnOffComponent and so on.

There 3 main Tapo Device class family, which simplify access to underlying components:

  • TapoBulb
  • TapoPlug
  • TapoHub

Supported Devices

This library supports a wide range of Tapo devices, including:

  • Tapo Smart Plugs
  • Tapo Smart Plug Strip
  • Tapo Smart Led Strip
  • Tapo Smart Bulb
  • Tapo HUB H100
    • Water Leak
    • Trigger Button (like S200)
    • Switch
    • Smart Door
    • Temperature Humidity Sensor

Every device class has more than one component which enrich the basic capability of Tapo Device. You can see the supported components inside plugp100/new/components package.

Usage

Replace <tapo_username>, <tapo_password>, and <tapo_device_ip> with your Tapo account credentials and device IP address.

Authentication

Before using the library, make sure to have your Tapo credentials ready:

from plugp100.common.credentials import AuthCredential

credentials = AuthCredential("<tapo_username>", "<tapo_password>")

Example: Discovery

Use the library to discover Tapo devices on the network:

import asyncio
import logging
from plugp100.common.credentials import AuthCredential
from plugp100.discovery.tapo_discovery import TapoDiscovery

async def example_discovery(credentials: AuthCredential):
    discovered = await TapoDiscovery.scan(timeout=5)
    for discovered_device in discovered:
        try:
            device = await discovered_device.get_tapo_device(credentials)
            await device.update()
            print({
                'type': type(device),
                'protocol': device.protocol_version,
                'raw_state': device.raw_state
            })
            await device.client.close()
        except Exception as e:
            logging.error(f"Failed to update {discovered_device.ip} {discovered_device.device_type}", exc_info=e)

async def main():
    credentials = AuthCredential("<tapo_username>", "<tapo_password>")
    await example_discovery(credentials)

if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    loop.run_until_complete(main())
    loop.run_until_complete(asyncio.sleep(0.1))
    loop.close()

Example: Connecting by only ip address

Connect to a Tapo device without knowing its device type and protocol. The library will try to guess:

import asyncio
from plugp100.common.credentials import AuthCredential
from plugp100.new.device_factory import connect, DeviceConnectConfiguration

async def example_connect_by_guessing(credentials: AuthCredential, host: str):
    device_configuration = DeviceConnectConfiguration(
        host=host,
        credentials=credentials
    )
    device = await connect(device_configuration)
    await device.update()
    print({
        'type': type(device),
        'protocol': device.protocol_version,
        'raw_state': device.raw_state,
        'components': device.get_device_components
    })

async def main():
    credentials = AuthCredential("<tapo_username>", "<tapo_password>")
    await example_connect_by_guessing(credentials, "<tapo_device_ip>")

if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    loop.run_until_complete(main())
    loop.run_until_complete(asyncio.sleep(0.1))
    loop.close()

Example: Connecting by knowing Protocol

Connect to a Tapo device with known device type and protocol details:

import asyncio
from plugp100.common.credentials import AuthCredential
from plugp100.new.device_factory import connect, DeviceConnectConfiguration

async def example_connect_knowing_device_and_protocol(credentials: AuthCredential, host: str):
    device_configuration = DeviceConnectConfiguration(
        host=host,
        credentials=credentials,
        device_type="SMART.TAPOPLUG",
        encryption_type="klap",
        encryption_version=2
    )
    device = await connect(device_configuration)
    await device.update()
    print({
        'type': type(device),
        'protocol': device.protocol_version,
        'raw_state': device.raw_state,
        'components': device.get_device_components
    })

async def main():
    credentials = AuthCredential("<tapo_username>", "<tapo_password>")
    await example_connect_knowing_device_and_protocol(credentials, "<tapo_device_ip>")

if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    loop.run_until_complete(main())
    loop.run_until_complete(asyncio.sleep(0.1))
    loop.close()

Supported Protocols

  • Klap v1
  • Klap v2
  • Passthorugh
  • Ipcamera-like?! (work in progress hub H200)

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

plugp100-6.0.0.dev2.tar.gz (61.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

plugp100-6.0.0.dev2-py3-none-any.whl (94.6 kB view details)

Uploaded Python 3

File details

Details for the file plugp100-6.0.0.dev2.tar.gz.

File metadata

  • Download URL: plugp100-6.0.0.dev2.tar.gz
  • Upload date:
  • Size: 61.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for plugp100-6.0.0.dev2.tar.gz
Algorithm Hash digest
SHA256 45d83cfad11d425154fb36f1bb8c66dddfa0709b088d3672cc91f4f405b5f799
MD5 c30cdd16c9b0f614aac2bbe3709f8304
BLAKE2b-256 7668cb8565b45ab02fc1be38c7fb4e936e01a1265c3369ae084cf88f1fdb213e

See more details on using hashes here.

File details

Details for the file plugp100-6.0.0.dev2-py3-none-any.whl.

File metadata

  • Download URL: plugp100-6.0.0.dev2-py3-none-any.whl
  • Upload date:
  • Size: 94.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for plugp100-6.0.0.dev2-py3-none-any.whl
Algorithm Hash digest
SHA256 e197a10133770d18b75b5679b3fd52e8d4a7fa787adac4d69b010050b5dc0876
MD5 a5912d61f7a935827d94a5a3427dcf48
BLAKE2b-256 a438cb59c63a4c1319074b8b1869cde01c28b8cc5597489ea45153a0fb3a9bff

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page