e-data 2.0.1.dev131__py3-none-any.whl → 2.0.1.dev132__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: e-data
3
- Version: 2.0.1.dev131
3
+ Version: 2.0.1.dev132
4
4
  Summary: Python library for managing spanish energy data from various web providers
5
5
  Author-email: VMG <vmayorg@outlook.es>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -1,4 +1,4 @@
1
- e_data-2.0.1.dev131.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
1
+ e_data-2.0.1.dev132.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
2
2
  edata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  edata/cli.py,sha256=0pmlaaXPVfbxPVHMovsuK9qf8PGXl38AV3gtIsk95O4,4010
4
4
  edata/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -15,18 +15,18 @@ edata/models/bill.py,sha256=-qZ4l9f8BnPFlykFRoNYnmRe6-ELWmuNh6usks_k4X0,2674
15
15
  edata/models/data.py,sha256=O1aj0H_G92mnJjm6mYhC8fnl8ZOoatGiokRf8b7ziD8,2388
16
16
  edata/models/supply.py,sha256=qM0Q22-7PfBN93-Tu3ljAE58p5gfob0YWw-o5FccjrI,878
17
17
  edata/providers/__init__.py,sha256=5xaRKPttYM6EpVE1I_vhUAF25L9pEM_qK_5Ix6xnQe0,104
18
- edata/providers/datadis.py,sha256=a084ArY83ncvrMQvMSD2BY1rHlhp42dwJJkU8avmleo,20137
18
+ edata/providers/datadis.py,sha256=CUodqOQUBIvS9OyY1YREoYnfvtYUoz3cJp1RxrNvY-M,20582
19
19
  edata/providers/redata.py,sha256=uvxO2TTtSNSfPRWHZifLjbaP7zAr6O7CZ1oRQFNbIhQ,3122
20
20
  edata/services/bill_service.py,sha256=vukgeQAN0fMjAkyI9cqPqQ4wSRvPdOaswfSR1KheIYc,14947
21
21
  edata/services/data_service.py,sha256=tgLjPPPobKSc5txbkpa8mQspcFwxA8zevlRFUC56YPQ,17238
22
22
  edata/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
23
  edata/tests/test_completion.py,sha256=-iyVt-juU3U1HqMuLUJXJthil2-n_4ddWiJq2GwnXTo,3551
24
- edata/tests/test_datadis_connector.py,sha256=O3mjI5uIOgFz3PzQsApcG6J2yXd8rlEtj8By-9dsDbg,9270
24
+ edata/tests/test_datadis_connector.py,sha256=cJmQP9_yxxwIfQf9h5IJhUsS2itvkPwSeYuvem_pFzI,11332
25
25
  edata/tests/test_incremental.py,sha256=dn1LRgjBi2HuNYELPKDVdZQlS01hk4lsP9L-vyvtEHo,3479
26
26
  edata/tests/test_redata_connector.py,sha256=SBvxsma5t-qvz2drxNisNM2P1STTurqEs1TSDgwaPJ8,508
27
27
  edata/tests/test_services.py,sha256=BMw-MYXs2L_c1Sg_v4TwAZGOJnx2BoWH8U50M05-ZC8,6816
28
28
  edata/tests/test_utils.py,sha256=h6yBzT7j3eA42zbXJ-AK9lXcZkjCMf16wnob1oqGvUE,2307
29
- e_data-2.0.1.dev131.dist-info/METADATA,sha256=IGNLDaNDJ_S4zqVw0IIoDuIaCp4TrQqtBtKek7NNu08,48084
30
- e_data-2.0.1.dev131.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
31
- e_data-2.0.1.dev131.dist-info/top_level.txt,sha256=Ez-fReWtUVTMcFuH0dzCnoKIgMBHgjLaBuba8QiKC7g,6
32
- e_data-2.0.1.dev131.dist-info/RECORD,,
29
+ e_data-2.0.1.dev132.dist-info/METADATA,sha256=FdrpigzLiKDQ0UtvPOp9BNvOAPhjA9R1OqqX3qBqfG0,48084
30
+ e_data-2.0.1.dev132.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
31
+ e_data-2.0.1.dev132.dist-info/top_level.txt,sha256=Ez-fReWtUVTMcFuH0dzCnoKIgMBHgjLaBuba8QiKC7g,6
32
+ e_data-2.0.1.dev132.dist-info/RECORD,,
@@ -403,10 +403,17 @@ class DatadisConnector:
403
403
  for i in response.get("timeCurve", []):
404
404
  if "consumptionKWh" in i:
405
405
  if all(k in i for k in GET_CONSUMPTION_DATA_MANDATORY_FIELDS):
406
- hour = str(int(i["time"].split(":")[0]) - 1)
406
+ raw_hour = int(i["time"].split(":")[0])
407
+ # Datadis delivers hours 1..24 (end-of-interval). A sporadic
408
+ # i-DE glitch emits an extra "00:00" row on a day already
409
+ # carrying its full 24 hours, so drop it -- 01:00..24:00
410
+ # already covers the day -- instead of remapping onto 23:00
411
+ # and overlapping that day's 24:00 slot.
412
+ if raw_hour == 0:
413
+ continue
407
414
  date_as_dt = datetime.strptime(
408
- f"{i['date']} {hour.zfill(2)}:00", "%Y/%m/%d %H:%M"
409
- )
415
+ i["date"], "%Y/%m/%d"
416
+ ) + timedelta(hours=raw_hour - 1)
410
417
  if not (start_date <= date_as_dt <= end_date):
411
418
  continue # skip element if dt is out of range
412
419
 
@@ -56,6 +56,34 @@ CONSUMPTIONS_RESPONSE = {
56
56
  ]
57
57
  }
58
58
 
59
+ CONSUMPTIONS_RESPONSE_WITH_ZERO_HOUR = {
60
+ "timeCurve": [
61
+ {
62
+ "date": "2022/10/22",
63
+ "time": "01:00",
64
+ "consumptionKWh": 0.203,
65
+ "surplusEnergyKWh": 0,
66
+ "obtainMethod": "Real",
67
+ },
68
+ {
69
+ "date": "2022/10/22",
70
+ "time": "02:00",
71
+ "consumptionKWh": 0.163,
72
+ "surplusEnergyKWh": 0,
73
+ "obtainMethod": "Real",
74
+ },
75
+ # Sporadic i-DE glitch: an extra "00:00" row on a day that already
76
+ # carries its full 24 hours. Must be dropped, not remapped to 23:00.
77
+ {
78
+ "date": "2022/10/22",
79
+ "time": "00:00",
80
+ "consumptionKWh": 0.999,
81
+ "surplusEnergyKWh": 0,
82
+ "obtainMethod": "Real",
83
+ },
84
+ ]
85
+ }
86
+
59
87
  MAXIMETER_RESPONSE = {
60
88
  "maxPower": [
61
89
  {
@@ -132,6 +160,40 @@ def test_get_consumption_data(mock_token, mock_get, snapshot):
132
160
  )
133
161
 
134
162
 
163
+ @patch("aiohttp.ClientSession.get")
164
+ @patch.object(
165
+ DatadisConnector, "_async_get_token", new_callable=AsyncMock, return_value=True
166
+ )
167
+ def test_get_consumption_data_skips_zero_hour(mock_token, mock_get):
168
+ """A stray "00:00" row is dropped, not remapped, and never aborts the fetch."""
169
+ mock_response = MagicMock()
170
+ mock_response.status = 200
171
+ mock_response.text = AsyncMock(return_value="text")
172
+ mock_response.json = AsyncMock(
173
+ return_value=CONSUMPTIONS_RESPONSE_WITH_ZERO_HOUR
174
+ )
175
+ mock_get.return_value.__aenter__.return_value = mock_response
176
+ connector = DatadisConnector(MOCK_USERNAME, MOCK_PASSWORD)
177
+
178
+ # Range spans the previous day, so a remapped "00:00" -> 2022/10/21 23:00
179
+ # would fall inside it; its absence proves the explicit skip, not the filter.
180
+ result = connector.get_consumption_data(
181
+ "ESXXXXXXXXXXXXXXXXTEST",
182
+ "2",
183
+ datetime.datetime(2022, 10, 21, 0, 0, 0),
184
+ datetime.datetime(2022, 10, 22, 23, 59, 59),
185
+ "0",
186
+ 5,
187
+ )
188
+
189
+ datetimes = [x.datetime for x in result]
190
+ assert datetimes == [
191
+ datetime.datetime(2022, 10, 22, 0, 0),
192
+ datetime.datetime(2022, 10, 22, 1, 0),
193
+ ]
194
+ assert datetime.datetime(2022, 10, 21, 23, 0) not in datetimes
195
+
196
+
135
197
  @patch("aiohttp.ClientSession.get")
136
198
  @patch.object(
137
199
  DatadisConnector, "_async_get_token", new_callable=AsyncMock, return_value=True