Support (HA) camera snapshots in image view.

This commit is contained in:
Dermot Duffy
2022-02-13 14:02:38 -08:00
parent 6be88fe0b6
commit 5184d0df62
8 changed files with 86 additions and 24 deletions
+37 -12
View File
@@ -7,16 +7,16 @@ import {
ReactiveController,
ReactiveControllerHost,
} from 'lit';
import { HomeAssistant } from 'custom-card-helpers';
import { customElement, property, state } from 'lit/decorators.js';
import { ImageViewConfig } from '../types.js';
import { CameraConfig, ImageViewConfig } from '../types.js';
import { View } from '../view.js';
import { dispatchMediaShowEvent } from '../common.js';
import defaultImage from '../images/frigate-bird-in-sky.jpg';
import imageStyle from '../scss/image.scss';
export class CachedValueController<T> implements ReactiveController {
public value?: T;
@@ -59,6 +59,20 @@ export class CachedValueController<T> implements ReactiveController {
@customElement('frigate-card-image')
export class FrigateCardImage extends LitElement {
@property({ attribute: false })
public hass?: HomeAssistant;
@property({ attribute: false })
protected view?: Readonly<View>;
@property({ attribute: false })
protected cameraConfig?: CameraConfig;
@state()
protected _imageConfig?: ImageViewConfig;
protected _cachedValueController?: CachedValueController<string>;
set imageConfig(imageConfig: ImageViewConfig) {
this._imageConfig = imageConfig;
if (this._cachedValueController) {
@@ -70,19 +84,30 @@ export class FrigateCardImage extends LitElement {
this._getImageSource.bind(this),
);
}
@state()
protected _imageConfig?: ImageViewConfig;
// A new view should trigger an image re-render.
@property({ attribute: false })
protected view?: Readonly<View>;
protected _cachedValueController?: CachedValueController<string>;
/**
* Build a working absolute image URL that the browser will not cache.
* @param url An input URL (may be relative to document origin)
* @returns A new URL (absolute, will not be browser cached).
*/
protected _buildImageURL(url: string): string {
const urlObj = new URL(url, document.baseURI);
urlObj.searchParams.append('_t', String(Date.now()));
return urlObj.toString();
}
protected _getImageSource(): string {
if (this._imageConfig?.src) {
const url = new URL(this._imageConfig.src);
url.searchParams.append('t', String(Date.now()));
return url.toString();
if (this._imageConfig?.mode === 'url' && this._imageConfig?.url) {
return this._buildImageURL(this._imageConfig.url);
} else if (this.hass && this._imageConfig?.mode === 'camera') {
const entity =
this.cameraConfig?.camera_entity || this.cameraConfig?.webrtc_card?.entity;
if (entity) {
const state = this.hass.states[entity];
if (state && state.attributes.entity_picture) {
return this._buildImageURL(state.attributes.entity_picture);
}
}
}
return defaultImage;
}