iobroker.agent-dvr 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.de.md CHANGED
@@ -45,6 +45,9 @@ Verbindet ioBroker mit [AgentDVR](https://www.ispyconnect.com): Kameras und Mikr
45
45
  | Übersichts-Widget | Einzelner HTML-State mit allen Kamera-Live-Kacheln | `true` |
46
46
  | Galerie-Widget pro Kamera | HTML-Aufnahmegalerie pro Kamera | `true` |
47
47
  | Roh-API-JSON speichern | Die vollständige getObjects-Antwort in `system.raw_getObjects` schreiben | `false` |
48
+ | go2rtc aktivieren | WebRTC-Streams von go2rtc statt MJPEG im Dashboard verwenden | `false` |
49
+ | go2rtc URL | Basis-URL des go2rtc-Servers, z.B. `http://192.168.1.10:1984` | — |
50
+ | Stream-Mapping | Tabelle pro Kamera: AgentDVR-Kamera-Key → go2rtc-Stream-Name | — |
48
51
 
49
52
  ## Datenpunkte
50
53
 
@@ -157,6 +160,32 @@ Die rohen Gerätedaten aus AgentDVR werden rekursiv gespiegelt (Tiefe konfigurie
157
160
  |-----------|-----|-----|-------------|
158
161
  | `overview` | string | R | HTML-Kachelraster aller Kameras mit Livestream-Links |
159
162
 
163
+ ## Live-Dashboard
164
+
165
+ Der Adapter liefert ein eingebautes Live-Dashboard unter `http://<iobroker>:<webport>/agent-dvr/`.
166
+
167
+ **Funktionen:**
168
+ - MJPEG- oder WebRTC-Livestream pro Kachel (konfigurierbar)
169
+ - Vollbild-Ansicht mit PTZ-Overlay und Aufnahme-Button
170
+ - Echtzeit-Bewegungs- (gelber Rahmen) und Alert-Indikator (oranger Rahmen)
171
+ - Aufnahmen-Tab mit Raster- und Timeline-Ansicht, Suche und Tag-Filter, Video-Player mit Vor/Zurück-Navigation
172
+ - Farbthema über Adapter-Konfiguration (7 Color-Picker)
173
+
174
+ ## go2rtc WebRTC-Streams
175
+
176
+ Das Dashboard kann [go2rtc](https://github.com/AlexxIT/go2rtc) nutzen, um flüssige WebRTC-Streams statt des MJPEG-Fallbacks anzuzeigen.
177
+
178
+ **Voraussetzung:** go2rtc muss installiert und gestartet sein, mit bereits konfigurierten Streams für die Kameras.
179
+
180
+ **Einrichtung:**
181
+ 1. In der Adapter-Konfiguration → Tab *Live-Dashboard*: **go2rtc aktivieren** und die **go2rtc URL** eintragen (z.B. `http://192.168.1.10:1984`).
182
+ 2. Die **Stream-Mapping**-Tabelle befüllen — eine Zeile pro Kamera:
183
+ - **AgentDVR Kamera-Key**: der ioBroker-Datenpunkt-Präfix, z.B. `cam_8_Reolink` (im ioBroker-Objektbaum sichtbar)
184
+ - **go2rtc Stream-Name**: der Stream-Name wie in der go2rtc-Oberfläche oder unter `/api/streams`, z.B. `Reolink`
185
+ 3. Speichern und Adapter neu starten. Gemappte Kameras zeigen den WebRTC-Stream; nicht gemappte Kameras verwenden weiterhin MJPEG.
186
+
187
+ **Funktionsweise:** Das Dashboard verbindet sich per WebSocket mit dem ioBroker-Webadapter, der die WebRTC-Signalisierung intern an go2rtc weiterleitet. Damit werden Browser-Cross-Origin-Beschränkungen umgangen, ohne go2rtc konfigurieren zu müssen.
188
+
160
189
  ## Snapshot als Base64
161
190
 
162
191
  Der State `snapshot_b64` enthält das aktuelle Kamerabild als `data:image/jpeg;base64,…`-String und kann direkt in vis/vis-2-Bild-Widgets verwendet werden, ohne dass der Browser einen eigenen HTTP-Request durchführen muss.
@@ -171,6 +200,28 @@ Der State `snapshot_b64` enthält das aktuelle Kamerabild als `data:image/jpeg;b
171
200
  Placeholder for the next version (at the beginning of the line):
172
201
  ### **WORK IN PROGRESS**
173
202
  -->
203
+ ### 0.0.6 (2026-07-01)
204
+ * (ipod86) docs: Live-Dashboard- und go2rtc-WebRTC-Abschnitte zur README hinzugefügt
205
+
206
+ ### 0.0.5 (2026-07-01)
207
+ * (ipod86) feat: go2rtc WebRTC-Stream-Integration — Mapping-Tabelle pro Kamera im Admin, ioBroker WebSocket-Proxy umgeht Browser-Cross-Origin-Sperre
208
+ * (ipod86) feat: Automatisches Löschen von Kamera-/Mikrofon-Datenpunkten wenn das Gerät in AgentDVR entfernt wird
209
+ * (ipod86) feat: Dedizierte `status.*`-Datenpunkte pro Kamera — `recording`, `online`, `connected`, `detected`, `alerted` mit korrekten ioBroker-Rollen
210
+ * (ipod86) feat: `/api/record`-Endpoint — Aufnahme über ioBroker-State aus dem Dashboard starten/stoppen
211
+ * (ipod86) feat: Dashboard — vollständiges Farbthema (7 Color-Picker), konfigurierbarer Tag-Badge-Bereich
212
+ * (ipod86) feat: Dashboard — Aufnahme-/Stop-Button auf Kacheln und im Vollbild-Panel
213
+ * (ipod86) feat: Dashboard — Echtzeit-Bewegungs- (gelber Rahmen) und Alert-Indikator (oranger Rahmen) via Socket.io
214
+ * (ipod86) feat: Dashboard — Aufnahme-Timeline in der Aufnahmen-Ansicht: proportionale Blöcke pro Tag, Klick zum Abspielen
215
+ * (ipod86) feat: Dashboard — PTZ- und Aufnahme-Buttons im Vollbild-Panel mit PTZ-Overlay
216
+ * (ipod86) feat: Dashboard — Einstellung `dashBtnsVisible`: PTZ- und Aufnahme-Button immer oder nur bei Hover anzeigen
217
+ * (ipod86) feat: Dashboard — MJPEG-Streams stoppen bei Tab-Wechsel, Neustart beim Zurückkehren (Bandbreite sparen)
218
+ * (ipod86) feat: Dashboard — Zuletzt gewählte Kamera in der Aufnahmen-Ansicht im localStorage gespeichert
219
+ * (ipod86) fix: Dashboard — Vor/Zurück-Navigation bei Aufnahmen folgt nun chronologischer Reihenfolge
220
+ * (ipod86) fix: Dashboard — PTZ-Button-Kontrast verbessert, Download-Button im Video-Modal, Schließen-Button oben rechts
221
+ * (ipod86) fix: Dashboard — Stream-Neuverbindung nach Tab-Rückkehr löst keine Snapshot-Rückfall mehr aus
222
+ * (ipod86) fix: jsonConfig-Header-Einträge fehlendes Pflichtfeld `size` ergänzt (E5512)
223
+ * (ipod86) fix: Admin-Config-Beschriftungen bereinigt (Snapshot Base64, Widget-Tooltips, go2rtc-Tooltip)
224
+
174
225
  ### 0.0.4 (2026-06-27)
175
226
  * (ipod86) fix: DP-Rollen korrigiert: snapshot_b64 → state (E1008), Profil-Selektor → level (E1011)
176
227
 
package/README.md CHANGED
@@ -47,6 +47,9 @@ Connects ioBroker to [AgentDVR](https://www.ispyconnect.com): auto-discovers all
47
47
  | Overview widget | Single HTML state combining all camera live tiles | `true` |
48
48
  | Gallery widget per camera | HTML recording gallery per camera | `true` |
49
49
  | Store raw API JSON | Write the full getObjects response to `system.raw_getObjects` | `false` |
50
+ | Enable go2rtc | Use WebRTC streams from go2rtc instead of MJPEG in the dashboard | `false` |
51
+ | go2rtc URL | Base URL of your go2rtc server, e.g. `http://192.168.1.10:1984` | — |
52
+ | Stream mapping | Per-camera table: AgentDVR camera key → go2rtc stream name | — |
50
53
 
51
54
  ## Data points
52
55
 
@@ -159,6 +162,32 @@ The raw device data from AgentDVR is mirrored recursively (depth configurable, d
159
162
  |-----------|------|-----|-------------|
160
163
  | `overview` | string | R | HTML tile grid of all cameras with live stream links |
161
164
 
165
+ ## Live Dashboard
166
+
167
+ The adapter ships a built-in live dashboard at `http://<iobroker>:<webport>/agent-dvr/`.
168
+
169
+ **Features:**
170
+ - Live MJPEG or WebRTC stream per camera tile (configurable)
171
+ - Fullscreen view with PTZ overlay and record button
172
+ - Real-time motion (yellow border) and alert (orange border) indicators
173
+ - Recordings tab with grid and timeline view, search and tag filter, video player with prev/next navigation
174
+ - Color theming via adapter config (7 color pickers)
175
+
176
+ ## go2rtc WebRTC Streams
177
+
178
+ The dashboard can use [go2rtc](https://github.com/AlexxIT/go2rtc) to display smooth WebRTC streams instead of the MJPEG fallback.
179
+
180
+ **Requirements:** go2rtc must be installed and running, with streams already configured pointing to your cameras.
181
+
182
+ **Setup:**
183
+ 1. In the adapter config → *Live Dashboard* tab, enable **go2rtc** and enter the **go2rtc URL** (e.g. `http://192.168.1.10:1984`).
184
+ 2. Fill in the **Stream mapping** table — one row per camera:
185
+ - **AgentDVR camera key**: the ioBroker data point prefix, e.g. `cam_8_Reolink` (visible in the ioBroker object tree)
186
+ - **go2rtc stream name**: the stream name as shown in go2rtc's web UI or `/api/streams` endpoint, e.g. `Reolink`
187
+ 3. Save and restart the adapter. Mapped cameras show the WebRTC stream; unmapped cameras continue using MJPEG.
188
+
189
+ **How it works:** The dashboard connects via WebSocket to the ioBroker web adapter, which proxies the WebRTC signaling to go2rtc internally. This avoids browser cross-origin restrictions without any go2rtc configuration changes.
190
+
162
191
  ## Snapshot as Base64
163
192
 
164
193
  The `snapshot_b64` state stores the current camera frame as a `data:image/jpeg;base64,…` string so it can be used directly in vis/vis-2 image widgets without a separate HTTP request from the browser.
@@ -173,6 +202,28 @@ The `snapshot_b64` state stores the current camera frame as a `data:image/jpeg;b
173
202
  Placeholder for the next version (at the beginning of the line):
174
203
  ### **WORK IN PROGRESS**
175
204
  -->
205
+ ### 0.0.6 (2026-07-01)
206
+ * (ipod86) docs: add Live Dashboard and go2rtc WebRTC sections to README
207
+
208
+ ### 0.0.5 (2026-07-01)
209
+ * (ipod86) feat: go2rtc WebRTC stream integration — per-camera mapping table in admin, ioBroker WebSocket proxy to bypass browser cross-origin restrictions
210
+ * (ipod86) feat: auto-delete camera/microphone data points when device is removed from AgentDVR
211
+ * (ipod86) feat: dedicated `status.*` data points per camera — `recording`, `online`, `connected`, `detected`, `alerted` with correct ioBroker roles
212
+ * (ipod86) feat: `/api/record` endpoint — start/stop recording via ioBroker state from the dashboard
213
+ * (ipod86) feat: dashboard — full color theming (7 color pickers), configurable tag-badge corner position
214
+ * (ipod86) feat: dashboard — record/stop button on camera tiles and in fullscreen panel
215
+ * (ipod86) feat: dashboard — real-time motion (yellow border) and alert (orange border) indicators via Socket.io subscription
216
+ * (ipod86) feat: dashboard — recording timeline view in recordings tab: proportional blocks per day, click to play
217
+ * (ipod86) feat: dashboard — PTZ and record buttons visible in fullscreen panel with PTZ overlay
218
+ * (ipod86) feat: dashboard — `dashBtnsVisible` setting: always show or hover-only for both PTZ and record buttons
219
+ * (ipod86) feat: dashboard — MJPEG streams stop on tab hide, restart on return (saves bandwidth)
220
+ * (ipod86) feat: dashboard — last selected camera in recordings tab persisted to localStorage
221
+ * (ipod86) fix: dashboard — recording prev/next navigation now follows chronological order
222
+ * (ipod86) fix: dashboard — PTZ button contrast improved, DL button in video modal, X button top-right
223
+ * (ipod86) fix: dashboard — stream reconnect after tab return no longer triggers snapshot fallback
224
+ * (ipod86) fix: jsonConfig header items missing required `size` property (E5512)
225
+ * (ipod86) fix: admin config label improvements (snapshot Base64, widget tooltips, go2rtc tooltip)
226
+
176
227
  ### 0.0.4 (2026-06-27)
177
228
  * (ipod86) fix: snapshot_b64 role corrected to `state` (E1008)
178
229
  * (ipod86) fix: profile selector role corrected to `level` (E1011)
@@ -0,0 +1,169 @@
1
+ /**
2
+ * ioBroker jsonConfig custom component — go2rtc stream mapping table
3
+ * Loaded by the admin when the Dashboard tab is opened in the adapter config.
4
+ * Depends on: global React (provided by the admin page), props.socket (ioBroker socket).
5
+ */
6
+ (function () {
7
+ 'use strict';
8
+
9
+ window.customComponents = window.customComponents || {};
10
+
11
+ var e = React.createElement;
12
+
13
+ // ── Helper: normalize socket methods (Promise or callback-based) ────────
14
+
15
+ function socketGetStates(socket, pattern) {
16
+ try {
17
+ var result = socket.getStates(pattern);
18
+ if (result && typeof result.then === 'function') return result;
19
+ return new Promise(function (resolve, reject) {
20
+ socket.getStates(pattern, function (err, states) {
21
+ if (err) reject(err); else resolve(states || {});
22
+ });
23
+ });
24
+ } catch (ex) { return Promise.reject(ex); }
25
+ }
26
+
27
+ function socketSendTo(socket, target, command, data) {
28
+ try {
29
+ var result = socket.sendTo(target, command, data);
30
+ if (result && typeof result.then === 'function') return result;
31
+ return new Promise(function (resolve) {
32
+ socket.sendTo(target, command, data, function (res) { resolve(res); });
33
+ });
34
+ } catch (ex) { return Promise.resolve(null); }
35
+ }
36
+
37
+ // ── Component ───────────────────────────────────────────────────────────
38
+
39
+ function Go2rtcMapping(props) {
40
+ var useState = React.useState;
41
+ var useEffect = React.useEffect;
42
+ var useMemo = React.useMemo;
43
+
44
+ var _cameras = useState(null); // null = loading
45
+ var cameras = _cameras[0]; var setCameras = _cameras[1];
46
+ var _streams = useState([]);
47
+ var streams = _streams[0]; var setStreams = _streams[1];
48
+ var _error = useState(null);
49
+ var error = _error[0]; var setError = _error[1];
50
+
51
+ var instanceStr = 'agent-dvr.' + (props.instance !== undefined ? String(props.instance) : '0');
52
+
53
+ // Parse current mapping from data
54
+ var mapping = useMemo(function () {
55
+ try {
56
+ var raw = props.data && props.data.go2rtcMapping;
57
+ return raw ? JSON.parse(raw) : {};
58
+ } catch (_) { return {}; }
59
+ }, [props.data && props.data.go2rtcMapping]);
60
+
61
+ useEffect(function () {
62
+ if (!props.socket) { setCameras([]); return; }
63
+
64
+ // Fetch cameras from ioBroker states + go2rtc streams via sendTo in parallel
65
+ Promise.all([
66
+ socketGetStates(props.socket, instanceStr + '.cam_*.name'),
67
+ socketSendTo(props.socket, instanceStr, 'getGo2rtcStreams', null),
68
+ ]).then(function (results) {
69
+ var states = results[0] || {};
70
+ var g2result = results[1];
71
+
72
+ // Build camera list from states: id pattern = agent-dvr.0.cam_xxx.name
73
+ var cams = [];
74
+ Object.entries(states).forEach(function (entry) {
75
+ var id = entry[0];
76
+ var state = entry[1];
77
+ var match = id.match(/\.(cam_[^.]+)\.name$/);
78
+ if (match && state && state.val != null) {
79
+ cams.push({ key: match[1], name: String(state.val) });
80
+ }
81
+ });
82
+ cams.sort(function (a, b) { return a.name.localeCompare(b.name); });
83
+ setCameras(cams);
84
+
85
+ var strs = (g2result && Array.isArray(g2result.streams)) ? g2result.streams : [];
86
+ setStreams(strs);
87
+ }).catch(function (err) {
88
+ setError(String(err && err.message ? err.message : err));
89
+ setCameras([]);
90
+ });
91
+ }, [instanceStr]);
92
+
93
+ function updateMapping(camKey, streamName) {
94
+ var newMapping = Object.assign({}, mapping);
95
+ if (streamName) {
96
+ newMapping[camKey] = streamName;
97
+ } else {
98
+ delete newMapping[camKey];
99
+ }
100
+ if (props.onChange) props.onChange('go2rtcMapping', JSON.stringify(newMapping));
101
+ }
102
+
103
+ // Don't render if go2rtcEnabled is false
104
+ if (!props.data || !props.data.go2rtcEnabled) return null;
105
+
106
+ if (cameras === null) {
107
+ return e('div', { style: { color: '#888', fontSize: '13px', padding: '6px 0' } },
108
+ 'Lade Kamera- und Stream-Liste…');
109
+ }
110
+
111
+ if (error) {
112
+ return e('div', { style: { color: '#ef4444', fontSize: '13px', padding: '6px 0' } },
113
+ 'Fehler: ' + error);
114
+ }
115
+
116
+ var isDark = props.themeType === 'dark';
117
+ var borderColor = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)';
118
+ var mutedColor = isDark ? 'rgba(255,255,255,0.5)' : 'rgba(0,0,0,0.5)';
119
+
120
+ var headerStyle = {
121
+ textAlign: 'left', padding: '5px 10px',
122
+ fontSize: '12px', color: mutedColor, fontWeight: 600,
123
+ borderBottom: '1px solid ' + borderColor,
124
+ };
125
+ var cellStyle = { padding: '6px 10px', fontSize: '13px', verticalAlign: 'middle' };
126
+ var selectStyle = {
127
+ background: 'transparent', border: '1px solid ' + borderColor,
128
+ color: 'inherit', padding: '4px 8px', borderRadius: '4px',
129
+ fontSize: '13px', minWidth: '180px', cursor: 'pointer',
130
+ };
131
+
132
+ var rows = (cameras || []).map(function (cam) {
133
+ var currentStream = (typeof mapping[cam.key] === 'string') ? mapping[cam.key] : '';
134
+ return e('tr', { key: cam.key, style: { borderBottom: '1px solid ' + borderColor } },
135
+ e('td', { style: cellStyle }, cam.name),
136
+ e('td', { style: cellStyle },
137
+ e('select', {
138
+ value: currentStream,
139
+ onChange: function (ev) { updateMapping(cam.key, ev.target.value); },
140
+ style: selectStyle,
141
+ },
142
+ e('option', { value: '' }, '— MJPEG / Snapshot —'),
143
+ streams.map(function (s) { return e('option', { key: s, value: s }, s); })
144
+ )
145
+ )
146
+ );
147
+ });
148
+
149
+ return e('div', { style: { width: '100%', marginTop: '4px' } },
150
+ streams.length === 0 && e('div', {
151
+ style: { color: '#f97316', fontSize: '12px', marginBottom: '8px' }
152
+ }, '⚠ Keine go2rtc-Streams gefunden — go2rtc-URL prüfen und Adapter neu starten.'),
153
+ !cameras.length && e('div', {
154
+ style: { color: mutedColor, fontSize: '12px' }
155
+ }, 'Keine Kameras in ioBroker gefunden — Adapter konfiguriert und gestartet?'),
156
+ cameras.length > 0 && e('table', { style: { borderCollapse: 'collapse', width: '100%' } },
157
+ e('thead', null,
158
+ e('tr', null,
159
+ e('th', { style: headerStyle }, 'AgentDVR-Kamera'),
160
+ e('th', { style: headerStyle }, 'go2rtc Stream')
161
+ )
162
+ ),
163
+ e('tbody', null, rows)
164
+ )
165
+ );
166
+ }
167
+
168
+ window.customComponents['Go2rtcMapping'] = Go2rtcMapping;
169
+ })();
@@ -37,5 +37,101 @@
37
37
  "cfgEventTagsDynamic": "Ereignis-Tags automatisch aus Aufnahmen erkennen",
38
38
  "cfgEventTagsIgnore": "Zu ignorierende Ereignis-Tags (kommagetrennt)",
39
39
  "cfgEventTags": "Feste Ereignis-Tags, die immer erstellt werden (kommagetrennt)",
40
- "cfgEnableSnapshotB64": "Snapshot als Base64 (media.picture-State pro Kamera)"
40
+ "cfgEnableSnapshotB64": "Snapshot als Base64",
41
+ "hdrControls": "Steuerbuttons",
42
+ "hdrEvents": "Ereignisse & Push",
43
+ "hdrDisplay": "Darstellung",
44
+ "hdrDebug": "Debug",
45
+ "hdrWidgetGeneral": "Galerie-Widget",
46
+ "hdrWidgetLayout": "Layout",
47
+ "hdrWidgetTags": "Tags",
48
+ "hdrWidgetPlayer": "Livestream & Player",
49
+ "cfgEnableSystemControls_tt": "Arm/Disarm/Neustart-Buttons, Profil-Selektor und alle systemweiten Steuerbefehle",
50
+ "cfgEnablePtz_tt": "Hold-Switches für PTZ (links/rechts/oben/unten/Zoom) pro Kamera",
51
+ "cfgEnableUrls_tt": "URL-States für Snapshot, MJPEG und MP4-Stream pro Kamera",
52
+ "cfgEnableSnapshotB64_tt": "Kamerabild als Base64 bei jedem Poll speichern (photo.jpg, volle Auflösung). Refresh-Button immer vorhanden.",
53
+ "cfgEnableEventDps_tt": "Metadaten der letzten Aufnahme spiegeln (Dateiname, Datum, Dauer, Tags)",
54
+ "cfgEnablePush_tt": "Push-Trigger-State wird sofort aktualisiert wenn AgentDVR eine neue Aufnahme meldet",
55
+ "cfgEnableOverview_tt": "HTML-State mit allen Kameras als Kachelraster (für Visualisierungen, Dashboards etc.)",
56
+ "cfgStoreRawJson_tt": "Vollständige getObjects-Antwort in system.raw_getObjects schreiben (nützlich für Debugging)",
57
+ "cfgEnableWidget_tt": "HTML-Galerie mit den letzten Aufnahmen pro Kamera (für Visualisierungen, Dashboards etc.)",
58
+ "cfgWidgetMode_tt": "Pure HTML/CSS überall kompatibel. Full JS mit Suchfeld und Tag-Filter (benötigt Script-Ausführung).",
59
+ "cfgWidgetAnzahl_tt": "Maximale Anzahl Aufnahmen in der Galerie pro Kamera",
60
+ "cfgWidgetMinCol_tt": "Minimale Spaltenbreite des Galerie-Grids in Pixeln",
61
+ "cfgWidgetMaxModalWidth_tt": "Maximale Breite des Video-Players im Modal-Dialog in Pixeln",
62
+ "cfgWidgetShowTags_tt": "Event-Tags als farbige Badge-Labels auf den Galerie-Kacheln anzeigen",
63
+ "cfgWidgetTagPosition_tt": "Ecke des Bildes wo der Tag-Badge erscheint",
64
+ "cfgWidgetLiveAspect_tt": "Seitenverhältnis der Livestream-Kachel z.B. 16/9. Leer lassen für automatisch.",
65
+ "cfgWidgetPlayerUrl_tt": "URL eines externen Video-Players. Leer lassen für eingebauten Player.",
66
+ "hdrWidgetFilter": "Filter & Sortierung",
67
+ "cfgWidgetSortNewest": "Neueste zuerst",
68
+ "cfgWidgetSortNewest_tt": "Aufnahmen nach Datum sortieren, neueste zuerst",
69
+ "cfgWidgetShowSearch": "Suchfeld anzeigen (nur JS-Modus)",
70
+ "cfgWidgetShowSearch_tt": "Textsuche über Datum, Tag und Dateiname im JS-Modus einblenden",
71
+ "cfgWidgetCompact": "Kompaktes Layout",
72
+ "cfgWidgetCompact_tt": "Kleinere Abstände und Schrift – mehr Einträge auf einen Blick (wirkt in beiden Modi)",
73
+ "cfgWidgetDefaultTag": "Standard-Tag-Filter (leer = alle)",
74
+ "cfgWidgetDefaultTag_tt": "Dieser Tag ist beim ersten Laden vorausgewählt (nur JS-Modus)",
75
+ "cfgWidgetThumbSize": "Thumbnail-Größe",
76
+ "cfgWidgetThumbSize_tt": "Breite der Vorschaubilder in der Galerie (überschreibt Min. Spaltenbreite)",
77
+ "cfgWidgetThumbSmall": "Klein (120 px)",
78
+ "cfgWidgetThumbMedium": "Mittel (180 px)",
79
+ "cfgWidgetThumbLarge": "Groß (240 px)",
80
+ "tabDashboard": "Live-Dashboard",
81
+ "hdrDashView": "Ansicht",
82
+ "cfgDashDefaultView": "Standard-Ansicht beim Öffnen",
83
+ "cfgDashDefaultView_tt": "Welcher Tab beim Öffnen des Dashboards aktiv ist",
84
+ "cfgDashViewLive": "Live-Ansicht",
85
+ "cfgDashViewRec": "Aufnahmen",
86
+ "cfgDashShowOffline": "Offline-Kameras anzeigen",
87
+ "cfgDashShowOffline_tt": "Kameras die gerade offline sind trotzdem im Live-Grid einblenden",
88
+ "hdrDashGrid": "Kamera-Grid",
89
+ "cfgDashGridCols": "Spaltenanzahl (0 = automatisch)",
90
+ "cfgDashGridCols_tt": "Anzahl Kamera-Spalten fest vorgeben. 0 = optimale Anzahl wird automatisch berechnet.",
91
+ "hdrDashStream": "Stream & Aktualisierung",
92
+ "cfgDashRefreshSec": "Kameraliste neu laden alle (Sekunden)",
93
+ "cfgDashRefreshSec_tt": "Wie oft die Kameraliste vom Server neu geladen wird (0 = kein automatischer Reload)",
94
+ "cfgDashStreamReconnect": "Stream bei Fehler automatisch neu verbinden",
95
+ "cfgDashStreamReconnect_tt": "MJPEG-Stream wird nach einem Verbindungsabbruch automatisch neu gestartet",
96
+ "hdrWidgetTheme": "Farben & Design",
97
+ "cfgWidgetColorCardBg": "Kachel-Hintergrund",
98
+ "cfgWidgetColorCardBg_tt": "Hintergrundfarbe der Vorschaukacheln – rgba(r,g,b,a) oder #hex",
99
+ "cfgWidgetColorTagBg": "Tag-Badge-Hintergrund",
100
+ "cfgWidgetColorTagBg_tt": "Hintergrundfarbe des Tag-Badges",
101
+ "cfgWidgetColorTagText": "Tag-Badge-Textfarbe",
102
+ "cfgWidgetColorTagText_tt": "Textfarbe des Tag-Badges",
103
+ "cfgWidgetColorAccent": "Akzentfarbe",
104
+ "cfgWidgetColorAccent_tt": "Akzentfarbe für Links und Buttons im Widget",
105
+ "cfgWidgetColorModalBg": "Modal-Hintergrund",
106
+ "cfgWidgetColorModalBg_tt": "Hintergrundfarbe des Video-Player-Dialogs",
107
+ "cfgWidgetBorderRadius": "Eckenradius (px)",
108
+ "cfgWidgetBorderRadius_tt": "Abrundungsradius der Vorschaukacheln in Pixeln (0 = eckig)",
109
+ "hdrDashTheme": "Farben & Design",
110
+ "cfgDashColorBg": "Hintergrund",
111
+ "cfgDashColorBg_tt": "Haupthintergrundfarbe des Dashboards",
112
+ "cfgDashColorSurface": "Oberfläche / Karten",
113
+ "cfgDashColorSurface_tt": "Hintergrundfarbe von Kacheln und Karten",
114
+ "cfgDashColorAccent": "Akzentfarbe",
115
+ "cfgDashColorAccent_tt": "Hauptakzentfarbe (Buttons, aktive Elemente, Rahmen)",
116
+ "cfgDashColorText": "Textfarbe",
117
+ "cfgDashColorText_tt": "Primäre Textfarbe",
118
+ "cfgDashColorBorder": "Rahmenfarbe",
119
+ "cfgDashColorBorder_tt": "Farbe von Trennlinien und Rahmen",
120
+ "cfgDashColorOnline": "Online-Farbe",
121
+ "cfgDashColorOnline_tt": "Farbe des Online-Status-Indikators",
122
+ "cfgDashColorOffline": "Offline-Farbe",
123
+ "cfgDashColorOffline_tt": "Farbe des Offline-Status-Indikators",
124
+ "cfgDashTagPosition": "Tag-Badge-Position",
125
+ "cfgDashTagPosition_tt": "Ecke der Aufnahme-Kachel, in der der Tag-Badge erscheint",
126
+ "cfgDashBtnsVisible": "Buttons immer sichtbar",
127
+ "cfgDashBtnsVisible_tt": "Aufnahme- und PTZ-Button immer anzeigen (sonst nur bei Hover)",
128
+ "hdrGo2rtc": "go2rtc WebRTC-Streams",
129
+ "cfgGo2rtcEnabled": "go2rtc aktivieren",
130
+ "cfgGo2rtcEnabled_tt": "WebRTC-Streams von go2rtc statt MJPEG verwenden",
131
+ "cfgGo2rtcUrl": "go2rtc URL",
132
+ "cfgGo2rtcUrl_tt": "Basis-URL des go2rtc-Servers, z. B. http://192.168.1.1:1984",
133
+ "cfgGo2rtcMapping": "Stream-Mapping",
134
+ "cfgGo2rtcMapping_tt": "Ordnet jeder AgentDVR-Kamera einen go2rtc-Stream zu. Füge eine Zeile pro Kamera hinzu. Ohne Eintrag wird MJPEG verwendet.",
135
+ "cfgGo2rtcCamKey": "AgentDVR Kamera-Key (z.B. cam_8_Reolink)",
136
+ "cfgGo2rtcStream": "go2rtc Stream-Name (z.B. Reolink)"
41
137
  }
@@ -37,5 +37,101 @@
37
37
  "cfgEventTagsDynamic": "Auto-detect event tags from recordings",
38
38
  "cfgEventTagsIgnore": "Event tags to ignore (comma-separated)",
39
39
  "cfgEventTags": "Fixed event tags to always create (comma-separated)",
40
- "cfgEnableSnapshotB64": "Snapshot as Base64 (media.picture state per camera)"
40
+ "cfgEnableSnapshotB64": "Snapshot as Base64",
41
+ "hdrControls": "Control Buttons",
42
+ "hdrEvents": "Events & Push",
43
+ "hdrDisplay": "Display",
44
+ "hdrDebug": "Debug",
45
+ "hdrWidgetGeneral": "Gallery Widget",
46
+ "hdrWidgetLayout": "Layout",
47
+ "hdrWidgetTags": "Tags",
48
+ "hdrWidgetPlayer": "Livestream & Player",
49
+ "cfgEnableSystemControls_tt": "Arm/Disarm/Restart buttons, profile selector and all system-wide control commands",
50
+ "cfgEnablePtz_tt": "Hold switches for PTZ (left/right/up/down/zoom) per camera",
51
+ "cfgEnableUrls_tt": "URL states for snapshot, MJPEG and MP4 stream per camera",
52
+ "cfgEnableSnapshotB64_tt": "Save camera image as Base64 on every poll (photo.jpg, full resolution). Refresh button always present.",
53
+ "cfgEnableEventDps_tt": "Mirror metadata of the last recording (filename, date, duration, tags)",
54
+ "cfgEnablePush_tt": "Push trigger state is updated immediately when AgentDVR reports a new recording",
55
+ "cfgEnableOverview_tt": "HTML state with all cameras as tile grid (for visualizations, dashboards etc.)",
56
+ "cfgStoreRawJson_tt": "Write full getObjects response to system.raw_getObjects (useful for debugging)",
57
+ "cfgEnableWidget_tt": "HTML gallery with the latest recordings per camera (for visualizations, dashboards etc.)",
58
+ "cfgWidgetMode_tt": "Pure HTML/CSS compatible everywhere. Full JS with search field and tag filter (requires script execution).",
59
+ "cfgWidgetAnzahl_tt": "Maximum number of recordings in the gallery per camera",
60
+ "cfgWidgetMinCol_tt": "Minimum column width of the gallery grid in pixels",
61
+ "cfgWidgetMaxModalWidth_tt": "Maximum width of the video player in the modal dialog in pixels",
62
+ "cfgWidgetShowTags_tt": "Show event tags as colored badge labels on gallery tiles",
63
+ "cfgWidgetTagPosition_tt": "Corner of the image where the tag badge appears",
64
+ "cfgWidgetLiveAspect_tt": "Aspect ratio of the livestream tile e.g. 16/9. Leave empty for automatic.",
65
+ "cfgWidgetPlayerUrl_tt": "URL of an external video player. Leave empty for built-in player.",
66
+ "hdrWidgetFilter": "Filter & Sort",
67
+ "cfgWidgetSortNewest": "Newest first",
68
+ "cfgWidgetSortNewest_tt": "Sort recordings by date, newest first",
69
+ "cfgWidgetShowSearch": "Show search field (JS mode only)",
70
+ "cfgWidgetShowSearch_tt": "Show text search over date, tag and filename in JS mode",
71
+ "cfgWidgetCompact": "Compact layout",
72
+ "cfgWidgetCompact_tt": "Smaller spacing and font – more entries at a glance (works in both modes)",
73
+ "cfgWidgetDefaultTag": "Default tag filter (empty = all)",
74
+ "cfgWidgetDefaultTag_tt": "This tag is pre-selected on first load (JS mode only)",
75
+ "cfgWidgetThumbSize": "Thumbnail size",
76
+ "cfgWidgetThumbSize_tt": "Width of preview images in the gallery (overrides min. column width)",
77
+ "cfgWidgetThumbSmall": "Small (120 px)",
78
+ "cfgWidgetThumbMedium": "Medium (180 px)",
79
+ "cfgWidgetThumbLarge": "Large (240 px)",
80
+ "tabDashboard": "Live Dashboard",
81
+ "hdrDashView": "View",
82
+ "cfgDashDefaultView": "Default view on open",
83
+ "cfgDashDefaultView_tt": "Which tab is active when the dashboard opens",
84
+ "cfgDashViewLive": "Live view",
85
+ "cfgDashViewRec": "Recordings",
86
+ "cfgDashShowOffline": "Show offline cameras",
87
+ "cfgDashShowOffline_tt": "Include cameras that are currently offline in the live grid",
88
+ "hdrDashGrid": "Camera grid",
89
+ "cfgDashGridCols": "Column count (0 = automatic)",
90
+ "cfgDashGridCols_tt": "Force a fixed number of camera columns. 0 = optimal count is calculated automatically.",
91
+ "hdrDashStream": "Stream & Refresh",
92
+ "cfgDashRefreshSec": "Reload camera list every (seconds)",
93
+ "cfgDashRefreshSec_tt": "How often the camera list is reloaded from the server (0 = no automatic reload)",
94
+ "cfgDashStreamReconnect": "Auto-reconnect stream on error",
95
+ "cfgDashStreamReconnect_tt": "Automatically restart the MJPEG stream after a connection drop",
96
+ "hdrWidgetTheme": "Colors & Design",
97
+ "cfgWidgetColorCardBg": "Tile background",
98
+ "cfgWidgetColorCardBg_tt": "Background color of thumbnail tiles – rgba(r,g,b,a) or #hex",
99
+ "cfgWidgetColorTagBg": "Tag badge background",
100
+ "cfgWidgetColorTagBg_tt": "Background color of the tag badge",
101
+ "cfgWidgetColorTagText": "Tag badge text color",
102
+ "cfgWidgetColorTagText_tt": "Text color of the tag badge",
103
+ "cfgWidgetColorAccent": "Accent color",
104
+ "cfgWidgetColorAccent_tt": "Accent color for links and buttons in the widget",
105
+ "cfgWidgetColorModalBg": "Modal background",
106
+ "cfgWidgetColorModalBg_tt": "Background color of the video player dialog",
107
+ "cfgWidgetBorderRadius": "Border radius (px)",
108
+ "cfgWidgetBorderRadius_tt": "Corner radius of thumbnail tiles in pixels (0 = square)",
109
+ "hdrDashTheme": "Colors & Design",
110
+ "cfgDashColorBg": "Background",
111
+ "cfgDashColorBg_tt": "Main background color of the dashboard",
112
+ "cfgDashColorSurface": "Surface / Cards",
113
+ "cfgDashColorSurface_tt": "Background color of tiles and cards",
114
+ "cfgDashColorAccent": "Accent color",
115
+ "cfgDashColorAccent_tt": "Main accent color (buttons, active elements, borders)",
116
+ "cfgDashColorText": "Text color",
117
+ "cfgDashColorText_tt": "Primary text color",
118
+ "cfgDashColorBorder": "Border color",
119
+ "cfgDashColorBorder_tt": "Color of dividers and borders",
120
+ "cfgDashColorOnline": "Online color",
121
+ "cfgDashColorOnline_tt": "Color of the online status indicator",
122
+ "cfgDashColorOffline": "Offline color",
123
+ "cfgDashColorOffline_tt": "Color of the offline status indicator",
124
+ "cfgDashTagPosition": "Tag badge position",
125
+ "cfgDashTagPosition_tt": "Corner of the recording tile where the tag badge appears",
126
+ "cfgDashBtnsVisible": "Buttons always visible",
127
+ "cfgDashBtnsVisible_tt": "Always show record and PTZ buttons on camera tile (otherwise only visible on hover)",
128
+ "hdrGo2rtc": "go2rtc WebRTC Streams",
129
+ "cfgGo2rtcEnabled": "Enable go2rtc",
130
+ "cfgGo2rtcEnabled_tt": "Use WebRTC streams from go2rtc instead of MJPEG",
131
+ "cfgGo2rtcUrl": "go2rtc URL",
132
+ "cfgGo2rtcUrl_tt": "Base URL of the go2rtc server, e.g. http://192.168.1.1:1984",
133
+ "cfgGo2rtcMapping": "Stream mapping",
134
+ "cfgGo2rtcMapping_tt": "Maps each AgentDVR camera to a go2rtc stream. Add one row per camera. Cameras without an entry fall back to MJPEG.",
135
+ "cfgGo2rtcCamKey": "AgentDVR camera key (e.g. cam_8_Reolink)",
136
+ "cfgGo2rtcStream": "go2rtc stream name (e.g. Reolink)"
41
137
  }
@@ -37,5 +37,101 @@
37
37
  "cfgEventTagsDynamic": "Detectar automáticamente etiquetas de eventos desde grabaciones",
38
38
  "cfgEventTagsIgnore": "Etiquetas de eventos a ignorar (separadas por comas)",
39
39
  "cfgEventTags": "Etiquetas de eventos fijas a crear siempre (separadas por comas)",
40
- "cfgEnableSnapshotB64": "Snapshot como Base64 (estado media.picture por cámara)"
40
+ "cfgEnableSnapshotB64": "Instantánea como Base64",
41
+ "hdrControls": "Control Buttons",
42
+ "hdrEvents": "Events & Push",
43
+ "hdrDisplay": "Display",
44
+ "hdrDebug": "Debug",
45
+ "hdrWidgetGeneral": "Gallery Widget",
46
+ "hdrWidgetLayout": "Layout",
47
+ "hdrWidgetTags": "Tags",
48
+ "hdrWidgetPlayer": "Livestream & Player",
49
+ "cfgEnableSystemControls_tt": "Arm/Disarm/Restart buttons, profile selector and all system-wide control commands",
50
+ "cfgEnablePtz_tt": "Hold switches for PTZ (left/right/up/down/zoom) per camera",
51
+ "cfgEnableUrls_tt": "URL states for snapshot, MJPEG and MP4 stream per camera",
52
+ "cfgEnableSnapshotB64_tt": "Save camera image as Base64 on every poll (photo.jpg, full resolution). Refresh button always present.",
53
+ "cfgEnableEventDps_tt": "Mirror metadata of the last recording (filename, date, duration, tags)",
54
+ "cfgEnablePush_tt": "Push trigger state is updated immediately when AgentDVR reports a new recording",
55
+ "cfgEnableOverview_tt": "Estado HTML con todas las cámaras como cuadrícula (para visualizaciones, paneles, etc.)",
56
+ "cfgStoreRawJson_tt": "Write full getObjects response to system.raw_getObjects (useful for debugging)",
57
+ "cfgEnableWidget_tt": "Galería HTML con las últimas grabaciones por cámara (para visualizaciones, paneles, etc.)",
58
+ "cfgWidgetMode_tt": "Pure HTML/CSS compatible everywhere. Full JS with search field and tag filter (requires script execution).",
59
+ "cfgWidgetAnzahl_tt": "Maximum number of recordings in the gallery per camera",
60
+ "cfgWidgetMinCol_tt": "Minimum column width of the gallery grid in pixels",
61
+ "cfgWidgetMaxModalWidth_tt": "Maximum width of the video player in the modal dialog in pixels",
62
+ "cfgWidgetShowTags_tt": "Show event tags as colored badge labels on gallery tiles",
63
+ "cfgWidgetTagPosition_tt": "Corner of the image where the tag badge appears",
64
+ "cfgWidgetLiveAspect_tt": "Aspect ratio of the livestream tile e.g. 16/9. Leave empty for automatic.",
65
+ "cfgWidgetPlayerUrl_tt": "URL of an external video player. Leave empty for built-in player.",
66
+ "hdrWidgetFilter": "Filter & Sort",
67
+ "cfgWidgetSortNewest": "Newest first",
68
+ "cfgWidgetSortNewest_tt": "Sort recordings by date, newest first",
69
+ "cfgWidgetShowSearch": "Show search field (JS mode only)",
70
+ "cfgWidgetShowSearch_tt": "Show text search over date, tag and filename in JS mode",
71
+ "cfgWidgetCompact": "Compact layout",
72
+ "cfgWidgetCompact_tt": "Smaller spacing and font – more entries at a glance (works in both modes)",
73
+ "cfgWidgetDefaultTag": "Default tag filter (empty = all)",
74
+ "cfgWidgetDefaultTag_tt": "This tag is pre-selected on first load (JS mode only)",
75
+ "cfgWidgetThumbSize": "Thumbnail size",
76
+ "cfgWidgetThumbSize_tt": "Width of preview images in the gallery (overrides min. column width)",
77
+ "cfgWidgetThumbSmall": "Small (120 px)",
78
+ "cfgWidgetThumbMedium": "Medium (180 px)",
79
+ "cfgWidgetThumbLarge": "Large (240 px)",
80
+ "tabDashboard": "Live Dashboard",
81
+ "hdrDashView": "View",
82
+ "cfgDashDefaultView": "Default view on open",
83
+ "cfgDashDefaultView_tt": "Which tab is active when the dashboard opens",
84
+ "cfgDashViewLive": "Live view",
85
+ "cfgDashViewRec": "Recordings",
86
+ "cfgDashShowOffline": "Show offline cameras",
87
+ "cfgDashShowOffline_tt": "Include cameras that are currently offline in the live grid",
88
+ "hdrDashGrid": "Camera grid",
89
+ "cfgDashGridCols": "Column count (0 = automatic)",
90
+ "cfgDashGridCols_tt": "Force a fixed number of camera columns. 0 = optimal count is calculated automatically.",
91
+ "hdrDashStream": "Stream & Refresh",
92
+ "cfgDashRefreshSec": "Reload camera list every (seconds)",
93
+ "cfgDashRefreshSec_tt": "How often the camera list is reloaded from the server (0 = no automatic reload)",
94
+ "cfgDashStreamReconnect": "Auto-reconnect stream on error",
95
+ "cfgDashStreamReconnect_tt": "Automatically restart the MJPEG stream after a connection drop",
96
+ "hdrWidgetTheme": "Colors & Design",
97
+ "cfgWidgetColorCardBg": "Tile background",
98
+ "cfgWidgetColorCardBg_tt": "Background color of thumbnail tiles – rgba(r,g,b,a) or #hex",
99
+ "cfgWidgetColorTagBg": "Tag badge background",
100
+ "cfgWidgetColorTagBg_tt": "Background color of the tag badge",
101
+ "cfgWidgetColorTagText": "Tag badge text color",
102
+ "cfgWidgetColorTagText_tt": "Text color of the tag badge",
103
+ "cfgWidgetColorAccent": "Accent color",
104
+ "cfgWidgetColorAccent_tt": "Accent color for links and buttons in the widget",
105
+ "cfgWidgetColorModalBg": "Modal background",
106
+ "cfgWidgetColorModalBg_tt": "Background color of the video player dialog",
107
+ "cfgWidgetBorderRadius": "Border radius (px)",
108
+ "cfgWidgetBorderRadius_tt": "Corner radius of thumbnail tiles in pixels (0 = square)",
109
+ "hdrDashTheme": "Colors & Design",
110
+ "cfgDashColorBg": "Background",
111
+ "cfgDashColorBg_tt": "Main background color of the dashboard",
112
+ "cfgDashColorSurface": "Surface / Cards",
113
+ "cfgDashColorSurface_tt": "Background color of tiles and cards",
114
+ "cfgDashColorAccent": "Accent color",
115
+ "cfgDashColorAccent_tt": "Main accent color (buttons, active elements, borders)",
116
+ "cfgDashColorText": "Text color",
117
+ "cfgDashColorText_tt": "Primary text color",
118
+ "cfgDashColorBorder": "Border color",
119
+ "cfgDashColorBorder_tt": "Color of dividers and borders",
120
+ "cfgDashColorOnline": "Online color",
121
+ "cfgDashColorOnline_tt": "Color of the online status indicator",
122
+ "cfgDashColorOffline": "Offline color",
123
+ "cfgDashColorOffline_tt": "Color of the offline status indicator",
124
+ "cfgDashTagPosition": "Tag badge position",
125
+ "cfgDashTagPosition_tt": "Corner of the recording tile where the tag badge appears",
126
+ "cfgDashBtnsVisible": "Botones siempre visibles",
127
+ "cfgDashBtnsVisible_tt": "Mostrar siempre los botones de grabación y PTZ (de lo contrario, solo al pasar el cursor)",
128
+ "hdrGo2rtc": "Streams WebRTC go2rtc",
129
+ "cfgGo2rtcEnabled": "Activar go2rtc",
130
+ "cfgGo2rtcEnabled_tt": "Usar streams WebRTC de go2rtc en lugar de MJPEG",
131
+ "cfgGo2rtcUrl": "URL go2rtc",
132
+ "cfgGo2rtcUrl_tt": "URL base del servidor go2rtc, p. ej. http://192.168.1.1:1984",
133
+ "cfgGo2rtcMapping": "Mapeo de streams",
134
+ "cfgGo2rtcMapping_tt": "Asigna cada cámara de AgentDVR a un stream de go2rtc. Añade una fila por cámara. Las cámaras sin entrada utilizan MJPEG.",
135
+ "cfgGo2rtcCamKey": "Clave de cámara AgentDVR (p.ej. cam_8_Reolink)",
136
+ "cfgGo2rtcStream": "Nombre de stream go2rtc (p.ej. Reolink)"
41
137
  }