diff --git a/sense_energy/__init__.py b/sense_energy/__init__.py index 9baaf25..7285069 100644 --- a/sense_energy/__init__.py +++ b/sense_energy/__init__.py @@ -1,4 +1,4 @@ -from .sense_api import SenseableBase, Scale +from .sense_api import SenseableBase, Scale, SenseDevice from .sense_exceptions import * from .senseable import Senseable diff --git a/sense_energy/asyncsenseable.py b/sense_energy/asyncsenseable.py index 50b2f17..3bbef9d 100644 --- a/sense_energy/asyncsenseable.py +++ b/sense_energy/asyncsenseable.py @@ -246,9 +246,31 @@ async def get_monitor_data(self): async def fetch_devices(self) -> None: """Fetch discovered devices from API.""" json = await self._api_call(f"app/monitors/{self.sense_monitor_id}/devices/overview") + smart_plugs = {} for device in json["devices"]: - if not device["tags"].get("DeviceListAllowed", True): + if not device["tags"].get("DeviceListAllowed", True) or device["tags"].get("MergeId", None): continue + + # handle smart plugs after + if device["tags"].get("DefaultUserDeviceType", "") == "SmartPlug": + if device["name"] not in smart_plugs: + smart_plugs[device["name"]] = [] + smart_plugs[device["name"]].append(device) + continue + + id = device["id"] + if id not in self._devices: + self._devices[id] = SenseDevice(id) + self._devices[id].name = device["name"] + self._devices[id].icon = device["icon"] + + for devices in smart_plugs.values(): + device = {"tags": {"DateCreated": "2010-01-01T01:01:01.000Z"}} + for d in devices: + print(f'{d["name"]=}, {d["id"]=}, {d["tags"].get("DateCreated", "")}, {device["tags"]["DateCreated"]}') + if d["tags"].get("DateCreated", "") > device["tags"]["DateCreated"]: + device = d + id = device["id"] if id not in self._devices: self._devices[id] = SenseDevice(id) diff --git a/sense_energy/sense_api.py b/sense_energy/sense_api.py index bfae0ec..cae1e1a 100644 --- a/sense_energy/sense_api.py +++ b/sense_energy/sense_api.py @@ -27,10 +27,9 @@ def __init__(self, id): self.icon = "" self.is_on = False self.power_w = 0.0 - self.daily_kwh = 0.0 - self.weekly_kwh = 0.0 - self.monthly_kwh = 0.0 - self.yearly_kwh = 0.0 + self.energy_kwh = {} + for scale in Scale: + self.energy_kwh[scale] = 0.0 class SenseableBase(object): @@ -98,21 +97,22 @@ def _set_auth_data(self, data): def _update_device_trends(self, scale: Scale): if not self._trend_data[scale]["consumption"].get("devices"): return + for d in self._devices.values(): + d.energy_kwh[scale] = 0 for d in self._trend_data[scale]["consumption"]["devices"]: id = d["id"] if id not in self._devices: - self._devices[id] = SenseDevice(id) - self._devices[id].icon = d["icon"] + # try to match device name and combine with newer device + for did in self._devices: + if self._devices[did].name == d["name"]: + id = did + break + else: + self._devices[id] = SenseDevice(id) + self._devices[id].icon = d["icon"] if not self._devices[id].name: self._devices[id].name = d["name"] - if scale == Scale.DAY: - self._devices[id].daily_kwh = d["total_kwh"] - elif scale == Scale.WEEK: - self._devices[id].weekly_kwh = d["total_kwh"] - elif scale == Scale.MONTH: - self._devices[id].monthly_kwh = d["total_kwh"] - elif scale == Scale.YEAR: - self._devices[id].yearly_kwh = d["total_kwh"] + self._devices[id].energy_kwh[scale] += d["total_kwh"] @property def devices(self) -> list[SenseDevice]: diff --git a/sense_energy/sense_link.py b/sense_energy/sense_link.py index 2adb064..0db0474 100644 --- a/sense_energy/sense_link.py +++ b/sense_energy/sense_link.py @@ -5,7 +5,7 @@ import asyncio import logging -from typing import Iterator, Optional, Union +from typing import Optional, Union import orjson from kasa_crypt import decrypt as tp_link_decrypt @@ -21,7 +21,7 @@ class SenseLinkServerProtocol: """Class to represent a SenseLink server.""" - def __init__(self, devices: callable[[], Iterator[PlugInstance]]) -> None: + def __init__(self, devices: callable) -> None: """Initialize the SenseLink server.""" self._devices = devices self.should_respond = True @@ -90,7 +90,7 @@ class SenseLink: _devices = [] - def __init__(self, devices: callable[[], Iterator[PlugInstance]], port=SENSE_TP_LINK_PORT) -> None: + def __init__(self, devices: callable, port=SENSE_TP_LINK_PORT) -> None: """Initialize the SenseLink server.""" self.port = port self._devices = devices