Fix issue causing image to refetch too frequently.

This commit is contained in:
Dermot Duffy
2022-06-11 15:40:56 -07:00
parent 5da13d82b7
commit 89a90ec1a2
+36 -32
View File
@@ -1,13 +1,13 @@
import { HomeAssistant } from 'custom-card-helpers'; import { HomeAssistant } from 'custom-card-helpers';
import { import {
CSSResultGroup, CSSResultGroup,
html, html,
LitElement, LitElement,
PropertyValues, PropertyValues,
TemplateResult, TemplateResult,
unsafeCSS unsafeCSS
} from 'lit'; } from 'lit';
import { customElement, property, state } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import { createRef, ref, Ref } from 'lit/directives/ref.js'; import { createRef, ref, Ref } from 'lit/directives/ref.js';
import { CachedValueController } from '../cached-value-controller.js'; import { CachedValueController } from '../cached-value-controller.js';
import defaultImage from '../images/frigate-bird-in-sky.jpg'; import defaultImage from '../images/frigate-bird-in-sky.jpg';
@@ -33,27 +33,13 @@ export class FrigateCardImage extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
protected cameraConfig?: CameraConfig; protected cameraConfig?: CameraConfig;
@state() @property({ attribute: false })
protected _imageConfig?: ImageViewConfig; protected imageConfig?: ImageViewConfig;
protected _refImage: Ref<HTMLImageElement> = createRef(); protected _refImage: Ref<HTMLImageElement> = createRef();
protected _cachedValueController?: CachedValueController<string>; protected _cachedValueController?: CachedValueController<string>;
protected _boundVisibilityHandler = this._visibilityHandler.bind(this); protected _boundVisibilityHandler = this._visibilityHandler.bind(this);
/**
* Set the image configuration.
*/
set imageConfig(imageConfig: ImageViewConfig) {
this._imageConfig = imageConfig;
if (this._cachedValueController) {
this._cachedValueController.removeController();
}
this._cachedValueController = new CachedValueController(
this,
this._imageConfig.refresh_seconds,
this._getImageSource.bind(this),
);
}
/** /**
* Get the camera entity for the current camera configuration. * Get the camera entity for the current camera configuration.
@@ -82,7 +68,7 @@ export class FrigateCardImage extends LitElement {
const cameraEntity = this._getCameraEntity(); const cameraEntity = this._getCameraEntity();
const state = cameraEntity ? this.hass.states[cameraEntity] : undefined; const state = cameraEntity ? this.hass.states[cameraEntity] : undefined;
if ( if (
this._imageConfig?.mode === 'camera' && this.imageConfig?.mode === 'camera' &&
(!this.hass.connected || (!this.hass.connected ||
!state || !state ||
Date.now() - Date.parse(state.last_updated) >= HASS_REJECTION_CUTOFF_MS) Date.now() - Date.parse(state.last_updated) >= HASS_REJECTION_CUTOFF_MS)
@@ -93,7 +79,7 @@ export class FrigateCardImage extends LitElement {
if ( if (
changedProps.has('hass') && changedProps.has('hass') &&
changedProps.size == 1 && changedProps.size == 1 &&
this._imageConfig?.mode === 'camera' && this.imageConfig?.mode === 'camera' &&
cameraEntity cameraEntity
) { ) {
if (isHassDifferent(this.hass, changedProps.get('hass'), [cameraEntity])) { if (isHassDifferent(this.hass, changedProps.get('hass'), [cameraEntity])) {
@@ -113,7 +99,25 @@ export class FrigateCardImage extends LitElement {
* @param _changedProps The changed properties * @param _changedProps The changed properties
*/ */
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
protected willUpdate(_changedProps: PropertyValues): void { protected willUpdate(changedProps: PropertyValues): void {
if (changedProps.has('imageConfig')) {
if (this._cachedValueController) {
this._cachedValueController.removeController();
}
if (this.imageConfig) {
this._cachedValueController = new CachedValueController(
this,
this.imageConfig.refresh_seconds,
this._getImageSource.bind(this),
);
}
}
// If the camera changed, immediately discard the old value.
if (changedProps.has('cameraConfig')) {
this._cachedValueController?.clearValue();
}
if (!this._cachedValueController?.value) { if (!this._cachedValueController?.value) {
this._cachedValueController?.updateValue(); this._cachedValueController?.updateValue();
} }
@@ -173,9 +177,9 @@ export class FrigateCardImage extends LitElement {
} }
protected _getImageSource(): string { protected _getImageSource(): string {
if (this._imageConfig?.mode === 'url' && this._imageConfig?.url) { if (this.imageConfig?.mode === 'url' && this.imageConfig?.url) {
return this._buildImageURL(this._imageConfig.url); return this._buildImageURL(this.imageConfig.url);
} else if (this.hass && this._imageConfig?.mode === 'camera') { } else if (this.hass && this.imageConfig?.mode === 'camera') {
const entity = this._getCameraEntity(); const entity = this._getCameraEntity();
if (entity) { if (entity) {
const state = this.hass.states[entity]; const state = this.hass.states[entity];
@@ -206,17 +210,17 @@ export class FrigateCardImage extends LitElement {
dispatchMediaShowEvent(this, ev); dispatchMediaShowEvent(this, ev);
}} }}
@error=${() => { @error=${() => {
if (this._imageConfig?.mode === 'camera') { if (this.imageConfig?.mode === 'camera') {
// In camera mode, the user has likely not made an error, but HA // In camera mode, the user has likely not made an error, but HA
// may be unavailble, so show the stock image. // may be unavailble, so show the stock image.
this._forceStockImage(); this._forceStockImage();
} else if (this._imageConfig?.mode === 'url') { } else if (this.imageConfig?.mode === 'url') {
// In url mode, the user likely specified a URL that cannot be // In url mode, the user likely specified a URL that cannot be
// resolved. Show an error message. // resolved. Show an error message.
dispatchErrorMessageEvent( dispatchErrorMessageEvent(
this, this,
localize('error.image_load_error'), localize('error.image_load_error'),
this._imageConfig, this.imageConfig,
); );
} }
}} }}