@homebridge-plugins/homebridge-eufy-security 5.0.0-beta.14 → 5.0.0-beta.16
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/config.schema.json +4 -0
- package/dist/account/temporary-authentication.js +3 -1
- package/dist/account/temporary-authentication.js.map +1 -1
- package/dist/configuration.js +11 -1
- package/dist/configuration.js.map +1 -1
- package/dist/diagnostics.js +29 -5
- package/dist/diagnostics.js.map +1 -1
- package/dist/homekit/adapters/lock.js +27 -11
- package/dist/homekit/adapters/lock.js.map +1 -1
- package/dist/homekit/adapters/package-sensor.js +63 -0
- package/dist/homekit/adapters/package-sensor.js.map +1 -0
- package/dist/homekit/adapters/registry.js +2 -0
- package/dist/homekit/adapters/registry.js.map +1 -1
- package/dist/homekit/adapters/security-system.js +10 -0
- package/dist/homekit/adapters/security-system.js.map +1 -1
- package/dist/homekit/coverage-matrix.js +0 -2
- package/dist/homekit/coverage-matrix.js.map +1 -1
- package/dist/homekit/reconciler.js +1 -0
- package/dist/homekit/reconciler.js.map +1 -1
- package/dist/ui/dashboard.js +12 -3
- package/dist/ui/dashboard.js.map +1 -1
- package/homebridge-ui/public/i18n/en.json +11 -3
- package/homebridge-ui/public/i18n/fr.json +11 -3
- package/homebridge-ui/public/index.html +2 -1
- package/homebridge-ui/public/js/app.js +40 -17
- package/homebridge-ui/public/js/dashboard.js +20 -8
- package/i18n/runtime/en.json +4 -2
- package/package.json +4 -4
|
@@ -37,8 +37,10 @@
|
|
|
37
37
|
*
|
|
38
38
|
* A row is the whole control — the state names itself and the select beside it says what it means. An
|
|
39
39
|
* unassigned state shows a dash, which is what keeps Night out of HomeKit until it is given a mode.
|
|
40
|
+
*
|
|
41
|
+
* It is withheld while the security system it maps is turned off, and the stored map is kept for when it is back.
|
|
40
42
|
*/
|
|
41
|
-
function armingModeControl(device, assigned, messages) {
|
|
43
|
+
function armingModeControl(device, assigned, messages, securitySystem) {
|
|
42
44
|
const summary = ARMING_SLOTS.map(
|
|
43
45
|
({ slot, label }) => `${messages[label]} → ${EUFY_MODES.find((mode) => mode.value === assigned[slot])?.label ?? '—'}`,
|
|
44
46
|
).join(' · ');
|
|
@@ -52,17 +54,18 @@
|
|
|
52
54
|
return `<tr><th scope="row"><label for="${id}">${escapeHtml(messages[label])}</label></th><td><select id="${id}" data-preference="armingModes" data-slot="${slot}" data-serial="${escapeHtml(device.serial)}" data-original="${escapeHtml(value)}"><option value=""${value === '' ? ' selected' : ''}>—</option>${options}</select></td></tr>`;
|
|
53
55
|
}).join('');
|
|
54
56
|
const assignedItself = ARMING_SLOTS.some(({ slot }) => assigned[slot] !== DEFAULT_ARMING_MODES[slot]);
|
|
55
|
-
return `<details class="arming-setting" data-setting${assignedItself ? ' open' : ''}${device.represented ? '' : ' hidden'} data-requires-representation><summary><span class="setting-label">${escapeHtml(messages.preferenceArmingModes)}</span><span class="arming-summary">${escapeHtml(summary)}</span></summary><table class="arming-table"><thead><tr><th scope="col">HomeKit</th><th scope="col">eufy</th></tr></thead><tbody>${rows}</tbody></table><p class="snapshot-help">${escapeHtml(messages.armingModesHelp)}</p></details>`;
|
|
57
|
+
return `<details class="arming-setting" data-setting${assignedItself ? ' open' : ''}${device.represented && securitySystem ? '' : ' hidden'} data-requires-representation data-requires-security-system><summary><span class="setting-label">${escapeHtml(messages.preferenceArmingModes)}</span><span class="arming-summary">${escapeHtml(summary)}</span></summary><table class="arming-table"><thead><tr><th scope="col">HomeKit</th><th scope="col">eufy</th></tr></thead><tbody>${rows}</tbody></table><p class="snapshot-help">${escapeHtml(messages.armingModesHelp)}</p></details>`;
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
function preferenceControl(device, key, preference, messages) {
|
|
59
61
|
const labels = {
|
|
60
62
|
represented: messages.preferenceRepresented,
|
|
61
63
|
audio: messages.preferenceAudio,
|
|
64
|
+
securitySystem: messages.preferenceSecuritySystem,
|
|
62
65
|
snapshotMode: messages.preferenceSnapshotMode,
|
|
63
66
|
};
|
|
64
67
|
if (key === 'armingModes') {
|
|
65
|
-
return armingModeControl(device, preference.armingModes, messages);
|
|
68
|
+
return armingModeControl(device, preference.armingModes, messages, preference.securitySystem);
|
|
66
69
|
}
|
|
67
70
|
const represented = preference.represented;
|
|
68
71
|
const dependent = key === 'represented' ? '' : ` data-requires-representation${represented ? '' : ' hidden'}`;
|
|
@@ -254,10 +257,11 @@
|
|
|
254
257
|
}
|
|
255
258
|
|
|
256
259
|
/*
|
|
257
|
-
* The states a diagnostic run can shed light on. Sign-in, another process holding the session,
|
|
258
|
-
* restart
|
|
260
|
+
* The states a diagnostic run can shed light on. Sign-in, another process holding the session, a pending
|
|
261
|
+
* restart, a plugin that stopped on an error, a page that could not load, and a connection that recovers on its
|
|
262
|
+
* own each have their own remedy stated on the page, so sending those to the wizard would be a detour.
|
|
259
263
|
*/
|
|
260
|
-
const DIAGNOSABLE = new Set(['
|
|
264
|
+
const DIAGNOSABLE = new Set(['incomplete', 'missing', 'stale']);
|
|
261
265
|
|
|
262
266
|
function render(result, config, messages, elements) {
|
|
263
267
|
const suffix = result.state
|
|
@@ -310,7 +314,7 @@
|
|
|
310
314
|
const key = control?.dataset?.preference;
|
|
311
315
|
const existing = getConfig();
|
|
312
316
|
if (!existing || !serial || !key) return;
|
|
313
|
-
const defaults = { represented: true, audio: true, snapshotMode: 'Refresh' };
|
|
317
|
+
const defaults = { represented: true, audio: true, securitySystem: true, snapshotMode: 'Refresh' };
|
|
314
318
|
if (key === 'armingModes') {
|
|
315
319
|
await saveArmingMode(control, serial, existing, saveConfig, getMessages, elements);
|
|
316
320
|
return;
|
|
@@ -336,9 +340,16 @@
|
|
|
336
340
|
(candidate) => candidate.dataset.serial === serial,
|
|
337
341
|
);
|
|
338
342
|
tile?.classList.toggle('device-tile-disabled', !value);
|
|
343
|
+
const grid = control.closest('.preference-grid');
|
|
344
|
+
const securityOff = grid?.querySelector('[data-preference="securitySystem"]')?.checked === false;
|
|
345
|
+
grid?.querySelectorAll('[data-requires-representation]').forEach((setting) => {
|
|
346
|
+
setting.hidden = !value || (securityOff && setting.hasAttribute('data-requires-security-system'));
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
if (key === 'securitySystem') {
|
|
339
350
|
control
|
|
340
351
|
.closest('.preference-grid')
|
|
341
|
-
?.querySelectorAll('[data-requires-
|
|
352
|
+
?.querySelectorAll('[data-requires-security-system]')
|
|
342
353
|
.forEach((setting) => {
|
|
343
354
|
setting.hidden = !value;
|
|
344
355
|
});
|
|
@@ -390,6 +401,7 @@
|
|
|
390
401
|
const preference = {
|
|
391
402
|
represented: preferences[device.serial]?.represented ?? true,
|
|
392
403
|
audio: preferences[device.serial]?.audio ?? true,
|
|
404
|
+
securitySystem: preferences[device.serial]?.securitySystem ?? true,
|
|
393
405
|
snapshotMode: preferences[device.serial]?.snapshotMode ?? 'Refresh',
|
|
394
406
|
armingModes: { ...DEFAULT_ARMING_MODES, ...preferences[device.serial]?.armingModes },
|
|
395
407
|
};
|
package/i18n/runtime/en.json
CHANGED
|
@@ -9,17 +9,19 @@
|
|
|
9
9
|
"log.action.checkCameraControl": "Check the camera in the Eufy app; this control is unavailable until it reports its state",
|
|
10
10
|
"log.action.retryCameraControl": "Try the control again; the camera did not confirm the change",
|
|
11
11
|
"log.action.enableCamera": "Turn the camera on in the Eufy app, then open live view again",
|
|
12
|
-
"log.action.
|
|
12
|
+
"log.action.notSupportedYet": "No action is needed; these devices are not supported in HomeKit yet",
|
|
13
13
|
"log.action.reduceConcurrentMedia": "Open live view again; if it keeps happening, close a camera already open or raise the concurrent camera media limit in the plugin settings",
|
|
14
14
|
"log.action.reauthenticate": "Authenticate again in the Homebridge Eufy dashboard, then restart Homebridge",
|
|
15
15
|
"log.action.retryArming": "Retry the security-system control manually",
|
|
16
16
|
"log.action.retryLight": "Retry the smart-light control manually",
|
|
17
17
|
"log.action.retryLiveView": "Open live view again, and check network access between Homebridge and the camera",
|
|
18
|
+
"log.action.setFfmpegPath": "Set a custom FFmpeg path in Advanced settings in the Homebridge Eufy dashboard",
|
|
19
|
+
"log.action.checkFfmpegPath": "FFmpeg could not be started; check the custom FFmpeg path in Advanced settings in the Homebridge Eufy dashboard",
|
|
18
20
|
"log.action.retryLock": "Retry the lock control manually",
|
|
19
21
|
"log.action.retryTalkback": "Close and reopen the camera, then try speaking again",
|
|
20
22
|
"log.action.reviewRuntime": "Review Homebridge Eufy health in the dashboard and restart Homebridge",
|
|
21
23
|
"log.action.stopOtherOwner": "Stop the other Homebridge Eufy owner before restarting Homebridge",
|
|
22
|
-
"log.action.
|
|
24
|
+
"log.action.mapArmingMode": "Assign this mode to a HomeKit state under HomeKit guard modes in the device's settings in the Homebridge Eufy dashboard",
|
|
23
25
|
"log.action.waitBattery": "Wait for complete battery capability evidence",
|
|
24
26
|
"log.action.waitArming": "Wait for complete arming capability evidence",
|
|
25
27
|
"log.action.waitBatteryObservation": "Wait for a valid battery observation",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "Homebridge Eufy",
|
|
3
3
|
"name": "@homebridge-plugins/homebridge-eufy-security",
|
|
4
|
-
"version": "5.0.0-beta.
|
|
4
|
+
"version": "5.0.0-beta.16",
|
|
5
5
|
"description": "Control Eufy Security from homebridge.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -47,17 +47,17 @@
|
|
|
47
47
|
],
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@homebridge/plugin-ui-utils": "^2.2.6",
|
|
50
|
-
"@mega-yfue/eufy-sdk": "0.
|
|
50
|
+
"@mega-yfue/eufy-sdk": "0.3.0",
|
|
51
51
|
"ffmpeg-for-homebridge": "2.2.2"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@homebridge/hap-nodejs": "2.2.3",
|
|
55
|
-
"@types/node": "^26.6.
|
|
55
|
+
"@types/node": "^26.6.3",
|
|
56
56
|
"homebridge": "^2.4.0",
|
|
57
57
|
"prettier": "^3.9.9",
|
|
58
58
|
"rimraf": "^6.1.3",
|
|
59
59
|
"typescript": "^7.0.2",
|
|
60
|
-
"vitest": "^5.0.
|
|
60
|
+
"vitest": "^5.0.2"
|
|
61
61
|
},
|
|
62
62
|
"homepage": "https://homebridge-plugins.github.io/homebridge-eufy/",
|
|
63
63
|
"author": "homebridge-eufy",
|