@camera.ui/camera-ui-ring 0.0.22 → 0.0.23
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 +8 -10
- package/dist/camera.d.ts +19 -12
- package/dist/camera.js +173 -119
- package/dist/camera.js.map +1 -1
- package/dist/index.d.ts +22 -3
- package/dist/index.js +139 -96
- package/dist/index.js.map +1 -1
- package/dist/peer.d.ts +5 -8
- package/dist/peer.js +18 -34
- package/dist/peer.js.map +1 -1
- package/dist/types.d.ts +1 -16
- package/dist/types.js +1 -2
- package/package.json +27 -18
- package/dist/contract.d.ts +0 -2
- package/dist/contract.js +0 -9
- package/dist/contract.js.map +0 -1
- package/example-config.json +0 -16
package/config.schema.json
CHANGED
|
@@ -15,33 +15,31 @@
|
|
|
15
15
|
"type": "string",
|
|
16
16
|
"title": "Home Name",
|
|
17
17
|
"description": "Name of the home",
|
|
18
|
-
"required": true
|
|
18
|
+
"required": true,
|
|
19
|
+
"store": true
|
|
19
20
|
},
|
|
20
21
|
"email": {
|
|
21
22
|
"type": "string",
|
|
22
23
|
"title": "Login Email",
|
|
23
24
|
"description": "Email for the login",
|
|
24
25
|
"format": "email",
|
|
25
|
-
"required": false
|
|
26
|
+
"required": false,
|
|
27
|
+
"store": true
|
|
26
28
|
},
|
|
27
29
|
"password": {
|
|
28
30
|
"type": "string",
|
|
29
31
|
"title": "Login Password",
|
|
30
32
|
"description": "Password for the login",
|
|
31
33
|
"format": "password",
|
|
32
|
-
"required": false
|
|
33
|
-
|
|
34
|
-
"pin": {
|
|
35
|
-
"type": "string",
|
|
36
|
-
"title": "2FA Pin",
|
|
37
|
-
"description": "2FA Pin for the login",
|
|
38
|
-
"required": false
|
|
34
|
+
"required": false,
|
|
35
|
+
"store": true
|
|
39
36
|
},
|
|
40
37
|
"token": {
|
|
41
38
|
"type": "string",
|
|
42
39
|
"title": "Refresh Token",
|
|
43
40
|
"description": "Refresh Token",
|
|
44
|
-
"hidden": true
|
|
41
|
+
"hidden": true,
|
|
42
|
+
"store": true
|
|
45
43
|
}
|
|
46
44
|
},
|
|
47
45
|
"buttons": [
|
package/dist/camera.d.ts
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import type { RingCamera } from 'ring-client-api';
|
|
1
|
+
import { WebRTCReceiver } from '@camera.ui/rtsp';
|
|
2
|
+
import type { AnswerSDP } from '@camera.ui/rtsp';
|
|
4
3
|
import type { CameraDelegate, CameraDevice, PluginLogger } from '@camera.ui/types';
|
|
5
|
-
|
|
4
|
+
import type { RingCamera } from 'ring-client-api';
|
|
5
|
+
import type Ring from './index.js';
|
|
6
|
+
import type { RingHome } from './types.js';
|
|
7
|
+
export declare class Camera extends WebRTCReceiver implements CameraDelegate {
|
|
8
|
+
cameraDevice: CameraDevice;
|
|
9
|
+
private platform;
|
|
10
|
+
private home;
|
|
6
11
|
private ringCamera;
|
|
7
|
-
private cameraDevice;
|
|
8
12
|
private logger;
|
|
9
|
-
private
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
private pc?;
|
|
14
|
+
private rtspServer;
|
|
15
|
+
constructor(platform: Ring, home: RingHome, ringCamera: RingCamera, logger: PluginLogger);
|
|
16
|
+
onOffer(offerSdp: string): Promise<AnswerSDP>;
|
|
17
|
+
onCandidate(candidate: string): Promise<void>;
|
|
18
|
+
createCameraDevice(): Promise<void>;
|
|
19
|
+
snapshot(): Promise<ArrayBuffer>;
|
|
20
|
+
reboot(): Promise<void>;
|
|
21
|
+
private createRTSPServer;
|
|
16
22
|
private createPeerCoonection;
|
|
23
|
+
private checkStates;
|
|
17
24
|
}
|
package/dist/camera.js
CHANGED
|
@@ -1,44 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const werift_1 = require("werift");
|
|
6
|
-
class Camera {
|
|
7
|
-
ringCamera;
|
|
1
|
+
import { RTSPSingleServer, WebRTCReceiver } from '@camera.ui/rtsp';
|
|
2
|
+
import { MediaStreamTrack, RTCIceCandidate, RTCPeerConnection, RTCRtpCodecParameters, RTCSessionDescription } from 'werift';
|
|
3
|
+
import { CustomPeerConnection } from './peer.js';
|
|
4
|
+
export class Camera extends WebRTCReceiver {
|
|
8
5
|
cameraDevice;
|
|
6
|
+
platform;
|
|
7
|
+
home;
|
|
8
|
+
ringCamera;
|
|
9
9
|
logger;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
pc;
|
|
11
|
+
rtspServer;
|
|
12
|
+
constructor(platform, home, ringCamera, logger) {
|
|
13
|
+
super();
|
|
14
|
+
this.platform = platform;
|
|
15
|
+
this.home = home;
|
|
12
16
|
this.ringCamera = ringCamera;
|
|
13
|
-
this.cameraDevice = cameraDevice;
|
|
14
17
|
this.logger = logger;
|
|
15
|
-
this.checkStates();
|
|
16
|
-
}
|
|
17
|
-
async snapshotRequest(requestId) {
|
|
18
|
-
return await this.ringCamera.getSnapshot();
|
|
19
18
|
}
|
|
20
|
-
async
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
19
|
+
async onOffer(offerSdp) {
|
|
20
|
+
this.logger.debug(`${this.cameraDevice.name}: Preparing stream...`);
|
|
21
|
+
let timeout;
|
|
22
|
+
const cleanup = () => {
|
|
23
|
+
clearTimeout(timeout);
|
|
24
|
+
call.stop();
|
|
25
|
+
receiver.onAudioRtcp.unsubscribe();
|
|
26
|
+
receiver.onVideoRtcp.unsubscribe();
|
|
27
|
+
receiver.close();
|
|
28
|
+
pc.connectionStateChange.allUnsubscribe();
|
|
29
|
+
pc.onTrack.allUnsubscribe();
|
|
30
|
+
pc.close();
|
|
31
|
+
this.logger.debug(`${this.cameraDevice.name}: Stream stopped!`);
|
|
32
|
+
};
|
|
33
|
+
const receiver = new CustomPeerConnection();
|
|
34
|
+
const audioTrack = new MediaStreamTrack({ kind: 'audio' });
|
|
35
|
+
const videoTrack = new MediaStreamTrack({ kind: 'video' });
|
|
25
36
|
receiver.onAudioRtp.subscribe((rtp) => {
|
|
26
37
|
audioTrack.writeRtp(rtp);
|
|
27
38
|
});
|
|
28
39
|
receiver.onVideoRtp.subscribe((rtp) => {
|
|
29
40
|
videoTrack.writeRtp(rtp);
|
|
30
41
|
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
const call = await this.ringCamera.startLiveCall({
|
|
43
|
+
createPeerConnection: () => receiver,
|
|
44
|
+
});
|
|
45
|
+
if (!call.cameraSpeakerActivated) {
|
|
46
|
+
call.activateCameraSpeaker();
|
|
47
|
+
}
|
|
48
|
+
const pc = (this.pc = this.createPeerCoonection());
|
|
49
|
+
pc.onIceCandidate.subscribe((candidate) => {
|
|
50
|
+
this.events.emit('candidate', candidate.candidate);
|
|
39
51
|
});
|
|
40
52
|
pc.connectionStateChange.subscribe((ev) => {
|
|
41
53
|
this.logger.debug(`${this.cameraDevice.name}: connectionStateChange: ${ev}`);
|
|
54
|
+
if (ev === 'disconnected' || ev === 'failed' || ev === 'closed') {
|
|
55
|
+
cleanup();
|
|
56
|
+
}
|
|
57
|
+
if (ev === 'connecting') {
|
|
58
|
+
timeout = setTimeout(() => {
|
|
59
|
+
this.logger.warn(`${this.cameraDevice.name}: Connection timeout!`);
|
|
60
|
+
cleanup();
|
|
61
|
+
}, 10000);
|
|
62
|
+
}
|
|
63
|
+
if (ev === 'connected') {
|
|
64
|
+
this.logger.log(`${this.cameraDevice.name}: Stream started!`);
|
|
65
|
+
clearTimeout(timeout);
|
|
66
|
+
}
|
|
42
67
|
});
|
|
43
68
|
pc.onTrack.subscribe((track) => {
|
|
44
69
|
if (track.kind === 'audio') {
|
|
@@ -49,125 +74,154 @@ class Camera {
|
|
|
49
74
|
});
|
|
50
75
|
pc.addTransceiver(videoTrack, { direction: 'sendonly' });
|
|
51
76
|
pc.addTransceiver(audioTrack, { direction: 'sendonly' });
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
call.onCallEnded.subscribe(() => {
|
|
58
|
-
this.logger.debug(`${this.cameraDevice.name}: Stream ended`);
|
|
59
|
-
});
|
|
60
|
-
if (!call.cameraSpeakerActivated) {
|
|
61
|
-
this.logger.debug(`${this.cameraDevice.name}: Activating camera speaker`);
|
|
62
|
-
call.activateCameraSpeaker();
|
|
63
|
-
}
|
|
64
|
-
this.connectionMap.set(requestId, { pc, call });
|
|
77
|
+
const offer = new RTCSessionDescription(offerSdp, 'offer');
|
|
78
|
+
await pc.setRemoteDescription(offer);
|
|
79
|
+
const answer = await pc.createAnswer();
|
|
80
|
+
await pc.setLocalDescription(answer);
|
|
81
|
+
return answer.sdp;
|
|
65
82
|
}
|
|
66
|
-
async
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
83
|
+
async onCandidate(candidate) {
|
|
84
|
+
await this.pc?.addIceCandidate(new RTCIceCandidate({ candidate }));
|
|
85
|
+
}
|
|
86
|
+
async createCameraDevice() {
|
|
87
|
+
await this.createRTSPServer();
|
|
88
|
+
const cameraDevice = Array.from(this.platform.cameras.values()).find((camera) => camera.nativeId === this.ringCamera.id.toString());
|
|
89
|
+
if (!cameraDevice) {
|
|
90
|
+
this.logger.log(this.home.name, 'Adding camera', this.ringCamera.name);
|
|
91
|
+
this.cameraDevice = await this.platform.api.deviceManager.createCamera({
|
|
92
|
+
name: this.ringCamera.name,
|
|
93
|
+
nativeId: this.ringCamera.id.toString(),
|
|
94
|
+
isCloud: true,
|
|
95
|
+
hasSiren: this.ringCamera.hasSiren,
|
|
96
|
+
hasLight: this.ringCamera.hasLight,
|
|
97
|
+
hasBinarySensor: this.ringCamera.hasInHomeDoorbell,
|
|
98
|
+
hasBattery: this.ringCamera.hasBattery,
|
|
99
|
+
info: {
|
|
100
|
+
manufacturer: 'Ring',
|
|
101
|
+
model: this.ringCamera.model,
|
|
102
|
+
hardware: this.ringCamera.data.kind,
|
|
103
|
+
serialNumber: this.ringCamera.data.device_id,
|
|
104
|
+
firmwareVersion: this.ringCamera.data.health.firmware_version,
|
|
105
|
+
supportUrl: 'https://support.ring.com/',
|
|
106
|
+
},
|
|
107
|
+
sources: [
|
|
108
|
+
{
|
|
109
|
+
name: 'P2P',
|
|
110
|
+
roles: ['high-resolution'],
|
|
111
|
+
urls: [this.rtspServer.streamUrl],
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
});
|
|
70
115
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
116
|
+
else {
|
|
117
|
+
this.cameraDevice = cameraDevice;
|
|
118
|
+
await this.cameraDevice.updateCameraSource(cameraDevice.streamSource._id, { urls: [this.rtspServer.streamUrl] });
|
|
119
|
+
}
|
|
120
|
+
this.cameraDevice.setDelegate('cameraDelegate', this);
|
|
121
|
+
const ffmpegPath = await this.cameraDevice.getFfmpegPath();
|
|
122
|
+
this.rtspServer.changeFFmpegPath(ffmpegPath);
|
|
123
|
+
await this.cameraDevice.connect();
|
|
124
|
+
this.checkStates();
|
|
75
125
|
}
|
|
76
|
-
async
|
|
77
|
-
|
|
78
|
-
await
|
|
126
|
+
async snapshot() {
|
|
127
|
+
this.logger.debug(`${this.cameraDevice.name}: Snapshot requested`);
|
|
128
|
+
return await this.ringCamera.getSnapshot();
|
|
79
129
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
130
|
+
async reboot() {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
async createRTSPServer() {
|
|
134
|
+
const stream = {
|
|
135
|
+
name: 'Ring',
|
|
136
|
+
receiver: this,
|
|
137
|
+
addBackchannel: true,
|
|
87
138
|
};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
139
|
+
const rtspLogger = {
|
|
140
|
+
// log: this.logger.log.bind(this.logger),
|
|
141
|
+
warn: this.logger.warn.bind(this.logger),
|
|
142
|
+
error: this.logger.error.bind(this.logger),
|
|
143
|
+
// debug: this.logger.debug.bind(this.logger),
|
|
144
|
+
// trace: this.logger.trace.bind(this.logger),
|
|
94
145
|
};
|
|
95
|
-
this.
|
|
96
|
-
|
|
97
|
-
this.cameraDevice.updateState('doorbell', { state: true }).catch();
|
|
98
|
-
resetDoorbellTimeout();
|
|
99
|
-
});
|
|
100
|
-
this.ringCamera.onMotionDetected.subscribe((motionDetected) => {
|
|
101
|
-
if (motionDetected) {
|
|
102
|
-
this.logger.log(this.cameraDevice.name, 'onMotionDetected');
|
|
103
|
-
resetTimeout();
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
clearTimeout(motionTimeout);
|
|
107
|
-
}
|
|
108
|
-
this.cameraDevice.updateState('motion', { state: motionDetected }).catch();
|
|
109
|
-
});
|
|
110
|
-
this.ringCamera.onData.subscribe((data) => {
|
|
111
|
-
if (this.ringCamera.hasLight && data.led_status) {
|
|
112
|
-
this.logger.log(this.cameraDevice.name, 'light', data.led_status === 'on');
|
|
113
|
-
this.cameraDevice.updateState('light', { state: data.led_status === 'on' }).catch();
|
|
114
|
-
}
|
|
115
|
-
if (this.ringCamera.hasSiren && data.siren_status) {
|
|
116
|
-
this.logger.log(this.cameraDevice.name, 'siren', data.siren_status.seconds_remaining > 0 ? true : false);
|
|
117
|
-
this.cameraDevice.updateState('siren', { state: data.siren_status.seconds_remaining > 0 ? true : false }).catch();
|
|
118
|
-
}
|
|
119
|
-
});
|
|
146
|
+
this.rtspServer = await RTSPSingleServer.initialize({ stream }, rtspLogger);
|
|
147
|
+
await this.rtspServer.listen();
|
|
120
148
|
}
|
|
121
149
|
createPeerCoonection() {
|
|
122
|
-
return new
|
|
150
|
+
return new RTCPeerConnection({
|
|
123
151
|
codecs: {
|
|
124
152
|
video: [
|
|
125
|
-
new
|
|
153
|
+
new RTCRtpCodecParameters({
|
|
126
154
|
mimeType: 'video/H264',
|
|
127
155
|
clockRate: 90000,
|
|
128
156
|
payloadType: 96,
|
|
129
157
|
rtcpFeedback: [{ type: 'transport-cc' }, { type: 'ccm', parameter: 'fir' }, { type: 'nack' }, { type: 'nack', parameter: 'pli' }, { type: 'goog-remb' }],
|
|
130
158
|
parameters: 'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f',
|
|
131
159
|
}),
|
|
132
|
-
new werift_1.RTCRtpCodecParameters({
|
|
133
|
-
mimeType: 'video/H264',
|
|
134
|
-
clockRate: 90000,
|
|
135
|
-
payloadType: 97,
|
|
136
|
-
rtcpFeedback: [{ type: 'transport-cc' }, { type: 'ccm', parameter: 'fir' }, { type: 'nack' }, { type: 'nack', parameter: 'pli' }, { type: 'goog-remb' }],
|
|
137
|
-
parameters: 'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f',
|
|
138
|
-
}),
|
|
139
|
-
new werift_1.RTCRtpCodecParameters({
|
|
140
|
-
mimeType: 'video/H264',
|
|
141
|
-
clockRate: 90000,
|
|
142
|
-
payloadType: 98,
|
|
143
|
-
rtcpFeedback: [{ type: 'transport-cc' }, { type: 'ccm', parameter: 'fir' }, { type: 'nack' }, { type: 'nack', parameter: 'pli' }, { type: 'goog-remb' }],
|
|
144
|
-
parameters: 'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032',
|
|
145
|
-
}),
|
|
146
160
|
],
|
|
147
161
|
audio: [
|
|
148
|
-
new
|
|
162
|
+
new RTCRtpCodecParameters({
|
|
149
163
|
mimeType: 'audio/opus',
|
|
150
164
|
clockRate: 48000,
|
|
151
165
|
payloadType: 101,
|
|
152
166
|
channels: 2,
|
|
153
167
|
parameters: 'minptime=10;useinbandfec=1',
|
|
154
168
|
}),
|
|
155
|
-
new werift_1.RTCRtpCodecParameters({
|
|
156
|
-
mimeType: 'audio/PCMU',
|
|
157
|
-
clockRate: 8000,
|
|
158
|
-
channels: 1,
|
|
159
|
-
payloadType: 0,
|
|
160
|
-
}),
|
|
161
|
-
new werift_1.RTCRtpCodecParameters({
|
|
162
|
-
mimeType: 'audio/PCMA',
|
|
163
|
-
clockRate: 8000,
|
|
164
|
-
channels: 1,
|
|
165
|
-
payloadType: 8,
|
|
166
|
-
}),
|
|
167
169
|
],
|
|
168
170
|
},
|
|
169
171
|
});
|
|
170
172
|
}
|
|
173
|
+
checkStates() {
|
|
174
|
+
if (this.ringCamera.hasInHomeDoorbell) {
|
|
175
|
+
this.ringCamera.onDoorbellPressed.subscribe(async (ding) => {
|
|
176
|
+
try {
|
|
177
|
+
this.logger.log(this.cameraDevice.name, 'onDoorbellPressed', ding);
|
|
178
|
+
await this.cameraDevice.updateState('doorbell', { state: true });
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
this.logger.error('Failed to update motion state', error);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
this.ringCamera.onMotionDetected.subscribe(async (motionDetected) => {
|
|
186
|
+
try {
|
|
187
|
+
this.logger.log(this.cameraDevice.name, 'onMotionDetected', motionDetected);
|
|
188
|
+
await this.cameraDevice.updateState('motion', { state: motionDetected, detections: [] });
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
this.logger.error('Failed to update motion state', error);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
if (this.ringCamera.hasBattery) {
|
|
195
|
+
this.ringCamera.onBatteryLevel.subscribe(async (batteryLevel) => {
|
|
196
|
+
try {
|
|
197
|
+
this.logger.log(this.cameraDevice.name, 'battery', batteryLevel ?? 100);
|
|
198
|
+
await this.cameraDevice.updateState('battery', { level: batteryLevel ?? 100 });
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
this.logger.error('Failed to update battery state', error);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
this.ringCamera.onData.subscribe(async (data) => {
|
|
206
|
+
if (this.ringCamera.hasLight && data.led_status) {
|
|
207
|
+
try {
|
|
208
|
+
this.logger.log(this.cameraDevice.name, 'light', data.led_status == 'on');
|
|
209
|
+
await this.cameraDevice.updateState('light', { state: data.led_status == 'on' });
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
this.logger.error('Failed to update light state', error);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (this.ringCamera.hasSiren && data.siren_status) {
|
|
216
|
+
try {
|
|
217
|
+
this.logger.log(this.cameraDevice.name, 'siren', data.siren_status.seconds_remaining > 0);
|
|
218
|
+
await this.cameraDevice.updateState('siren', { state: data.siren_status.seconds_remaining > 0 });
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
this.logger.error('Failed to update siren state', error);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
171
226
|
}
|
|
172
|
-
exports.Camera = Camera;
|
|
173
227
|
//# sourceMappingURL=camera.js.map
|
package/dist/camera.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"camera.js","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"camera.js","sourceRoot":"","sources":["../src/camera.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export default
|
|
1
|
+
import type { BasePlugin, CameraDevice, FormSubmitResponse, PluginAPI, PluginLogger } from '@camera.ui/types';
|
|
2
|
+
import type { Config, FormAction, RingHome } from './types.js';
|
|
3
|
+
export default class RingPlugin implements BasePlugin {
|
|
4
|
+
config: Config;
|
|
5
|
+
logger: PluginLogger;
|
|
6
|
+
api: PluginAPI;
|
|
7
|
+
cameras: Map<string, CameraDevice>;
|
|
8
|
+
private restClient;
|
|
9
|
+
private ringConnections;
|
|
10
|
+
private ringCamerasMap;
|
|
11
|
+
constructor(logger: PluginLogger, api: PluginAPI);
|
|
12
|
+
configureCameras(cameras: CameraDevice[]): void;
|
|
13
|
+
onFormSubmit(actionId: FormAction, home: RingHome & {
|
|
14
|
+
twoFactorCode?: string;
|
|
15
|
+
}): Promise<FormSubmitResponse | void>;
|
|
16
|
+
private start;
|
|
17
|
+
private stop;
|
|
18
|
+
private connectHome;
|
|
19
|
+
private generateCode;
|
|
20
|
+
private generateToken;
|
|
21
|
+
private refreshConfig;
|
|
22
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const types_1 = require("@camera.ui/types");
|
|
6
|
-
const camera_1 = require("./camera");
|
|
7
|
-
const contract_1 = require("./contract");
|
|
8
|
-
exports.default = (api) => api.registerPlugin(RingPlugin, contract_1.pluginContract);
|
|
9
|
-
class RingPlugin extends types_1.BasePlugin {
|
|
1
|
+
import { RingApi } from 'ring-client-api';
|
|
2
|
+
import { RingRestClient } from 'ring-client-api/rest-client';
|
|
3
|
+
import { Camera } from './camera.js';
|
|
4
|
+
export default class RingPlugin {
|
|
10
5
|
config;
|
|
11
|
-
|
|
6
|
+
logger;
|
|
7
|
+
api;
|
|
8
|
+
cameras = new Map();
|
|
9
|
+
restClient = new Map();
|
|
12
10
|
ringConnections = new Map();
|
|
13
11
|
ringCamerasMap = new Map();
|
|
14
|
-
constructor(
|
|
15
|
-
|
|
16
|
-
this.
|
|
17
|
-
this.config
|
|
18
|
-
this.api.
|
|
19
|
-
this.api.on('
|
|
20
|
-
this.api.deviceManager.listen('cameraRemoved', (cameraId) => {
|
|
12
|
+
constructor(logger, api) {
|
|
13
|
+
this.logger = logger;
|
|
14
|
+
this.api = api;
|
|
15
|
+
this.config = api.configService.all();
|
|
16
|
+
this.config.homes = api.configService.get('homes', [], (value) => Array.isArray(value), false, true);
|
|
17
|
+
this.api.deviceManager.on('cameraDeselected', (cameraId) => {
|
|
21
18
|
const cameraDevice = this.cameras.get(cameraId);
|
|
22
19
|
const nativeId = cameraDevice?.nativeId;
|
|
23
20
|
const ringCamera = nativeId ? this.ringCamerasMap.get(nativeId) : undefined;
|
|
@@ -25,26 +22,8 @@ class RingPlugin extends types_1.BasePlugin {
|
|
|
25
22
|
this.ringCamerasMap.delete(nativeId);
|
|
26
23
|
this.cameras.delete(cameraId);
|
|
27
24
|
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
for (const home of this.config.homes) {
|
|
31
|
-
await this.connectHome(home);
|
|
32
|
-
}
|
|
33
|
-
// Remove orphaned cameras
|
|
34
|
-
for (const [cameraId, cameraDevice] of this.cameras) {
|
|
35
|
-
const ringCameraId = cameraDevice.nativeId;
|
|
36
|
-
if (!this.ringCamerasMap.get(ringCameraId)) {
|
|
37
|
-
this.logger.warn('Removing camera', cameraDevice.name);
|
|
38
|
-
this.cameras.delete(cameraId);
|
|
39
|
-
await this.api.deviceManager.removeCameraById(cameraDevice.id);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
stop() {
|
|
44
|
-
this.ringCamerasMap.forEach((ringCamera) => ringCamera.disconnect());
|
|
45
|
-
this.ringConnections.forEach((ringApi) => ringApi.disconnect());
|
|
46
|
-
this.ringConnections.clear();
|
|
47
|
-
this.ringCamerasMap.clear();
|
|
25
|
+
this.api.on('finishLaunching', this.start.bind(this));
|
|
26
|
+
this.api.on('shutdown', this.stop.bind(this));
|
|
48
27
|
}
|
|
49
28
|
configureCameras(cameras) {
|
|
50
29
|
for (const camera of cameras) {
|
|
@@ -54,19 +33,22 @@ class RingPlugin extends types_1.BasePlugin {
|
|
|
54
33
|
async onFormSubmit(actionId, home) {
|
|
55
34
|
switch (actionId) {
|
|
56
35
|
case 'onLogin':
|
|
57
|
-
|
|
36
|
+
case 'on2FA':
|
|
37
|
+
if (home.twoFactorCode) {
|
|
58
38
|
try {
|
|
59
|
-
const response = await this.generateToken(
|
|
60
|
-
email: home.email,
|
|
61
|
-
password: home.password,
|
|
62
|
-
code: home.pin,
|
|
63
|
-
});
|
|
39
|
+
const response = await this.generateToken(home.name, home.email, home.password, home.twoFactorCode);
|
|
64
40
|
if (response?.refreshToken) {
|
|
65
|
-
this.restClient
|
|
41
|
+
this.restClient.delete(home.name);
|
|
66
42
|
home.token = response.refreshToken;
|
|
67
|
-
this.
|
|
43
|
+
this.refreshConfig(home);
|
|
68
44
|
this.connectHome(home);
|
|
69
|
-
|
|
45
|
+
const formResponse = {
|
|
46
|
+
toast: {
|
|
47
|
+
message: 'Logged in',
|
|
48
|
+
type: 'success',
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
return formResponse;
|
|
70
52
|
}
|
|
71
53
|
else {
|
|
72
54
|
throw new Error('Failed to Login');
|
|
@@ -79,61 +61,117 @@ class RingPlugin extends types_1.BasePlugin {
|
|
|
79
61
|
}
|
|
80
62
|
// token was not valid, login again
|
|
81
63
|
try {
|
|
82
|
-
const response =
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
64
|
+
const response = await this.generateCode(home.name, home.email, home.password);
|
|
65
|
+
if (!response) {
|
|
66
|
+
throw new Error('Failed to get code');
|
|
67
|
+
}
|
|
86
68
|
if ('refreshToken' in response) {
|
|
87
|
-
|
|
88
|
-
this.restClient = undefined;
|
|
69
|
+
this.restClient.delete(home.name);
|
|
89
70
|
home.token = response.refreshToken;
|
|
90
|
-
this.
|
|
71
|
+
this.refreshConfig(home);
|
|
91
72
|
this.connectHome(home);
|
|
92
|
-
|
|
73
|
+
const formResponse = {
|
|
74
|
+
toast: {
|
|
75
|
+
message: 'Logged in!',
|
|
76
|
+
type: 'success',
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
return formResponse;
|
|
93
80
|
}
|
|
94
81
|
else {
|
|
95
|
-
|
|
82
|
+
const formResponse = {
|
|
83
|
+
schema: {
|
|
84
|
+
config: {
|
|
85
|
+
type: 'object',
|
|
86
|
+
title: 'Two-Factor Authentication (2FA)',
|
|
87
|
+
description: 'Enter the 2FA code',
|
|
88
|
+
required: true,
|
|
89
|
+
opened: true,
|
|
90
|
+
properties: {
|
|
91
|
+
twoFactorCode: {
|
|
92
|
+
type: 'string',
|
|
93
|
+
key: 'twoFactorCode',
|
|
94
|
+
title: 'Two-Factor Code',
|
|
95
|
+
description: 'Enter the two-factor code',
|
|
96
|
+
required: true,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
buttons: [
|
|
100
|
+
{
|
|
101
|
+
label: 'Authenticate',
|
|
102
|
+
onSubmit: 'on2FA',
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
toast: {
|
|
108
|
+
message: 'Two-Factor Authentication (2FA) Required!',
|
|
109
|
+
type: 'warning',
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
return formResponse;
|
|
96
113
|
}
|
|
97
114
|
}
|
|
98
115
|
catch (error) {
|
|
99
116
|
const message = `Failed to Link Account. Reason: ${error.message}`;
|
|
100
117
|
this.logger.error(home.name, message);
|
|
101
|
-
|
|
118
|
+
const formResponse = {
|
|
119
|
+
toast: {
|
|
120
|
+
message,
|
|
121
|
+
type: 'error',
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
return formResponse;
|
|
102
125
|
}
|
|
103
|
-
break;
|
|
104
126
|
default:
|
|
105
127
|
const message = `Unknown actionId: ${actionId}`;
|
|
106
|
-
this.logger.warn(message);
|
|
107
|
-
|
|
128
|
+
this.logger.warn(home.name, message);
|
|
129
|
+
const formResponse = {
|
|
130
|
+
toast: {
|
|
131
|
+
message,
|
|
132
|
+
type: 'error',
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
return formResponse;
|
|
108
136
|
}
|
|
109
137
|
}
|
|
138
|
+
async start() {
|
|
139
|
+
for (const home of this.config.homes) {
|
|
140
|
+
await this.connectHome(home);
|
|
141
|
+
}
|
|
142
|
+
// Remove orphaned cameras
|
|
143
|
+
for (const [cameraId, cameraDevice] of this.cameras) {
|
|
144
|
+
const ringCameraId = cameraDevice.nativeId;
|
|
145
|
+
if (!this.ringCamerasMap.get(ringCameraId)) {
|
|
146
|
+
this.logger.warn('Removing camera', cameraDevice.name);
|
|
147
|
+
this.cameras.delete(cameraId);
|
|
148
|
+
await this.api.deviceManager.removeCameraById(cameraDevice.id);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
stop() {
|
|
153
|
+
this.ringCamerasMap.forEach((ringCamera) => ringCamera.disconnect());
|
|
154
|
+
this.ringConnections.forEach((ringApi) => ringApi.disconnect());
|
|
155
|
+
this.restClient.clear();
|
|
156
|
+
this.ringConnections.clear();
|
|
157
|
+
this.ringCamerasMap.clear();
|
|
158
|
+
}
|
|
110
159
|
async connectHome(home) {
|
|
111
160
|
try {
|
|
112
161
|
if (home.token) {
|
|
113
|
-
const api = new
|
|
162
|
+
const api = new RingApi({ refreshToken: home.token });
|
|
114
163
|
this.ringConnections.set(home.name, api);
|
|
115
164
|
api.onRefreshTokenUpdated.subscribe(async (refreshToken) => {
|
|
116
165
|
home.token = refreshToken.newRefreshToken;
|
|
117
|
-
this.
|
|
166
|
+
this.refreshConfig(home);
|
|
118
167
|
});
|
|
119
168
|
const ringCameras = await api.getCameras();
|
|
120
|
-
for (const
|
|
121
|
-
const ringCameraId =
|
|
122
|
-
this.ringCamerasMap.set(ringCameraId,
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
cameraDevice = await this.api.deviceManager.createCamera({
|
|
127
|
-
name: camera.name,
|
|
128
|
-
nativeId: ringCameraId,
|
|
129
|
-
model: 'Ring Camera',
|
|
130
|
-
});
|
|
131
|
-
cameraDevice.configureDelegate(new camera_1.Camera(camera, cameraDevice, this.logger));
|
|
132
|
-
this.cameras.set(cameraDevice.id, cameraDevice);
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
cameraDevice.configureDelegate(new camera_1.Camera(camera, cameraDevice, this.logger));
|
|
136
|
-
}
|
|
169
|
+
for (const ringCamera of ringCameras) {
|
|
170
|
+
const ringCameraId = ringCamera.id.toString();
|
|
171
|
+
this.ringCamerasMap.set(ringCameraId, ringCamera);
|
|
172
|
+
const camera = new Camera(this, home, ringCamera, this.logger);
|
|
173
|
+
await camera.createCameraDevice();
|
|
174
|
+
this.cameras.set(camera.cameraDevice.id, camera.cameraDevice);
|
|
137
175
|
}
|
|
138
176
|
}
|
|
139
177
|
else {
|
|
@@ -144,40 +182,45 @@ class RingPlugin extends types_1.BasePlugin {
|
|
|
144
182
|
this.logger.error(home.name, error);
|
|
145
183
|
}
|
|
146
184
|
}
|
|
147
|
-
async generateCode(
|
|
148
|
-
this.logger.log(`Logging in with email '${email}'`);
|
|
149
|
-
|
|
185
|
+
async generateCode(homeName, email, password) {
|
|
186
|
+
this.logger.log(homeName, `Logging in with email '${email}'`);
|
|
187
|
+
const ringClient = new RingRestClient({
|
|
150
188
|
email,
|
|
151
189
|
password,
|
|
152
190
|
});
|
|
191
|
+
this.restClient.set(homeName, ringClient);
|
|
153
192
|
try {
|
|
154
|
-
const { refresh_token } = await
|
|
155
|
-
// If we get here, 2fa was not required.
|
|
156
|
-
// I'm not sure this is possible anymore, but it's here just in case
|
|
193
|
+
const { refresh_token } = await ringClient.getCurrentAuth();
|
|
157
194
|
return { refreshToken: refresh_token };
|
|
158
195
|
}
|
|
159
196
|
catch (error) {
|
|
160
|
-
if (
|
|
161
|
-
this.logger.log(
|
|
162
|
-
return { codePrompt:
|
|
197
|
+
if (ringClient.promptFor2fa) {
|
|
198
|
+
this.logger.log(homeName, ringClient.promptFor2fa);
|
|
199
|
+
return { codePrompt: ringClient.promptFor2fa };
|
|
163
200
|
}
|
|
164
|
-
this.logger.error(error);
|
|
201
|
+
this.logger.error(homeName, error);
|
|
165
202
|
}
|
|
166
203
|
}
|
|
167
|
-
async generateToken(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
204
|
+
async generateToken(homeName, email, password, code) {
|
|
205
|
+
let restClient = this.restClient.get(homeName);
|
|
206
|
+
if (!restClient) {
|
|
207
|
+
restClient = new RingRestClient({ email, password });
|
|
208
|
+
this.restClient.set(homeName, restClient);
|
|
209
|
+
}
|
|
210
|
+
this.logger.log(homeName, `Getting token for ${email} with code ${code}`);
|
|
171
211
|
try {
|
|
172
|
-
const authResponse = await
|
|
212
|
+
const authResponse = await restClient.getAuth(code);
|
|
173
213
|
return { refreshToken: authResponse.refresh_token };
|
|
174
214
|
}
|
|
175
215
|
catch (error) {
|
|
176
|
-
this.logger.error('Incorrect 2fa Code. Please check the code and try again', error);
|
|
216
|
+
this.logger.error(homeName, 'Incorrect 2fa Code. Please check the code and try again', error);
|
|
177
217
|
}
|
|
178
218
|
}
|
|
179
|
-
|
|
180
|
-
|
|
219
|
+
refreshConfig(home) {
|
|
220
|
+
if ('twoFactorCode' in home) {
|
|
221
|
+
delete home.twoFactorCode;
|
|
222
|
+
}
|
|
223
|
+
this.api.configService.replaceOrAddItem('homes', 'name', home.name, home, true);
|
|
181
224
|
}
|
|
182
225
|
}
|
|
183
226
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAMrC,MAAM,CAAC,OAAO,OAAO,UAAU;IACtB,MAAM,CAAS;IACf,MAAM,CAAe;IACrB,GAAG,CAAY;IACf,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEzC,UAAU,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC/C,eAAe,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC7C,cAAc,GAAG,IAAI,GAAG,EAAsB,CAAC;IAEvD,YAAY,MAAoB,EAAE,GAAc;QAC9C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QAEf,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,EAAY,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAE1G,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,QAAgB,EAAE,EAAE;YACjE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,QAAQ,GAAG,YAAY,EAAE,QAAQ,CAAC;YACxC,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAE5E,UAAU,EAAE,UAAU,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,QAAS,CAAC,CAAC;YACtC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAEM,gBAAgB,CAAC,OAAuB;QAC7C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,QAAoB,EAAE,IAA2C;QACzF,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,SAAS,CAAC;YACf,KAAK,OAAO;gBACV,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;oBACvB,IAAI,CAAC;wBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;wBAEpG,IAAI,QAAQ,EAAE,YAAY,EAAE,CAAC;4BAC3B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;4BAClC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC;4BAEnC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;4BACzB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;4BAEvB,MAAM,YAAY,GAAuB;gCACvC,KAAK,EAAE;oCACL,OAAO,EAAE,WAAW;oCACpB,IAAI,EAAE,SAAS;iCAChB;6BACF,CAAC;4BAEF,OAAO,YAAY,CAAC;wBACtB,CAAC;6BAAM,CAAC;4BACN,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;wBACrC,CAAC;oBACH,CAAC;oBAAC,OAAO,KAAU,EAAE,CAAC;wBACpB,MAAM,OAAO,GAAG,mCAAmC,KAAK,CAAC,OAAO,4BAA4B,CAAC;wBAC7F,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;oBACxC,CAAC;gBACH,CAAC;gBAED,mCAAmC;gBACnC,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAE/E,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACd,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;oBACxC,CAAC;oBAED,IAAI,cAAc,IAAI,QAAQ,EAAE,CAAC;wBAC/B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAClC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC;wBAEnC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;wBACzB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;wBAEvB,MAAM,YAAY,GAAuB;4BACvC,KAAK,EAAE;gCACL,OAAO,EAAE,YAAY;gCACrB,IAAI,EAAE,SAAS;6BAChB;yBACF,CAAC;wBAEF,OAAO,YAAY,CAAC;oBACtB,CAAC;yBAAM,CAAC;wBACN,MAAM,YAAY,GAAuB;4BACvC,MAAM,EAAE;gCACN,MAAM,EAAE;oCACN,IAAI,EAAE,QAAQ;oCACd,KAAK,EAAE,iCAAiC;oCACxC,WAAW,EAAE,oBAAoB;oCACjC,QAAQ,EAAE,IAAI;oCACd,MAAM,EAAE,IAAI;oCACZ,UAAU,EAAE;wCACV,aAAa,EAAE;4CACb,IAAI,EAAE,QAAQ;4CACd,GAAG,EAAE,eAAe;4CACpB,KAAK,EAAE,iBAAiB;4CACxB,WAAW,EAAE,2BAA2B;4CACxC,QAAQ,EAAE,IAAI;yCACf;qCACF;oCACD,OAAO,EAAE;wCACP;4CACE,KAAK,EAAE,cAAc;4CACrB,QAAQ,EAAE,OAAO;yCAClB;qCACF;iCACF;6BACF;4BACD,KAAK,EAAE;gCACL,OAAO,EAAE,2CAA2C;gCACpD,IAAI,EAAE,SAAS;6BAChB;yBACF,CAAC;wBAEF,OAAO,YAAY,CAAC;oBACtB,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAU,EAAE,CAAC;oBACpB,MAAM,OAAO,GAAG,mCAAmC,KAAK,CAAC,OAAO,EAAE,CAAC;oBACnE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;oBAEtC,MAAM,YAAY,GAAuB;wBACvC,KAAK,EAAE;4BACL,OAAO;4BACP,IAAI,EAAE,OAAO;yBACd;qBACF,CAAC;oBAEF,OAAO,YAAY,CAAC;gBACtB,CAAC;YAEH;gBACE,MAAM,OAAO,GAAG,qBAAqB,QAAQ,EAAE,CAAC;gBAChD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAErC,MAAM,YAAY,GAAuB;oBACvC,KAAK,EAAE;wBACL,OAAO;wBACP,IAAI,EAAE,OAAO;qBACd;iBACF,CAAC;gBAEF,OAAO,YAAY,CAAC;QACxB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,KAAK;QACjB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,0BAA0B;QAC1B,KAAK,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACpD,MAAM,YAAY,GAAG,YAAY,CAAC,QAAS,CAAC;YAE5C,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC3C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;gBACvD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC9B,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;IACH,CAAC;IAEO,IAAI;QACV,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,IAAc;QACtC,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;gBACtD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBAEzC,GAAG,CAAC,qBAAqB,CAAC,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;oBACzD,IAAI,CAAC,KAAK,GAAG,YAAY,CAAC,eAAe,CAAC;oBAC1C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAC3B,CAAC,CAAC,CAAC;gBAEH,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;gBAE3C,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;oBACrC,MAAM,YAAY,GAAG,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;oBAC9C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;oBAElD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;oBAC/D,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC;oBAElC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;gBAChE,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,QAAgB,EAAE,KAAa,EAAE,QAAgB;QAC1E,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,0BAA0B,KAAK,GAAG,CAAC,CAAC;QAE9D,MAAM,UAAU,GAAG,IAAI,cAAc,CAAC;YACpC,KAAK;YACL,QAAQ;SACT,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,UAAU,CAAC,cAAc,EAAE,CAAC;YAC5D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;QACzC,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,UAAU,CAAC,YAAY,EAAE,CAAC;gBAC5B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;gBACnD,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC,YAAY,EAAE,CAAC;YACjD,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,QAAgB,EAAE,KAAa,EAAE,QAAgB,EAAE,IAAY;QACzF,IAAI,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE/C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,UAAU,GAAG,IAAI,cAAc,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,qBAAqB,KAAK,cAAc,IAAI,EAAE,CAAC,CAAC;QAE1E,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpD,OAAO,EAAE,YAAY,EAAE,YAAY,CAAC,aAAa,EAAE,CAAC;QACtD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,yDAAyD,EAAE,KAAK,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,IAAc;QAClC,IAAI,eAAe,IAAI,IAAI,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAClF,CAAC;CACF"}
|
package/dist/peer.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { MediaStreamTrack, RTCIceCandidate, RtcpPacket, RtpPacket } from 'werift';
|
|
2
1
|
import { ReplaySubject, Subject } from 'rxjs';
|
|
3
|
-
import {
|
|
2
|
+
import { MediaStreamTrack } from 'werift';
|
|
3
|
+
import type { BasicPeerConnection } from '@camera.ui/types';
|
|
4
|
+
import type { RTCIceCandidate, RTCSessionDescription, RtcpPacket, RtpPacket } from 'werift';
|
|
4
5
|
export declare class CustomPeerConnection implements BasicPeerConnection {
|
|
5
6
|
private pc;
|
|
6
|
-
private onRequestKeyFrame;
|
|
7
|
-
private cameraName;
|
|
8
|
-
private logger;
|
|
9
7
|
onAudioRtp: Subject<RtpPacket>;
|
|
10
8
|
onAudioRtcp: Subject<RtcpPacket>;
|
|
11
9
|
onVideoRtp: Subject<RtpPacket>;
|
|
@@ -13,13 +11,12 @@ export declare class CustomPeerConnection implements BasicPeerConnection {
|
|
|
13
11
|
onIceCandidate: Subject<RTCIceCandidate>;
|
|
14
12
|
onConnectionState: ReplaySubject<"closed" | "failed" | "disconnected" | "new" | "connecting" | "connected">;
|
|
15
13
|
returnAudioTrack: MediaStreamTrack;
|
|
16
|
-
constructor(
|
|
17
|
-
createOffer(): Promise<
|
|
14
|
+
constructor();
|
|
15
|
+
createOffer(): Promise<RTCSessionDescription>;
|
|
18
16
|
acceptAnswer(answer: {
|
|
19
17
|
type: 'answer';
|
|
20
18
|
sdp: string;
|
|
21
19
|
}): Promise<void>;
|
|
22
20
|
addIceCandidate(candidate: RTCIceCandidate): Promise<void>;
|
|
23
|
-
requestKeyFrame(): void;
|
|
24
21
|
close(): void;
|
|
25
22
|
}
|
package/dist/peer.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.CustomPeerConnection = void 0;
|
|
4
|
-
const werift_1 = require("werift");
|
|
5
|
-
const rxjs_1 = require("rxjs");
|
|
1
|
+
import { ReplaySubject, Subject } from 'rxjs';
|
|
2
|
+
import { MediaStreamTrack, RTCPeerConnection, RTCRtpCodecParameters } from 'werift';
|
|
6
3
|
const ringIceServers = [
|
|
7
4
|
'stun:stun.kinesisvideo.us-east-1.amazonaws.com:443',
|
|
8
5
|
'stun:stun.kinesisvideo.us-east-2.amazonaws.com:443',
|
|
@@ -13,30 +10,25 @@ const ringIceServers = [
|
|
|
13
10
|
'stun:stun3.l.google.com:19302',
|
|
14
11
|
'stun:stun4.l.google.com:19302',
|
|
15
12
|
];
|
|
16
|
-
class CustomPeerConnection {
|
|
13
|
+
export class CustomPeerConnection {
|
|
17
14
|
pc;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
returnAudioTrack = new werift_1.MediaStreamTrack({ kind: 'audio' });
|
|
28
|
-
constructor(cameraName, logger) {
|
|
29
|
-
this.logger = logger;
|
|
30
|
-
this.cameraName = cameraName;
|
|
31
|
-
const pc = (this.pc = new werift_1.RTCPeerConnection({
|
|
15
|
+
onAudioRtp = new Subject();
|
|
16
|
+
onAudioRtcp = new Subject();
|
|
17
|
+
onVideoRtp = new Subject();
|
|
18
|
+
onVideoRtcp = new Subject();
|
|
19
|
+
onIceCandidate = new Subject();
|
|
20
|
+
onConnectionState = new ReplaySubject(1);
|
|
21
|
+
returnAudioTrack = new MediaStreamTrack({ kind: 'audio' });
|
|
22
|
+
constructor() {
|
|
23
|
+
const pc = (this.pc = new RTCPeerConnection({
|
|
32
24
|
codecs: {
|
|
33
25
|
audio: [
|
|
34
|
-
new
|
|
26
|
+
new RTCRtpCodecParameters({
|
|
35
27
|
mimeType: 'audio/opus',
|
|
36
28
|
clockRate: 48000,
|
|
37
29
|
channels: 2,
|
|
38
30
|
}),
|
|
39
|
-
new
|
|
31
|
+
new RTCRtpCodecParameters({
|
|
40
32
|
mimeType: 'audio/PCMU',
|
|
41
33
|
clockRate: 8000,
|
|
42
34
|
channels: 1,
|
|
@@ -44,16 +36,12 @@ class CustomPeerConnection {
|
|
|
44
36
|
}),
|
|
45
37
|
],
|
|
46
38
|
video: [
|
|
47
|
-
new
|
|
39
|
+
new RTCRtpCodecParameters({
|
|
48
40
|
mimeType: 'video/H264',
|
|
49
41
|
clockRate: 90000,
|
|
50
42
|
rtcpFeedback: [{ type: 'transport-cc' }, { type: 'ccm', parameter: 'fir' }, { type: 'nack' }, { type: 'nack', parameter: 'pli' }, { type: 'goog-remb' }],
|
|
51
43
|
parameters: 'packetization-mode=1;profile-level-id=640029;level-asymmetry-allowed=1',
|
|
52
44
|
}),
|
|
53
|
-
new werift_1.RTCRtpCodecParameters({
|
|
54
|
-
mimeType: 'video/rtx',
|
|
55
|
-
clockRate: 90000,
|
|
56
|
-
}),
|
|
57
45
|
],
|
|
58
46
|
},
|
|
59
47
|
iceServers: ringIceServers.map((server) => ({ urls: server })),
|
|
@@ -105,15 +93,11 @@ class CustomPeerConnection {
|
|
|
105
93
|
async acceptAnswer(answer) {
|
|
106
94
|
await this.pc.setRemoteDescription(answer);
|
|
107
95
|
}
|
|
108
|
-
addIceCandidate(candidate) {
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
requestKeyFrame() {
|
|
112
|
-
this.onRequestKeyFrame.next();
|
|
96
|
+
async addIceCandidate(candidate) {
|
|
97
|
+
await this.pc.addIceCandidate(candidate);
|
|
113
98
|
}
|
|
114
99
|
close() {
|
|
115
|
-
this.pc.close().catch((
|
|
100
|
+
this.pc.close().catch(() => { });
|
|
116
101
|
}
|
|
117
102
|
}
|
|
118
|
-
exports.CustomPeerConnection = CustomPeerConnection;
|
|
119
103
|
//# sourceMappingURL=peer.js.map
|
package/dist/peer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peer.js","sourceRoot":"","sources":["../src/peer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"peer.js","sourceRoot":"","sources":["../src/peer.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -2,24 +2,9 @@ export interface RingHome {
|
|
|
2
2
|
name: string;
|
|
3
3
|
email: string;
|
|
4
4
|
password: string;
|
|
5
|
-
pin?: string;
|
|
6
5
|
token?: string;
|
|
7
6
|
}
|
|
8
7
|
export interface Config {
|
|
9
|
-
server: {
|
|
10
|
-
listen: number;
|
|
11
|
-
username?: string;
|
|
12
|
-
password?: string;
|
|
13
|
-
};
|
|
14
8
|
homes: RingHome[];
|
|
15
9
|
}
|
|
16
|
-
export
|
|
17
|
-
email: string;
|
|
18
|
-
password: string;
|
|
19
|
-
}
|
|
20
|
-
export interface TokenRequest {
|
|
21
|
-
email: string;
|
|
22
|
-
password: string;
|
|
23
|
-
code: string;
|
|
24
|
-
}
|
|
25
|
-
export type FormAction = 'onLogin';
|
|
10
|
+
export type FormAction = 'onLogin' | 'on2FA';
|
package/dist/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,44 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "Ring",
|
|
3
3
|
"name": "@camera.ui/camera-ui-ring",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.23",
|
|
5
5
|
"description": "camera.ui ring plugin",
|
|
6
6
|
"author": "seydx (https://github.com/seydx/camera.ui)",
|
|
7
7
|
"main": "./dist/index.js",
|
|
8
|
+
"type": "module",
|
|
8
9
|
"scripts": {
|
|
9
10
|
"build": "rimraf dist && tsc",
|
|
10
11
|
"format": "prettier --write 'src/' --ignore-unknown --no-error-on-unmatched-pattern",
|
|
11
12
|
"lint": "eslint --fix --ext .js,.ts .",
|
|
12
13
|
"update": "updates --update ./",
|
|
13
14
|
"install-updates": "npm i --save",
|
|
14
|
-
"prepublishOnly": "npm run lint && npm run format && npm run build"
|
|
15
|
+
"prepublishOnly": "npm i --package-lock-only && npm run lint && npm run format && npm run build"
|
|
15
16
|
},
|
|
16
17
|
"dependencies": {
|
|
17
|
-
"@camera.ui/
|
|
18
|
-
"ring-client-api": "^
|
|
19
|
-
"
|
|
20
|
-
"
|
|
18
|
+
"@camera.ui/rtsp": "^0.0.24",
|
|
19
|
+
"ring-client-api": "^13.0.0",
|
|
20
|
+
"rxjs": "^7.8.1",
|
|
21
|
+
"werift": "^0.19.4",
|
|
22
|
+
"ws": "^8.18.0"
|
|
21
23
|
},
|
|
22
24
|
"devDependencies": {
|
|
23
|
-
"@
|
|
24
|
-
"@
|
|
25
|
-
"@types/
|
|
26
|
-
"@
|
|
27
|
-
"@typescript-eslint/
|
|
25
|
+
"@camera.ui/types": "^0.0.53",
|
|
26
|
+
"@rushstack/eslint-patch": "^1.10.4",
|
|
27
|
+
"@types/node": "^22.1.0",
|
|
28
|
+
"@types/ws": "^8.5.12",
|
|
29
|
+
"@typescript-eslint/eslint-plugin": "^8.0.1",
|
|
30
|
+
"@typescript-eslint/parser": "^8.0.1",
|
|
28
31
|
"concurrently": "^8.2.2",
|
|
29
|
-
"eslint": "
|
|
32
|
+
"eslint": "8.57.0",
|
|
30
33
|
"eslint-config-prettier": "^9.1.0",
|
|
31
|
-
"eslint-plugin-prettier": "^5.1
|
|
32
|
-
"prettier": "^3.
|
|
33
|
-
"rimraf": "^
|
|
34
|
-
"typescript": "^5.
|
|
35
|
-
"updates": "^
|
|
34
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
35
|
+
"prettier": "^3.3.3",
|
|
36
|
+
"rimraf": "^6.0.1",
|
|
37
|
+
"typescript": "^5.5.4",
|
|
38
|
+
"updates": "^16.3.7"
|
|
36
39
|
},
|
|
37
40
|
"bugs": {
|
|
38
41
|
"url": "https://github.com/seydx/camera.ui/issues"
|
|
39
42
|
},
|
|
40
43
|
"engines": {
|
|
41
|
-
"camera.ui": ">=
|
|
44
|
+
"camera.ui": ">=0.0.1",
|
|
42
45
|
"node": ">=18.12.0"
|
|
43
46
|
},
|
|
44
47
|
"homepage": "https://github.com/seydx/camera.ui#readme",
|
|
@@ -51,5 +54,11 @@
|
|
|
51
54
|
"repository": {
|
|
52
55
|
"type": "git",
|
|
53
56
|
"url": "git+https://github.com/seydx/camera.ui.git"
|
|
57
|
+
},
|
|
58
|
+
"camera.ui": {
|
|
59
|
+
"builtIns": [
|
|
60
|
+
"motionDetection"
|
|
61
|
+
],
|
|
62
|
+
"dependencies": []
|
|
54
63
|
}
|
|
55
64
|
}
|
package/dist/contract.d.ts
DELETED
package/dist/contract.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.pluginContract = void 0;
|
|
4
|
-
exports.pluginContract = {
|
|
5
|
-
pluginName: '@camera.ui/camera-ui-ring',
|
|
6
|
-
builtIns: ['motionDetection'],
|
|
7
|
-
dependencies: [],
|
|
8
|
-
};
|
|
9
|
-
//# sourceMappingURL=contract.js.map
|
package/dist/contract.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":";;;AAEa,QAAA,cAAc,GAAmB;IAC5C,UAAU,EAAE,2BAA2B;IACvC,QAAQ,EAAE,CAAC,iBAAiB,CAAC;IAC7B,YAAY,EAAE,EAAE;CACjB,CAAC"}
|