python-bsblan 6.1.0__tar.gz → 6.1.2__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_bsblan-6.1.2/.github/agents/pr-review.agent.md +39 -0
- python_bsblan-6.1.2/.github/agents/tdd-refactor.agent.md +97 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/codeql.yaml +3 -3
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/dependency-review.yaml +1 -1
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/docs.yaml +2 -2
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/labels.yaml +1 -1
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/linting.yaml +4 -4
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/release.yaml +2 -2
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/scorecard.yml +2 -2
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/tests.yaml +6 -6
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/typing.yaml +2 -2
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/PKG-INFO +22 -1
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/README.md +21 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/docs/api/models.md +4 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/docs/getting-started.md +29 -5
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/docs/index.md +2 -1
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/examples/control.py +36 -5
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/pyproject.toml +3 -3
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/src/bsblan/__init__.py +9 -1
- python_bsblan-6.1.2/src/bsblan/_temperature.py +324 -0
- python_bsblan-6.1.2/src/bsblan/_transport.py +221 -0
- python_bsblan-6.1.2/src/bsblan/_validation.py +402 -0
- python_bsblan-6.1.2/src/bsblan/_version.py +77 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/src/bsblan/bsblan.py +201 -604
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/src/bsblan/constants.py +55 -19
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/src/bsblan/exceptions.py +17 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/src/bsblan/models.py +18 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/conftest.py +3 -3
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/dict_version.json +2 -2
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_api_initialization.py +6 -6
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_api_validation.py +48 -48
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_auth.py +2 -2
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_bsblan_edge_cases.py +4 -4
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_circuit.py +66 -64
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_configuration.py +5 -5
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_constants.py +38 -16
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_hot_water_additional.py +76 -76
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_hotwater_state.py +16 -16
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_include_parameter.py +54 -49
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_info.py +3 -3
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_initialization.py +9 -20
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_pps.py +15 -15
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_read_parameters.py +7 -7
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_sensor.py +7 -7
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_state.py +12 -12
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_static_state.py +10 -9
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_temperature_unit.py +23 -23
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_temperature_validation.py +44 -30
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_thermostat.py +3 -3
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_utility_additional.py +2 -2
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_utility_edge_cases.py +3 -3
- python_bsblan-6.1.2/tests/test_version_errors.py +297 -0
- python_bsblan-6.1.0/tests/test_version_errors.py +0 -219
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.editorconfig +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.gitattributes +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/CODE_OF_CONDUCT.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/CONTRIBUTING.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/ISSUE_TEMPLATE/PULL_REQUEST_TEMPLATE.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/SECURITY.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/agents/security-reviewer.agent.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/copilot-instructions.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/hooks/run-validation-after-edits.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/hooks/run_validation_after_edits.sh +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/labels.yml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/prompts/add-parameter.prompt.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/prompts/code-review.prompt.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/release-drafter.yml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/renovate.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/skills/bsblan-parameters/SKILL.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/skills/bsblan-testing/SKILL.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/skills/feature-doc-updates/SKILL.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/auto-approve-renovate.yml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/lock.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/pr-labels.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/release-drafter.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/workflows/stale.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.github/zizmor.yml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.gitignore +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.nvmrc +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.pre-commit-config.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.prettierignore +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/.yamllint +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/AGENTS.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/CLAUDE.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/LICENSE.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/Makefile +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/docs/api/client.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/docs/api/constants.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/docs/api/exceptions.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/examples/discovery.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/examples/fetch_param.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/examples/profile_init.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/examples/ruff.toml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/examples/speed_test.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/mkdocs.yml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/package-lock.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/package.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/sonar-project.properties +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/src/bsblan/py.typed +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/src/bsblan/utility.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/__init__.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/device.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/hot_water_state.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/info.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/password.txt +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/pps_device.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/pps_state.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/pps_static_values.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/sensor.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/state.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/state_circuit2.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/static_state.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/static_state_circuit2.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/thermostat_hvac.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/thermostat_temp.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/fixtures/time.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/ruff.toml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_backoff_retry.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_bsblan.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_context_manager.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_device.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_dhw_time_switch.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_entity_info.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_entity_info_ha.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_heating_schedule.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_reset_validation.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_schedule_models.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_set_heating_schedule.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_set_hot_water_schedule.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_set_hotwater.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_time.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.2}/tests/test_utility.py +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Use when reviewing code changes, diffs, or a branch before opening or updating a pull request. Checks that changes are clean, lean, minimal, idiomatic, well-tested, and ready for review. Trigger phrases: review my changes, review the diff, PR review, is this ready to merge, check before pushing."
|
|
3
|
+
name: "PR Reviewer"
|
|
4
|
+
tools: [read, search, execute]
|
|
5
|
+
argument-hint: "What to review (branch, diff, or files) and any specific concerns"
|
|
6
|
+
user-invocable: true
|
|
7
|
+
---
|
|
8
|
+
You are a meticulous code reviewer for the python-bsblan library. Your job is to
|
|
9
|
+
review pending changes and confirm they are clean, lean, and minimal before a
|
|
10
|
+
pull request — nothing more.
|
|
11
|
+
|
|
12
|
+
## Constraints
|
|
13
|
+
- DO NOT edit, refactor, or write code. You review only; report findings and let the author act.
|
|
14
|
+
- DO NOT suggest features, abstractions, or "improvements" beyond the diff's stated purpose.
|
|
15
|
+
- DO NOT approve changes that add docstrings, comments, or type hints to lines the diff did not already touch.
|
|
16
|
+
- ONLY assess the actual changes (working tree + commits vs the default branch `main`).
|
|
17
|
+
|
|
18
|
+
## Approach
|
|
19
|
+
1. Establish the diff scope. Run `git fetch` if needed, then `git --no-pager diff main...HEAD` and `git --no-pager diff` to capture committed and uncommitted changes.
|
|
20
|
+
2. Read each changed file's surrounding context so feedback reflects real code, not the diff in isolation.
|
|
21
|
+
3. Evaluate against the checklist below, flagging the smallest set of concrete problems.
|
|
22
|
+
4. Verify the repo quality gate when changes are non-trivial: run `uv run pytest` and confirm coverage stays at 95%+ total with 100% patch coverage (via CI/Codecov), and run `SKIP=no-commit-to-branch uv run prek run --all-files`.
|
|
23
|
+
|
|
24
|
+
## Review Checklist
|
|
25
|
+
- **Minimal**: every hunk is necessary for the stated goal; no drive-by edits, reformatting, or unrelated files.
|
|
26
|
+
- **Lean**: no dead code, duplication, unused imports/vars, or speculative error handling for cases that can't occur.
|
|
27
|
+
- **Idiomatic**: follows AGENTS.md conventions — type hints, <=88 char lines, `snake_case` params, pydantic for response models, `@dataclass` for set-param payloads, one `/JS` request per populated parameter.
|
|
28
|
+
- **Correct**: logic is sound; edge cases and version gating align with the constants.
|
|
29
|
+
- **Tested**: new behavior has focused tests; patch coverage is 100%.
|
|
30
|
+
- **Docs**: user-visible changes update README/docs/examples to match the code exactly.
|
|
31
|
+
- **Secure**: no secrets, injection risks, or OWASP Top 10 issues.
|
|
32
|
+
|
|
33
|
+
## Output Format
|
|
34
|
+
Return a single review:
|
|
35
|
+
- **Verdict**: Ready / Needs changes / Blocked.
|
|
36
|
+
- **Must fix**: numbered list, each with `path:line`, the problem, and the minimal fix.
|
|
37
|
+
- **Consider**: optional, lower-priority notes (clearly non-blocking).
|
|
38
|
+
- **Validation**: the commands you ran and their result (pass/fail), or why you skipped them.
|
|
39
|
+
Keep it concise. If the diff is clean, say so plainly without inventing issues.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Improve code quality, apply security best practices, and enhance design whilst maintaining green tests and GitHub issue compliance."
|
|
3
|
+
name: "TDD Refactor Phase - Improve Quality & Security"
|
|
4
|
+
tools: ["github/*", "search/fileSearch", "edit/editFiles", "execute/runTests", "execute/runInTerminal", "execute/getTerminalOutput", "execute/testFailure", "read/readFile", "read/terminalLastCommand", "read/terminalSelection", "read/problems", "search/codebase"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# TDD Refactor Phase - Improve Quality & Security
|
|
8
|
+
|
|
9
|
+
Clean up code, apply security best practices, and enhance design whilst keeping all tests green and maintaining GitHub issue compliance.
|
|
10
|
+
|
|
11
|
+
## Repository Standards
|
|
12
|
+
Follow `AGENTS.md` for python-bsblan conventions and required validation (at minimum: `uv run prek run --all-files` and `uv run pytest`).
|
|
13
|
+
|
|
14
|
+
## GitHub Issue Integration
|
|
15
|
+
|
|
16
|
+
### Issue Completion Validation
|
|
17
|
+
|
|
18
|
+
- **Verify all acceptance criteria met** - Cross-check implementation against GitHub issue requirements
|
|
19
|
+
- **Update issue status** - Mark issue as completed or identify remaining work
|
|
20
|
+
- **Document design decisions** - Comment on issue with architectural choices made during refactor
|
|
21
|
+
- **Link related issues** - Identify technical debt or follow-up issues created during refactoring
|
|
22
|
+
|
|
23
|
+
### Quality Gates
|
|
24
|
+
|
|
25
|
+
- **Definition of Done adherence** - Ensure all issue checklist items are satisfied
|
|
26
|
+
- **Security requirements** - Address any security considerations mentioned in issue
|
|
27
|
+
- **Performance criteria** - Meet any performance requirements specified in issue
|
|
28
|
+
- **Documentation updates** - Update any documentation referenced in issue
|
|
29
|
+
|
|
30
|
+
## Core Principles
|
|
31
|
+
|
|
32
|
+
### Code Quality Improvements
|
|
33
|
+
|
|
34
|
+
- **Remove duplication** - Extract common code into reusable methods or classes
|
|
35
|
+
- **Improve readability** - Use intention-revealing names and clear structure aligned with issue domain
|
|
36
|
+
- **Apply SOLID principles** - Single responsibility, dependency inversion, etc.
|
|
37
|
+
- **Simplify complexity** - Break down large methods, reduce cyclomatic complexity
|
|
38
|
+
|
|
39
|
+
### Security Hardening
|
|
40
|
+
|
|
41
|
+
- **Input validation** - Sanitise and validate all external inputs per issue security requirements
|
|
42
|
+
- **Authentication/Authorisation** - Implement proper access controls if specified in issue
|
|
43
|
+
- **Data protection** - Encrypt sensitive data, use secure connection strings
|
|
44
|
+
- **Error handling** - Avoid information disclosure through exception details
|
|
45
|
+
- **Dependency scanning** - Check for vulnerable packages (`npm audit`, `pip audit`, `dotnet list package --vulnerable`, etc.)
|
|
46
|
+
- **Secrets management** - Use environment variables or a secrets manager; never hard-code credentials
|
|
47
|
+
- **OWASP compliance** - Address security concerns mentioned in issue or related security tickets
|
|
48
|
+
|
|
49
|
+
### Design Excellence
|
|
50
|
+
|
|
51
|
+
- **Design patterns** - Apply appropriate patterns (Repository, Factory, Strategy, etc.)
|
|
52
|
+
- **Dependency injection** - Use DI container or constructor injection for loose coupling
|
|
53
|
+
- **Configuration management** - Externalise settings using environment variables or config files
|
|
54
|
+
- **Logging and monitoring** - Add structured logging appropriate to your stack for issue troubleshooting
|
|
55
|
+
- **Performance optimisation** - Use async/await or equivalent concurrency primitives, efficient collections, caching
|
|
56
|
+
|
|
57
|
+
### Language Best Practices (Polyglot)
|
|
58
|
+
|
|
59
|
+
- **Null safety** - Enable strict null checks (TypeScript), nullable reference types (C#), or Optional types (Java/Kotlin)
|
|
60
|
+
- **Modern language features** - Use pattern matching, destructuring, and idiomatic constructs for your language
|
|
61
|
+
- **Memory & performance** - Apply language-specific optimisations only when profiling reveals a bottleneck
|
|
62
|
+
- **Error handling** - Use specific error/exception types; avoid swallowing errors silently
|
|
63
|
+
|
|
64
|
+
## Security Checklist
|
|
65
|
+
|
|
66
|
+
- [ ] Input validation on all public methods
|
|
67
|
+
- [ ] SQL injection prevention (parameterised queries)
|
|
68
|
+
- [ ] XSS protection for web applications
|
|
69
|
+
- [ ] Authorisation checks on sensitive operations
|
|
70
|
+
- [ ] Secure configuration (no secrets in code)
|
|
71
|
+
- [ ] Error handling without information disclosure
|
|
72
|
+
- [ ] Dependency vulnerability scanning
|
|
73
|
+
- [ ] OWASP Top 10 considerations addressed
|
|
74
|
+
|
|
75
|
+
## Execution Guidelines
|
|
76
|
+
|
|
77
|
+
1. **Review issue completion** - Ensure GitHub issue acceptance criteria are fully met
|
|
78
|
+
2. **Ensure green tests** - All tests must pass before refactoring
|
|
79
|
+
3. **Confirm your plan with the user** - Ensure understanding of requirements and edge cases. NEVER start making changes without user confirmation
|
|
80
|
+
4. **Small incremental changes** - Refactor in tiny steps, running tests frequently
|
|
81
|
+
5. **Apply one improvement at a time** - Focus on single refactoring technique
|
|
82
|
+
6. **Run security analysis** - Use static analysis tools (SonarQube, Checkmarx)
|
|
83
|
+
7. **Document security decisions** - Add comments for security-critical code
|
|
84
|
+
8. **Update issue** - Comment on final implementation and close issue if complete
|
|
85
|
+
|
|
86
|
+
## Refactor Phase Checklist
|
|
87
|
+
|
|
88
|
+
- [ ] GitHub issue acceptance criteria fully satisfied
|
|
89
|
+
- [ ] Code duplication eliminated
|
|
90
|
+
- [ ] Names clearly express intent aligned with issue domain
|
|
91
|
+
- [ ] Methods have single responsibility
|
|
92
|
+
- [ ] Security vulnerabilities addressed per issue requirements
|
|
93
|
+
- [ ] Performance considerations applied
|
|
94
|
+
- [ ] All tests remain green
|
|
95
|
+
- [ ] Code coverage maintained or improved
|
|
96
|
+
- [ ] Issue marked as complete or follow-up issues created
|
|
97
|
+
- [ ] Documentation updated as specified in issue
|
|
@@ -23,10 +23,10 @@ jobs:
|
|
|
23
23
|
security-events: write
|
|
24
24
|
steps:
|
|
25
25
|
- name: ⤵️ Check out code from GitHub
|
|
26
|
-
uses: actions/checkout@
|
|
26
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
27
27
|
with:
|
|
28
28
|
persist-credentials: false
|
|
29
29
|
- name: 🏗 Initialize CodeQL
|
|
30
|
-
uses: github/codeql-action/init@
|
|
30
|
+
uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
|
31
31
|
- name: 🚀 Perform CodeQL Analysis
|
|
32
|
-
uses: github/codeql-action/analyze@
|
|
32
|
+
uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
|
@@ -13,7 +13,7 @@ jobs:
|
|
|
13
13
|
steps:
|
|
14
14
|
- name: ⤵️ Check out code from GitHub
|
|
15
15
|
# yamllint disable-line rule:line-length
|
|
16
|
-
uses: actions/checkout@
|
|
16
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
17
17
|
with:
|
|
18
18
|
persist-credentials: false
|
|
19
19
|
- name: 👀 Dependency review
|
|
@@ -23,11 +23,11 @@ jobs:
|
|
|
23
23
|
runs-on: ubuntu-latest
|
|
24
24
|
steps:
|
|
25
25
|
- name: ⤵️ Check out code from GitHub
|
|
26
|
-
uses: actions/checkout@
|
|
26
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
27
27
|
with:
|
|
28
28
|
persist-credentials: false
|
|
29
29
|
- name: 🏗 Set up uv
|
|
30
|
-
uses: astral-sh/setup-uv@
|
|
30
|
+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
31
31
|
with:
|
|
32
32
|
enable-cache: true
|
|
33
33
|
- name: 🏗 Set up Python ${{ env.DEFAULT_PYTHON }}
|
|
@@ -21,7 +21,7 @@ jobs:
|
|
|
21
21
|
issues: write
|
|
22
22
|
steps:
|
|
23
23
|
- name: ⤵️ Check out code from GitHub
|
|
24
|
-
uses: actions/checkout@
|
|
24
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
25
25
|
with:
|
|
26
26
|
persist-credentials: false
|
|
27
27
|
- name: 🚀 Run Label Syncer
|
|
@@ -21,11 +21,11 @@ jobs:
|
|
|
21
21
|
runs-on: ubuntu-latest
|
|
22
22
|
steps:
|
|
23
23
|
- name: ⤵️ Check out code from GitHub
|
|
24
|
-
uses: actions/checkout@
|
|
24
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
25
25
|
with:
|
|
26
26
|
persist-credentials: false
|
|
27
27
|
- name: 🏗 Set up uv
|
|
28
|
-
uses: astral-sh/setup-uv@
|
|
28
|
+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
29
29
|
with:
|
|
30
30
|
enable-cache: true
|
|
31
31
|
- name: 🏗 Set up Python ${{ env.DEFAULT_PYTHON }}
|
|
@@ -45,11 +45,11 @@ jobs:
|
|
|
45
45
|
runs-on: ubuntu-latest
|
|
46
46
|
steps:
|
|
47
47
|
- name: ⤵️ Check out code from GitHub
|
|
48
|
-
uses: actions/checkout@
|
|
48
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
49
49
|
with:
|
|
50
50
|
persist-credentials: false
|
|
51
51
|
- name: 🏗 Set up uv
|
|
52
|
-
uses: astral-sh/setup-uv@
|
|
52
|
+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
53
53
|
with:
|
|
54
54
|
enable-cache: true
|
|
55
55
|
- name: 🏗 Set up Python ${{ env.DEFAULT_PYTHON }}
|
|
@@ -25,11 +25,11 @@ jobs:
|
|
|
25
25
|
id-token: write
|
|
26
26
|
steps:
|
|
27
27
|
- name: ⤵️ Check out code from GitHub
|
|
28
|
-
uses: actions/checkout@
|
|
28
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
29
29
|
with:
|
|
30
30
|
persist-credentials: false
|
|
31
31
|
- name: 🏗 Set up uv
|
|
32
|
-
uses: astral-sh/setup-uv@
|
|
32
|
+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
33
33
|
with:
|
|
34
34
|
enable-cache: false
|
|
35
35
|
- name: 🏗 Set up Python ${{ env.DEFAULT_PYTHON }}
|
|
@@ -34,7 +34,7 @@ jobs:
|
|
|
34
34
|
steps:
|
|
35
35
|
- name: "Checkout code"
|
|
36
36
|
# yamllint disable-line rule:line-length
|
|
37
|
-
uses: actions/checkout@
|
|
37
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
38
38
|
with:
|
|
39
39
|
persist-credentials: false
|
|
40
40
|
|
|
@@ -66,6 +66,6 @@ jobs:
|
|
|
66
66
|
# Upload the results to GitHub's code scanning dashboard (optional).
|
|
67
67
|
- name: "Upload to code-scanning"
|
|
68
68
|
# yamllint disable-line rule:line-length
|
|
69
|
-
uses: github/codeql-action/upload-sarif@
|
|
69
|
+
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
|
|
70
70
|
with:
|
|
71
71
|
sarif_file: results.sarif
|
|
@@ -29,11 +29,11 @@ jobs:
|
|
|
29
29
|
python: ["3.12", "3.13", "3.14"]
|
|
30
30
|
steps:
|
|
31
31
|
- name: ⤵️ Check out code from GitHub
|
|
32
|
-
uses: actions/checkout@
|
|
32
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
33
33
|
with:
|
|
34
34
|
persist-credentials: false
|
|
35
35
|
- name: 🏗 Set up uv
|
|
36
|
-
uses: astral-sh/setup-uv@
|
|
36
|
+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
37
37
|
with:
|
|
38
38
|
enable-cache: true
|
|
39
39
|
- name: 🏗 Set up Python ${{ matrix.python }}
|
|
@@ -61,14 +61,14 @@ jobs:
|
|
|
61
61
|
pull-requests: read
|
|
62
62
|
steps:
|
|
63
63
|
- name: ⤵️ Check out code from GitHub
|
|
64
|
-
uses: actions/checkout@
|
|
64
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
65
65
|
with:
|
|
66
66
|
fetch-depth: 0
|
|
67
67
|
persist-credentials: false
|
|
68
68
|
- name: ⬇️ Download coverage data
|
|
69
69
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
70
70
|
- name: 🏗 Set up uv
|
|
71
|
-
uses: astral-sh/setup-uv@
|
|
71
|
+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
72
72
|
with:
|
|
73
73
|
enable-cache: true
|
|
74
74
|
- name: 🏗 Set up Python ${{ env.DEFAULT_PYTHON }}
|
|
@@ -84,14 +84,14 @@ jobs:
|
|
|
84
84
|
uv run python -m coverage xml -i
|
|
85
85
|
- name: 🚀 Upload coverage report
|
|
86
86
|
if: env.HAS_CODECOV_TOKEN == 'true'
|
|
87
|
-
uses: codecov/codecov-action@
|
|
87
|
+
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
88
88
|
with:
|
|
89
89
|
fail_ci_if_error: true
|
|
90
90
|
files: coverage.xml
|
|
91
91
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
92
92
|
- name: 🚀 Upload coverage report (tokenless)
|
|
93
93
|
if: env.HAS_CODECOV_TOKEN != 'true' && github.event_name == 'pull_request'
|
|
94
|
-
uses: codecov/codecov-action@
|
|
94
|
+
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
95
95
|
with:
|
|
96
96
|
fail_ci_if_error: false
|
|
97
97
|
files: coverage.xml
|
|
@@ -22,12 +22,12 @@ jobs:
|
|
|
22
22
|
steps:
|
|
23
23
|
- name: ⤵️ Check out code from GitHub
|
|
24
24
|
# yamllint disable-line rule:line-length
|
|
25
|
-
uses: actions/checkout@
|
|
25
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
26
26
|
with:
|
|
27
27
|
persist-credentials: false
|
|
28
28
|
- name: 🏗 Set up uv
|
|
29
29
|
# yamllint disable-line rule:line-length
|
|
30
|
-
uses: astral-sh/setup-uv@
|
|
30
|
+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
31
31
|
with:
|
|
32
32
|
enable-cache: true
|
|
33
33
|
- name: 🏗 Set up Python ${{ env.DEFAULT_PYTHON }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-bsblan
|
|
3
|
-
Version: 6.1.
|
|
3
|
+
Version: 6.1.2
|
|
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
|
|
@@ -83,6 +83,27 @@ asyncio.run(main())
|
|
|
83
83
|
For more examples, including hot water control, multi-circuit support, and
|
|
84
84
|
authentication setup, see the [Getting Started][docs-getting-started] guide.
|
|
85
85
|
|
|
86
|
+
## Compatibility
|
|
87
|
+
|
|
88
|
+
The client automatically detects the device's capabilities during
|
|
89
|
+
`initialize()` and selects a matching configuration based on the BSB-LAN
|
|
90
|
+
JSON-API version reported by the `/JV` endpoint:
|
|
91
|
+
|
|
92
|
+
- **Full configuration** — JSON-API version 2.0 or newer. All features are
|
|
93
|
+
available: multiple heating circuits, hot water control, schedules, sensors,
|
|
94
|
+
and cooling setpoints.
|
|
95
|
+
- **Basic configuration** — JSON-API version 1.x. A reduced, single-circuit
|
|
96
|
+
configuration covering essential heating, hot water, and sensor parameters.
|
|
97
|
+
|
|
98
|
+
The JSON-API version is the documented, firmware-independent compatibility
|
|
99
|
+
signal. The adapter firmware version (from `/JI`) is still retrieved and
|
|
100
|
+
exposed via `device_info`, but it is not used to determine support. A device
|
|
101
|
+
that does not expose `/JV`, or reports a JSON-API version below 1.0, is not
|
|
102
|
+
supported and raises `BSBLANVersionError` during `initialize()`.
|
|
103
|
+
|
|
104
|
+
> Note: basic (JSON-API 1.x) support is best-effort and may not cover every
|
|
105
|
+
> parameter your heating system exposes.
|
|
106
|
+
|
|
86
107
|
## Changelog & Releases
|
|
87
108
|
|
|
88
109
|
This repository keeps a change log using [GitHub's releases][releases]
|
|
@@ -51,6 +51,27 @@ asyncio.run(main())
|
|
|
51
51
|
For more examples, including hot water control, multi-circuit support, and
|
|
52
52
|
authentication setup, see the [Getting Started][docs-getting-started] guide.
|
|
53
53
|
|
|
54
|
+
## Compatibility
|
|
55
|
+
|
|
56
|
+
The client automatically detects the device's capabilities during
|
|
57
|
+
`initialize()` and selects a matching configuration based on the BSB-LAN
|
|
58
|
+
JSON-API version reported by the `/JV` endpoint:
|
|
59
|
+
|
|
60
|
+
- **Full configuration** — JSON-API version 2.0 or newer. All features are
|
|
61
|
+
available: multiple heating circuits, hot water control, schedules, sensors,
|
|
62
|
+
and cooling setpoints.
|
|
63
|
+
- **Basic configuration** — JSON-API version 1.x. A reduced, single-circuit
|
|
64
|
+
configuration covering essential heating, hot water, and sensor parameters.
|
|
65
|
+
|
|
66
|
+
The JSON-API version is the documented, firmware-independent compatibility
|
|
67
|
+
signal. The adapter firmware version (from `/JI`) is still retrieved and
|
|
68
|
+
exposed via `device_info`, but it is not used to determine support. A device
|
|
69
|
+
that does not expose `/JV`, or reports a JSON-API version below 1.0, is not
|
|
70
|
+
supported and raises `BSBLANVersionError` during `initialize()`.
|
|
71
|
+
|
|
72
|
+
> Note: basic (JSON-API 1.x) support is best-effort and may not cover every
|
|
73
|
+
> parameter your heating system exposes.
|
|
74
|
+
|
|
54
75
|
## Changelog & Releases
|
|
55
76
|
|
|
56
77
|
This repository keeps a change log using [GitHub's releases][releases]
|
|
@@ -63,13 +63,37 @@ async def main() -> None:
|
|
|
63
63
|
asyncio.run(main())
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
## Firmware compatibility
|
|
67
|
+
|
|
68
|
+
On the first request the client lazily runs `initialize()`, which detects the
|
|
69
|
+
device's capabilities and selects a matching configuration based on the BSB-LAN
|
|
70
|
+
JSON-API version reported by the `/JV` endpoint:
|
|
71
|
+
|
|
72
|
+
- **Full configuration** — JSON-API version 2.0 or newer. All features are
|
|
73
|
+
available, including multiple heating circuits, hot water control, schedules,
|
|
74
|
+
sensors, and cooling setpoints.
|
|
75
|
+
- **Basic configuration** — JSON-API version 1.x. A reduced, single-circuit
|
|
76
|
+
configuration covering essential heating, hot water, and sensor parameters.
|
|
77
|
+
|
|
78
|
+
The JSON-API version is the documented, firmware-independent compatibility
|
|
79
|
+
signal. The adapter firmware version (from `/JI`) is still retrieved and exposed
|
|
80
|
+
via `device_info`, but it is not used to determine support. A device that does
|
|
81
|
+
not expose `/JV`, or reports a JSON-API version below 1.0, raises
|
|
82
|
+
`BSBLANVersionError`.
|
|
83
|
+
|
|
84
|
+
Basic (JSON-API 1.x) support is best-effort and may not cover every parameter
|
|
85
|
+
your heating system exposes.
|
|
86
|
+
|
|
66
87
|
## Temperature bounds
|
|
67
88
|
|
|
68
|
-
For heating comfort setpoint writes (`target_temperature`),
|
|
69
|
-
the
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
89
|
+
For heating comfort setpoint writes (`target_temperature`), the lower bound is
|
|
90
|
+
the protective (frost) setpoint (`714` for circuit 1, `1014` for circuit 2),
|
|
91
|
+
which allows setpoints down to the frost-protection temperature. The reduced
|
|
92
|
+
setpoint (`712`/`1012`) is exposed as `min_temp` for reference and is used as a
|
|
93
|
+
fallback lower bound only when the protective setpoint is unavailable (for
|
|
94
|
+
example, on PPS devices). The upper heating bound is the comfort maximum (`716`
|
|
95
|
+
for circuit 1 and `1016` for circuit 2) when the device exposes those
|
|
96
|
+
parameters.
|
|
73
97
|
|
|
74
98
|
## Cooling setpoint support
|
|
75
99
|
|
|
@@ -9,7 +9,8 @@ Asynchronous Python client for [BSB-LAN](https://github.com/fredlcore/bsb_lan) d
|
|
|
9
9
|
- Control thermostat settings and hot water parameters
|
|
10
10
|
- Detect optional cooling setpoints for heat/cool range controls
|
|
11
11
|
- Fully typed with PEP 561 support
|
|
12
|
-
-
|
|
12
|
+
- Full parameter support, plus basic support for JSON-API 1.x devices
|
|
13
|
+
- Automatic capability detection via the BSB-LAN JSON-API (`/JV`)
|
|
13
14
|
- Lazy loading with per-section validation
|
|
14
15
|
|
|
15
16
|
## Quick example
|
|
@@ -171,17 +171,24 @@ def print_device_time(device_time: DeviceTime) -> None:
|
|
|
171
171
|
print_attributes("Device Time", attributes)
|
|
172
172
|
|
|
173
173
|
|
|
174
|
-
def print_device_info(
|
|
174
|
+
def print_device_info(
|
|
175
|
+
device: Device,
|
|
176
|
+
info: Info,
|
|
177
|
+
json_api_version: str | None = None,
|
|
178
|
+
) -> None:
|
|
175
179
|
"""Print device and general information.
|
|
176
180
|
|
|
177
181
|
Args:
|
|
178
182
|
device (Device): The device information from the BSBLan device.
|
|
179
183
|
info (Info): The general information from the BSBLan device.
|
|
184
|
+
json_api_version (str | None): The BSB-LAN JSON-API version reported by
|
|
185
|
+
the ``/JV`` endpoint, if available.
|
|
180
186
|
|
|
181
187
|
"""
|
|
182
188
|
attributes = {
|
|
183
189
|
"Device Name": device.name or "N/A",
|
|
184
190
|
"Version": device.version or "N/A",
|
|
191
|
+
"JSON-API Version (/JV)": format_optional(json_api_version),
|
|
185
192
|
"Device Identification": get_attribute(info.device_identification),
|
|
186
193
|
"Bus Type": format_optional(device.bus),
|
|
187
194
|
"Bus Writable Flag": format_optional(device.buswritable),
|
|
@@ -192,6 +199,22 @@ def print_device_info(device: Device, info: Info) -> None:
|
|
|
192
199
|
print_attributes("Device Information", attributes)
|
|
193
200
|
|
|
194
201
|
|
|
202
|
+
def _first_temperature_attribute(static_state: StaticState) -> Any:
|
|
203
|
+
"""Return the first available temperature attribute for unit detection."""
|
|
204
|
+
for attribute in (
|
|
205
|
+
static_state.heating_protective_setpoint,
|
|
206
|
+
static_state.temp_reduced_setpoint,
|
|
207
|
+
static_state.comfort_setpoint_max,
|
|
208
|
+
static_state.min_temp,
|
|
209
|
+
static_state.max_temp,
|
|
210
|
+
static_state.cooling_comfort_setpoint_min,
|
|
211
|
+
static_state.cooling_reduced_setpoint,
|
|
212
|
+
):
|
|
213
|
+
if attribute is not None:
|
|
214
|
+
return attribute
|
|
215
|
+
return None
|
|
216
|
+
|
|
217
|
+
|
|
195
218
|
def print_static_state(static_state: StaticState) -> None:
|
|
196
219
|
"""Print static state information, including heating and cooling bounds.
|
|
197
220
|
|
|
@@ -200,8 +223,10 @@ def print_static_state(static_state: StaticState) -> None:
|
|
|
200
223
|
|
|
201
224
|
"""
|
|
202
225
|
attributes = {
|
|
203
|
-
"
|
|
204
|
-
|
|
226
|
+
"Reduced Setpoint (eco/night)": get_attribute(
|
|
227
|
+
static_state.temp_reduced_setpoint
|
|
228
|
+
),
|
|
229
|
+
"Comfort Setpoint Max": get_attribute(static_state.comfort_setpoint_max),
|
|
205
230
|
"Heating Protective Setpoint": get_attribute(
|
|
206
231
|
static_state.heating_protective_setpoint
|
|
207
232
|
),
|
|
@@ -211,7 +236,9 @@ def print_static_state(static_state: StaticState) -> None:
|
|
|
211
236
|
"Cooling Setpoint Max (reduced)": get_attribute(
|
|
212
237
|
static_state.cooling_reduced_setpoint
|
|
213
238
|
),
|
|
214
|
-
"Temperature Unit": get_attribute(
|
|
239
|
+
"Temperature Unit": get_attribute(
|
|
240
|
+
_first_temperature_attribute(static_state), "unit"
|
|
241
|
+
),
|
|
215
242
|
}
|
|
216
243
|
print_attributes("Static State", attributes)
|
|
217
244
|
|
|
@@ -319,7 +346,11 @@ async def main() -> None:
|
|
|
319
346
|
# Get and print device and general info, including bus metadata
|
|
320
347
|
device: Device = bsblan.device_info or await bsblan.device()
|
|
321
348
|
info: Info = await bsblan.info()
|
|
322
|
-
print_device_info(
|
|
349
|
+
print_device_info(
|
|
350
|
+
device,
|
|
351
|
+
info,
|
|
352
|
+
json_api_version=bsblan.json_api_version,
|
|
353
|
+
)
|
|
323
354
|
|
|
324
355
|
# Get and print state
|
|
325
356
|
state: State = await bsblan.state()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-bsblan"
|
|
3
|
-
version = "6.1.
|
|
3
|
+
version = "6.1.2"
|
|
4
4
|
description = "Asynchronous Python client for BSBLAN API"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Willem-Jan van Rootselaar", email = "liudgervr@gmail.com"}
|
|
@@ -196,7 +196,7 @@ dev = [
|
|
|
196
196
|
# hatch is required to support type hinting and proper packaging of the py.typed file.
|
|
197
197
|
"hatch>=1.14.1",
|
|
198
198
|
"isort==8.0.1",
|
|
199
|
-
"ty==0.0.
|
|
199
|
+
"ty==0.0.44",
|
|
200
200
|
"prek>=0.3.3",
|
|
201
201
|
"pre-commit-hooks==6.0.0",
|
|
202
202
|
"pylint==4.0.5",
|
|
@@ -205,7 +205,7 @@ dev = [
|
|
|
205
205
|
"pytest-cov==7.1.0",
|
|
206
206
|
"pytest-xdist>=3.8.0",
|
|
207
207
|
"pyupgrade==3.21.2",
|
|
208
|
-
"ruff==0.15.
|
|
208
|
+
"ruff==0.15.16",
|
|
209
209
|
"safety==3.7.0",
|
|
210
210
|
"vulture==2.16",
|
|
211
211
|
"yamllint==1.38.0",
|
|
@@ -8,8 +8,14 @@ from .constants import (
|
|
|
8
8
|
HVACActionCategory,
|
|
9
9
|
get_hvac_action_category,
|
|
10
10
|
)
|
|
11
|
-
from .exceptions import
|
|
11
|
+
from .exceptions import (
|
|
12
|
+
BSBLANAuthError,
|
|
13
|
+
BSBLANConnectionError,
|
|
14
|
+
BSBLANError,
|
|
15
|
+
BSBLANVersionError,
|
|
16
|
+
)
|
|
12
17
|
from .models import (
|
|
18
|
+
ApiVersion,
|
|
13
19
|
DaySchedule,
|
|
14
20
|
Device,
|
|
15
21
|
DeviceTime,
|
|
@@ -34,10 +40,12 @@ __all__ = [
|
|
|
34
40
|
"BSBLAN",
|
|
35
41
|
"UNIT_DEVICE_CLASS_MAP",
|
|
36
42
|
"UNIT_STATE_CLASS_MAP",
|
|
43
|
+
"ApiVersion",
|
|
37
44
|
"BSBLANAuthError",
|
|
38
45
|
"BSBLANConfig",
|
|
39
46
|
"BSBLANConnectionError",
|
|
40
47
|
"BSBLANError",
|
|
48
|
+
"BSBLANVersionError",
|
|
41
49
|
"DHWSchedule",
|
|
42
50
|
"DHWTimeSwitchPrograms",
|
|
43
51
|
"DaySchedule",
|