From ea9d3b48090293bd7839a626490c0d7f6847b2be Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Sun, 23 Jan 2022 21:01:55 -0800 Subject: [PATCH 1/3] Separate timeout_seconds from refresh_seconds . --- README.md | 54 +++++++++++------- src/card.ts | 105 ++++++++++++++++++++++------------- src/common.ts | 16 ------ src/components/live.ts | 26 +-------- src/patches/ha-hls-player.ts | 9 +-- src/types.ts | 6 +- 6 files changed, 107 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index 53ecfb13..3b58fa62 100644 --- a/README.md +++ b/README.md @@ -135,12 +135,12 @@ view: | Option | Default | Overridable | Description | | - | - | - | - | | `default` | `live` | :heavy_multiplication_x: | The view to show in the card by default. See [views](#views) below.| -| `timeout_seconds` | | :heavy_multiplication_x: | A numbers of seconds of inactivity after which the card will reset to the default configured view. Inactivity is defined as lack of interaction with the Frigate menu.| -| `actions` | | :heavy_multiplication_x: | Actions to use for all views, individual actions may be overriden by view-specific actions. See [actions](#actions) below.| -| `update_force` | `false` | :heavy_multiplication_x: | Whether card updates/refreshes should ignore playing media and human interaction. See [card updates](#card-updates) below for behavior and usecases.| +| `timeout_seconds` | `300` | :heavy_multiplication_x: | A numbers of seconds of inactivity after human interaction, after which the card will reset to the default configured view (i.e. 'screensaver' functionality). Inactivity is defined as lack of mouse/touch interaction with the Frigate card. If the default view occurs sooner (e.g. via `update_seconds` or manually) the timer will be stopped. `0` means disable this functionality. | +| `update_seconds` | `0` | :heavy_multiplication_x: | A number of seconds after which to automatically update/refresh the default view. See [card updates](#card-updates) below for behavior and usecases. If the default view occurs sooner (e.g. manually) the timer will start over. `0` disables this functionality.| +| `update_force` | `false` | :heavy_multiplication_x: | Whether automated card updates/refreshes should ignore human interaction. See [card updates](#card-updates) below for behavior and usecases.| | `update_entities` | | :heavy_multiplication_x: | **YAML only**: A list of entity ids that should cause the view to reset to the default. See [card updates](#card-updates) below for behavior and usecases.| | `update_cycle_camera` | `false` | :heavy_multiplication_x: | When set to `true` the selected camera is cycled on each default view change. | - +| `actions` | | :heavy_multiplication_x: | Actions to use for all views, individual actions may be overriden by view-specific actions. See [actions](#actions) below.| ### Menu Options All configuration is under: @@ -412,8 +412,6 @@ item, that has both of the following parameters set: | `conditions` | | :heavy_multiplication_x: | A set of conditions that must evaluate to `true` in order for the overrides to be applied. See [Frigate Card Conditions](#frigate-card-conditions). | | `overrides` | | :heavy_multiplication_x: |Configuration overrides to be applied. Any configuration parameter described in this documentation as 'Overridable' is supported. | - - ### Using WebRTC WebRTC support blends the use of the ultra-realtime [WebRTC live @@ -1099,31 +1097,34 @@ image: ## Card Refreshes -Three sets of flags govern when the card will automatically re-render in the +Four sets of flags govern when the card will automatically refresh in the absence of human interaction. -The following table describes the behavior these 3 flags have. +The following table describes the behavior these flags have. ### Card Update Truth Table -| `view.timeout_seconds` | `view.update_force` | `view.update_entities` | Behavior | -| :-: | :-: | :-: | - | -| Unset or `0` | *(Any value)* | Unset | Card will not automatically refresh. | -| Unset or `0` | `false` | *(Any entity)* | Card will reload default view when entity state changes, unless media is playing. | -| Unset or `0` | `true` | *(Any entity)* | Card will reload default view when entity state changes. | -| `X` seconds | `false` | Unset | Card will reload default view `X` seconds after human interaction stops, unless media is playing. | -| `X` seconds | `false` | *(Any entity)* | Card will reload default view `X` seconds after human interaction stops or when entity state changes -- in both cases unless media is playing. | -| `X` seconds | `true` | Unset | Card will reload default view every `X` seconds. | -| `X` seconds | `true` | *(Any entity)* | Card will reload default view every `X` seconds or when entity state changes. | +| `view.update_seconds` | `view.timeout_seconds` | `view.update_force` | `view.update_entities` | Behavior | +| :-: | :-: | :-: | :-: | - | +| `0` | `0` | *(Any value)* | Unset | Card will not automatically refresh. | +| `0` | `0` | *(Any value)* | *(Any entity)* | Card will reload default view when entity state changes. | +| `0` | `X` seconds | *(Any value)* | Unset | Card will reload default view `X` seconds after human interaction stops. | +| `0` | `X` seconds | `false` | *(Any entity)* | Card will reload default view `X` seconds after human interaction stops, or when entity state changes (as long as human interaction has not occurred in the last `X` seconds). | +| `0` | `X` seconds | `true` | *(Any entity)* | Card will reload default view `X` seconds after human interaction stops or when entity state changes. | +| `Y` seconds | `0` | *(Any value)* | Unset | Card will reload default view every `Y` seconds. | +| `Y` seconds | `0` | *(Any value)* | *(Any entity)* | Card will reload default view every `Y` seconds, or whenever entity state changes. | +| `Y` seconds | `X` seconds | `false` | Unset | Card will reload default view `X` seconds after human interaction stops, and every `Y` seconds (as long as there hasn't been human interaction in the last `X` seconds). | +| `Y` seconds | `X` seconds | `false` | *(Any entity)* | Card will reload default view `X` seconds after human interaction stops, and every `Y` seconds or whenever entity state changes (in both cases -- as long as there hasn't been human interaction in the last `X` seconds). | +| `Y` seconds | `X` seconds | `true` | Unset | Card will reload default view `X` seconds after human interaction stops, and every `Y` seconds. | +| `Y` seconds | `X` seconds | `true` | *(Any entity)* | Card will reload default view `X` seconds after human interaction stops, and every `Y` seconds or whenever entity state changes. | ### Usecases For Automated Refreshes - * Refreshing the `live` thumbnails periodically. + * Refreshing the `live` thumbnails every 30 seconds. ```yaml view: default: live - timeout_seconds: 30 - force: true + update_seconds: 30 ``` * Using `clip` or `snapshot` as the default view (for the most recent clip or snapshot respectively) and having the card automatically refresh (to fetch a @@ -1135,6 +1136,19 @@ view: update_entities: - binary_sensor.office_person_motion ``` + * Cycle the live view of the camera every 60 seconds +```yaml +view: + update_cycle_camera: true + update_seconds: 60 +``` + * Return to the most recent clip of the default camera 30 seconds after human + interaction with the card stops. +```yaml +view: + default: clip + timeout_seconds: 30 +``` ## Troubleshooting diff --git a/src/card.ts b/src/card.ts index 05e5e336..b230f392 100644 --- a/src/card.ts +++ b/src/card.ts @@ -151,11 +151,12 @@ export class FrigateCard extends LitElement { @query('frigate-card-elements') _elements?: FrigateCardElements; - // Human interaction timer ID. + // Human interaction timer ("screensaver" functionality, return to default + // view after human interaction). protected _interactionTimerID: number | null = null; - // Whether or not media is actively playing (live or clip). - protected _mediaPlaying = false; + // Automated refreshes of the default view. + protected _updateTimerID: number | null = null; // Information about the most recently loaded media item. protected _mediaShowInfo: MediaShowInfo | null = null; @@ -619,10 +620,6 @@ export class FrigateCard extends LitElement { this._cameras = undefined; this._view = undefined; - if (this._getConfig().view.update_force) { - // If update force is enabled, start a timer right away. - this._resetInteractionTimer(); - } this._changeView(); } @@ -640,6 +637,7 @@ export class FrigateCard extends LitElement { } if (args?.view === undefined) { + // Load the default view. let camera = this._view?.camera; if (this._cameras?.size) { if (!camera) { @@ -658,6 +656,14 @@ export class FrigateCard extends LitElement { camera: camera, }); this._generateConditionState(); + + // The default view has been loaded, so can abandon any running + // 'screensaver' timer. + this._clearInteractionTimer(); + + // Restart the update timer, so the default view is refreshed at a fixed + // interval from now (if so configured). + this._startUpdateTimer(); } } else { this._view = args.view; @@ -692,8 +698,7 @@ export class FrigateCard extends LitElement { // Assistant update if there's been recent interaction (e.g. clicks on the // card) or if there is media active playing. if ( - (this._getConfig().view.update_force || - !(this._interactionTimerID && this._mediaPlaying)) && + this._isAutomatedViewUpdateAllowed() && shouldUpdateBasedOnHass( this._hass, oldHass, @@ -701,9 +706,8 @@ export class FrigateCard extends LitElement { ) ) { // If entities being monitored have changed then reset the view to the - // default and allow a re-render. Note that as per the Lit lifecycle, - // the setting of the view itself will not trigger an *additional* - // re-render here. + // default. Note that as per the Lit lifecycle, the setting of the view + // itself will not trigger an *additional* re-render here. this._changeView(); return true; } @@ -891,25 +895,66 @@ export class FrigateCard extends LitElement { ) { handleAction(node, this._hass as HomeAssistant, config, ev.detail.action); } - this._resetInteractionTimer(); + + // Set the 'screensaver' timer. + this._startInteractionTimer(); } - protected _resetInteractionTimer(): void { + /** + * Clear the human interaction ('screensaver') timer. + */ + protected _clearInteractionTimer(): void { + if (this._interactionTimerID) { + window.clearTimeout(this._interactionTimerID); + this._interactionTimerID = null; + } + } + + /** + * Start the human interaction ('screensaver') timer to reset the view to + * default `view.timeout_seconds` after human interaction. + */ + protected _startInteractionTimer(): void { + this._clearInteractionTimer(); if (this._getConfig().view.timeout_seconds) { - if (this._interactionTimerID) { - window.clearTimeout(this._interactionTimerID); - } this._interactionTimerID = window.setTimeout(() => { - this._interactionTimerID = null; this._changeView(); - if (this._getConfig().view.update_force) { - // If force is enabled, the timer just resets and starts over. - this._resetInteractionTimer(); - } }, this._getConfig().view.timeout_seconds * 1000); } } + /** + * Set the update timer to trigger an update refresh every + * `view.update_seconds`. + */ + protected _startUpdateTimer(): void { + if (this._updateTimerID) { + window.clearTimeout(this._updateTimerID); + this._updateTimerID = null; + } + if (this._getConfig().view.update_seconds) { + this._updateTimerID = window.setTimeout(() => { + if (this._isAutomatedViewUpdateAllowed()) { + this._changeView(); + } else { + // Not allowed to update this time around, but try again at the next + // interval. + this._startUpdateTimer(); + } + }, this._getConfig().view.update_seconds * 1000); + } + } + + /** + * Determine if an automated view update is allowed. + * @returns `true` if it's allowed, `false` otherwise. + */ + protected _isAutomatedViewUpdateAllowed(): boolean { + return ( + this._getConfig().view.update_force || !this._interactionTimerID + ); + } + /** * Render the card menu. * @returns A rendered template. @@ -929,20 +974,6 @@ export class FrigateCard extends LitElement { `; } - /** - * Handler for media play event. - */ - protected _playHandler(): void { - this._mediaPlaying = true; - } - - /** - * Handler for media pause event. - */ - protected _pauseHandler(): void { - this._mediaPlaying = false; - } - /** * Set the message to display and trigger an update. * @param message The message to display. @@ -1115,8 +1146,6 @@ export class FrigateCard extends LitElement { @frigate-card:message=${this._messageHandler} @frigate-card:change-view=${this._changeViewHandler} @frigate-card:media-show=${this._mediaShowHandler} - @frigate-card:pause=${this._pauseHandler} - @frigate-card:play=${this._playHandler} > ${this._getConfig().menu.mode == 'above' ? this._renderMenu() : ''}
diff --git a/src/common.ts b/src/common.ts index 46327533..b589cac9 100644 --- a/src/common.ts +++ b/src/common.ts @@ -114,22 +114,6 @@ export function dispatchFrigateCardEvent( ); } -/** - * Dispatch a Frigate card play event. - * @param element The element to send the event. - */ -export function dispatchPlayEvent(element: HTMLElement): void { - dispatchFrigateCardEvent(element, 'play'); -} - -/** - * Dispatch a Frigate card pause event. - * @param element The element to send the event. - */ -export function dispatchPauseEvent(element: HTMLElement): void { - dispatchFrigateCardEvent(element, 'pause'); -} - /** * Create a MediaShowInfo object. * @param source An event or HTMLElement that should be used as a source. diff --git a/src/components/live.ts b/src/components/live.ts index be86e2a2..59aeffe1 100644 --- a/src/components/live.ts +++ b/src/components/live.ts @@ -40,8 +40,6 @@ import { dispatchExistingMediaShowInfoAsEvent, dispatchMediaShowEvent, dispatchMessageEvent, - dispatchPauseEvent, - dispatchPlayEvent, getCameraIcon, getCameraTitle, homeAssistantSignPath, @@ -701,7 +699,7 @@ export class FrigateCardLiveWebRTC extends LitElement { * @returns The player or `null` if not found. */ protected _getPlayer(): HTMLVideoElement | null { - return this.renderRoot.querySelector('#video') as HTMLVideoElement | null; + return this.renderRoot?.querySelector('#video') as HTMLVideoElement | null; } /** @@ -763,8 +761,6 @@ export class FrigateCardLiveWebRTC extends LitElement { const video = this._getPlayer(); if (video) { const onloadedmetadata = video.onloadedmetadata; - const onplay = video.onplay; - const onpause = video.onpause; video.onloadedmetadata = (e) => { if (onloadedmetadata) { @@ -772,18 +768,6 @@ export class FrigateCardLiveWebRTC extends LitElement { } dispatchMediaShowEvent(this, video); }; - video.onplay = (e) => { - if (onplay) { - onplay.call(video, e); - } - dispatchPlayEvent(this); - }; - video.onpause = (e) => { - if (onpause) { - onpause.call(video, e); - } - dispatchPauseEvent(this); - }; } }); } @@ -864,14 +848,6 @@ export class FrigateCardLiveJSMPEG extends LitElement { url, { canvas: this._jsmpegCanvasElement, - hooks: { - play: () => { - dispatchPlayEvent(this); - }, - pause: () => { - dispatchPauseEvent(this); - }, - }, }, { pauseWhenHidden: false, diff --git a/src/patches/ha-hls-player.ts b/src/patches/ha-hls-player.ts index c2f06f43..ff255eaf 100644 --- a/src/patches/ha-hls-player.ts +++ b/src/patches/ha-hls-player.ts @@ -12,12 +12,7 @@ import { TemplateResult, css, html } from 'lit'; import { Ref, createRef, ref } from 'lit/directives/ref'; import { customElement } from 'lit/decorators.js'; - -import { - dispatchMediaShowEvent, - dispatchPauseEvent, - dispatchPlayEvent, -} from '../common.js'; +import { dispatchMediaShowEvent } from '../common.js'; customElements.whenDefined('ha-hls-player').then(() => { @customElement('frigate-card-ha-hls-player') @@ -54,8 +49,6 @@ customElements.whenDefined('ha-hls-player').then(() => { @loadeddata=${(e) => { dispatchMediaShowEvent(this, e); }} - @pause=${() => dispatchPauseEvent(this)} - @play=${() => dispatchPlayEvent(this)} > `; } diff --git a/src/types.ts b/src/types.ts index c428d4a4..34579767 100644 --- a/src/types.ts +++ b/src/types.ts @@ -370,7 +370,8 @@ export type PictureElements = z.infer; */ const viewConfigDefault = { default: 'live' as const, - timeout: 180, + timeout_seconds: 300, + update_seconds: 0, update_force: false, update_cycle_camera: false, }; @@ -380,7 +381,8 @@ const viewConfigSchema = z .enum(FRIGATE_CARD_VIEWS_USER_SPECIFIED) .optional() .default(viewConfigDefault.default), - timeout_seconds: z.number().default(viewConfigDefault.timeout), + timeout_seconds: z.number().default(viewConfigDefault.timeout_seconds), + update_seconds: z.number().default(viewConfigDefault.update_seconds), update_force: z.boolean().default(viewConfigDefault.update_force), update_cycle_camera: z.boolean().default(viewConfigDefault.update_cycle_camera), update_entities: z.string().array().optional(), From 548dd71a556a49ba7016d351a5de94a39812366a Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Sun, 23 Jan 2022 21:58:59 -0800 Subject: [PATCH 2/3] Add support to editor. --- src/const.ts | 1 + src/editor.ts | 2 ++ src/localize/languages/en.json | 5 +++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/const.ts b/src/const.ts index da48e0ee..4ccb4c6d 100644 --- a/src/const.ts +++ b/src/const.ts @@ -24,6 +24,7 @@ export const CONF_VIEW_TIMEOUT_SECONDS = `${CONF_VIEW}.timeout_seconds` as const export const CONF_VIEW_UPDATE_CYCLE_CAMERA = `${CONF_VIEW}.update_cycle_camera` as const; export const CONF_VIEW_UPDATE_FORCE = `${CONF_VIEW}.update_force` as const; export const CONF_VIEW_UPDATE_ENTITIES = `${CONF_VIEW}.update_entities` as const; +export const CONF_VIEW_UPDATE_SECONDS = `${CONF_VIEW}.update_seconds` as const; export const CONF_EVENT_GALLERY = 'event_gallery' as const; export const CONF_EVENT_GALLERY_MIN_COLUMNS = `${CONF_EVENT_GALLERY}.min_columns` as const; diff --git a/src/editor.ts b/src/editor.ts index dfd75cd9..c3c60d2b 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -59,6 +59,7 @@ import { CONF_VIEW_TIMEOUT_SECONDS, CONF_VIEW_UPDATE_CYCLE_CAMERA, CONF_VIEW_UPDATE_FORCE, + CONF_VIEW_UPDATE_SECONDS, } from './const.js'; import { arrayMove, getEntityTitle, prettifyFrigateName } from './common.js'; import { @@ -659,6 +660,7 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderDropdown(CONF_VIEW_DEFAULT, viewModes)} ${this._renderStringInput(CONF_VIEW_TIMEOUT_SECONDS, 'number')} + ${this._renderStringInput(CONF_VIEW_UPDATE_SECONDS, 'number')} ${this._renderSwitch(CONF_VIEW_UPDATE_FORCE, defaults.view.update_force)} ${this._renderSwitch(CONF_VIEW_UPDATE_CYCLE_CAMERA, defaults.view.update_cycle_camera)}
diff --git a/src/localize/languages/en.json b/src/localize/languages/en.json index 78dce17f..4ad5b15a 100644 --- a/src/localize/languages/en.json +++ b/src/localize/languages/en.json @@ -41,9 +41,10 @@ "snapshots": "Snapshots gallery", "image": "Static image" }, - "timeout_seconds": "View timeout seconds (before returning to default, 0=never)", + "timeout_seconds": "Reset to default view X seconds after user action (0=never)", "update_cycle_camera": "Cycle through cameras when default view updates", - "update_force": "Force card updates (ignore media playing / interaction)" + "update_force": "Force card updates (ignore human interaction)", + "update_seconds": "Refresh default view every X seconds (0=never)" }, "event_gallery": { "min_columns": "Minimum number of columns" From 7149db2277064f1f24fba776967e65e32647c2de Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Sun, 23 Jan 2022 22:01:55 -0800 Subject: [PATCH 3/3] s/human/user/ --- README.md | 24 ++++++++++++------------ src/card.ts | 14 +++++++------- src/localize/languages/en.json | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 3b58fa62..6c0d38ef 100644 --- a/README.md +++ b/README.md @@ -135,9 +135,9 @@ view: | Option | Default | Overridable | Description | | - | - | - | - | | `default` | `live` | :heavy_multiplication_x: | The view to show in the card by default. See [views](#views) below.| -| `timeout_seconds` | `300` | :heavy_multiplication_x: | A numbers of seconds of inactivity after human interaction, after which the card will reset to the default configured view (i.e. 'screensaver' functionality). Inactivity is defined as lack of mouse/touch interaction with the Frigate card. If the default view occurs sooner (e.g. via `update_seconds` or manually) the timer will be stopped. `0` means disable this functionality. | +| `timeout_seconds` | `300` | :heavy_multiplication_x: | A numbers of seconds of inactivity after user interaction, after which the card will reset to the default configured view (i.e. 'screensaver' functionality). Inactivity is defined as lack of mouse/touch interaction with the Frigate card. If the default view occurs sooner (e.g. via `update_seconds` or manually) the timer will be stopped. `0` means disable this functionality. | | `update_seconds` | `0` | :heavy_multiplication_x: | A number of seconds after which to automatically update/refresh the default view. See [card updates](#card-updates) below for behavior and usecases. If the default view occurs sooner (e.g. manually) the timer will start over. `0` disables this functionality.| -| `update_force` | `false` | :heavy_multiplication_x: | Whether automated card updates/refreshes should ignore human interaction. See [card updates](#card-updates) below for behavior and usecases.| +| `update_force` | `false` | :heavy_multiplication_x: | Whether automated card updates/refreshes should ignore user interaction. See [card updates](#card-updates) below for behavior and usecases.| | `update_entities` | | :heavy_multiplication_x: | **YAML only**: A list of entity ids that should cause the view to reset to the default. See [card updates](#card-updates) below for behavior and usecases.| | `update_cycle_camera` | `false` | :heavy_multiplication_x: | When set to `true` the selected camera is cycled on each default view change. | | `actions` | | :heavy_multiplication_x: | Actions to use for all views, individual actions may be overriden by view-specific actions. See [actions](#actions) below.| @@ -603,7 +603,7 @@ format](https://www.home-assistant.io/lovelace/actions/#tap-action) as well as the custom [Frigate card action](#frigate-card-action) to trigger Frigate card changes. -**Note:** The card itself obviously relies on human interactions to function +**Note:** The card itself obviously relies on user interactions to function (e.g. `tap` on the menu should activate that button, `tap` on a gallery thumbnail should open that piece of media, etc). These internal actions are executed _also_, which means that a card-wide `tap` action probably isn't that useful as @@ -1098,7 +1098,7 @@ image: ## Card Refreshes Four sets of flags govern when the card will automatically refresh in the -absence of human interaction. +absence of user interaction. The following table describes the behavior these flags have. @@ -1108,15 +1108,15 @@ The following table describes the behavior these flags have. | :-: | :-: | :-: | :-: | - | | `0` | `0` | *(Any value)* | Unset | Card will not automatically refresh. | | `0` | `0` | *(Any value)* | *(Any entity)* | Card will reload default view when entity state changes. | -| `0` | `X` seconds | *(Any value)* | Unset | Card will reload default view `X` seconds after human interaction stops. | -| `0` | `X` seconds | `false` | *(Any entity)* | Card will reload default view `X` seconds after human interaction stops, or when entity state changes (as long as human interaction has not occurred in the last `X` seconds). | -| `0` | `X` seconds | `true` | *(Any entity)* | Card will reload default view `X` seconds after human interaction stops or when entity state changes. | +| `0` | `X` seconds | *(Any value)* | Unset | Card will reload default view `X` seconds after user interaction stops. | +| `0` | `X` seconds | `false` | *(Any entity)* | Card will reload default view `X` seconds after user interaction stops, or when entity state changes (as long as user interaction has not occurred in the last `X` seconds). | +| `0` | `X` seconds | `true` | *(Any entity)* | Card will reload default view `X` seconds after user interaction stops or when entity state changes. | | `Y` seconds | `0` | *(Any value)* | Unset | Card will reload default view every `Y` seconds. | | `Y` seconds | `0` | *(Any value)* | *(Any entity)* | Card will reload default view every `Y` seconds, or whenever entity state changes. | -| `Y` seconds | `X` seconds | `false` | Unset | Card will reload default view `X` seconds after human interaction stops, and every `Y` seconds (as long as there hasn't been human interaction in the last `X` seconds). | -| `Y` seconds | `X` seconds | `false` | *(Any entity)* | Card will reload default view `X` seconds after human interaction stops, and every `Y` seconds or whenever entity state changes (in both cases -- as long as there hasn't been human interaction in the last `X` seconds). | -| `Y` seconds | `X` seconds | `true` | Unset | Card will reload default view `X` seconds after human interaction stops, and every `Y` seconds. | -| `Y` seconds | `X` seconds | `true` | *(Any entity)* | Card will reload default view `X` seconds after human interaction stops, and every `Y` seconds or whenever entity state changes. | +| `Y` seconds | `X` seconds | `false` | Unset | Card will reload default view `X` seconds after user interaction stops, and every `Y` seconds (as long as there hasn't been user interaction in the last `X` seconds). | +| `Y` seconds | `X` seconds | `false` | *(Any entity)* | Card will reload default view `X` seconds after user interaction stops, and every `Y` seconds or whenever entity state changes (in both cases -- as long as there hasn't been user interaction in the last `X` seconds). | +| `Y` seconds | `X` seconds | `true` | Unset | Card will reload default view `X` seconds after user interaction stops, and every `Y` seconds. | +| `Y` seconds | `X` seconds | `true` | *(Any entity)* | Card will reload default view `X` seconds after user interaction stops, and every `Y` seconds or whenever entity state changes. | ### Usecases For Automated Refreshes @@ -1142,7 +1142,7 @@ view: update_cycle_camera: true update_seconds: 60 ``` - * Return to the most recent clip of the default camera 30 seconds after human + * Return to the most recent clip of the default camera 30 seconds after user interaction with the card stops. ```yaml view: diff --git a/src/card.ts b/src/card.ts index b230f392..fdef5b30 100644 --- a/src/card.ts +++ b/src/card.ts @@ -151,8 +151,8 @@ export class FrigateCard extends LitElement { @query('frigate-card-elements') _elements?: FrigateCardElements; - // Human interaction timer ("screensaver" functionality, return to default - // view after human interaction). + // user interaction timer ("screensaver" functionality, return to default + // view after user interaction). protected _interactionTimerID: number | null = null; // Automated refreshes of the default view. @@ -533,7 +533,7 @@ export class FrigateCard extends LitElement { * where the 'real' error is vs simply a union option not matching. This * function finds all ZodError "issues" that don't have an error with 'type' * in that object ('type' is the union discriminator for picture elements, - * the major union in the schema). An array of human-readable error + * the major union in the schema). An array of user-readable error * locations is returned, or an empty list if none is available. None being * available suggests the configuration has an error, but we can't tell * exactly why (or rather Zod simply says it doesn't match any of the @@ -565,7 +565,7 @@ export class FrigateCard extends LitElement { } /** - * Convert an array of strings and indices into a more human readable string, + * Convert an array of strings and indices into a more user readable string, * e.g. [a, 1, b, 2] => 'a[1] -> b[2]' * @param path An array of strings and numbers. * @returns A single string. @@ -901,7 +901,7 @@ export class FrigateCard extends LitElement { } /** - * Clear the human interaction ('screensaver') timer. + * Clear the user interaction ('screensaver') timer. */ protected _clearInteractionTimer(): void { if (this._interactionTimerID) { @@ -911,8 +911,8 @@ export class FrigateCard extends LitElement { } /** - * Start the human interaction ('screensaver') timer to reset the view to - * default `view.timeout_seconds` after human interaction. + * Start the user interaction ('screensaver') timer to reset the view to + * default `view.timeout_seconds` after user interaction. */ protected _startInteractionTimer(): void { this._clearInteractionTimer(); diff --git a/src/localize/languages/en.json b/src/localize/languages/en.json index 4ad5b15a..6b7d709b 100644 --- a/src/localize/languages/en.json +++ b/src/localize/languages/en.json @@ -43,7 +43,7 @@ }, "timeout_seconds": "Reset to default view X seconds after user action (0=never)", "update_cycle_camera": "Cycle through cameras when default view updates", - "update_force": "Force card updates (ignore human interaction)", + "update_force": "Force card updates (ignore user interaction)", "update_seconds": "Refresh default view every X seconds (0=never)" }, "event_gallery": {