Skip to content

feat(public-api): add typed alarm hub accessors to LinkStation#894

Merged
RaHehl merged 3 commits into
uilibs:mainfrom
bluetoothbot:koan/implement-893
Jun 2, 2026
Merged

feat(public-api): add typed alarm hub accessors to LinkStation#894
RaHehl merged 3 commits into
uilibs:mainfrom
bluetoothbot:koan/implement-893

Conversation

@bluetoothbot
Copy link
Copy Markdown
Contributor

@bluetoothbot bluetoothbot commented Jun 2, 2026

Summary

Exposes the well-formed slice of the alarmHub payload (armed, battery, cover, input, output) on LinkStation via read-only typed accessors. Field shapes and the AlarmHubInputType enum members are derived from the alarmHubStatus OpenAPI sub-schema (matching the approach used by the rest of the public-API typing work in #881#885). The opaque alarm_hub dict is retained verbatim so the electrical sub-sections (connector, *MeterStatus, *TerminalStatus, buckboost) — whose keys aren't valid Python identifiers and which the spec itself models as additionalProperties maps — survive untouched alongside any unmodeled/future top-level keys.

Closes #893

Changes

  • Add AlarmHubInputType enum (UnknownValuesEnumMixin) with the full spec set (MOTION, ENTRY, SMOKE, GLASS_BREAK, EMERGENCY_BUTTON, UNKNOWN).
  • Add four ProtectBaseObject sub-models matching the alarmHubStatus sub-schemas: AlarmHubBattery, AlarmHubCover, AlarmHubInput, AlarmHubOutput.
  • Add five read-only accessors on LinkStation: alarm_hub_armed, alarm_hub_battery, alarm_hub_cover, alarm_hub_inputs, alarm_hub_outputs. Each re-derives from the stored dict on every access so it stays live against WS updates; non-integer keys in input/output maps are silently skipped.
  • Re-export the new types from uiprotect.data.
  • Update the dict-opacity comment to explain the surviving electrical-section use case and point at the new accessors.

Test plan

  • New tests/test_api_linkstation_public.py driven by tests/sample_data/sample_link_station_alarm_hub.json covers: armed wire flag; typed battery/cover; int-keyed inputs/outputs with non-numeric keys skipped; configured vs. unconfigured zones; a camera-linked zone; an unknown inputType value falling back to AlarmHubInputType.UNKNOWN; round-trip preservation of unmodeled keys (buckboost, connector, currentMeterStatus); and None/{} returns for a non-alarm-hub LinkStation and for an empty alarmHub section.
  • poetry run pytest — 1428 passed.
  • poetry run .bin/run-mypy — clean against the touched files (5 pre-existing errors in src/uiprotect/cli/backup.py reproduce on main and are unrelated to this change).

Generated by Kōan


Quality Report

Changes: 5 files changed, 379 insertions(+), 3 deletions(-)

Code scan: clean

Tests: failed (FAILED)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

Summary by CodeRabbit

  • New Features
    • Added structured access to alarm hub data for LinkStation devices with new properties for armed status, battery status, cover status, input zones, and output channels
    • Input zones are now categorized by type: motion, entry, smoke, glass break, and emergency button

Expose the well-formed alarmHub payload slice (armed, battery, cover,
input, output) via read-only typed accessors on LinkStation. Field
shapes and the AlarmHubInputType enum members are taken from the
alarmHubStatus OpenAPI sub-schema. The opaque alarm_hub dict is
retained so electrical sub-sections (connector, *MeterStatus,
*TerminalStatus, buckboost) and unmodeled/future keys survive untouched.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 41020510-5f13-4232-98e2-5df8430a6863

📥 Commits

Reviewing files that changed from the base of the PR and between 97eaff1 and 91422e9.

📒 Files selected for processing (5)
  • src/uiprotect/data/__init__.py
  • src/uiprotect/data/public_devices.py
  • src/uiprotect/data/types.py
  • tests/sample_data/sample_link_station_alarm_hub.json
  • tests/test_api_linkstation_public.py

📝 Walkthrough

Walkthrough

This PR adds typed read-only accessors to LinkStation that expose the alarm-hub payload as structured models. It defines a new AlarmHubInputType enum and four sub-models (Battery, Cover, Input, Output), adds five accessor properties to LinkStation that safely re-derive these from the stored opaque dict, exports them from the public API, and validates the implementation with fixtures and comprehensive tests.

Changes

Alarm Hub Typed Accessors on LinkStation

Layer / File(s) Summary
AlarmHubInputType enum definition
src/uiprotect/data/types.py
Defines AlarmHubInputType as a StrEnum covering input zone kinds (motion, entry, smoke, glass break, emergency button) with unknown fallback.
AlarmHub sub-models and LinkStation accessors
src/uiprotect/data/public_devices.py
Adds AlarmHubBattery, AlarmHubCover, AlarmHubInput, AlarmHubOutput sub-models and imports AlarmHubInputType. Updates LinkStation documentation to explain opaque-dict retention for electrical sections while exposing the well-typed slice via five new accessor properties: alarm_hub_armed, alarm_hub_battery, alarm_hub_cover, alarm_hub_inputs, alarm_hub_outputs. Accessors safely return None/empty dicts when absent or unshapen.
Public API exports
src/uiprotect/data/__init__.py
Imports and exports AlarmHubBattery, AlarmHubCover, AlarmHubInput, AlarmHubOutput, AlarmHubInputType via __all__ for public consumer access.
Tests and fixtures
tests/sample_data/sample_link_station_alarm_hub.json, tests/test_api_linkstation_public.py
Adds JSON fixture with representative alarm-hub payloads including inputs/outputs, battery/cover state, and unmodeled electrical keys. Test suite validates accessor types, int-keyed indexing, unknown enum fallback, dict round-trip preservation, and correct behavior when alarm-hub is missing, empty, or present.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • uilibs/uiprotect#877: Both PRs extend the LinkStation public API model; PR #877 adds the base LinkStation endpoints and trigger plumbing, while this PR builds on that foundation by adding typed alarm-hub sub-models and accessor properties.

Suggested reviewers

  • RaHehl
  • bdraco

Poem

🐰 A LinkStation learns to speak so clear,
With Battery, Cover, Input near,
No more opaque dicts cast about—
Typed accessors let the data out!
Alarm hub voices now ring true,

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(public-api): add typed alarm hub accessors to LinkStation' clearly and accurately summarizes the main change: adding typed accessor properties for alarm hub functionality to the LinkStation class.
Linked Issues check ✅ Passed The pull request successfully implements all coding requirements from issue #893: adds AlarmHubInputType enum with all required values (MOTION, ENTRY, SMOKE, GLASS_BREAK, EMERGENCY_BUTTON, UNKNOWN), creates four ProtectBaseObject sub-models (AlarmHubBattery, AlarmHubCover, AlarmHubInput, AlarmHubOutput) with spec-aligned fields, implements five typed read-only properties on LinkStation, exports all new types from uiprotect.data, and includes comprehensive tests with fixture data.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #893 requirements: type definitions, accessor properties, exports, and tests for alarm hub functionality. No unrelated or scope-creeping modifications are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Jun 2, 2026

Merging this PR will not alter performance

✅ 4 untouched benchmarks


Comparing bluetoothbot:koan/implement-893 (91422e9) with main (97eaff1)

Open in CodSpeed

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
src/uiprotect/data/__init__.py 100.00% <ø> (ø)
src/uiprotect/data/public_devices.py 100.00% <100.00%> (ø)
src/uiprotect/data/types.py 99.27% <100.00%> (+<0.01%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@RaHehl RaHehl marked this pull request as ready for review June 2, 2026 20:40
Copilot AI review requested due to automatic review settings June 2, 2026 20:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the public LinkStation model to expose a typed, read-only view of the well-structured alarmHub payload (armed, battery, cover, input, output) while preserving the original opaque alarm_hub dict for electrical/unmodeled sections and future keys.

Changes:

  • Added AlarmHubInputType (UnknownValuesEnumMixin) for typed alarmHub.input[*].inputType handling with unknown-value fallback.
  • Introduced AlarmHubBattery, AlarmHubCover, AlarmHubInput, and AlarmHubOutput sub-models plus LinkStation accessors that re-derive typed views from the raw dict on each access.
  • Added fixture-backed tests covering typed accessors, unknown enum fallback, integer-key filtering, and raw dict preservation of unmodeled keys.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/test_api_linkstation_public.py Adds public-API tests validating typed alarm-hub accessors and raw dict preservation behavior.
tests/sample_data/sample_link_station_alarm_hub.json Adds an alarm-hub sample payload fixture (including unmodeled electrical sections) used by the new tests.
src/uiprotect/data/types.py Adds AlarmHubInputType enum with unknown-value fallback support.
src/uiprotect/data/public_devices.py Adds alarm-hub sub-models and LinkStation typed accessor properties while keeping alarm_hub opaque.
src/uiprotect/data/init.py Re-exports the new alarm-hub types and enum from uiprotect.data.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@RaHehl
Copy link
Copy Markdown
Collaborator

RaHehl commented Jun 2, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@RaHehl RaHehl merged commit 5754734 into uilibs:main Jun 2, 2026
13 checks passed
@bluetoothbot bluetoothbot deleted the koan/implement-893 branch June 2, 2026 22:27
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.

feat(public-api): add typed alarm hub accessors to LinkStation

3 participants