{"id":9186,"library":"plugp100","title":"Tapo P100 Smart Plug Controller","description":"PlugP100 is an asynchronous Python library designed to control TP-Link Tapo P100, P105, P110, L900, L920, and similar smart devices locally. It provides a simple API for common operations like turning devices on/off, checking status, and accessing energy monitoring data where available. The current stable version is 5.1.7, with active development on version 6.x indicating a potential upcoming major release with significant changes.","status":"active","version":"5.1.7","language":"en","source_language":"en","source_url":"https://github.com/petretiandrea/plugp100","tags":["smart home","tapo","tp-link","iot","asyncio","smart plug","local control"],"install":[{"cmd":"pip install plugp100","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"PlugP100","correct":"from plugp100.api.plug_device import PlugP100"},{"symbol":"TapoError","correct":"from plugp100.common.exceptions import TapoError"}],"quickstart":{"code":"import asyncio\nimport os\nfrom plugp100.api.plug_device import PlugP100\nfrom plugp100.common.exceptions import TapoError\n\nasync def main():\n    # It's recommended to use environment variables for sensitive data\n    ip_address = os.environ.get(\"TAPO_IP\", \"192.168.1.100\") # Replace with your device IP\n    username = os.environ.get(\"TAPO_USERNAME\", \"your_tapo_email@example.com\") # Your Tapo account email\n    password = os.environ.get(\"TAPO_PASSWORD\", \"YourTapoPassword\") # Your Tapo account password\n\n    if not all([ip_address, username, password]):\n        print(\"Please set TAPO_IP, TAPO_USERNAME, and TAPO_PASSWORD environment variables.\")\n        return\n\n    # Initialize the device client\n    plug = PlugP100(ip_address, username, password)\n\n    try:\n        # Authenticate with the device\n        await plug.login()\n        print(f\"Successfully logged in to Tapo device at {ip_address}\")\n\n        # Get device information\n        device_info = await plug.get_device_info()\n        print(f\"Device Model: {device_info.model}\")\n        print(f\"Device Name: {device_info.device_name}\")\n        print(f\"Device is currently {'On' if device_info.device_on else 'Off'}\")\n\n        # Toggle the plug's power state\n        if device_info.device_on:\n            print(\"Turning off the device...\")\n            await plug.turn_off()\n        else:\n            print(\"Turning on the device...\")\n            await plug.turn_on()\n\n        # Get updated device info to confirm state change\n        device_info_updated = await plug.get_device_info()\n        print(f\"Device is now {'On' if device_info_updated.device_on else 'Off'}\")\n\n        # Example for P110/P105 with energy monitoring (uncomment if applicable)\n        # if hasattr(plug, 'get_current_energy_usage'):\n        #     energy_usage = await plug.get_current_energy_usage()\n        #     print(f\"Current Power: {energy_usage.current_power} mW\")\n\n    except TapoError as e:\n        print(f\"Tapo device error: {e}\")\n    except Exception as e:\n        print(f\"An unexpected error occurred: {e}\")\n    finally:\n        # Ensure the session is properly closed\n        if plug.is_logged_in: # Check if plug is still logged in before attempting logout\n            await plug.logout()\n            print(\"Logged out from Tapo device.\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())","lang":"python","description":"This quickstart demonstrates how to connect to a Tapo P100-series smart plug, retrieve its status, and toggle its power state. It uses environment variables for secure credential management and handles common exceptions. The library is asynchronous, so the code must be run within an `asyncio` event loop."},"warnings":[{"fix":"Monitor the official GitHub repository for release notes of 6.0.0 and review the migration guide upon its stable release.","message":"Version 6.0.0, currently in development, is expected to introduce breaking changes to the API. Users should consult the release notes when upgrading from 5.x to 6.x to adapt their code.","severity":"breaking","affected_versions":">=6.0.0-dev.1"},{"fix":"Ensure your application's entry point uses `asyncio.run(main_async_function())` and all library calls are properly `await`-ed. Review `asyncio` basics if unfamiliar.","message":"The `plugp100` library is built entirely on `asyncio`. All interactions with Tapo devices require `await` calls within an `async` function and must be run within an `asyncio` event loop.","severity":"gotcha","affected_versions":"All"},{"fix":"Verify the device's local IP address, your Tapo account credentials, and ensure the device is on the same network as the script and accessible. Tapo credentials are email and password, not local device passwords.","message":"Authentication errors, specifically `TapoError: Handshake failed`, are common if the IP address, username (Tapo account email), or password for your device is incorrect or if the device is unreachable.","severity":"gotcha","affected_versions":"All"},{"fix":"Refer to the device's specifications and the library's documentation for which features are available for your specific Tapo device model (e.g., `get_current_energy_usage` is only for P110/P105).","message":"Not all Tapo devices or models support every feature. For example, some plugs (like P100) do not provide energy monitoring data, while others (like P110, P105) do. Attempting to access unsupported features may raise errors or return empty data.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Prefix all calls to asynchronous methods with `await` (e.g., `await plug.login()`) and ensure your main application entry point is `asyncio.run(your_async_main_function())`.","cause":"Attempting to call an asynchronous function (like `plug.login()`, `plug.turn_on()`) without using the `await` keyword, or not running the top-level async function with `asyncio.run()`.","error":"RuntimeWarning: coroutine '...' was never awaited"},{"fix":"Double-check the IP address of your Tapo device, ensure the email and password match your Tapo account credentials, and confirm the device is powered on and accessible on your local network.","cause":"The library failed to establish a secure connection or authenticate with the Tapo device, typically due to an incorrect IP address, an invalid Tapo account email, or an incorrect Tapo account password.","error":"plugp100.common.exceptions.TapoError: Handshake failed"},{"fix":"Install the library using pip: `pip install plugp100`.","cause":"The `plugp100` library has not been installed in your current Python environment.","error":"ModuleNotFoundError: No module named 'plugp100'"},{"fix":"Check your device model. If it's a P100, it doesn't support energy monitoring. If it's a P110 or P105, ensure you are calling the correct energy monitoring methods (e.g., `plug.get_current_energy_usage()` or `plug.get_month_energy_usage()`) as these details are not typically part of the basic `DeviceInfo`.","cause":"You are trying to access an attribute, like `current_power` or `today_energy`, from a `DeviceInfo` object that was returned by a device that does not support energy monitoring (e.g., a P100 plug).","error":"AttributeError: 'DeviceInfo' object has no attribute 'current_power'"}]}