Skip to content

Commit 252c980

Browse files
authored
fix: sometimes FutureConsumption returns null from IEC API (#48)
1 parent e8c422f commit 252c980

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

custom_components/iec/coordinator.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from iec_api.models.device import Device
2424
from iec_api.models.exceptions import IECError
2525
from iec_api.models.jwt import JWT
26-
from iec_api.models.remote_reading import ReadingResolution, RemoteReading, FutureConsumptionInfo
26+
from iec_api.models.remote_reading import ReadingResolution, RemoteReading, FutureConsumptionInfo, RemoteReadingResponse
2727

2828
from .commons import find_reading_by_date
2929
from .const import DOMAIN, CONF_USER_ID, STATICS_DICT_NAME, STATIC_KWH_TARIFF, INVOICE_DICT_NAME, \
@@ -34,7 +34,8 @@
3434

3535

3636
async def _verify_daily_readings_exist(daily_readings: list[RemoteReading], desired_date: datetime, device: Device,
37-
contract_id: str, api: IecClient, prefetched_reading: RemoteReading | None = None):
37+
contract_id: str, api: IecClient,
38+
prefetched_reading: RemoteReadingResponse | None = None):
3839
desired_date = desired_date.replace(hour=0, minute=0, second=0, microsecond=0)
3940
daily_reading = next(filter(lambda x: find_reading_by_date(x, desired_date), daily_readings), None)
4041
if not daily_reading:
@@ -137,7 +138,7 @@ async def _async_update_data(
137138

138139
future_consumption: FutureConsumptionInfo | None = None
139140
daily_readings: list[RemoteReading] | None = None
140-
today_reading: RemoteReading | None = None
141+
today_reading: RemoteReadingResponse| None = None
141142
if self.is_smart_meter:
142143
# For some reason, there are differences between sending 2024-03-01 and sending 2024-03-07 (Today)
143144
# So instead of sending the 1st day of the month, just sending today date
@@ -155,6 +156,7 @@ async def _async_update_data(
155156
future_consumption = remote_reading.future_consumption_info
156157
daily_readings = remote_reading.data
157158

159+
weekly_future_consumption = None
158160
if datetime.today().day == 1:
159161
# if today's the 1st of the month, "yesterday" is on a different month
160162
yesterday: datetime = monthly_report_req_date - timedelta(days=1)
@@ -163,6 +165,7 @@ async def _async_update_data(
163165
ReadingResolution.WEEKLY, self._contract_id)
164166
if remote_reading:
165167
daily_readings += remote_reading.data
168+
weekly_future_consumption = remote_reading.future_consumption_info
166169

167170
# Remove duplicates
168171
daily_readings = list(dict.fromkeys(daily_readings))
@@ -179,9 +182,30 @@ async def _async_update_data(
179182
today_reading = await self.api.get_remote_reading(device.device_number, int(device.device_code),
180183
datetime.today(), datetime.today(),
181184
ReadingResolution.DAILY, self._contract_id)
185+
self._today_reading = today_reading
186+
182187
await _verify_daily_readings_exist(daily_readings, datetime.today(), device, self._contract_id, self.api,
183188
today_reading)
184189

190+
# fallbacks for future consumption since IEC api is broken :/
191+
if not future_consumption.future_consumption:
192+
if weekly_future_consumption and weekly_future_consumption.future_consumption:
193+
future_consumption = weekly_future_consumption
194+
elif self._today_reading and self._today_reading.future_consumption_info.future_consumption:
195+
future_consumption = self._today_reading.future_consumption_info
196+
else:
197+
req_date = datetime.today() - timedelta(days=2)
198+
two_days_ago_reading = await self.api.get_remote_reading(device.device_number,
199+
int(device.device_code),
200+
req_date, req_date,
201+
ReadingResolution.DAILY,
202+
self._contract_id)
203+
204+
if two_days_ago_reading:
205+
future_consumption = two_days_ago_reading.future_consumption_info
206+
else:
207+
_LOGGER.debug("Failed fetching FutureConsumption, data in IEC API is corrupted")
208+
185209
static_data = {
186210
STATIC_KWH_TARIFF: (await self.api.get_kwh_tariff()) / 100,
187211
STATIC_CONTRACT: self._contract_id,

custom_components/iec/sensor.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def _get_reading_by_date(readings: list[RemoteReading] | None, desired_date: dat
7272
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
7373
# state_class=SensorStateClass.TOTAL,
7474
suggested_display_precision=3,
75-
value_fn=lambda data: data[FUTURE_CONSUMPTIONS_DICT_NAME].future_consumption,
75+
value_fn=lambda data: data[FUTURE_CONSUMPTIONS_DICT_NAME].future_consumption or 0,
7676
),
7777
IecEntityDescription(
7878
key="elec_forecasted_cost",
@@ -81,7 +81,7 @@ def _get_reading_by_date(readings: list[RemoteReading] | None, desired_date: dat
8181
# state_class=SensorStateClass.TOTAL,
8282
suggested_display_precision=2,
8383
# The API doesn't provide future *cost* so we can try to estimate it by the previous consumption
84-
value_fn=lambda data: data[FUTURE_CONSUMPTIONS_DICT_NAME].future_consumption * data[STATICS_DICT_NAME][
84+
value_fn=lambda data: (data[FUTURE_CONSUMPTIONS_DICT_NAME].future_consumption or 0) * data[STATICS_DICT_NAME][
8585
STATIC_KWH_TARIFF]
8686
),
8787
IecEntityDescription(
@@ -116,7 +116,7 @@ def _get_reading_by_date(readings: list[RemoteReading] | None, desired_date: dat
116116
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
117117
state_class=SensorStateClass.TOTAL_INCREASING,
118118
suggested_display_precision=3,
119-
value_fn=lambda data: data[FUTURE_CONSUMPTIONS_DICT_NAME].total_import
119+
value_fn=lambda data: data[FUTURE_CONSUMPTIONS_DICT_NAME].total_import or 0
120120
),
121121
)
122122

0 commit comments

Comments
 (0)