File: copilot-instructions.md

package info (click to toggle)
python-bsblan 3.1.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,028 kB
  • sloc: python: 4,453; makefile: 3
file content (205 lines) | stat: -rw-r--r-- 5,960 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# GitHub Copilot Instructions for python-bsblan

This repository contains the `python-bsblan` library, an asynchronous Python client for BSB-LAN devices (heating controllers).

## Project Overview

- **Language**: Python 3.12+
- **Type**: Async library using `aiohttp`
- **Purpose**: Communicate with BSB-LAN devices to read/write heating parameters
- **License**: MIT

## Code Quality Standards

### Required Before Committing

Always run these commands after making changes:

```bash
# Run all pre-commit hooks (ruff, mypy, pylint, pytest)
uv run pre-commit run --all-files
```

### Pre-commit Includes
- **Ruff**: Linting and formatting (88 char line limit)
- **MyPy**: Static type checking
- **Pylint**: Code analysis
- **Pytest**: Test execution with coverage

### Coverage Requirements
- Maintain **95%+ total test coverage**
- **Patch coverage must be 100%** - all new/modified code must be fully tested
- GitHub Actions will fail if patch coverage is below 100%
- Run coverage check: `uv run pytest --cov=src/bsblan --cov-report=term-missing`

## Project Structure

```
src/bsblan/
├── __init__.py          # Package exports
├── bsblan.py            # Main BSBLAN client class
├── constants.py         # Parameter IDs and mappings
├── models.py            # Dataclass models for API responses
├── utility.py           # Helper utilities
├── exceptions.py        # Custom exceptions
└── py.typed             # PEP-561 marker

tests/
├── conftest.py          # Pytest fixtures
├── fixtures/            # JSON test data
└── test_*.py            # Test files
```

## Parameter Naming Conventions

### BSB-LAN Parameters
Parameters are identified by numeric IDs and mapped to readable names in `constants.py`.

**Naming Rules:**
- Use `snake_case` for all parameter names
- Group related parameters with common prefixes
- Legionella-related parameters use `legionella_function_*` prefix:
  - `legionella_function_setpoint` (ID: 1645)
  - `legionella_function_periodicity` (ID: 1641)
  - `legionella_function_day` (ID: 1642)
  - `legionella_function_time` (ID: 1644)
  - `legionella_function_dwelling_time` (ID: 1646)
- DHW (Domestic Hot Water) parameters use `dhw_*` prefix

### Adding New Parameters

1. **Add to `constants.py`**:
   ```python
   BASE_HOT_WATER_PARAMS: Final[dict[str, str]] = {
       "1645": "legionella_function_setpoint",  # Parameter ID: name
   }
   ```

2. **Add to model in `models.py`**:
   ```python
   @dataclass
   class HotWaterConfig(DataClassORJSONMixin):
       legionella_function_setpoint: ParameterValue | None = None
   ```

3. **Update method in `bsblan.py`** if the parameter is settable:
   ```python
   async def set_hot_water(
       self,
       legionella_function_setpoint: float | None = None,
   ) -> None:
   ```

4. **Add tests in `tests/test_*.py`**

## Polling Categories

Parameters are organized into polling categories based on how frequently they change:

### Fast Poll (State - every update)
- Current temperatures
- HVAC action/state
- Pump states

### Slow Poll (Config - every 5 minutes)
- Operating modes
- Setpoints
- Legionella function settings
- Time programs

### Static (rarely changes)
- Device identification
- Min/max temperature limits

## Data Models

### Model Pattern
All models use `mashumaro` for JSON serialization:

```python
from dataclasses import dataclass
from mashumaro.mixins.orjson import DataClassORJSONMixin

@dataclass
class HotWaterConfig(DataClassORJSONMixin):
    """Hot water configuration parameters."""
    operating_mode: ParameterValue | None = None
    nominal_setpoint: ParameterValue | None = None
```

### ParameterValue Structure
Each parameter returns a `ParameterValue` with:
- `value`: The actual value
- `unit`: Unit of measurement
- `desc`: Human-readable description
- `dataType`: Data type information

## Async Patterns

### Client Usage
```python
async with BSBLAN(host="192.168.1.100") as client:
    state = await client.state()
    await client.set_hot_water(nominal_setpoint=55.0)
```

### Error Handling
- Use `BSBLANError` for general errors
- Use `BSBLANConnectionError` for connection issues
- Always validate only one parameter is set per API call

## Testing Patterns

### Test Structure
```python
@pytest.mark.asyncio
async def test_set_hot_water(mock_bsblan: BSBLAN) -> None:
    """Test setting BSBLAN hot water state."""
    await mock_bsblan.set_hot_water(nominal_setpoint=60.0)
    mock_bsblan._request.assert_awaited_with(
        base_path="/JS",
        data={"Parameter": "1610", "Value": "60.0", "Type": "1"},
    )
```

### Fixtures Location
Test fixtures (JSON responses) are in `tests/fixtures/`

## Common Tasks

### Adding a New Settable Parameter

1. Add parameter ID mapping in `constants.py`
2. Add field to appropriate model in `models.py`
3. Add parameter to method signature in `bsblan.py`
4. Update docstring with parameter description
5. Add state preparation logic in `_prepare_*_state()` method
6. Add tests for the new parameter
7. Run `uv run pre-commit run --all-files`

### Renaming a Parameter

When renaming parameters for consistency:
1. Update `constants.py` - parameter mapping
2. Update `models.py` - dataclass field
3. Update `bsblan.py` - method parameters and state handling
4. Update `tests/` - all test files using the parameter
5. Update `examples/` - any example code
6. Run `uv run pre-commit run --all-files`

## API Versions

The library supports BSB-LAN API versions:
- **v1**: Original API
- **v3**: Extended API with additional parameters

Version-specific parameters are handled in `constants.py` with extension dictionaries.

## Don't Forget

- ✅ Run `uv run pre-commit run --all-files` after every change
- ✅ Maintain 95%+ test coverage
- ✅ Use type hints on all functions
- ✅ Add docstrings to public methods
- ✅ Keep line length under 88 characters
- ✅ Use consistent parameter naming (check existing patterns)