@camera.ui/camera-ui-eufy 0.0.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/CHANGELOG.md +8 -0
- package/CONTRIBUTING.md +1 -0
- package/LICENSE.md +22 -0
- package/README.md +1 -0
- package/config.schema.json +348 -0
- package/dist/camera.d.ts +21 -0
- package/dist/camera.js +121 -0
- package/dist/camera.js.map +1 -0
- package/dist/eufy/LocalLiveStreamManager.d.ts +31 -0
- package/dist/eufy/LocalLiveStreamManager.js +111 -0
- package/dist/eufy/LocalLiveStreamManager.js.map +1 -0
- package/dist/eufy/Talkback.d.ts +23 -0
- package/dist/eufy/Talkback.js +93 -0
- package/dist/eufy/Talkback.js.map +1 -0
- package/dist/eufy/utils.d.ts +22 -0
- package/dist/eufy/utils.js +103 -0
- package/dist/eufy/utils.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +402 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +36 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +259 -0
- package/dist/utils.js.map +1 -0
- package/example-config.json +13 -0
- package/package.json +64 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalLiveStreamManager.js","sourceRoot":"","sources":["../../src/eufy/LocalLiveStreamManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Duplex } from 'node:stream';
|
|
2
|
+
import type { CameraDevice, PluginLogger } from '@camera.ui/types';
|
|
3
|
+
import type { Device, EufySecurity } from 'eufy-security-client';
|
|
4
|
+
import type { EufyHome } from '../types.js';
|
|
5
|
+
export declare class TalkbackStream extends Duplex {
|
|
6
|
+
private cacheData;
|
|
7
|
+
private talkbackStarted;
|
|
8
|
+
private stopTalkbackTimeout?;
|
|
9
|
+
private targetStream?;
|
|
10
|
+
private eufyClient;
|
|
11
|
+
private cameraSN;
|
|
12
|
+
private logger;
|
|
13
|
+
private home;
|
|
14
|
+
private cameraDevice;
|
|
15
|
+
constructor(home: EufyHome, eufyClient: EufySecurity, eufyDevice: Device, cameraDevice: CameraDevice, logger: PluginLogger);
|
|
16
|
+
private onTalkbackStarted;
|
|
17
|
+
private onTalkbackStopped;
|
|
18
|
+
stopTalkbackStream(): void;
|
|
19
|
+
_read(): void;
|
|
20
|
+
_write(chunk: Buffer, encoding: BufferEncoding, callback: (error?: Error | null | undefined) => void): void;
|
|
21
|
+
private startTalkback;
|
|
22
|
+
private stopTalkback;
|
|
23
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Duplex } from 'node:stream';
|
|
2
|
+
export class TalkbackStream extends Duplex {
|
|
3
|
+
cacheData = [];
|
|
4
|
+
talkbackStarted = false;
|
|
5
|
+
stopTalkbackTimeout;
|
|
6
|
+
targetStream;
|
|
7
|
+
eufyClient;
|
|
8
|
+
cameraSN;
|
|
9
|
+
logger;
|
|
10
|
+
home;
|
|
11
|
+
cameraDevice;
|
|
12
|
+
constructor(home, eufyClient, eufyDevice, cameraDevice, logger) {
|
|
13
|
+
super();
|
|
14
|
+
this.home = home;
|
|
15
|
+
this.eufyClient = eufyClient;
|
|
16
|
+
this.logger = logger;
|
|
17
|
+
this.cameraDevice = cameraDevice;
|
|
18
|
+
this.cameraSN = eufyDevice.getSerial();
|
|
19
|
+
this.eufyClient.on('station talkback start', this.onTalkbackStarted.bind(this));
|
|
20
|
+
this.eufyClient.on('station talkback stop', this.onTalkbackStopped.bind(this));
|
|
21
|
+
}
|
|
22
|
+
onTalkbackStarted(station, device, stream) {
|
|
23
|
+
if (device.getSerial() !== this.cameraSN) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this.logger.debug(this.home.name, this.cameraDevice.name, 'talkback started event from station ' + station.getName());
|
|
27
|
+
if (this.targetStream) {
|
|
28
|
+
this.unpipe(this.targetStream);
|
|
29
|
+
}
|
|
30
|
+
this.targetStream = stream;
|
|
31
|
+
this.pipe(this.targetStream);
|
|
32
|
+
}
|
|
33
|
+
onTalkbackStopped(station, device) {
|
|
34
|
+
if (device.getSerial() !== this.cameraSN) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.logger.debug(this.home.name, this.cameraDevice.name, 'talkback stopped event from station ' + station.getName());
|
|
38
|
+
if (this.targetStream) {
|
|
39
|
+
this.unpipe(this.targetStream);
|
|
40
|
+
}
|
|
41
|
+
this.targetStream = undefined;
|
|
42
|
+
}
|
|
43
|
+
stopTalkbackStream() {
|
|
44
|
+
// remove event listeners
|
|
45
|
+
this.eufyClient.removeListener('station talkback start', this.onTalkbackStarted);
|
|
46
|
+
this.eufyClient.removeListener('station talkback stop', this.onTalkbackStopped);
|
|
47
|
+
this.stopTalkback();
|
|
48
|
+
this.unpipe();
|
|
49
|
+
this.destroy();
|
|
50
|
+
}
|
|
51
|
+
_read() {
|
|
52
|
+
let pushReturn = true;
|
|
53
|
+
while (this.cacheData.length > 0 && pushReturn) {
|
|
54
|
+
const data = this.cacheData.shift();
|
|
55
|
+
pushReturn = this.push(data);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
_write(chunk, encoding, callback) {
|
|
59
|
+
if (this.stopTalkbackTimeout) {
|
|
60
|
+
clearTimeout(this.stopTalkbackTimeout);
|
|
61
|
+
}
|
|
62
|
+
this.stopTalkbackTimeout = setTimeout(() => {
|
|
63
|
+
this.stopTalkback();
|
|
64
|
+
}, 2000);
|
|
65
|
+
if (this.targetStream) {
|
|
66
|
+
this.push(chunk);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
this.cacheData.push(chunk);
|
|
70
|
+
this.startTalkback();
|
|
71
|
+
}
|
|
72
|
+
callback();
|
|
73
|
+
}
|
|
74
|
+
startTalkback() {
|
|
75
|
+
if (!this.talkbackStarted) {
|
|
76
|
+
this.talkbackStarted = true;
|
|
77
|
+
this.logger.debug(this.home.name, this.cameraDevice.name, 'starting talkback');
|
|
78
|
+
this.eufyClient.startStationTalkback(this.cameraSN).catch((err) => {
|
|
79
|
+
this.logger.error(this.home.name, this.cameraDevice.name, 'talkback could not be started: ' + err);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
stopTalkback() {
|
|
84
|
+
if (this.talkbackStarted) {
|
|
85
|
+
this.talkbackStarted = false;
|
|
86
|
+
this.logger.debug(this.home.name, this.cameraDevice.name, 'stopping talkback');
|
|
87
|
+
this.eufyClient.stopStationTalkback(this.cameraSN).catch((err) => {
|
|
88
|
+
this.logger.error(this.home.name, this.cameraDevice.name, 'talkback could not be stopped: ' + err);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=Talkback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Talkback.js","sourceRoot":"","sources":["../../src/eufy/Talkback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Camera } from 'eufy-security-client';
|
|
2
|
+
export declare class Deferred<T> {
|
|
3
|
+
finished: boolean;
|
|
4
|
+
resolve: (value: T | PromiseLike<T>) => this;
|
|
5
|
+
reject: (error: Error) => this;
|
|
6
|
+
promise: Promise<T>;
|
|
7
|
+
}
|
|
8
|
+
export declare class UniversalStream {
|
|
9
|
+
url: string;
|
|
10
|
+
private static socks;
|
|
11
|
+
private server;
|
|
12
|
+
private sock_id;
|
|
13
|
+
private isWin32;
|
|
14
|
+
private readonly startTime;
|
|
15
|
+
private constructor();
|
|
16
|
+
private generateSockPath;
|
|
17
|
+
private generateUrl;
|
|
18
|
+
close(): void;
|
|
19
|
+
static StreamInput(namespace: string, stream: NodeJS.ReadableStream): UniversalStream;
|
|
20
|
+
static StreamOutput(namespace: string, stream: NodeJS.WritableStream): UniversalStream;
|
|
21
|
+
}
|
|
22
|
+
export declare const is_rtsp_ready: (device: Camera) => boolean;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { PropertyName } from 'eufy-security-client';
|
|
2
|
+
import fse from 'fs';
|
|
3
|
+
import net from 'net';
|
|
4
|
+
import { tmpdir } from 'os';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
export class Deferred {
|
|
7
|
+
finished = false;
|
|
8
|
+
resolve;
|
|
9
|
+
reject;
|
|
10
|
+
promise = new Promise((resolve, reject) => {
|
|
11
|
+
this.resolve = (v) => {
|
|
12
|
+
this.finished = true;
|
|
13
|
+
resolve(v);
|
|
14
|
+
return this;
|
|
15
|
+
};
|
|
16
|
+
this.reject = (e) => {
|
|
17
|
+
this.finished = true;
|
|
18
|
+
reject(e);
|
|
19
|
+
return this;
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export class UniversalStream {
|
|
24
|
+
url;
|
|
25
|
+
static socks = new Set();
|
|
26
|
+
server;
|
|
27
|
+
sock_id;
|
|
28
|
+
isWin32 = false;
|
|
29
|
+
startTime = Date.now();
|
|
30
|
+
constructor(namespace, onSocket) {
|
|
31
|
+
this.isWin32 = process.platform === 'win32'; // Cache platform check
|
|
32
|
+
const unique_sock_id = Math.min(...Array.from({ length: 100 }, (_, i) => i + 1).filter((i) => !UniversalStream.socks.has(i)));
|
|
33
|
+
UniversalStream.socks.add(unique_sock_id);
|
|
34
|
+
this.sock_id = unique_sock_id;
|
|
35
|
+
const sockpath = this.generateSockPath(namespace, unique_sock_id);
|
|
36
|
+
this.url = this.generateUrl(sockpath);
|
|
37
|
+
this.server = net
|
|
38
|
+
.createServer(onSocket)
|
|
39
|
+
.on('error', () => {
|
|
40
|
+
this.close();
|
|
41
|
+
})
|
|
42
|
+
.listen(sockpath);
|
|
43
|
+
}
|
|
44
|
+
generateSockPath(namespace, unique_sock_id) {
|
|
45
|
+
let sockpath = '';
|
|
46
|
+
const pipeName = `${namespace}.${unique_sock_id}.sock`; // Use template literals
|
|
47
|
+
if (this.isWin32) {
|
|
48
|
+
const pipePrefix = '\\\\.\\pipe\\';
|
|
49
|
+
sockpath = path.join(pipePrefix, pipeName);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
sockpath = path.join(tmpdir(), pipeName);
|
|
53
|
+
// Use async file operations
|
|
54
|
+
if (fse.existsSync(sockpath)) {
|
|
55
|
+
fse.unlinkSync(sockpath);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return sockpath;
|
|
59
|
+
}
|
|
60
|
+
generateUrl(sockpath) {
|
|
61
|
+
return this.isWin32 ? sockpath : `unix:${sockpath}`; // Use template literals
|
|
62
|
+
}
|
|
63
|
+
close() {
|
|
64
|
+
try {
|
|
65
|
+
if (this.server) {
|
|
66
|
+
this.server.close();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
//
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
if (!this.isWin32 && this.url) {
|
|
74
|
+
try {
|
|
75
|
+
fse.unlinkSync(this.url.replace('unix:', ''));
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
//
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
UniversalStream.socks.delete(this.sock_id);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
static StreamInput(namespace, stream) {
|
|
85
|
+
return new UniversalStream(namespace, (socket) => stream.pipe(socket, { end: true }));
|
|
86
|
+
}
|
|
87
|
+
static StreamOutput(namespace, stream) {
|
|
88
|
+
return new UniversalStream(namespace, (socket) => socket.pipe(stream, { end: true }));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export const is_rtsp_ready = function (device) {
|
|
92
|
+
if (!device.hasProperty('rtspStream')) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
if (!device.getPropertyValue(PropertyName.DeviceRTSPStream)) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
if (device.getPropertyValue(PropertyName.DeviceRTSPStreamUrl) === '') {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/eufy/utils.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { BasePlugin, CameraDevice, FormSubmitResponse, PluginAPI, PluginLogger } from '@camera.ui/types';
|
|
2
|
+
import type { Config, EufyHome, FormAction } from './types.js';
|
|
3
|
+
export default class Eufy implements BasePlugin {
|
|
4
|
+
config: Config;
|
|
5
|
+
logger: PluginLogger;
|
|
6
|
+
api: PluginAPI;
|
|
7
|
+
cameras: Map<string, CameraDevice>;
|
|
8
|
+
private eufyClients;
|
|
9
|
+
private eufyCameras;
|
|
10
|
+
private cleanOrphanedCamerasTimeout?;
|
|
11
|
+
constructor(logger: PluginLogger, api: PluginAPI);
|
|
12
|
+
configureCameras(cameras: CameraDevice[]): void;
|
|
13
|
+
onFormSubmit(actionId: FormAction, home: EufyHome & {
|
|
14
|
+
twoFactorCode?: string;
|
|
15
|
+
} & {
|
|
16
|
+
captchaCode?: string;
|
|
17
|
+
captchaId: string;
|
|
18
|
+
}): Promise<FormSubmitResponse | undefined>;
|
|
19
|
+
private start;
|
|
20
|
+
private stop;
|
|
21
|
+
private closeClient;
|
|
22
|
+
private connectHome;
|
|
23
|
+
private deviceAdded;
|
|
24
|
+
private deviceRemoved;
|
|
25
|
+
private addOrUpdateDevice;
|
|
26
|
+
private checkOrphanedCameras;
|
|
27
|
+
private tryLogin;
|
|
28
|
+
private getClient;
|
|
29
|
+
private createFormResponse;
|
|
30
|
+
private refreshConfig;
|
|
31
|
+
}
|