Person detection via direct MQTT instead of HA entities
- Electron main process subscribes to Frigate's MQTT topics (frigate/<camera>/person and frigate/events) directly via mqtt.js, bypassing the broken HA MQTT integration - Watched cameras: Front_Porch, FPE, Porch_Downstairs, Driveway_door - On person detection, exits photo-frame idle and shows full-screen camera feed for 30 seconds - Removed HA entity-based person detection code (entityToCameraName, personDetectionEntities config dependency) - Deleted unused useFrigateDetection HTTP polling hook (superseded)
This commit is contained in:
48
src/App.tsx
48
src/App.tsx
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState, useRef, useCallback } from 'react';
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import { Dashboard } from '@/components/layout';
|
||||
import { ThermostatOverlay } from '@/components/climate';
|
||||
import { LightsOverlay } from '@/components/lights';
|
||||
@@ -14,19 +14,11 @@ import { GlobalKeyboard } from '@/components/keyboard';
|
||||
import { PhotoFrame } from '@/components/photoframe';
|
||||
import { useHomeAssistant } from '@/hooks';
|
||||
import { useIdle } from '@/hooks/useIdle';
|
||||
// Motion detection now runs in Electron main process (MotionDetector.ts)
|
||||
// import { useSimpleMotion } from '@/hooks/useSimpleMotion';
|
||||
import { useHAStore } from '@/stores/haStore';
|
||||
import { useUIStore, useCameraOverlay } from '@/stores/uiStore';
|
||||
import { useSettingsStore } from '@/stores/settingsStore';
|
||||
import { env } from '@/config/environment';
|
||||
|
||||
// Map a Frigate person_occupancy entity to its camera name
|
||||
// e.g. 'binary_sensor.fpe_person_occupancy' -> 'fpe' -> match camera by frigateCamera
|
||||
function entityToCameraName(entityId: string): string | null {
|
||||
const match = entityId.match(/^binary_sensor\.(.+)_person_occupancy$/);
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
// Person detection alert overlay - shows for 30 seconds when person detected on any configured camera
|
||||
function PersonAlert({ cameraName, onClose }: { cameraName: string; onClose: () => void }) {
|
||||
@@ -116,10 +108,9 @@ function DashboardContent() {
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
const { isConnected, connectionState } = useHomeAssistant();
|
||||
const { connectionState } = useHomeAssistant();
|
||||
const accessToken = useHAStore((state) => state.accessToken);
|
||||
const connect = useHAStore((state) => state.connect);
|
||||
const entities = useHAStore((state) => state.entities);
|
||||
const settingsOpen = useUIStore((state) => state.settingsOpen);
|
||||
const lightsOverlayOpen = useUIStore((state) => state.lightsOverlayOpen);
|
||||
const locksOverlayOpen = useUIStore((state) => state.locksOverlayOpen);
|
||||
@@ -129,10 +120,8 @@ export default function App() {
|
||||
const { isOpen: cameraOverlayOpen } = useCameraOverlay();
|
||||
const isIdle = useIdle(env.photoFrameIdleTimeout);
|
||||
|
||||
// Person detection alert state
|
||||
const personDetectionEntities = useSettingsStore((state) => state.config.personDetectionEntities);
|
||||
// Person detection alert state (via MQTT from Electron main process)
|
||||
const [alertCamera, setAlertCamera] = useState<string | null>(null);
|
||||
const alertShownForRef = useRef<Set<string>>(new Set());
|
||||
|
||||
// Report touch/click activity to main process for screen wake on Wayland
|
||||
useEffect(() => {
|
||||
@@ -183,29 +172,16 @@ export default function App() {
|
||||
initConfig();
|
||||
}, [accessToken, connect]);
|
||||
|
||||
// Listen for person detection on all configured entities
|
||||
// Listen for person detection via MQTT (from Electron main process)
|
||||
useEffect(() => {
|
||||
if (!isConnected) return;
|
||||
|
||||
for (const entityId of personDetectionEntities) {
|
||||
const entity = entities[entityId];
|
||||
const isDetected = entity?.state === 'on';
|
||||
const cameraName = entityToCameraName(entityId);
|
||||
|
||||
if (isDetected && cameraName && !alertShownForRef.current.has(entityId)) {
|
||||
// Person just detected on this camera - show alert
|
||||
alertShownForRef.current.add(entityId);
|
||||
setAlertCamera(cameraName);
|
||||
if (window.electronAPI?.screen?.wake) {
|
||||
window.electronAPI.screen.wake();
|
||||
}
|
||||
break; // Show one alert at a time
|
||||
} else if (!isDetected) {
|
||||
// Reset so next detection on this entity triggers again
|
||||
alertShownForRef.current.delete(entityId);
|
||||
}
|
||||
}
|
||||
}, [isConnected, entities, personDetectionEntities]);
|
||||
const api = window.electronAPI;
|
||||
if (!api?.frigate?.onPersonDetected) return;
|
||||
const unsub = api.frigate.onPersonDetected((camera: string) => {
|
||||
setAlertCamera(camera);
|
||||
useUIStore.getState().setIdle(false);
|
||||
});
|
||||
return unsub;
|
||||
}, []);
|
||||
|
||||
const closePersonAlert = useCallback(() => {
|
||||
setAlertCamera(null);
|
||||
|
||||
Reference in New Issue
Block a user