gazpar2haws 0.3.0b19__py3-none-any.whl → 0.3.0b21__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/date_array.py +27 -6
- gazpar2haws/gazpar.py +34 -10
- gazpar2haws/pricer.py +13 -13
- {gazpar2haws-0.3.0b19.dist-info → gazpar2haws-0.3.0b21.dist-info}/METADATA +1 -1
- {gazpar2haws-0.3.0b19.dist-info → gazpar2haws-0.3.0b21.dist-info}/RECORD +7 -7
- {gazpar2haws-0.3.0b19.dist-info → gazpar2haws-0.3.0b21.dist-info}/LICENSE +0 -0
- {gazpar2haws-0.3.0b19.dist-info → gazpar2haws-0.3.0b21.dist-info}/WHEEL +0 -0
gazpar2haws/date_array.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import datetime as dt
|
4
|
+
from datetime import timedelta
|
4
5
|
from typing import Optional, overload
|
5
6
|
|
6
7
|
import numpy as np
|
@@ -57,7 +58,7 @@ class DateArray(BaseModel): # pylint: disable=too-few-public-methods
|
|
57
58
|
def __getitem__(self, date: dt.date) -> float: ...
|
58
59
|
|
59
60
|
@overload
|
60
|
-
def __getitem__(self, date_slice: slice) ->
|
61
|
+
def __getitem__(self, date_slice: slice) -> DateArray: ...
|
61
62
|
|
62
63
|
def __getitem__(self, key):
|
63
64
|
if self.array is None:
|
@@ -70,8 +71,14 @@ class DateArray(BaseModel): # pylint: disable=too-few-public-methods
|
|
70
71
|
start_date: dt.date = key.start # type: ignore
|
71
72
|
end_date: dt.date = key.stop # type: ignore
|
72
73
|
start_index: int = (start_date - self.start_date).days
|
73
|
-
end_index: int = (end_date - self.start_date).days
|
74
|
-
|
74
|
+
end_index: int = (end_date - self.start_date).days
|
75
|
+
if start_index < 0 or end_index > len(self.array):
|
76
|
+
raise ValueError(
|
77
|
+
f"Date slice [{start_date}:{end_date}] is out of range [{self.start_date}:{self.end_date}]"
|
78
|
+
)
|
79
|
+
return DateArray(
|
80
|
+
start_date=start_date, end_date=end_date + timedelta(-1), array=self.array[start_index:end_index]
|
81
|
+
)
|
75
82
|
raise TypeError("Key must be a date or a slice of dates")
|
76
83
|
|
77
84
|
# ----------------------------------
|
@@ -84,7 +91,10 @@ class DateArray(BaseModel): # pylint: disable=too-few-public-methods
|
|
84
91
|
@overload
|
85
92
|
def __setitem__(self, date_slice: slice, value: float): ...
|
86
93
|
|
87
|
-
|
94
|
+
@overload
|
95
|
+
def __setitem__(self, date_slice: slice, value: DateArray): ...
|
96
|
+
|
97
|
+
def __setitem__(self, key, value):
|
88
98
|
if self.array is None:
|
89
99
|
raise ValueError("Array is not initialized")
|
90
100
|
if isinstance(key, int):
|
@@ -95,8 +105,19 @@ class DateArray(BaseModel): # pylint: disable=too-few-public-methods
|
|
95
105
|
start_date: dt.date = key.start # type: ignore
|
96
106
|
end_date: dt.date = key.stop # type: ignore
|
97
107
|
start_index: int = (start_date - self.start_date).days
|
98
|
-
end_index: int = (end_date - self.start_date).days
|
99
|
-
self.array
|
108
|
+
end_index: int = (end_date - self.start_date).days
|
109
|
+
if start_index < 0 or end_index > len(self.array):
|
110
|
+
raise ValueError(
|
111
|
+
f"Date slice [{start_date}:{end_date}] is out of range [{self.start_date}:{self.end_date}]"
|
112
|
+
)
|
113
|
+
self.start_date = start_date
|
114
|
+
self.end_date = end_date + timedelta(-1)
|
115
|
+
if isinstance(value, float):
|
116
|
+
self.array[start_index:end_index] = value
|
117
|
+
elif isinstance(value, DateArray):
|
118
|
+
self.array[start_index:end_index] = value.array
|
119
|
+
else:
|
120
|
+
raise TypeError("Value must be a float or a DateArray")
|
100
121
|
else:
|
101
122
|
raise TypeError("Key must be a date or a slice of dates")
|
102
123
|
|
gazpar2haws/gazpar.py
CHANGED
@@ -78,7 +78,7 @@ class Gazpar:
|
|
78
78
|
|
79
79
|
# ----------------------------------
|
80
80
|
# Publish Gaspar data to Home Assistant WS
|
81
|
-
async def publish(self):
|
81
|
+
async def publish(self): # pylint: disable=too-many-branches, too-many-statements
|
82
82
|
|
83
83
|
# Volume, energy and cost sensor names.
|
84
84
|
volume_sensor_name = f"sensor.{self._name}_volume"
|
@@ -104,17 +104,32 @@ class Gazpar:
|
|
104
104
|
min(v[0] for v in last_date_and_value_by_sensor.values()) + timedelta(days=1), self._as_of_date
|
105
105
|
)
|
106
106
|
|
107
|
+
# Get all start dates
|
108
|
+
energy_start_date = last_date_and_value_by_sensor[energy_sensor_name][0] + timedelta(days=1)
|
109
|
+
volume_start_date = last_date_and_value_by_sensor[volume_sensor_name][0] + timedelta(days=1)
|
110
|
+
cost_start_date = last_date_and_value_by_sensor[cost_sensor_name][0] + timedelta(days=1)
|
111
|
+
|
112
|
+
Logger.debug(f"Min start date for all sensors: {start_date}")
|
113
|
+
Logger.debug(f"Energy start date: {energy_start_date}")
|
114
|
+
Logger.debug(f"Volume start date: {volume_start_date}")
|
115
|
+
Logger.debug(f"Cost start date: {cost_start_date}")
|
116
|
+
|
107
117
|
# Fetch the data from GrDF and publish it to Home Assistant
|
108
118
|
daily_history = self.fetch_daily_gazpar_history(start_date, self._as_of_date)
|
109
119
|
|
110
120
|
# The end date is the last date of the daily history
|
111
|
-
|
121
|
+
if daily_history is None or len(daily_history) == 0:
|
122
|
+
end_date = start_date
|
123
|
+
else:
|
124
|
+
end_date = datetime.strptime(daily_history[-1][pygazpar.PropertyName.TIME_PERIOD.value], "%d/%m/%Y").date()
|
125
|
+
|
126
|
+
Logger.debug(f"End date: {end_date}")
|
112
127
|
|
113
128
|
# Extract the volume from the daily history
|
114
129
|
volume_array = self.extract_property_from_daily_gazpar_history(
|
115
130
|
daily_history,
|
116
131
|
pygazpar.PropertyName.VOLUME.value,
|
117
|
-
|
132
|
+
volume_start_date,
|
118
133
|
end_date,
|
119
134
|
)
|
120
135
|
|
@@ -122,7 +137,7 @@ class Gazpar:
|
|
122
137
|
energy_array = self.extract_property_from_daily_gazpar_history(
|
123
138
|
daily_history,
|
124
139
|
pygazpar.PropertyName.ENERGY.value,
|
125
|
-
|
140
|
+
min(energy_start_date, cost_start_date),
|
126
141
|
end_date,
|
127
142
|
)
|
128
143
|
|
@@ -137,11 +152,11 @@ class Gazpar:
|
|
137
152
|
else:
|
138
153
|
Logger.info("No volume data to publish")
|
139
154
|
|
140
|
-
if energy_array is not None:
|
155
|
+
if energy_array is not None and energy_start_date <= end_date:
|
141
156
|
await self.publish_date_array(
|
142
157
|
energy_sensor_name,
|
143
158
|
"kWh",
|
144
|
-
energy_array,
|
159
|
+
energy_array[energy_start_date : end_date + timedelta(days=1)],
|
145
160
|
last_date_and_value_by_sensor[energy_sensor_name][1],
|
146
161
|
)
|
147
162
|
else:
|
@@ -156,11 +171,11 @@ class Gazpar:
|
|
156
171
|
pricer = Pricer(self._pricing_config)
|
157
172
|
|
158
173
|
quantities = ConsumptionQuantityArray(
|
159
|
-
start_date=
|
174
|
+
start_date=cost_start_date,
|
160
175
|
end_date=end_date,
|
161
176
|
value_unit=QuantityUnit.KWH,
|
162
177
|
base_unit=TimeUnit.DAY,
|
163
|
-
value_array=energy_array,
|
178
|
+
value_array=energy_array[cost_start_date : end_date + timedelta(days=1)],
|
164
179
|
)
|
165
180
|
|
166
181
|
cost_array = pricer.compute(quantities, PriceUnit.EURO)
|
@@ -169,11 +184,12 @@ class Gazpar:
|
|
169
184
|
|
170
185
|
# Publish the cost to Home Assistant
|
171
186
|
if cost_array is not None:
|
187
|
+
cost_initial_value = last_date_and_value_by_sensor[cost_sensor_name][1]
|
172
188
|
await self.publish_date_array(
|
173
189
|
cost_sensor_name,
|
174
190
|
cost_array.value_unit,
|
175
191
|
cost_array.value_array,
|
176
|
-
|
192
|
+
cost_initial_value,
|
177
193
|
)
|
178
194
|
else:
|
179
195
|
Logger.info("No cost data to publish")
|
@@ -199,7 +215,15 @@ class Gazpar:
|
|
199
215
|
endDate=end_date,
|
200
216
|
frequencies=[pygazpar.Frequency.DAILY],
|
201
217
|
)
|
202
|
-
|
218
|
+
|
219
|
+
# Filter the daily readings by keeping only dates between start_date and end_date
|
220
|
+
res = []
|
221
|
+
for reading in history[pygazpar.Frequency.DAILY.value]:
|
222
|
+
reading_date = datetime.strptime(reading[pygazpar.PropertyName.TIME_PERIOD.value], "%d/%m/%Y").date()
|
223
|
+
if start_date <= reading_date <= end_date:
|
224
|
+
res.append(reading)
|
225
|
+
|
226
|
+
Logger.debug(f"Fetched {len(res)} daily readings from start date {start_date} to end date {end_date}")
|
203
227
|
except Exception: # pylint: disable=broad-except
|
204
228
|
Logger.warning(f"Error while fetching data from GrDF: {traceback.format_exc()}")
|
205
229
|
res = MeterReadings()
|
gazpar2haws/pricer.py
CHANGED
@@ -315,17 +315,17 @@ class Pricer:
|
|
315
315
|
|
316
316
|
if first_value.start_date > end_date:
|
317
317
|
# Fully before first value period.
|
318
|
-
value_array[start_date:end_date] = first_value.value # type: ignore
|
318
|
+
value_array[start_date : end_date + timedelta(1)] = first_value.value # type: ignore
|
319
319
|
elif last_value.end_date is not None and last_value.end_date < start_date:
|
320
320
|
# Fully after last value period.
|
321
|
-
value_array[start_date:end_date] = last_value.value # type: ignore
|
321
|
+
value_array[start_date : end_date + timedelta(1)] = last_value.value # type: ignore
|
322
322
|
else:
|
323
323
|
if start_date < first_value.start_date:
|
324
324
|
# Partially before first value period.
|
325
|
-
value_array[start_date : first_value.start_date] = first_value.value # type: ignore
|
325
|
+
value_array[start_date : first_value.start_date + timedelta(1)] = first_value.value # type: ignore
|
326
326
|
if last_value.end_date is not None and end_date > last_value.end_date:
|
327
327
|
# Partially after last value period.
|
328
|
-
value_array[last_value.end_date : end_date] = last_value.value # type: ignore
|
328
|
+
value_array[last_value.end_date : end_date + timedelta(1)] = last_value.value # type: ignore
|
329
329
|
# Inside value periods.
|
330
330
|
for value in in_values:
|
331
331
|
latest_start = max(value.start_date, start_date)
|
@@ -371,32 +371,32 @@ class Pricer:
|
|
371
371
|
if first_value.start_date > end_date:
|
372
372
|
# Fully before first value period.
|
373
373
|
if vat_rate_array_by_id is not None and first_value.vat_id in vat_rate_array_by_id:
|
374
|
-
vat_value = vat_rate_array_by_id[first_value.vat_id].value_array[start_date:end_date] # type: ignore
|
374
|
+
vat_value = vat_rate_array_by_id[first_value.vat_id].value_array[start_date : end_date + timedelta(1)] # type: ignore
|
375
375
|
else:
|
376
376
|
vat_value = 0.0
|
377
|
-
value_array[start_date:end_date] =
|
377
|
+
value_array[start_date : end_date + timedelta(1)] = (vat_value + 1) * first_value.value # type: ignore
|
378
378
|
elif last_value.end_date is not None and last_value.end_date < start_date:
|
379
379
|
# Fully after last value period.
|
380
380
|
if vat_rate_array_by_id is not None and last_value.vat_id in vat_rate_array_by_id:
|
381
|
-
vat_value = vat_rate_array_by_id[last_value.vat_id].value_array[start_date:end_date] # type: ignore
|
381
|
+
vat_value = vat_rate_array_by_id[last_value.vat_id].value_array[start_date : end_date + timedelta(1)] # type: ignore
|
382
382
|
else:
|
383
383
|
vat_value = 0.0
|
384
|
-
value_array[start_date:end_date] =
|
384
|
+
value_array[start_date : end_date + timedelta(1)] = (vat_value + 1) * last_value.value # type: ignore
|
385
385
|
else:
|
386
386
|
if start_date < first_value.start_date:
|
387
387
|
# Partially before first value period.
|
388
388
|
if vat_rate_array_by_id is not None and first_value.vat_id in vat_rate_array_by_id:
|
389
|
-
vat_value = vat_rate_array_by_id[first_value.vat_id].value_array[start_date : first_value.start_date] # type: ignore
|
389
|
+
vat_value = vat_rate_array_by_id[first_value.vat_id].value_array[start_date : first_value.start_date + timedelta(1)] # type: ignore
|
390
390
|
else:
|
391
391
|
vat_value = 0.0
|
392
|
-
value_array[start_date : first_value.start_date] =
|
392
|
+
value_array[start_date : first_value.start_date + timedelta(1)] = (vat_value + 1) * first_value.value # type: ignore
|
393
393
|
if last_value.end_date is not None and end_date > last_value.end_date:
|
394
394
|
# Partially after last value period.
|
395
395
|
if vat_rate_array_by_id is not None and last_value.vat_id in vat_rate_array_by_id:
|
396
|
-
vat_value = vat_rate_array_by_id[last_value.vat_id].value_array[last_value.end_date : end_date] # type: ignore
|
396
|
+
vat_value = vat_rate_array_by_id[last_value.vat_id].value_array[last_value.end_date : end_date + timedelta(1)] # type: ignore
|
397
397
|
else:
|
398
398
|
vat_value = 0.0
|
399
|
-
value_array[last_value.end_date : end_date] =
|
399
|
+
value_array[last_value.end_date : end_date + timedelta(1)] = (vat_value + 1) * last_value.value # type: ignore
|
400
400
|
# Inside value periods.
|
401
401
|
for value in in_values:
|
402
402
|
latest_start = max(value.start_date, start_date)
|
@@ -407,7 +407,7 @@ class Pricer:
|
|
407
407
|
vat_value = vat_rate_array_by_id[value.vat_id].value_array[current_date] # type: ignore
|
408
408
|
else:
|
409
409
|
vat_value = 0.0
|
410
|
-
value_array[current_date] =
|
410
|
+
value_array[current_date] = (vat_value + 1) * value.value # type: ignore
|
411
411
|
current_date += timedelta(days=1)
|
412
412
|
|
413
413
|
# ----------------------------------
|
@@ -3,13 +3,13 @@ gazpar2haws/__main__.py,sha256=wD28dqa3weiz5cj9--hgLLN7FnW0eeA9ZmlIvriKXNk,3125
|
|
3
3
|
gazpar2haws/bridge.py,sha256=VEl22xt2Szgk_FVrxSvZNxp3T5Q2JXc9ulfrunHHkmo,3685
|
4
4
|
gazpar2haws/config_utils.py,sha256=yT2G-naMA2Vst6bQdm1bD2oVsPTU3Q_RuukCs-dZ6Ak,2280
|
5
5
|
gazpar2haws/configuration.py,sha256=24q8FUBMS1vpqU6RYAv5Au179HbiBk1CZIEMiBGuXq0,722
|
6
|
-
gazpar2haws/date_array.py,sha256=
|
7
|
-
gazpar2haws/gazpar.py,sha256=
|
6
|
+
gazpar2haws/date_array.py,sha256=RxvK_ZQxaeYCg4kg088_lMh5b1WDBa4wXPPqSIUDS2E,9779
|
7
|
+
gazpar2haws/gazpar.py,sha256=n3KugBo31_0nwql-QAiU9BHdDyIks139E3ENblgVNME,14224
|
8
8
|
gazpar2haws/haws.py,sha256=1ELdompdACNf5XkpjCN6Bdiw7stPfzar3x8OjoBmhxQ,7969
|
9
9
|
gazpar2haws/model.py,sha256=-1yhLNNcEvEtW67GMVLZ4lcXw6Lk75kWvrdjoVgjKCw,7055
|
10
|
-
gazpar2haws/pricer.py,sha256=
|
10
|
+
gazpar2haws/pricer.py,sha256=PcjRTBhOECzJCJ0mrIgS5agGf8N3O2u0mLVky-cbvhk,22124
|
11
11
|
gazpar2haws/version.py,sha256=9Iq5Jm63Ev7QquCjhDqa9_KAgHdKl9FJHynq8M6JNrY,83
|
12
|
-
gazpar2haws-0.3.
|
13
|
-
gazpar2haws-0.3.
|
14
|
-
gazpar2haws-0.3.
|
15
|
-
gazpar2haws-0.3.
|
12
|
+
gazpar2haws-0.3.0b21.dist-info/LICENSE,sha256=ajApZPyhVx8AU9wN7DXeRGhoWFqY2ylBZUa5GRhTmok,1073
|
13
|
+
gazpar2haws-0.3.0b21.dist-info/METADATA,sha256=sZuaDthuV50-HpNF4ghSIspSoRw80R9HnsikXbGjQNA,17406
|
14
|
+
gazpar2haws-0.3.0b21.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
|
15
|
+
gazpar2haws-0.3.0b21.dist-info/RECORD,,
|
File without changes
|
File without changes
|