# Interact with devices

Note

The library is fully async and methods that perform IO need to be run inside an async coroutine. Code examples assume you are following them inside `asyncio REPL`:

        $ python -m asyncio

Or the code is running inside an async function:

    import asyncio
    from kasa import Discover

    async def main():
        dev = await Discover.discover_single("127.0.0.1",username="un@example.com",password="pw")
        await dev.turn_on()
        await dev.update()

    if __name__ == "__main__":
        asyncio.run(main())

All of your code needs to run inside the same event loop so only call `asyncio.run` once.

The main entry point for the API is `discover()` and `discover_single()` which return Device objects. Most newer devices require your TP-Link cloud username and password, but this can be omitted for older devices.

Interact with TPLink Smart Home devices.

Once you have a device via Discovery or Connect you can start interacting with a device.

    >>> from kasa import Discover
    >>>
    >>> dev = await Discover.discover_single(
    >>>     "127.0.0.2",
    >>>     username="user@example.com",
    >>>     password="great_password"
    >>> )
    >>>

Most devices can be turned on and off

    >>> await dev.turn_on()
    >>> await dev.update()
    >>> print(dev.is_on)
    True

    >>> await dev.turn_off()
    >>> await dev.update()
    >>> print(dev.is_on)
    False

All devices provide several informational properties:

    >>> dev.alias
    Bedroom Lamp Plug
    >>> dev.model
    HS110
    >>> dev.rssi
    -71
    >>> dev.mac
    50:C7:BF:00:00:00

Some information can also be changed programmatically:

    >>> await dev.set_alias("new alias")
    >>> await dev.update()
    >>> dev.alias
    new alias

Devices support different functionality that are exposed via modules that you can access via `modules`:

    >>> for module_name in dev.modules:
    >>>     print(module_name)
    Energy
    schedule
    usage
    anti_theft
    Time
    cloud
    Led

    >>> led_module = dev.modules["Led"]
    >>> print(led_module.led)
    False
    >>> await led_module.set_led(True)
    >>> await dev.update()
    >>> print(led_module.led)
    True

Individual pieces of functionality are also exposed via features which you can access via `features` and will only be present if they are supported.

Features are similar to modules in that they provide functionality that may or may not be present.

Whereas modules group functionality into a common interface, features expose a single function that may or may not be part of a module.

The advantage of features is that they have a simple common interface of id, name, value and set_value so no need to learn the module API.

They are useful if you want write code that dynamically adapts as new features are added to the API.

    >>> for feature_name in dev.features:
    >>>     print(feature_name)
    state
    rssi
    on_since
    reboot
    current_consumption
    consumption_today
    consumption_this_month
    consumption_total
    voltage
    current
    cloud_connection
    led

    >>> led_feature = dev.features["led"]
    >>> print(led_feature.value)
    True
    >>> await led_feature.set_value(False)
    >>> await dev.update()
    >>> print(led_feature.value)
    False