Release: dev -> master - #119
github-actions[bot] wants to merge 92 commits into
Conversation
Provides architecture overview, command reference, and development guidance for AI-assisted code editing. Documents async/sync package generation, device discovery pattern, token refresh strategy, and file-based testing workflow.
merg master onto Dev
- Scan interval fixed at 2 minutes (_SCAN_INTERVAL constant); removed updateInterval() method and scan_interval config option from startSession() - Added forceUpdate() to Hive class for power users needing an immediate poll; skips with debug log if another poll is already in flight - Extracted _pollDevices() as the single internal poll call site; used by both updateData() and forceUpdate() - Removed all Hive camera code (discontinued product): camera.py, data/camera.json, getCamera(), getCameraImage/Recording API methods, camera URLs, camera param from request(), deviceList["camera"], Camera_Temp sensor command, and hivecamera PRODUCTS block - Added pytest-asyncio tests for forceUpdate() idle and locked scenarios Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ranch protection - Added dev-release-pr.yml workflow that triggers on dev branch pushes to automatically bump patch version in setup.py and create a release PR to master (skips if PR already exists or commit message contains 'chore: bump version') - Added guard-master.yml workflow that enforces PRs to master branch must originate from dev branch only - Both workflows use GitHub CLI (gh) for PR operations and configure github-actions[bot] as commit
…mic-refresh Refactor: fix scan interval at 2 min, add forceUpdate, remove camera
…mplicit (fall through) returns' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
…lease pipeline, document branching model - Removed python-package.yml (duplicated by ci.yml lint-flake8 job) - Removed release_draft.yml (superseded by automatic release notes in release-on-master.yml) - Removed dev branch trigger from ci.yml (now runs on PRs and master pushes only) - Added release-on-master.yml workflow that reads version from setup.py, creates tag vX.Y.Z and GitHub Release with auto-generated notes on master pushes (skips if tag exists) - Added docs/workflows/README.md documenting the feature
…nges - Added paths filter to master push trigger (src, tests, requirements, setup files, config files, CI workflow itself) - Added identical paths filter to pull_request trigger - Prevents unnecessary CI runs when only docs, README, or other non-code files change
Consolidate GitHub workflows and document release automation
Deletes alarm.py, alarm.json, and removes all alarm-related code from hive.py, session.py, const.py, hive_async_api.py, and hive_api.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Renames all camelCase instance attributes to follow Python snake_case convention: tokenData→token_data, tokenCreated→token_created, tokenExpiry→token_expiry, homeID→home_id, lastUpdate→last_update, scanInterval→scan_interval, userID→user_id, errorList→error_list, updateLock→update_lock, _refreshLock→_refresh_lock, _refreshThreshold→_refresh_threshold, _updateTask→_update_task, _lastPollSlow→_last_poll_slow, _slowPollThreshold→_slow_poll_threshold. Updated across session.py, hive.py, hive_api.py, hive_async_api.py, and hive_helper.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
entityCache→entity_cache, deviceList→device_list, _entityCacheKey→_entity_cache_key, getCachedDevice→get_cached_device, setCachedDevice→set_cached_device, shouldUseCachedData→should_use_cached_data. Updated across session.py, hive_helper.py, heating.py, hotwater.py, light.py, plug.py, action.py, and sensor.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…aclasses
- hivedataclasses.py: update Device to snake_case fields, add EntityConfig
- const.py: replace string-based PRODUCTS/DEVICES with EntityConfig instances,
remove ACTIONS constant, update sensor_commands to use attribute access
- session.py: replace eval() in createDevices with EntityConfig iteration,
update addList to return Device objects with snake_case fields,
update _entity_cache_key to use attribute access
- All device modules: replace device["hiveID"] dict access with device.hive_id
attribute access throughout (hive_id, hive_type, ha_type, hive_name, ha_name,
device_data, parent_device, is_group, device_id, device_name)
- Replace device.setdefault("status", ...) with direct attribute assignment
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes the blanket `# pylint: skip-file` from all source files and replaces it with explicit `# pylint: disable=<codes>` directives that document exactly which rules are suppressed and why: - C0103: public API method names use camelCase (HA integration constraint) - E1101: false positives from the mixin pattern (self.session injected by subclass) - R0914/R0915: complex methods that would need major refactoring to split Also fixes all pylint issues that were genuinely easy to resolve: removes unnecessary else-after-return, converts f-strings in logging calls to lazy % formatting, fixes inconsistent return statements, uses `in` for tuple membership tests, and removes an unnecessary pass statement. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The updateLock attribute was renamed to update_lock in the snake_case refactor. Update the test to match. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Converts remaining camelCase method names to Python snake_case convention: - action.py: getAction→get_action, getState→get_state, setStatusOn→set_status_on, setStatusOff→set_status_off, actionType→action_type - hive_api.py: refreshTokens→refresh_tokens, getLoginInfo→get_login_info, getAll→get_all, getDevices→get_devices, getProducts→get_products, getActions→get_actions, motionSensor→motion_sensor, getWeather→get_weather, setState
Adds camelCase wrapper methods that delegate to the new snake_case methods to maintain compatibility with existing Home Assistant integration code: - session.py: deviceList property, startSession, updateData - heating.py: setMode, setTargetTemperature, setBoostOn, setBoostOff, getClimate - hotwater.py: setMode, setBoostOn, setBoostOff, getWaterHeater - light.py: turnOn, turnOff, getLight - plug.py: turnOn, turnOff, getSwitch - sensor.
…ead of dict construction Replaces manual dict construction in get_* methods across heating.py, hotwater.py, light.py, plug.py, and sensor.py with direct Device attribute assignment. Updates set_cached_device to store and return the Device object itself rather than a separate dict. Adds dict-style access methods (__getitem__, __setitem__, __contains__, get) to Device dataclass with camelCase→snake_case key translation via
Adds special-case handling for action-type entities in addList to construct Device objects directly from the action data dict instead of calling get_device_data (which expects product/device structure). Actions now populate minimal fields (hive_id, hive_name, device_id, device_name, ha_name all set to action name/id, empty device_data, parent_device set to hub_id). Updates action.py get_action to assign status and device_data
…leaner state management - .claude/settings.json, .codex/hooks.json: add PreToolUse hooks to prompt reading GRAPH_REPORT.md before file searches - AGENTS.md, CLAUDE.md: document graphify usage rules (read GRAPH_REPORT.md first, prefer `graphify query/path/explain` over grep, run `graphify update` after code changes) - pyproject.toml: add dev dependencies including graphifyy - action.py: extract _set_action_state helper to deduplicate set
Adds graphify-out/ to exclusion patterns in .github/workflows/ci.yml (via find -not -path) and .pre-commit-config.yaml (via exclude directive) to prevent linting/formatting of generated knowledge graph artifacts. Includes initial graphify output: .graphify_python interpreter marker, GRAPH_REPORT.md with 689 nodes/1578 edges across 44 communities, and JSON cache files for extracted code entities.
…pers - hivedataclasses.py: add SessionTokens and SessionConfig dataclasses to replace Map-based tokens/config dicts - session.py: replace self.tokens/self.config Map instances with SessionTokens/SessionConfig dataclasses, update all attribute access to use dataclass fields - hive_helper.py: move epoch_time from session.py to helper module as standalone function - session.py: add _retry_with_backoff helper to deduplicate retry logic in
…eapi into tidy-up-codebase-v2
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5 to 7. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](codecov/codecov-action@v5...v7) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Khole <29937485+KJonline@users.noreply.github.com>
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6 to 7. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](actions/setup-python@v6...v7) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v6...v7) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Khole <29937485+KJonline@users.noreply.github.com>
* Raise HiveConnectionError when Hive can't be reached at startup A read timeout on the SSO login page made get_login_info() return None, which surfaced as HiveUnknownConfiguration. A failed device fetch during start_session() did the same. Callers could not tell a network blip from a broken configuration, so Home Assistant left the entry in setup error and never retried (home-assistant/core#182752). Add HiveConnectionError, a HiveApiError subclass so existing handlers still catch it, and raise it when the SSO page or the Cognito refresh endpoint can't be reached, and when start_session() has no data because the fetch failed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Update .secrets.baseline line numbers Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](actions/cache@v5...v6) --- updated-dependencies: - dependency-name: actions/cache dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Khole <29937485+KJonline@users.noreply.github.com>
* feat: add holiday mode support (get/set/cancel) Adds get_holiday_mode/set_holiday_mode/cancel_holiday_mode to the async and sync API layers and a HiveHub wrapper accepting datetime start/end. Payload shape (GET/POST/DELETE on /holiday-mode, epoch-ms start/end + temperature) was confirmed via a HAR capture of Hive's own website, since this endpoint was previously unimplemented. Includes the diagnostic scripts used to reverse-engineer it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * test: add live end-to-end script for holiday mode Exercises HiveHub.get_holiday_mode/set_holiday_mode/cancel_holiday_mode against a real Hive account: schedules a 7-day window starting in an hour (verified via GET readback, then cancelled before it can go active), and a second window starting an hour in the past to check whether the backend rejects it (it doesn't -- only the app's UI enforces that, not the API). Prints both UTC and local time so results are directly comparable against the Hive app/website. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * chore: remove live holiday mode test script from tracking Not intended to be committed to the repo -- kept locally only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * chore: remove diagnostic scripts from tracking Not intended to be committed to the repo -- kept locally only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * style: fix ruff-format violation in holiday mode tests Two dict literals in test_hub.py exceeded ruff format's line-wrap threshold, failing the Lint CI check (ruff check itself was clean, since E501 is ignored, but ruff format still wants the wrap). * fix: resolve remaining pylint warnings in holiday mode tests - test_hive_api.py: drop unused url_arg from tuple-unpack, index the two needed values individually (matches existing pattern elsewhere in this file) — fixes W0612 unused-variable - test_hive_async_api.py: remove redundant local 'import json', module already imports it at the top — fixes W0404 reimported --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* fix(packaging): ship the devices and session subpackages
The 2.0 refactor moved the implementation into src/devices/ and
src/session/, but [tool.setuptools] packages still described the 1.x
flat layout, so setuptools never copied either directory into the
build. The published 2.0.0b1 wheel and sdist therefore contain only
api/, helper/, data/, hive.py and the flat deprecation shims — and
every one of those entry points imports from the two missing
subpackages:
apyhiveapi/__init__.py:29 from .hive import Hive
apyhiveapi/hive.py:8 from .devices.action import HiveAction
ModuleNotFoundError: No module named 'apyhiveapi.devices'
All three flavours (apyhiveapi, pyhive, pyhiveapi) fail at import, so
2.0.0b1 is unusable: it pip-installs cleanly and then breaks Home
Assistant at integration setup.
Add the four missing package names, and note in a comment why the list
is explicit rather than find: (package-dir maps two distribution names
onto one source tree) and why the sync flavour is absent from it (it is
generated by the unasync build_py cmdclass).
MANIFEST.in was stale for the same reason: it referenced a top-level
pyhiveapi/ and data/ that have not existed since the move to src/,
which is why SOURCES.txt listed no devices/ or session/ entries.
The test suite could not catch this — it runs against src/ via an
editable install and never touches the built artifact. Add
scripts/verify_dist.py, which installs the wheel into a throwaway venv
and imports every module in every flavour, and wire it into the tests
workflow and both publish workflows so a build like this cannot reach
PyPI again. Verified: it fails on the published 2.0.0b1 wheel and
passes on this build (132 modules, 3 flavours).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* ci: align packaging job build deps with the tests job
verify_dist.py installs the built wheel, which resolves pyquery -> lxml.
The packaging job runs on "3.x" (latest stable), which is exactly where a
prebuilt lxml wheel may not yet exist, so install the same headers the
tests job does rather than depending on wheel availability.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: update repository URLs from Pyhive to Pyhass organization
Update all GitHub repository references from github.com/Pyhive/Pyhiveapi to github.com/Pyhass/Pyhive in pyproject.toml, README.md badges/links, and LICENSE link. Also skip Claude code review workflow for fork PRs since they lack secrets/OIDC tokens for authentication, and enhance the review prompt to use gh CLI commands and MCP inline comment tool for more targeted feedback.
* chore: refresh detect-secrets baseline line numbers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Fetch full git history (fetch-depth: 0) so Claude can run local `git diff` when the GitHub diff API fails on PRs >20k lines (e.g. dev -> master). Update prompt to suggest `git diff origin/BASE...HEAD` as a fallback when `gh pr diff` errors, and require Claude to always post a summary comment even if no issues found or only partial review possible. Add git diff/log/show to allowed tools.
Heredoc/$(...)/piped gh commands are blocked by the allowed-tools list, so the summary comment was silently never posted. Also enable show_full_output temporarily to surface denied tool calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On large PRs Claude fanned the review out to background agents and ended its turn to wait for them; the Action session then exited, the agents were killed and no comment was ever posted. Disallow Agent/Task and allow git fetch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review summaryThis is a large release/aggregation PR (133 files, +22.3k/-8k) that restructures Notable security fixes in this PR (not new issues, call these out as good):
Correctness/async review: no blocking-call-in-async-context or incorrect await/async issues found in the reviewed files. Types/style: the renamed methods consistently use Tests: extensive new coverage was added ( Caveat: given the size of this PR I was not able to exhaustively review every device handler ( |
- Skip release PRs targeting master (huge aggregate diffs, ~$1.70/run) - Remove temporary show_full_output now that reviews post correctly - Rewrite prompt: prioritised checklist with project rules (unasync source, shims, HA camelCase aliases, placeholder AWS creds, PII, 99% coverage), no style nits, de-dupe earlier comments, summary format Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…egration Add HA integration source, user docs and developer docs URLs to the review prompt, and allow WebFetch for those domains only, so API changes are checked against how Home Assistant actually calls them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fork PRs get no secrets on pull_request. pull_request_target runs with secrets but bypasses the fork-approval setting, so gate it on a maintainer adding the claude-review label. PR head is fetched as data only (never checked out or executed) and checkout no longer persists credentials. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uest_target) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fork reviews post as github-actions[bot], so every inline comment and summary now carries a 'Claude Code Review' header, and the summary ends with a link to the workflow run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ults - Add .github/CODEOWNERS so changes under .github/ need maintainer review - Pin every action to a full commit SHA (version kept in a comment for Dependabot) so a moved tag can't swap in different code - Declare contents: read in workflows that relied on the repo default, ahead of switching the default GITHUB_TOKEN to read-only Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The review blocked #153 based on #136's history, but Home Assistant has since moved to aiobotocore 3.x and pins boto3/botocore==1.42.97 in package_constraints.txt. For dependency changes, fetch HA's current constraints and requirements before judging version ranges. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts (#153) The <1.38 ceiling was stale and started conflicting with other Home Assistant integrations (e.g. LLM Vision) that require a newer boto3 with no upper bound, causing HA's requirements installer to fail setup entirely with RequirementsNotFound for any integration that depends on this package. The AWS Cognito IdP auth calls this library relies on (InitiateAuth/RespondToAuthChallenge) are stable across boto3/botocore versions, so there's no need to cap it. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: Khole <29937485+KJonline@users.noreply.github.com>
Replace path filters with a 'changes' job. Path-filtered workflows never report their required checks (Tests (Python 3.x), Coverage), so PRs that didn't touch code sat blocked. Now the workflow always runs and: - Tests (per-version) skip their steps unless .py/src/tests changed (matrix jobs can't be skipped at job level without breaking the required check names) - Coverage (moved in from coverage.yml) skips at job level - Packaging also runs for pyproject.toml/setup.py/MANIFEST.in changes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…39 (#160) Bumps [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) from 1.0.235 to 1.0.239. - [Release notes](https://github.com/anthropics/claude-code-action/releases) - [Commits](anthropics/claude-code-action@756cc22...97c5347) --- updated-dependencies: - dependency-name: anthropics/claude-code-action dependency-version: 1.0.239 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Automated release PR. Contains merged feature PRs and a single version bump.