Merge pull request #402 from dermotduffy/unavailable-error

Add context to errors
This commit is contained in:
Dermot Duffy
2022-02-20 10:58:59 -08:00
committed by GitHub
10 changed files with 81 additions and 29 deletions
+4 -2
View File
@@ -451,14 +451,16 @@ export class FrigateCard extends LitElement {
if (!id) { if (!id) {
this._setMessageAndUpdate({ this._setMessageAndUpdate({
message: localize('error.no_camera_id') + `: ${JSON.stringify(config)}`, message: localize('error.no_camera_id'),
type: 'error', type: 'error',
context: config,
}); });
errorFree = false; errorFree = false;
} else if (cameras.has(id)) { } else if (cameras.has(id)) {
this._setMessageAndUpdate({ this._setMessageAndUpdate({
message: localize('error.duplicate_camera_id') + `: ${JSON.stringify(config)}`, message: localize('error.duplicate_camera_id'),
type: 'error', type: 'error',
context: config,
}); });
errorFree = false; errorFree = false;
} else { } else {
+8 -1
View File
@@ -191,11 +191,13 @@ export function dispatchMessageEvent(
element: HTMLElement, element: HTMLElement,
message: string, message: string,
icon?: string, icon?: string,
context?: unknown,
): void { ): void {
dispatchFrigateCardEvent<Message>(element, 'message', { dispatchFrigateCardEvent<Message>(element, 'message', {
message: message, message: message,
type: 'info', type: 'info',
icon: icon, icon: icon,
context: context,
}); });
} }
@@ -204,10 +206,15 @@ export function dispatchMessageEvent(
* @param element The element to send the event. * @param element The element to send the event.
* @param message The message to show. * @param message The message to show.
*/ */
export function dispatchErrorMessageEvent(element: HTMLElement, message: string): void { export function dispatchErrorMessageEvent(
element: HTMLElement,
message: string,
context?: unknown,
): void {
dispatchFrigateCardEvent<Message>(element, 'message', { dispatchFrigateCardEvent<Message>(element, 'message', {
message: message, message: message,
type: 'error', type: 'error',
context: context,
}); });
} }
+16 -6
View File
@@ -672,7 +672,7 @@ export class FrigateCardLiveProvider extends LitElement {
? html` <frigate-card-live-ha ? html` <frigate-card-live-ha
${ref(this._providerRef)} ${ref(this._providerRef)}
.hass=${this.hass} .hass=${this.hass}
.cameraEntity=${this.cameraConfig.camera_entity} .cameraConfig=${this.cameraConfig}
> >
</frigate-card-live-ha>` </frigate-card-live-ha>`
: provider == 'webrtc-card' : provider == 'webrtc-card'
@@ -700,7 +700,7 @@ export class FrigateCardLiveFrigate extends LitElement {
protected hass?: HomeAssistant & ExtendedHomeAssistant; protected hass?: HomeAssistant & ExtendedHomeAssistant;
@property({ attribute: false }) @property({ attribute: false })
protected cameraEntity?: string; protected cameraConfig?: CameraConfig;
protected _playerRef: Ref<FrigateCardLiveFrigate> = createRef(); protected _playerRef: Ref<FrigateCardLiveFrigate> = createRef();
@@ -741,17 +741,27 @@ export class FrigateCardLiveFrigate extends LitElement {
return; return;
} }
if (!this.cameraEntity || !(this.cameraEntity in this.hass.states)) { if (!this.cameraConfig?.camera_entity) {
return dispatchMessageEvent( return dispatchErrorMessageEvent(
this, this,
localize('error.no_live_camera'), localize('error.no_live_camera'),
'mdi:camera-off', this.cameraConfig,
); );
} }
const stateObj = this.hass.states[this.cameraConfig.camera_entity];
if (!stateObj || stateObj.state === 'unavailable') {
return dispatchErrorMessageEvent(
this,
localize('error.live_camera_unavailable'),
this.cameraConfig,
);
}
return html` <frigate-card-ha-camera-stream return html` <frigate-card-ha-camera-stream
${ref(this._playerRef)} ${ref(this._playerRef)}
.hass=${this.hass} .hass=${this.hass}
.stateObj=${this.hass.states[this.cameraEntity]} .stateObj=${stateObj}
.controls=${true} .controls=${true}
.muted=${true} .muted=${true}
> >
+1 -2
View File
@@ -1,5 +1,5 @@
import { computeStateDomain, HASSDomEvent, HomeAssistant } from 'custom-card-helpers';
import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit'; import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit';
import { HASSDomEvent, HomeAssistant } from 'custom-card-helpers';
import { customElement, property, state } from 'lit/decorators.js'; import { customElement, property, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined'; import { ifDefined } from 'lit/directives/if-defined';
@@ -18,7 +18,6 @@ import type {
StateParameters, StateParameters,
} from '../types.js'; } from '../types.js';
import { import {
computeActiveState,
convertActionToFrigateCardCustomAction, convertActionToFrigateCardCustomAction,
frigateCardHandleActionConfig, frigateCardHandleActionConfig,
frigateCardHasAction, frigateCardHasAction,
+26 -8
View File
@@ -13,16 +13,25 @@ export class FrigateCardMessage extends LitElement {
protected message = ''; protected message = '';
@property({ attribute: false }) @property({ attribute: false })
protected icon?; protected context?: unknown;
@property({ attribute: false })
protected icon?: string;
// Render the menu. // Render the menu.
protected render(): TemplateResult { protected render(): TemplateResult {
const icon = this.icon ? this.icon : 'mdi:information-outline'; const icon = this.icon ? this.icon : 'mdi:information-outline';
return html` <div class="message"> return html`
<span> <div class="wrapper">
<div class="message">
<div class="icon">
<ha-icon icon="${icon}"> </ha-icon> <ha-icon icon="${icon}"> </ha-icon>
</span> </div>
<div class="contents">
<span> ${this.message ? html`${this.message}` : ''} </span> <span> ${this.message ? html`${this.message}` : ''} </span>
${this.context ? html`<pre>${JSON.stringify(this.context, null, 2)}</pre>` : ''}
</div>
</div>
</div>`; </div>`;
} }
@@ -34,16 +43,24 @@ export class FrigateCardMessage extends LitElement {
@customElement('frigate-card-error-message') @customElement('frigate-card-error-message')
export class FrigateCardErrorMessage extends LitElement { export class FrigateCardErrorMessage extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
protected error = ''; protected message?: Message;
protected render(): TemplateResult { protected render(): TemplateResult | void {
if (!this.message) {
return;
}
return html` <frigate-card-message return html` <frigate-card-message
.message=${html` ${this.error}. .message=${html` ${this.message.message}.
<a href="${TROUBLESHOOTING_URL}"> ${localize('error.troubleshooting')}</a>.`} <a href="${TROUBLESHOOTING_URL}"> ${localize('error.troubleshooting')}</a>.`}
.icon=${'mdi:alert-circle'} .icon=${'mdi:alert-circle'}
.context=${this.message.context}
> >
</frigate-card-message>`; </frigate-card-message>`;
} }
static get styles(): CSSResultGroup {
return unsafeCSS(messageStyle);
}
} }
@customElement('frigate-card-progress-indicator') @customElement('frigate-card-progress-indicator')
@@ -68,12 +85,13 @@ export class FrigateCardProgressIndicator extends LitElement {
export function renderMessage(message: Message): TemplateResult { export function renderMessage(message: Message): TemplateResult {
if (message.type == 'error') { if (message.type == 'error') {
return html` <frigate-card-error-message return html` <frigate-card-error-message
.error=${message.message} .message=${message}
></frigate-card-error-message>`; ></frigate-card-error-message>`;
} else if (message.type == 'info') { } else if (message.type == 'info') {
return html` <frigate-card-message return html` <frigate-card-message
.message=${message.message} .message=${message.message}
.icon=${message.icon} .icon=${message.icon}
.context=${message.context}
></frigate-card-message>`; ></frigate-card-message>`;
} }
return html``; return html``;
+2 -2
View File
@@ -1,7 +1,7 @@
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit'; import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
import { HomeAssistant } from 'custom-card-helpers';
import { customElement, property } from 'lit/decorators'; import { customElement, property } from 'lit/decorators';
import { computeActiveState, frigateCardHasAction, refreshDynamicStateParameters } from '../common.js'; import { frigateCardHasAction, refreshDynamicStateParameters } from '../common.js';
import { computeStateDomain, HomeAssistant } from 'custom-card-helpers';
import { ifDefined } from 'lit/directives/if-defined'; import { ifDefined } from 'lit/directives/if-defined';
import { styleMap } from 'lit/directives/style-map'; import { styleMap } from 'lit/directives/style-map';
+1
View File
@@ -213,6 +213,7 @@
"troubleshooting": "Check troubleshooting", "troubleshooting": "Check troubleshooting",
"could_not_resolve": "Could not resolve media URL", "could_not_resolve": "Could not resolve media URL",
"no_live_camera": "The camera_entity parameter must be set and valid for this live provider", "no_live_camera": "The camera_entity parameter must be set and valid for this live provider",
"live_camera_unavailable": "The configured camera_entity is unavailable",
"invalid_configuration": "Invalid configuration", "invalid_configuration": "Invalid configuration",
"invalid_configuration_no_hint": "No location hint available (bad or missing type?)", "invalid_configuration_no_hint": "No location hint available (bad or missing type?)",
"upgrade_available": "An automated card configuration upgrade is available, please visit the visual card editor", "upgrade_available": "An automated card configuration upgrade is available, please visit the visual card editor",
+1
View File
@@ -213,6 +213,7 @@
"troubleshooting": "Verifique a solução de problemas", "troubleshooting": "Verifique a solução de problemas",
"could_not_resolve": "Não foi possível resolver o URL de mídia", "could_not_resolve": "Não foi possível resolver o URL de mídia",
"no_live_camera": "O parâmetro camera_entity deve ser definido e válido para este provedor ativo", "no_live_camera": "O parâmetro camera_entity deve ser definido e válido para este provedor ativo",
"live_camera_unavailable": "camera_entity configurada não está disponível",
"invalid_configuration": "Configuração inválida", "invalid_configuration": "Configuração inválida",
"invalid_configuration_no_hint": "Nenhuma dica de local disponível (tipo incorreto ou ausente?)", "invalid_configuration_no_hint": "Nenhuma dica de local disponível (tipo incorreto ou ausente?)",
"upgrade_available": "Uma atualização automatizada da configuração do cartão está disponível, visite o editor visual do cartão", "upgrade_available": "Uma atualização automatizada da configuração do cartão está disponível, visite o editor visual do cartão",
+18 -5
View File
@@ -4,13 +4,26 @@
display: block; display: block;
} }
.message { div.wrapper {
height: 100%; height: 100%;
}
div.message {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
padding: 10%; padding: 10%;
height: 100%;
}
div.message div.contents {
padding: 10px;
height: 100%;
}
div.message div.icon {
padding: 10px;
} }
.vertical { .vertical {
@@ -19,9 +32,9 @@
.message a { .message a {
color: var(--primary-text-color, white); color: var(--primary-text-color, white);
}
span {
padding: 10px;
word-break: break-word; word-break: break-word;
} }
.message pre {
margin-top: 20px;
}
+1
View File
@@ -835,6 +835,7 @@ export interface Message {
message: string; message: string;
type: 'error' | 'info'; type: 'error' | 'info';
icon?: string; icon?: string;
context?: unknown;
} }
export interface StateParameters { export interface StateParameters {