Break out triggers into their own config section.

This commit is contained in:
Dermot Duffy
2022-06-10 10:07:40 -07:00
parent a295cbd870
commit b8f1fb2aa3
7 changed files with 187 additions and 83 deletions
+40 -20
View File
@@ -114,9 +114,7 @@ See the [fully expanded cameras configuration example](#config-expanded-cameras)
| `webrtc_card` | | :heavy_multiplication_x: | The WebRTC entity/URL to use for this camera with the `webrtc-card` live provider. See below. | | `webrtc_card` | | :heavy_multiplication_x: | The WebRTC entity/URL to use for this camera with the `webrtc-card` live provider. See below. |
| `id` | `camera_entity`, `webrtc_card.entity` or `camera_name` if set (in that preference order). | :heavy_multiplication_x: | An optional identifier to use throughout the card configuration to refer unambiguously to this camera. See [camera IDs](#camera-ids). | | `id` | `camera_entity`, `webrtc_card.entity` or `camera_name` if set (in that preference order). | :heavy_multiplication_x: | An optional identifier to use throughout the card configuration to refer unambiguously to this camera. See [camera IDs](#camera-ids). |
| `dependencies` | | :heavy_multiplication_x: | Other cameras that this camera should depend upon. See [camera dependencies](#camera-dependency-configuration) below. | | `dependencies` | | :heavy_multiplication_x: | Other cameras that this camera should depend upon. See [camera dependencies](#camera-dependency-configuration) below. |
| `trigger_by_motion` | `false` | :heavy_multiplication_x: | Whether to not to trigger the camera (used to trigger [scan mode](#scan-mode) or reseting the default view) by automatically detecting and using the motion `binary_sensor` for this camera. This autodetection only works for Frigate cameras, and only when the motion `binary_sensor` entity has been enabled in Home Assistant.| | `triggers` | | :heavy_multiplication_x: | Define what should cause this camera to update/trigger. See [camera triggers](#camera-trigger-configuration) below. |
| `trigger_by_occupancy` | `true` | :heavy_multiplication_x: | Whether to not to trigger the camera (used to trigger [scan mode](#scan-mode) or reseting the default view) by automatically detecting and using the occupancy `binary_sensor` for this camera. This autodetection only works for Frigate cameras, and only when the occupancy `binary_sensor` entity has been enabled in Home Assistant.|
| `trigger_by_entities` | | :heavy_multiplication_x: | Whether to not to trigger the camera (used to trigger [scan mode](#scan-mode) or reseting the default view) when the state of any Home Assistant entity becomes active (i.e. state becomes `on` or `open`). This works for Frigate or non-Frigate cameras.|
<a name="live-providers"></a> <a name="live-providers"></a>
@@ -162,6 +160,23 @@ cameras:
| `cameras` | | :heavy_multiplication_x: | An optional array of other camera identifiers (see [camera IDs](#camera-ids)). If specified the card will fetch events for this camera and *also* recursively events for the named cameras. All dependent cameras must themselves be a configured camera in the card. This can be useful to group events for cameras that are close together, to always have clips/snapshots show fully merged events across all cameras or to show events for the `birdseye` camera that otherwise would not have events itself.| | `cameras` | | :heavy_multiplication_x: | An optional array of other camera identifiers (see [camera IDs](#camera-ids)). If specified the card will fetch events for this camera and *also* recursively events for the named cameras. All dependent cameras must themselves be a configured camera in the card. This can be useful to group events for cameras that are close together, to always have clips/snapshots show fully merged events across all cameras or to show events for the `birdseye` camera that otherwise would not have events itself.|
| `all_cameras` | `false` | :heavy_multiplication_x: | Shortcut to specify all other cameras as dependent cameras.| | `all_cameras` | `false` | :heavy_multiplication_x: | Shortcut to specify all other cameras as dependent cameras.|
<a name="camera-triggers"></a>
#### Camera Trigger Configuration
The `triggers` block configures what triggers a camera. Triggering can be used to either reset to the default view / update the card, or active the camera in [scan mode](#scan-mode).
```yaml
cameras:
- triggers:
```
| Option | Default | Overridable | Description |
| - | - | - | - |
| `motion` | `false` | :heavy_multiplication_x: | Whether to not to trigger the camera by automatically detecting and using the motion `binary_sensor` for this camera. This autodetection only works for Frigate cameras, and only when the motion `binary_sensor` entity has been enabled in Home Assistant.|
| `occupancy` | `true` | :heavy_multiplication_x: | Whether to not to trigger the camera by automatically detecting and using the occupancy `binary_sensor` for this camera. This autodetection only works for Frigate cameras, and only when the occupancy `binary_sensor` entity has been enabled in Home Assistant.|
| `entities` | | :heavy_multiplication_x: | Whether to not to trigger the camera when the state of any Home Assistant entity becomes active (i.e. state becomes `on` or `open`). This works for Frigate or non-Frigate cameras.|
<a name="camera-ids"></a> <a name="camera-ids"></a>
#### Camera IDs: Refering to cameras in card configuration #### Camera IDs: Refering to cameras in card configuration
@@ -190,7 +205,7 @@ See the [fully expanded view configuration example](#config-expanded-view) for h
| `timeout_seconds` | `300` | :white_check_mark: | A numbers of seconds of inactivity after user interaction, after which the card will reset to the default configured view (i.e. 'screensaver' functionality). Inactivity is defined as lack of mouse/touch interaction with the Frigate card. If the default view occurs sooner (e.g. via `update_seconds` or manually) the timer will be stopped. `0` means disable this functionality. | | `timeout_seconds` | `300` | :white_check_mark: | A numbers of seconds of inactivity after user interaction, after which the card will reset to the default configured view (i.e. 'screensaver' functionality). Inactivity is defined as lack of mouse/touch interaction with the Frigate card. If the default view occurs sooner (e.g. via `update_seconds` or manually) the timer will be stopped. `0` means disable this functionality. |
| `update_seconds` | `0` | :white_check_mark: | A number of seconds after which to automatically update/refresh the default view. See [card updates](#card-updates) below for behavior and usecases. If the default view occurs sooner (e.g. manually) the timer will start over. `0` disables this functionality.| | `update_seconds` | `0` | :white_check_mark: | A number of seconds after which to automatically update/refresh the default view. See [card updates](#card-updates) below for behavior and usecases. If the default view occurs sooner (e.g. manually) the timer will start over. `0` disables this functionality.|
| `update_force` | `false` | :white_check_mark: | Whether automated card updates/refreshes should ignore user interaction. See [card updates](#card-updates) below for behavior and usecases.| | `update_force` | `false` | :white_check_mark: | Whether automated card updates/refreshes should ignore user interaction. See [card updates](#card-updates) below for behavior and usecases.|
| `update_entities` | | :white_check_mark: | **YAML only**: A card-wide list of entities that should cause the view to reset to the default (if the entity only pertains to a particular camera use `trigger_by_entities` for the selected camera instead) See [card updates](#card-updates) below for behavior and usecases.| | `update_entities` | | :white_check_mark: | **YAML only**: A card-wide list of entities that should cause the view to reset to the default (if the entity only pertains to a particular camera use `triggers` for the selected camera instead, see [Trigger Configuration](#camera-triggers)). See [card updates](#card-updates) below for behavior and usecases.|
| `update_cycle_camera` | `false` | :white_check_mark: | When set to `true` the selected camera is cycled on each default view change. | | `update_cycle_camera` | `false` | :white_check_mark: | When set to `true` the selected camera is cycled on each default view change. |
| `render_entities` | | :white_check_mark: | **YAML only**: A list of entity ids that should cause the card to re-render 'in-place'. The view/camera is not changed. `update_*` flags do not pertain/relate to the behavior of this flag. This should **very** rarely be needed, but could be useful if the card is both setting and changing HA state of the same object as could be the case for some complex `card_mod` scenarios ([example](https://github.com/dermotduffy/frigate-hass-card/issues/343)). | | `render_entities` | | :white_check_mark: | **YAML only**: A list of entity ids that should cause the card to re-render 'in-place'. The view/camera is not changed. `update_*` flags do not pertain/relate to the behavior of this flag. This should **very** rarely be needed, but could be useful if the card is both setting and changing HA state of the same object as could be the case for some complex `card_mod` scenarios ([example](https://github.com/dermotduffy/frigate-hass-card/issues/343)). |
| `scan` | | :white_check_mark: | Configuration for [scan mode](#scan-mode). | | `scan` | | :white_check_mark: | Configuration for [scan mode](#scan-mode). |
@@ -207,7 +222,7 @@ view:
scan: scan:
``` ```
Scan mode allows the card to automatically "follow the action". In this mode the card will automatically select a camera in the `live` view when an entity changes to an active state (specifically `on` or `open`). The entities considered are defined by your camera configuration (see `trigger_by_motion`, `trigger_by_occupancy` and `trigger_by_entities` parameters). An untrigger is defined as the state for all the configured entities returning to inactive (i.e. not `on` or `open`), with an optional number of seconds to wait prior to the untriggering (see `untrigger_seconds`). Scan mode allows the card to automatically "follow the action". In this mode the card will automatically select a camera in the `live` view when an entity changes to an active state (specifically `on` or `open`). The entities considered are defined by your camera configuration (see `triggers` parameters). An untrigger is defined as the state for all the configured entities returning to inactive (i.e. not `on` or `open`), with an optional number of seconds to wait prior to the untriggering (see `untrigger_seconds`).
When the camera untriggers, the view will either remain as-is (if `untrigger_reset` is `false`) and the card return to normal operation, or reset to the default view (if `untrigger_reset` is `true` -- the default). When the camera untriggers, the view will either remain as-is (if `untrigger_reset` is `false`) and the card return to normal operation, or reset to the default view (if `untrigger_reset` is `true` -- the default).
@@ -1031,10 +1046,11 @@ cameras:
all_cameras: false all_cameras: false
cameras: cameras:
- camera-2 - camera-2
trigger_by_motion: false triggers:
trigger_by_occupancy: true motion: false
trigger_by_entities: occupancy: true
- binary_sensor.front_door_sensor entities:
- binary_sensor.front_door_sensor
- frigate_url: http://my-other.frigate.local - frigate_url: http://my-other.frigate.local
client_id: frigate-other client_id: frigate-other
camera_name: entrance camera_name: entrance
@@ -1049,10 +1065,11 @@ cameras:
webrtc_card: webrtc_card:
entity: camera.entrance_rtsp entity: camera.entrance_rtsp
url: 'rtsp://username:password@camera:554/av_stream/ch0' url: 'rtsp://username:password@camera:554/av_stream/ch0'
trigger_by_motion: false triggers:
trigger_by_occupancy: true motion: false
trigger_by_entities: occupancy: true
- binary_sensor.entrance_sensor entities:
- binary_sensor.entrance_sensor
dependencies: dependencies:
all_cameras: false all_cameras: false
``` ```
@@ -2360,7 +2377,8 @@ the card to trigger a card update based on that entity -- which causes it to use
the new overriden default immediately. Alternatives to trigger the card to the new overriden default immediately. Alternatives to trigger the card to
change view but without `update_entities` would just be having an change view but without `update_entities` would just be having an
`update_seconds` parameter which reloads the default view that many seconds `update_seconds` parameter which reloads the default view that many seconds
after user interaction stops or through the use of the `trigger_by_entities` option for a given camera. after user interaction stops or through the use of the `triggers` option for a
given camera (see [Trigger Configuration](#camera-triggers)).
```yaml ```yaml
view: view:
@@ -2521,10 +2539,11 @@ cameras:
- camera_entity: camera.back_yard - camera_entity: camera.back_yard
# This camera will automatically trigger by occupancy. # This camera will automatically trigger by occupancy.
- camera_entity: camera.front_door - camera_entity: camera.front_door
trigger_by_occupancy: false triggers:
trigger_by_motion: true occupancy: false
trigger_by_entities: motion: true
- binary_sensor.door_opened entities:
- binary_sensor.door_opened
view: view:
scan: scan:
enabled: true enabled: true
@@ -2545,7 +2564,7 @@ The following table describes the behavior these flags have.
Note that no (other) automated updates are permitted when [scan mode](#scan-mode) is being triggered. Note that no (other) automated updates are permitted when [scan mode](#scan-mode) is being triggered.
In the below "Trigger Entities" refers to the combination of `view.update_entities` and the `trigger_by_entities` for the currently selected camera (which in turn will also include the occupancy and motion sensor entities for Frigate cameras if `trigger_by_occupancy` and `trigger_by_motion` options are enabled). In the below "Trigger Entities" refers to the combination of `view.update_entities` and the `triggers.entities` for the currently selected camera (which in turn will also include the occupancy and motion sensor entities for Frigate cameras if `triggers.occupancy` and `triggers.motion` options are enabled, see [Trigger Configuration](#camera-triggers)).
| `view . update_seconds` | `view . timeout_seconds` | `view . update_force` | Trigger Entities | Behavior | | `view . update_seconds` | `view . timeout_seconds` | `view . update_force` | Trigger Entities | Behavior |
| :-: | :-: | :-: | :-: | - | | :-: | :-: | :-: | :-: | - |
@@ -2575,7 +2594,8 @@ view:
```yaml ```yaml
cameras: cameras:
- entity: camera.office - entity: camera.office
trigger_by_motion: true triggers:
motion: true
``` ```
* Cycle the live view of the camera every 60 seconds * Cycle the live view of the camera every 60 seconds
```yaml ```yaml
+7 -7
View File
@@ -702,21 +702,21 @@ export class FrigateCard extends LitElement {
console.error(e, (e as Error).stack); console.error(e, (e as Error).stack);
} }
if (config.trigger_by_motion) { if (config.triggers.motion) {
const motionEntity = this._getMotionSensor(cache, config); const motionEntity = this._getMotionSensor(cache, config);
if (motionEntity) { if (motionEntity) {
config.trigger_by_entities.push(motionEntity); config.triggers.entities.push(motionEntity);
} }
} }
if (config.trigger_by_occupancy) { if (config.triggers.occupancy) {
const occupancyEntity = this._getOccupancySensor(cache, config); const occupancyEntity = this._getOccupancySensor(cache, config);
if (occupancyEntity) { if (occupancyEntity) {
config.trigger_by_entities.push(occupancyEntity); config.triggers.entities.push(occupancyEntity);
} }
} }
} }
config.trigger_by_entities = [...new Set(config.trigger_by_entities)]; config.triggers.entities = [...new Set(config.triggers.entities)];
const id = getCameraID(config); const id = getCameraID(config);
if (!id) { if (!id) {
@@ -996,7 +996,7 @@ export class FrigateCard extends LitElement {
let triggerChanges = false; let triggerChanges = false;
for (const [camera, config] of this._cameras?.entries() ?? []) { for (const [camera, config] of this._cameras?.entries() ?? []) {
const triggerEntities = config?.trigger_by_entities ?? []; const triggerEntities = config.triggers.entities ?? [];
const diffs = getHassDifferences(this._hass, oldHass, triggerEntities, { const diffs = getHassDifferences(this._hass, oldHass, triggerEntities, {
stateOnly: true, stateOnly: true,
}); });
@@ -1096,7 +1096,7 @@ export class FrigateCard extends LitElement {
this._isAutomatedViewUpdateAllowed() && this._isAutomatedViewUpdateAllowed() &&
isHassDifferent(this._hass, oldHass, [ isHassDifferent(this._hass, oldHass, [
...(this._getConfig().view.update_entities || []), ...(this._getConfig().view.update_entities || []),
...(selectedCamera?.trigger_by_entities || []), ...(selectedCamera?.triggers.entities || []),
]) ])
) { ) {
// If entities being monitored have changed then reset the view to the // If entities being monitored have changed then reset the view to the
+6 -6
View File
@@ -25,12 +25,12 @@ export const CONF_CAMERAS_ARRAY_DEPENDENCIES_CAMERAS =
`${CONF_CAMERAS}.#.dependencies.cameras` as const; `${CONF_CAMERAS}.#.dependencies.cameras` as const;
export const CONF_CAMERAS_ARRAY_DEPENDENCIES_ALL_CAMERAS = export const CONF_CAMERAS_ARRAY_DEPENDENCIES_ALL_CAMERAS =
`${CONF_CAMERAS}.#.dependencies.all_cameras` as const; `${CONF_CAMERAS}.#.dependencies.all_cameras` as const;
export const CONF_CAMERAS_ARRAY_TRIGGER_BY_MOTION = export const CONF_CAMERAS_ARRAY_TRIGGERS_MOTION =
`${CONF_CAMERAS}.#.trigger_by_motion` as const; `${CONF_CAMERAS}.#.triggers.motion` as const;
export const CONF_CAMERAS_ARRAY_TRIGGER_BY_OCCUPANCY = export const CONF_CAMERAS_ARRAY_TRIGGERS_OCCUPANCY =
`${CONF_CAMERAS}.#.trigger_by_occupancy` as const; `${CONF_CAMERAS}.#.triggers.occupancy` as const;
export const CONF_CAMERAS_ARRAY_TRIGGER_BY_ENTITIES = export const CONF_CAMERAS_ARRAY_TRIGGERS_ENTITIES =
`${CONF_CAMERAS}.#.trigger_by_entities` as const; `${CONF_CAMERAS}.#.triggers.entities` as const;
export const CONF_VIEW = 'view' as const; export const CONF_VIEW = 'view' as const;
export const CONF_VIEW_CAMERA_SELECT = `${CONF_VIEW}.camera_select` as const; export const CONF_VIEW_CAMERA_SELECT = `${CONF_VIEW}.camera_select` as const;
+100 -36
View File
@@ -23,9 +23,9 @@ import {
CONF_CAMERAS_ARRAY_LABEL, CONF_CAMERAS_ARRAY_LABEL,
CONF_CAMERAS_ARRAY_LIVE_PROVIDER, CONF_CAMERAS_ARRAY_LIVE_PROVIDER,
CONF_CAMERAS_ARRAY_TITLE, CONF_CAMERAS_ARRAY_TITLE,
CONF_CAMERAS_ARRAY_TRIGGER_BY_ENTITIES, CONF_CAMERAS_ARRAY_TRIGGERS_ENTITIES,
CONF_CAMERAS_ARRAY_TRIGGER_BY_MOTION, CONF_CAMERAS_ARRAY_TRIGGERS_MOTION,
CONF_CAMERAS_ARRAY_TRIGGER_BY_OCCUPANCY, CONF_CAMERAS_ARRAY_TRIGGERS_OCCUPANCY,
CONF_CAMERAS_ARRAY_URL, CONF_CAMERAS_ARRAY_URL,
CONF_CAMERAS_ARRAY_WEBRTC_CARD_ENTITY, CONF_CAMERAS_ARRAY_WEBRTC_CARD_ENTITY,
CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL,
@@ -114,6 +114,9 @@ import { getEntitiesFromHASS, sideLoadHomeAssistantElements } from './utils/ha';
const MENU_BUTTONS = 'buttons'; const MENU_BUTTONS = 'buttons';
const MENU_CAMERAS = 'cameras'; const MENU_CAMERAS = 'cameras';
const MENU_CAMERAS_DEPENDENCIES = 'cameras.dependencies';
const MENU_CAMERAS_TRIGGERS = 'cameras.triggers';
const MENU_CAMERAS_WEBRTC = 'cameras.webrtc';
const MENU_OPTIONS = 'options'; const MENU_OPTIONS = 'options';
const MENU_VIEW_SCAN = 'scan'; const MENU_VIEW_SCAN = 'scan';
@@ -706,6 +709,46 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
`; `;
} }
/**
* Put a given rendered template into a submenu.
* @param domain The submenu domain.
* @param key The submenu key.
* @param icon The icon for the submenu.
* @param labelPath The path to the label to localize.
* @param template The template to put in the submenu.
* @returns
*/
protected _putInSubmenu(
domain: string,
key: unknown,
icon: string,
labelPath: string,
template: TemplateResult,
): TemplateResult {
const submenuClasses = {
submenu: true,
selected: this._expandedMenus[domain] === key,
};
return html` <div class="${classMap(submenuClasses)}">
<div
class="submenu-header"
@click=${this._toggleMenu}
.domain=${domain}
.key=${key}
>
<ha-icon .icon=${icon}></ha-icon>
<span>${localize(labelPath)}</span>
</div>
${
this._expandedMenus[domain] === key
? html`<div class="values">${template}</div>`
: ''
}
</div>
</div>`;
}
/** /**
* Render a camera section. * Render a camera section.
* @param cameras The full array of cameras. * @param cameras The full array of cameras.
@@ -876,41 +919,62 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
${this._renderStringInput( ${this._renderStringInput(
getArrayConfigPath(CONF_CAMERAS_ARRAY_ID, cameraIndex), getArrayConfigPath(CONF_CAMERAS_ARRAY_ID, cameraIndex),
)} )}
${this._renderEntitySelector( ${this._putInSubmenu(
getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_ENTITY, cameraIndex), MENU_CAMERAS_WEBRTC,
'camera', cameraIndex,
'mdi:webrtc',
'config.cameras.webrtc_card.options',
html`${this._renderEntitySelector(
getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_ENTITY, cameraIndex),
'camera',
)}
${this._renderStringInput(
getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, cameraIndex),
)}`,
)} )}
${this._renderStringInput( ${this._putInSubmenu(
getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, cameraIndex), MENU_CAMERAS_DEPENDENCIES,
cameraIndex,
'mdi:graph',
'config.cameras.dependencies.options',
html` ${this._renderSwitch(
getArrayConfigPath(
CONF_CAMERAS_ARRAY_DEPENDENCIES_ALL_CAMERAS,
cameraIndex,
),
frigateCardConfigDefaults.cameras.dependencies.all_cameras,
)}
${this._renderOptionSelector(
getArrayConfigPath(
CONF_CAMERAS_ARRAY_DEPENDENCIES_CAMERAS,
cameraIndex,
),
dependentCameras,
{
multiple: true,
},
)}`,
)} )}
${this._renderSwitch( ${this._putInSubmenu(
getArrayConfigPath( MENU_CAMERAS_TRIGGERS,
CONF_CAMERAS_ARRAY_DEPENDENCIES_ALL_CAMERAS, cameraIndex,
cameraIndex, 'mdi:magnify-scan',
), 'config.cameras.triggers.options',
frigateCardConfigDefaults.cameras.dependencies.all_cameras, html` ${this._renderSwitch(
)} getArrayConfigPath(CONF_CAMERAS_ARRAY_TRIGGERS_OCCUPANCY, cameraIndex),
${this._renderOptionSelector( frigateCardConfigDefaults.cameras.triggers.occupancy,
getArrayConfigPath(CONF_CAMERAS_ARRAY_DEPENDENCIES_CAMERAS, cameraIndex), )}
dependentCameras, ${this._renderSwitch(
{ getArrayConfigPath(CONF_CAMERAS_ARRAY_TRIGGERS_MOTION, cameraIndex),
multiple: true, frigateCardConfigDefaults.cameras.triggers.motion,
}, )}
)} ${this._renderOptionSelector(
${this._renderSwitch( getArrayConfigPath(CONF_CAMERAS_ARRAY_TRIGGERS_ENTITIES, cameraIndex),
getArrayConfigPath(CONF_CAMERAS_ARRAY_TRIGGER_BY_OCCUPANCY, cameraIndex), entities,
frigateCardConfigDefaults.cameras.trigger_by_occupancy, {
)} multiple: true,
${this._renderSwitch( },
getArrayConfigPath(CONF_CAMERAS_ARRAY_TRIGGER_BY_MOTION, cameraIndex), )}`,
frigateCardConfigDefaults.cameras.trigger_by_motion,
)}
${this._renderOptionSelector(
getArrayConfigPath(CONF_CAMERAS_ARRAY_TRIGGER_BY_ENTITIES, cameraIndex),
entities,
{
multiple: true,
},
)} )}
</div>` </div>`
: ``} : ``}
+8 -3
View File
@@ -16,6 +16,7 @@
"camera_name": "Frigate camera name (Autodetected from entity)", "camera_name": "Frigate camera name (Autodetected from entity)",
"client_id": "Frigate client id (For >1 Frigate server)", "client_id": "Frigate client id (For >1 Frigate server)",
"dependencies": { "dependencies": {
"options": "Dependency Options",
"cameras": "Show events for specific cameras with this camera", "cameras": "Show events for specific cameras with this camera",
"all_cameras": "Show events for all cameras with this camera" "all_cameras": "Show events for all cameras with this camera"
}, },
@@ -31,10 +32,14 @@
"frigate-jsmpeg": "Frigate JSMpeg", "frigate-jsmpeg": "Frigate JSMpeg",
"webrtc-card": "WebRTC Card (i.e. AlexxIT's WebRTC Card)" "webrtc-card": "WebRTC Card (i.e. AlexxIT's WebRTC Card)"
}, },
"trigger_by_entities": "Trigger from other entities", "triggers": {
"trigger_by_motion": "Trigger by auto-detecting the motion sensor", "options": "Trigger Options",
"trigger_by_occupancy": "Trigger by auto-detecting the occupancy sensor", "entities": "Trigger from other entities",
"motion": "Trigger by auto-detecting the motion sensor",
"occupancy": "Trigger by auto-detecting the occupancy sensor"
},
"webrtc_card": { "webrtc_card": {
"options": "WebRTC Card Options",
"entity": "WebRTC Card Camera Entity (Not a Frigate camera)", "entity": "WebRTC Card Camera Entity (Not a Frigate camera)",
"url": "WebRTC Card Camera URL" "url": "WebRTC Card Camera URL"
}, },
+13 -2
View File
@@ -44,7 +44,7 @@ div.upgrade span {
cursor: pointer; cursor: pointer;
} }
.submenu.selected .submenu-header { .submenu.selected > .submenu-header {
background-color: var(--primary-color); background-color: var(--primary-color);
color: var(--primary-text-color); color: var(--primary-text-color);
} }
@@ -58,7 +58,7 @@ div.upgrade span {
.submenu-header .new-camera { .submenu-header .new-camera {
font-style: italic; font-style: italic;
} }
.submenu:not(.selected) .submenu-header .new-camera { .submenu:not(.selected) > .submenu-header .new-camera {
color: var(--secondary-text-color, 'black'); color: var(--secondary-text-color, 'black');
} }
@@ -73,6 +73,17 @@ div.upgrade span {
border: 1px solid var(--primary-color); border: 1px solid var(--primary-color);
} }
// Nested menus should shrink width.
.submenu .submenu {
width: calc(100% - 10px * 2);
margin: auto;
margin-bottom: 10px;
}
.submenu :not(.submenu.selected) {
border: none;
}
.submenu .controls { .submenu .controls {
display: inline-block; display: inline-block;
margin-left: auto; margin-left: auto;
+13 -9
View File
@@ -372,13 +372,15 @@ const customSchema = z
export const cameraConfigDefault = { export const cameraConfigDefault = {
client_id: 'frigate' as const, client_id: 'frigate' as const,
live_provider: 'auto' as const, live_provider: 'auto' as const,
trigger_by_motion: false,
trigger_by_occupancy: true,
trigger_by_entities: [],
dependencies: { dependencies: {
all_cameras: false, all_cameras: false,
cameras: [], cameras: [],
}, },
triggers: {
motion: false,
occupancy: true,
entities: [],
},
}; };
const webrtcCardCameraConfigSchema = z.object({ const webrtcCardCameraConfigSchema = z.object({
entity: z.string().optional(), entity: z.string().optional(),
@@ -414,12 +416,14 @@ const cameraConfigSchema = z
}) })
.default(cameraConfigDefault.dependencies), .default(cameraConfigDefault.dependencies),
trigger_by_motion: z.boolean().default(cameraConfigDefault.trigger_by_motion), triggers: z.object({
trigger_by_occupancy: z.boolean().default(cameraConfigDefault.trigger_by_occupancy), motion: z.boolean().default(cameraConfigDefault.triggers.motion),
trigger_by_entities: z occupancy: z.boolean().default(cameraConfigDefault.triggers.occupancy),
.string() entities: z
.array() .string()
.default(cameraConfigDefault.trigger_by_entities), .array()
.default(cameraConfigDefault.triggers.entities),
}).default(cameraConfigDefault.triggers),
}) })
.default(cameraConfigDefault); .default(cameraConfigDefault);
export type CameraConfig = z.infer<typeof cameraConfigSchema>; export type CameraConfig = z.infer<typeof cameraConfigSchema>;