feat: Triggers should fire on startup if entities are in an active state (#2095)

- Closes: #2087
This commit is contained in:
Dermot Duffy
2025-06-08 16:01:26 -07:00
committed by GitHub
parent 2b92f84665
commit 3b4752b257
7 changed files with 166 additions and 5 deletions
@@ -10,6 +10,10 @@ export enum InitializationAspect {
CAMERAS = 'cameras',
MICROPHONE_CONNECT = 'microphone-connect',
VIEW = 'view',
// The initial triggering must happen after both the config is set (and
// cameras initialized), and hass is set.
INITIAL_TRIGGER = 'initial-trigger',
}
// =========================================================================
@@ -60,6 +64,7 @@ export class InitializationManager {
? [InitializationAspect.MICROPHONE_CONNECT]
: []),
InitializationAspect.VIEW,
InitializationAspect.INITIAL_TRIGGER,
]);
}
@@ -131,6 +136,21 @@ export class InitializationManager {
return;
}
if (
!(await this._initializer.initializeIfNecessary(
InitializationAspect.INITIAL_TRIGGER,
async (): Promise<boolean> => {
await this._api.getTriggersManager().handleInitialCameraTriggers();
// Force a card update to continue the initialization.
this._api.getCardElementManager().update();
return true;
},
))
) {
return;
}
this._everInitialized = true;
// When the card is initialized, both the initialization state (will never
+26
View File
@@ -1,5 +1,6 @@
import { orderBy, throttle } from 'lodash-es';
import { CameraEvent } from '../camera-manager/types';
import { isTriggeredState } from '../ha/is-triggered-state';
import { Timer } from '../utils/timer';
import { CardTriggersAPI } from './types';
@@ -34,6 +35,31 @@ export class TriggersManager {
return sorted.length ? sorted[0][0] : null;
}
public handleInitialCameraTriggers = async (): Promise<boolean> => {
const hass = this._api.getHASSManager().getHASS();
let triggered = false;
for (const [cameraID, camera] of this._api
.getCameraManager()
.getStore()
.getCameras()) {
if (
camera
.getConfig()
.triggers.entities.some((entityID) =>
isTriggeredState(hass?.states[entityID]?.state),
)
) {
triggered = true;
await this.handleCameraEvent({
cameraID,
type: 'new',
});
}
}
return triggered;
};
public async handleCameraEvent(ev: CameraEvent): Promise<void> {
const triggersConfig = this._api.getConfigManager().getConfig()?.view.triggers;
const selectedCameraID = this._api.getViewManager().getView()?.camera;
+2
View File
@@ -199,6 +199,7 @@ export interface CardInitializerAPI {
getMessageManager(): MessageManager;
getQueryStringManager(): QueryStringManager;
getResolvedMediaCache(): ResolvedMediaCache;
getTriggersManager(): TriggersManager;
getViewManager(): ViewManager;
}
@@ -272,6 +273,7 @@ export interface CardTriggersAPI {
getConditionStateManager(): ConditionStateManager;
getCardElementManager(): CardElementManager;
getConfigManager(): ConfigManager;
getHASSManager(): HASSManager;
getInteractionManager(): InteractionManager;
getViewManager(): ViewManager;
}
+2 -2
View File
@@ -1,2 +1,2 @@
export const STATES_OFF = ['closed', 'locked', 'off'];
export const STATES_ON = ['open', 'unlocked', 'on'];
export const STATES_OFF = ['off', 'closed', 'locked'];
export const STATES_ON = ['on', 'open', 'unlocked'];