homebridge-ring 9.23.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 +14 -0
- package/README.md +4 -0
- package/lib/api/api.js +3 -1
- package/lib/api/rest-client.d.ts +2 -0
- package/lib/api/rest-client.js +11 -4
- package/lib/api/ring-camera.js +14 -13
- package/lib/api/ring-chime.d.ts +1 -1
- package/lib/api/ring-chime.js +1 -1
- package/lib/api/ring-types.d.ts +2 -1
- package/lib/api/ring-types.js +1 -0
- package/lib/api/sip-session.js +1 -1
- package/lib/api/sip.d.ts +1 -0
- package/lib/api/sip.js +1 -0
- package/lib/api/util.js +5 -2
- package/lib/homebridge/camera-source.js +3 -3
- package/lib/homebridge/ring-platform.js +1 -0
- package/package.json +20 -20
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
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.24.0](https://github.com/dgreif/ring/compare/v9.23.0...v9.24.0) (2022-01-22)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
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
|
+
|
|
5
19
|
## [9.23.0](https://github.com/dgreif/ring/compare/v9.22.1...v9.23.0) (2021-10-17)
|
|
6
20
|
|
|
7
21
|
|
package/README.md
CHANGED
|
@@ -165,6 +165,10 @@ If you are having issues with your cameras in the Home app, please see the [Came
|
|
|
165
165
|
* Detect water leak
|
|
166
166
|
* Tamper status
|
|
167
167
|
* Battery status
|
|
168
|
+
* Glassbreak Sensor (**untested**)
|
|
169
|
+
* Detect glass breaking
|
|
170
|
+
* Tamper status
|
|
171
|
+
* Battery status
|
|
168
172
|
* Ring Smart Lights (Motion Detector, Flood/Path/Step/Spot Lights, Bulbs, Transformer, Outdoor Smart Plug, Mailbox Sensor)
|
|
169
173
|
* On/Off
|
|
170
174
|
* Brightness Level
|
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 =
|
|
27
|
+
this.onRefreshTokenUpdated =
|
|
28
|
+
this.restClient.onRefreshTokenUpdated.asObservable();
|
|
28
29
|
if (options.debug) {
|
|
29
30
|
(0, util_1.enableDebug)();
|
|
30
31
|
}
|
|
@@ -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;
|
package/lib/api/rest-client.d.ts
CHANGED
|
@@ -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
|
}
|
package/lib/api/rest-client.js
CHANGED
|
@@ -66,12 +66,15 @@ function requestWithRetry(requestOptions) {
|
|
|
66
66
|
class RingRestClient {
|
|
67
67
|
constructor(authOptions) {
|
|
68
68
|
this.authOptions = authOptions;
|
|
69
|
-
|
|
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;
|
package/lib/api/ring-camera.js
CHANGED
|
@@ -73,17 +73,6 @@ class RingCamera extends subscribed_1.Subscribed {
|
|
|
73
73
|
this.restClient = restClient;
|
|
74
74
|
this.avoidSnapshotBatteryDrain = avoidSnapshotBatteryDrain;
|
|
75
75
|
this.treatKnockAsDing = treatKnockAsDing;
|
|
76
|
-
this.id = this.initialData.id;
|
|
77
|
-
this.deviceType = this.initialData.kind;
|
|
78
|
-
this.model = ring_types_1.RingCameraModel[this.initialData.kind] || 'Unknown Model';
|
|
79
|
-
this.onData = new rxjs_1.BehaviorSubject(this.initialData);
|
|
80
|
-
this.hasLight = this.initialData.led_status !== undefined;
|
|
81
|
-
this.hasSiren = this.initialData.siren_status !== undefined;
|
|
82
|
-
this.hasBattery = (0, ring_types_1.isBatteryCameraKind)(this.deviceType) ||
|
|
83
|
-
(typeof this.initialData.battery_life === 'string' &&
|
|
84
|
-
this.batteryLevel !== null &&
|
|
85
|
-
this.batteryLevel < 100 &&
|
|
86
|
-
this.batteryLevel >= 0);
|
|
87
76
|
this.onRequestUpdate = new rxjs_1.Subject();
|
|
88
77
|
this.onRequestActiveDings = new rxjs_1.Subject();
|
|
89
78
|
this.onNewDing = new rxjs_1.Subject();
|
|
@@ -93,12 +82,24 @@ class RingCamera extends subscribed_1.Subscribed {
|
|
|
93
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)());
|
|
94
83
|
this.onMotionStarted = this.onMotionDetected.pipe((0, operators_1.filter)((currentlyDetected) => currentlyDetected), (0, operators_1.mapTo)(null), // no value needed, event is what matters
|
|
95
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);
|
|
96
99
|
this.onBatteryLevel = this.onData.pipe((0, operators_1.map)(getBatteryLevel), (0, operators_1.distinctUntilChanged)());
|
|
97
100
|
this.onInHomeDoorbellStatus = this.onData.pipe((0, operators_1.map)(({ settings: { chime_settings } }) => {
|
|
98
101
|
return Boolean(chime_settings === null || chime_settings === void 0 ? void 0 : chime_settings.enable);
|
|
99
102
|
}), (0, operators_1.distinctUntilChanged)());
|
|
100
|
-
this.expiredDingIds = [];
|
|
101
|
-
this.lastSnapshotTimestampLocal = 0;
|
|
102
103
|
if (!initialData.subscribed) {
|
|
103
104
|
this.subscribeToDingEvents().catch((e) => {
|
|
104
105
|
(0, util_1.logError)('Failed to subscribe ' + initialData.description + ' to ding events');
|
package/lib/api/ring-chime.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare class RingChime {
|
|
|
5
5
|
private initialData;
|
|
6
6
|
private restClient;
|
|
7
7
|
id: number;
|
|
8
|
-
deviceType: "
|
|
8
|
+
deviceType: import("./ring-types").ChimeKind;
|
|
9
9
|
model: string;
|
|
10
10
|
onData: BehaviorSubject<ChimeData>;
|
|
11
11
|
onRequestUpdate: Subject<unknown>;
|
package/lib/api/ring-chime.js
CHANGED
|
@@ -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);
|
package/lib/api/ring-types.d.ts
CHANGED
|
@@ -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
|
};
|
package/lib/api/ring-types.js
CHANGED
|
@@ -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";
|
package/lib/api/sip-session.js
CHANGED
|
@@ -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) {
|
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
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
|
|
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 =
|
|
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);
|
|
@@ -268,13 +268,13 @@ class CameraSource {
|
|
|
268
268
|
});
|
|
269
269
|
let returnAudioPort = null;
|
|
270
270
|
if (libfdkAacInstalled) {
|
|
271
|
-
let
|
|
271
|
+
let cameraSpeakerActive = false;
|
|
272
272
|
const ringAudioLocation = {
|
|
273
273
|
address: ringRtpDescription.address,
|
|
274
274
|
port: ringRtpDescription.audio.port,
|
|
275
275
|
}, returnAudioTranscodedSplitter = new camera_utils_1.RtpSplitter((description) => {
|
|
276
|
-
if (!
|
|
277
|
-
|
|
276
|
+
if (!cameraSpeakerActive) {
|
|
277
|
+
cameraSpeakerActive = true;
|
|
278
278
|
sipSession.activateCameraSpeaker().catch(util_1.logError);
|
|
279
279
|
}
|
|
280
280
|
sipSession.audioSplitter
|
|
@@ -61,6 +61,7 @@ function getAccessoryClass(device) {
|
|
|
61
61
|
case api_1.RingDeviceType.ContactSensor:
|
|
62
62
|
case api_1.RingDeviceType.RetrofitZone:
|
|
63
63
|
case api_1.RingDeviceType.TiltSensor:
|
|
64
|
+
case api_1.RingDeviceType.GlassbreakSensor:
|
|
64
65
|
return contact_sensor_1.ContactSensor;
|
|
65
66
|
case api_1.RingDeviceType.MotionSensor:
|
|
66
67
|
return motion_sensor_1.MotionSensor;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-ring",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.24.0",
|
|
4
4
|
"description": "Homebridge plugin for Ring doorbells, cameras, security alarm system and smart lighting",
|
|
5
5
|
"main": "lib/homebridge/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -43,38 +43,38 @@
|
|
|
43
43
|
"@homebridge/plugin-ui-utils": "0.0.19",
|
|
44
44
|
"@types/socket.io-client": "1.4.36",
|
|
45
45
|
"colors": "1.4.0",
|
|
46
|
-
"debug": "4.3.
|
|
47
|
-
"got": "11.8.
|
|
48
|
-
"rxjs": "7.
|
|
46
|
+
"debug": "4.3.3",
|
|
47
|
+
"got": "11.8.3",
|
|
48
|
+
"rxjs": "7.5.2",
|
|
49
49
|
"sdp": "3.0.3",
|
|
50
50
|
"socket.io-client": "2.4.0",
|
|
51
51
|
"stun": "2.1.0",
|
|
52
|
-
"systeminformation": "5.
|
|
52
|
+
"systeminformation": "5.10.7",
|
|
53
53
|
"uuid": "8.3.2"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/debug": "4.1.7",
|
|
57
|
-
"@types/jest": "27.0
|
|
58
|
-
"@types/node": "
|
|
59
|
-
"@types/uuid": "8.3.
|
|
60
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
61
|
-
"@typescript-eslint/parser": "5.
|
|
62
|
-
"concurrently": "^
|
|
57
|
+
"@types/jest": "27.4.0",
|
|
58
|
+
"@types/node": "17.0.10",
|
|
59
|
+
"@types/uuid": "8.3.4",
|
|
60
|
+
"@typescript-eslint/eslint-plugin": "5.10.0",
|
|
61
|
+
"@typescript-eslint/parser": "5.10.0",
|
|
62
|
+
"concurrently": "^7.0.0",
|
|
63
63
|
"conventional-github-releaser": "3.1.5",
|
|
64
|
-
"dotenv": "
|
|
65
|
-
"eslint": "8.0
|
|
64
|
+
"dotenv": "14.2.0",
|
|
65
|
+
"eslint": "8.7.0",
|
|
66
66
|
"eslint-config-prettier": "8.3.0",
|
|
67
|
-
"eslint-plugin-jest": "25.
|
|
67
|
+
"eslint-plugin-jest": "25.7.0",
|
|
68
68
|
"eslint-plugin-prettier": "4.0.0",
|
|
69
|
-
"express": "4.17.
|
|
70
|
-
"homebridge": "1.
|
|
71
|
-
"jest": "27.
|
|
72
|
-
"prettier": "2.
|
|
69
|
+
"express": "4.17.2",
|
|
70
|
+
"homebridge": "1.4.0",
|
|
71
|
+
"jest": "27.4.7",
|
|
72
|
+
"prettier": "2.5.1",
|
|
73
73
|
"reflect-metadata": "0.1.13",
|
|
74
74
|
"rimraf": "3.0.2",
|
|
75
75
|
"standard-version": "9.3.2",
|
|
76
|
-
"ts-jest": "27.
|
|
77
|
-
"typescript": "4.
|
|
76
|
+
"ts-jest": "27.1.3",
|
|
77
|
+
"typescript": "4.5.5"
|
|
78
78
|
},
|
|
79
79
|
"engines": {
|
|
80
80
|
"node": ">=8.3.0",
|