Skip to content

Release: dev -> master - #119

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

github-actions[bot] wants to merge 105 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
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>
dependabot Bot and others added 9 commits October 5, 2026 20:30
…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>
* ci: remove Claude Code Review workflow

* ci: add automatic PR review job and centralize Claude configuration

Add `claude-review` job that runs on every PR (same-repo via `pull_request`, forks via labeled `pull_request_target`). Move project knowledge to `CLAUDE.md` and consolidate tool permissions in workflow `env` so both jobs (review and `@claude` mentions) share the same configuration. The review job fetches PR head as data only, never executes fork code, and posts findings as inline comments plus a summary via `gh pr comment`.
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 8.0.1 to 8.0.2.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](actions/download-artifact@3e5f45b...9000827)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 8.0.2
  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>
…47 (#163)

Bumps [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) from 1.0.239 to 1.0.247.
- [Release notes](https://github.com/anthropics/claude-code-action/releases)
- [Commits](anthropics/claude-code-action@97c5347...2dca132)

---
updated-dependencies:
- dependency-name: anthropics/claude-code-action
  dependency-version: 1.0.247
  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>
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.1 to 7.0.2.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@043fb46...cf430e0)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.2
  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>
_execute_state_change is documented to return False on failure, but a
Hive API timeout propagated as asyncio.TimeoutError, and a failed
request (for which _call_endpoint returns {}) raised KeyError on
resp["original"]. In Home Assistant this aborts the whole multi-entity
service call (e.g. climate.set_hvac_mode on several TRVs) and bypasses
continue_on_error, since neither is a HomeAssistantError.

Catch the timeout and read the status with .get() so both cases log
and return False as documented. Polling's own timeout handling is
unchanged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Khole <29937485+KJonline@users.noreply.github.com>
…gs (#162)

* refactor: handle incomplete Hive API state responses without error logs

Replace try/except KeyError blocks in heating/hotwater get_mode with early
returns when state.mode is missing. Add _keep_missing_state to PollingMixin
that carries over dropped state keys from the previous poll for up to
MAX_STALE_STATE_POLLS (5) consecutive incomplete responses, logging a
warning per poll listing affected products and missing keys, plus a debug
log showing the keys that did arrive. After the threshold, accept

* fix: only carry over required state keys from an incomplete poll

Keys Hive may legitimately omit (boost, the colour keys) were kept from
the previous poll for up to five polls, which could report stale state
such as boost ON. Carry over only mode, name, status and target, and
drop the per-product count for products that leave the response.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* refactor: handle incomplete Hive API state responses without error logs

Replace try/except KeyError blocks in heating/hotwater get_mode with early
returns when state.mode is missing. Add _keep_missing_state to PollingMixin
that carries over dropped state keys from the previous poll for up to
MAX_STALE_STATE_POLLS (5) consecutive incomplete responses, logging a
warning per poll listing affected products and missing keys, plus a debug
log showing the keys that did arrive. After the threshold, accept

* fix: only carry over required state keys from an incomplete poll

Keys Hive may legitimately omit (boost, the colour keys) were kept from
the previous poll for up to five polls, which could report stale state
such as boost ON. Carry over only mode, name, status and target, and
drop the per-product count for products that leave the response.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: add Makefile targets for local session runner and ignore logs/

Add `run-file`, `run-live`, `simulate-file`, `simulate-live` targets that start background polling sessions (fixture or real account) and write to logs/. Add `logs` (tail -F), `status` (list runners), `stop` (kill runners), and `live-forget` (clear keychain credentials). Ignore logs/ in .gitignore.

* feat: add interactive admin commands to local session runner

Add `make call` target and `--call` flag that send commands to a running session over a Unix socket. Commands include poll, mode/state inspection, drop control, debug/interval adjustment, and device control (set-mode, set-temp, boost, turn-on/off). Device control requires `--allow-writes` flag at session start. Add `make help` target documenting all targets and options. Refactor Makefile to use RUN_FLAGS for shared options and add detailed

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* chore: bump version to 2.0.0.B4

* fix: treat HiveInvalidDeviceAuthentication as reauth-required and handle options=None

Add HiveInvalidDeviceAuthentication to the set of exceptions that trigger
HiveReauthRequired in _retry_login, since rejected device credentials need
a fresh SMS login. Replace config.get("options", {}) with
(config.get("options") or {}) so options=None doesn't raise AttributeError.
Add tests for both cases.

* fix: round RGB channels and retry all login failures before reauth

Change int() to round() in LightColorHandler.get_color so HSV->RGB conversion rounds channels instead of truncating (2.55 -> 3, not 2). Remove retry_on parameter from _retry_with_delays since it always retried Exception anyway. Retry every login failure (network, malformed response, library errors) in _retry_login instead of only HiveApiError, converting all exhausted retries to HiveReauthRequired. Add tests for channel rounding and transient failure
matt-thepie and others added 4 commits October 20, 2026 19:48
Adds examples/example_login.py: password + SMS on the first run, with the machine registered as a trusted device and credentials saved to hive_device.json (owner-only, gitignored); later runs use device_login and skip SMS. Verified live: second run skipped SMS and listed the same 73 devices.

Closes #68, closes #57, closes #63, closes #65, closes #109

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Since 2026-10-20 https://sso.hivehome.com/ emits its bootstrap config as
window.HiveSSOPoolId = 'eu-west-1_...' (single quotes, spaces around =)
instead of window.HiveSSOPoolId="...". _SSO_ASSIGNMENT only matched
double quotes, so get_login_info() raised KeyError, returned None, and
HiveAuthAsync.async_init crashed with AttributeError on self.data.get.
Home Assistant then fails to set up the Hive integration after a restart
(home-assistant/core#187516).

Accept either quote character, requiring the closing quote to match, and
add unit tests for the new format and for mismatched quotes.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Khole <29937485+KJonline@users.noreply.github.com>
…51 (#168)

Bumps [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) from 1.0.247 to 1.0.251.
- [Release notes](https://github.com/anthropics/claude-code-action/releases)
- [Commits](anthropics/claude-code-action@2dca132...374f254)

---
updated-dependencies:
- dependency-name: anthropics/claude-code-action
  dependency-version: 1.0.251
  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>
…RROR (#180)

* fix: log skipped discovery entities with context instead of a blank ERROR

add_list caught KeyError and called _LOGGER.error(error). For a
trvcontrol product with no linked TRVs, get_device_data logged its own
ERROR and then raised a bare KeyError, whose str() is empty, so Home
Assistant showed a second, blank ERROR entry.

get_device_data now raises KeyError with a message and no longer logs,
and add_list logs one WARNING naming the entity type, Hive product type
and id, and the missing key.

Fixes home-assistant/core#172819

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: drop local logging import now imported at module level

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

1 active (outdated) deployment
pypi — 2979710b Deployed Oct 15, 2026 by KJonline via Publish to PyPI #8
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.

5 participants