feat: Auto-resolve Frigate client_id from camera entity (#2475)

Credit goes to @Eduardo-Jaramillo for the inspiration and contribution
of https://github.com/dermotduffy/advanced-camera-card/pull/2474 .
This commit is contained in:
Dermot Duffy
2026-06-30 17:45:12 -07:00
committed by dermotduffy
parent 9d088d7bcb
commit 261a7e1a92
8 changed files with 207 additions and 32 deletions
+38 -7
View File
@@ -133,6 +133,16 @@ export class FrigateCamera extends Camera {
}
}
if (!this._config.frigate.client_id) {
const stateEntity = cameraEntity ? hass.states[cameraEntity] : undefined;
const clientID = stateEntity?.attributes?.client_id;
if (typeof clientID === 'string' && clientID) {
this._config.frigate.client_id = clientID;
} else if (stateEntity?.state !== 'unavailable') {
this._config.frigate.client_id = 'frigate';
}
}
if (hasAutoTriggers) {
// Try to find the correct entities for the motion & occupancy sensors.
// We know they are binary_sensors, and that they'll have the same
@@ -227,7 +237,12 @@ export class FrigateCamera extends Camera {
const stream = this._config.go2rtc?.stream ?? this._config.frigate.camera_name;
const url =
this._config.go2rtc?.url ??
`/api/frigate/${this._config.frigate.client_id}/go2rtc`;
(this._config.frigate.client_id
? `/api/frigate/${this._config.frigate.client_id}/go2rtc`
: null);
if (!url) {
return null;
}
return getGo2RTCMetadataEndpoint(this._config, { url, stream });
}
@@ -236,8 +251,12 @@ export class FrigateCamera extends Camera {
const url =
this._config.go2rtc?.url ??
// go2rtc is exposed by the Frigate integration under the 'mse' path.
`/api/frigate/${this._config.frigate.client_id}/mse`;
(this._config.frigate.client_id
? `/api/frigate/${this._config.frigate.client_id}/mse`
: null);
if (!url) {
return null;
}
return getGo2RTCStreamEndpoint(this._config, {
url,
stream,
@@ -245,7 +264,7 @@ export class FrigateCamera extends Camera {
}
private _getJSMPEGEndpoint(): Endpoint | null {
if (!this._config.frigate.camera_name) {
if (!this._config.frigate.camera_name || !this._config.frigate.client_id) {
return null;
}
return {
@@ -305,7 +324,11 @@ export class FrigateCamera extends Camera {
hass: HomeAssistant,
cameraConfig: CameraConfig,
): Promise<PTZCapabilities | null> {
if (!cameraConfig.frigate.camera_name || isBirdseye(cameraConfig)) {
if (
!cameraConfig.frigate.camera_name ||
!cameraConfig.frigate.client_id ||
isBirdseye(cameraConfig)
) {
return null;
}
@@ -424,7 +447,11 @@ export class FrigateCamera extends Camera {
frigateEventWatcher: FrigateWatcherSubscriptionInterface<FrigateEventChange>,
): Promise<void> {
const config = this.getConfig();
if (!config.triggers.events.length || !config.frigate.camera_name) {
if (
!config.triggers.events.length ||
!config.frigate.camera_name ||
!config.frigate.client_id
) {
return;
}
@@ -495,7 +522,11 @@ export class FrigateCamera extends Camera {
const reviewConfig = config.triggers.reviews;
// Must have at least one severity configured and a camera name to subscribe
if (!reviewConfig.severities.length || !config.frigate.camera_name) {
if (
!reviewConfig.severities.length ||
!config.frigate.camera_name ||
!config.frigate.client_id
) {
return;
}
+21 -4
View File
@@ -188,6 +188,9 @@ export class FrigateCameraManagerEngine
cameraConfig: CameraConfig,
media: ViewMedia,
): Promise<Endpoint | null> {
if (!cameraConfig.frigate.client_id) {
return null;
}
if (FrigateViewMediaClassifier.isFrigateEvent(media)) {
return {
endpoint:
@@ -342,7 +345,10 @@ export class FrigateCameraManagerEngine
media: ViewMedia,
favorite: boolean,
): Promise<void> {
if (!FrigateViewMediaClassifier.isFrigateEvent(media)) {
if (
!FrigateViewMediaClassifier.isFrigateEvent(media) ||
!cameraConfig.frigate.client_id
) {
return;
}
@@ -356,7 +362,10 @@ export class FrigateCameraManagerEngine
media: ViewMedia,
reviewed: boolean,
): Promise<void> {
if (!FrigateViewMediaClassifier.isFrigateReview(media)) {
if (
!FrigateViewMediaClassifier.isFrigateReview(media) ||
!cameraConfig.frigate.client_id
) {
return;
}
@@ -590,7 +599,11 @@ export class FrigateCameraManagerEngine
}
const cameraConfig = this._getQueryableCameraConfig(store, cameraID);
if (!cameraConfig || !cameraConfig.frigate.camera_name) {
if (
!cameraConfig ||
!cameraConfig.frigate.camera_name ||
!cameraConfig.frigate.client_id
) {
return;
}
@@ -669,7 +682,11 @@ export class FrigateCameraManagerEngine
): Promise<void> => {
const query = { ...baseQuery, cameraIDs: new Set([cameraID]) };
const cameraConfig = this._getQueryableCameraConfig(store, cameraID);
if (!cameraConfig || !cameraConfig.frigate.camera_name) {
if (
!cameraConfig ||
!cameraConfig.frigate.camera_name ||
!cameraConfig.frigate.client_id
) {
return;
}