Skip to content

Commit 1843287

Browse files
authored
v4.1.1 Normalize EMeter Data (#61)
Per #51, the `HS110` device seems to be the only EMeter device supported by this library that can have a different response for the request to get emeter data from the Kasa API. Rather than having a unit-type suffix like `_wh` (watt hours), the response just has `energy` or `total`. This change handles emeter data normalization by ensuring that the same contracts (class properties) are maintained by the library while accounting for the deviation in results from the Kasa API.
1 parent d632f6d commit 1843287

2 files changed

Lines changed: 32 additions & 4 deletions

File tree

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from setuptools import setup, find_packages
44

5-
__version__ = '4.1.0'
5+
__version__ = '4.1.1'
66

77
with open('README.md', 'r', encoding='utf-8') as readme:
88
long_description = readme.read()

tplinkcloud/emeter_device.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,30 @@
11
import asyncio
22

33
from .device import TPLinkDevice
4+
from .device_type import TPLinkDeviceType
45

56

67
class CurrentPower:
78

89
def __init__(self, realtime_data):
10+
# The HS110 does not have the unit type suffixes, and others
11+
# also may not but have yet to be identified. We attempt to
12+
# normalize the results by trying both possible keys
913
self.voltage_mv = realtime_data.get('voltage_mv')
14+
if self.voltage_mv is None:
15+
self.voltage_mv = realtime_data.get('voltage')
16+
1017
self.current_ma = realtime_data.get('current_ma')
18+
if self.current_ma is None:
19+
self.current_ma = realtime_data.get('current')
20+
1121
self.power_mw = realtime_data.get('power_mw')
22+
if self.power_mw is None:
23+
self.power_mw = realtime_data.get('power')
24+
1225
self.total_wh = realtime_data.get('total_wh')
26+
if self.total_wh is None:
27+
self.total_wh = realtime_data.get('total')
1328

1429

1530
class DayPowerSummary:
@@ -18,33 +33,44 @@ def __init__(self, day_data):
1833
self.year = day_data.get('year')
1934
self.month = day_data.get('month')
2035
self.day = day_data.get('day')
36+
# The HS110 does not have the unit type suffixes, and others
37+
# also may not but have yet to be identified. We attempt to
38+
# normalize the results by trying both possible keys
2139
self.energy_wh = day_data.get('energy_wh')
40+
if self.energy_wh is None:
41+
self.energy_wh = day_data.get('energy')
2242

2343

2444
class MonthPowerSummary:
2545

2646
def __init__(self, day_data):
2747
self.year = day_data.get('year')
2848
self.month = day_data.get('month')
49+
# The HS110 does not have the unit type suffixes, and others
50+
# also may not but have yet to be identified. We attempt to
51+
# normalize the results by trying both possible keys
2952
self.energy_wh = day_data.get('energy_wh')
53+
if self.energy_wh is None:
54+
self.energy_wh = day_data.get('energy')
3055

3156

3257
class TPLinkEMeterDevice(TPLinkDevice):
3358

3459
def __init__(self, client, device_id, device_info, child_id=None):
3560
super().__init__(client, device_id, device_info, child_id)
36-
61+
3762
# This is an override for regular devices
3863
def has_emeter(self):
3964
return True
4065

4166
async def get_power_usage_realtime(self):
4267
realtime_data = await self._pass_through_request(
43-
'emeter',
44-
'get_realtime',
68+
'emeter',
69+
'get_realtime',
4570
None
4671
)
4772
if realtime_data is not None and realtime_data.get('err_code') == 0:
73+
print(f"Found: {realtime_data}")
4874
return CurrentPower(realtime_data)
4975
return None
5076

@@ -59,6 +85,7 @@ async def get_power_usage_day(self, year, month):
5985
)
6086
# If there is no data for the requested month, data will be None
6187
if day_response_data and day_response_data.get('err_code') == 0:
88+
print(f"Day response: {day_response_data}")
6289
return [DayPowerSummary(day_data) for day_data in day_response_data['day_list']]
6390
return []
6491

@@ -72,5 +99,6 @@ async def get_power_usage_month(self, year):
7299
)
73100
# If there is no data for the requested year, data will be None
74101
if month_response_data and month_response_data.get('err_code') == 0:
102+
print(f"Month response: {month_response_data}")
75103
return [MonthPowerSummary(month_data) for month_data in month_response_data['month_list']]
76104
return []

0 commit comments

Comments
 (0)