tapo 0.9.0

Unofficial Tapo API Client. Works with TP-Link Tapo smart devices. Tested with light bulbs (L510, L520, L530, L535, L610, L630), light strips (L900, L920, L930), plugs (P100, P105, P110, P110M, P115), power strips (P300, P304M, P306, P316M), hubs (H100), switches (S200B, S200D, S210) and sensors (KE100, T100, T110, T300, T310, T315).
Documentation
//! H100 Example
use std::env;
use std::time::Duration;

use log::info;
use tapo::requests::{AlarmDuration, AlarmRingtone, AlarmVolume};
use tapo::responses::ChildDeviceHubResult;
use tapo::{ApiClient, HubDevice};

mod common;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    common::setup_logger();

    let tapo_username = env::var("TAPO_USERNAME")?;
    let tapo_password = env::var("TAPO_PASSWORD")?;
    let ip_address = env::var("IP_ADDRESS")?;

    let hub = ApiClient::new(tapo_username, tapo_password)
        .h100(ip_address)
        .await?;

    let device_info = hub.get_device_info().await?;
    info!("Device info: {device_info:?}");

    info!("Getting child devices...");
    let child_device_list = hub.get_child_device_list().await?;

    for child in child_device_list {
        match child {
            ChildDeviceHubResult::KE100(device) => {
                info!(
                    "Found KE100 child device with nickname: {}, id: {}, current temperature: {} {:?} and target temperature: {} {:?}.",
                    device.nickname,
                    device.device_id,
                    device.current_temperature,
                    device.temperature_unit,
                    device.target_temperature,
                    device.temperature_unit,
                );
            }
            ChildDeviceHubResult::S200(device) => {
                let s200 = hub
                    .s200(HubDevice::ByDeviceId(device.device_id.clone()))
                    .await?;
                let trigger_logs = s200.get_trigger_logs(5, 0).await?;

                info!(
                    "Found S200B/S200D child device with nickname: {}, id: {}, last 5 trigger logs: {:?}.",
                    device.nickname, device.device_id, trigger_logs
                );
            }
            ChildDeviceHubResult::S210(device) => {
                let s210 = hub
                    .s210(HubDevice::ByDeviceId(device.device_id.clone()))
                    .await?;
                let device_usage = s210.get_device_usage().await?;

                info!(
                    "Found S210 child device with nickname: {}, id: {}, device_on: {}, device usage: {:?}.",
                    device.nickname, device.device_id, device.device_on, device_usage
                );
            }
            ChildDeviceHubResult::T100(device) => {
                let t100 = hub
                    .t100(HubDevice::ByDeviceId(device.device_id.clone()))
                    .await?;
                let trigger_logs = t100.get_trigger_logs(5, 0).await?;

                info!(
                    "Found T100 child device with nickname: {}, id: {}, detected: {}, last 5 trigger logs: {:?}.",
                    device.nickname, device.device_id, device.detected, trigger_logs
                );
            }
            ChildDeviceHubResult::T110(device) => {
                let t110 = hub
                    .t110(HubDevice::ByDeviceId(device.device_id.clone()))
                    .await?;
                let trigger_logs = t110.get_trigger_logs(5, 0).await?;

                info!(
                    "Found T110 child device with nickname: {}, id: {}, open: {}, last 5 trigger logs: {:?}.",
                    device.nickname, device.device_id, device.open, trigger_logs
                );
            }
            ChildDeviceHubResult::T300(device) => {
                let t300 = hub
                    .t300(HubDevice::ByDeviceId(device.device_id.clone()))
                    .await?;
                let trigger_logs = t300.get_trigger_logs(5, 0).await?;

                info!(
                    "Found T300 child device with nickname: {}, id: {}, in_alarm: {}, water_leak_status: {:?}, last 5 trigger logs: {:?}.",
                    device.nickname,
                    device.device_id,
                    device.in_alarm,
                    device.water_leak_status,
                    trigger_logs
                );
            }
            ChildDeviceHubResult::T31X(device) => {
                let t31x = hub
                    .t31x(HubDevice::ByDeviceId(device.device_id.clone()))
                    .await?;
                let temperature_humidity_records = t31x.get_temperature_humidity_records().await?;

                info!(
                    "Found T310/T315 child device with nickname: {}, id: {}, temperature: {} {:?}, humidity: {}%, earliest temperature and humidity record available: {:?}.",
                    device.nickname,
                    device.device_id,
                    device.current_temperature,
                    device.temperature_unit,
                    device.current_humidity,
                    temperature_humidity_records.records.first()
                );
            }
            ChildDeviceHubResult::Other(device) => {
                info!(
                    "Found unsupported child device with nickname: {}, id: {}, model: {}.",
                    device.nickname, device.device_id, device.model
                );
            }
        }
    }

    info!("Triggering the alarm ringtone 'Alarm 1' at a 'Low' volume for '3 Seconds'...");
    hub.play_alarm(
        AlarmRingtone::Alarm1,
        AlarmVolume::Low,
        AlarmDuration::Seconds(3),
    )
    .await?;

    let device_info = hub.get_device_info().await?;
    info!("Is device ringing?: {:?}", device_info.in_alarm);

    info!("Stopping the alarm after 1 Second...");
    tokio::time::sleep(Duration::from_secs(1)).await;
    hub.stop_alarm().await?;

    let device_info = hub.get_device_info().await?;
    info!("Is device ringing?: {:?}", device_info.in_alarm);

    Ok(())
}