Add birdseye support.

This commit is contained in:
Dermot Duffy
2021-10-10 20:21:21 -07:00
parent da2508de21
commit bb9c27e34c
7 changed files with 101 additions and 93 deletions
+48 -41
View File
@@ -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>
`;
}
+2 -2
View File
@@ -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
View File
@@ -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 || ''}
+6 -6
View File
@@ -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
View File
@@ -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'),