Repository navigation
fix: a Calendar Condition sensor follows its calendar to the next event, matching its user by name or slot - #1789
Merged
Conversation
The blueprint matched its condition template against the event that was current when the sensor loaded, because a state-based template entity renders its variables once at startup. On a shared booking calendar the first guest's sensor stayed on through later bookings and the next guest's never turned on until template entities were reloaded. Make it trigger-based, which renders the variables after every trigger: the calendar's state or attributes changing, Home Assistant starting, template entities reloading, and once a minute as a backstop for a user renamed just after their booking starts and for templates that read the time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Entire-Checkpoint: 11565057bfa8
…es empty A trigger-based template entity skips the update when a variable fails to render, so the sensor kept its last state. The documented slot_number example goes empty when the event ends and int raised, leaving a past guest's sensor on. int(0) finds no user instead. Guard the shared-calendar example with name_state and, since name_state is empty when the name entity can't be found and an empty string is in every message. Document that a condition template that raises keeps the sensor where it was, and double the backslash in the regex examples. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Entire-Checkpoint: 1f9f13140e49
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1789 +/- ##
=======================================
Coverage 98.89% 98.89%
=======================================
Files 72 72
Lines 10299 10299
Branches 569 569
=======================================
Hits 10185 10185
Misses 114 114
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
Replace the free-form condition template with a Match choice (any event, the user's name in the title or description, or "slot N" in the description) and optional Match text, evaluated in the state template. A state-based template entity tracks everything its state template reads, so the sensor follows the calendar and a rename at once, and a render error makes it unavailable, which leaves the PIN inactive. Match defaults to "not set" rather than being required: a blueprint instance missing an input raises MissingInput, which the template integration doesn't catch, so it would stop every template entity from loading. A sensor from before Match that never set a condition template keeps working as any event; one that set its own is unavailable until it has a Match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Entire-Checkpoint: cd13dbe43947
A plain substring match turned one user's sensor on for another user's event: test1 during test10's, Al during Alice's. Normalise punctuation and spacing on both sides and match the name between word boundaries. Say what a render error does: the sensor goes unknown, not unavailable, because the availability template takes precedence. Update the two BLUEPRINTS.md passages that still described a templated slot number for the Calendar Condition. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Entire-Checkpoint: 3d6a10be98e9
1 of 5 tasks
The blueprint still declares the condition template input so an old sensor that set one goes unavailable instead of failing to load, so the inputs table documents it and the breaking note no longer says it is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Entire-Checkpoint: 7300de11f870
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Breaking change
The Calendar Condition blueprint no longer takes a free-form condition template. It has a Match choice and an optional Match text field instead. After re-importing the blueprint:
{{ true }}meant.{{ true }}: the blueprint can't read the stored template back to tell a default from a real filter.What to do: re-import the blueprint, then open each Calendar Condition sensor and choose a Match. For a rule the choices don't cover, make your own template binary sensor and use it as the condition entity.
Proposed change
The Calendar Condition blueprint matched its user against the event that was current when the sensor loaded. A state-based template entity renders its
variablesonce at startup (homeassistant/components/template/template_entity.py:478-481), and the event attributes, the user's name and the condition result were all variables. On one shared booking calendar, the first guest's sensor stayed on through every later booking, and the next guest's never turned on until template entities were reloaded.The fix: everything that can change now lives in the
state:template. Home Assistant tracks every entity a state template reads, so the sensor updates as soon as the calendar moves to another event or the user is renamed, with no timer. Ifstate:fails to render, the sensor goesunknown: with an availability template present, Home Assistant sets the state to none rather than making the sensor unavailable. Onlyonmakes a PIN active, so that leaves it inactive.That rules out a free-form condition template: a blueprint
!inputreplaces a whole YAML value (annotatedyaml/input.py:43-56), so a user's template can only reach the event throughvariables, which are frozen. The template is replaced by:slot 3, for the user on slot 3 (slot 12doesn't count asslot 1)Match text narrows any of them: the title or description must also contain it. Names match as whole words and ignore case, so
test1doesn't matchtest10andAldoesn't matchAlice. Match text is a plain substring, socleanfindsCleaning. A user the sensor can't find (no such slot, or the name entity unavailable and so without attributes) matches no event. An empty name would otherwise be in every title.Why Match has a default of "not set" rather than being required: a blueprint instance missing an input raises
MissingInput, aHomeAssistantError(blueprint/errors.py:73). The template integration only skips entries that raisevol.Invalid(template/config.py:444), so one stale sensor without Match would stop every template entity in the user's configuration from loading. I reproduced this with a second, unrelated template entity. The default instead keeps old sensors that never filtered working, and fails closed only for those that did.An earlier version of this PR made the blueprint trigger-based with a one-minute backstop. Review found it failed open, keeping its last state when a template errored, and it needed the timer. This version needs neither.
Tests:
tests/test_blueprint_behavior.pytest10isn'ttest1), names between punctuation,slot 12not matchingslot 1, title versus description, text narrowing a name match.unknown, noton.{{ true }}→ unavailable; choosing a Match brings a sensor with an old template back.Mutations checked, each failing at least one test: substring name matching, the empty-name guard, the exact slot match, case-folding, Match text, treating an old template as any event, the availability check on Match, and freezing the event title in
variables(the original bug).Type of change
Additional information
🤖 Generated with Claude Code