gazpar2haws 0.2.1__py3-none-any.whl → 0.3.0b16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gazpar2haws/__main__.py +11 -18
- gazpar2haws/bridge.py +11 -29
- gazpar2haws/config_utils.py +4 -3
- gazpar2haws/configuration.py +28 -0
- gazpar2haws/date_array.py +236 -0
- gazpar2haws/gazpar.py +199 -138
- gazpar2haws/haws.py +10 -28
- gazpar2haws/model.py +234 -0
- gazpar2haws/pricer.py +571 -0
- {gazpar2haws-0.2.1.dist-info → gazpar2haws-0.3.0b16.dist-info}/METADATA +259 -1
- gazpar2haws-0.3.0b16.dist-info/RECORD +15 -0
- gazpar2haws-0.2.1.dist-info/RECORD +0 -11
- {gazpar2haws-0.2.1.dist-info → gazpar2haws-0.3.0b16.dist-info}/LICENSE +0 -0
- {gazpar2haws-0.2.1.dist-info → gazpar2haws-0.3.0b16.dist-info}/WHEEL +0 -0
gazpar2haws/gazpar.py
CHANGED
@@ -1,12 +1,23 @@
|
|
1
1
|
import logging
|
2
2
|
import traceback
|
3
|
-
from datetime import datetime, timedelta
|
4
|
-
from typing import
|
3
|
+
from datetime import date, datetime, timedelta
|
4
|
+
from typing import Optional
|
5
5
|
|
6
6
|
import pygazpar # type: ignore
|
7
7
|
import pytz
|
8
|
+
from pygazpar.datasource import MeterReadings # type: ignore
|
8
9
|
|
10
|
+
from gazpar2haws.date_array import DateArray
|
9
11
|
from gazpar2haws.haws import HomeAssistantWS, HomeAssistantWSException
|
12
|
+
from gazpar2haws.model import (
|
13
|
+
ConsumptionQuantityArray,
|
14
|
+
Device,
|
15
|
+
PriceUnit,
|
16
|
+
Pricing,
|
17
|
+
QuantityUnit,
|
18
|
+
TimeUnit,
|
19
|
+
)
|
20
|
+
from gazpar2haws.pricer import Pricer
|
10
21
|
|
11
22
|
Logger = logging.getLogger(__name__)
|
12
23
|
|
@@ -15,80 +26,51 @@ Logger = logging.getLogger(__name__)
|
|
15
26
|
class Gazpar:
|
16
27
|
|
17
28
|
# ----------------------------------
|
18
|
-
def __init__(
|
29
|
+
def __init__(
|
30
|
+
self,
|
31
|
+
device_config: Device,
|
32
|
+
pricing_config: Optional[Pricing],
|
33
|
+
homeassistant: HomeAssistantWS,
|
34
|
+
):
|
19
35
|
|
20
36
|
self._homeassistant = homeassistant
|
37
|
+
self._grdf_config = device_config
|
38
|
+
self._pricing_config = pricing_config
|
21
39
|
|
22
40
|
# GrDF configuration: name
|
23
|
-
|
24
|
-
raise ValueError("Configuration parameter 'grdf.devices[].name' is missing")
|
25
|
-
self._name = config.get("name")
|
41
|
+
self._name = device_config.name
|
26
42
|
|
27
43
|
# GrDF configuration: data source
|
28
|
-
self._data_source =
|
29
|
-
config.get("data_source") if config.get("data_source") else "json"
|
30
|
-
)
|
44
|
+
self._data_source = device_config.data_source
|
31
45
|
|
32
46
|
# GrDF configuration: username
|
33
|
-
|
34
|
-
raise ValueError(
|
35
|
-
"Configuration parameter 'grdf.devices[].username' is missing"
|
36
|
-
)
|
37
|
-
self._username = config.get("username")
|
47
|
+
self._username = device_config.username
|
38
48
|
|
39
49
|
# GrDF configuration: password
|
40
|
-
|
41
|
-
raise ValueError(
|
42
|
-
"Configuration parameter 'grdf.devices[].password' is missing"
|
43
|
-
)
|
44
|
-
self._password = config.get("password")
|
50
|
+
self._password = device_config.password.get_secret_value() if device_config.password is not None else None
|
45
51
|
|
46
52
|
# GrDF configuration: pce_identifier
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
)
|
51
|
-
self._pce_identifier = str(config.get("pce_identifier"))
|
53
|
+
self._pce_identifier = (
|
54
|
+
device_config.pce_identifier.get_secret_value() if device_config.pce_identifier is not None else None
|
55
|
+
)
|
52
56
|
|
53
57
|
# GrDF configuration: tmp_dir
|
54
|
-
self._tmp_dir =
|
58
|
+
self._tmp_dir = device_config.tmp_dir
|
55
59
|
|
56
60
|
# GrDF configuration: last_days
|
57
|
-
|
58
|
-
raise ValueError(
|
59
|
-
"Configuration parameter 'grdf.devices[].last_days' is missing"
|
60
|
-
)
|
61
|
-
self._last_days = int(str(config.get("last_days")))
|
61
|
+
self._last_days = device_config.last_days
|
62
62
|
|
63
63
|
# GrDF configuration: timezone
|
64
|
-
|
65
|
-
raise ValueError(
|
66
|
-
"Configuration parameter 'grdf.devices[].timezone' is missing"
|
67
|
-
)
|
68
|
-
self._timezone = str(config.get("timezone"))
|
64
|
+
self._timezone = device_config.timezone
|
69
65
|
|
70
66
|
# GrDF configuration: reset
|
71
|
-
|
72
|
-
raise ValueError(
|
73
|
-
"Configuration parameter 'grdf.devices[].reset' is missing"
|
74
|
-
)
|
75
|
-
self._reset = bool(config.get("reset"))
|
67
|
+
self._reset = device_config.reset
|
76
68
|
|
77
69
|
# As of date: YYYY-MM-DD
|
78
|
-
|
79
|
-
if self._data_source is not None and str(self._data_source).lower() == "test":
|
80
|
-
self._as_of_date = (
|
81
|
-
datetime.now(tz=pytz.timezone(self._timezone))
|
82
|
-
if as_of_date is None
|
83
|
-
else datetime.strptime(as_of_date, "%Y-%m-%d")
|
84
|
-
)
|
85
|
-
else:
|
86
|
-
self._as_of_date = datetime.now(tz=pytz.timezone(self._timezone))
|
70
|
+
self._as_of_date = device_config.as_of_date
|
87
71
|
|
88
72
|
# Set the timezone
|
89
|
-
|
90
|
-
if self._as_of_date.tzinfo is None:
|
91
|
-
self._as_of_date = timezone.localize(self._as_of_date)
|
73
|
+
self._timezone = device_config.timezone
|
92
74
|
|
93
75
|
# ----------------------------------
|
94
76
|
def name(self):
|
@@ -98,41 +80,108 @@ class Gazpar:
|
|
98
80
|
# Publish Gaspar data to Home Assistant WS
|
99
81
|
async def publish(self):
|
100
82
|
|
101
|
-
# Volume and
|
83
|
+
# Volume, energy and cost sensor names.
|
102
84
|
volume_sensor_name = f"sensor.{self._name}_volume"
|
103
85
|
energy_sensor_name = f"sensor.{self._name}_energy"
|
86
|
+
cost_sensor_name = f"sensor.{self._name}_cost"
|
104
87
|
|
105
88
|
# Eventually reset the sensor in Home Assistant
|
106
89
|
if self._reset:
|
107
90
|
try:
|
108
|
-
await self._homeassistant.clear_statistics(
|
109
|
-
[volume_sensor_name, energy_sensor_name]
|
110
|
-
)
|
91
|
+
await self._homeassistant.clear_statistics([volume_sensor_name, energy_sensor_name])
|
111
92
|
except Exception:
|
112
|
-
Logger.warning(
|
113
|
-
f"Error while resetting the sensor in Home Assistant: {traceback.format_exc()}"
|
114
|
-
)
|
93
|
+
Logger.warning(f"Error while resetting the sensor in Home Assistant: {traceback.format_exc()}")
|
115
94
|
raise
|
116
95
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
)
|
121
|
-
await self.
|
122
|
-
|
96
|
+
last_date_and_value_by_sensor = dict[str, tuple[date, float]]()
|
97
|
+
|
98
|
+
last_date_and_value_by_sensor[volume_sensor_name] = await self.find_last_date_and_value(volume_sensor_name)
|
99
|
+
last_date_and_value_by_sensor[energy_sensor_name] = await self.find_last_date_and_value(energy_sensor_name)
|
100
|
+
last_date_and_value_by_sensor[cost_sensor_name] = await self.find_last_date_and_value(cost_sensor_name)
|
101
|
+
|
102
|
+
# Compute the start date as the minimum of the last dates plus one day
|
103
|
+
start_date = min(
|
104
|
+
min(v[0] for v in last_date_and_value_by_sensor.values()) + timedelta(days=1), self._as_of_date
|
123
105
|
)
|
124
106
|
|
125
|
-
|
126
|
-
|
127
|
-
async def _publish_entity(
|
128
|
-
self, entity_id: str, property_name: str, unit_of_measurement: str
|
129
|
-
):
|
107
|
+
# The end date is the as of date
|
108
|
+
end_date = self._as_of_date
|
130
109
|
|
131
|
-
#
|
132
|
-
|
133
|
-
|
110
|
+
# Fetch the data from GrDF and publish it to Home Assistant
|
111
|
+
daily_history = self.fetch_daily_gazpar_history(start_date, end_date)
|
112
|
+
|
113
|
+
# Extract the volume from the daily history
|
114
|
+
volume_array = self.extract_property_from_daily_gazpar_history(
|
115
|
+
daily_history,
|
116
|
+
pygazpar.PropertyName.VOLUME.value,
|
117
|
+
last_date_and_value_by_sensor[volume_sensor_name][0],
|
118
|
+
end_date,
|
134
119
|
)
|
135
120
|
|
121
|
+
# Extract the energy from the daily history
|
122
|
+
energy_array = self.extract_property_from_daily_gazpar_history(
|
123
|
+
daily_history,
|
124
|
+
pygazpar.PropertyName.ENERGY.value,
|
125
|
+
last_date_and_value_by_sensor[energy_sensor_name][0],
|
126
|
+
end_date,
|
127
|
+
)
|
128
|
+
|
129
|
+
# Publish the volume and energy to Home Assistant
|
130
|
+
if volume_array is not None:
|
131
|
+
await self.publish_date_array(
|
132
|
+
volume_sensor_name,
|
133
|
+
"m³",
|
134
|
+
volume_array,
|
135
|
+
last_date_and_value_by_sensor[volume_sensor_name][1],
|
136
|
+
)
|
137
|
+
else:
|
138
|
+
Logger.info("No volume data to publish")
|
139
|
+
|
140
|
+
if energy_array is not None:
|
141
|
+
await self.publish_date_array(
|
142
|
+
energy_sensor_name,
|
143
|
+
"kWh",
|
144
|
+
energy_array,
|
145
|
+
last_date_and_value_by_sensor[energy_sensor_name][1],
|
146
|
+
)
|
147
|
+
else:
|
148
|
+
Logger.info("No energy data to publish")
|
149
|
+
|
150
|
+
if self._pricing_config is None:
|
151
|
+
Logger.info("No pricing configuration provided")
|
152
|
+
return
|
153
|
+
|
154
|
+
# Compute the cost from the energy
|
155
|
+
if energy_array is not None:
|
156
|
+
pricer = Pricer(self._pricing_config)
|
157
|
+
|
158
|
+
quantities = ConsumptionQuantityArray(
|
159
|
+
start_date=last_date_and_value_by_sensor[energy_sensor_name][0],
|
160
|
+
end_date=end_date,
|
161
|
+
value_unit=QuantityUnit.KWH,
|
162
|
+
base_unit=TimeUnit.DAY,
|
163
|
+
value_array=energy_array,
|
164
|
+
)
|
165
|
+
|
166
|
+
cost_array = pricer.compute(quantities, PriceUnit.EURO)
|
167
|
+
else:
|
168
|
+
cost_array = None
|
169
|
+
|
170
|
+
# Publish the cost to Home Assistant
|
171
|
+
if cost_array is not None:
|
172
|
+
await self.publish_date_array(
|
173
|
+
cost_sensor_name,
|
174
|
+
cost_array.value_unit,
|
175
|
+
cost_array.value_array,
|
176
|
+
last_date_and_value_by_sensor[cost_sensor_name][1],
|
177
|
+
)
|
178
|
+
else:
|
179
|
+
Logger.info("No cost data to publish")
|
180
|
+
|
181
|
+
# ----------------------------------
|
182
|
+
# Fetch daily Gazpar history.
|
183
|
+
def fetch_daily_gazpar_history(self, start_date: date, end_date: date) -> MeterReadings:
|
184
|
+
|
136
185
|
# Instantiate the right data source.
|
137
186
|
data_source = self._create_data_source()
|
138
187
|
|
@@ -140,48 +189,77 @@ class Gazpar:
|
|
140
189
|
client = pygazpar.Client(data_source)
|
141
190
|
|
142
191
|
try:
|
143
|
-
|
192
|
+
history = client.loadDateRange(
|
144
193
|
pceIdentifier=self._pce_identifier,
|
145
|
-
|
194
|
+
startDate=start_date,
|
195
|
+
endDate=end_date,
|
146
196
|
frequencies=[pygazpar.Frequency.DAILY],
|
147
197
|
)
|
198
|
+
res = history[pygazpar.Frequency.DAILY.value]
|
148
199
|
except Exception: # pylint: disable=broad-except
|
149
|
-
Logger.warning(
|
150
|
-
|
151
|
-
)
|
152
|
-
data = {}
|
200
|
+
Logger.warning(f"Error while fetching data from GrDF: {traceback.format_exc()}")
|
201
|
+
res = MeterReadings()
|
153
202
|
|
154
|
-
|
155
|
-
timezone = pytz.timezone(self._timezone)
|
203
|
+
return res
|
156
204
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
205
|
+
# ----------------------------------
|
206
|
+
# Extract a given property from the daily Gazpar history and return a DateArray.
|
207
|
+
def extract_property_from_daily_gazpar_history(
|
208
|
+
self,
|
209
|
+
readings: MeterReadings,
|
210
|
+
property_name: str,
|
211
|
+
start_date: date,
|
212
|
+
end_date: date,
|
213
|
+
) -> Optional[DateArray]:
|
214
|
+
|
215
|
+
# Fill the quantity array.
|
216
|
+
res: Optional[DateArray] = None
|
217
|
+
|
218
|
+
for reading in readings:
|
162
219
|
# Parse date format DD/MM/YYYY into datetime.
|
163
|
-
|
164
|
-
reading[pygazpar.PropertyName.TIME_PERIOD.value], "%d/%m/%Y"
|
165
|
-
)
|
220
|
+
reading_date = datetime.strptime(reading[pygazpar.PropertyName.TIME_PERIOD.value], "%d/%m/%Y").date()
|
166
221
|
|
167
|
-
#
|
168
|
-
|
222
|
+
# Skip all readings before the start date.
|
223
|
+
if reading_date < start_date:
|
224
|
+
# Logger.debug(f"Skip date: {reading_date} < {start_date}")
|
225
|
+
continue
|
169
226
|
|
170
|
-
# Skip all readings
|
171
|
-
if
|
172
|
-
Logger.debug(f"Skip date: {
|
227
|
+
# Skip all readings after the end date.
|
228
|
+
if reading_date > end_date:
|
229
|
+
# Logger.debug(f"Skip date: {reading_date} > {end_date}")
|
173
230
|
continue
|
174
231
|
|
175
|
-
#
|
232
|
+
# Fill the quantity array.
|
176
233
|
if reading[property_name] is not None:
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
234
|
+
if res is None:
|
235
|
+
res = DateArray(start_date=start_date, end_date=end_date)
|
236
|
+
res[reading_date] = reading[property_name]
|
237
|
+
|
238
|
+
return res
|
239
|
+
|
240
|
+
# ----------------------------------
|
241
|
+
# Push a date array to Home Assistant.
|
242
|
+
async def publish_date_array(
|
243
|
+
self,
|
244
|
+
entity_id: str,
|
245
|
+
unit_of_measurement: str,
|
246
|
+
date_array: DateArray,
|
247
|
+
initial_value: float,
|
248
|
+
):
|
183
249
|
|
184
|
-
|
250
|
+
# Compute the cumulative sum of the values.
|
251
|
+
total_array = date_array.cumsum() + initial_value
|
252
|
+
|
253
|
+
# Timezone
|
254
|
+
timezone = pytz.timezone(self._timezone)
|
255
|
+
|
256
|
+
# Fill the statistics.
|
257
|
+
statistics = []
|
258
|
+
for dt, total in total_array:
|
259
|
+
# Set the timezone
|
260
|
+
date_time = datetime.combine(dt, datetime.min.time())
|
261
|
+
date_time = timezone.localize(date_time)
|
262
|
+
statistics.append({"start": date_time.isoformat(), "state": total, "sum": total})
|
185
263
|
|
186
264
|
# Publish statistics to Home Assistant
|
187
265
|
try:
|
@@ -189,9 +267,7 @@ class Gazpar:
|
|
189
267
|
entity_id, "recorder", "gazpar2haws", unit_of_measurement, statistics
|
190
268
|
)
|
191
269
|
except Exception:
|
192
|
-
Logger.warning(
|
193
|
-
f"Error while importing statistics to Home Assistant: {traceback.format_exc()}"
|
194
|
-
)
|
270
|
+
Logger.warning(f"Error while importing statistics to Home Assistant: {traceback.format_exc()}")
|
195
271
|
raise
|
196
272
|
|
197
273
|
# ----------------------------------
|
@@ -209,36 +285,31 @@ class Gazpar:
|
|
209
285
|
tmpDirectory=self._tmp_dir,
|
210
286
|
)
|
211
287
|
|
212
|
-
return pygazpar.JsonWebDataSource(
|
213
|
-
username=self._username, password=self._password
|
214
|
-
)
|
288
|
+
return pygazpar.JsonWebDataSource(username=self._username, password=self._password)
|
215
289
|
|
216
290
|
# ----------------------------------
|
217
|
-
# Find last date,
|
218
|
-
async def
|
219
|
-
self, entity_id: str
|
220
|
-
) -> tuple[datetime, int, float]:
|
291
|
+
# Find last date, value of the entity.
|
292
|
+
async def find_last_date_and_value(self, entity_id: str) -> tuple[date, float]:
|
221
293
|
|
222
294
|
# Check the existence of the sensor in Home Assistant
|
223
295
|
try:
|
224
|
-
exists_statistic_id = await self._homeassistant.exists_statistic_id(
|
225
|
-
entity_id, "sum"
|
226
|
-
)
|
296
|
+
exists_statistic_id = await self._homeassistant.exists_statistic_id(entity_id, "sum")
|
227
297
|
except Exception:
|
228
298
|
Logger.warning(
|
229
|
-
f"Error while checking the existence of the
|
299
|
+
f"Error while checking the existence of the entity '{entity_id}' in Home Assistant: {traceback.format_exc()}"
|
230
300
|
)
|
231
301
|
raise
|
232
302
|
|
233
303
|
if exists_statistic_id:
|
234
304
|
# Get the last statistic from Home Assistant
|
235
305
|
try:
|
236
|
-
|
237
|
-
|
238
|
-
|
306
|
+
as_of_date = datetime.combine(self._as_of_date, datetime.min.time())
|
307
|
+
as_of_date = pytz.timezone(self._timezone).localize(as_of_date)
|
308
|
+
|
309
|
+
last_statistic = await self._homeassistant.get_last_statistic(entity_id, as_of_date, self._last_days)
|
239
310
|
except HomeAssistantWSException:
|
240
311
|
Logger.warning(
|
241
|
-
f"Error while fetching last statistics from Home Assistant: {traceback.format_exc()}"
|
312
|
+
f"Error while fetching last statistics of the entity '{entity_id}' from Home Assistant: {traceback.format_exc()}"
|
242
313
|
)
|
243
314
|
|
244
315
|
if last_statistic:
|
@@ -246,35 +317,25 @@ class Gazpar:
|
|
246
317
|
last_date = datetime.fromtimestamp(
|
247
318
|
int(str(last_statistic.get("start"))) / 1000,
|
248
319
|
tz=pytz.timezone(self._timezone),
|
249
|
-
)
|
250
|
-
|
251
|
-
# Compute the number of days since the last statistics
|
252
|
-
last_days = (self._as_of_date - last_date).days
|
320
|
+
).date()
|
253
321
|
|
254
322
|
# Get the last meter value
|
255
323
|
last_value = float(str(last_statistic.get("sum")))
|
256
324
|
|
257
|
-
Logger.debug(
|
258
|
-
f"Last date: {last_date}, last days: {last_days}, last value: {last_value}"
|
259
|
-
)
|
325
|
+
Logger.debug(f"Entity '{entity_id}' => Last date: {last_date}, last value: {last_value}")
|
260
326
|
|
261
|
-
return last_date,
|
327
|
+
return last_date, last_value
|
262
328
|
|
263
|
-
Logger.debug(f"No statistics found
|
329
|
+
Logger.debug(f"Entity '{entity_id}' => No statistics found.")
|
264
330
|
else:
|
265
|
-
Logger.debug(f"
|
266
|
-
|
267
|
-
# If the sensor does not exist in Home Assistant, fetch the last days defined in the configuration
|
268
|
-
last_days = self._last_days
|
331
|
+
Logger.debug(f"Entity '{entity_id}' does not exist in Home Assistant.")
|
269
332
|
|
270
333
|
# Compute the corresponding last_date
|
271
|
-
last_date = self._as_of_date - timedelta(days=
|
334
|
+
last_date = self._as_of_date - timedelta(days=self._last_days)
|
272
335
|
|
273
336
|
# If no statistic, the last value is initialized to zero
|
274
337
|
last_value = 0
|
275
338
|
|
276
|
-
Logger.debug(
|
277
|
-
f"Last date: {last_date}, last days: {last_days}, last value: {last_value}"
|
278
|
-
)
|
339
|
+
Logger.debug(f"Entity '{entity_id}' => Last date: {last_date}, last value: {last_value}")
|
279
340
|
|
280
|
-
return last_date,
|
341
|
+
return last_date, last_value
|
gazpar2haws/haws.py
CHANGED
@@ -15,7 +15,7 @@ class HomeAssistantWSException(Exception):
|
|
15
15
|
# ----------------------------------
|
16
16
|
class HomeAssistantWS:
|
17
17
|
# ----------------------------------
|
18
|
-
def __init__(self, host: str, port:
|
18
|
+
def __init__(self, host: str, port: int, endpoint: str, token: str):
|
19
19
|
self._host = host
|
20
20
|
self._port = port
|
21
21
|
self._endpoint = endpoint
|
@@ -92,9 +92,7 @@ class HomeAssistantWS:
|
|
92
92
|
raise HomeAssistantWSException(f"Invalid response message: {response_data}")
|
93
93
|
|
94
94
|
if not response_data.get("success"):
|
95
|
-
raise HomeAssistantWSException(
|
96
|
-
f"Request failed: {response_data.get('error')}"
|
97
|
-
)
|
95
|
+
raise HomeAssistantWSException(f"Request failed: {response_data.get('error')}")
|
98
96
|
|
99
97
|
return response_data.get("result")
|
100
98
|
|
@@ -122,17 +120,13 @@ class HomeAssistantWS:
|
|
122
120
|
return response
|
123
121
|
|
124
122
|
# ----------------------------------
|
125
|
-
async def exists_statistic_id(
|
126
|
-
self, entity_id: str, statistic_type: str | None = None
|
127
|
-
) -> bool:
|
123
|
+
async def exists_statistic_id(self, entity_id: str, statistic_type: str | None = None) -> bool:
|
128
124
|
|
129
125
|
Logger.debug(f"Checking if {entity_id} exists...")
|
130
126
|
|
131
127
|
statistic_ids = await self.list_statistic_ids(statistic_type)
|
132
128
|
|
133
|
-
entity_ids = [
|
134
|
-
statistic_id.get("statistic_id") for statistic_id in statistic_ids
|
135
|
-
]
|
129
|
+
entity_ids = [statistic_id.get("statistic_id") for statistic_id in statistic_ids]
|
136
130
|
|
137
131
|
exists_statistic = entity_id in entity_ids
|
138
132
|
|
@@ -141,13 +135,9 @@ class HomeAssistantWS:
|
|
141
135
|
return exists_statistic
|
142
136
|
|
143
137
|
# ----------------------------------
|
144
|
-
async def statistics_during_period(
|
145
|
-
self, entity_ids: list[str], start_time: datetime, end_time: datetime
|
146
|
-
) -> dict:
|
138
|
+
async def statistics_during_period(self, entity_ids: list[str], start_time: datetime, end_time: datetime) -> dict:
|
147
139
|
|
148
|
-
Logger.debug(
|
149
|
-
f"Getting {entity_ids} statistics during period from {start_time} to {end_time}..."
|
150
|
-
)
|
140
|
+
Logger.debug(f"Getting {entity_ids} statistics during period from {start_time} to {end_time}...")
|
151
141
|
|
152
142
|
# Subscribe to statistics
|
153
143
|
statistics_message = {
|
@@ -166,16 +156,12 @@ class HomeAssistantWS:
|
|
166
156
|
f"Invalid statistics_during_period response type: got {type(response)} instead of dict"
|
167
157
|
)
|
168
158
|
|
169
|
-
Logger.debug(
|
170
|
-
f"Received {entity_ids} statistics during period from {start_time} to {end_time}"
|
171
|
-
)
|
159
|
+
Logger.debug(f"Received {entity_ids} statistics during period from {start_time} to {end_time}")
|
172
160
|
|
173
161
|
return response
|
174
162
|
|
175
163
|
# ----------------------------------
|
176
|
-
async def get_last_statistic(
|
177
|
-
self, entity_id: str, as_of_date: datetime, depth_days: int
|
178
|
-
) -> dict:
|
164
|
+
async def get_last_statistic(self, entity_id: str, as_of_date: datetime, depth_days: int) -> dict:
|
179
165
|
|
180
166
|
Logger.debug(f"Getting last statistic for {entity_id}...")
|
181
167
|
|
@@ -201,9 +187,7 @@ class HomeAssistantWS:
|
|
201
187
|
statistics: list[dict],
|
202
188
|
):
|
203
189
|
|
204
|
-
Logger.debug(
|
205
|
-
f"Importing {len(statistics)} statistics for {entity_id} from {source}..."
|
206
|
-
)
|
190
|
+
Logger.debug(f"Importing {len(statistics)} statistics for {entity_id} from {source}...")
|
207
191
|
|
208
192
|
if len(statistics) == 0:
|
209
193
|
Logger.debug("No statistics to import")
|
@@ -225,9 +209,7 @@ class HomeAssistantWS:
|
|
225
209
|
|
226
210
|
await self.send_message(import_statistics_message)
|
227
211
|
|
228
|
-
Logger.debug(
|
229
|
-
f"Imported {len(statistics)} statistics for {entity_id} from {source}"
|
230
|
-
)
|
212
|
+
Logger.debug(f"Imported {len(statistics)} statistics for {entity_id} from {source}")
|
231
213
|
|
232
214
|
# ----------------------------------
|
233
215
|
async def clear_statistics(self, entity_ids: list[str]):
|