python-bsblan 3.1.1__tar.gz → 3.1.3__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 (91) hide show
  1. python_bsblan-3.1.3/.github/copilot-instructions.md +205 -0
  2. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/workflows/codeql.yaml +3 -3
  3. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/workflows/labels.yaml +1 -1
  4. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/workflows/linting.yaml +7 -7
  5. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/workflows/release.yaml +3 -3
  6. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/workflows/tests.yaml +4 -4
  7. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/workflows/typing.yaml +2 -2
  8. python_bsblan-3.1.3/.nvmrc +1 -0
  9. python_bsblan-3.1.3/AGENTS.md +1 -0
  10. python_bsblan-3.1.3/CLAUDE.md +1 -0
  11. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/PKG-INFO +4 -3
  12. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/examples/control.py +6 -5
  13. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/pyproject.toml +11 -10
  14. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/src/bsblan/__init__.py +8 -0
  15. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/src/bsblan/bsblan.py +245 -371
  16. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/src/bsblan/constants.py +39 -46
  17. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/src/bsblan/models.py +231 -7
  18. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/src/bsblan/utility.py +60 -1
  19. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_bsblan_edge_cases.py +33 -0
  20. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_dhw_time_switch.py +18 -28
  21. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_info.py +10 -0
  22. python_bsblan-3.1.3/tests/test_schedule_models.py +229 -0
  23. python_bsblan-3.1.3/tests/test_set_hot_water_schedule.py +174 -0
  24. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_set_hotwater.py +50 -72
  25. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_state.py +1 -1
  26. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_thermostat.py +37 -3
  27. python_bsblan-3.1.3/tests/test_utility.py +387 -0
  28. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/uv.lock +338 -623
  29. python_bsblan-3.1.1/.nvmrc +0 -1
  30. python_bsblan-3.1.1/tests/test_utility.py +0 -162
  31. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.editorconfig +0 -0
  32. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.gitattributes +0 -0
  33. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/CODE_OF_CONDUCT.md +0 -0
  34. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/CONTRIBUTING.md +0 -0
  35. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/ISSUE_TEMPLATE/PULL_REQUEST_TEMPLATE.md +0 -0
  36. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  37. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  38. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/LICENSE.md +0 -0
  39. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/labels.yml +0 -0
  40. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/release-drafter.yml +0 -0
  41. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/renovate.json +0 -0
  42. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/workflows/lock.yaml +0 -0
  43. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/workflows/pr-labels.yaml +0 -0
  44. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/workflows/release-drafter.yaml +0 -0
  45. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.github/workflows/stale.yaml +0 -0
  46. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.gitignore +0 -0
  47. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.pre-commit-config.yaml +0 -0
  48. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.prettierignore +0 -0
  49. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/.yamllint +0 -0
  50. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/README.md +0 -0
  51. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/examples/ruff.toml +0 -0
  52. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/package-lock.json +0 -0
  53. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/package.json +0 -0
  54. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/sonar-project.properties +0 -0
  55. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/src/bsblan/exceptions.py +0 -0
  56. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/src/bsblan/py.typed +0 -0
  57. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/__init__.py +0 -0
  58. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/conftest.py +0 -0
  59. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/fixtures/device.json +0 -0
  60. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/fixtures/dict_version.json +0 -0
  61. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/fixtures/hot_water_state.json +0 -0
  62. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/fixtures/info.json +0 -0
  63. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/fixtures/password.txt +0 -0
  64. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/fixtures/sensor.json +0 -0
  65. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/fixtures/state.json +0 -0
  66. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/fixtures/static_state.json +0 -0
  67. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/fixtures/thermostat_hvac.json +0 -0
  68. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/fixtures/thermostat_temp.json +0 -0
  69. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/fixtures/time.json +0 -0
  70. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/ruff.toml +0 -0
  71. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_api_initialization.py +0 -0
  72. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_api_validation.py +0 -0
  73. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_auth.py +0 -0
  74. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_bsblan.py +0 -0
  75. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_configuration.py +0 -0
  76. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_constants.py +0 -0
  77. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_context_manager.py +0 -0
  78. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_device.py +0 -0
  79. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_entity_info.py +0 -0
  80. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_hot_water_additional.py +0 -0
  81. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_hotwater_state.py +0 -0
  82. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_initialization.py +0 -0
  83. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_reset_validation.py +0 -0
  84. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_sensor.py +0 -0
  85. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_static_state.py +0 -0
  86. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_temperature_unit.py +0 -0
  87. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_temperature_validation.py +0 -0
  88. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_time.py +0 -0
  89. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_utility_additional.py +0 -0
  90. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_utility_edge_cases.py +0 -0
  91. {python_bsblan-3.1.1 → python_bsblan-3.1.3}/tests/test_version_errors.py +0 -0
@@ -0,0 +1,205 @@
1
+ # GitHub Copilot Instructions for python-bsblan
2
+
3
+ This repository contains the `python-bsblan` library, an asynchronous Python client for BSB-LAN devices (heating controllers).
4
+
5
+ ## Project Overview
6
+
7
+ - **Language**: Python 3.12+
8
+ - **Type**: Async library using `aiohttp`
9
+ - **Purpose**: Communicate with BSB-LAN devices to read/write heating parameters
10
+ - **License**: MIT
11
+
12
+ ## Code Quality Standards
13
+
14
+ ### Required Before Committing
15
+
16
+ Always run these commands after making changes:
17
+
18
+ ```bash
19
+ # Run all pre-commit hooks (ruff, mypy, pylint, pytest)
20
+ uv run pre-commit run --all-files
21
+ ```
22
+
23
+ ### Pre-commit Includes
24
+ - **Ruff**: Linting and formatting (88 char line limit)
25
+ - **MyPy**: Static type checking
26
+ - **Pylint**: Code analysis
27
+ - **Pytest**: Test execution with coverage
28
+
29
+ ### Coverage Requirements
30
+ - Maintain **95%+ total test coverage**
31
+ - **Patch coverage must be 100%** - all new/modified code must be fully tested
32
+ - GitHub Actions will fail if patch coverage is below 100%
33
+ - Run coverage check: `uv run pytest --cov=src/bsblan --cov-report=term-missing`
34
+
35
+ ## Project Structure
36
+
37
+ ```
38
+ src/bsblan/
39
+ ├── __init__.py # Package exports
40
+ ├── bsblan.py # Main BSBLAN client class
41
+ ├── constants.py # Parameter IDs and mappings
42
+ ├── models.py # Dataclass models for API responses
43
+ ├── utility.py # Helper utilities
44
+ ├── exceptions.py # Custom exceptions
45
+ └── py.typed # PEP-561 marker
46
+
47
+ tests/
48
+ ├── conftest.py # Pytest fixtures
49
+ ├── fixtures/ # JSON test data
50
+ └── test_*.py # Test files
51
+ ```
52
+
53
+ ## Parameter Naming Conventions
54
+
55
+ ### BSB-LAN Parameters
56
+ Parameters are identified by numeric IDs and mapped to readable names in `constants.py`.
57
+
58
+ **Naming Rules:**
59
+ - Use `snake_case` for all parameter names
60
+ - Group related parameters with common prefixes
61
+ - Legionella-related parameters use `legionella_function_*` prefix:
62
+ - `legionella_function_setpoint` (ID: 1645)
63
+ - `legionella_function_periodicity` (ID: 1641)
64
+ - `legionella_function_day` (ID: 1642)
65
+ - `legionella_function_time` (ID: 1644)
66
+ - `legionella_function_dwelling_time` (ID: 1646)
67
+ - DHW (Domestic Hot Water) parameters use `dhw_*` prefix
68
+
69
+ ### Adding New Parameters
70
+
71
+ 1. **Add to `constants.py`**:
72
+ ```python
73
+ BASE_HOT_WATER_PARAMS: Final[dict[str, str]] = {
74
+ "1645": "legionella_function_setpoint", # Parameter ID: name
75
+ }
76
+ ```
77
+
78
+ 2. **Add to model in `models.py`**:
79
+ ```python
80
+ @dataclass
81
+ class HotWaterConfig(DataClassORJSONMixin):
82
+ legionella_function_setpoint: ParameterValue | None = None
83
+ ```
84
+
85
+ 3. **Update method in `bsblan.py`** if the parameter is settable:
86
+ ```python
87
+ async def set_hot_water(
88
+ self,
89
+ legionella_function_setpoint: float | None = None,
90
+ ) -> None:
91
+ ```
92
+
93
+ 4. **Add tests in `tests/test_*.py`**
94
+
95
+ ## Polling Categories
96
+
97
+ Parameters are organized into polling categories based on how frequently they change:
98
+
99
+ ### Fast Poll (State - every update)
100
+ - Current temperatures
101
+ - HVAC action/state
102
+ - Pump states
103
+
104
+ ### Slow Poll (Config - every 5 minutes)
105
+ - Operating modes
106
+ - Setpoints
107
+ - Legionella function settings
108
+ - Time programs
109
+
110
+ ### Static (rarely changes)
111
+ - Device identification
112
+ - Min/max temperature limits
113
+
114
+ ## Data Models
115
+
116
+ ### Model Pattern
117
+ All models use `mashumaro` for JSON serialization:
118
+
119
+ ```python
120
+ from dataclasses import dataclass
121
+ from mashumaro.mixins.orjson import DataClassORJSONMixin
122
+
123
+ @dataclass
124
+ class HotWaterConfig(DataClassORJSONMixin):
125
+ """Hot water configuration parameters."""
126
+ operating_mode: ParameterValue | None = None
127
+ nominal_setpoint: ParameterValue | None = None
128
+ ```
129
+
130
+ ### ParameterValue Structure
131
+ Each parameter returns a `ParameterValue` with:
132
+ - `value`: The actual value
133
+ - `unit`: Unit of measurement
134
+ - `desc`: Human-readable description
135
+ - `dataType`: Data type information
136
+
137
+ ## Async Patterns
138
+
139
+ ### Client Usage
140
+ ```python
141
+ async with BSBLAN(host="192.168.1.100") as client:
142
+ state = await client.state()
143
+ await client.set_hot_water(nominal_setpoint=55.0)
144
+ ```
145
+
146
+ ### Error Handling
147
+ - Use `BSBLANError` for general errors
148
+ - Use `BSBLANConnectionError` for connection issues
149
+ - Always validate only one parameter is set per API call
150
+
151
+ ## Testing Patterns
152
+
153
+ ### Test Structure
154
+ ```python
155
+ @pytest.mark.asyncio
156
+ async def test_set_hot_water(mock_bsblan: BSBLAN) -> None:
157
+ """Test setting BSBLAN hot water state."""
158
+ await mock_bsblan.set_hot_water(nominal_setpoint=60.0)
159
+ mock_bsblan._request.assert_awaited_with(
160
+ base_path="/JS",
161
+ data={"Parameter": "1610", "Value": "60.0", "Type": "1"},
162
+ )
163
+ ```
164
+
165
+ ### Fixtures Location
166
+ Test fixtures (JSON responses) are in `tests/fixtures/`
167
+
168
+ ## Common Tasks
169
+
170
+ ### Adding a New Settable Parameter
171
+
172
+ 1. Add parameter ID mapping in `constants.py`
173
+ 2. Add field to appropriate model in `models.py`
174
+ 3. Add parameter to method signature in `bsblan.py`
175
+ 4. Update docstring with parameter description
176
+ 5. Add state preparation logic in `_prepare_*_state()` method
177
+ 6. Add tests for the new parameter
178
+ 7. Run `uv run pre-commit run --all-files`
179
+
180
+ ### Renaming a Parameter
181
+
182
+ When renaming parameters for consistency:
183
+ 1. Update `constants.py` - parameter mapping
184
+ 2. Update `models.py` - dataclass field
185
+ 3. Update `bsblan.py` - method parameters and state handling
186
+ 4. Update `tests/` - all test files using the parameter
187
+ 5. Update `examples/` - any example code
188
+ 6. Run `uv run pre-commit run --all-files`
189
+
190
+ ## API Versions
191
+
192
+ The library supports BSB-LAN API versions:
193
+ - **v1**: Original API
194
+ - **v3**: Extended API with additional parameters
195
+
196
+ Version-specific parameters are handled in `constants.py` with extension dictionaries.
197
+
198
+ ## Don't Forget
199
+
200
+ - ✅ Run `uv run pre-commit run --all-files` after every change
201
+ - ✅ Maintain 95%+ test coverage
202
+ - ✅ Use type hints on all functions
203
+ - ✅ Add docstrings to public methods
204
+ - ✅ Keep line length under 88 characters
205
+ - ✅ Use consistent parameter naming (check existing patterns)
@@ -17,8 +17,8 @@ jobs:
17
17
  runs-on: ubuntu-latest
18
18
  steps:
19
19
  - name: ⤵️ Check out code from GitHub
20
- uses: actions/checkout@v5.0.0
20
+ uses: actions/checkout@v5.0.1
21
21
  - name: 🏗 Initialize CodeQL
22
- uses: github/codeql-action/init@v3.30.3
22
+ uses: github/codeql-action/init@v3.31.6
23
23
  - name: 🚀 Perform CodeQL Analysis
24
- uses: github/codeql-action/analyze@v3.30.3
24
+ uses: github/codeql-action/analyze@v3.31.6
@@ -16,7 +16,7 @@ jobs:
16
16
  runs-on: ubuntu-latest
17
17
  steps:
18
18
  - name: ⤵️ Check out code from GitHub
19
- uses: actions/checkout@v5.0.0
19
+ uses: actions/checkout@v5.0.1
20
20
  - name: 🚀 Run Label Syncer
21
21
  uses: micnncim/action-label-syncer@v1.3.0
22
22
  env:
@@ -8,7 +8,7 @@ on:
8
8
  workflow_dispatch:
9
9
 
10
10
  env:
11
- DEFAULT_PYTHON: "3.11"
11
+ DEFAULT_PYTHON: "3.13"
12
12
 
13
13
  jobs:
14
14
  codespell:
@@ -16,7 +16,7 @@ jobs:
16
16
  runs-on: ubuntu-latest
17
17
  steps:
18
18
  - name: ⤵️ Check out code from GitHub
19
- uses: actions/checkout@v5.0.0
19
+ uses: actions/checkout@v5.0.1
20
20
  - name: 🏗 Set up uv
21
21
  uses: astral-sh/setup-uv@v6
22
22
  with:
@@ -36,7 +36,7 @@ jobs:
36
36
  runs-on: ubuntu-latest
37
37
  steps:
38
38
  - name: ⤵️ Check out code from GitHub
39
- uses: actions/checkout@v5.0.0
39
+ uses: actions/checkout@v5.0.1
40
40
  - name: 🏗 Set up uv
41
41
  uses: astral-sh/setup-uv@v6
42
42
  with:
@@ -58,7 +58,7 @@ jobs:
58
58
  runs-on: ubuntu-latest
59
59
  steps:
60
60
  - name: ⤵️ Check out code from GitHub
61
- uses: actions/checkout@v5.0.0
61
+ uses: actions/checkout@v5.0.1
62
62
  - name: 🏗 Set up uv
63
63
  uses: astral-sh/setup-uv@v6
64
64
  with:
@@ -102,7 +102,7 @@ jobs:
102
102
  runs-on: ubuntu-latest
103
103
  steps:
104
104
  - name: ⤵️ Check out code from GitHub
105
- uses: actions/checkout@v5.0.0
105
+ uses: actions/checkout@v5.0.1
106
106
  - name: 🏗 Set up uv
107
107
  uses: astral-sh/setup-uv@v6
108
108
  with:
@@ -122,7 +122,7 @@ jobs:
122
122
  runs-on: ubuntu-latest
123
123
  steps:
124
124
  - name: ⤵️ Check out code from GitHub
125
- uses: actions/checkout@v5.0.0
125
+ uses: actions/checkout@v5.0.1
126
126
  - name: 🏗 Set up uv
127
127
  uses: astral-sh/setup-uv@v6
128
128
  with:
@@ -142,7 +142,7 @@ jobs:
142
142
  runs-on: ubuntu-latest
143
143
  steps:
144
144
  - name: ⤵️ Check out code from GitHub
145
- uses: actions/checkout@v5.0.0
145
+ uses: actions/checkout@v5.0.1
146
146
  - name: 🏗 Set up uv
147
147
  uses: astral-sh/setup-uv@v6
148
148
  with:
@@ -8,7 +8,7 @@ on:
8
8
  - published
9
9
 
10
10
  env:
11
- DEFAULT_PYTHON: "3.11"
11
+ DEFAULT_PYTHON: "3.13"
12
12
 
13
13
  jobs:
14
14
  release:
@@ -22,7 +22,7 @@ jobs:
22
22
  id-token: write
23
23
  steps:
24
24
  - name: ⤵️ Check out code from GitHub
25
- uses: actions/checkout@v5.0.0
25
+ uses: actions/checkout@v5.0.1
26
26
  - name: 🏗 Set up uv
27
27
  uses: astral-sh/setup-uv@v6
28
28
  with:
@@ -48,7 +48,7 @@ jobs:
48
48
  verbose: true
49
49
  print-hash: true
50
50
  - name: ✍️ Sign published artifacts
51
- uses: sigstore/gh-action-sigstore-python@v3.0.1
51
+ uses: sigstore/gh-action-sigstore-python@v3.1.0
52
52
  with:
53
53
  inputs: ./dist/*.tar.gz ./dist/*.whl
54
54
  release-signing-artifacts: false
@@ -8,7 +8,7 @@ on:
8
8
  workflow_dispatch:
9
9
 
10
10
  env:
11
- DEFAULT_PYTHON: "3.11"
11
+ DEFAULT_PYTHON: "3.13"
12
12
 
13
13
  jobs:
14
14
  pytest:
@@ -16,10 +16,10 @@ jobs:
16
16
  runs-on: ubuntu-latest
17
17
  strategy:
18
18
  matrix:
19
- python: ["3.11", "3.12"]
19
+ python: ["3.12", "3.13", "3.14"]
20
20
  steps:
21
21
  - name: ⤵️ Check out code from GitHub
22
- uses: actions/checkout@v5.0.0
22
+ uses: actions/checkout@v5.0.1
23
23
  - name: 🏗 Set up uv
24
24
  uses: astral-sh/setup-uv@v6
25
25
  with:
@@ -45,7 +45,7 @@ jobs:
45
45
  needs: pytest
46
46
  steps:
47
47
  - name: ⤵️ Check out code from GitHub
48
- uses: actions/checkout@v5.0.0
48
+ uses: actions/checkout@v5.0.1
49
49
  with:
50
50
  fetch-depth: 0
51
51
  - name: ⬇️ Download coverage data
@@ -8,7 +8,7 @@ on:
8
8
  workflow_dispatch:
9
9
 
10
10
  env:
11
- DEFAULT_PYTHON: "3.11"
11
+ DEFAULT_PYTHON: "3.13"
12
12
 
13
13
  jobs:
14
14
  mypy:
@@ -16,7 +16,7 @@ jobs:
16
16
  runs-on: ubuntu-latest
17
17
  steps:
18
18
  - name: ⤵️ Check out code from GitHub
19
- uses: actions/checkout@v5.0.0
19
+ uses: actions/checkout@v5.0.1
20
20
  - name: 🏗 Set up uv
21
21
  uses: astral-sh/setup-uv@v6
22
22
  with:
@@ -0,0 +1 @@
1
+ 22.21.1
@@ -0,0 +1 @@
1
+ .github/copilot-instructions.md
@@ -0,0 +1 @@
1
+ .github/copilot-instructions.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-bsblan
3
- Version: 3.1.1
3
+ Version: 3.1.3
4
4
  Summary: Asynchronous Python client for BSBLAN API
5
5
  Project-URL: Homepage, https://github.com/liudger/python-bsblan
6
6
  Project-URL: Repository, https://github.com/liudger/python-bsblan
@@ -17,10 +17,11 @@ Classifier: Intended Audience :: Developers
17
17
  Classifier: License :: OSI Approved :: MIT License
18
18
  Classifier: Natural Language :: English
19
19
  Classifier: Programming Language :: Python :: 3
20
- Classifier: Programming Language :: Python :: 3.11
21
20
  Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
22
23
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
- Requires-Python: >=3.11
24
+ Requires-Python: >=3.12
24
25
  Requires-Dist: aiohttp>=3.8.1
25
26
  Requires-Dist: backoff>=2.2.1
26
27
  Requires-Dist: mashumaro>=3.13.1
@@ -26,6 +26,7 @@ from bsblan import (
26
26
  HotWaterState,
27
27
  Info,
28
28
  Sensor,
29
+ SetHotWaterParam,
29
30
  State,
30
31
  StaticState,
31
32
  )
@@ -199,10 +200,10 @@ async def print_hot_water_config(hot_water_config: HotWaterConfig) -> None:
199
200
  hot_water_config.legionella_function, "desc", "N/A"
200
201
  ),
201
202
  "Legionella Setpoint": await get_attribute(
202
- hot_water_config.legionella_setpoint, "value", "N/A"
203
+ hot_water_config.legionella_function_setpoint, "value", "N/A"
203
204
  ),
204
205
  "Legionella Periodicity": await get_attribute(
205
- hot_water_config.legionella_periodicity, "value", "N/A"
206
+ hot_water_config.legionella_function_periodicity, "value", "N/A"
206
207
  ),
207
208
  "Circulation Pump Release": await get_attribute(
208
209
  hot_water_config.dhw_circulation_pump_release, "desc", "N/A"
@@ -271,9 +272,9 @@ async def main() -> None:
271
272
  print("\nSetting temperature to 18°C")
272
273
  await bsblan.thermostat(target_temperature="18")
273
274
 
274
- # Set HVAC mode
275
+ # Set HVAC mode (using raw integer: 0=off, 1=auto, 2=eco, 3=heat)
275
276
  print("Setting HVAC mode to heat")
276
- await bsblan.thermostat(hvac_mode="heat")
277
+ await bsblan.thermostat(hvac_mode=3) # 3 = heat
277
278
 
278
279
  # Get and print sensor information
279
280
  sensor: Sensor = await bsblan.sensor()
@@ -316,7 +317,7 @@ async def main() -> None:
316
317
  dhw_programs = DHWTimeSwitchPrograms(
317
318
  monday="13:00-14:00 ##:##-##:## ##:##-##:##"
318
319
  )
319
- await bsblan.set_hot_water(dhw_time_programs=dhw_programs)
320
+ await bsblan.set_hot_water(SetHotWaterParam(dhw_time_programs=dhw_programs))
320
321
 
321
322
  # Example: Set device time
322
323
  print("\nSetting device time to current system time")
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "python-bsblan"
3
- version = "3.1.1"
3
+ version = "3.1.3"
4
4
  description = "Asynchronous Python client for BSBLAN API"
5
5
  authors = [
6
6
  {name = "Willem-Jan van Rootselaar", email = "liudgervr@gmail.com"}
@@ -17,12 +17,13 @@ classifiers = [
17
17
  "Framework :: AsyncIO",
18
18
  "Intended Audience :: Developers",
19
19
  "Natural Language :: English",
20
- "Programming Language :: Python :: 3.11",
21
20
  "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Programming Language :: Python :: 3.14",
22
23
  "Programming Language :: Python :: 3",
23
24
  "Topic :: Software Development :: Libraries :: Python Modules",
24
25
  ]
25
- requires-python = ">=3.11"
26
+ requires-python = ">=3.12"
26
27
  dependencies = [
27
28
  "aiohttp>=3.8.1",
28
29
  "yarl>=1.7.2",
@@ -176,28 +177,28 @@ build-backend = "hatchling.build"
176
177
  [dependency-groups]
177
178
  dev = [
178
179
  "aresponses==3.0.0",
179
- "bandit==1.8.6",
180
+ "bandit==1.9.2",
180
181
  "black==25.11.0",
181
182
  "blacken-docs==1.20.0",
182
183
  "codespell==2.4.1",
183
184
  "covdefaults==2.3.0",
184
- "coverage==7.10.6",
185
+ "coverage==7.12.0",
185
186
  "darglint==1.8.1",
186
187
  "flake8==7.3.0",
187
188
  "flake8-simplify==0.22.0",
188
189
  # hatch is required to support type hinting and proper packaging of the py.typed file.
189
190
  "hatch>=1.14.1",
190
- "isort==6.0.1",
191
+ "isort==6.1.0",
191
192
  "mypy==1.18.2",
192
- "pre-commit==4.3.0",
193
+ "pre-commit==4.5.0",
193
194
  "pre-commit-hooks==6.0.0",
194
195
  "pylint==3.3.9",
195
196
  "pytest>=8.3.5",
196
197
  "pytest-asyncio==1.3.0",
197
198
  "pytest-cov==7.0.0",
198
- "pyupgrade==3.20.0",
199
- "ruff==0.14.4",
200
- "safety==3.6.1",
199
+ "pyupgrade==3.21.2",
200
+ "ruff==0.14.6",
201
+ "safety==3.7.0",
201
202
  "vulture==2.14",
202
203
  "yamllint==1.37.1",
203
204
  ]
@@ -3,16 +3,20 @@
3
3
  from .bsblan import BSBLAN, BSBLANConfig
4
4
  from .exceptions import BSBLANAuthError, BSBLANConnectionError, BSBLANError
5
5
  from .models import (
6
+ DaySchedule,
6
7
  Device,
7
8
  DeviceTime,
9
+ DHWSchedule,
8
10
  DHWTimeSwitchPrograms,
9
11
  HotWaterConfig,
10
12
  HotWaterSchedule,
11
13
  HotWaterState,
12
14
  Info,
13
15
  Sensor,
16
+ SetHotWaterParam,
14
17
  State,
15
18
  StaticState,
19
+ TimeSlot,
16
20
  )
17
21
 
18
22
  __all__ = [
@@ -21,7 +25,9 @@ __all__ = [
21
25
  "BSBLANConfig",
22
26
  "BSBLANConnectionError",
23
27
  "BSBLANError",
28
+ "DHWSchedule",
24
29
  "DHWTimeSwitchPrograms",
30
+ "DaySchedule",
25
31
  "Device",
26
32
  "DeviceTime",
27
33
  "HotWaterConfig",
@@ -29,6 +35,8 @@ __all__ = [
29
35
  "HotWaterState",
30
36
  "Info",
31
37
  "Sensor",
38
+ "SetHotWaterParam",
32
39
  "State",
33
40
  "StaticState",
41
+ "TimeSlot",
34
42
  ]