pycaldera 0.1.dev0__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.
- pycaldera-0.1.dev0/CHANGELOG.rst +18 -0
- pycaldera-0.1.dev0/LICENSE +21 -0
- pycaldera-0.1.dev0/MANIFEST.in +10 -0
- pycaldera-0.1.dev0/PKG-INFO +198 -0
- pycaldera-0.1.dev0/README.md +117 -0
- pycaldera-0.1.dev0/pycaldera/__init__.py +22 -0
- pycaldera-0.1.dev0/pycaldera/__meta__.py +12 -0
- pycaldera-0.1.dev0/pycaldera/async_client.py +495 -0
- pycaldera-0.1.dev0/pycaldera/exceptions.py +31 -0
- pycaldera-0.1.dev0/pycaldera/models.py +261 -0
- pycaldera-0.1.dev0/pycaldera.egg-info/PKG-INFO +198 -0
- pycaldera-0.1.dev0/pycaldera.egg-info/SOURCES.txt +21 -0
- pycaldera-0.1.dev0/pycaldera.egg-info/dependency_links.txt +1 -0
- pycaldera-0.1.dev0/pycaldera.egg-info/requires.txt +62 -0
- pycaldera-0.1.dev0/pycaldera.egg-info/top_level.txt +1 -0
- pycaldera-0.1.dev0/pyproject.toml +15 -0
- pycaldera-0.1.dev0/requirements-dev.txt +8 -0
- pycaldera-0.1.dev0/requirements-docs.txt +7 -0
- pycaldera-0.1.dev0/requirements-test.txt +3 -0
- pycaldera-0.1.dev0/requirements.txt +13 -0
- pycaldera-0.1.dev0/setup.cfg +4 -0
- pycaldera-0.1.dev0/setup.py +156 -0
- pycaldera-0.1.dev0/tests/test_async_client.py +413 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Changelog
|
|
2
|
+
=========
|
|
3
|
+
|
|
4
|
+
All notable changes to package_name will be documented here.
|
|
5
|
+
|
|
6
|
+
The format is based on `Keep a Changelog`_, and this project adheres to `Semantic Versioning`_.
|
|
7
|
+
|
|
8
|
+
.. _Keep a Changelog: https://keepachangelog.com/en/1.0.0/
|
|
9
|
+
.. _Semantic Versioning: https://semver.org/spec/v2.0.0.html
|
|
10
|
+
|
|
11
|
+
Categories for changes are: Added, Changed, Deprecated, Removed, Fixed, Security.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Version `0.1.0 <https://github.com/your_organisation/package_name/tree/0.1.0>`__
|
|
15
|
+
--------------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
Release date: YYYY-MM-DD.
|
|
18
|
+
Initial release (to be released).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Mark Watson
|
|
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,198 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: pycaldera
|
|
3
|
+
Version: 0.1.dev0
|
|
4
|
+
Summary: Unofficial Python client for Caldera Spa API
|
|
5
|
+
Home-page: https://github.com/mwatson2/pycaldera
|
|
6
|
+
Author: Mark Watson
|
|
7
|
+
Author-email: markwatson@cantab.net
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Natural Language :: English
|
|
10
|
+
Classifier: Programming Language :: Python
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: aiohttp>=3.8.0
|
|
21
|
+
Requires-Dist: pydantic>=2.0.0
|
|
22
|
+
Requires-Dist: black>=23.0.0
|
|
23
|
+
Requires-Dist: isort>=5.12.0
|
|
24
|
+
Requires-Dist: mypy>=1.0.0
|
|
25
|
+
Requires-Dist: pylint>=2.17.0
|
|
26
|
+
Requires-Dist: pytest>=7.0.0
|
|
27
|
+
Requires-Dist: pytest-aiohttp>=1.0.0
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.21.0
|
|
29
|
+
Requires-Dist: pytest-cov>=4.0.0
|
|
30
|
+
Provides-Extra: test
|
|
31
|
+
Requires-Dist: pytest; extra == "test"
|
|
32
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
33
|
+
Requires-Dist: pytest-flake8; extra == "test"
|
|
34
|
+
Provides-Extra: docs
|
|
35
|
+
Requires-Dist: myst-parser; extra == "docs"
|
|
36
|
+
Requires-Dist: pypandoc>=1.6.3; extra == "docs"
|
|
37
|
+
Requires-Dist: readthedocs-sphinx-search; python_version >= "3.6" and extra == "docs"
|
|
38
|
+
Requires-Dist: sphinx<6,>=3.5.4; extra == "docs"
|
|
39
|
+
Requires-Dist: sphinx-autobuild; extra == "docs"
|
|
40
|
+
Requires-Dist: sphinx_book_theme; extra == "docs"
|
|
41
|
+
Requires-Dist: watchdog<1.0.0; python_version < "3.6" and extra == "docs"
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
44
|
+
Requires-Dist: isort>=5.12.0; extra == "dev"
|
|
45
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
46
|
+
Requires-Dist: pylint>=2.17.0; extra == "dev"
|
|
47
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
48
|
+
Requires-Dist: pytest-aiohttp>=1.0.0; extra == "dev"
|
|
49
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
50
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
51
|
+
Provides-Extra: all
|
|
52
|
+
Requires-Dist: black>=23.0.0; extra == "all"
|
|
53
|
+
Requires-Dist: isort>=5.12.0; extra == "all"
|
|
54
|
+
Requires-Dist: mypy>=1.0.0; extra == "all"
|
|
55
|
+
Requires-Dist: myst-parser; extra == "all"
|
|
56
|
+
Requires-Dist: pylint>=2.17.0; extra == "all"
|
|
57
|
+
Requires-Dist: pypandoc>=1.6.3; extra == "all"
|
|
58
|
+
Requires-Dist: pytest; extra == "all"
|
|
59
|
+
Requires-Dist: pytest-aiohttp>=1.0.0; extra == "all"
|
|
60
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "all"
|
|
61
|
+
Requires-Dist: pytest-cov; extra == "all"
|
|
62
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "all"
|
|
63
|
+
Requires-Dist: pytest-flake8; extra == "all"
|
|
64
|
+
Requires-Dist: pytest>=7.0.0; extra == "all"
|
|
65
|
+
Requires-Dist: readthedocs-sphinx-search; python_version >= "3.6" and extra == "all"
|
|
66
|
+
Requires-Dist: sphinx-autobuild; extra == "all"
|
|
67
|
+
Requires-Dist: sphinx<6,>=3.5.4; extra == "all"
|
|
68
|
+
Requires-Dist: sphinx_book_theme; extra == "all"
|
|
69
|
+
Requires-Dist: watchdog<1.0.0; python_version < "3.6" and extra == "all"
|
|
70
|
+
Dynamic: author
|
|
71
|
+
Dynamic: author-email
|
|
72
|
+
Dynamic: classifier
|
|
73
|
+
Dynamic: description
|
|
74
|
+
Dynamic: description-content-type
|
|
75
|
+
Dynamic: home-page
|
|
76
|
+
Dynamic: license
|
|
77
|
+
Dynamic: provides-extra
|
|
78
|
+
Dynamic: requires-dist
|
|
79
|
+
Dynamic: requires-python
|
|
80
|
+
Dynamic: summary
|
|
81
|
+
|
|
82
|
+
# pycaldera
|
|
83
|
+
|
|
84
|
+
Python client library for controlling Caldera spas via their cloud API.
|
|
85
|
+
|
|
86
|
+
## Installation
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pip install pycaldera
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Usage
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
import asyncio
|
|
96
|
+
from pycaldera import AsyncCalderaClient, PUMP_OFF, PUMP_LOW, PUMP_HIGH
|
|
97
|
+
|
|
98
|
+
async def main():
|
|
99
|
+
async with AsyncCalderaClient("email@example.com", "password") as spa:
|
|
100
|
+
# Get current spa status
|
|
101
|
+
status = await spa.get_spa_status()
|
|
102
|
+
print(f"Current temperature: {status.ctrl_head_water_temperature}°F")
|
|
103
|
+
|
|
104
|
+
# Get detailed live settings
|
|
105
|
+
settings = await spa.get_live_settings()
|
|
106
|
+
print(f"Target temperature: {settings.ctrl_head_set_temperature}°F")
|
|
107
|
+
|
|
108
|
+
# Control the spa
|
|
109
|
+
await spa.set_temperature(102) # Set temperature to 102°F
|
|
110
|
+
await spa.set_pump(1, PUMP_HIGH) # Set pump 1 to high speed
|
|
111
|
+
await spa.set_lights(True) # Turn on the lights
|
|
112
|
+
|
|
113
|
+
asyncio.run(main())
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## API Reference
|
|
117
|
+
|
|
118
|
+
### AsyncCalderaClient
|
|
119
|
+
|
|
120
|
+
Main client class for interacting with the spa.
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
client = AsyncCalderaClient(
|
|
124
|
+
email="email@example.com",
|
|
125
|
+
password="password",
|
|
126
|
+
timeout=10.0, # Optional: request timeout in seconds
|
|
127
|
+
debug=False, # Optional: enable debug logging
|
|
128
|
+
)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Temperature Control
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
# Set temperature (80-104°F or 26.5-40°C)
|
|
135
|
+
await spa.set_temperature(102) # Fahrenheit
|
|
136
|
+
await spa.set_temperature(39, "C") # Celsius
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Pump Control
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
# Set pump speed
|
|
143
|
+
await spa.set_pump(1, PUMP_HIGH) # Set pump 1 to high speed
|
|
144
|
+
await spa.set_pump(2, PUMP_LOW) # Set pump 2 to low speed
|
|
145
|
+
await spa.set_pump(3, PUMP_OFF) # Turn off pump 3
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Light Control
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
await spa.set_lights(True) # Turn lights on
|
|
152
|
+
await spa.set_lights(False) # Turn lights off
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Status & Settings
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
# Get basic spa status
|
|
159
|
+
status = await spa.get_spa_status()
|
|
160
|
+
print(f"Spa name: {status.spaName}")
|
|
161
|
+
print(f"Current temp: {status.ctrl_head_water_temperature}°F")
|
|
162
|
+
print(f"Online: {status.status == 'ONLINE'}")
|
|
163
|
+
|
|
164
|
+
# Get detailed live settings
|
|
165
|
+
settings = await spa.get_live_settings()
|
|
166
|
+
print(f"Target temp: {settings.ctrl_head_set_temperature}°F")
|
|
167
|
+
print(f"Pump 1 speed: {settings.usr_set_pump1_speed}")
|
|
168
|
+
print(f"Lights on: {settings.usr_set_light_state}")
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Development
|
|
172
|
+
|
|
173
|
+
1. Clone the repository
|
|
174
|
+
2. Create a virtual environment:
|
|
175
|
+
```bash
|
|
176
|
+
python -m venv venv
|
|
177
|
+
source venv/bin/activate # or `venv\Scripts\activate` on Windows
|
|
178
|
+
```
|
|
179
|
+
3. Install development dependencies:
|
|
180
|
+
```bash
|
|
181
|
+
pip install -r requirements-dev.txt
|
|
182
|
+
```
|
|
183
|
+
4. Install pre-commit hooks:
|
|
184
|
+
```bash
|
|
185
|
+
pre-commit install
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
The pre-commit hooks will run automatically on git commit, checking:
|
|
189
|
+
- Code formatting (Black)
|
|
190
|
+
- Import sorting (isort)
|
|
191
|
+
- Type checking (mypy)
|
|
192
|
+
- Linting (pylint, ruff)
|
|
193
|
+
- YAML/TOML syntax
|
|
194
|
+
- Trailing whitespace and file endings
|
|
195
|
+
|
|
196
|
+
## License
|
|
197
|
+
|
|
198
|
+
MIT License - see LICENSE file for details.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# pycaldera
|
|
2
|
+
|
|
3
|
+
Python client library for controlling Caldera spas via their cloud API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install pycaldera
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import asyncio
|
|
15
|
+
from pycaldera import AsyncCalderaClient, PUMP_OFF, PUMP_LOW, PUMP_HIGH
|
|
16
|
+
|
|
17
|
+
async def main():
|
|
18
|
+
async with AsyncCalderaClient("email@example.com", "password") as spa:
|
|
19
|
+
# Get current spa status
|
|
20
|
+
status = await spa.get_spa_status()
|
|
21
|
+
print(f"Current temperature: {status.ctrl_head_water_temperature}°F")
|
|
22
|
+
|
|
23
|
+
# Get detailed live settings
|
|
24
|
+
settings = await spa.get_live_settings()
|
|
25
|
+
print(f"Target temperature: {settings.ctrl_head_set_temperature}°F")
|
|
26
|
+
|
|
27
|
+
# Control the spa
|
|
28
|
+
await spa.set_temperature(102) # Set temperature to 102°F
|
|
29
|
+
await spa.set_pump(1, PUMP_HIGH) # Set pump 1 to high speed
|
|
30
|
+
await spa.set_lights(True) # Turn on the lights
|
|
31
|
+
|
|
32
|
+
asyncio.run(main())
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## API Reference
|
|
36
|
+
|
|
37
|
+
### AsyncCalderaClient
|
|
38
|
+
|
|
39
|
+
Main client class for interacting with the spa.
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
client = AsyncCalderaClient(
|
|
43
|
+
email="email@example.com",
|
|
44
|
+
password="password",
|
|
45
|
+
timeout=10.0, # Optional: request timeout in seconds
|
|
46
|
+
debug=False, # Optional: enable debug logging
|
|
47
|
+
)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Temperature Control
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
# Set temperature (80-104°F or 26.5-40°C)
|
|
54
|
+
await spa.set_temperature(102) # Fahrenheit
|
|
55
|
+
await spa.set_temperature(39, "C") # Celsius
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Pump Control
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
# Set pump speed
|
|
62
|
+
await spa.set_pump(1, PUMP_HIGH) # Set pump 1 to high speed
|
|
63
|
+
await spa.set_pump(2, PUMP_LOW) # Set pump 2 to low speed
|
|
64
|
+
await spa.set_pump(3, PUMP_OFF) # Turn off pump 3
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Light Control
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
await spa.set_lights(True) # Turn lights on
|
|
71
|
+
await spa.set_lights(False) # Turn lights off
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Status & Settings
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
# Get basic spa status
|
|
78
|
+
status = await spa.get_spa_status()
|
|
79
|
+
print(f"Spa name: {status.spaName}")
|
|
80
|
+
print(f"Current temp: {status.ctrl_head_water_temperature}°F")
|
|
81
|
+
print(f"Online: {status.status == 'ONLINE'}")
|
|
82
|
+
|
|
83
|
+
# Get detailed live settings
|
|
84
|
+
settings = await spa.get_live_settings()
|
|
85
|
+
print(f"Target temp: {settings.ctrl_head_set_temperature}°F")
|
|
86
|
+
print(f"Pump 1 speed: {settings.usr_set_pump1_speed}")
|
|
87
|
+
print(f"Lights on: {settings.usr_set_light_state}")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Development
|
|
91
|
+
|
|
92
|
+
1. Clone the repository
|
|
93
|
+
2. Create a virtual environment:
|
|
94
|
+
```bash
|
|
95
|
+
python -m venv venv
|
|
96
|
+
source venv/bin/activate # or `venv\Scripts\activate` on Windows
|
|
97
|
+
```
|
|
98
|
+
3. Install development dependencies:
|
|
99
|
+
```bash
|
|
100
|
+
pip install -r requirements-dev.txt
|
|
101
|
+
```
|
|
102
|
+
4. Install pre-commit hooks:
|
|
103
|
+
```bash
|
|
104
|
+
pre-commit install
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The pre-commit hooks will run automatically on git commit, checking:
|
|
108
|
+
- Code formatting (Black)
|
|
109
|
+
- Import sorting (isort)
|
|
110
|
+
- Type checking (mypy)
|
|
111
|
+
- Linting (pylint, ruff)
|
|
112
|
+
- YAML/TOML syntax
|
|
113
|
+
- Trailing whitespace and file endings
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT License - see LICENSE file for details.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Python client for Caldera Spa Connexion API."""
|
|
2
|
+
|
|
3
|
+
from .async_client import AsyncCalderaClient
|
|
4
|
+
from .exceptions import (
|
|
5
|
+
AuthenticationError,
|
|
6
|
+
CalderaError,
|
|
7
|
+
ConnectionError,
|
|
8
|
+
InvalidParameterError,
|
|
9
|
+
SpaControlError,
|
|
10
|
+
)
|
|
11
|
+
from .models import LiveSettings
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"AsyncCalderaClient",
|
|
15
|
+
"LiveSettings",
|
|
16
|
+
"CalderaError",
|
|
17
|
+
"AuthenticationError",
|
|
18
|
+
"ConnectionError",
|
|
19
|
+
"SpaControlError",
|
|
20
|
+
"InvalidParameterError",
|
|
21
|
+
]
|
|
22
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# `name` is the name of the package as used for `pip install package`
|
|
2
|
+
name = "pycaldera"
|
|
3
|
+
# `path` is the name of the package for `import package`
|
|
4
|
+
path = name.lower().replace("-", "_").replace(" ", "_")
|
|
5
|
+
# Your version number should follow https://python.org/dev/peps/pep-0440 and
|
|
6
|
+
# https://semver.org
|
|
7
|
+
version = "0.1.dev0"
|
|
8
|
+
author = "Mark Watson"
|
|
9
|
+
author_email = "markwatson@cantab.net"
|
|
10
|
+
description = "Unofficial Python client for Caldera Spa API" # One-liner
|
|
11
|
+
url = "https://github.com/mwatson2/pycaldera" # Add your GitHub repo URL
|
|
12
|
+
license = "MIT" # See https://choosealicense.com
|