Add refresh_seconds option for live image.

This commit is contained in:
Dermot Duffy
2022-10-09 16:32:42 -07:00
parent 0366ad9736
commit ad872eb3be
7 changed files with 37 additions and 6 deletions
+1 -1
View File
@@ -955,9 +955,9 @@ export class FrigateCard extends LitElement {
throw new Error(localize('error.invalid_configuration')); throw new Error(localize('error.invalid_configuration'));
} }
const configUpgradeable = isConfigUpgradeable(inputConfig);
const parseResult = frigateCardConfigSchema.safeParse(inputConfig); const parseResult = frigateCardConfigSchema.safeParse(inputConfig);
if (!parseResult.success) { if (!parseResult.success) {
const configUpgradeable = isConfigUpgradeable(inputConfig);
const hint = this._getParseErrorPaths(parseResult.error); const hint = this._getParseErrorPaths(parseResult.error);
let upgradeMessage = ''; let upgradeMessage = '';
if (configUpgradeable && getLovelace().mode !== 'yaml') { if (configUpgradeable && getLovelace().mode !== 'yaml') {
+6 -3
View File
@@ -2,7 +2,7 @@ import { HomeAssistant } from 'custom-card-helpers';
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit'; import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
import { customElement, property, state } from 'lit/decorators.js'; import { customElement, property, state } from 'lit/decorators.js';
import liveFrigateStyle from '../../scss/live-frigate.scss'; import liveFrigateStyle from '../../scss/live-frigate.scss';
import { CameraConfig } from '../../types.js'; import { CameraConfig, LiveImageConfig } from '../../types.js';
import { getStateObjOrDispatchError } from './live.js'; import { getStateObjOrDispatchError } from './live.js';
import '../image.js'; import '../image.js';
@@ -14,6 +14,9 @@ export class FrigateCardLiveImage extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public cameraConfig?: CameraConfig; public cameraConfig?: CameraConfig;
@property({ attribute: false })
public liveImageConfig?: LiveImageConfig;
@state() @state()
protected _playing = true; protected _playing = true;
@@ -58,7 +61,7 @@ export class FrigateCardLiveImage extends LitElement {
* @returns A rendered template. * @returns A rendered template.
*/ */
protected render(): TemplateResult | void { protected render(): TemplateResult | void {
if (!this.hass) { if (!this.hass || !this.liveImageConfig) {
return; return;
} }
@@ -67,7 +70,7 @@ export class FrigateCardLiveImage extends LitElement {
return html` <frigate-card-image return html` <frigate-card-image
.imageConfig=${{ .imageConfig=${{
mode: 'camera' as const, mode: 'camera' as const,
refresh_seconds: this._playing ? 1 : 0, refresh_seconds: this._playing ? this.liveImageConfig.refresh_seconds : 0,
}} }}
.hass=${this.hass} .hass=${this.hass}
.cameraConfig=${this.cameraConfig} .cameraConfig=${this.cameraConfig}
+1
View File
@@ -845,6 +845,7 @@ export class FrigateCardLiveProvider extends LitElement {
${ref(this._providerRef)} ${ref(this._providerRef)}
.hass=${this.hass} .hass=${this.hass}
.cameraConfig=${this.cameraConfig} .cameraConfig=${this.cameraConfig}
.liveImageConfig=${this.liveConfig.image}
@frigate-card:media:loaded=${() => { @frigate-card:media:loaded=${() => {
if (provider === 'image') { if (provider === 'image') {
// Only count the media has loaded if the required provider is // Only count the media has loaded if the required provider is
+2
View File
@@ -139,6 +139,8 @@ export const CONF_LIVE_CONTROLS_TIMELINE_WINDOW_SECONDS =
export const CONF_LIVE_CONTROLS_TITLE_MODE = `${CONF_LIVE}.controls.title.mode` as const; export const CONF_LIVE_CONTROLS_TITLE_MODE = `${CONF_LIVE}.controls.title.mode` as const;
export const CONF_LIVE_CONTROLS_TITLE_DURATION_SECONDS = export const CONF_LIVE_CONTROLS_TITLE_DURATION_SECONDS =
`${CONF_LIVE}.controls.title.duration_seconds` as const; `${CONF_LIVE}.controls.title.duration_seconds` as const;
export const CONF_LIVE_IMAGE_REFRESH_SECONDS =
`${CONF_LIVE}.image.refresh_seconds` as const;
export const CONF_LIVE_LAYOUT_FIT = `${CONF_LIVE}.layout.fit` as const; export const CONF_LIVE_LAYOUT_FIT = `${CONF_LIVE}.layout.fit` as const;
export const CONF_LIVE_LAYOUT_POSITION_X = `${CONF_LIVE}.layout.position.x` as const; export const CONF_LIVE_LAYOUT_POSITION_X = `${CONF_LIVE}.layout.position.x` as const;
export const CONF_LIVE_LAYOUT_POSITION_Y = `${CONF_LIVE}.layout.position.y` as const; export const CONF_LIVE_LAYOUT_POSITION_Y = `${CONF_LIVE}.layout.position.y` as const;
+9
View File
@@ -62,6 +62,7 @@ import {
CONF_LIVE_CONTROLS_TITLE_DURATION_SECONDS, CONF_LIVE_CONTROLS_TITLE_DURATION_SECONDS,
CONF_LIVE_CONTROLS_TITLE_MODE, CONF_LIVE_CONTROLS_TITLE_MODE,
CONF_LIVE_DRAGGABLE, CONF_LIVE_DRAGGABLE,
CONF_LIVE_IMAGE_REFRESH_SECONDS,
CONF_LIVE_LAYOUT_FIT, CONF_LIVE_LAYOUT_FIT,
CONF_LIVE_LAYOUT_POSITION_X, CONF_LIVE_LAYOUT_POSITION_X,
CONF_LIVE_LAYOUT_POSITION_Y, CONF_LIVE_LAYOUT_POSITION_Y,
@@ -156,6 +157,7 @@ const MENU_LIVE_CONTROLS_NEXT_PREVIOUS = 'live.controls.next_previous';
const MENU_LIVE_CONTROLS_THUMBNAILS = 'live.controls.thumbnails'; const MENU_LIVE_CONTROLS_THUMBNAILS = 'live.controls.thumbnails';
const MENU_LIVE_CONTROLS_TIMELINE = 'live.controls.timeline'; const MENU_LIVE_CONTROLS_TIMELINE = 'live.controls.timeline';
const MENU_LIVE_CONTROLS_TITLE = 'live.controls.title'; const MENU_LIVE_CONTROLS_TITLE = 'live.controls.title';
const MENU_LIVE_IMAGE = 'live.image';
const MENU_LIVE_LAYOUT = 'live.layout'; const MENU_LIVE_LAYOUT = 'live.layout';
const MENU_MEDIA_VIEWER_CONTROLS = 'media_viewer.controls'; const MENU_MEDIA_VIEWER_CONTROLS = 'media_viewer.controls';
const MENU_MEDIA_VIEWER_CONTROLS_NEXT_PREVIOUS = 'media_viewer.controls.next_previous'; const MENU_MEDIA_VIEWER_CONTROLS_NEXT_PREVIOUS = 'media_viewer.controls.next_previous';
@@ -1594,6 +1596,13 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
CONF_LIVE_LAYOUT_POSITION_X, CONF_LIVE_LAYOUT_POSITION_X,
CONF_LIVE_LAYOUT_POSITION_Y, CONF_LIVE_LAYOUT_POSITION_Y,
)} )}
${this._putInSubmenu(
MENU_LIVE_IMAGE,
true,
'config.live.image.editor_label',
{ name: 'mdi:image-sync' },
html` ${this._renderNumberInput(CONF_LIVE_IMAGE_REFRESH_SECONDS)} `,
)}
</div> </div>
` `
: ''} : ''}
+4
View File
@@ -166,6 +166,10 @@
"editor_label": "Live Controls" "editor_label": "Live Controls"
}, },
"draggable": "Live cameras view can be dragged/swiped", "draggable": "Live cameras view can be dragged/swiped",
"image": {
"editor_label": "Live Image Options",
"refresh_seconds": "Number of seconds after which to refresh live image (0=never)"
},
"layout": "Live Layout", "layout": "Live Layout",
"lazy_load": "Live cameras are lazily loaded", "lazy_load": "Live cameras are lazily loaded",
"lazy_unload": "Live cameras are lazily unloaded", "lazy_unload": "Live cameras are lazily unloaded",
+13 -1
View File
@@ -739,6 +739,11 @@ export type TitleControlConfig = z.infer<typeof titleControlConfigSchema>;
/** /**
* Live view configuration section. * Live view configuration section.
*/ */
const liveImageConfigDefault = {
refresh_seconds: 1,
};
const liveConfigDefault = { const liveConfigDefault = {
auto_play: 'all' as const, auto_play: 'all' as const,
auto_pause: 'never' as const, auto_pause: 'never' as const,
@@ -750,6 +755,7 @@ const liveConfigDefault = {
draggable: true, draggable: true,
transition_effect: 'slide' as const, transition_effect: 'slide' as const,
show_image_during_load: true, show_image_during_load: true,
image: liveImageConfigDefault,
controls: { controls: {
next_previous: { next_previous: {
size: 48, size: 48,
@@ -771,6 +777,11 @@ const liveConfigDefault = {
}, },
}; };
const liveImageConfigSchema = z.object({
refresh_seconds: z.number().min(0).default(liveConfigDefault.image.refresh_seconds),
});
export type LiveImageConfig = z.infer<typeof liveImageConfigSchema>;
const webrtcCardConfigSchema = webrtcCardCameraConfigSchema.passthrough().optional(); const webrtcCardConfigSchema = webrtcCardCameraConfigSchema.passthrough().optional();
export type WebRTCCardConfig = z.infer<typeof webrtcCardConfigSchema>; export type WebRTCCardConfig = z.infer<typeof webrtcCardConfigSchema>;
@@ -799,8 +810,9 @@ export type JSMPEGConfig = z.infer<typeof jsmpegConfigSchema>;
const liveOverridableConfigSchema = z const liveOverridableConfigSchema = z
.object({ .object({
webrtc_card: webrtcCardConfigSchema, image: liveImageConfigSchema.default(liveConfigDefault.image),
jsmpeg: jsmpegConfigSchema, jsmpeg: jsmpegConfigSchema,
webrtc_card: webrtcCardConfigSchema,
controls: z controls: z
.object({ .object({
next_previous: nextPreviousControlConfigSchema next_previous: nextPreviousControlConfigSchema