Add extra channels like Balance during first poll. Fix some types.

This commit is contained in:
magico13
2023-07-13 22:05:33 -04:00
parent 9d795526ee
commit e2e7f5ed01
4 changed files with 36 additions and 19 deletions

View File

@@ -1,7 +1,7 @@
"""The Emporia Vue integration."""
import asyncio
from datetime import datetime, timedelta, timezone
from typing import Any
from typing import Any, Optional
import dateutil.tz
import dateutil.relativedelta
import logging
@@ -52,8 +52,7 @@ DEVICE_GIDS: list[int] = []
DEVICE_INFORMATION: dict[int, VueDevice] = {}
LAST_MINUTE_DATA: dict[str, Any] = {}
LAST_DAY_DATA: dict[str, Any] = {}
LAST_DAY_UPDATE: datetime = None
LAST_DAY_UPDATE: Optional[datetime] = None
async def async_setup(hass: HomeAssistant, config: dict):
"""Set up the Emporia Vue component."""
@@ -88,7 +87,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
entry_data = entry.data
email = entry_data[CONF_EMAIL]
password = entry_data[CONF_PASSWORD]
vue = PyEmVue()
loop = asyncio.get_event_loop()
try:
@@ -366,9 +364,9 @@ def flatten_usage_data(
) -> tuple[dict[str, VueDeviceChannelUsage], datetime]:
"""Flattens the raw usage data into a dictionary of channel ids and usage info."""
flattened: dict[str, VueDeviceChannelUsage] = {}
data_time = None
data_time: datetime = datetime.now(timezone.utc)
for _, usage in usage_devices.items():
data_time = usage.timestamp
data_time = usage.timestamp or data_time
if usage.channels:
for _, channel in usage.channels.items():
identifier = make_channel_id(channel, scale)
@@ -386,9 +384,10 @@ def parse_flattened_usage_data(
scale: str,
data: dict[str, Any],
requested_time: datetime,
data_time: datetime = None,
data_time: datetime,
):
"""Loop through the device list and find the corresponding update data."""
unused_data = flattened_data.copy()
for gid, info in DEVICE_INFORMATION.items():
local_time = change_time_to_local(data_time, info.time_zone)
requested_time_local = change_time_to_local(requested_time, info.time_zone)
@@ -410,8 +409,8 @@ def parse_flattened_usage_data(
gid,
channel_num,
)
unused_data.pop(identifier, None)
reset_datetime = None
handle_special_channels_for_device(info_channel)
if scale in [Scale.DAY.value, Scale.MONTH.value]:
# We need to know when the value reset
@@ -448,9 +447,24 @@ def parse_flattened_usage_data(
"reset": reset_datetime,
"timestamp": local_time,
}
if unused_data:
# unused_data is not json serializable because VueDeviceChannelUsage is not JSON serializable
# instead print out dictionary as a string
_LOGGER.warning(
"Unused data found during update. Unused data: %s",
str(unused_data),
)
channels_were_added = False
for identifier, channel in unused_data.items():
channels_were_added |= handle_special_channels_for_device(channel)
# we'll also need to register these entities I think. They might show up automatically on the first run
# When we're done handling the unused data we need to rerun the update
if channels_were_added:
_LOGGER.info("Rerunning update due to added channels")
parse_flattened_usage_data(flattened_data, scale, data, requested_time, data_time)
def handle_special_channels_for_device(channel: VueDeviceChannel):
def handle_special_channels_for_device(channel: VueDeviceChannel) -> bool:
device_info = None
if channel.device_gid in DEVICE_INFORMATION:
device_info = DEVICE_INFORMATION[channel.device_gid]
@@ -489,7 +503,8 @@ def handle_special_channels_for_device(channel: VueDeviceChannel):
channelTypeGid=type_gid,
)
)
return device_info
return True
return False
def make_channel_id(channel: VueDeviceChannel, scale: str):

View File

@@ -1,5 +1,5 @@
import logging
from typing import Any
from typing import Any, Optional
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
@@ -21,7 +21,7 @@ class EmporiaChargerEntity(CoordinatorEntity):
coordinator,
vue: pyemvue.PyEmVue,
device: VueDevice,
units: str,
units: Optional[str],
device_class: str,
enabled_default=True,
) -> None:
@@ -50,7 +50,7 @@ class EmporiaChargerEntity(CoordinatorEntity):
"message": data.message,
"fault_text": data.fault_text,
}
return None
return {}
@property
def unique_id(self) -> str:

View File

@@ -9,7 +9,7 @@
"integration_type": "hub",
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/magico13/ha-emporia-vue/issues",
"requirements": ["pyemvue==0.17.1"],
"requirements": ["pyemvue==0.17.2"],
"ssdp": [],
"version": "0.9.0",
"zeroconf": []

View File

@@ -1,4 +1,5 @@
"""Platform for sensor integration."""
from typing import Optional
from homeassistant.components.sensor import (
SensorStateClass,
SensorDeviceClass,
@@ -19,6 +20,7 @@ from homeassistant.helpers.update_coordinator import (
from .const import DOMAIN
from pyemvue.enums import Scale
from pyemvue.device import VueDevice, VueDeviceChannel
_LOGGER = logging.getLogger(__name__)
@@ -60,11 +62,11 @@ class CurrentVuePowerSensor(CoordinatorEntity, SensorEntity):
"""Pass coordinator to CoordinatorEntity."""
super().__init__(coordinator)
self._id = identifier
self._scale = coordinator.data[identifier]["scale"]
device_gid = coordinator.data[identifier]["device_gid"]
channel_num = coordinator.data[identifier]["channel_num"]
self._device = coordinator.data[identifier]["info"]
self._channel = None
self._scale: str = coordinator.data[identifier]["scale"]
device_gid: int = coordinator.data[identifier]["device_gid"]
channel_num: str = coordinator.data[identifier]["channel_num"]
self._device: VueDevice = coordinator.data[identifier]["info"]
self._channel: Optional[VueDeviceChannel] = None
if self._device is not None:
for channel in self._device.channels:
if channel.channel_num == channel_num: