diff --git a/docs/docs/usage/mqtt.md b/docs/docs/usage/mqtt.md index e061292fa..73ab23bb8 100644 --- a/docs/docs/usage/mqtt.md +++ b/docs/docs/usage/mqtt.md @@ -88,13 +88,13 @@ Topic to turn detection for a camera on and off. Expected values are `ON` and `O Topic with current state of detection for a camera. Published values are `ON` and `OFF`. -### `frigate//clips/set` +### `frigate//recordings/set` -Topic to turn clips for a camera on and off. Expected values are `ON` and `OFF`. +Topic to turn recordings for a camera on and off. Expected values are `ON` and `OFF`. -### `frigate//clips/state` +### `frigate//recordings/state` -Topic with current state of clips for a camera. Published values are `ON` and `OFF`. +Topic with current state of recordings for a camera. Published values are `ON` and `OFF`. ### `frigate//snapshots/set` diff --git a/frigate/mqtt.py b/frigate/mqtt.py index ee8aee6cb..78b6590a9 100644 --- a/frigate/mqtt.py +++ b/frigate/mqtt.py @@ -21,22 +21,22 @@ logger = logging.getLogger(__name__) def create_mqtt_client(config: FrigateConfig, camera_metrics): mqtt_config = config.mqtt - def on_clips_command(client, userdata, message): + def on_recordings_command(client, userdata, message): payload = message.payload.decode() - logger.debug(f"on_clips_toggle: {message.topic} {payload}") + logger.debug(f"on_recordings_toggle: {message.topic} {payload}") camera_name = message.topic.split("/")[-3] - clips_settings = config.cameras[camera_name].clips + record_settings = config.cameras[camera_name].record if payload == "ON": - if not clips_settings.enabled: - logger.info(f"Turning on clips for {camera_name} via mqtt") - clips_settings.enabled = True + if not record_settings.enabled: + logger.info(f"Turning on recordings for {camera_name} via mqtt") + record_settings.enabled = True elif payload == "OFF": - if clips_settings.enabled: - logger.info(f"Turning off clips for {camera_name} via mqtt") - clips_settings.enabled = False + if record_settings.enabled: + logger.info(f"Turning off recordings for {camera_name} via mqtt") + record_settings.enabled = False else: logger.warning(f"Received unsupported value at {message.topic}: {payload}") @@ -120,7 +120,7 @@ def create_mqtt_client(config: FrigateConfig, camera_metrics): # register callbacks for name in config.cameras.keys(): client.message_callback_add( - f"{mqtt_config.topic_prefix}/{name}/clips/set", on_clips_command + f"{mqtt_config.topic_prefix}/{name}/recordings/set", on_recordings_command ) client.message_callback_add( f"{mqtt_config.topic_prefix}/{name}/snapshots/set", on_snapshots_command @@ -159,8 +159,8 @@ def create_mqtt_client(config: FrigateConfig, camera_metrics): for name in config.cameras.keys(): client.publish( - f"{mqtt_config.topic_prefix}/{name}/clips/state", - "ON" if config.cameras[name].clips.enabled else "OFF", + f"{mqtt_config.topic_prefix}/{name}/recordings/state", + "ON" if config.cameras[name].record.enabled else "OFF", retain=True, ) client.publish( diff --git a/web/src/api/__tests__/mqtt.test.jsx b/web/src/api/__tests__/mqtt.test.jsx index 8e1705b7c..31b539522 100644 --- a/web/src/api/__tests__/mqtt.test.jsx +++ b/web/src/api/__tests__/mqtt.test.jsx @@ -107,12 +107,12 @@ describe('MqttProvider', () => { ); }); - test('prefills the clips/detect/snapshots state from config', async () => { + test('prefills the recordings/detect/snapshots state from config', async () => { jest.spyOn(Date, 'now').mockReturnValue(123456); const config = { cameras: { - front: { name: 'front', detect: { enabled: true }, clips: { enabled: false }, snapshots: { enabled: true } }, - side: { name: 'side', detect: { enabled: false }, clips: { enabled: false }, snapshots: { enabled: false } }, + front: { name: 'front', detect: { enabled: true }, record: { enabled: false }, snapshots: { enabled: true } }, + side: { name: 'side', detect: { enabled: false }, record: { enabled: false }, snapshots: { enabled: false } }, }, }; render( @@ -122,10 +122,10 @@ describe('MqttProvider', () => { ); await screen.findByTestId('data'); expect(screen.getByTestId('front/detect/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"ON"}'); - expect(screen.getByTestId('front/clips/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"OFF"}'); + expect(screen.getByTestId('front/recordings/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"OFF"}'); expect(screen.getByTestId('front/snapshots/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"ON"}'); expect(screen.getByTestId('side/detect/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"OFF"}'); - expect(screen.getByTestId('side/clips/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"OFF"}'); + expect(screen.getByTestId('side/recordings/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"OFF"}'); expect(screen.getByTestId('side/snapshots/state')).toHaveTextContent('{"lastUpdate":123456,"payload":"OFF"}'); }); }); diff --git a/web/src/api/mqtt.jsx b/web/src/api/mqtt.jsx index b4b15d6fa..5d7639450 100644 --- a/web/src/api/mqtt.jsx +++ b/web/src/api/mqtt.jsx @@ -41,8 +41,8 @@ export function MqttProvider({ useEffect(() => { Object.keys(config.cameras).forEach((camera) => { - const { name, clips, detect, snapshots } = config.cameras[camera]; - dispatch({ topic: `${name}/clips/state`, payload: clips.enabled ? 'ON' : 'OFF' }); + const { name, record, detect, snapshots } = config.cameras[camera]; + dispatch({ topic: `${name}/recordings/state`, payload: record.enabled ? 'ON' : 'OFF' }); dispatch({ topic: `${name}/detect/state`, payload: detect.enabled ? 'ON' : 'OFF' }); dispatch({ topic: `${name}/snapshots/state`, payload: snapshots.enabled ? 'ON' : 'OFF' }); }); @@ -101,12 +101,12 @@ export function useDetectState(camera) { return { payload, send, connected }; } -export function useClipsState(camera) { +export function useRecordingsState(camera) { const { value: { payload }, send, connected, - } = useMqtt(`${camera}/clips/state`, `${camera}/clips/set`); + } = useMqtt(`${camera}/recordings/state`, `${camera}/recordings/set`); return { payload, send, connected }; } diff --git a/web/src/routes/Cameras.jsx b/web/src/routes/Cameras.jsx index b0bb5a228..94b7cb7f1 100644 --- a/web/src/routes/Cameras.jsx +++ b/web/src/routes/Cameras.jsx @@ -5,7 +5,7 @@ import CameraImage from '../components/CameraImage'; import ClipIcon from '../icons/Clip'; import MotionIcon from '../icons/Motion'; import SnapshotIcon from '../icons/Snapshot'; -import { useDetectState, useClipsState, useSnapshotsState } from '../api/mqtt'; +import { useDetectState, useRecordingsState, useSnapshotsState } from '../api/mqtt'; import { useConfig, FetchStatus } from '../api'; import { useMemo } from 'preact/hooks'; @@ -25,7 +25,7 @@ export default function Cameras() { function Camera({ name, conf }) { const { payload: detectValue, send: sendDetect } = useDetectState(name); - const { payload: clipValue, send: sendClips } = useClipsState(name); + const { payload: recordValue, send: sendRecordings } = useRecordingsState(name); const { payload: snapshotValue, send: sendSnapshots } = useSnapshotsState(name); const href = `/cameras/${name}`; const buttons = useMemo(() => { @@ -46,11 +46,11 @@ function Camera({ name, conf }) { }, }, { - name: `Toggle clips ${clipValue === 'ON' ? 'off' : 'on'}`, + name: `Toggle recordings ${recordValue === 'ON' ? 'off' : 'on'}`, icon: ClipIcon, - color: clipValue === 'ON' ? 'blue' : 'gray', + color: recordValue === 'ON' ? 'blue' : 'gray', onClick: () => { - sendClips(clipValue === 'ON' ? 'OFF' : 'ON'); + sendRecordings(recordValue === 'ON' ? 'OFF' : 'ON'); }, }, { @@ -62,7 +62,7 @@ function Camera({ name, conf }) { }, }, ], - [detectValue, sendDetect, clipValue, sendClips, snapshotValue, sendSnapshots] + [detectValue, sendDetect, recordValue, sendRecordings, snapshotValue, sendSnapshots] ); return ( diff --git a/web/src/routes/__tests__/Cameras.test.jsx b/web/src/routes/__tests__/Cameras.test.jsx index 9828e527c..68d0d0a80 100644 --- a/web/src/routes/__tests__/Cameras.test.jsx +++ b/web/src/routes/__tests__/Cameras.test.jsx @@ -51,13 +51,13 @@ describe('Cameras Route', () => { test('buttons toggle detect, clips, and snapshots', async () => { const sendDetect = jest.fn(); - const sendClips = jest.fn(); + const sendRecordings = jest.fn(); const sendSnapshots = jest.fn(); jest.spyOn(Mqtt, 'useDetectState').mockImplementation(() => { return { payload: 'ON', send: sendDetect }; }); - jest.spyOn(Mqtt, 'useClipsState').mockImplementation(() => { - return { payload: 'OFF', send: sendClips }; + jest.spyOn(Mqtt, 'useRecordingsState').mockImplementation(() => { + return { payload: 'OFF', send: sendRecordings }; }); jest.spyOn(Mqtt, 'useSnapshotsState').mockImplementation(() => { return { payload: 'ON', send: sendSnapshots }; @@ -72,11 +72,11 @@ describe('Cameras Route', () => { fireEvent.click(screen.getAllByLabelText('Toggle snapshots off')[0]); expect(sendSnapshots).toHaveBeenCalledWith('OFF'); - fireEvent.click(screen.getAllByLabelText('Toggle clips on')[0]); - expect(sendClips).toHaveBeenCalledWith('ON'); + fireEvent.click(screen.getAllByLabelText('Toggle recordings on')[0]); + expect(sendRecordings).toHaveBeenCalledWith('ON'); expect(sendDetect).toHaveBeenCalledTimes(1); expect(sendSnapshots).toHaveBeenCalledTimes(1); - expect(sendClips).toHaveBeenCalledTimes(1); + expect(sendRecordings).toHaveBeenCalledTimes(1); }); });