From 1ff316211212dcb2c128ad4a6de7439ae6996c62 Mon Sep 17 00:00:00 2001 From: Teemu R Date: Thu, 25 Apr 2024 14:59:17 +0200 Subject: [PATCH] Expose IOT emeter info as features (#844) Exposes IOT emeter information using features, bases on #843 to allow defining the units. --------- Co-authored-by: Steven B <51370195+sdb9696@users.noreply.github.com> --- kasa/iot/iotstrip.py | 7 ++-- kasa/iot/modules/emeter.py | 84 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/kasa/iot/iotstrip.py b/kasa/iot/iotstrip.py index 17671545..99f5913d 100755 --- a/kasa/iot/iotstrip.py +++ b/kasa/iot/iotstrip.py @@ -18,7 +18,7 @@ from .iotdevice import ( requires_update, ) from .iotplug import IotPlug -from .modules import Antitheft, Countdown, Emeter, Schedule, Time, Usage +from .modules import Antitheft, Countdown, Schedule, Time, Usage _LOGGER = logging.getLogger(__name__) @@ -100,7 +100,6 @@ class IotStrip(IotDevice): self.add_module("usage", Usage(self, "schedule")) self.add_module("time", Time(self, "time")) self.add_module("countdown", Countdown(self, "countdown")) - self.add_module("emeter", Emeter(self, "emeter")) @property # type: ignore @requires_update @@ -217,13 +216,13 @@ class IotStrip(IotDevice): @requires_update def emeter_this_month(self) -> float | None: """Return this month's energy consumption in kWh.""" - return sum(plug.emeter_this_month for plug in self.children) + return sum(v if (v := plug.emeter_this_month) else 0 for plug in self.children) @property # type: ignore @requires_update def emeter_today(self) -> float | None: """Return this month's energy consumption in kWh.""" - return sum(plug.emeter_today for plug in self.children) + return sum(v if (v := plug.emeter_today) else 0 for plug in self.children) @property # type: ignore @requires_update diff --git a/kasa/iot/modules/emeter.py b/kasa/iot/modules/emeter.py index 52346ecc..6025eab2 100644 --- a/kasa/iot/modules/emeter.py +++ b/kasa/iot/modules/emeter.py @@ -4,13 +4,77 @@ from __future__ import annotations from datetime import datetime +from ... import Device from ...emeterstatus import EmeterStatus +from ...feature import Feature from .usage import Usage class Emeter(Usage): """Emeter module.""" + def __init__(self, device: Device, module: str): + super().__init__(device, module) + self._add_feature( + Feature( + device, + name="Current consumption", + attribute_getter="current_consumption", + container=self, + unit="W", + id="current_power_w", # for homeassistant backwards compat + ) + ) + self._add_feature( + Feature( + device, + name="Today's consumption", + attribute_getter="emeter_today", + container=self, + unit="kWh", + id="today_energy_kwh", # for homeassistant backwards compat + ) + ) + self._add_feature( + Feature( + device, + name="This month's consumption", + attribute_getter="emeter_this_month", + container=self, + unit="kWh", + ) + ) + self._add_feature( + Feature( + device, + name="Total consumption since reboot", + attribute_getter="emeter_total", + container=self, + unit="kWh", + id="total_energy_kwh", # for homeassistant backwards compat + ) + ) + self._add_feature( + Feature( + device, + name="Voltage", + attribute_getter="voltage", + container=self, + unit="V", + id="voltage", # for homeassistant backwards compat + ) + ) + self._add_feature( + Feature( + device, + name="Current", + attribute_getter="current", + container=self, + unit="A", + id="current_a", # for homeassistant backwards compat + ) + ) + @property # type: ignore def realtime(self) -> EmeterStatus: """Return current energy readings.""" @@ -32,6 +96,26 @@ class Emeter(Usage): data = self._convert_stat_data(raw_data, entry_key="month", key=current_month) return data.get(current_month) + @property + def current_consumption(self) -> float | None: + """Get the current power consumption in Watt.""" + return self.realtime.power + + @property + def emeter_total(self) -> float | None: + """Return total consumption since last reboot in kWh.""" + return self.realtime.total + + @property + def current(self) -> float | None: + """Return the current in A.""" + return self.realtime.current + + @property + def voltage(self) -> float | None: + """Get the current voltage in V.""" + return self.realtime.voltage + async def erase_stats(self): """Erase all stats.