feat: Add hardened error handling and retries (#2451)
- Closes #1830 - Closes #2099
This commit is contained in:
committed by
dermotduffy
parent
4bc787e2b7
commit
47bcce93d3
@@ -1,6 +1,5 @@
|
||||
import { hasHAConnectionStateChanged } from '../../ha/has-hass-connection-changed';
|
||||
import { STATE_RUNNING } from 'home-assistant-js-websocket';
|
||||
import { HomeAssistant } from '../../ha/types';
|
||||
import { localize } from '../../localize/localize';
|
||||
import { log } from '../../utils/debug';
|
||||
import { InitializationAspect } from '../initialization-manager';
|
||||
import { CardHASSAPI } from '../types';
|
||||
@@ -28,39 +27,30 @@ export class HASSManager {
|
||||
}
|
||||
|
||||
public setHASS(hass?: HomeAssistant | null): void {
|
||||
if (hasHAConnectionStateChanged(this._hass, hass)) {
|
||||
if (!hass?.connected) {
|
||||
this._api.getMessageManager().setMessageIfHigherPriority({
|
||||
message: localize('error.reconnecting'),
|
||||
icon: 'mdi:lan-disconnect',
|
||||
type: 'connection',
|
||||
dotdotdot: true,
|
||||
});
|
||||
} else {
|
||||
this._api.getMessageManager().resetType('connection');
|
||||
// When HA transitions from "not ready" to "ready" (WebSocket reconnected
|
||||
// AND all integrations finished loading), reinitialize cameras and the
|
||||
// view. This is necessary because event subscriptions (e.g. Frigate
|
||||
// WebSocket subscriptions via hass.connection.subscribeMessage) are tied to
|
||||
// the old connection and are lost when it drops. Without reinitialization,
|
||||
// triggers and thumbnail updates stop working.
|
||||
//
|
||||
// We deliberately wait for hass.config.state === STATE_RUNNING rather than
|
||||
// just hass.connected, because HA exposes the WebSocket before integrations
|
||||
// have finished loading. Triggering re-init too early would race against
|
||||
// integration startup and fail with "Unknown command" on
|
||||
// integration-specific WS calls.
|
||||
if (this._hass && !this._isReady(this._hass) && this._isReady(hass)) {
|
||||
log(
|
||||
this._api.getConfigManager().getCardWideConfig(),
|
||||
'Advanced Camera Card: HA fully ready, reinitializing...',
|
||||
);
|
||||
|
||||
// When the HA WebSocket connection is restored after a drop,
|
||||
// reinitialize cameras and the view. This is necessary because
|
||||
// event subscriptions (e.g. Frigate WebSocket subscriptions via
|
||||
// hass.connection.subscribeMessage) are tied to the old connection
|
||||
// and are lost when it drops. Without reinitialization, triggers
|
||||
// and thumbnail updates stop working.
|
||||
if (this._hass) {
|
||||
log(
|
||||
this._api.getConfigManager().getCardWideConfig(),
|
||||
'Advanced Camera Card: HA connection restored, reinitializing...',
|
||||
);
|
||||
|
||||
this._api
|
||||
.getInitializationManager()
|
||||
.uninitialize(InitializationAspect.CAMERAS);
|
||||
this._api.getCameraManager().destroy();
|
||||
this._api.getInitializationManager().uninitialize(InitializationAspect.VIEW);
|
||||
this._api
|
||||
.getInitializationManager()
|
||||
.uninitialize(InitializationAspect.INITIAL_TRIGGER);
|
||||
}
|
||||
}
|
||||
this._api.getInitializationManager().uninitialize(InitializationAspect.CAMERAS);
|
||||
this._api.getCameraManager().destroy();
|
||||
this._api.getInitializationManager().uninitialize(InitializationAspect.VIEW);
|
||||
this._api
|
||||
.getInitializationManager()
|
||||
.uninitialize(InitializationAspect.INITIAL_TRIGGER);
|
||||
}
|
||||
|
||||
if (!hass) {
|
||||
@@ -79,4 +69,8 @@ export class HASSManager {
|
||||
|
||||
this._stateWatcher.setHASS(oldHass, hass);
|
||||
}
|
||||
|
||||
private _isReady(hass?: HomeAssistant | null): boolean {
|
||||
return !!hass?.connected && hass.config?.state === STATE_RUNNING;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user