diff --git a/tapo-py/examples/tapo_p110.py b/tapo-py/examples/tapo_p110.py index 6bfb5da..2b80a0b 100644 --- a/tapo-py/examples/tapo_p110.py +++ b/tapo-py/examples/tapo_p110.py @@ -29,6 +29,9 @@ async def main(): device_usage = await device.get_device_usage() print(f"Device usage: {device_usage.to_dict()}") + current_power = await device.get_current_power() + print(f"Current power: {current_power.to_dict()}") + energy_usage = await device.get_energy_usage() print(f"Energy usage: {energy_usage.to_dict()}") diff --git a/tapo-py/src/handlers/energy_monitoring_plug_handler.rs b/tapo-py/src/handlers/energy_monitoring_plug_handler.rs index fb2ae54..1c0f613 100644 --- a/tapo-py/src/handlers/energy_monitoring_plug_handler.rs +++ b/tapo-py/src/handlers/energy_monitoring_plug_handler.rs @@ -77,6 +77,19 @@ impl PyEnergyMonitoringPlugHandler { }) } + pub fn get_current_power<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> { + let handler = self.handler.clone(); + pyo3_asyncio::tokio::future_into_py(py, async move { + let device_info = handler + .lock() + .await + .get_current_power() + .await + .map_err(ErrorWrapper)?; + Ok(device_info) + }) + } + pub fn get_energy_usage<'a>(&'a self, py: Python<'a>) -> PyResult<&'a PyAny> { let handler = self.handler.clone(); pyo3_asyncio::tokio::future_into_py(py, async move { diff --git a/tapo-py/tapo.pyi b/tapo-py/tapo.pyi index a0d41d9..5d02424 100644 --- a/tapo-py/tapo.pyi +++ b/tapo-py/tapo.pyi @@ -234,6 +234,13 @@ class EnergyMonitoringPlugHandler: DeviceUsageResult: Contains the time in use, the power consumption, and the energy savings of the device. """ + async def get_current_power(self) -> CurrentPowerResult: + """Returns *current power* as `CurrentPowerResult`. + + Returns: + CurrentPowerResult: Contains the current power reading of the device. + """ + async def get_energy_usage(self) -> EnergyUsageResult: """Returns *energy usage* as `EnergyUsageResult`. @@ -330,6 +337,20 @@ class UsageByPeriodResult: """Past 30 days.""" +class CurrentPowerResult: + """Contains the current power reading of the device.""" + + current_power: int + """Current power in watts (W).""" + + def to_dict(self) -> dict: + """Get all the properties of this result as a dictionary. + + Returns: + dict: The result as a dictionary. + """ + + class EnergyUsageResult: """Contains local time, current power and the energy usage and runtime for today and for the current month.""" diff --git a/tapo/src/api/energy_monitoring_plug_handler.rs b/tapo/src/api/energy_monitoring_plug_handler.rs index 48e6b61..5cd39d7 100644 --- a/tapo/src/api/energy_monitoring_plug_handler.rs +++ b/tapo/src/api/energy_monitoring_plug_handler.rs @@ -67,7 +67,7 @@ impl EnergyMonitoringPlugHandler { self.client.get_energy_data(interval).await } - /// Returns *energy usage* as [`CurrentPowerResult`]. + /// Returns *current power* as [`CurrentPowerResult`]. pub async fn get_current_power(&self) -> Result { self.client.get_current_power().await } diff --git a/tapo/src/responses/current_power_result.rs b/tapo/src/responses/current_power_result.rs index 643ea93..99e1615 100644 --- a/tapo/src/responses/current_power_result.rs +++ b/tapo/src/responses/current_power_result.rs @@ -2,10 +2,29 @@ use serde::{Deserialize, Serialize}; use crate::responses::TapoResponseExt; -/// Contains local time, current power and the energy usage and runtime for today and for the current month. +/// Contains the current power reading of the device. #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "python", pyo3::prelude::pyclass(get_all))] pub struct CurrentPowerResult { - /// Current power in watts (W) + /// Current power in watts (W). pub current_power: u64, } impl TapoResponseExt for CurrentPowerResult {} + +#[cfg(feature = "python")] +#[pyo3::pymethods] +impl CurrentPowerResult { + /// Get all the properties of this result as a dictionary. + pub fn to_dict<'a>(&self, py: pyo3::Python<'a>) -> pyo3::PyResult<&'a pyo3::types::PyDict> { + let serialized = serde_json::to_value(self) + .map_err(|e| pyo3::exceptions::PyException::new_err(e.to_string()))?; + + if let Some(object) = serialized.as_object() { + let dict = crate::python::serde_object_to_py_dict(py, object)?; + + Ok(dict) + } else { + Ok(pyo3::types::PyDict::new(py)) + } + } +}