Merge pull request #1505 from dermotduffy/automations-init

Don't run automations prior to initialization .
This commit is contained in:
Dermot Duffy
2024-08-26 15:00:44 -07:00
committed by GitHub
5 changed files with 60 additions and 11 deletions
+8 -3
View File
@@ -27,11 +27,16 @@ export class AutomationsManager {
} }
public execute(): void { public execute(): void {
const hass = this._api.getHASSManager().getHASS(); if (
!this._api.getHASSManager().hasHASS() ||
// Never execute automations if the card hasn't finished initializing, as
// it could cause a view change when camera loads are not finished.
// See: https://github.com/dermotduffy/frigate-hass-card/issues/1407
!this._api.getInitializationManager().isInitializedMandatory() ||
// Never execute automations if there's an error (as our automation loop // Never execute automations if there's an error (as our automation loop
// avoidance -- which shows as an error -- would not work!). // avoidance -- which shows as an error -- would not work!).
if (!hass || this._api.getMessageManager().hasErrorMessage()) { this._api.getMessageManager().hasErrorMessage()
) {
return; return;
} }
+4
View File
@@ -17,6 +17,10 @@ export class HASSManager {
return this._hass; return this._hass;
} }
public hasHASS(): boolean {
return !!this._hass;
}
public getStateWatcher(): StateWatcherSubscriptionInterface { public getStateWatcher(): StateWatcherSubscriptionInterface {
return this._stateWatcher; return this._stateWatcher;
} }
+1
View File
@@ -59,6 +59,7 @@ export interface CardAutomationsAPI {
getCardElementManager(): CardElementManager; getCardElementManager(): CardElementManager;
getConditionsManager(): ConditionsManager; getConditionsManager(): ConditionsManager;
getHASSManager(): HASSManager; getHASSManager(): HASSManager;
getInitializationManager(): InitializationManager;
getMessageManager(): MessageManager; getMessageManager(): MessageManager;
} }
@@ -1,6 +1,6 @@
import { afterEach, describe, expect, it, vi } from 'vitest'; import { afterEach, describe, expect, it, vi } from 'vitest';
import { AutomationsManager } from '../../src/card-controller/automations-manager.js'; import { AutomationsManager } from '../../src/card-controller/automations-manager.js';
import { createCardAPI, createHASS } from '../test-utils.js'; import { createCardAPI } from '../test-utils.js';
import { ActionType } from '../../src/config/types.js'; import { ActionType } from '../../src/config/types.js';
import { AuxillaryActionConfig } from '../../src/card-controller/actions/types.js'; import { AuxillaryActionConfig } from '../../src/card-controller/actions/types.js';
@@ -34,9 +34,25 @@ describe('AutomationsManager', () => {
expect(api.getActionsManager().executeActions).not.toBeCalled(); expect(api.getActionsManager().executeActions).not.toBeCalled();
}); });
it('should do nothing without being initialized', () => {
const api = createCardAPI();
vi.mocked(api.getHASSManager().hasHASS).mockReturnValue(true);
vi.mocked(api.getInitializationManager().isInitializedMandatory).mockReturnValue(
false,
);
const automationsManager = new AutomationsManager(api);
automationsManager.execute();
expect(api.getActionsManager().executeActions).not.toBeCalled();
});
it('should do nothing without automations', () => { it('should do nothing without automations', () => {
const api = createCardAPI(); const api = createCardAPI();
vi.mocked(api.getHASSManager().getHASS).mockReturnValue(createHASS()); vi.mocked(api.getHASSManager().hasHASS).mockReturnValue(true);
vi.mocked(api.getInitializationManager().isInitializedMandatory).mockReturnValue(
true,
);
const automationsManager = new AutomationsManager(api); const automationsManager = new AutomationsManager(api);
automationsManager.execute(); automationsManager.execute();
@@ -46,7 +62,10 @@ describe('AutomationsManager', () => {
it('should execute actions', () => { it('should execute actions', () => {
const api = createCardAPI(); const api = createCardAPI();
vi.mocked(api.getHASSManager().getHASS).mockReturnValue(createHASS()); vi.mocked(api.getHASSManager().hasHASS).mockReturnValue(true);
vi.mocked(api.getInitializationManager().isInitializedMandatory).mockReturnValue(
true,
);
const automationsManager = new AutomationsManager(api); const automationsManager = new AutomationsManager(api);
automationsManager.addAutomations([automation]); automationsManager.addAutomations([automation]);
@@ -77,7 +96,11 @@ describe('AutomationsManager', () => {
it('should execute actions_not', () => { it('should execute actions_not', () => {
const api = createCardAPI(); const api = createCardAPI();
vi.mocked(api.getHASSManager().getHASS).mockReturnValue(createHASS()); vi.mocked(api.getHASSManager().hasHASS).mockReturnValue(true);
vi.mocked(api.getInitializationManager().isInitializedMandatory).mockReturnValue(
true,
);
vi.mocked(api.getConditionsManager().evaluateConditions).mockReturnValue(false); vi.mocked(api.getConditionsManager().evaluateConditions).mockReturnValue(false);
const automationsManager = new AutomationsManager(api); const automationsManager = new AutomationsManager(api);
@@ -90,7 +113,10 @@ describe('AutomationsManager', () => {
it('should prevent automation loops', () => { it('should prevent automation loops', () => {
const api = createCardAPI(); const api = createCardAPI();
vi.mocked(api.getHASSManager().getHASS).mockReturnValue(createHASS()); vi.mocked(api.getHASSManager().hasHASS).mockReturnValue(true);
vi.mocked(api.getInitializationManager().isInitializedMandatory).mockReturnValue(
true,
);
const automationsManager = new AutomationsManager(api); const automationsManager = new AutomationsManager(api);
automationsManager.addAutomations([automation, not_automation]); automationsManager.addAutomations([automation, not_automation]);
@@ -130,7 +156,10 @@ describe('AutomationsManager', () => {
it('should delete automations', () => { it('should delete automations', () => {
const api = createCardAPI(); const api = createCardAPI();
vi.mocked(api.getHASSManager().getHASS).mockReturnValue(createHASS()); vi.mocked(api.getHASSManager().hasHASS).mockReturnValue(true);
vi.mocked(api.getInitializationManager().isInitializedMandatory).mockReturnValue(
true,
);
const automationsManager = new AutomationsManager(api); const automationsManager = new AutomationsManager(api);
automationsManager.addAutomations([automation]); automationsManager.addAutomations([automation]);
@@ -21,6 +21,7 @@ describe('HASSManager', () => {
it('should have null hass on construction', () => { it('should have null hass on construction', () => {
const manager = new HASSManager(createCardAPI()); const manager = new HASSManager(createCardAPI());
expect(manager.getHASS()).toBeNull(); expect(manager.getHASS()).toBeNull();
expect(manager.hasHASS()).toBeFalsy();
}); });
it('should get state watcher', () => { it('should get state watcher', () => {
@@ -28,6 +29,15 @@ describe('HASSManager', () => {
expect(manager.getStateWatcher()).toEqual(expect.any(StateWatcher)); expect(manager.getStateWatcher()).toEqual(expect.any(StateWatcher));
}); });
it('should get hass after set', () => {
const manager = new HASSManager(createCardAPI());
const hass = createHASS();
manager.setHASS(hass);
expect(manager.getHASS()).toBe(hass);
expect(manager.hasHASS()).toBeTruthy();
});
it('should set light or dark mode upon setting hass', () => { it('should set light or dark mode upon setting hass', () => {
const api = createCardAPI(); const api = createCardAPI();
const manager = new HASSManager(api); const manager = new HASSManager(api);