Skip to content

Commit

Permalink
tapo-py: Reorganize the types
Browse files Browse the repository at this point in the history
  • Loading branch information
mihai-dinculescu committed May 4, 2024
1 parent eabdba0 commit bc6f22c
Show file tree
Hide file tree
Showing 33 changed files with 587 additions and 509 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ file. This change log follows the conventions of

- Added partial support for the H100 hub and it's child devices. Currently, only the `get_device_info` function is supported for the child devices through the hub's `get_child_device_list` method.

### Changed

- A large number of types have been reorganized to me more in line with the Rust library. This includes moving many of them under the `requests` and `responses` sub modules.

### Removed

- `l900` has been removed from the `ApiClient` until proper support is added.
Expand Down
3 changes: 2 additions & 1 deletion tapo-py/examples/tapo_l530.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import asyncio
import os

from tapo import ApiClient, Color
from tapo import ApiClient
from tapo.requests import Color


async def main():
Expand Down
3 changes: 2 additions & 1 deletion tapo-py/examples/tapo_p110.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import os
from datetime import datetime

from tapo import ApiClient, EnergyDataInterval
from tapo import ApiClient
from tapo.requests import EnergyDataInterval


async def main():
Expand Down
61 changes: 51 additions & 10 deletions tapo-py/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,80 @@ mod handlers;
use pyo3::prelude::*;

use api_client::PyApiClient;
use handlers::PyEnergyDataInterval;
use handlers::{PyColorLightSetDeviceInfoParams, PyEnergyDataInterval};
use tapo::requests::Color;
use tapo::responses::{
KE100Result, S200BResult, Status, T100Result, T110Result, T300Result, T31XResult,
TemperatureUnit, TemperatureUnitKE100, WaterLeakStatus,
ColorLightState, CurrentPowerResult, DefaultBrightnessState, DefaultColorLightState,
DefaultLightState, DefaultPlugState, DefaultPowerType, DefaultStateType,
DeviceInfoColorLightResult, DeviceInfoGenericResult, DeviceInfoHubResult,
DeviceInfoLightResult, DeviceInfoPlugResult, DeviceUsageEnergyMonitoringResult,
DeviceUsageResult, EnergyDataResult, EnergyUsageResult, KE100Result, PlugState, S200BResult,
Status, T100Result, T110Result, T300Result, T31XResult, TemperatureUnit, TemperatureUnitKE100,
UsageByPeriodResult, WaterLeakStatus,
};

#[pymodule]
#[pyo3(name = "tapo")]
fn tapo_py(py: Python, module: &PyModule) -> PyResult<()> {
module.add_class::<PyApiClient>()?;

module.add_class::<PyEnergyDataInterval>()?;
module.add_class::<Color>()?;

let requests = PyModule::new(py, "tapo.requests")?;
let responses = PyModule::new(py, "tapo.responses")?;

responses.add_class::<Status>()?;
responses.add_class::<TemperatureUnit>()?;
responses.add_class::<TemperatureUnitKE100>()?;
responses.add_class::<WaterLeakStatus>()?;
// requests
requests.add_class::<PyEnergyDataInterval>()?;
requests.add_class::<Color>()?;
requests.add_class::<PyColorLightSetDeviceInfoParams>()?;

// responses
responses.add_class::<CurrentPowerResult>()?;
responses.add_class::<DefaultBrightnessState>()?;
responses.add_class::<DefaultPowerType>()?;
responses.add_class::<DefaultStateType>()?;
responses.add_class::<DeviceUsageEnergyMonitoringResult>()?;
responses.add_class::<DeviceUsageResult>()?;
responses.add_class::<EnergyDataResult>()?;
responses.add_class::<EnergyUsageResult>()?;
responses.add_class::<UsageByPeriodResult>()?;

// responses: device info: color light
responses.add_class::<DeviceInfoColorLightResult>()?;
responses.add_class::<DefaultColorLightState>()?;
responses.add_class::<ColorLightState>()?;

// responses: device info: generic
responses.add_class::<DeviceInfoGenericResult>()?;

// responses: hub
responses.add_class::<DeviceInfoHubResult>()?;
responses.add_class::<KE100Result>()?;
responses.add_class::<S200BResult>()?;
responses.add_class::<T100Result>()?;
responses.add_class::<T110Result>()?;
responses.add_class::<T300Result>()?;
responses.add_class::<T31XResult>()?;

// responses: hub devices
responses.add_class::<Status>()?;
responses.add_class::<TemperatureUnit>()?;
responses.add_class::<TemperatureUnitKE100>()?;
responses.add_class::<WaterLeakStatus>()?;

// responses: light
responses.add_class::<DeviceInfoLightResult>()?;
responses.add_class::<DefaultLightState>()?;

// responses: plug
responses.add_class::<DeviceInfoPlugResult>()?;
responses.add_class::<DefaultPlugState>()?;
responses.add_class::<PlugState>()?;

let sys = py.import("sys")?;
let modules = sys.getattr("modules")?;
modules.set_item("tapo.requests", requests)?;
modules.set_item("tapo.responses", responses)?;

module.add_submodule(requests)?;
module.add_submodule(responses)?;

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion tapo-py/tapo-py/tapo/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ from .hub_handler import *
from .light_handler import *
from .plug_energy_monitoring_handler import *
from .plug_handler import *
from .requests import *
from .responses import *
from .types import *
122 changes: 2 additions & 120 deletions tapo-py/tapo-py/tapo/color_light_handler.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import Optional

from .types import Color, DefaultStateType, DefaultStateType, DeviceUsageResult
from tapo.responses import DeviceInfoColorLightResult, DeviceUsageResult
from tapo.requests import Color, ColorLightSetDeviceInfoParams

class ColorLightHandler:
"""Handler for the [L530](https://www.tapo.com/en/search/?q=L530) and [L630](https://www.tapo.com/en/search/?q=L630) devices."""
Expand Down Expand Up @@ -95,120 +94,3 @@ class ColorLightHandler:
Args:
color_temperature (int): between 2500 and 6500
"""

class DeviceInfoColorLightResult:
"""Device info of Tapo L530, L630 and L900. Superset of `GenericDeviceInfoResult`."""

device_id: str
type: str
model: str
hw_id: str
hw_ver: str
fw_id: str
fw_ver: str
oem_id: str
mac: str
ip: str
ssid: str
signal_level: int
rssi: int
specs: str
lang: str
device_on: bool
on_time: int
"""The time in seconds this device has been ON since the last state change (ON/OFF)."""
overheated: bool
nickname: str
avatar: str
has_set_location_info: bool
region: Optional[str]
latitude: Optional[float]
longitude: Optional[float]
time_diff: Optional[int]

# Unique to this device
brightness: int
dynamic_light_effect_enable: bool
dynamic_light_effect_id: Optional[str]
hue: Optional[int]
saturation: Optional[int]
color_temp: int
default_states: DefaultColorLightState
"""The default state of a device to be used when internet connectivity is lost after a power cut."""

def to_dict(self) -> dict:
"""Gets all the properties of this result as a dictionary.
Returns:
dict: The result as a dictionary.
"""

class DefaultColorLightState:
"""Color Light Default State."""

type: DefaultStateType
state: ColorLightState

class ColorLightState:
"""Color Light State."""

brightness: int
hue: Optional[int]
saturation: Optional[int]
color_temp: int

class ColorLightSetDeviceInfoParams:
"""Builder that is used by the `ColorLightHandler.set` API to set
multiple properties in a single request.
"""

def on(self) -> ColorLightSetDeviceInfoParams:
"""Turns *on* the device.
`ColorLightSetDeviceInfoParams.send` must be called at the end to apply the changes.
"""

def off(self) -> ColorLightSetDeviceInfoParams:
"""Turns *off* the device.
`ColorLightSetDeviceInfoParams.send` must be called at the end to apply the changes.
"""

def brightness(self, brightness: int) -> ColorLightSetDeviceInfoParams:
"""Sets the *brightness*.
`ColorLightSetDeviceInfoParams.send` must be called at the end to apply the changes.
The device will also be turned *on*, unless `ColorLightSetDeviceInfoParams.off` is called.
Args:
brightness (int): between 1 and 100
"""

def color(self, color: Color) -> ColorLightSetDeviceInfoParams:
"""Sets the *color*.
`ColorLightSetDeviceInfoParams.send` must be called at the end to apply the changes.
The device will also be turned *on*, unless `ColorLightSetDeviceInfoParams.off` is called.
Args:
color (Color): one of `tapo.Color` as defined in the Google Home app.
"""

def hue_saturation(self, hue: int, saturation: int) -> ColorLightSetDeviceInfoParams:
"""Sets the *hue* and *saturation*.
`ColorLightSetDeviceInfoParams.send` must be called at the end to apply the changes.
The device will also be turned *on*, unless `ColorLightSetDeviceInfoParams.off` is called.
Args:
hue (int): between 1 and 360
saturation (int): between 1 and 100
"""

def color_temperature(self, color_temperature: int) -> ColorLightSetDeviceInfoParams:
"""
Sets the *color temperature*.
`ColorLightSetDeviceInfoParams.send` must be called at the end to apply the changes.
The device will also be turned *on*, unless `ColorLightSetDeviceInfoParams.off` is called.
Args:
color_temperature (int): between 2500 and 6500
"""

async def send(self) -> None:
"""Performs a request to apply the changes to the device."""
39 changes: 1 addition & 38 deletions tapo-py/tapo-py/tapo/generic_device_handler.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional
from tapo.responses import DeviceInfoGenericResult

class GenericDeviceHandler:
"""Handler for generic devices. It provides the functionality common to
Expand Down Expand Up @@ -36,40 +36,3 @@ class GenericDeviceHandler:
Returns:
dict: Device info as a dictionary.
"""

class DeviceInfoGenericResult:
"""Device info of a Generic Tapo device."""

device_id: str
type: str
model: str
hw_id: str
hw_ver: str
fw_id: str
fw_ver: str
oem_id: str
mac: str
ip: str
ssid: str
signal_level: int
rssi: int
specs: str
lang: str
device_on: Optional[bool]
on_time: Optional[int]
"""The time in seconds this device has been ON since the last state change (ON/OFF)."""
overheated: bool
nickname: str
avatar: str
has_set_location_info: bool
region: Optional[str]
latitude: Optional[float]
longitude: Optional[float]
time_diff: Optional[int]

def to_dict(self) -> dict:
"""Gets all the properties of this result as a dictionary.
Returns:
dict: The result as a dictionary.
"""
52 changes: 11 additions & 41 deletions tapo-py/tapo-py/tapo/hub_handler.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
from typing import List, Optional, Union

from tapo.responses import KE100Result, S200BResult, T100Result, T110Result, T300Result, T31XResult
from typing import List, Union

from tapo.responses import (
DeviceInfoHubResult,
KE100Result,
S200BResult,
T100Result,
T110Result,
T300Result,
T31XResult,
)

class HubHandler:
"""Handler for the [H100](https://www.tapo.com/en/search/?q=H100) hubs."""
Expand Down Expand Up @@ -62,41 +70,3 @@ class HubHandler:
Returns:
dict: Device info as a dictionary.
"""

class DeviceInfoHubResult:
"""Device info of Tapo H100. Superset of `GenericDeviceInfoResult`."""

device_id: str
type: str
model: str
hw_id: str
hw_ver: str
fw_id: str
fw_ver: str
oem_id: str
mac: str
ip: str
ssid: str
signal_level: int
rssi: int
specs: str
lang: str
overheated: bool
nickname: str
avatar: str
has_set_location_info: bool
region: Optional[str]
latitude: Optional[float]
longitude: Optional[float]
time_diff: Optional[int]

# Unique to this device
in_alarm: bool
in_alarm_source: str

def to_dict(self) -> dict:
"""Gets all the properties of this result as a dictionary.
Returns:
dict: The result as a dictionary.
"""
Loading

0 comments on commit bc6f22c

Please sign in to comment.