Add birdseye support.
This commit is contained in:
+48
-41
@@ -33,7 +33,6 @@ import { CARD_VERSION } from './const';
|
||||
import { FrigateCardMenu, MENU_HEIGHT } from './components/menu';
|
||||
import { View } from './view';
|
||||
import {
|
||||
getParseErrorKeys,
|
||||
homeAssistantWSRequest,
|
||||
shouldUpdateBasedOnHass,
|
||||
} from './common';
|
||||
@@ -221,30 +220,32 @@ export class FrigateCard extends LitElement {
|
||||
return this.config.frigate_camera_name;
|
||||
}
|
||||
|
||||
// Option 2: Find entity unique_id in registry.
|
||||
const request = {
|
||||
type: 'config/entity_registry/get',
|
||||
entity_id: this.config.camera_entity,
|
||||
};
|
||||
try {
|
||||
const entityResult = await homeAssistantWSRequest<Entity>(
|
||||
this._hass,
|
||||
entitySchema,
|
||||
request,
|
||||
);
|
||||
if (entityResult && entityResult.platform == 'frigate') {
|
||||
const match = entityResult.unique_id.match(/:camera:(?<camera>[^:]+)$/);
|
||||
if (match && match.groups) {
|
||||
return match.groups['camera'];
|
||||
if (this.config.camera_entity) {
|
||||
// Option 2: Find entity unique_id in registry.
|
||||
const request = {
|
||||
type: 'config/entity_registry/get',
|
||||
entity_id: this.config.camera_entity,
|
||||
};
|
||||
try {
|
||||
const entityResult = await homeAssistantWSRequest<Entity>(
|
||||
this._hass,
|
||||
entitySchema,
|
||||
request,
|
||||
);
|
||||
if (entityResult && entityResult.platform == 'frigate') {
|
||||
const match = entityResult.unique_id.match(/:camera:(?<camera>[^:]+)$/);
|
||||
if (match && match.groups) {
|
||||
return match.groups['camera'];
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
// Pass.
|
||||
}
|
||||
} catch (e: any) {
|
||||
// Pass.
|
||||
}
|
||||
|
||||
// Option 3: Guess from the entity_id.
|
||||
if (this.config.camera_entity.includes('.')) {
|
||||
return this.config.camera_entity.split('.', 2)[1];
|
||||
// Option 3: Guess from the entity_id.
|
||||
if (this.config.camera_entity.includes('.')) {
|
||||
return this.config.camera_entity.split('.', 2)[1];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -287,11 +288,13 @@ export class FrigateCard extends LitElement {
|
||||
getLovelace().setEditMode(true);
|
||||
}
|
||||
|
||||
this._frigateCameraName = null;
|
||||
this.config = config;
|
||||
this._entitiesToMonitor = [
|
||||
...(this.config.update_entities || []),
|
||||
this.config.camera_entity,
|
||||
];
|
||||
|
||||
this._entitiesToMonitor = this.config.update_entities || [];
|
||||
if (this.config.camera_entity) {
|
||||
this._entitiesToMonitor.push(this.config.camera_entity);
|
||||
}
|
||||
this._changeView();
|
||||
}
|
||||
|
||||
@@ -636,21 +639,25 @@ export class FrigateCard extends LitElement {
|
||||
</frigate-card-live>
|
||||
`
|
||||
: ``}
|
||||
<frigate-card-elements
|
||||
.hass=${this._hass}
|
||||
.elements=${this.config.elements}
|
||||
@frigate-card:message=${this._messageHandler}
|
||||
@frigate-card:menu-add=${(e) => {
|
||||
this._menu.addButton(e.detail);
|
||||
}}
|
||||
@frigate-card:menu-remove=${(e) => {
|
||||
this._menu.removeButton(e.detail);
|
||||
}}
|
||||
@frigate-card:state-request=${(e) => {
|
||||
e.view = this._view;
|
||||
}}
|
||||
>
|
||||
</frigate-card-elements>
|
||||
${this.config.elements
|
||||
? html`
|
||||
<frigate-card-elements
|
||||
.hass=${this._hass}
|
||||
.elements=${this.config.elements}
|
||||
@frigate-card:message=${this._messageHandler}
|
||||
@frigate-card:menu-add=${(e) => {
|
||||
this._menu.addButton(e.detail);
|
||||
}}
|
||||
@frigate-card:menu-remove=${(e) => {
|
||||
this._menu.removeButton(e.detail);
|
||||
}}
|
||||
@frigate-card:state-request=${(e) => {
|
||||
e.view = this._view;
|
||||
}}
|
||||
>
|
||||
</frigate-card-elements>
|
||||
`
|
||||
: ``}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -68,10 +68,10 @@ export class FrigateCardViewerFrigate extends LitElement {
|
||||
protected hass!: HomeAssistant & ExtendedHomeAssistant;
|
||||
|
||||
@property({ attribute: false })
|
||||
protected cameraEntity!: string;
|
||||
protected cameraEntity?: string;
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
if (!(this.cameraEntity in this.hass.states)) {
|
||||
if (!this.cameraEntity || !(this.cameraEntity in this.hass.states)) {
|
||||
return dispatchMessageEvent(
|
||||
this,
|
||||
localize('error.no_live_camera'),
|
||||
|
||||
+32
-32
@@ -9,10 +9,10 @@ import type { FrigateCardConfig } from './types';
|
||||
import frigate_card_editor_style from './scss/editor.scss';
|
||||
|
||||
const options = {
|
||||
required: {
|
||||
basic: {
|
||||
icon: 'cog',
|
||||
name: localize('editor.required'),
|
||||
secondary: localize('editor.required_secondary'),
|
||||
name: localize('editor.basic'),
|
||||
secondary: localize('editor.basic_secondary'),
|
||||
show: true,
|
||||
},
|
||||
optional: {
|
||||
@@ -146,14 +146,14 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
||||
|
||||
return html`
|
||||
<div class="card-config">
|
||||
<div class="option" @click=${this._toggleOption} .option=${'required'}>
|
||||
<div class="option" @click=${this._toggleOption} .option=${'basic'}>
|
||||
<div class="row">
|
||||
<ha-icon .icon=${`mdi:${options.required.icon}`}></ha-icon>
|
||||
<div class="title">${options.required.name}</div>
|
||||
<ha-icon .icon=${`mdi:${options.basic.icon}`}></ha-icon>
|
||||
<div class="title">${options.basic.name}</div>
|
||||
</div>
|
||||
<div class="secondary">${options.required.secondary}</div>
|
||||
<div class="secondary">${options.basic.secondary}</div>
|
||||
</div>
|
||||
${options.required.show
|
||||
${options.basic.show
|
||||
? html`
|
||||
<div class="values">
|
||||
<paper-dropdown-menu
|
||||
@@ -172,6 +172,30 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
||||
})}
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
<paper-input
|
||||
label=${localize('editor.frigate_camera_name')}
|
||||
.value=${this._config?.frigate_camera_name || ''}
|
||||
.configValue=${'frigate_camera_name'}
|
||||
@value-changed=${this._valueChanged}
|
||||
></paper-input>
|
||||
<paper-dropdown-menu
|
||||
label=${localize('editor.default_view')}
|
||||
@value-changed=${this._valueChanged}
|
||||
.configValue=${'view_default'}
|
||||
>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
.selected=${Object.keys(viewModes).indexOf(
|
||||
this._config?.view_default || '',
|
||||
)}
|
||||
>
|
||||
${Object.keys(viewModes).map((key) => {
|
||||
return html`
|
||||
<paper-item .label="${key}"> ${viewModes[key]} </paper-item>
|
||||
`;
|
||||
})}
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
`
|
||||
: ''}
|
||||
@@ -184,12 +208,6 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
||||
</div>
|
||||
${options.optional.show
|
||||
? html` <div class="values">
|
||||
<paper-input
|
||||
label=${localize('editor.frigate_camera_name')}
|
||||
.value=${this._config?.frigate_camera_name || ''}
|
||||
.configValue=${'frigate_camera_name'}
|
||||
@value-changed=${this._valueChanged}
|
||||
></paper-input>
|
||||
<paper-dropdown-menu
|
||||
.label=${localize('editor.live_provider')}
|
||||
@value-changed=${this._valueChanged}
|
||||
@@ -208,24 +226,6 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
||||
})}
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
<paper-dropdown-menu
|
||||
label=${localize('editor.default_view')}
|
||||
@value-changed=${this._valueChanged}
|
||||
.configValue=${'view_default'}
|
||||
>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
.selected=${Object.keys(viewModes).indexOf(
|
||||
this._config?.view_default || '',
|
||||
)}
|
||||
>
|
||||
${Object.keys(viewModes).map((key) => {
|
||||
return html`
|
||||
<paper-item .label="${key}"> ${viewModes[key]} </paper-item>
|
||||
`;
|
||||
})}
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
<paper-input
|
||||
label=${localize('editor.frigate_client_id')}
|
||||
.value=${this._config?.frigate_client_id || ''}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"no_clip": "No recent clip"
|
||||
},
|
||||
"editor": {
|
||||
"required": "Required",
|
||||
"required_secondary": "Required options for this card to function",
|
||||
"basic": "Basic",
|
||||
"basic_secondary": "Basic options for most users",
|
||||
"optional": "Optional",
|
||||
"optional_secondary": "Optional configuration to tweak card behavior",
|
||||
"appearance": "Appearance",
|
||||
@@ -21,8 +21,8 @@
|
||||
"webrtc_secondary": "Optional WebRTC parameters",
|
||||
"advanced": "Advanced",
|
||||
"advanced_secondary": "Advanced options",
|
||||
"camera_entity": "Camera Entity (Required)",
|
||||
"frigate_camera_name": "Frigate camera name (Optional)",
|
||||
"camera_entity": "Camera Entity (Optional)",
|
||||
"frigate_camera_name": "Frigate camera name (Optional, autodetected from entity)",
|
||||
"default_view": "Default view (Optional)",
|
||||
"frigate_client_id": "Frigate client id (Optional, for >1 Frigate server)",
|
||||
"view_timeout": "View timeout (seconds)",
|
||||
@@ -92,10 +92,10 @@
|
||||
"unknown": "Unknown error",
|
||||
"troubleshooting": "Check troubleshooting",
|
||||
"could_not_resolve": "Could not resolve media URL",
|
||||
"no_live_camera": "No live camera",
|
||||
"no_live_camera": "The camera_entity parameter must be set and valid for this live provider",
|
||||
"invalid_configuration": "Invalid configuration",
|
||||
"missing_webrtc": "WebRTC component not found",
|
||||
"no_frigate_camera_name": "Cannot derive frigate_camera_name, you may need to set it manually",
|
||||
"no_frigate_camera_name": "Cannot autodetect Frigate camera name, you need to either set camera_entity and / or frigate_camera_name",
|
||||
"could_not_render_elements": "Could not render picture elements",
|
||||
"invalid_elements_config": "Invalid picture elements configuration"
|
||||
}
|
||||
|
||||
+2
-1
@@ -244,7 +244,8 @@ const pictureElementsSchema = pictureElementSchema.array().optional();
|
||||
export type PictureElements = z.infer<typeof pictureElementsSchema>;
|
||||
|
||||
export const frigateCardConfigSchema = z.object({
|
||||
camera_entity: z.string(),
|
||||
camera_entity: z.string().optional(),
|
||||
|
||||
// No URL validation to allow relative URLs within HA (e.g. addons).
|
||||
frigate_url: z.string().optional(),
|
||||
frigate_client_id: z.string().optional().default('frigate'),
|
||||
|
||||
Reference in New Issue
Block a user