Skip to content

Add flexible entity condition support for code slots#785

Merged
raman325 merged 10 commits intomainfrom
feat/entity-condition
Jan 15, 2026
Merged

Add flexible entity condition support for code slots#785
raman325 merged 10 commits intomainfrom
feat/entity-condition

Conversation

@raman325
Copy link
Owner

@raman325 raman325 commented Jan 13, 2026

Breaking change

calendar has been replaced with entity_id as a configuration option. While calendar only supported calendar entities, entity_id supports calendar, binary_sensor, switch, schedule, and input_boolean for more flexibility - users can use a template binary sensor to control PIN access with any logic they want.

Existing config entries will automatically be migrated to use the new key. Any automations or scripts that rely on the original calendar key will need to be updated to use entity_id.

Proposed change

Replace CONF_CALENDAR with flexible CONF_ENTITY_ID that supports multiple entity types as slot conditions:

  • calendar - existing calendar support with rich event display
  • binary_sensor - on/off state controls access
  • switch - on/off state controls access
  • schedule - Home Assistant schedule entities
  • input_boolean - simple on/off toggles

A state of on means access is granted, matching existing calendar behavior.

Capabilities

Backend:

  • Entity selector in config flow with multi-domain support
  • Automatic migration from CONF_CALENDAR to CONF_ENTITY_ID (config entry v1 → v2)
  • State tracking with fallback for late-registering entities
  • WebSocket API returns condition entity info with domain-specific data
  • Async calendar event fetching for "next access" display

Frontend:

  • Rich calendar display preserved (event summary, end time, next event)
  • Calendar "next access" display - shows next upcoming event when inactive
  • Schedule timing info - shows when access starts/ends
  • Domain-specific icons for different entity types
  • Clickable condition entities open Home Assistant's more-info dialog
  • "Access allowed/blocked" status display for non-calendar entities

Known Limitations

  1. Single entity per slot - Only one condition entity per slot. Complex logic can use template binary_sensors.
  2. State tracking optimization not implemented - Tracks all state changes until entities available (minimal performance impact due to early-return guards).
  3. Entity domain detection - Uses entity_id domain prefix for display behavior.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (which adds functionality)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

  • This PR fixes or closes issue:
  • This PR is related to issue: Flexible slot conditions feature request

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings January 13, 2026 17:44
@github-actions github-actions bot added documentation Documentation changes enhancement New feature or request javascript Pull requests that update javascript code python Pull requests that update Python code labels Jan 13, 2026
@codecov
Copy link

codecov bot commented Jan 13, 2026

Codecov Report

❌ Patch coverage is 94.70588% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.02%. Comparing base (865ee91) to head (b34358a).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
custom_components/lock_code_manager/websocket.py 90.80% 8 Missing ⚠️
custom_components/lock_code_manager/__init__.py 94.73% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #785      +/-   ##
==========================================
+ Coverage   95.45%   96.02%   +0.57%     
==========================================
  Files          29       29              
  Lines        2397     2516     +119     
  Branches       83       83              
==========================================
+ Hits         2288     2416     +128     
+ Misses        109      100       -9     
Flag Coverage Δ
python 95.98% <94.61%> (+0.63%) ⬆️
typescript 96.47% <100.00%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...stom_components/lock_code_manager/binary_sensor.py 97.84% <100.00%> (+0.77%) ⬆️
custom_components/lock_code_manager/config_flow.py 100.00% <100.00%> (ø)
custom_components/lock_code_manager/const.py 100.00% <100.00%> (ø)
custom_components/lock_code_manager/entity.py 99.16% <ø> (-0.03%) ⬇️
custom_components/lock_code_manager/helpers.py 100.00% <100.00%> (ø)
ts/const.ts 100.00% <100.00%> (ø)
custom_components/lock_code_manager/__init__.py 96.72% <94.73%> (-0.17%) ⬇️
custom_components/lock_code_manager/websocket.py 95.57% <90.80%> (+0.09%) ⬆️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@raman325 raman325 added the breaking-change Pull requests that break existing functionality label Jan 14, 2026
@raman325 raman325 force-pushed the feat/entity-condition branch from 84728ea to 6d2381a Compare January 15, 2026 02:57
@raman325 raman325 requested a review from Copilot January 15, 2026 03:11
Copy link
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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@raman325 raman325 force-pushed the feat/entity-condition branch from e701fbb to d4b863d Compare January 15, 2026 07:47
@github-actions github-actions bot removed the breaking-change Pull requests that break existing functionality label Jan 15, 2026
@raman325 raman325 added the breaking-change Pull requests that break existing functionality label Jan 15, 2026
@github-actions github-actions bot removed the breaking-change Pull requests that break existing functionality label Jan 15, 2026
@raman325 raman325 added breaking-change Pull requests that break existing functionality and removed breaking-change Pull requests that break existing functionality labels Jan 15, 2026
@github-actions github-actions bot added the breaking-change Pull requests that break existing functionality label Jan 15, 2026
@raman325 raman325 mentioned this pull request Jan 15, 2026
5 tasks
@raman325 raman325 force-pushed the feat/entity-condition branch from 932ee94 to 688a7c2 Compare January 15, 2026 19:23
@raman325 raman325 force-pushed the feat/entity-condition branch from 688a7c2 to d0a238b Compare January 15, 2026 19:43
raman325 and others added 6 commits January 15, 2026 16:37
Replace CONF_CALENDAR with CONF_ENTITY_ID that supports multiple entity types
(calendar, binary_sensor, switch, schedule, input_boolean) as slot conditions.
A state of 'on' means access is granted, matching existing calendar behavior.

Features:
- Config flow entity selector with multi-domain support
- Automatic migration from CONF_CALENDAR to CONF_ENTITY_ID (v1 -> v2)
- Rich calendar display preserved (event summary, end time, next event)
- Domain-specific icons for different entity types
- Clickable condition entities open more-info dialog
- State tracking with fallback for late-registering entities

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
For schedule entities, show next state change time:
- "Until 5:00 PM" when schedule is active
- "Starts at 9:00 AM" when schedule is inactive
- Includes day prefix for non-today events (tomorrow, Mon, etc.)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a calendar condition is inactive, fetch the next upcoming event
and display "Next access" with relative time and event summary.

- Add async _get_next_calendar_event() to fetch events via calendar.get_events
- Pass calendar_next_event through subscription handler
- Add calendar_next to ConditionEntityInfo type
- Update _renderConditionEntity to pass calendar_next to calendar renderer

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TestGetConditionEntityData class with 11 tests for different entity domains
- Add TestGetNextCalendarEvent class with 8 tests for calendar event fetching
- Replace string literals with constants throughout websocket.py and tests
- Use CALENDAR_DOMAIN, SERVICE_GET_EVENTS, STATE_ON/OFF/UNKNOWN/UNAVAILABLE
- Use ATTR_ENTITY_ID for dictionary key access
- Add test entity ID constants for cleaner test code
- Move _LOGGER to top of websocket.py module
- Use split_entity_id() for domain extraction instead of string operations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update the code_slot step description to clearly explain that a slot
is active when all conditions are met: the condition entity is 'on'
AND number of uses (if configured) is greater than 0.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add input_boolean, schedule, and template to after_dependencies
since these are now supported entity domains for slot conditions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
raman325 and others added 2 commits January 15, 2026 16:38
Improve test coverage for provider implementations:

- zwave_js.py: 82% → 99% coverage
  - Client state checks (not ready, not connected, driver not ready)
  - Push subscription retry logic (deferred, retry handler, cleanup)
  - Value update filters (non-usercode events, slot 0, empty values)
  - Exception handling (cache errors, refresh errors, disconnection)
  - Hard refresh triggers for missing/unknown slots

- _base.py: 91% → 95% coverage
  - __eq__ with non-BaseLock objects
  - Event firing with State and dict source data
  - Deferred push subscription when config entry not loaded
  - Config entry state listener same-state handling

Overall coverage: 95.28% → 97.40%

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- const.py: Set ATTR_CALENDAR_NEXT_START and ATTR_CALENDAR_NEXT_SUMMARY
  to reference the base constants instead of duplicating string values
- binary_sensor.py: Capture old entity ID before updating subscription
  so debug log correctly shows "old -> new" transition

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Keep fixtures and conftest for future use. Tests restored to baseline
from main branch (before any PR-specific changes).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@raman325 raman325 force-pushed the feat/entity-condition branch from 22849f5 to 6d26dbf Compare January 15, 2026 21:42
Copy link
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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@raman325 raman325 requested a review from Copilot January 15, 2026 22:30
Frontend changes:
- Fix hasConditions check to include condition_entity field
- Unify condition entity rendering across all domain types (calendar,
  schedule, input_boolean, switch, binary_sensor)
- Add domain badge (Calendar, Schedule, Toggle, etc.) for clarity
- Consistent click behavior: all entities open more-info dialog
- Improved status text: "Not blocking" / "Blocking access"
- Calendar shows: Event name, started time, end time, next event preview
- Schedule shows: end/start time with date context
- Remove duplicate CSS classes (calendar-* and entity-condition-*)
- Fix active state icon color to green for visual clarity

Backend changes:
- Add start_time to calendar condition entity data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@raman325 raman325 force-pushed the feat/entity-condition branch from f131729 to b34358a Compare January 15, 2026 22:30
@raman325 raman325 merged commit 5dc9619 into main Jan 15, 2026
19 checks passed
@raman325 raman325 deleted the feat/entity-condition branch January 15, 2026 22:36
@raman325 raman325 added major Dependabot: major dependency update lcm-major Major version bump and removed major Dependabot: major dependency update labels Jan 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change Pull requests that break existing functionality documentation Documentation changes enhancement New feature or request javascript Pull requests that update javascript code lcm-major Major version bump python Pull requests that update Python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant