@camera.ui/camera-ui-ring 0.0.21 → 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.
@@ -1,38 +1,5 @@
1
1
  {
2
2
  "schema": {
3
- "server": {
4
- "type": "object",
5
- "key": "server",
6
- "title": "Server Settings",
7
- "description": "Settings for the server",
8
- "properties": {
9
- "listen": {
10
- "type": "number",
11
- "key": "listen",
12
- "title": "Server Port",
13
- "description": "Port to listen on for incoming connections",
14
- "defaultValue": 9999,
15
- "required": true
16
- },
17
- "username": {
18
- "type": "string",
19
- "key": "username",
20
- "title": "Server Username",
21
- "description": "Username for the server",
22
- "defaultValue": "camera.ui",
23
- "required": true
24
- },
25
- "password": {
26
- "type": "string",
27
- "key": "password",
28
- "format": "password",
29
- "title": "Server Password",
30
- "description": "Password for the server",
31
- "defaultValue": "camera.ui",
32
- "required": true
33
- }
34
- }
35
- },
36
3
  "homes": {
37
4
  "type": "array",
38
5
  "key": "homes",
@@ -48,33 +15,31 @@
48
15
  "type": "string",
49
16
  "title": "Home Name",
50
17
  "description": "Name of the home",
51
- "required": true
18
+ "required": true,
19
+ "store": true
52
20
  },
53
21
  "email": {
54
22
  "type": "string",
55
23
  "title": "Login Email",
56
24
  "description": "Email for the login",
57
25
  "format": "email",
58
- "required": false
26
+ "required": false,
27
+ "store": true
59
28
  },
60
29
  "password": {
61
30
  "type": "string",
62
31
  "title": "Login Password",
63
32
  "description": "Password for the login",
64
33
  "format": "password",
65
- "required": false
66
- },
67
- "pin": {
68
- "type": "string",
69
- "title": "2FA Pin",
70
- "description": "2FA Pin for the login",
71
- "required": false
34
+ "required": false,
35
+ "store": true
72
36
  },
73
37
  "token": {
74
38
  "type": "string",
75
39
  "title": "Refresh Token",
76
40
  "description": "Refresh Token",
77
- "hidden": true
41
+ "hidden": true,
42
+ "store": true
78
43
  }
79
44
  },
80
45
  "buttons": [
@@ -0,0 +1,24 @@
1
+ import { WebRTCReceiver } from '@camera.ui/rtsp';
2
+ import type { AnswerSDP } from '@camera.ui/rtsp';
3
+ import type { CameraDelegate, CameraDevice, PluginLogger } from '@camera.ui/types';
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;
11
+ private ringCamera;
12
+ private logger;
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;
22
+ private createPeerCoonection;
23
+ private checkStates;
24
+ }
package/dist/camera.js ADDED
@@ -0,0 +1,227 @@
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 {
5
+ cameraDevice;
6
+ platform;
7
+ home;
8
+ ringCamera;
9
+ logger;
10
+ pc;
11
+ rtspServer;
12
+ constructor(platform, home, ringCamera, logger) {
13
+ super();
14
+ this.platform = platform;
15
+ this.home = home;
16
+ this.ringCamera = ringCamera;
17
+ this.logger = logger;
18
+ }
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' });
36
+ receiver.onAudioRtp.subscribe((rtp) => {
37
+ audioTrack.writeRtp(rtp);
38
+ });
39
+ receiver.onVideoRtp.subscribe((rtp) => {
40
+ videoTrack.writeRtp(rtp);
41
+ });
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);
51
+ });
52
+ pc.connectionStateChange.subscribe((ev) => {
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
+ }
67
+ });
68
+ pc.onTrack.subscribe((track) => {
69
+ if (track.kind === 'audio') {
70
+ track.onReceiveRtp.subscribe((rtp) => {
71
+ receiver.returnAudioTrack.writeRtp(rtp);
72
+ });
73
+ }
74
+ });
75
+ pc.addTransceiver(videoTrack, { direction: 'sendonly' });
76
+ pc.addTransceiver(audioTrack, { direction: 'sendonly' });
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;
82
+ }
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
+ });
115
+ }
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();
125
+ }
126
+ async snapshot() {
127
+ this.logger.debug(`${this.cameraDevice.name}: Snapshot requested`);
128
+ return await this.ringCamera.getSnapshot();
129
+ }
130
+ async reboot() {
131
+ return;
132
+ }
133
+ async createRTSPServer() {
134
+ const stream = {
135
+ name: 'Ring',
136
+ receiver: this,
137
+ addBackchannel: true,
138
+ };
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),
145
+ };
146
+ this.rtspServer = await RTSPSingleServer.initialize({ stream }, rtspLogger);
147
+ await this.rtspServer.listen();
148
+ }
149
+ createPeerCoonection() {
150
+ return new RTCPeerConnection({
151
+ codecs: {
152
+ video: [
153
+ new RTCRtpCodecParameters({
154
+ mimeType: 'video/H264',
155
+ clockRate: 90000,
156
+ payloadType: 96,
157
+ rtcpFeedback: [{ type: 'transport-cc' }, { type: 'ccm', parameter: 'fir' }, { type: 'nack' }, { type: 'nack', parameter: 'pli' }, { type: 'goog-remb' }],
158
+ parameters: 'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f',
159
+ }),
160
+ ],
161
+ audio: [
162
+ new RTCRtpCodecParameters({
163
+ mimeType: 'audio/opus',
164
+ clockRate: 48000,
165
+ payloadType: 101,
166
+ channels: 2,
167
+ parameters: 'minptime=10;useinbandfec=1',
168
+ }),
169
+ ],
170
+ },
171
+ });
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
+ }
226
+ }
227
+ //# sourceMappingURL=camera.js.map
@@ -0,0 +1 @@
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 { API } from '@camera.ui/types';
2
- declare const _default: (api: API) => void;
3
- export default _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
+ }