ring-client-api 9.22.0-beta.0 → 9.24.0

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 CHANGED
@@ -2,12 +2,53 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- ## [9.22.0-beta.0](https://github.com/dgreif/ring/compare/v9.21.2...v9.22.0-beta.0) (2021-09-26)
5
+ ## [9.24.0](https://github.com/dgreif/ring/compare/v9.23.0...v9.24.0) (2022-01-22)
6
6
 
7
7
 
8
8
  ### Features
9
9
 
10
- * support unknown zwave switch ([45ee375](https://github.com/dgreif/ring/commit/45ee37508436bb84b64c7816f228620333934f25)), closes [#775](https://github.com/dgreif/ring/issues/775)
10
+ * support glassbreak sensor ([98271f9](https://github.com/dgreif/ring/commit/98271f91f13aaae051fccaab7165cd17f2a2377c))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * allow process to exit when RingApi.disconnect() is called ([#851](https://github.com/dgreif/ring/issues/851)) ([8ef25ac](https://github.com/dgreif/ring/commit/8ef25acca66c533873b7fd43c7c899e34b4a7617))
16
+ * avoid error when ring terminates video stream ([7717d5e](https://github.com/dgreif/ring/commit/7717d5eaa40afed3d34f0e8e6eea1402e21afef7)), closes [#853](https://github.com/dgreif/ring/issues/853)
17
+ * update dependencies ([c80d052](https://github.com/dgreif/ring/commit/c80d052f9eaf4c0a50a495166177daa40299ffa7))
18
+
19
+ ## [9.23.0](https://github.com/dgreif/ring/compare/v9.22.1...v9.23.0) (2021-10-17)
20
+
21
+
22
+ ### Features
23
+
24
+ * **homebridge:** config option to hide camera lights ([58be17c](https://github.com/dgreif/ring/commit/58be17cfee524bfb158566e59d60438e9b6f0f5d)), closes [#802](https://github.com/dgreif/ring/issues/802)
25
+ * **homebridge:** option to treat "knock" as a ding ([7ece8b2](https://github.com/dgreif/ring/commit/7ece8b25314ef403a6c2bab6a28476a3b7229507)), closes [#514](https://github.com/dgreif/ring/issues/514)
26
+
27
+
28
+ ### Bug Fixes
29
+
30
+ * update dependencies ([b685e27](https://github.com/dgreif/ring/commit/b685e27e952a94635a277848821ebfa640d50ee2))
31
+
32
+ ### [9.22.1](https://github.com/dgreif/ring/compare/v9.22.0...v9.22.1) (2021-10-13)
33
+
34
+
35
+ ### Bug Fixes
36
+
37
+ * **homebridge:** prevent login attempt for null refresh tokens ([#791](https://github.com/dgreif/ring/issues/791)) ([bbc9db5](https://github.com/dgreif/ring/commit/bbc9db5578f9b3ed2af49256c8581fef5af8e134))
38
+
39
+ ## [9.22.0](https://github.com/dgreif/ring/compare/v9.21.2...v9.22.0) (2021-10-02)
40
+
41
+
42
+ ### Features
43
+
44
+ * support unknown zwave switch ([9a0a0b9](https://github.com/dgreif/ring/commit/9a0a0b9a3518e2ab9ec732d61fc1102a4e3b9458)), closes [#775](https://github.com/dgreif/ring/issues/775)
45
+
46
+
47
+ ### Bug Fixes
48
+
49
+ * handle promise rejections ([2df5591](https://github.com/dgreif/ring/commit/2df559128fbaeda7de6a64fa7029c86a08b26633))
50
+ * **homebridge:** handle camera stream ending before it is active ([4a0edc0](https://github.com/dgreif/ring/commit/4a0edc031fa6093ec0fa873f04479efa98307bc1)), closes [#762](https://github.com/dgreif/ring/issues/762)
51
+ * update dependencies ([24d5fde](https://github.com/dgreif/ring/commit/24d5fde5f456fa9bb3191c0dc8fa2b483a7ee310))
11
52
 
12
53
  ### [9.21.2](https://github.com/dgreif/ring/compare/v9.21.1...v9.21.2) (2021-09-08)
13
54
 
package/README.md CHANGED
@@ -45,6 +45,7 @@ Option | Default | Explanation
45
45
  `ffmpegPath` | Uses `ffmpeg-for-homebridge` | A custom path to the `ffmpeg` executable. By default, the static binaries built in [ffmpeg-for-homebridge](https://github.com/oznu/ffmpeg-for-homebridg) will be used. If you prefer to use your own version of ffmpeg, you can pass a complete path, or simply `"ffmpeg"` to use ffmpeg from your `PATH`.
46
46
  `controlCenterDisplayName` | 'ring-client-api' | This allows you to change the displayed name for the Authorized Device within Control Center in the Ring app
47
47
  `avoidSnapshotBatteryDrain` | false | Causes snapshots for battery cameras to be fetched at a minimum 10 minute interval to avoid draining the battery.
48
+ `treatKnockAsDing` | false | Will cause "knock" (`door_activity`) dings to be emitted from `onDoorbellPressed`
48
49
 
49
50
  ## Locations
50
51
  ```typescript
@@ -108,7 +109,7 @@ Camera also includes the following observables:
108
109
  * `onDoorbellPressed`: emits a ding every time the doorbell is pressed
109
110
  * `onMotionDetected`: `true` or `false` based on `onActiveDings` containing a motion ding
110
111
 
111
- Some other useful propeties
112
+ Some other useful properties
112
113
  * `id`
113
114
  * `name`: same as `description` from `data`
114
115
  * `hasLight`: does this camera have a light
package/lib/api/api.d.ts CHANGED
@@ -9,6 +9,7 @@ export interface RingApiOptions extends SessionOptions {
9
9
  cameraDingsPollingSeconds?: number;
10
10
  locationModePollingSeconds?: number;
11
11
  avoidSnapshotBatteryDrain?: boolean;
12
+ treatKnockAsDing?: boolean;
12
13
  debug?: boolean;
13
14
  ffmpegPath?: string;
14
15
  externalPorts?: {
package/lib/api/api.js CHANGED
@@ -24,7 +24,8 @@ class RingApi extends subscribed_1.Subscribed {
24
24
  super();
25
25
  this.options = options;
26
26
  this.restClient = new rest_client_1.RingRestClient(this.options);
27
- this.onRefreshTokenUpdated = this.restClient.onRefreshTokenUpdated.asObservable();
27
+ this.onRefreshTokenUpdated =
28
+ this.restClient.onRefreshTokenUpdated.asObservable();
28
29
  if (options.debug) {
29
30
  (0, util_1.enableDebug)();
30
31
  }
@@ -128,7 +129,7 @@ class RingApi extends subscribed_1.Subscribed {
128
129
  return __awaiter(this, void 0, void 0, function* () {
129
130
  const rawLocations = yield this.fetchRawLocations(), { authorizedDoorbots, chimes, doorbots, allCameras, baseStations, beamBridges, } = yield this.fetchRingDevices(), locationIdsWithHubs = [...baseStations, ...beamBridges].map((x) => x.location_id), cameras = allCameras.map((data) => new ring_camera_1.RingCamera(data, doorbots.includes(data) ||
130
131
  authorizedDoorbots.includes(data) ||
131
- data.kind.startsWith('doorbell'), this.restClient, this.options.avoidSnapshotBatteryDrain || false)), ringChimes = chimes.map((data) => new ring_chime_1.RingChime(data, this.restClient)), locations = rawLocations
132
+ data.kind.startsWith('doorbell'), this.restClient, this.options.avoidSnapshotBatteryDrain || false, this.options.treatKnockAsDing || false)), ringChimes = chimes.map((data) => new ring_chime_1.RingChime(data, this.restClient)), locations = rawLocations
132
133
  .filter((location) => {
133
134
  return (!Array.isArray(this.options.locationIds) ||
134
135
  this.options.locationIds.includes(location.location_id));
@@ -169,6 +170,7 @@ class RingApi extends subscribed_1.Subscribed {
169
170
  .catch((e) => {
170
171
  (0, util_1.logError)(e);
171
172
  });
173
+ this.restClient.clearTimeouts();
172
174
  }
173
175
  }
174
176
  exports.RingApi = RingApi;
@@ -96,7 +96,7 @@ class Location extends subscribed_1.Subscribed {
96
96
  this.addSubscriptions((0, rxjs_1.merge)(this.onLocationModeRequested, this.onLocationMode)
97
97
  .pipe((0, operators_1.debounceTime)(options.locationModePollingSeconds * 1000))
98
98
  .subscribe(() => this.getLocationMode()));
99
- void this.getLocationMode();
99
+ this.getLocationMode().catch(util_1.logError);
100
100
  }
101
101
  }
102
102
  get id() {
@@ -188,7 +188,7 @@ class Location extends subscribed_1.Subscribed {
188
188
  }
189
189
  setAlarmMode(alarmMode, bypassSensorZids) {
190
190
  return __awaiter(this, void 0, void 0, function* () {
191
- const securityPanel = yield this.getSecurityPanel(), updatedDataPromise = (0, rxjs_1.lastValueFrom)(securityPanel.onData.pipe((0, operators_1.skip)(1), (0, operators_1.take)(1)));
191
+ const securityPanel = yield this.getSecurityPanel(), updatedDataPromise = (0, rxjs_1.firstValueFrom)(securityPanel.onData.pipe((0, operators_1.skip)(1)));
192
192
  yield this.sendCommandToSecurityPanel('security-panel.switch-mode', {
193
193
  mode: alarmMode,
194
194
  bypass: bypassSensorZids,
@@ -224,7 +224,7 @@ class Location extends subscribed_1.Subscribed {
224
224
  });
225
225
  }
226
226
  getNextMessageOfType(type, src) {
227
- return (0, rxjs_1.lastValueFrom)(this.onMessage.pipe((0, operators_1.filter)((m) => m.msg === type && m.src === src), (0, operators_1.map)((m) => m.body), (0, operators_1.take)(1)));
227
+ return (0, rxjs_1.firstValueFrom)(this.onMessage.pipe((0, operators_1.filter)((m) => m.msg === type && m.src === src), (0, operators_1.map)((m) => m.body)));
228
228
  }
229
229
  requestList(listType, assetId) {
230
230
  return this.sendMessage({ msg: listType, dst: assetId });
@@ -243,7 +243,7 @@ class Location extends subscribed_1.Subscribed {
243
243
  if (!this.connectionPromise) {
244
244
  yield this.getConnection();
245
245
  }
246
- return (0, rxjs_1.lastValueFrom)(this.onDevices.pipe((0, operators_1.take)(1)));
246
+ return (0, rxjs_1.firstValueFrom)(this.onDevices);
247
247
  });
248
248
  }
249
249
  getRoomList(assetId) {
@@ -391,11 +391,15 @@ class Location extends subscribed_1.Subscribed {
391
391
  this.disconnected = true;
392
392
  this.unsubscribe();
393
393
  this.cameras.forEach((camera) => camera.disconnect());
394
- this.getDevices().then((devices) => {
394
+ this.getDevices()
395
+ .then((devices) => {
395
396
  devices.forEach((device) => device.disconnect());
396
- });
397
+ })
398
+ .catch(util_1.logError);
397
399
  if (this.connectionPromise) {
398
- this.connectionPromise.then((connection) => connection.close());
400
+ this.connectionPromise
401
+ .then((connection) => connection.close())
402
+ .catch(util_1.logError);
399
403
  }
400
404
  }
401
405
  }
@@ -24,6 +24,7 @@ export declare class RingRestClient {
24
24
  refreshToken: string | undefined;
25
25
  private hardwareIdPromise;
26
26
  private _authPromise;
27
+ private timeouts;
27
28
  private clearPreviousAuth;
28
29
  private get authPromise();
29
30
  private sessionPromise?;
@@ -44,4 +45,5 @@ export declare class RingRestClient {
44
45
  url: string;
45
46
  }): Promise<T & ExtendedResponse>;
46
47
  getCurrentAuth(): Promise<AuthTokenResponse>;
48
+ clearTimeouts(): void;
47
49
  }
@@ -66,12 +66,15 @@ function requestWithRetry(requestOptions) {
66
66
  class RingRestClient {
67
67
  constructor(authOptions) {
68
68
  this.authOptions = authOptions;
69
- // prettier-ignore
70
- this.refreshToken = ('refreshToken' in this.authOptions ? this.authOptions.refreshToken : undefined);
71
- this.hardwareIdPromise = (0, util_1.getHardwareId)(this.authOptions.systemId);
69
+ this.timeouts = [];
72
70
  this.sessionPromise = undefined;
73
71
  this.using2fa = false;
74
72
  this.onRefreshTokenUpdated = new rxjs_1.ReplaySubject(1);
73
+ this.refreshToken =
74
+ 'refreshToken' in this.authOptions
75
+ ? this.authOptions.refreshToken
76
+ : undefined;
77
+ this.hardwareIdPromise = (0, util_1.getHardwareId)(this.authOptions.systemId);
75
78
  }
76
79
  clearPreviousAuth() {
77
80
  this._authPromise = undefined;
@@ -83,11 +86,12 @@ class RingRestClient {
83
86
  authPromise
84
87
  .then(({ expires_in }) => {
85
88
  // clear the existing auth promise 1 minute before it expires
86
- setTimeout(() => {
89
+ const timeout = setTimeout(() => {
87
90
  if (this._authPromise === authPromise) {
88
91
  this.clearPreviousAuth();
89
92
  }
90
93
  }, ((expires_in || 3600) - 60) * 1000);
94
+ this.timeouts.push(timeout);
91
95
  })
92
96
  .catch(() => {
93
97
  // ignore these errors here, they should be handled by the function making a rest request
@@ -288,5 +292,8 @@ class RingRestClient {
288
292
  getCurrentAuth() {
289
293
  return this.authPromise;
290
294
  }
295
+ clearTimeouts() {
296
+ this.timeouts.forEach(clearTimeout);
297
+ }
291
298
  }
292
299
  exports.RingRestClient = RingRestClient;
@@ -16,6 +16,7 @@ export declare class RingCamera extends Subscribed {
16
16
  isDoorbot: boolean;
17
17
  private restClient;
18
18
  private avoidSnapshotBatteryDrain;
19
+ private treatKnockAsDing;
19
20
  id: number;
20
21
  deviceType: import("./ring-types").RingCameraKind;
21
22
  model: string;
@@ -32,7 +33,7 @@ export declare class RingCamera extends Subscribed {
32
33
  onMotionStarted: import("rxjs").Observable<null>;
33
34
  onBatteryLevel: import("rxjs").Observable<number | null>;
34
35
  onInHomeDoorbellStatus: import("rxjs").Observable<boolean>;
35
- constructor(initialData: CameraData, isDoorbot: boolean, restClient: RingRestClient, avoidSnapshotBatteryDrain: boolean);
36
+ constructor(initialData: CameraData, isDoorbot: boolean, restClient: RingRestClient, avoidSnapshotBatteryDrain: boolean, treatKnockAsDing: boolean);
36
37
  updateData(update: CameraData): void;
37
38
  requestUpdate(): void;
38
39
  get data(): CameraData;
@@ -85,7 +86,7 @@ export declare class RingCamera extends Subscribed {
85
86
  private checkIfSnapshotsAreBlocked;
86
87
  private requestSnapshotUpdate;
87
88
  private refreshSnapshot;
88
- getSnapshot(): Promise<Buffer>;
89
+ getSnapshot(): Promise<Buffer | undefined>;
89
90
  getSipOptions(): Promise<SipOptions>;
90
91
  getUpdatedSipOptions(expiredDingId: string): Promise<SipOptions>;
91
92
  createSipSession(options?: {
@@ -66,37 +66,40 @@ function getSearchQueryString(options) {
66
66
  }
67
67
  exports.getSearchQueryString = getSearchQueryString;
68
68
  class RingCamera extends subscribed_1.Subscribed {
69
- constructor(initialData, isDoorbot, restClient, avoidSnapshotBatteryDrain) {
69
+ constructor(initialData, isDoorbot, restClient, avoidSnapshotBatteryDrain, treatKnockAsDing) {
70
70
  super();
71
71
  this.initialData = initialData;
72
72
  this.isDoorbot = isDoorbot;
73
73
  this.restClient = restClient;
74
74
  this.avoidSnapshotBatteryDrain = avoidSnapshotBatteryDrain;
75
- this.id = this.initialData.id;
76
- this.deviceType = this.initialData.kind;
77
- this.model = ring_types_1.RingCameraModel[this.initialData.kind] || 'Unknown Model';
78
- this.onData = new rxjs_1.BehaviorSubject(this.initialData);
79
- this.hasLight = this.initialData.led_status !== undefined;
80
- this.hasSiren = this.initialData.siren_status !== undefined;
81
- this.hasBattery = (0, ring_types_1.isBatteryCameraKind)(this.deviceType) ||
82
- (typeof this.initialData.battery_life === 'string' &&
83
- this.batteryLevel !== null &&
84
- this.batteryLevel < 100 &&
85
- this.batteryLevel >= 0);
75
+ this.treatKnockAsDing = treatKnockAsDing;
86
76
  this.onRequestUpdate = new rxjs_1.Subject();
87
77
  this.onRequestActiveDings = new rxjs_1.Subject();
88
78
  this.onNewDing = new rxjs_1.Subject();
89
79
  this.onActiveDings = new rxjs_1.BehaviorSubject([]);
90
- this.onDoorbellPressed = this.onNewDing.pipe((0, operators_1.filter)((ding) => ding.kind === 'ding'), (0, operators_1.share)());
80
+ this.onDoorbellPressed = this.onNewDing.pipe((0, operators_1.filter)((ding) => ding.kind === 'ding' ||
81
+ (this.treatKnockAsDing && ding.kind === 'door_activity')), (0, operators_1.share)());
91
82
  this.onMotionDetected = this.onActiveDings.pipe((0, operators_1.map)((dings) => dings.some((ding) => ding.motion || ding.kind === 'motion')), (0, operators_1.distinctUntilChanged)(), (0, operators_1.publishReplay)(1), (0, operators_1.refCount)());
92
83
  this.onMotionStarted = this.onMotionDetected.pipe((0, operators_1.filter)((currentlyDetected) => currentlyDetected), (0, operators_1.mapTo)(null), // no value needed, event is what matters
93
84
  (0, operators_1.share)());
85
+ this.expiredDingIds = [];
86
+ this.lastSnapshotTimestampLocal = 0;
87
+ this.id = this.initialData.id;
88
+ this.deviceType = this.initialData.kind;
89
+ this.model = ring_types_1.RingCameraModel[this.initialData.kind] || 'Unknown Model';
90
+ this.onData = new rxjs_1.BehaviorSubject(this.initialData);
91
+ this.hasLight = this.initialData.led_status !== undefined;
92
+ this.hasSiren = this.initialData.siren_status !== undefined;
93
+ this.hasBattery =
94
+ (0, ring_types_1.isBatteryCameraKind)(this.deviceType) ||
95
+ (typeof this.initialData.battery_life === 'string' &&
96
+ this.batteryLevel !== null &&
97
+ this.batteryLevel < 100 &&
98
+ this.batteryLevel >= 0);
94
99
  this.onBatteryLevel = this.onData.pipe((0, operators_1.map)(getBatteryLevel), (0, operators_1.distinctUntilChanged)());
95
100
  this.onInHomeDoorbellStatus = this.onData.pipe((0, operators_1.map)(({ settings: { chime_settings } }) => {
96
101
  return Boolean(chime_settings === null || chime_settings === void 0 ? void 0 : chime_settings.enable);
97
102
  }), (0, operators_1.distinctUntilChanged)());
98
- this.expiredDingIds = [];
99
- this.lastSnapshotTimestampLocal = 0;
100
103
  if (!initialData.subscribed) {
101
104
  this.subscribeToDingEvents().catch((e) => {
102
105
  (0, util_1.logError)('Failed to subscribe ' + initialData.description + ' to ding events');
@@ -250,7 +253,7 @@ class RingCamera extends subscribed_1.Subscribed {
250
253
  }
251
254
  getSipConnectionDetails() {
252
255
  return __awaiter(this, void 0, void 0, function* () {
253
- const vodPromise = (0, rxjs_1.lastValueFrom)(this.onNewDing.pipe((0, operators_1.take)(1))), videoOnDemandDing = yield this.startVideoOnDemand();
256
+ const vodPromise = (0, rxjs_1.firstValueFrom)(this.onNewDing), videoOnDemandDing = yield this.startVideoOnDemand();
254
257
  if (videoOnDemandDing && 'sip_from' in videoOnDemandDing) {
255
258
  // wired cams return a ding from live_view so we don't need to wait
256
259
  return videoOnDemandDing;
@@ -407,10 +410,13 @@ class RingCamera extends subscribed_1.Subscribed {
407
410
  url: (0, rest_client_1.clientApi)(`snapshots/image/${this.id}`),
408
411
  responseType: 'buffer',
409
412
  });
410
- this.lastSnapshotPromise.catch(() => {
413
+ try {
414
+ yield this.lastSnapshotPromise;
415
+ }
416
+ catch (_) {
411
417
  // snapshot request failed, don't use it again
412
418
  this.lastSnapshotPromise = undefined;
413
- });
419
+ }
414
420
  return this.lastSnapshotPromise;
415
421
  });
416
422
  }
@@ -458,7 +464,7 @@ class RingCamera extends subscribed_1.Subscribed {
458
464
  const sipSession = yield this.streamVideo({
459
465
  output: ['-t', duration.toString(), outputPath],
460
466
  });
461
- yield (0, rxjs_1.lastValueFrom)(sipSession.onCallEnded.pipe((0, operators_1.take)(1)));
467
+ yield (0, rxjs_1.firstValueFrom)(sipSession.onCallEnded);
462
468
  });
463
469
  }
464
470
  streamVideo(ffmpegOptions) {
@@ -5,7 +5,7 @@ export declare class RingChime {
5
5
  private initialData;
6
6
  private restClient;
7
7
  id: number;
8
- deviceType: "chime" | "chime_pro" | "chime_v2" | "chime_pro_v2";
8
+ deviceType: import("./ring-types").ChimeKind;
9
9
  model: string;
10
10
  onData: BehaviorSubject<ChimeData>;
11
11
  onRequestUpdate: Subject<unknown>;
@@ -23,11 +23,11 @@ class RingChime {
23
23
  constructor(initialData, restClient) {
24
24
  this.initialData = initialData;
25
25
  this.restClient = restClient;
26
+ this.onRequestUpdate = new rxjs_1.Subject();
26
27
  this.id = this.initialData.id;
27
28
  this.deviceType = this.initialData.kind;
28
29
  this.model = ring_types_1.ChimeModel[this.deviceType] || 'Chime';
29
30
  this.onData = new rxjs_1.BehaviorSubject(this.initialData);
30
- this.onRequestUpdate = new rxjs_1.Subject();
31
31
  }
32
32
  updateData(update) {
33
33
  this.onData.next(update);
@@ -5,6 +5,7 @@ const rxjs_1 = require("rxjs");
5
5
  const ring_types_1 = require("./ring-types");
6
6
  const operators_1 = require("rxjs/operators");
7
7
  const subscribed_1 = require("./subscribed");
8
+ const util_1 = require("./util");
8
9
  class RingDevice extends subscribed_1.Subscribed {
9
10
  constructor(initialData, location, assetId) {
10
11
  super();
@@ -63,7 +64,7 @@ class RingDevice extends subscribed_1.Subscribed {
63
64
  },
64
65
  ],
65
66
  },
66
- });
67
+ }).catch(util_1.logError);
67
68
  }
68
69
  toString() {
69
70
  return this.toJSON();
@@ -10,6 +10,7 @@ export declare enum RingDeviceType {
10
10
  TemperatureSensor = "sensor.temperature",
11
11
  WaterSensor = "sensor.water",
12
12
  TiltSensor = "sensor.tilt",
13
+ GlassbreakSensor = "sensor.glassbreak",
13
14
  RangeExtender = "range-extender.zwave",
14
15
  ZigbeeAdapter = "adapter.zigbee",
15
16
  AccessCodeVault = "access-code.vault",
@@ -214,7 +215,7 @@ export interface BeamBridge {
214
215
  role: string;
215
216
  updated_at: string;
216
217
  }
217
- declare type ChimeKind = 'chime' | 'chime_pro' | 'chime_v2' | 'chime_pro_v2';
218
+ export declare type ChimeKind = 'chime' | 'chime_pro' | 'chime_v2' | 'chime_pro_v2';
218
219
  export declare const ChimeModel: {
219
220
  readonly [P in ChimeKind]: string;
220
221
  };
@@ -14,6 +14,7 @@ var RingDeviceType;
14
14
  RingDeviceType["TemperatureSensor"] = "sensor.temperature";
15
15
  RingDeviceType["WaterSensor"] = "sensor.water";
16
16
  RingDeviceType["TiltSensor"] = "sensor.tilt";
17
+ RingDeviceType["GlassbreakSensor"] = "sensor.glassbreak";
17
18
  RingDeviceType["RangeExtender"] = "range-extender.zwave";
18
19
  RingDeviceType["ZigbeeAdapter"] = "adapter.zigbee";
19
20
  RingDeviceType["AccessCodeVault"] = "access-code.vault";
@@ -28,8 +28,10 @@ function sendStunBindingRequest({ rtpDescription, rtpSplitter, rtcpSplitter, loc
28
28
  else {
29
29
  // ICE not supported. Fire and forget the stun request for RTP and RTCP
30
30
  const encodedMessage = stun.encode(message);
31
- rtpSplitter.send(encodedMessage, { address, port });
32
- rtcpSplitter.send(encodedMessage, { address, port: rtcpPort });
31
+ rtpSplitter.send(encodedMessage, { address, port }).catch(util_1.logError);
32
+ rtcpSplitter
33
+ .send(encodedMessage, { address, port: rtcpPort })
34
+ .catch(util_1.logError);
33
35
  }
34
36
  }
35
37
  exports.sendStunBindingRequest = sendStunBindingRequest;
@@ -166,7 +166,7 @@ class SipCall {
166
166
  ackWithInfo(seq) {
167
167
  return __awaiter(this, void 0, void 0, function* () {
168
168
  // Don't wait for ack, it won't ever come back.
169
- void this.request({
169
+ this.request({
170
170
  method: 'ACK',
171
171
  seq, // The ACK must have the original sequence number.
172
172
  }).catch(rxjs_1.noop);
@@ -32,8 +32,8 @@ class SipSession extends subscribed_1.Subscribed {
32
32
  this.hasStarted = false;
33
33
  this.hasCallEnded = false;
34
34
  this.onCallEndedSubject = new rxjs_1.ReplaySubject(1);
35
- this.sipCall = this.createSipCall(this.sipOptions);
36
35
  this.onCallEnded = this.onCallEndedSubject.asObservable();
36
+ this.sipCall = this.createSipCall(this.sipOptions);
37
37
  }
38
38
  createSipCall(sipOptions) {
39
39
  if (this.sipCall) {
@@ -159,7 +159,7 @@ class SipSession extends subscribed_1.Subscribed {
159
159
  return null;
160
160
  }
161
161
  if (!haveReceivedStreamPacket) {
162
- void this.sipCall.requestKeyFrame();
162
+ this.sipCall.requestKeyFrame().catch(rxjs_1.noop);
163
163
  haveReceivedStreamPacket = true;
164
164
  }
165
165
  return {
@@ -196,7 +196,7 @@ class SipSession extends subscribed_1.Subscribed {
196
196
  }
197
197
  this.hasCallEnded = true;
198
198
  if (sendBye) {
199
- this.sipCall.sendBye();
199
+ this.sipCall.sendBye().catch(util_1.logError);
200
200
  }
201
201
  // clean up
202
202
  this.onCallEndedSubject.next(null);
package/lib/api/sip.d.ts CHANGED
@@ -19,6 +19,7 @@ export function create(options: any, callback: any): {
19
19
  isFlowUri: (uri: any) => boolean;
20
20
  hostname: () => any;
21
21
  destroy: () => void;
22
+ makeResponse: typeof makeResponse;
22
23
  };
23
24
  export function start(options: any, callback: any): void;
24
25
  export function parseAOR(data: any): any;
package/lib/api/sip.js CHANGED
@@ -1300,6 +1300,7 @@ exports.create = function (options, callback) {
1300
1300
  transaction.destroy();
1301
1301
  transport.destroy();
1302
1302
  },
1303
+ makeResponse,
1303
1304
  };
1304
1305
  };
1305
1306
  exports.start = function (options, callback) {
package/lib/api/util.js CHANGED
@@ -8,14 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
15
  exports.randomString = exports.randomInteger = exports.mapAsync = exports.stringify = exports.requestInput = exports.getHardwareId = exports.generateUuid = exports.enableDebug = exports.useLogger = exports.logError = exports.logInfo = exports.logDebug = exports.delay = void 0;
13
- const debug = require("debug");
16
+ const debug_1 = __importDefault(require("debug"));
14
17
  const colors_1 = require("colors");
15
18
  const readline_1 = require("readline");
16
19
  const uuid_1 = require("uuid");
17
20
  const systeminformation_1 = require("systeminformation");
18
- const debugLogger = debug('ring'), uuidNamespace = 'e53ffdc0-e91d-4ce1-bec2-df939d94739c';
21
+ const debugLogger = (0, debug_1.default)('ring'), uuidNamespace = 'e53ffdc0-e91d-4ce1-bec2-df939d94739c';
19
22
  let logger = {
20
23
  logInfo(message) {
21
24
  debugLogger(message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ring-client-api",
3
- "version": "9.22.0-beta.0",
3
+ "version": "9.24.0",
4
4
  "description": "Unofficial API for Ring doorbells, cameras, security alarm system and smart lighting",
5
5
  "main": "lib/api/index.js",
6
6
  "bin": {
@@ -57,41 +57,41 @@
57
57
  "@homebridge/plugin-ui-utils": "0.0.19",
58
58
  "@types/socket.io-client": "1.4.36",
59
59
  "colors": "1.4.0",
60
- "debug": "4.3.2",
61
- "got": "11.8.2",
62
- "rxjs": "7.3.0",
60
+ "debug": "4.3.3",
61
+ "got": "11.8.3",
62
+ "rxjs": "7.5.2",
63
63
  "sdp": "3.0.3",
64
64
  "socket.io-client": "2.4.0",
65
65
  "stun": "2.1.0",
66
- "systeminformation": "5.8.7",
66
+ "systeminformation": "5.10.7",
67
67
  "uuid": "8.3.2"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@types/debug": "4.1.7",
71
- "@types/jest": "27.0.1",
72
- "@types/node": "16.7.10",
73
- "@types/uuid": "8.3.1",
74
- "@typescript-eslint/eslint-plugin": "4.29.1",
75
- "@typescript-eslint/parser": "4.29.1",
76
- "concurrently": "^6.2.1",
71
+ "@types/jest": "27.4.0",
72
+ "@types/node": "17.0.10",
73
+ "@types/uuid": "8.3.4",
74
+ "@typescript-eslint/eslint-plugin": "5.10.0",
75
+ "@typescript-eslint/parser": "5.10.0",
76
+ "concurrently": "^7.0.0",
77
77
  "conventional-github-releaser": "3.1.5",
78
- "dotenv": "10.0.0",
79
- "eslint": "7.32.0",
78
+ "dotenv": "14.2.0",
79
+ "eslint": "8.7.0",
80
80
  "eslint-config-prettier": "8.3.0",
81
- "eslint-plugin-jest": "24.4.0",
82
- "eslint-plugin-prettier": "3.4.0",
83
- "express": "4.17.1",
84
- "homebridge": "1.3.4",
85
- "jest": "27.1.0",
86
- "prettier": "2.3.2",
81
+ "eslint-plugin-jest": "25.7.0",
82
+ "eslint-plugin-prettier": "4.0.0",
83
+ "express": "4.17.2",
84
+ "homebridge": "1.4.0",
85
+ "jest": "27.4.7",
86
+ "prettier": "2.5.1",
87
87
  "reflect-metadata": "0.1.13",
88
88
  "rimraf": "3.0.2",
89
- "standard-version": "9.3.1",
90
- "ts-jest": "27.0.5",
91
- "typescript": "4.4.2"
89
+ "standard-version": "9.3.2",
90
+ "ts-jest": "27.1.3",
91
+ "typescript": "4.5.5"
92
92
  },
93
93
  "engines": {
94
- "node": "^10 || ^12.20 || ^14",
94
+ "node": "^10 || ^12.20 || ^14 || ^16",
95
95
  "homebridge": ">=1.0.0"
96
96
  },
97
97
  "bugs": {
@@ -107,5 +107,8 @@
107
107
  "type": "github",
108
108
  "url": "https://github.com/sponsors/dgreif"
109
109
  }
110
+ ],
111
+ "workspaces": [
112
+ "homebridge-ui"
110
113
  ]
111
114
  }