Improve engine identification and id generation.

This commit is contained in:
Dermot Duffy
2023-10-08 14:53:05 -07:00
parent fb5fbe4ce1
commit 7a33f75889
12 changed files with 222 additions and 142 deletions
+5
View File
@@ -96,6 +96,11 @@ export class CameraManagerEngineFactory {
// Frigate technically does not need an entity, if the camera name is
// manually set the camera is assumed to be Frigate.
engine = Engine.Frigate;
} else if (
cameraConfig.webrtc_card?.url ||
(cameraConfig.go2rtc?.url && cameraConfig.go2rtc?.stream)
) {
engine = Engine.Generic;
}
}
+5 -2
View File
@@ -31,7 +31,7 @@ import {
RecordingSegmentsQuery,
RecordingSegmentsQueryResultsMap,
} from '../types';
import { getDefaultGo2RTCEndpoint } from '../utils.js';
import { getCameraEntityFromConfig, getDefaultGo2RTCEndpoint } from '../utils.js';
export class GenericCameraManagerEngine implements CameraManagerEngine {
public getEngineType(): Engine {
@@ -159,6 +159,7 @@ export class GenericCameraManagerEngine implements CameraManagerEngine {
hass: HomeAssistant,
cameraConfig: CameraConfig,
): CameraManagerCameraMetadata {
const cameraEntity = getCameraEntityFromConfig(cameraConfig);
return {
title:
cameraConfig.title ??
@@ -166,7 +167,9 @@ export class GenericCameraManagerEngine implements CameraManagerEngine {
getEntityTitle(hass, cameraConfig.webrtc_card?.entity) ??
cameraConfig.id ??
'',
icon: cameraConfig?.icon ?? getEntityIcon(hass, cameraConfig.camera_entity),
icon:
cameraConfig?.icon ??
(cameraEntity ? getEntityIcon(hass, cameraEntity, 'mdi:video') : 'mdi:video'),
};
}
+3
View File
@@ -259,6 +259,9 @@ export class CameraManager {
);
}
// Always ensure the actual ID used in the card is in the configuration itself.
result.initializedConfig.id = id;
this._store.addCamera(id, result.initializedConfig, result.engine);
});
+1 -1
View File
@@ -91,7 +91,7 @@ export class MenuButtonController {
const action = createFrigateCardCustomAction('camera_select', {
camera: cameraID,
});
const metadata = cameraManager.getCameraMetadata(cameraID) ?? undefined;
const metadata = cameraManager.getCameraMetadata(cameraID);
return {
enabled: true,
+9 -2
View File
@@ -14,8 +14,15 @@ export function getCameraID(
(typeof config?.camera_entity === 'string' && config.camera_entity) ||
(typeof config?.webrtc_card === 'object' &&
config.webrtc_card &&
typeof config.webrtc_card['entity'] === 'string' &&
config.webrtc_card['entity']) ||
((typeof config.webrtc_card['entity'] === 'string' &&
config.webrtc_card['entity']) ||
(typeof config.webrtc_card['url'] === 'string' && config.webrtc_card['url']))) ||
(typeof config?.go2rtc === 'object' &&
config.go2rtc &&
typeof config.go2rtc['url'] === 'string' &&
typeof config.go2rtc['stream'] === 'string' &&
// Artifical identifier that includes both url / stream.
`${config.go2rtc['url']}#${config.go2rtc['stream']}`) ||
(typeof config?.frigate === 'object' &&
config.frigate &&
typeof config?.frigate['camera_name'] === 'string' &&
+19 -6
View File
@@ -1,4 +1,4 @@
import { computeStateDomain, HomeAssistant } from 'custom-card-helpers';
import { computeDomain, computeStateDomain, HomeAssistant } from 'custom-card-helpers';
import { HassEntity, MessageBase } from 'home-assistant-js-websocket';
import { StyleInfo } from 'lit/directives/style-map.js';
import { ZodSchema } from 'zod';
@@ -11,7 +11,7 @@ import {
signedPathSchema,
StateParameters,
} from '../../types.js';
import { stateIcon } from '../icons/state-icon.js';
import { domainIcon } from '../icons/domain-icon.js';
import { getParseErrorKeys } from '../zod.js';
/**
@@ -234,7 +234,7 @@ export function refreshDynamicStateParameters(
params.style = { ...computeStyle(state), ...params.style };
}
params.title = params.title ?? (state?.attributes?.friendly_name || params.entity);
params.icon = params.icon ?? stateIcon(state);
params.icon = params.icon ?? getEntityIcon(hass, params.entity);
const domain = state ? computeStateDomain(state) : undefined;
params.data_domain =
@@ -262,12 +262,25 @@ export function getEntityTitle(
/**
* Get the icon of an entity.
* @param entity The entity id.
* @param entityID The entity id.
* @param hass The Home Assistant object.
* @returns The icon or undefined.
*/
export function getEntityIcon(hass?: HomeAssistant, entity?: string): string {
return stateIcon(entity ? hass?.states[entity] : null);
export function getEntityIcon(
hass: HomeAssistant,
entityID: string,
defaultIcon?: string,
): string {
const entityState = hass.states[entityID];
if (entityState && entityState.attributes.icon) {
return entityState.attributes.icon;
}
return domainIcon(
computeDomain(entityID),
entityState,
entityState?.state,
defaultIcon,
);
}
/**
+2 -3
View File
@@ -52,7 +52,7 @@ const FIXED_DOMAIN_ICONS = {
zone: 'mdi:map-marker-radius',
};
export function domainIcon(domain: string, entity?: HassEntity, state?: string): string {
export function domainIcon(domain: string, entity?: HassEntity, state?: string, defaultIcon?: string): string {
switch (domain) {
case 'alarm_control_panel':
return alarmPanelIcon(state);
@@ -195,6 +195,5 @@ export function domainIcon(domain: string, entity?: HassEntity, state?: string):
return FIXED_DOMAIN_ICONS[domain];
}
console.warn(`Unable to find icon for domain: ${domain}`);
return DEFAULT_DOMAIN_ICON;
return defaultIcon ?? DEFAULT_DOMAIN_ICON;
}
-18
View File
@@ -1,18 +0,0 @@
import { computeDomain } from 'custom-card-helpers';
import { HassEntity } from 'home-assistant-js-websocket';
import { DEFAULT_DOMAIN_ICON, domainIcon } from './domain-icon';
export function stateIcon(entity?: HassEntity | null): string {
if (!entity) {
return DEFAULT_DOMAIN_ICON;
}
if (entity.attributes.icon) {
return entity.attributes.icon;
}
const domain = computeDomain(entity.entity_id);
const state = entity.state;
return domainIcon(domain, entity, state);
}