feat: Trigger cameras on HA bus events (#2512)

This commit is contained in:
Dermot Duffy
2026-06-30 17:45:13 -07:00
committed by dermotduffy
parent 406176eebc
commit 0a36358394
49 changed files with 1376 additions and 269 deletions
+11
View File
@@ -0,0 +1,11 @@
import { isMatch } from 'lodash-es';
// Deep subset match between an HA bus event's payload `data` and a user-
// configured filter. Mirrors HA automation `event_data` semantics: every key in
// `filter` must exist in `data` and recursively match; extra keys in `data` are
// ignored. The `unknown` guard lives here (not at the caller) because HA event
// payloads arrive untyped from the WebSocket bus.
export const matchesEventData = (
filter: Record<string, unknown>,
data: unknown,
): boolean => typeof data === 'object' && data !== null && isMatch(data, filter);
+3 -3
View File
@@ -21,7 +21,7 @@ const isUsableOldState = (state: string | undefined): boolean =>
* produce a single `'new'` or `'end'`.
*
* HA `event.*` entities are different: each fire just updates `state` to a new
* ISO timestamp, with no continuous on/off. Those map to `signal` -- the
* ISO timestamp, with no continuous on/off. Those map to `momentary` -- the
* instantaneous-event discriminator. Transitions are skipped when the old state
* is undefined (entity not previously observed) or `unavailable` (entity
* reconnecting -- new state could be restored, not fresh), or when the new
@@ -29,11 +29,11 @@ const isUsableOldState = (state: string | undefined): boolean =>
*/
export const getTriggerEventType = (
difference: HassStateDifference,
): 'new' | 'end' | 'signal' | null => {
): 'new' | 'end' | 'momentary' | null => {
if (computeDomain(difference.entityID) === 'event') {
return isUsableOldState(difference.oldState?.state) &&
isUsableNewState(difference.newState.state)
? 'signal'
? 'momentary'
: null;
}
return isTriggeredState(difference.newState.state) ? 'new' : 'end';
+2
View File
@@ -243,6 +243,8 @@ export interface HassStateDifference {
newState: HassEntity;
}
export type SubscriptionUnsubscribe = () => Promise<void>;
// *************************************************************************
// Home Assistant API types.
// *************************************************************************