python-hotspring 1.0.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.
- python_hotspring-1.0.0/LICENSE +21 -0
- python_hotspring-1.0.0/PKG-INFO +208 -0
- python_hotspring-1.0.0/README.md +174 -0
- python_hotspring-1.0.0/pyproject.toml +176 -0
- python_hotspring-1.0.0/src/hotspring/__init__.py +67 -0
- python_hotspring-1.0.0/src/hotspring/const.py +237 -0
- python_hotspring-1.0.0/src/hotspring/exceptions.py +28 -0
- python_hotspring-1.0.0/src/hotspring/hotspring.py +487 -0
- python_hotspring-1.0.0/src/hotspring/models.py +762 -0
- python_hotspring-1.0.0/src/hotspring/py.typed +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 Christophe Gagnier
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-hotspring
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Asynchronous Python client for Hot Spring Connected Spa Kit 2.
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: hotspring,spa,hot-tub,home-assistant,iq2020
|
|
8
|
+
Author: Christophe Gagnier
|
|
9
|
+
Author-email: christopheextensions@gmail.com
|
|
10
|
+
Maintainer: Christophe Gagnier
|
|
11
|
+
Maintainer-email: christopheextensions@gmail.com
|
|
12
|
+
Requires-Python: >=3.12,<4.0
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Framework :: AsyncIO
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Natural Language :: English
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Requires-Dist: aiohttp (>=3.0.0)
|
|
24
|
+
Requires-Dist: awesomeversion (>=22.1.0)
|
|
25
|
+
Requires-Dist: backoff (>=2.2.0)
|
|
26
|
+
Requires-Dist: yarl (>=1.6.0)
|
|
27
|
+
Project-URL: Bug Tracker, https://github.com/Moustachauve/python-hotspring/issues
|
|
28
|
+
Project-URL: Changelog, https://github.com/Moustachauve/python-hotspring/releases
|
|
29
|
+
Project-URL: Documentation, https://github.com/Moustachauve/python-hotspring
|
|
30
|
+
Project-URL: Homepage, https://github.com/Moustachauve/python-hotspring
|
|
31
|
+
Project-URL: Repository, https://github.com/Moustachauve/python-hotspring
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
[![GitHub Release][releases-shield]][releases]
|
|
35
|
+
[![Python Versions][python-versions-shield]][pypi]
|
|
36
|
+
![Project Stage][project-stage-shield]
|
|
37
|
+
![Project Maintenance][maintenance-shield]
|
|
38
|
+
[![License][license-shield]](LICENSE)
|
|
39
|
+
|
|
40
|
+
[![Build Status][build-shield]][build]
|
|
41
|
+
[![Code Coverage][codecov-shield]][codecov]
|
|
42
|
+
|
|
43
|
+
Asynchronous Python client for Hot Spring Connected Spa Kit 2.
|
|
44
|
+
|
|
45
|
+
> [!WARNING]
|
|
46
|
+
> This library is currently in heavy development. Not all features might work
|
|
47
|
+
> perfectly, and some features may not be fully tested as they depend on the
|
|
48
|
+
> physical hardware available for testing.
|
|
49
|
+
|
|
50
|
+
## About
|
|
51
|
+
|
|
52
|
+
This package allows you to control and monitor a Hot Spring spa equipped with the
|
|
53
|
+
[Connected Spa Kit 2](https://www.hotspring.com/) programmatically via its local
|
|
54
|
+
HTTP API. It communicates with the Home Network Adapter (HNA), which bridges your
|
|
55
|
+
home network to the spa's control board over LoRA radio.
|
|
56
|
+
|
|
57
|
+
It is primarily designed to be used as the communication layer for an official
|
|
58
|
+
[Home Assistant](https://www.home-assistant.io/) integration.
|
|
59
|
+
|
|
60
|
+
### Supported Features
|
|
61
|
+
|
|
62
|
+
- **Temperature monitoring & control** — Read current/target water temperature,
|
|
63
|
+
set target temperature, change heating modes
|
|
64
|
+
- **Jets & blower** — Control jet speeds (off, low, high) across all jet pumps
|
|
65
|
+
- **Multi-zone lighting** — Set colors and brightness for up to 4 light zones
|
|
66
|
+
plus the logo light
|
|
67
|
+
- **Water care** — Monitor FreshWater IQ salt system metrics (pH, chlorine,
|
|
68
|
+
ORP, sensor life)
|
|
69
|
+
- **Diagnostics** — Read voltage, power consumption, and failure states
|
|
70
|
+
- **Connection monitoring** — Check LoRA bridge and cloud connectivity status
|
|
71
|
+
- **Energy saving schedules** — View configured energy saving time windows
|
|
72
|
+
- **Clean cycle** — Start or stop the 10-minute clean cycle
|
|
73
|
+
|
|
74
|
+
### Compatible Spas
|
|
75
|
+
|
|
76
|
+
This library works with any Hot Spring, Caldera, or Freeflow spa that supports
|
|
77
|
+
the **Connected Spa Kit 2** (compatible with spas from 2014 onwards that use
|
|
78
|
+
the IQ2020/Eagle control board).
|
|
79
|
+
|
|
80
|
+
> [!NOTE]
|
|
81
|
+
> This library has been primarily tested on a **Hotspring Hot Spot Relay 2025**.
|
|
82
|
+
> Compatibility with other specific models and configurations may vary.
|
|
83
|
+
|
|
84
|
+
## Installation
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pip install python-hotspring
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Usage
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
import asyncio
|
|
94
|
+
|
|
95
|
+
from hotspring import HotSpring
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
async def main() -> None:
|
|
99
|
+
"""Show example of controlling your Hot Spring spa."""
|
|
100
|
+
async with HotSpring("192.168.1.100") as spa_client:
|
|
101
|
+
# Get full spa status
|
|
102
|
+
spa = await spa_client.update()
|
|
103
|
+
print(f"Water temperature: {spa.heater.current_temperature}°F")
|
|
104
|
+
print(f"Heater: {'on' if spa.heater.is_on else 'off'}")
|
|
105
|
+
print(f"Heating mode: {spa.heater.heating_mode.name}")
|
|
106
|
+
|
|
107
|
+
# Control the spa
|
|
108
|
+
await spa_client.set_temperature(102)
|
|
109
|
+
await spa_client.set_jet(1, "highSpeed")
|
|
110
|
+
await spa_client.set_light_color(1, "Blue")
|
|
111
|
+
await spa_client.set_clean_cycle(enabled=True)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
if __name__ == "__main__":
|
|
115
|
+
asyncio.run(main())
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Demos
|
|
119
|
+
|
|
120
|
+
Several demonstration scripts are available in the [demo/](demo/README.md) directory to help you get started with the library and verify connectivity with your spa.
|
|
121
|
+
|
|
122
|
+
## Architecture
|
|
123
|
+
|
|
124
|
+
The Hot Spring Connected Spa Kit 2 uses a two-part system:
|
|
125
|
+
|
|
126
|
+
- **HNA (Home Network Adapter)** — Located inside the home, connects to
|
|
127
|
+
WiFi/Internet and runs the local HTTP API that this library communicates with
|
|
128
|
+
- **SNA (Spa Network Adapter)** — Located inside the spa, wired to the IQ2020
|
|
129
|
+
control board via RS485, communicates with the HNA via LoRA radio
|
|
130
|
+
|
|
131
|
+
All API calls go through the HNA, which relays commands to the spa over LoRA.
|
|
132
|
+
Commands typically take 2–5 seconds to process.
|
|
133
|
+
|
|
134
|
+
## Changelog & Releases
|
|
135
|
+
|
|
136
|
+
This repository keeps a change log using [GitHub's releases][releases]
|
|
137
|
+
functionality.
|
|
138
|
+
|
|
139
|
+
Releases are based on [Semantic Versioning][semver], and use the format
|
|
140
|
+
of `MAJOR.MINOR.PATCH`. In a nutshell, the version will be incremented
|
|
141
|
+
based on the following:
|
|
142
|
+
|
|
143
|
+
- `MAJOR`: Incompatible or major changes.
|
|
144
|
+
- `MINOR`: Backwards-compatible new features and enhancements.
|
|
145
|
+
- `PATCH`: Backwards-compatible bugfixes and package updates.
|
|
146
|
+
|
|
147
|
+
## Contributing
|
|
148
|
+
|
|
149
|
+
This is an active open-source project. We are always open to people who want to
|
|
150
|
+
use the code or contribute to it.
|
|
151
|
+
|
|
152
|
+
Thank you for being involved! :heart_eyes:
|
|
153
|
+
|
|
154
|
+
## Setting up development environment
|
|
155
|
+
|
|
156
|
+
This Python project is fully managed using the [Poetry][poetry] dependency
|
|
157
|
+
manager.
|
|
158
|
+
|
|
159
|
+
You need at least:
|
|
160
|
+
|
|
161
|
+
- Python 3.12+
|
|
162
|
+
- [Poetry][poetry-install]
|
|
163
|
+
|
|
164
|
+
To install all packages, including all development requirements:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
poetry install
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
As this repository uses the [prek][prek] framework, all changes
|
|
171
|
+
are linted and tested with each commit. You can run all checks and tests
|
|
172
|
+
manually, using the following command:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
poetry run prek run --all-files
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
To run just the Python tests:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
poetry run pytest
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Authors & contributors
|
|
185
|
+
|
|
186
|
+
The original setup of this repository is by @Moustachauve.
|
|
187
|
+
|
|
188
|
+
The structure of this library is inspired by [python-wled][python-wled] from
|
|
189
|
+
@frenck and [pytechnove][pytechnove] from @Moustachauve.
|
|
190
|
+
|
|
191
|
+
[build-shield]: https://github.com/Moustachauve/python-hotspring/actions/workflows/tests.yaml/badge.svg
|
|
192
|
+
[build]: https://github.com/Moustachauve/python-hotspring/actions/workflows/tests.yaml
|
|
193
|
+
[codecov-shield]: https://codecov.io/gh/Moustachauve/python-hotspring/branch/main/graph/badge.svg
|
|
194
|
+
[codecov]: https://codecov.io/gh/Moustachauve/python-hotspring
|
|
195
|
+
[license-shield]: https://img.shields.io/github/license/Moustachauve/python-hotspring.svg
|
|
196
|
+
[maintenance-shield]: https://img.shields.io/maintenance/yes/2026.svg
|
|
197
|
+
[poetry-install]: https://python-poetry.org/docs/#installation
|
|
198
|
+
[poetry]: https://python-poetry.org
|
|
199
|
+
[prek]: https://github.com/j178/prek
|
|
200
|
+
[project-stage-shield]: https://img.shields.io/badge/project%20stage-experimental-yellow.svg
|
|
201
|
+
[pypi]: https://pypi.org/project/python-hotspring/
|
|
202
|
+
[python-versions-shield]: https://img.shields.io/pypi/pyversions/python-hotspring
|
|
203
|
+
[releases-shield]: https://img.shields.io/github/release/Moustachauve/python-hotspring.svg
|
|
204
|
+
[releases]: https://github.com/Moustachauve/python-hotspring/releases
|
|
205
|
+
[semver]: http://semver.org/spec/v2.0.0.html
|
|
206
|
+
[python-wled]: https://github.com/frenck/python-wled
|
|
207
|
+
[pytechnove]: https://github.com/Moustachauve/pytechnove/
|
|
208
|
+
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
[![GitHub Release][releases-shield]][releases]
|
|
2
|
+
[![Python Versions][python-versions-shield]][pypi]
|
|
3
|
+
![Project Stage][project-stage-shield]
|
|
4
|
+
![Project Maintenance][maintenance-shield]
|
|
5
|
+
[![License][license-shield]](LICENSE)
|
|
6
|
+
|
|
7
|
+
[![Build Status][build-shield]][build]
|
|
8
|
+
[![Code Coverage][codecov-shield]][codecov]
|
|
9
|
+
|
|
10
|
+
Asynchronous Python client for Hot Spring Connected Spa Kit 2.
|
|
11
|
+
|
|
12
|
+
> [!WARNING]
|
|
13
|
+
> This library is currently in heavy development. Not all features might work
|
|
14
|
+
> perfectly, and some features may not be fully tested as they depend on the
|
|
15
|
+
> physical hardware available for testing.
|
|
16
|
+
|
|
17
|
+
## About
|
|
18
|
+
|
|
19
|
+
This package allows you to control and monitor a Hot Spring spa equipped with the
|
|
20
|
+
[Connected Spa Kit 2](https://www.hotspring.com/) programmatically via its local
|
|
21
|
+
HTTP API. It communicates with the Home Network Adapter (HNA), which bridges your
|
|
22
|
+
home network to the spa's control board over LoRA radio.
|
|
23
|
+
|
|
24
|
+
It is primarily designed to be used as the communication layer for an official
|
|
25
|
+
[Home Assistant](https://www.home-assistant.io/) integration.
|
|
26
|
+
|
|
27
|
+
### Supported Features
|
|
28
|
+
|
|
29
|
+
- **Temperature monitoring & control** — Read current/target water temperature,
|
|
30
|
+
set target temperature, change heating modes
|
|
31
|
+
- **Jets & blower** — Control jet speeds (off, low, high) across all jet pumps
|
|
32
|
+
- **Multi-zone lighting** — Set colors and brightness for up to 4 light zones
|
|
33
|
+
plus the logo light
|
|
34
|
+
- **Water care** — Monitor FreshWater IQ salt system metrics (pH, chlorine,
|
|
35
|
+
ORP, sensor life)
|
|
36
|
+
- **Diagnostics** — Read voltage, power consumption, and failure states
|
|
37
|
+
- **Connection monitoring** — Check LoRA bridge and cloud connectivity status
|
|
38
|
+
- **Energy saving schedules** — View configured energy saving time windows
|
|
39
|
+
- **Clean cycle** — Start or stop the 10-minute clean cycle
|
|
40
|
+
|
|
41
|
+
### Compatible Spas
|
|
42
|
+
|
|
43
|
+
This library works with any Hot Spring, Caldera, or Freeflow spa that supports
|
|
44
|
+
the **Connected Spa Kit 2** (compatible with spas from 2014 onwards that use
|
|
45
|
+
the IQ2020/Eagle control board).
|
|
46
|
+
|
|
47
|
+
> [!NOTE]
|
|
48
|
+
> This library has been primarily tested on a **Hotspring Hot Spot Relay 2025**.
|
|
49
|
+
> Compatibility with other specific models and configurations may vary.
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install python-hotspring
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
import asyncio
|
|
61
|
+
|
|
62
|
+
from hotspring import HotSpring
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
async def main() -> None:
|
|
66
|
+
"""Show example of controlling your Hot Spring spa."""
|
|
67
|
+
async with HotSpring("192.168.1.100") as spa_client:
|
|
68
|
+
# Get full spa status
|
|
69
|
+
spa = await spa_client.update()
|
|
70
|
+
print(f"Water temperature: {spa.heater.current_temperature}°F")
|
|
71
|
+
print(f"Heater: {'on' if spa.heater.is_on else 'off'}")
|
|
72
|
+
print(f"Heating mode: {spa.heater.heating_mode.name}")
|
|
73
|
+
|
|
74
|
+
# Control the spa
|
|
75
|
+
await spa_client.set_temperature(102)
|
|
76
|
+
await spa_client.set_jet(1, "highSpeed")
|
|
77
|
+
await spa_client.set_light_color(1, "Blue")
|
|
78
|
+
await spa_client.set_clean_cycle(enabled=True)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
if __name__ == "__main__":
|
|
82
|
+
asyncio.run(main())
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Demos
|
|
86
|
+
|
|
87
|
+
Several demonstration scripts are available in the [demo/](demo/README.md) directory to help you get started with the library and verify connectivity with your spa.
|
|
88
|
+
|
|
89
|
+
## Architecture
|
|
90
|
+
|
|
91
|
+
The Hot Spring Connected Spa Kit 2 uses a two-part system:
|
|
92
|
+
|
|
93
|
+
- **HNA (Home Network Adapter)** — Located inside the home, connects to
|
|
94
|
+
WiFi/Internet and runs the local HTTP API that this library communicates with
|
|
95
|
+
- **SNA (Spa Network Adapter)** — Located inside the spa, wired to the IQ2020
|
|
96
|
+
control board via RS485, communicates with the HNA via LoRA radio
|
|
97
|
+
|
|
98
|
+
All API calls go through the HNA, which relays commands to the spa over LoRA.
|
|
99
|
+
Commands typically take 2–5 seconds to process.
|
|
100
|
+
|
|
101
|
+
## Changelog & Releases
|
|
102
|
+
|
|
103
|
+
This repository keeps a change log using [GitHub's releases][releases]
|
|
104
|
+
functionality.
|
|
105
|
+
|
|
106
|
+
Releases are based on [Semantic Versioning][semver], and use the format
|
|
107
|
+
of `MAJOR.MINOR.PATCH`. In a nutshell, the version will be incremented
|
|
108
|
+
based on the following:
|
|
109
|
+
|
|
110
|
+
- `MAJOR`: Incompatible or major changes.
|
|
111
|
+
- `MINOR`: Backwards-compatible new features and enhancements.
|
|
112
|
+
- `PATCH`: Backwards-compatible bugfixes and package updates.
|
|
113
|
+
|
|
114
|
+
## Contributing
|
|
115
|
+
|
|
116
|
+
This is an active open-source project. We are always open to people who want to
|
|
117
|
+
use the code or contribute to it.
|
|
118
|
+
|
|
119
|
+
Thank you for being involved! :heart_eyes:
|
|
120
|
+
|
|
121
|
+
## Setting up development environment
|
|
122
|
+
|
|
123
|
+
This Python project is fully managed using the [Poetry][poetry] dependency
|
|
124
|
+
manager.
|
|
125
|
+
|
|
126
|
+
You need at least:
|
|
127
|
+
|
|
128
|
+
- Python 3.12+
|
|
129
|
+
- [Poetry][poetry-install]
|
|
130
|
+
|
|
131
|
+
To install all packages, including all development requirements:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
poetry install
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
As this repository uses the [prek][prek] framework, all changes
|
|
138
|
+
are linted and tested with each commit. You can run all checks and tests
|
|
139
|
+
manually, using the following command:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
poetry run prek run --all-files
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
To run just the Python tests:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
poetry run pytest
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Authors & contributors
|
|
152
|
+
|
|
153
|
+
The original setup of this repository is by @Moustachauve.
|
|
154
|
+
|
|
155
|
+
The structure of this library is inspired by [python-wled][python-wled] from
|
|
156
|
+
@frenck and [pytechnove][pytechnove] from @Moustachauve.
|
|
157
|
+
|
|
158
|
+
[build-shield]: https://github.com/Moustachauve/python-hotspring/actions/workflows/tests.yaml/badge.svg
|
|
159
|
+
[build]: https://github.com/Moustachauve/python-hotspring/actions/workflows/tests.yaml
|
|
160
|
+
[codecov-shield]: https://codecov.io/gh/Moustachauve/python-hotspring/branch/main/graph/badge.svg
|
|
161
|
+
[codecov]: https://codecov.io/gh/Moustachauve/python-hotspring
|
|
162
|
+
[license-shield]: https://img.shields.io/github/license/Moustachauve/python-hotspring.svg
|
|
163
|
+
[maintenance-shield]: https://img.shields.io/maintenance/yes/2026.svg
|
|
164
|
+
[poetry-install]: https://python-poetry.org/docs/#installation
|
|
165
|
+
[poetry]: https://python-poetry.org
|
|
166
|
+
[prek]: https://github.com/j178/prek
|
|
167
|
+
[project-stage-shield]: https://img.shields.io/badge/project%20stage-experimental-yellow.svg
|
|
168
|
+
[pypi]: https://pypi.org/project/python-hotspring/
|
|
169
|
+
[python-versions-shield]: https://img.shields.io/pypi/pyversions/python-hotspring
|
|
170
|
+
[releases-shield]: https://img.shields.io/github/release/Moustachauve/python-hotspring.svg
|
|
171
|
+
[releases]: https://github.com/Moustachauve/python-hotspring/releases
|
|
172
|
+
[semver]: http://semver.org/spec/v2.0.0.html
|
|
173
|
+
[python-wled]: https://github.com/frenck/python-wled
|
|
174
|
+
[pytechnove]: https://github.com/Moustachauve/pytechnove/
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
authors = ["Christophe Gagnier <christopheextensions@gmail.com>"]
|
|
3
|
+
classifiers = [
|
|
4
|
+
"Development Status :: 3 - Alpha",
|
|
5
|
+
"Framework :: AsyncIO",
|
|
6
|
+
"Intended Audience :: Developers",
|
|
7
|
+
"Natural Language :: English",
|
|
8
|
+
"Programming Language :: Python :: 3.12",
|
|
9
|
+
"Programming Language :: Python :: 3.13",
|
|
10
|
+
"Programming Language :: Python :: 3",
|
|
11
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
12
|
+
]
|
|
13
|
+
description = "Asynchronous Python client for Hot Spring Connected Spa Kit 2."
|
|
14
|
+
documentation = "https://github.com/Moustachauve/python-hotspring"
|
|
15
|
+
homepage = "https://github.com/Moustachauve/python-hotspring"
|
|
16
|
+
keywords = ["hotspring", "spa", "hot-tub", "home-assistant", "iq2020"]
|
|
17
|
+
license = "MIT"
|
|
18
|
+
maintainers = ["Christophe Gagnier <christopheextensions@gmail.com>"]
|
|
19
|
+
name = "python-hotspring"
|
|
20
|
+
packages = [
|
|
21
|
+
{include = "hotspring", from = "src"},
|
|
22
|
+
]
|
|
23
|
+
readme = "README.md"
|
|
24
|
+
repository = "https://github.com/Moustachauve/python-hotspring"
|
|
25
|
+
version = "1.0.0"
|
|
26
|
+
|
|
27
|
+
[tool.poetry.dependencies]
|
|
28
|
+
aiohttp = ">=3.0.0"
|
|
29
|
+
awesomeversion = ">=22.1.0"
|
|
30
|
+
backoff = ">=2.2.0"
|
|
31
|
+
python = "^3.12"
|
|
32
|
+
yarl = ">=1.6.0"
|
|
33
|
+
|
|
34
|
+
[tool.poetry.urls]
|
|
35
|
+
"Bug Tracker" = "https://github.com/Moustachauve/python-hotspring/issues"
|
|
36
|
+
Changelog = "https://github.com/Moustachauve/python-hotspring/releases"
|
|
37
|
+
|
|
38
|
+
[tool.poetry.group.dev.dependencies]
|
|
39
|
+
aresponses = "3.0.0"
|
|
40
|
+
codespell = "2.4.2"
|
|
41
|
+
covdefaults = "2.3.0"
|
|
42
|
+
coverage = {version = "7.13.5", extras = ["toml"]}
|
|
43
|
+
mypy = "1.20.1"
|
|
44
|
+
pre-commit-hooks = "6.0.0"
|
|
45
|
+
prek = "0.3.9"
|
|
46
|
+
pylint = "4.0.5"
|
|
47
|
+
pytest = "9.0.3"
|
|
48
|
+
pytest-asyncio = "1.3.0"
|
|
49
|
+
pytest-cov = "7.1.0"
|
|
50
|
+
ruff = "0.15.11"
|
|
51
|
+
safety = "3.7.0"
|
|
52
|
+
yamllint = "1.38.0"
|
|
53
|
+
|
|
54
|
+
[tool.coverage.run]
|
|
55
|
+
plugins = ["covdefaults"]
|
|
56
|
+
source = ["hotspring"]
|
|
57
|
+
|
|
58
|
+
[tool.coverage.report]
|
|
59
|
+
fail_under = 90
|
|
60
|
+
show_missing = true
|
|
61
|
+
|
|
62
|
+
[tool.mypy]
|
|
63
|
+
platform = "linux"
|
|
64
|
+
python_version = "3.12"
|
|
65
|
+
follow_imports = "normal"
|
|
66
|
+
ignore_missing_imports = true
|
|
67
|
+
|
|
68
|
+
# be strict
|
|
69
|
+
check_untyped_defs = true
|
|
70
|
+
disallow_any_generics = true
|
|
71
|
+
disallow_incomplete_defs = true
|
|
72
|
+
disallow_subclassing_any = true
|
|
73
|
+
disallow_untyped_calls = true
|
|
74
|
+
disallow_untyped_decorators = true
|
|
75
|
+
disallow_untyped_defs = true
|
|
76
|
+
no_implicit_optional = true
|
|
77
|
+
no_implicit_reexport = true
|
|
78
|
+
strict_optional = true
|
|
79
|
+
warn_incomplete_stub = true
|
|
80
|
+
warn_no_return = true
|
|
81
|
+
warn_redundant_casts = true
|
|
82
|
+
warn_return_any = true
|
|
83
|
+
warn_unused_configs = true
|
|
84
|
+
warn_unused_ignores = true
|
|
85
|
+
|
|
86
|
+
[tool.pylint.MASTER]
|
|
87
|
+
ignore = ["tests"]
|
|
88
|
+
|
|
89
|
+
[tool.pylint.BASIC]
|
|
90
|
+
good-names = [
|
|
91
|
+
"_",
|
|
92
|
+
"ex",
|
|
93
|
+
"fp",
|
|
94
|
+
"i",
|
|
95
|
+
"id",
|
|
96
|
+
"j",
|
|
97
|
+
"k",
|
|
98
|
+
"on",
|
|
99
|
+
"ph",
|
|
100
|
+
"Run",
|
|
101
|
+
"T",
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
[tool.pylint."MESSAGES CONTROL"]
|
|
105
|
+
disable = [
|
|
106
|
+
"too-few-public-methods",
|
|
107
|
+
"duplicate-code",
|
|
108
|
+
"format",
|
|
109
|
+
"unsubscriptable-object",
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
[tool.pylint.SIMILARITIES]
|
|
113
|
+
ignore-imports = true
|
|
114
|
+
|
|
115
|
+
[tool.pylint.FORMAT]
|
|
116
|
+
max-line-length = 88
|
|
117
|
+
|
|
118
|
+
[tool.pylint.DESIGN]
|
|
119
|
+
max-attributes = 30
|
|
120
|
+
|
|
121
|
+
[tool.pytest.ini_options]
|
|
122
|
+
addopts = "--cov"
|
|
123
|
+
asyncio_mode = "auto"
|
|
124
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
125
|
+
|
|
126
|
+
[tool.ruff]
|
|
127
|
+
exclude = ["demo"]
|
|
128
|
+
|
|
129
|
+
[tool.ruff.lint]
|
|
130
|
+
ignore = [
|
|
131
|
+
"ANN401", # Opinionated warning on disallowing dynamically typed expressions
|
|
132
|
+
"D203", # Conflicts with other rules
|
|
133
|
+
"D213", # Conflicts with other rules
|
|
134
|
+
"D417", # False positives in some occasions
|
|
135
|
+
"PLR2004", # Just annoying, not really useful
|
|
136
|
+
|
|
137
|
+
# Conflicts with the Ruff formatter
|
|
138
|
+
"COM812",
|
|
139
|
+
"ISC001",
|
|
140
|
+
]
|
|
141
|
+
select = ["ALL"]
|
|
142
|
+
|
|
143
|
+
[tool.ruff.lint.per-file-ignores]
|
|
144
|
+
"tests/**/*.py" = [
|
|
145
|
+
"FBT001", # Boolean positional args are idiomatic in parametrized tests
|
|
146
|
+
"FBT002", # Boolean defaults are idiomatic in parametrized tests
|
|
147
|
+
"PLC0415", # Inline imports are acceptable in tests
|
|
148
|
+
"S101", # Use of assert detected — expected in test code
|
|
149
|
+
"SLF001", # Private member access acceptable for test verification
|
|
150
|
+
]
|
|
151
|
+
"demo/**/*.py" = [
|
|
152
|
+
"T201", # allow print statements in demo
|
|
153
|
+
"S101", # allow assert in demo
|
|
154
|
+
"PTH118", # allow os.path.join
|
|
155
|
+
"PTH109", # allow os.getcwd
|
|
156
|
+
"INP001", # implicit namespace package is fine for demo
|
|
157
|
+
"ERA001", # commented out code is fine in demo
|
|
158
|
+
"E501", # line too long is fine
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
[tool.ruff.lint.flake8-pytest-style]
|
|
162
|
+
fixture-parentheses = false
|
|
163
|
+
mark-parentheses = false
|
|
164
|
+
|
|
165
|
+
[tool.ruff.lint.isort]
|
|
166
|
+
known-first-party = ["hotspring"]
|
|
167
|
+
|
|
168
|
+
[tool.ruff.lint.mccabe]
|
|
169
|
+
max-complexity = 25
|
|
170
|
+
|
|
171
|
+
[tool.codespell]
|
|
172
|
+
ignore-words-list = "hass,loopUp,loopDown"
|
|
173
|
+
|
|
174
|
+
[build-system]
|
|
175
|
+
build-backend = "poetry.core.masonry.api"
|
|
176
|
+
requires = ["poetry-core>=1.0.0"]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Asynchronous Python client for Hot Spring Connected Spa Kit 2."""
|
|
2
|
+
|
|
3
|
+
from .const import (
|
|
4
|
+
BrightnessLevel,
|
|
5
|
+
HeatingMode,
|
|
6
|
+
JetSpeed,
|
|
7
|
+
LightColor,
|
|
8
|
+
LightWheelMode,
|
|
9
|
+
SpaFailureState,
|
|
10
|
+
TemperatureUnit,
|
|
11
|
+
)
|
|
12
|
+
from .exceptions import (
|
|
13
|
+
HotSpringCommandError,
|
|
14
|
+
HotSpringConnectionError,
|
|
15
|
+
HotSpringConnectionTimeoutError,
|
|
16
|
+
HotSpringError,
|
|
17
|
+
HotSpringNotReadyError,
|
|
18
|
+
)
|
|
19
|
+
from .hotspring import HotSpring
|
|
20
|
+
from .models import (
|
|
21
|
+
Blower,
|
|
22
|
+
CleanCycle,
|
|
23
|
+
ConnectionStatus,
|
|
24
|
+
Diagnostics,
|
|
25
|
+
EnergySaving,
|
|
26
|
+
FreshWaterIQ,
|
|
27
|
+
Heater,
|
|
28
|
+
Jet,
|
|
29
|
+
LightZone,
|
|
30
|
+
LogoLight,
|
|
31
|
+
Spa,
|
|
32
|
+
SpaInfo,
|
|
33
|
+
SpaLock,
|
|
34
|
+
Versions,
|
|
35
|
+
WaterCare,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"Blower",
|
|
40
|
+
"BrightnessLevel",
|
|
41
|
+
"CleanCycle",
|
|
42
|
+
"ConnectionStatus",
|
|
43
|
+
"Diagnostics",
|
|
44
|
+
"EnergySaving",
|
|
45
|
+
"FreshWaterIQ",
|
|
46
|
+
"Heater",
|
|
47
|
+
"HeatingMode",
|
|
48
|
+
"HotSpring",
|
|
49
|
+
"HotSpringCommandError",
|
|
50
|
+
"HotSpringConnectionError",
|
|
51
|
+
"HotSpringConnectionTimeoutError",
|
|
52
|
+
"HotSpringError",
|
|
53
|
+
"HotSpringNotReadyError",
|
|
54
|
+
"Jet",
|
|
55
|
+
"JetSpeed",
|
|
56
|
+
"LightColor",
|
|
57
|
+
"LightWheelMode",
|
|
58
|
+
"LightZone",
|
|
59
|
+
"LogoLight",
|
|
60
|
+
"Spa",
|
|
61
|
+
"SpaFailureState",
|
|
62
|
+
"SpaInfo",
|
|
63
|
+
"SpaLock",
|
|
64
|
+
"TemperatureUnit",
|
|
65
|
+
"Versions",
|
|
66
|
+
"WaterCare",
|
|
67
|
+
]
|