homebridge-unifi-protect 6.12.0 → 6.12.2
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.md +3 -3
- package/config.schema.json +2 -2
- package/dist/protect-camera.d.ts +1 -1
- package/dist/protect-camera.js +16 -9
- package/dist/protect-camera.js.map +1 -1
- package/dist/protect-chime.js +1 -0
- package/dist/protect-chime.js.map +1 -1
- package/dist/protect-device.js +11 -3
- package/dist/protect-device.js.map +1 -1
- package/dist/protect-doorbell.js +6 -0
- package/dist/protect-doorbell.js.map +1 -1
- package/dist/protect-ffmpeg-codecs.js +6 -0
- package/dist/protect-ffmpeg-codecs.js.map +1 -1
- package/dist/protect-ffmpeg-options.js +4 -0
- package/dist/protect-ffmpeg-options.js.map +1 -1
- package/dist/protect-ffmpeg-record.js +2 -0
- package/dist/protect-ffmpeg-record.js.map +1 -1
- package/dist/protect-ffmpeg-stream.js +3 -0
- package/dist/protect-ffmpeg-stream.js.map +1 -1
- package/dist/protect-ffmpeg.js +15 -0
- package/dist/protect-ffmpeg.js.map +1 -1
- package/dist/protect-light.js +2 -0
- package/dist/protect-light.js.map +1 -1
- package/dist/protect-liveviews.js +7 -0
- package/dist/protect-liveviews.js.map +1 -1
- package/dist/protect-mqtt.js +10 -1
- package/dist/protect-mqtt.js.map +1 -1
- package/dist/protect-nvr-events.js +14 -0
- package/dist/protect-nvr-events.js.map +1 -1
- package/dist/protect-nvr-systeminfo.js +4 -0
- package/dist/protect-nvr-systeminfo.js.map +1 -1
- package/dist/protect-nvr.d.ts +2 -1
- package/dist/protect-nvr.js +37 -26
- package/dist/protect-nvr.js.map +1 -1
- package/dist/protect-options.js +4 -4
- package/dist/protect-options.js.map +1 -1
- package/dist/protect-platform.js +11 -0
- package/dist/protect-platform.js.map +1 -1
- package/dist/protect-record.js +17 -0
- package/dist/protect-record.js.map +1 -1
- package/dist/protect-rtp.d.ts +0 -3
- package/dist/protect-rtp.js +8 -47
- package/dist/protect-rtp.js.map +1 -1
- package/dist/protect-securitysystem.js +2 -0
- package/dist/protect-securitysystem.js.map +1 -1
- package/dist/protect-sensor.js +4 -0
- package/dist/protect-sensor.js.map +1 -1
- package/dist/protect-stream.d.ts +0 -1
- package/dist/protect-stream.js +18 -1
- package/dist/protect-stream.js.map +1 -1
- package/dist/protect-timeshift.js +12 -1
- package/dist/protect-timeshift.js.map +1 -1
- package/dist/protect-viewer.js +1 -0
- package/dist/protect-viewer.js.map +1 -1
- package/homebridge-ui/public/index.html +6 -1002
- package/homebridge-ui/public/lib/featureoptions.mjs +200 -0
- package/homebridge-ui/public/protect-featureoptions.mjs +740 -0
- package/homebridge-ui/public/ui.mjs +144 -0
- package/homebridge-ui/server.js +0 -34
- package/package.json +26 -16
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/* Copyright(C) 2017-2023, HJD (https://github.com/hjdhjd). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* ui.mjs: HBUP webUI.
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
import { ProtectFeatureOptions } from "./protect-featureoptions.mjs";
|
|
8
|
+
|
|
9
|
+
// Keep a list of all the feature options and option groups.
|
|
10
|
+
const featureOptions = new ProtectFeatureOptions();
|
|
11
|
+
|
|
12
|
+
// Toggle our enabled state.
|
|
13
|
+
async function enablePlugin() {
|
|
14
|
+
|
|
15
|
+
// Show the beachball while we setup.
|
|
16
|
+
homebridge.showSpinner();
|
|
17
|
+
|
|
18
|
+
// Create our UI.
|
|
19
|
+
document.getElementById("disabledBanner").style.display = "none";
|
|
20
|
+
featureOptions.currentConfig[0].disablePlugin = false;
|
|
21
|
+
|
|
22
|
+
await homebridge.updatePluginConfig(featureOptions.currentConfig)
|
|
23
|
+
await homebridge.savePluginConfig()
|
|
24
|
+
|
|
25
|
+
// All done. Let the user interact with us.
|
|
26
|
+
homebridge.hideSpinner()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Show a disabled interface.
|
|
30
|
+
function showDisabledBanner() {
|
|
31
|
+
|
|
32
|
+
document.getElementById("disabledBanner").style.display = "block";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Show an navigation bar at the top of the plugin configuration UI.
|
|
36
|
+
function showIntro () {
|
|
37
|
+
|
|
38
|
+
const introLink = document.getElementById("introLink");
|
|
39
|
+
|
|
40
|
+
introLink.addEventListener("click", () => {
|
|
41
|
+
|
|
42
|
+
// Show the beachball while we setup.
|
|
43
|
+
homebridge.showSpinner();
|
|
44
|
+
|
|
45
|
+
// Create our UI.
|
|
46
|
+
document.getElementById("pageIntro").style.display = "none";
|
|
47
|
+
document.getElementById("menuWrapper").style.display = "inline-flex";
|
|
48
|
+
showSettings();
|
|
49
|
+
|
|
50
|
+
// All done. Let the user interact with us.
|
|
51
|
+
homebridge.hideSpinner();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
document.getElementById("pageIntro").style.display = "block";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Show the main plugin configuration tab.
|
|
58
|
+
function showSettings () {
|
|
59
|
+
|
|
60
|
+
// Show the beachball while we setup.
|
|
61
|
+
homebridge.showSpinner();
|
|
62
|
+
|
|
63
|
+
// Create our UI.
|
|
64
|
+
document.getElementById("menuHome").classList.remove("btn-elegant");
|
|
65
|
+
document.getElementById("menuHome").classList.add("btn-primary");
|
|
66
|
+
document.getElementById("menuFeatureOptions").classList.remove("btn-elegant");
|
|
67
|
+
document.getElementById("menuFeatureOptions").classList.add("btn-primary");
|
|
68
|
+
document.getElementById("menuSettings").classList.add("btn-elegant");
|
|
69
|
+
document.getElementById("menuSettings").classList.remove("btn-primary");
|
|
70
|
+
|
|
71
|
+
document.getElementById("pageSupport").style.display = "none";
|
|
72
|
+
document.getElementById("pageFeatureOptions").style.display = "none";
|
|
73
|
+
|
|
74
|
+
homebridge.showSchemaForm();
|
|
75
|
+
|
|
76
|
+
// All done. Let the user interact with us.
|
|
77
|
+
homebridge.hideSpinner();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Show the support tab.
|
|
81
|
+
function showSupport() {
|
|
82
|
+
|
|
83
|
+
// Show the beachball while we setup.
|
|
84
|
+
homebridge.showSpinner();
|
|
85
|
+
homebridge.hideSchemaForm();
|
|
86
|
+
|
|
87
|
+
// Create our UI.
|
|
88
|
+
document.getElementById("menuHome").classList.add("btn-elegant");
|
|
89
|
+
document.getElementById("menuHome").classList.remove("btn-primary");
|
|
90
|
+
document.getElementById("menuFeatureOptions").classList.remove("btn-elegant");
|
|
91
|
+
document.getElementById("menuFeatureOptions").classList.add("btn-primary");
|
|
92
|
+
document.getElementById("menuSettings").classList.remove("btn-elegant");
|
|
93
|
+
document.getElementById("menuSettings").classList.add("btn-primary");
|
|
94
|
+
|
|
95
|
+
document.getElementById("pageSupport").style.display = "block";
|
|
96
|
+
document.getElementById("pageFeatureOptions").style.display = "none";
|
|
97
|
+
|
|
98
|
+
// All done. Let the user interact with us.
|
|
99
|
+
homebridge.hideSpinner();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Launch our webUI.
|
|
103
|
+
async function launchWebUI() {
|
|
104
|
+
|
|
105
|
+
// Retrieve the current plugin configuration.
|
|
106
|
+
featureOptions.currentConfig = await homebridge.getPluginConfig();
|
|
107
|
+
|
|
108
|
+
// Add our event listeners to animate the UI.
|
|
109
|
+
menuHome.addEventListener("click", () => showSupport());
|
|
110
|
+
menuFeatureOptions.addEventListener("click", () => featureOptions.showUI());
|
|
111
|
+
menuSettings.addEventListener("click", () => showSettings());
|
|
112
|
+
disabledEnable.addEventListener("click", () => enablePlugin());
|
|
113
|
+
|
|
114
|
+
if(featureOptions.currentConfig.length) {
|
|
115
|
+
|
|
116
|
+
document.getElementById("menuWrapper").style.display = "inline-flex"
|
|
117
|
+
showSettings();
|
|
118
|
+
|
|
119
|
+
// If the plugin's disabled, inform the user.
|
|
120
|
+
if(featureOptions.currentConfig[0].disablePlugin) {
|
|
121
|
+
|
|
122
|
+
showDisabledBanner();
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
|
|
126
|
+
featureOptions.currentConfig.push({ name: "UniFi Protect" });
|
|
127
|
+
await homebridge.updatePluginConfig(featureOptions.currentConfig);
|
|
128
|
+
showIntro();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Fire off our UI, catching errors along the way.
|
|
133
|
+
try {
|
|
134
|
+
|
|
135
|
+
launchWebUI();
|
|
136
|
+
} catch (err) {
|
|
137
|
+
|
|
138
|
+
// If we had an error instantiating or updating the UI, notify the user.
|
|
139
|
+
homebridge.toast.error(err.message, "Error");
|
|
140
|
+
} finally {
|
|
141
|
+
|
|
142
|
+
// Always leave the UI in a usable place for the end user.
|
|
143
|
+
homebridge.hideSpinner();
|
|
144
|
+
}
|
package/homebridge-ui/server.js
CHANGED
|
@@ -127,40 +127,6 @@ class PluginUiServer extends HomebridgePluginUiServer {
|
|
|
127
127
|
}
|
|
128
128
|
});
|
|
129
129
|
|
|
130
|
-
// Compatibility for older versions of the Homebridge UI.
|
|
131
|
-
this.onRequest("/getCachedAccessories", async () => {
|
|
132
|
-
|
|
133
|
-
try {
|
|
134
|
-
|
|
135
|
-
// Define the plugin and create the array to return.
|
|
136
|
-
const plugin = "homebridge-unifi-protect";
|
|
137
|
-
const devicesToReturn = [];
|
|
138
|
-
|
|
139
|
-
// The path and file of the cached accessories.
|
|
140
|
-
const accFile = this.homebridgeStoragePath + "/accessories/cachedAccessories";
|
|
141
|
-
|
|
142
|
-
// Check the file exists.
|
|
143
|
-
if(fs.existsSync(accFile)) {
|
|
144
|
-
|
|
145
|
-
// Read the cached accessories file
|
|
146
|
-
let cachedAccessories = await fs.promises.readFile(accFile);
|
|
147
|
-
|
|
148
|
-
// Parse the JSON
|
|
149
|
-
cachedAccessories = JSON.parse(cachedAccessories);
|
|
150
|
-
|
|
151
|
-
// We only want the accessories for this plugin
|
|
152
|
-
cachedAccessories.filter(accessory => accessory.plugin === plugin).map(accessory => devicesToReturn.push(accessory));
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Return the array
|
|
156
|
-
return devicesToReturn;
|
|
157
|
-
} catch(err) {
|
|
158
|
-
|
|
159
|
-
// Just return an empty accessory list in case of any errors.
|
|
160
|
-
return [];
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
|
|
164
130
|
this.ready();
|
|
165
131
|
}
|
|
166
132
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-unifi-protect",
|
|
3
|
-
"version": "6.12.
|
|
3
|
+
"version": "6.12.2",
|
|
4
4
|
"displayName": "Homebridge UniFi Protect",
|
|
5
5
|
"description": "Homebridge UniFi Protect plugin providing complete HomeKit integration for the UniFi Protect ecosystem with full support for most features including autoconfiguration, motion detection, multiple controllers, and realtime updates.",
|
|
6
6
|
"author": {
|
|
@@ -25,6 +25,9 @@
|
|
|
25
25
|
"homebridge",
|
|
26
26
|
"homebridge-plugin",
|
|
27
27
|
"homebridge-unifi-protect",
|
|
28
|
+
"homekit",
|
|
29
|
+
"homekit secure video",
|
|
30
|
+
"hksv",
|
|
28
31
|
"camera",
|
|
29
32
|
"doorbell",
|
|
30
33
|
"ubiquiti",
|
|
@@ -49,8 +52,14 @@
|
|
|
49
52
|
"unifi nvr",
|
|
50
53
|
"unifi-nvr",
|
|
51
54
|
"unifios",
|
|
55
|
+
"uvc ai pro",
|
|
56
|
+
"uvc g3 bullet",
|
|
52
57
|
"uvc g3 flex",
|
|
58
|
+
"uvc g3 instant",
|
|
59
|
+
"uvc g4 bullet",
|
|
53
60
|
"uvc g4 doorbell",
|
|
61
|
+
"uvc g4 flex",
|
|
62
|
+
"uvc g4 instant",
|
|
54
63
|
"uvc g4 pro",
|
|
55
64
|
"rtsp"
|
|
56
65
|
],
|
|
@@ -58,6 +67,7 @@
|
|
|
58
67
|
"build": "rimraf ./dist && tsc",
|
|
59
68
|
"clean": "rimraf ./dist",
|
|
60
69
|
"lint": "eslint src/**.ts",
|
|
70
|
+
"jlint": "eslint homebridge-ui/public/**.mjs",
|
|
61
71
|
"postpublish": "npm run clean",
|
|
62
72
|
"prepublishOnly": "npm run lint && npm run build",
|
|
63
73
|
"test": "eslint src/**.ts",
|
|
@@ -65,22 +75,22 @@
|
|
|
65
75
|
},
|
|
66
76
|
"main": "dist/index.js",
|
|
67
77
|
"dependencies": {
|
|
68
|
-
"@homebridge/plugin-ui-utils": "
|
|
69
|
-
"ffmpeg-for-homebridge": "
|
|
70
|
-
"mqtt": "5.0.
|
|
71
|
-
"unifi-protect": "
|
|
72
|
-
"ws": "
|
|
78
|
+
"@homebridge/plugin-ui-utils": "0.1.0",
|
|
79
|
+
"ffmpeg-for-homebridge": "0.1.4",
|
|
80
|
+
"mqtt": "5.0.3",
|
|
81
|
+
"unifi-protect": "4.6.1",
|
|
82
|
+
"ws": "8.13.0"
|
|
73
83
|
},
|
|
74
84
|
"devDependencies": {
|
|
75
|
-
"@types/node": "
|
|
76
|
-
"@types/readable-stream": "
|
|
77
|
-
"@types/ws": "
|
|
78
|
-
"@typescript-eslint/eslint-plugin": "
|
|
79
|
-
"@typescript-eslint/parser": "
|
|
80
|
-
"eslint": "
|
|
81
|
-
"homebridge": "
|
|
82
|
-
"nodemon": "
|
|
83
|
-
"rimraf": "
|
|
84
|
-
"typescript": "
|
|
85
|
+
"@types/node": "20.5.1",
|
|
86
|
+
"@types/readable-stream": "4.0.1",
|
|
87
|
+
"@types/ws": "8.5.5",
|
|
88
|
+
"@typescript-eslint/eslint-plugin": "6.4.0",
|
|
89
|
+
"@typescript-eslint/parser": "6.4.0",
|
|
90
|
+
"eslint": "8.47.0",
|
|
91
|
+
"homebridge": "1.6.1",
|
|
92
|
+
"nodemon": "3.0.1",
|
|
93
|
+
"rimraf": "5.0.1",
|
|
94
|
+
"typescript": "5.1.6"
|
|
85
95
|
}
|
|
86
96
|
}
|