Move live provider into the camera config.

This commit is contained in:
Dermot Duffy
2022-01-14 21:31:16 -08:00
parent 2277726a22
commit 59b89226bd
6 changed files with 54 additions and 52 deletions
+6 -3
View File
@@ -1,4 +1,7 @@
// TODO autodetect live provider from cameras configuration, or allow explicit setting. // TODO autodetect live provider from cameras configuration, or allow explicit setting.
// TODO config-mgmt move for live provider
// TODO unroll webrtc object in camera config for parity with live provider?
// TODO order of cameras may not be being preserved.
// TODO verify README links worked correctly (e.g. basic cameras configuration) // TODO verify README links worked correctly (e.g. basic cameras configuration)
import { import {
@@ -506,7 +509,7 @@ export class FrigateCardLiveProvider extends LitElement {
public disabled = false; public disabled = false;
protected _getResolvedProvider(): LiveProvider { protected _getResolvedProvider(): LiveProvider {
if (this.liveConfig?.provider === 'auto') { if (this.cameraConfig?.live_provider === 'auto') {
if (this.cameraConfig?.webrtc?.entity || this.cameraConfig?.webrtc?.url) { if (this.cameraConfig?.webrtc?.entity || this.cameraConfig?.webrtc?.url) {
return 'webrtc'; return 'webrtc';
} else if (this.cameraConfig?.camera_entity) { } else if (this.cameraConfig?.camera_entity) {
@@ -514,9 +517,9 @@ export class FrigateCardLiveProvider extends LitElement {
} else if (this.cameraConfig?.camera_name) { } else if (this.cameraConfig?.camera_name) {
return 'frigate-jsmpeg'; return 'frigate-jsmpeg';
} }
return frigateCardConfigDefaults.live.provider; return frigateCardConfigDefaults.cameras.live_provider;
} }
return this.liveConfig?.provider || frigateCardConfigDefaults.live.provider; return this.cameraConfig?.live_provider || frigateCardConfigDefaults.cameras.live_provider;
} }
/** /**
+23 -23
View File
@@ -5,6 +5,7 @@ import {
CONF_CAMERAS_ARRAY_CAMERA_NAME, CONF_CAMERAS_ARRAY_CAMERA_NAME,
CONF_CAMERAS_ARRAY_CLIENT_ID, CONF_CAMERAS_ARRAY_CLIENT_ID,
CONF_CAMERAS_ARRAY_LABEL, CONF_CAMERAS_ARRAY_LABEL,
CONF_CAMERAS_ARRAY_LIVE_PROVIDER,
CONF_CAMERAS_ARRAY_URL, CONF_CAMERAS_ARRAY_URL,
CONF_CAMERAS_ARRAY_WEBRTC_ENTITY, CONF_CAMERAS_ARRAY_WEBRTC_ENTITY,
CONF_CAMERAS_ARRAY_WEBRTC_URL, CONF_CAMERAS_ARRAY_WEBRTC_URL,
@@ -14,7 +15,6 @@ import {
CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE, CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE,
CONF_IMAGE_SRC, CONF_IMAGE_SRC,
CONF_LIVE_PRELOAD, CONF_LIVE_PRELOAD,
CONF_LIVE_PROVIDER,
CONF_MENU, CONF_MENU,
CONF_MENU_BUTTON_SIZE, CONF_MENU_BUTTON_SIZE,
CONF_MENU_MODE, CONF_MENU_MODE,
@@ -37,7 +37,7 @@ export const setConfigValue = (
keys: string | (string | number)[], keys: string | (string | number)[],
value: unknown, value: unknown,
): void => { ): void => {
set(obj, keys, value) set(obj, keys, value);
}; };
/** /**
@@ -213,13 +213,11 @@ const upgradeToMultipleCameras = (): ((obj: RawFrigateCardConfig) => boolean) =>
'frigate.zone': CONF_CAMERAS_ARRAY_ZONE, 'frigate.zone': CONF_CAMERAS_ARRAY_ZONE,
'live.webrtc.entity': CONF_CAMERAS_ARRAY_WEBRTC_ENTITY, 'live.webrtc.entity': CONF_CAMERAS_ARRAY_WEBRTC_ENTITY,
'live.webrtc.url': CONF_CAMERAS_ARRAY_WEBRTC_URL, 'live.webrtc.url': CONF_CAMERAS_ARRAY_WEBRTC_URL,
'live.provider': CONF_CAMERAS_ARRAY_LIVE_PROVIDER,
}; };
Object.keys(imports).forEach((key) => { Object.keys(imports).forEach((key) => {
modified = moveConfigValue( modified =
obj, moveConfigValue(obj, key, getArrayConfigPath(imports[key], 0)) || modified;
key,
getArrayConfigPath(imports[key], 0),
) || modified;
}); });
return modified; return modified;
}; };
@@ -231,27 +229,29 @@ const upgradeToMultipleCameras = (): ((obj: RawFrigateCardConfig) => boolean) =>
* @param key A string key. * @param key A string key.
* @returns A safe key. * @returns A safe key.
*/ */
const updateMenuConditionToMenuOverride = (): ((obj: RawFrigateCardConfig) => boolean) => { const updateMenuConditionToMenuOverride = (): ((
obj: RawFrigateCardConfig,
) => boolean) => {
return function (obj: RawFrigateCardConfig): boolean { return function (obj: RawFrigateCardConfig): boolean {
const menuConditions = getConfigValue(obj, `${CONF_MENU}.conditions`) as RawFrigateCardConfig; const menuConditions = getConfigValue(
obj,
`${CONF_MENU}.conditions`,
) as RawFrigateCardConfig;
if (menuConditions === undefined) { if (menuConditions === undefined) {
return false; return false;
} }
const overrides = getConfigValue(obj, `${CONF_OVERRIDES}`) as RawFrigateCardConfigArray || []; const overrides =
setConfigValue( (getConfigValue(obj, `${CONF_OVERRIDES}`) as RawFrigateCardConfigArray) || [];
obj, setConfigValue(obj, `${CONF_OVERRIDES}.[${overrides.length}]`, {
`${CONF_OVERRIDES}.[${overrides.length}]`, conditions: menuConditions,
{ overrides: {
conditions: menuConditions, menu: {
overrides: { mode: 'none',
menu: { },
mode: 'none' },
} });
}
}
);
deleteConfigValue(obj, `${CONF_MENU}.conditions`); deleteConfigValue(obj, `${CONF_MENU}.conditions`);
return true; return true;
}; };
@@ -266,7 +266,7 @@ const UPGRADES = [
upgradeMoveTo('zone', 'frigate.zone'), upgradeMoveTo('zone', 'frigate.zone'),
upgradeMoveTo('view_default', CONF_VIEW_DEFAULT), upgradeMoveTo('view_default', CONF_VIEW_DEFAULT),
upgradeMoveTo('view_timeout', CONF_VIEW_TIMEOUT), upgradeMoveTo('view_timeout', CONF_VIEW_TIMEOUT),
upgradeMoveTo('live_provider', CONF_LIVE_PROVIDER), upgradeMoveTo('live_provider', 'live.provider'),
upgradeMoveTo('live_preload', CONF_LIVE_PRELOAD), upgradeMoveTo('live_preload', CONF_LIVE_PRELOAD),
upgradeMoveTo('webrtc', 'live.webrtc'), upgradeMoveTo('webrtc', 'live.webrtc'),
upgradeMoveTo('autoplay_clip', CONF_EVENT_VIEWER_AUTOPLAY_CLIP), upgradeMoveTo('autoplay_clip', CONF_EVENT_VIEWER_AUTOPLAY_CLIP),
+1 -1
View File
@@ -16,6 +16,7 @@ export const CONF_CAMERAS_ARRAY_ICON = `${CONF_CAMERAS}.#.icon` as const;
export const CONF_CAMERAS_ARRAY_WEBRTC_ENTITY = export const CONF_CAMERAS_ARRAY_WEBRTC_ENTITY =
`${CONF_CAMERAS}.#.webrtc.entity` as const; `${CONF_CAMERAS}.#.webrtc.entity` as const;
export const CONF_CAMERAS_ARRAY_WEBRTC_URL = `${CONF_CAMERAS}.#.webrtc.url` as const; export const CONF_CAMERAS_ARRAY_WEBRTC_URL = `${CONF_CAMERAS}.#.webrtc.url` as const;
export const CONF_CAMERAS_ARRAY_LIVE_PROVIDER = `${CONF_CAMERAS}.#.live_provider` as const;
export const CONF_VIEW = 'view' as const; export const CONF_VIEW = 'view' as const;
export const CONF_VIEW_DEFAULT = `${CONF_VIEW}.default` as const; export const CONF_VIEW_DEFAULT = `${CONF_VIEW}.default` as const;
@@ -52,7 +53,6 @@ export const CONF_LIVE_DRAGGABLE = `${CONF_LIVE}.draggable` as const;
export const CONF_LIVE_JSMPEG = `${CONF_LIVE}.jsmpeg` as const; export const CONF_LIVE_JSMPEG = `${CONF_LIVE}.jsmpeg` as const;
export const CONF_LIVE_LAZY_LOAD = `${CONF_LIVE}.lazy_load` as const; export const CONF_LIVE_LAZY_LOAD = `${CONF_LIVE}.lazy_load` as const;
export const CONF_LIVE_PRELOAD = `${CONF_LIVE}.preload` as const; export const CONF_LIVE_PRELOAD = `${CONF_LIVE}.preload` as const;
export const CONF_LIVE_PROVIDER = `${CONF_LIVE}.provider` as const;
export const CONF_LIVE_WEBRTC = `${CONF_LIVE}.webrtc` as const; export const CONF_LIVE_WEBRTC = `${CONF_LIVE}.webrtc` as const;
export const CONF_LIVE_WEBRTC_ENTITY = `${CONF_LIVE_WEBRTC}.entity` as const; export const CONF_LIVE_WEBRTC_ENTITY = `${CONF_LIVE_WEBRTC}.entity` as const;
export const CONF_LIVE_WEBRTC_URL = `${CONF_LIVE_WEBRTC}.url` as const; export const CONF_LIVE_WEBRTC_URL = `${CONF_LIVE_WEBRTC}.url` as const;
+12 -10
View File
@@ -19,6 +19,7 @@ import {
CONF_CAMERAS_ARRAY_ICON, CONF_CAMERAS_ARRAY_ICON,
CONF_CAMERAS_ARRAY_ID, CONF_CAMERAS_ARRAY_ID,
CONF_CAMERAS_ARRAY_LABEL, CONF_CAMERAS_ARRAY_LABEL,
CONF_CAMERAS_ARRAY_LIVE_PROVIDER,
CONF_CAMERAS_ARRAY_TITLE, CONF_CAMERAS_ARRAY_TITLE,
CONF_CAMERAS_ARRAY_URL, CONF_CAMERAS_ARRAY_URL,
CONF_CAMERAS_ARRAY_WEBRTC_ENTITY, CONF_CAMERAS_ARRAY_WEBRTC_ENTITY,
@@ -42,7 +43,6 @@ import {
CONF_LIVE_DRAGGABLE, CONF_LIVE_DRAGGABLE,
CONF_LIVE_LAZY_LOAD, CONF_LIVE_LAZY_LOAD,
CONF_LIVE_PRELOAD, CONF_LIVE_PRELOAD,
CONF_LIVE_PROVIDER,
CONF_MENU_BUTTONS_CLIPS, CONF_MENU_BUTTONS_CLIPS,
CONF_MENU_BUTTONS_FRIGATE, CONF_MENU_BUTTONS_FRIGATE,
CONF_MENU_BUTTONS_FRIGATE_DOWNLOAD, CONF_MENU_BUTTONS_FRIGATE_DOWNLOAD,
@@ -322,6 +322,14 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
cameraEntities: string[], cameraEntities: string[],
addNewCamera?: boolean, addNewCamera?: boolean,
): TemplateResult | void { ): TemplateResult | void {
const liveProviders = {
'': '',
auto: localize('config.cameras.live_providers.auto'),
frigate: localize('config.cameras.live_providers.frigate'),
'frigate-jsmpeg': localize('config.cameras.live_providers.frigate-jsmpeg'),
webrtc: localize('config.cameras.live_providers.webrtc'),
} as const;
// Make a new config and update the editor with changes on it, // Make a new config and update the editor with changes on it,
const modifyConfig = (func: (config: RawFrigateCardConfig) => boolean): void => { const modifyConfig = (func: (config: RawFrigateCardConfig) => boolean): void => {
if (this._config) { if (this._config) {
@@ -405,6 +413,9 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderStringInput( ${this._renderStringInput(
getArrayConfigPath(CONF_CAMERAS_ARRAY_CAMERA_NAME, cameraIndex), getArrayConfigPath(CONF_CAMERAS_ARRAY_CAMERA_NAME, cameraIndex),
)} )}
${this._renderDropdown(
getArrayConfigPath(CONF_CAMERAS_ARRAY_LIVE_PROVIDER, cameraIndex),
liveProviders)}
${this._renderStringInput( ${this._renderStringInput(
getArrayConfigPath(CONF_CAMERAS_ARRAY_URL, cameraIndex), getArrayConfigPath(CONF_CAMERAS_ARRAY_URL, cameraIndex),
)} )}
@@ -530,14 +541,6 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
below: localize('config.menu.modes.below'), below: localize('config.menu.modes.below'),
}; };
const liveProviders = {
'': '',
auto: localize('config.live.providers.auto'),
frigate: localize('config.live.providers.frigate'),
'frigate-jsmpeg': localize('config.live.providers.frigate-jsmpeg'),
webrtc: localize('config.live.providers.webrtc'),
};
const eventViewerNextPreviousControlStyles = { const eventViewerNextPreviousControlStyles = {
'': '', '': '',
thumbnails: localize( thumbnails: localize(
@@ -685,7 +688,6 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
CONF_LIVE_LAZY_LOAD, CONF_LIVE_LAZY_LOAD,
defaults.live.lazy_load, defaults.live.lazy_load,
)} )}
${this._renderDropdown(CONF_LIVE_PROVIDER, liveProviders)}
${this._renderDropdown( ${this._renderDropdown(
CONF_LIVE_CONTROLS_NEXT_PREVIOUS_STYLE, CONF_LIVE_CONTROLS_NEXT_PREVIOUS_STYLE,
liveNextPreviousControlStyles, liveNextPreviousControlStyles,
+9 -9
View File
@@ -18,11 +18,18 @@
"frigate_url": "Frigate server URL", "frigate_url": "Frigate server URL",
"title": "Title for this camera (Autodetected from entity)", "title": "Title for this camera (Autodetected from entity)",
"icon": "Icon for this camera (Autodetected from entity)", "icon": "Icon for this camera (Autodetected from entity)",
"zone": "Frigate zone", "live_provider": "Live view provider for this camera",
"live_providers": {
"auto": "Automatic",
"frigate": "Frigate",
"frigate-jsmpeg": "Frigate JSMpeg",
"webrtc": "WebRTC"
},
"webrtc": { "webrtc": {
"entity": "WebRTC Camera Entity (Not a Frigate camera)", "entity": "WebRTC Camera Entity (Not a Frigate camera)",
"url": "WebRTC Camera URL" "url": "WebRTC Camera URL"
} },
"zone": "Frigate zone"
}, },
"view": { "view": {
"default": "Default view", "default": "Default view",
@@ -64,13 +71,6 @@
}, },
"live": { "live": {
"preload": "Preload live view in the background", "preload": "Preload live view in the background",
"provider": "Live view provider",
"providers": {
"auto": "Automatic",
"frigate": "Frigate",
"frigate-jsmpeg": "Frigate JSMpeg",
"webrtc": "WebRTC"
},
"draggable": "Live cameras view can be dragged/swiped", "draggable": "Live cameras view can be dragged/swiped",
"lazy_load": "Live cameras are lazily loaded in carousel", "lazy_load": "Live cameras are lazily loaded in carousel",
"controls": { "controls": {
+3 -6
View File
@@ -282,6 +282,7 @@ const customSchema = z
*/ */
export const cameraConfigDefault = { export const cameraConfigDefault = {
client_id: 'frigate' as const, client_id: 'frigate' as const,
live_provider: 'auto' as const,
}; };
const webrtcCameraConfigSchema = z.object({ const webrtcCameraConfigSchema = z.object({
entity: z.string().optional(), entity: z.string().optional(),
@@ -291,11 +292,12 @@ const cameraConfigSchema = z
.object({ .object({
// No URL validation to allow relative URLs within HA (e.g. Frigate addon). // No URL validation to allow relative URLs within HA (e.g. Frigate addon).
frigate_url: z.string().optional(), frigate_url: z.string().optional(),
client_id: z.string().optional().default(cameraConfigDefault.client_id), client_id: z.string().default(cameraConfigDefault.client_id),
camera_name: z.string().optional(), camera_name: z.string().optional(),
label: z.string().optional(), label: z.string().optional(),
zone: z.string().optional(), zone: z.string().optional(),
camera_entity: z.string().optional(), camera_entity: z.string().optional(),
live_provider: z.enum(LIVE_PROVIDERS).default(cameraConfigDefault.live_provider),
// Used for presentation in the UI (autodetected from the entity if // Used for presentation in the UI (autodetected from the entity if
// specified). // specified).
@@ -446,7 +448,6 @@ export type NextPreviousControlConfig = z.infer<typeof nextPreviousControlConfig
* Live view configuration section. * Live view configuration section.
*/ */
const liveConfigDefault = { const liveConfigDefault = {
provider: 'auto' as const,
preload: false, preload: false,
lazy_load: true, lazy_load: true,
draggable: true, draggable: true,
@@ -496,7 +497,6 @@ const liveNextPreviousControlConfigSchema = nextPreviousControlConfigSchema.exte
const liveOverridableConfigSchema = z const liveOverridableConfigSchema = z
.object({ .object({
provider: z.enum(LIVE_PROVIDERS).optional(),
webrtc: webrtcConfigSchema, webrtc: webrtcConfigSchema,
jsmpeg: jsmpegConfigSchema, jsmpeg: jsmpegConfigSchema,
controls: z controls: z
@@ -517,9 +517,6 @@ const liveOverridableConfigSchema = z
const liveConfigSchema = liveOverridableConfigSchema const liveConfigSchema = liveOverridableConfigSchema
.extend({ .extend({
// Replace attributes from the overridable schema with those with defaults. // Replace attributes from the overridable schema with those with defaults.
provider: liveOverridableConfigSchema.shape.provider.default(
liveConfigDefault.provider,
),
controls: z controls: z
.object({ .object({
next_previous: liveNextPreviousControlConfigSchema next_previous: liveNextPreviousControlConfigSchema