Skip to content

Release: dev -> master - #119

Open
github-actions[bot] wants to merge 92 commits into
masterfrom
dev
Open

github-actions[bot] wants to merge 92 commits into
masterfrom
dev

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Automated release PR. Contains merged feature PRs and a single version bump.

KJonline and others added 7 commits April 25, 2026 16:01
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.
- 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
Comment thread src/api/hive_api.py Fixed
KJonline and others added 22 commits April 25, 2026 18:53
…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
dependabot Bot and others added 7 commits June 21, 2026 23:32
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>
KJonline and others added 5 commits September 26, 2026 22:53
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>
@claude

claude Bot commented Sep 27, 2026

Copy link
Copy Markdown

Review summary

This is a large release/aggregation PR (133 files, +22.3k/-8k) that restructures pyhiveapi into src/{api,devices,helper,session}/ packages with a snake_case public API and camelCase back-compat shims (helper/compat_aliases.py, top-level src/*.py deprecation shims). Given the size, I focused on the security- and correctness-critical paths: Cognito/SRP auth (api/hive_auth.py, api/hive_auth_async.py, api/device_registration.py, api/srp_crypto.py), session lifecycle (session/auth.py, session/discovery.py, session/polling.py), HTTP clients (api/hive_api.py, api/hive_async_api.py), and helper/const.py/helper/hivedataclasses.py.

Notable security fixes in this PR (not new issues, call these out as good):

  • All eval() calls on string-encoded device/action configs (sensor.py, session.py) are gone, replaced by the typed EntityConfig dataclass in helper/const.py.
  • requests.get(..., verify=False) + urllib3.disable_warnings(...) in get_login_info has been removed — TLS verification is no longer disabled.
  • botocore.exceptions.ClientError handling previously compared err.__class__.__name__ against strings like "UserNotFoundException"/"NotAuthorizedException", which can never match (all boto3 ClientErrors share that class name) — the specific error is only available via err.response["Error"]["Code"]. This is fixed throughout hive_auth_async.py/device_registration.py, so username/password/2FA error mapping now actually works.
  • refresh_token's auth_params = ({"REFRESH_TOKEN": token},) (a 1-tuple containing a dict, due to a trailing comma) is fixed to a plain dict in hive_auth.py.
  • aiohttp.ClientSession() is now created lazily inside the event loop (HiveApiAsync._get_websession) instead of in the synchronous __init__, avoiding the "no running event loop" pitfall.
  • sys.excepthook/sys.settrace global overrides in hive.py are removed.

Correctness/async review: no blocking-call-in-async-context or incorrect await/async issues found in the reviewed files. session/discovery.py:open_file and the old openFile both do synchronous file I/O, but that's pre-existing (file-mode/test path only) and unchanged by this PR. SRP retry/lock logic in session/auth.py (_retry_with_backoff, hive_refresh_tokens's double-checked locking) and session/polling.py (update_data/get_devices) looks correct.

Types/style: the renamed methods consistently use snake_case, type hints use modern X | None syntax, and the new modules (session/*.py, devices/*.py, helper/device_handler_base.py) are fully annotated on public methods. Didn't spot unused imports in the files reviewed.

Tests: extensive new coverage was added (tests/unit/test_hive_auth_async.py, test_hive_auth.py, test_srp_crypto.py, test_device_registration.py, test_session_auth.py, test_discovery.py, test_polling.py, test_compat_aliases.py, etc.), including cases for the fixed Cognito error-code handling and the SRP crypto helpers.

Caveat: given the size of this PR I was not able to exhaustively review every device handler (devices/*.py) or every test file line-by-line; I concentrated on auth/session/HTTP plumbing since that's where the highest-impact bugs would live. I didn't find any new correctness or security regressions in what I reviewed, so no inline comments.

KJonline and others added 11 commits September 27, 2026 10:08
- 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>

This branch was successfully deployed

1 active (outdated) deployment
pypi — 91d96b47 Deployed Sep 27, 2026 by KJonline via Publish to PyPI #6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants