gazpar2haws 0.3.0b20__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 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) -> np.ndarray: ...
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 + 1
74
- return self.array[start_index:end_index]
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
- def __setitem__(self, key, value: float):
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 + 1
99
- self.array[start_index:end_index] = value
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,6 +104,16 @@ 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
 
@@ -113,11 +123,13 @@ class Gazpar:
113
123
  else:
114
124
  end_date = datetime.strptime(daily_history[-1][pygazpar.PropertyName.TIME_PERIOD.value], "%d/%m/%Y").date()
115
125
 
126
+ Logger.debug(f"End date: {end_date}")
127
+
116
128
  # Extract the volume from the daily history
117
129
  volume_array = self.extract_property_from_daily_gazpar_history(
118
130
  daily_history,
119
131
  pygazpar.PropertyName.VOLUME.value,
120
- last_date_and_value_by_sensor[volume_sensor_name][0],
132
+ volume_start_date,
121
133
  end_date,
122
134
  )
123
135
 
@@ -125,7 +137,7 @@ class Gazpar:
125
137
  energy_array = self.extract_property_from_daily_gazpar_history(
126
138
  daily_history,
127
139
  pygazpar.PropertyName.ENERGY.value,
128
- last_date_and_value_by_sensor[energy_sensor_name][0],
140
+ min(energy_start_date, cost_start_date),
129
141
  end_date,
130
142
  )
131
143
 
@@ -140,11 +152,11 @@ class Gazpar:
140
152
  else:
141
153
  Logger.info("No volume data to publish")
142
154
 
143
- if energy_array is not None:
155
+ if energy_array is not None and energy_start_date <= end_date:
144
156
  await self.publish_date_array(
145
157
  energy_sensor_name,
146
158
  "kWh",
147
- energy_array,
159
+ energy_array[energy_start_date : end_date + timedelta(days=1)],
148
160
  last_date_and_value_by_sensor[energy_sensor_name][1],
149
161
  )
150
162
  else:
@@ -159,11 +171,11 @@ class Gazpar:
159
171
  pricer = Pricer(self._pricing_config)
160
172
 
161
173
  quantities = ConsumptionQuantityArray(
162
- start_date=last_date_and_value_by_sensor[energy_sensor_name][0],
174
+ start_date=cost_start_date,
163
175
  end_date=end_date,
164
176
  value_unit=QuantityUnit.KWH,
165
177
  base_unit=TimeUnit.DAY,
166
- value_array=energy_array,
178
+ value_array=energy_array[cost_start_date : end_date + timedelta(days=1)],
167
179
  )
168
180
 
169
181
  cost_array = pricer.compute(quantities, PriceUnit.EURO)
@@ -172,11 +184,12 @@ class Gazpar:
172
184
 
173
185
  # Publish the cost to Home Assistant
174
186
  if cost_array is not None:
187
+ cost_initial_value = last_date_and_value_by_sensor[cost_sensor_name][1]
175
188
  await self.publish_date_array(
176
189
  cost_sensor_name,
177
190
  cost_array.value_unit,
178
191
  cost_array.value_array,
179
- last_date_and_value_by_sensor[cost_sensor_name][1],
192
+ cost_initial_value,
180
193
  )
181
194
  else:
182
195
  Logger.info("No cost data to publish")
@@ -202,7 +215,15 @@ class Gazpar:
202
215
  endDate=end_date,
203
216
  frequencies=[pygazpar.Frequency.DAILY],
204
217
  )
205
- res = history[pygazpar.Frequency.DAILY.value]
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}")
206
227
  except Exception: # pylint: disable=broad-except
207
228
  Logger.warning(f"Error while fetching data from GrDF: {traceback.format_exc()}")
208
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] = first_value.value * (1 + vat_value) # type: ignore
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] = last_value.value * (1 + vat_value) # type: ignore
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] = first_value.value * (1 + vat_value) # type: ignore
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] = last_value.value * (1 + vat_value) # type: ignore
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] = value.value * (1 + vat_value) # type: ignore
410
+ value_array[current_date] = (vat_value + 1) * value.value # type: ignore
411
411
  current_date += timedelta(days=1)
412
412
 
413
413
  # ----------------------------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: gazpar2haws
3
- Version: 0.3.0b20
3
+ Version: 0.3.0b21
4
4
  Summary: Gazpar2HAWS is a gateway that reads data history from the GrDF (French gas provider) meter and send it to Home Assistant using WebSocket interface
5
5
  License: MIT License
6
6
 
@@ -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=XQ8gwTl0w97ADjs6igdMZLxtPPrDWTLQzhhzTDVjC4M,8761
7
- gazpar2haws/gazpar.py,sha256=LtRHPUwu3SovkdkF9usd9nkGZJoXGr-xfpXO7bnlk3s,12951
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=YhMfvAKSxQhE2JGgrkNOpqQZdTWjGZ_bUtNsYA0u2fs,21932
10
+ gazpar2haws/pricer.py,sha256=PcjRTBhOECzJCJ0mrIgS5agGf8N3O2u0mLVky-cbvhk,22124
11
11
  gazpar2haws/version.py,sha256=9Iq5Jm63Ev7QquCjhDqa9_KAgHdKl9FJHynq8M6JNrY,83
12
- gazpar2haws-0.3.0b20.dist-info/LICENSE,sha256=ajApZPyhVx8AU9wN7DXeRGhoWFqY2ylBZUa5GRhTmok,1073
13
- gazpar2haws-0.3.0b20.dist-info/METADATA,sha256=NwGLFtS_fTZRUkXnurajcpYO7-ZVAASvgbrH07Ax4wM,17406
14
- gazpar2haws-0.3.0b20.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
15
- gazpar2haws-0.3.0b20.dist-info/RECORD,,
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,,