Skip to content

Commit 890900d

Browse files
rytilahtisdb9696
andauthored
Add support for feature units (#843)
Co-authored-by: Steven B <51370195+sdb9696@users.noreply.github.com>
1 parent 651ad96 commit 890900d

File tree

4 files changed

+27
-25
lines changed

4 files changed

+27
-25
lines changed

kasa/cli.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -598,9 +598,10 @@ async def state(ctx, dev: Device):
598598
echo("\t[bold]== Children ==[/bold]")
599599
for child in dev.children:
600600
echo(f"\t* {child.alias} ({child.model}, {child.device_type})")
601-
for feat in child.features.values():
601+
for id_, feat in child.features.items():
602602
try:
603-
echo(f"\t\t{feat.name}: {feat.value}")
603+
unit = f" {feat.unit}" if feat.unit else ""
604+
echo(f"\t\t{feat.name} ({id_}): {feat.value}{unit}")
604605
except Exception as ex:
605606
echo(f"\t\t{feat.name}: got exception (%s)" % ex)
606607
echo()
@@ -614,12 +615,8 @@ async def state(ctx, dev: Device):
614615

615616
echo("\n\t[bold]== Device-specific information == [/bold]")
616617
for id_, feature in dev.features.items():
617-
echo(f"\t{feature.name} ({id_}): {feature.value}")
618-
619-
if dev.has_emeter:
620-
echo("\n\t[bold]== Current State ==[/bold]")
621-
emeter_status = dev.emeter_realtime
622-
echo(f"\t{emeter_status}")
618+
unit = f" {feature.unit}" if feature.unit else ""
619+
echo(f"\t{feature.name} ({id_}): {feature.value}{unit}")
623620

624621
echo("\n\t[bold]== Modules ==[/bold]")
625622
for module in dev.modules.values():
@@ -1177,7 +1174,8 @@ async def feature(dev: Device, child: str, name: str, value):
11771174
def _print_features(dev):
11781175
for name, feat in dev.features.items():
11791176
try:
1180-
echo(f"\t{feat.name} ({name}): {feat.value}")
1177+
unit = f" {feat.unit}" if feat.unit else ""
1178+
echo(f"\t{feat.name} ({name}): {feat.value}{unit}")
11811179
except Exception as ex:
11821180
echo(f"\t{feat.name} ({name}): [red]{ex}[/red]")
11831181

@@ -1198,7 +1196,8 @@ def _print_features(dev):
11981196
feat = dev.features[name]
11991197

12001198
if value is None:
1201-
echo(f"{feat.name} ({name}): {feat.value}")
1199+
unit = f" {feat.unit}" if feat.unit else ""
1200+
echo(f"{feat.name} ({name}): {feat.value}{unit}")
12021201
return feat.value
12031202

12041203
echo(f"Setting {name} to {value}")

kasa/feature.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class Feature:
3636
container: Any = None
3737
#: Icon suggestion
3838
icon: str | None = None
39+
#: Unit, if applicable
40+
unit: str | None = None
3941
#: Type of the feature
4042
type: FeatureType = FeatureType.Sensor
4143

kasa/smart/modules/energymodule.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,27 @@ def __init__(self, device: SmartDevice, module: str):
2525
name="Current consumption",
2626
attribute_getter="current_power",
2727
container=self,
28+
unit="W",
2829
)
29-
) # W or mW?
30+
)
3031
self._add_feature(
3132
Feature(
3233
device,
3334
name="Today's consumption",
3435
attribute_getter="emeter_today",
3536
container=self,
37+
unit="Wh",
3638
)
37-
) # Wh or kWh?
39+
)
3840
self._add_feature(
3941
Feature(
4042
device,
4143
name="This month's consumption",
4244
attribute_getter="emeter_this_month",
4345
container=self,
46+
unit="Wh",
4447
)
45-
) # Wh or kWH?
48+
)
4649

4750
def query(self) -> dict:
4851
"""Query to execute during the update cycle."""
@@ -54,9 +57,11 @@ def query(self) -> dict:
5457
return req
5558

5659
@property
57-
def current_power(self):
58-
"""Current power."""
59-
return self.emeter_realtime.power
60+
def current_power(self) -> float | None:
61+
"""Current power in watts."""
62+
if power := self.energy.get("current_power"):
63+
return power / 1_000
64+
return None
6065

6166
@property
6267
def energy(self):
@@ -72,22 +77,16 @@ def emeter_realtime(self):
7277
return EmeterStatus(
7378
{
7479
"power_mw": self.energy.get("current_power"),
75-
"total": self._convert_energy_data(
76-
self.energy.get("today_energy"), 1 / 1000
77-
),
80+
"total": self.energy.get("today_energy") / 1_000,
7881
}
7982
)
8083

8184
@property
8285
def emeter_this_month(self) -> float | None:
8386
"""Get the emeter value for this month."""
84-
return self._convert_energy_data(self.energy.get("month_energy"), 1 / 1000)
87+
return self.energy.get("month_energy")
8588

8689
@property
8790
def emeter_today(self) -> float | None:
8891
"""Get the emeter value for today."""
89-
return self._convert_energy_data(self.energy.get("today_energy"), 1 / 1000)
90-
91-
def _convert_energy_data(self, data, scale) -> float | None:
92-
"""Return adjusted emeter information."""
93-
return data if not data else data * scale
92+
return self.energy.get("today_energy")

kasa/tests/test_feature.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class DummyDevice:
1717
container=None,
1818
icon="mdi:dummy",
1919
type=FeatureType.BinarySensor,
20+
unit="dummyunit",
2021
)
2122
return feat
2223

@@ -30,6 +31,7 @@ def test_feature_api(dummy_feature: Feature):
3031
assert dummy_feature.container is None
3132
assert dummy_feature.icon == "mdi:dummy"
3233
assert dummy_feature.type == FeatureType.BinarySensor
34+
assert dummy_feature.unit == "dummyunit"
3335

3436

3537
def test_feature_value(dummy_feature: Feature):

0 commit comments

Comments
 (0)