myelectricaldatapy 2.2.8__tar.gz → 2.2.9__tar.gz

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.
Files changed (47) hide show
  1. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/PKG-INFO +1 -1
  2. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy/__init__.py +3 -0
  3. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy/analytics.py +7 -5
  4. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy/api.py +5 -4
  5. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy/mypdl.py +14 -4
  6. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy/tz.py +23 -2
  7. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy.egg-info/PKG-INFO +1 -1
  8. myelectricaldatapy-2.2.9/myelectricaldatapy.egg-info/scm_version.json +8 -0
  9. myelectricaldatapy-2.2.8/myelectricaldatapy.egg-info/scm_version.json +0 -8
  10. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/.devcontainer/devcontainer-lock.json +0 -0
  11. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/.devcontainer/devcontainer.json +0 -0
  12. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/.github/dependabot.yml +0 -0
  13. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/.github/workflows/auto-approve.yml +0 -0
  14. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/.github/workflows/python-lint.yml +0 -0
  15. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/.github/workflows/python-publish.yml +0 -0
  16. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/.github/workflows/release.yml +0 -0
  17. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/.gitignore +0 -0
  18. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/.pre-commit-config.yaml +0 -0
  19. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/.vscode/settings.json +0 -0
  20. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/LICENSE +0 -0
  21. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/README.md +0 -0
  22. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/_secrets.yaml +0 -0
  23. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/example.py +0 -0
  24. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy/auth.py +0 -0
  25. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy/const.py +0 -0
  26. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy/exceptions.py +0 -0
  27. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy/py.typed +0 -0
  28. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy.egg-info/SOURCES.txt +0 -0
  29. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy.egg-info/dependency_links.txt +0 -0
  30. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy.egg-info/requires.txt +0 -0
  31. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy.egg-info/scm_file_list.json +0 -0
  32. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/myelectricaldatapy.egg-info/top_level.txt +0 -0
  33. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/pyproject.toml +0 -0
  34. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/setup.cfg +0 -0
  35. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/__init__.py +0 -0
  36. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/conftest.py +0 -0
  37. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/consts.py +0 -0
  38. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/fixtures/access.json +0 -0
  39. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/fixtures/address.json +0 -0
  40. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/fixtures/contract.json +0 -0
  41. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/fixtures/daily.json +0 -0
  42. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/fixtures/detail.json +0 -0
  43. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/fixtures/ecowatt.json +0 -0
  44. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/fixtures/invalid_access.json +0 -0
  45. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/fixtures/tempo.json +0 -0
  46. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/test_analytics.py +0 -0
  47. {myelectricaldatapy-2.2.8 → myelectricaldatapy-2.2.9}/tests/test_load_data.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: myelectricaldatapy
3
- Version: 2.2.8
3
+ Version: 2.2.9
4
4
  Summary: Fetch Linky data from myelectricaldata.fr
5
5
  Author-email: Cyr-ius <cyr-ius@ipocus.net>
6
6
  License-Expression: GPL-3.0-or-later
@@ -8,6 +8,7 @@ from .exceptions import (
8
8
  TimeoutExceededError,
9
9
  )
10
10
  from .mypdl import EnedisByPDL
11
+ from .tz import get_local_timezone, set_local_timezone
11
12
 
12
13
  __all__ = [
13
14
  "Enedis",
@@ -16,4 +17,6 @@ __all__ = [
16
17
  "HttpRequestError",
17
18
  "LimitReached",
18
19
  "TimeoutExceededError",
20
+ "get_local_timezone",
21
+ "set_local_timezone",
19
22
  ]
@@ -1,23 +1,25 @@
1
1
  """Class for analytics."""
2
2
 
3
- from datetime import datetime as dt, timedelta
3
+ from datetime import datetime as dt, timedelta, tzinfo as _tzinfo
4
4
  import re
5
5
  from typing import Any
6
6
 
7
7
  import pandas as pd
8
8
 
9
9
  from .const import ATTR_OFFPEAK, ATTR_STANDARD, TEMPO_DAYS
10
- from .tz import LOCAL_TIMEZONE
10
+ from .tz import get_local_timezone
11
11
 
12
12
 
13
13
  class EnedisAnalytics:
14
14
  """Data analytics."""
15
15
 
16
- local_timezone = LOCAL_TIMEZONE
17
-
18
- def __init__(self, data: Any) -> None:
16
+ def __init__(self, data: Any, timezone: _tzinfo | None = None) -> None:
19
17
  """Initialize Dataframe."""
20
18
  self.df = pd.DataFrame(data)
19
+ # Resolved per instance (not at import/class-definition time) so a
20
+ # timezone set later via tz.set_local_timezone(), or passed here
21
+ # explicitly, is honored.
22
+ self.local_timezone = timezone or get_local_timezone()
21
23
 
22
24
  def get_data_analytics(
23
25
  self,
@@ -11,7 +11,7 @@ from aiohttp import ClientSession
11
11
  from .auth import EnedisAuth
12
12
  from .const import DAILY_CONSUM, DAILY_PROD, DETAIL_CONSUM, DETAIL_PROD, TIMEOUT
13
13
  from .exceptions import EnedisException
14
- from .tz import LOCAL_TIMEZONE, as_local, local_now
14
+ from .tz import as_local, get_local_timezone, local_now
15
15
 
16
16
  _LOGGER = logging.getLogger(__name__)
17
17
 
@@ -126,16 +126,17 @@ class Enedis:
126
126
  if await self.async_has_offpeak(pdl) is True:
127
127
  # Off-peak windows are defined in local wall-clock time, so a
128
128
  # start given in another timezone must be converted first.
129
- start_time = as_local(start).astimezone(LOCAL_TIMEZONE).time()
129
+ local_timezone = get_local_timezone()
130
+ start_time = as_local(start).astimezone(local_timezone).time()
130
131
  for range_time in self.offpeaks:
131
132
  starting = (
132
133
  dt.strptime(range_time[0], "%HH%M")
133
- .replace(tzinfo=LOCAL_TIMEZONE)
134
+ .replace(tzinfo=local_timezone)
134
135
  .time()
135
136
  )
136
137
  ending = (
137
138
  dt.strptime(range_time[1], "%HH%M")
138
- .replace(tzinfo=LOCAL_TIMEZONE)
139
+ .replace(tzinfo=local_timezone)
139
140
  .time()
140
141
  )
141
142
  if starting < start_time <= ending:
@@ -1,7 +1,7 @@
1
1
  """Class for my PDL."""
2
2
 
3
3
  from collections.abc import Callable
4
- from datetime import date, datetime as dt, timedelta
4
+ from datetime import date, datetime as dt, timedelta, tzinfo as _tzinfo
5
5
  import logging
6
6
  from typing import Any, Literal
7
7
 
@@ -30,7 +30,7 @@ from .const import (
30
30
  TIMEOUT,
31
31
  )
32
32
  from .exceptions import EnedisException, LimitReached
33
- from .tz import as_local, local_now
33
+ from .tz import as_local, local_now, set_local_timezone
34
34
 
35
35
  _LOGGER = logging.getLogger(__name__)
36
36
 
@@ -84,11 +84,21 @@ class EnedisByPDL:
84
84
  token: str,
85
85
  session: ClientSession | None = None,
86
86
  timeout: int = TIMEOUT,
87
+ timezone: _tzinfo | None = None,
87
88
  ) -> None:
88
- """Initialize."""
89
+ """Initialize.
90
+
91
+ timezone: the timezone to interpret naive datetimes in (e.g. Home
92
+ Assistant's hass.config.time_zone / dt_util.get_default_time_zone()).
93
+ Defaults to the host machine's timezone, which has no reason to
94
+ match the consuming application's configured timezone.
95
+ """
89
96
  session = ClientSession() if session is None else session
90
97
  self._api: Enedis = Enedis(token, session, timeout)
91
98
  self.pdl = pdl
99
+ self._timezone = timezone
100
+ if timezone is not None:
101
+ set_local_timezone(timezone)
92
102
  self._connected: bool = False
93
103
  self._ecowatt_subs: bool = False
94
104
  self._maxpower_subs: bool = False
@@ -173,7 +183,7 @@ class EnedisByPDL:
173
183
  stats = {}
174
184
  for mode, params in self._params.items():
175
185
  data = params.get("data", {})
176
- analytics = EnedisAnalytics(data)
186
+ analytics = EnedisAnalytics(data, timezone=self._timezone)
177
187
  resultat = analytics.get_data_analytics(
178
188
  convertKwh=True,
179
189
  convertUTC=False,
@@ -30,14 +30,35 @@ def _resolve_local_timezone() -> _tzinfo:
30
30
 
31
31
  LOCAL_TIMEZONE = _resolve_local_timezone()
32
32
 
33
+ _override_timezone: _tzinfo | None = None
34
+
35
+
36
+ def get_local_timezone() -> _tzinfo:
37
+ """Return the timezone to use for interpreting naive datetimes.
38
+
39
+ Returns the timezone set via set_local_timezone(), if any, otherwise
40
+ falls back to LOCAL_TIMEZONE (the host machine's /etc/localtime). The
41
+ host's timezone has no reason to match the application embedding this
42
+ library, so a caller such as a Home Assistant integration should call
43
+ set_local_timezone() at startup with its own configured timezone (e.g.
44
+ hass.config.time_zone).
45
+ """
46
+ return _override_timezone or LOCAL_TIMEZONE
47
+
48
+
49
+ def set_local_timezone(tz: _tzinfo) -> None:
50
+ """Override the timezone used to interpret naive datetimes."""
51
+ global _override_timezone
52
+ _override_timezone = tz
53
+
33
54
 
34
55
  def local_now() -> dt:
35
56
  """Return the current time, timezone-aware in the local zone."""
36
- return dt.now(tz=LOCAL_TIMEZONE)
57
+ return dt.now(tz=get_local_timezone())
37
58
 
38
59
 
39
60
  def as_local(value: dt) -> dt:
40
61
  """Attach the local timezone to a naive datetime; pass aware ones through."""
41
62
  if value.tzinfo is None:
42
- return value.replace(tzinfo=LOCAL_TIMEZONE)
63
+ return value.replace(tzinfo=get_local_timezone())
43
64
  return value
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: myelectricaldatapy
3
- Version: 2.2.8
3
+ Version: 2.2.9
4
4
  Summary: Fetch Linky data from myelectricaldata.fr
5
5
  Author-email: Cyr-ius <cyr-ius@ipocus.net>
6
6
  License-Expression: GPL-3.0-or-later
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "2.2.9",
3
+ "distance": 0,
4
+ "node": "gd64089c5c53ebbcc9f4ffe8a04ed5c1abc20a527",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-08-24"
8
+ }
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "2.2.8",
3
- "distance": 0,
4
- "node": "gf2934154a6b07523adc3168370b85b03214b6087",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-08-23"
8
- }