dimplex-controller 0.11.0__tar.gz → 0.12.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dimplex-controller
3
- Version: 0.11.0
3
+ Version: 0.12.0
4
4
  Summary: Python client for Dimplex heating controllers (GDHV IoT)
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -30,8 +30,9 @@ Description-Content-Type: text/markdown
30
30
  [![PyPI version](https://img.shields.io/pypi/v/dimplex-controller.svg)](https://pypi.org/project/dimplex-controller/)
31
31
  [![Python versions](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
32
32
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
33
- [![CI Tests](https://github.com/KRoperUK/dimplex-controller-py/actions/workflows/tests.yml/badge.svg)](https://github.com/KRoperUK/dimplex-controller-py/actions)
33
+ [![CI Tests](https://img.shields.io/github/actions/workflow/status/KRoperUK/dimplex-controller-py/test.yml?branch=main&label=CI)](https://github.com/KRoperUK/dimplex-controller-py/actions/workflows/test.yml)
34
34
  [![Downloads](https://img.shields.io/pypi/dm/dimplex-controller.svg)](https://pypi.org/project/dimplex-controller/)
35
+ [![Buy me a coffee](https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg)](https://buymeacoffee.com/kroperukc)
35
36
 
36
37
  <p align="center">
37
38
  <strong>Async Python client for controlling Glen Dimplex Heating &amp; Ventilation (GDHV) appliances via the Dimplex cloud API.</strong>
@@ -3,8 +3,9 @@
3
3
  [![PyPI version](https://img.shields.io/pypi/v/dimplex-controller.svg)](https://pypi.org/project/dimplex-controller/)
4
4
  [![Python versions](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
- [![CI Tests](https://github.com/KRoperUK/dimplex-controller-py/actions/workflows/tests.yml/badge.svg)](https://github.com/KRoperUK/dimplex-controller-py/actions)
6
+ [![CI Tests](https://img.shields.io/github/actions/workflow/status/KRoperUK/dimplex-controller-py/test.yml?branch=main&label=CI)](https://github.com/KRoperUK/dimplex-controller-py/actions/workflows/test.yml)
7
7
  [![Downloads](https://img.shields.io/pypi/dm/dimplex-controller.svg)](https://pypi.org/project/dimplex-controller/)
8
+ [![Buy me a coffee](https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg)](https://buymeacoffee.com/kroperukc)
8
9
 
9
10
  <p align="center">
10
11
  <strong>Async Python client for controlling Glen Dimplex Heating &amp; Ventilation (GDHV) appliances via the Dimplex cloud API.</strong>
@@ -11,7 +11,7 @@ successful poll, not an error — use ``get_appliance_overview_map`` if you
11
11
  need a stable id → status mapping.
12
12
  """
13
13
 
14
- from .auth import TokenBundle
14
+ from .auth import TokenBundle, TokenListener
15
15
  from .capabilities import ApplianceCapabilities, capabilities_for
16
16
  from .client import DimplexControl
17
17
  from .exceptions import (
@@ -50,6 +50,7 @@ from .telemetry import (
50
50
  __all__ = [
51
51
  "DimplexControl",
52
52
  "TokenBundle",
53
+ "TokenListener",
53
54
  "ApplianceCapabilities",
54
55
  "capabilities_for",
55
56
  "Hub",
@@ -9,7 +9,7 @@ from typing import Any
9
9
 
10
10
  import aiohttp
11
11
 
12
- from .auth import AuthManager, TokenBundle
12
+ from .auth import AuthManager, TokenBundle, TokenListener
13
13
  from .capabilities import ApplianceCapabilities, capabilities_for
14
14
  from .const import (
15
15
  BASE_URL,
@@ -97,6 +97,7 @@ class DimplexControl:
97
97
  retry_max_delay: float = DEFAULT_RETRY_MAX_DELAY,
98
98
  retry_non_idempotent: bool = False,
99
99
  timeout: float | aiohttp.ClientTimeout | None = DEFAULT_TIMEOUT,
100
+ on_token_update: TokenListener | None = None,
100
101
  ):
101
102
  """Initialize the client.
102
103
 
@@ -119,6 +120,11 @@ class DimplexControl:
119
120
  for fine-grained control, or ``None`` to fall back to aiohttp defaults.
120
121
  A timed-out request is surfaced as :class:`DimplexConnectionError` and,
121
122
  for retryable methods, retried like any other connection error.
123
+
124
+ ``on_token_update`` is an optional callback (sync or async) invoked with
125
+ a :class:`TokenBundle` whenever tokens are refreshed or exchanged. Use
126
+ it to persist tokens reactively (e.g. write to a config-entry store)
127
+ rather than polling :meth:`export_tokens` after every request.
122
128
  """
123
129
  if token_bundle is not None:
124
130
  token_data: dict[str, Any] | TokenBundle = token_bundle
@@ -133,7 +139,7 @@ class DimplexControl:
133
139
 
134
140
  self._session = session
135
141
  self._timeout = _coerce_timeout(timeout)
136
- self.auth = AuthManager(session, token_data, timeout=self._timeout)
142
+ self.auth = AuthManager(session, token_data, timeout=self._timeout, on_token_update=on_token_update)
137
143
  self._max_retries = max(0, int(max_retries))
138
144
  self._retry_base_delay = float(retry_base_delay)
139
145
  self._retry_max_delay = float(retry_max_delay)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "dimplex-controller"
3
- version = "0.11.0"
3
+ version = "0.12.0"
4
4
  description = "Python client for Dimplex heating controllers (GDHV IoT)"
5
5
  authors = ["Kieran Roper"]
6
6
  license = "MIT"