homebridge-nest-accfactory 0.0.4-a → 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/CHANGELOG.md +12 -1
- package/README.md +7 -7
- package/dist/HomeKitDevice.js +21 -10
- package/dist/HomeKitHistory.js +2 -24
- package/dist/camera.js +225 -236
- package/dist/doorbell.js +4 -4
- package/dist/floodlight.js +97 -0
- package/dist/index.js +7 -7
- package/dist/nexustalk.js +229 -422
- package/dist/protect.js +8 -9
- package/dist/protobuf/google/trait/product/camera.proto +1 -0
- package/dist/protobuf/googlehome/foyer.proto +11 -3
- package/dist/protobuf/nest/nexustalk.proto +181 -0
- package/dist/protobuf/nestlabs/eventingapi/v1.proto +6 -2
- package/dist/protobuf/nestlabs/gateway/v1.proto +29 -23
- package/dist/protobuf/nestlabs/gateway/v2.proto +16 -8
- package/dist/protobuf/root.proto +2 -27
- package/dist/protobuf/weave/trait/actuator.proto +13 -0
- package/dist/streamer.js +54 -63
- package/dist/system.js +1105 -1095
- package/dist/thermostat.js +5 -6
- package/package.json +7 -6
- package/dist/protobuf/nest/messages.proto +0 -8
- package/dist/webrtc.js +0 -55
package/dist/streamer.js
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
//
|
|
9
9
|
// The following functions should be overriden in your class which extends this
|
|
10
10
|
//
|
|
11
|
-
// streamer.connect(
|
|
12
|
-
// streamer.close(
|
|
11
|
+
// streamer.connect()
|
|
12
|
+
// streamer.close()
|
|
13
13
|
// streamer.talkingAudio(talkingData)
|
|
14
14
|
// streamer.update(deviceData) <- call super after
|
|
15
15
|
//
|
|
16
|
-
// Code version
|
|
16
|
+
// Code version 13/9/2024
|
|
17
17
|
// Mark Hulskamp
|
|
18
18
|
'use strict';
|
|
19
19
|
|
|
@@ -35,17 +35,17 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Make a define
|
|
|
35
35
|
|
|
36
36
|
// Streamer object
|
|
37
37
|
export default class Streamer {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
host = ''; // Host to connect to or connected too
|
|
44
|
-
socket = null; // TCP socket object
|
|
38
|
+
videoEnabled = undefined; // Video stream on camera enabled or not
|
|
39
|
+
audioEnabled = undefined; // Audio from camera enabled or not
|
|
40
|
+
online = undefined; // Camera online or not
|
|
41
|
+
uuid = undefined; // UUID of the device connecting
|
|
42
|
+
connected = false; // Streamer connected to endpoint
|
|
45
43
|
|
|
46
44
|
// Internal data only for this class
|
|
47
45
|
#outputTimer = undefined; // Timer for non-blocking loop to stream output data
|
|
48
46
|
#outputs = {}; // Output streams ie: buffer, live, record
|
|
47
|
+
#cameraOfflineFrame = undefined; // Camera offline video frame
|
|
48
|
+
#cameraVideoOffFrame = undefined; // Video turned off on camera video frame
|
|
49
49
|
|
|
50
50
|
constructor(deviceData, options) {
|
|
51
51
|
// Setup logger object if passed as option
|
|
@@ -63,6 +63,7 @@ export default class Streamer {
|
|
|
63
63
|
this.online = deviceData?.online === true;
|
|
64
64
|
this.videoEnabled = deviceData?.streaming_enabled === true;
|
|
65
65
|
this.audioEnabled = deviceData?.audio_enabled === true;
|
|
66
|
+
this.uuid = deviceData?.uuid;
|
|
66
67
|
|
|
67
68
|
// Setup location for *.h264 frame files. This can be overriden by a passed in option
|
|
68
69
|
let resourcePath = path.resolve(__dirname + '/res'); // Default location for *.h264 files
|
|
@@ -76,19 +77,19 @@ export default class Streamer {
|
|
|
76
77
|
|
|
77
78
|
// load buffer for camera offline image in .h264 frame
|
|
78
79
|
if (fs.existsSync(path.resolve(resourcePath + '/' + CAMERAOFFLINEH264FILE)) === true) {
|
|
79
|
-
this
|
|
80
|
+
this.#cameraOfflineFrame = fs.readFileSync(path.resolve(resourcePath + '/' + CAMERAOFFLINEH264FILE));
|
|
80
81
|
// remove any H264 NALU from beginning of any video data. We do this as they are added later when output by our ffmpeg router
|
|
81
|
-
if (this
|
|
82
|
-
this
|
|
82
|
+
if (this.#cameraOfflineFrame.indexOf(H264NALStartcode) === 0) {
|
|
83
|
+
this.#cameraOfflineFrame = this.#cameraOfflineFrame.subarray(H264NALStartcode.length);
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
// load buffer for camera stream off image in .h264 frame
|
|
87
88
|
if (fs.existsSync(path.resolve(resourcePath + '/' + CAMERAOFFH264FILE)) === true) {
|
|
88
|
-
this
|
|
89
|
+
this.#cameraVideoOffFrame = fs.readFileSync(path.resolve(resourcePath + '/' + CAMERAOFFH264FILE));
|
|
89
90
|
// remove any H264 NALU from beginning of any video data. We do this as they are added later when output by our ffmpeg router
|
|
90
|
-
if (this
|
|
91
|
-
this
|
|
91
|
+
if (this.#cameraVideoOffFrame.indexOf(H264NALStartcode) === 0) {
|
|
92
|
+
this.#cameraVideoOffFrame = this.#cameraVideoOffFrame.subarray(H264NALStartcode.length);
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
|
|
@@ -103,15 +104,15 @@ export default class Streamer {
|
|
|
103
104
|
Object.values(this.#outputs).forEach((output) => {
|
|
104
105
|
// Monitor for camera going offline and/or video enabled/disabled
|
|
105
106
|
// We'll insert the appropriate video frame into the stream
|
|
106
|
-
if (this.online === false && this
|
|
107
|
+
if (this.online === false && this.#cameraOfflineFrame !== undefined && outputVideoFrame === true) {
|
|
107
108
|
// Camera is offline so feed in our custom h264 frame and AAC silence
|
|
108
|
-
output.buffer.push({ type: 'video', time: dateNow, data: this
|
|
109
|
+
output.buffer.push({ type: 'video', time: dateNow, data: this.#cameraOfflineFrame });
|
|
109
110
|
output.buffer.push({ type: 'audio', time: dateNow, data: AACAudioSilence });
|
|
110
111
|
lastTimeVideo = dateNow;
|
|
111
112
|
}
|
|
112
|
-
if (this.online === true && this.videoEnabled === false && this
|
|
113
|
+
if (this.online === true && this.videoEnabled === false && this.#cameraVideoOffFrame !== undefined && outputVideoFrame === true) {
|
|
113
114
|
// Camera video is turned off so feed in our custom h264 frame and AAC silence
|
|
114
|
-
output.buffer.push({ type: 'video', time: dateNow, data: this
|
|
115
|
+
output.buffer.push({ type: 'video', time: dateNow, data: this.#cameraVideoOffFrame });
|
|
115
116
|
output.buffer.push({ type: 'audio', time: dateNow, data: AACAudioSilence });
|
|
116
117
|
lastTimeVideo = dateNow;
|
|
117
118
|
}
|
|
@@ -150,11 +151,9 @@ export default class Streamer {
|
|
|
150
151
|
startBuffering() {
|
|
151
152
|
if (this.#outputs?.buffer === undefined) {
|
|
152
153
|
// No active buffer session, start connection to streamer
|
|
153
|
-
if (this.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
this?.log?.debug && this.log.debug('Started buffering from "%s"', this.host);
|
|
157
|
-
}
|
|
154
|
+
if (this.connected === false && typeof this.connect === 'function') {
|
|
155
|
+
this?.log?.debug && this.log.debug('Started buffering for uuid "%s"', this.uuid);
|
|
156
|
+
this.connect();
|
|
158
157
|
}
|
|
159
158
|
|
|
160
159
|
this.#outputs.buffer = {
|
|
@@ -199,11 +198,9 @@ export default class Streamer {
|
|
|
199
198
|
});
|
|
200
199
|
}
|
|
201
200
|
|
|
202
|
-
if (this.
|
|
203
|
-
// We do not have an active
|
|
204
|
-
|
|
205
|
-
this.connect(this.host);
|
|
206
|
-
}
|
|
201
|
+
if (this.connected === false && typeof this.connect === 'function') {
|
|
202
|
+
// We do not have an active connection, so startup connection
|
|
203
|
+
this.connect();
|
|
207
204
|
}
|
|
208
205
|
|
|
209
206
|
// Add video/audio streams for our output loop to handle outputting to
|
|
@@ -218,9 +215,9 @@ export default class Streamer {
|
|
|
218
215
|
// finally, we've started live stream
|
|
219
216
|
this?.log?.debug &&
|
|
220
217
|
this.log.debug(
|
|
221
|
-
'Started live stream from "%s" %s
|
|
222
|
-
this.
|
|
223
|
-
talkbackStream !== null && typeof talkbackStream === 'object' ? 'with two-way audio' : '',
|
|
218
|
+
'Started live stream from uuid "%s" %s "%s"',
|
|
219
|
+
this.uuid,
|
|
220
|
+
talkbackStream !== null && typeof talkbackStream === 'object' ? 'with two-way audio and sesssion id of' : 'and sesssion id of',
|
|
224
221
|
sessionID,
|
|
225
222
|
);
|
|
226
223
|
}
|
|
@@ -239,11 +236,9 @@ export default class Streamer {
|
|
|
239
236
|
});
|
|
240
237
|
}
|
|
241
238
|
|
|
242
|
-
if (this.
|
|
243
|
-
// We do not have an active
|
|
244
|
-
|
|
245
|
-
this.connect(this.host);
|
|
246
|
-
}
|
|
239
|
+
if (this.connected === false && typeof this.connect === 'function') {
|
|
240
|
+
// We do not have an active connection, so startup connection
|
|
241
|
+
this.connect();
|
|
247
242
|
}
|
|
248
243
|
|
|
249
244
|
// Add video/audio streams for our output loop to handle outputting to
|
|
@@ -256,44 +251,44 @@ export default class Streamer {
|
|
|
256
251
|
};
|
|
257
252
|
|
|
258
253
|
// Finally we've started the recording stream
|
|
259
|
-
this?.log?.debug && this.log.debug('Started recording stream from "%s" with sesison id of "%s"', this.
|
|
254
|
+
this?.log?.debug && this.log.debug('Started recording stream from uuid "%s" with sesison id of "%s"', this.uuid, sessionID);
|
|
260
255
|
}
|
|
261
256
|
|
|
262
257
|
stopRecordStream(sessionID) {
|
|
263
258
|
// Request to stop a recording stream
|
|
264
|
-
if (
|
|
265
|
-
this?.log?.debug && this.log.debug('Stopped recording stream from "%s"', this.
|
|
259
|
+
if (this.#outputs?.[sessionID] !== undefined) {
|
|
260
|
+
this?.log?.debug && this.log.debug('Stopped recording stream from uuid "%s"', this.uuid);
|
|
266
261
|
delete this.#outputs[sessionID];
|
|
267
262
|
}
|
|
268
263
|
|
|
269
|
-
// If we have no more output streams active, we'll close the connection
|
|
264
|
+
// If we have no more output streams active, we'll close the connection
|
|
270
265
|
if (Object.keys(this.#outputs).length === 0 && typeof this.close === 'function') {
|
|
271
|
-
this.close(
|
|
266
|
+
this.close();
|
|
272
267
|
}
|
|
273
268
|
}
|
|
274
269
|
|
|
275
270
|
stopLiveStream(sessionID) {
|
|
276
271
|
// Request to stop an active live stream
|
|
277
|
-
if (
|
|
278
|
-
this?.log?.debug && this.log.debug('Stopped live stream from "%s"', this.
|
|
272
|
+
if (this.#outputs?.[sessionID] !== undefined) {
|
|
273
|
+
this?.log?.debug && this.log.debug('Stopped live stream from uuid "%s"', this.uuid);
|
|
279
274
|
delete this.#outputs[sessionID];
|
|
280
275
|
}
|
|
281
276
|
|
|
282
|
-
// If we have no more output streams active, we'll close the connection
|
|
277
|
+
// If we have no more output streams active, we'll close the connection
|
|
283
278
|
if (Object.keys(this.#outputs).length === 0 && typeof this.close === 'function') {
|
|
284
|
-
this.close(
|
|
279
|
+
this.close();
|
|
285
280
|
}
|
|
286
281
|
}
|
|
287
282
|
|
|
288
283
|
stopBuffering() {
|
|
289
284
|
if (this.#outputs?.buffer !== undefined) {
|
|
290
|
-
this?.log?.debug && this.log.debug('Stopped buffering from "%s"', this.
|
|
285
|
+
this?.log?.debug && this.log.debug('Stopped buffering from uuid "%s"', this.uuid);
|
|
291
286
|
delete this.#outputs.buffer;
|
|
292
287
|
}
|
|
293
288
|
|
|
294
|
-
// If we have no more output streams active, we'll close the connection
|
|
289
|
+
// If we have no more output streams active, we'll close the connection
|
|
295
290
|
if (Object.keys(this.#outputs).length === 0 && typeof this.close === 'function') {
|
|
296
|
-
this.close(
|
|
291
|
+
this.close();
|
|
297
292
|
}
|
|
298
293
|
}
|
|
299
294
|
|
|
@@ -302,24 +297,20 @@ export default class Streamer {
|
|
|
302
297
|
return;
|
|
303
298
|
}
|
|
304
299
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
this.host = deviceData.streaming_host;
|
|
311
|
-
this?.log?.debug && this.log.debug('New streaming host has requested a new host "%s" for connection', this.host);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (this.online !== deviceData.online || this.videoEnabled !== deviceData.streaming_enabled) {
|
|
300
|
+
if (
|
|
301
|
+
this.online !== deviceData.online ||
|
|
302
|
+
this.videoEnabled !== deviceData.streaming_enabled ||
|
|
303
|
+
this.audioEnabled !== deviceData?.audio_enabled
|
|
304
|
+
) {
|
|
315
305
|
// Online status or streaming status has changed has changed
|
|
316
306
|
this.online = deviceData?.online === true;
|
|
317
307
|
this.videoEnabled = deviceData?.streaming_enabled === true;
|
|
318
|
-
|
|
319
|
-
|
|
308
|
+
this.audioEnabled = deviceData?.audio_enabled === true;
|
|
309
|
+
if ((this.online === false || this.videoEnabled === false || this.audioEnabled === false) && typeof this.close === 'function') {
|
|
310
|
+
this.close(); // as offline or streaming not enabled, close streamer
|
|
320
311
|
}
|
|
321
312
|
if (this.online === true && this.videoEnabled === true && typeof this.connect === 'function') {
|
|
322
|
-
this.connect(
|
|
313
|
+
this.connect(); // Connect for stream
|
|
323
314
|
}
|
|
324
315
|
}
|
|
325
316
|
}
|