homebridge-ring 13.0.1 → 13.2.0-beta.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 +28 -0
- package/README.md +2 -0
- package/lib/base-accessory.js +1 -3
- package/lib/beam.js +7 -1
- package/lib/brightness-only.js +3 -0
- package/lib/camera-source.js +29 -20
- package/lib/camera.js +5 -0
- package/lib/chime.js +3 -0
- package/lib/co-alarm.js +3 -0
- package/lib/contact-sensor.js +3 -0
- package/lib/fan.js +3 -0
- package/lib/flood-freeze-sensor.js +3 -0
- package/lib/freeze-sensor.js +3 -0
- package/lib/homebridge-ui/public/homebridge-ring-ui.js +1 -0
- package/lib/homebridge-ui/public/index.html +3 -8
- package/lib/homebridge-ui/server.js +37 -36
- package/lib/intercom.js +5 -1
- package/lib/location-mode-switch.js +6 -1
- package/lib/lock.js +4 -0
- package/lib/motion-sensor.js +3 -0
- package/lib/multi-level-switch.js +3 -0
- package/lib/opus-repacketizer.js +2 -1
- package/lib/outlet.js +3 -0
- package/lib/panic-buttons.js +3 -0
- package/lib/ring-platform.js +7 -1
- package/lib/security-panel.js +4 -0
- package/lib/smoke-alarm.js +3 -0
- package/lib/smoke-co-listener.js +3 -0
- package/lib/switch.js +3 -0
- package/lib/target-value-timer.js +2 -0
- package/lib/temperature-sensor.js +3 -0
- package/lib/thermostat.js +4 -0
- package/lib/unknown-zwave-switch.js +3 -0
- package/lib/valve.js +38 -0
- package/lib/water-sensor.js +3 -0
- package/package.json +6 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# homebridge-ring
|
|
2
2
|
|
|
3
|
+
## 13.2.0-beta.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`2df3073`](https://github.com/dgreif/ring/commit/2df307381f020bf494f7e436b3d1cb0bc6748a37) Thanks [@dgreif](https://github.com/dgreif)! - Add support for Node 22
|
|
8
|
+
|
|
9
|
+
- [`abd5e98`](https://github.com/dgreif/ring/commit/abd5e9880df08bcd2f3ed27b3c1c0b679e74f12a) Thanks [@dgreif](https://github.com/dgreif)! - Updated build target from ES2021 to ES2022. ES2022 is fully supported by Node 18, which is the current minimum supported version.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`306f76d`](https://github.com/dgreif/ring/commit/306f76d6fd2eef1831330e04792a244a51a2fb86) Thanks [@dgreif](https://github.com/dgreif)! - Updated dependencies
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`2df3073`](https://github.com/dgreif/ring/commit/2df307381f020bf494f7e436b3d1cb0bc6748a37), [`306f76d`](https://github.com/dgreif/ring/commit/306f76d6fd2eef1831330e04792a244a51a2fb86), [`abd5e98`](https://github.com/dgreif/ring/commit/abd5e9880df08bcd2f3ed27b3c1c0b679e74f12a)]:
|
|
16
|
+
- ring-client-api@13.2.0-beta.0
|
|
17
|
+
|
|
18
|
+
## 13.1.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- [`1a1ee4b`](https://github.com/dgreif/ring/commit/1a1ee4b7fe44ead78577ff22d2d13b9133c9737b) Thanks [@dgreif](https://github.com/dgreif)! - Add support for water valves. Note, these have not been tested extensively so please let us know if you run into issues.
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- [`2f5d646`](https://github.com/dgreif/ring/commit/2f5d646471abcae2e20a3929aab44e292e67d9ab) Thanks [@dgreif](https://github.com/dgreif)! - Update dependencies
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [[`1a1ee4b`](https://github.com/dgreif/ring/commit/1a1ee4b7fe44ead78577ff22d2d13b9133c9737b), [`2f5d646`](https://github.com/dgreif/ring/commit/2f5d646471abcae2e20a3929aab44e292e67d9ab)]:
|
|
29
|
+
- ring-client-api@13.1.0
|
|
30
|
+
|
|
3
31
|
## 13.0.1
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -209,6 +209,8 @@ Note: Although homebridge has support for HomeKit Secure Video (HKSV), I will no
|
|
|
209
209
|
- Set Thermostat mode to heat/cool/off
|
|
210
210
|
- Set target temperature
|
|
211
211
|
- View current temperature and heating/cooling status
|
|
212
|
+
- Water Valves (**untested**)
|
|
213
|
+
- Open/Close the valve
|
|
212
214
|
|
|
213
215
|
### Chimes
|
|
214
216
|
|
package/lib/base-accessory.js
CHANGED
package/lib/beam.js
CHANGED
|
@@ -6,12 +6,18 @@ const hap_1 = require("./hap");
|
|
|
6
6
|
const base_device_accessory_1 = require("./base-device-accessory");
|
|
7
7
|
const util_1 = require("ring-client-api/util");
|
|
8
8
|
class Beam extends base_device_accessory_1.BaseDeviceAccessory {
|
|
9
|
+
device;
|
|
10
|
+
accessory;
|
|
11
|
+
config;
|
|
12
|
+
isLightGroup;
|
|
13
|
+
groupId;
|
|
9
14
|
constructor(device, accessory, config) {
|
|
10
15
|
super();
|
|
11
16
|
this.device = device;
|
|
12
17
|
this.accessory = accessory;
|
|
13
18
|
this.config = config;
|
|
14
|
-
this.isLightGroup =
|
|
19
|
+
this.isLightGroup =
|
|
20
|
+
this.device.data.deviceType === ring_client_api_1.RingDeviceType.BeamsLightGroupSwitch;
|
|
15
21
|
this.groupId = this.device.data.groupId;
|
|
16
22
|
const { Characteristic, Service } = hap_1.hap, { MotionSensor } = Service, { data: { deviceType }, } = this.device;
|
|
17
23
|
if (deviceType !== ring_client_api_1.RingDeviceType.BeamsMotionSensor) {
|
package/lib/brightness-only.js
CHANGED
|
@@ -5,6 +5,9 @@ const base_device_accessory_1 = require("./base-device-accessory");
|
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
const util_1 = require("ring-client-api/util");
|
|
7
7
|
class BrightnessOnly extends base_device_accessory_1.BaseDeviceAccessory {
|
|
8
|
+
device;
|
|
9
|
+
accessory;
|
|
10
|
+
config;
|
|
8
11
|
constructor(device, accessory, config) {
|
|
9
12
|
super();
|
|
10
13
|
this.device = device;
|
package/lib/camera-source.js
CHANGED
|
@@ -27,29 +27,33 @@ function getSessionConfig(srtpOptions) {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
class StreamingSessionWrapper {
|
|
30
|
+
streamingSession;
|
|
31
|
+
prepareStreamRequest;
|
|
32
|
+
ringCamera;
|
|
33
|
+
start;
|
|
34
|
+
audioSsrc = hap_1.hap.CameraController.generateSynchronisationSource();
|
|
35
|
+
videoSsrc = hap_1.hap.CameraController.generateSynchronisationSource();
|
|
36
|
+
audioSrtp = (0, camera_utils_1.generateSrtpOptions)();
|
|
37
|
+
videoSrtp = (0, camera_utils_1.generateSrtpOptions)();
|
|
38
|
+
audioSplitter = new camera_utils_1.RtpSplitter();
|
|
39
|
+
videoSplitter = new camera_utils_1.RtpSplitter();
|
|
40
|
+
repacketizeAudioSplitter = new camera_utils_1.RtpSplitter();
|
|
41
|
+
libfdkAacInstalledPromise = (0, camera_utils_1.doesFfmpegSupportCodec)('libfdk_aac', (0, ffmpeg_1.getFfmpegPath)())
|
|
42
|
+
.then((supported) => {
|
|
43
|
+
if (!supported) {
|
|
44
|
+
(0, util_1.logError)('Streaming video only - found ffmpeg, but libfdk_aac is not installed. See https://github.com/dgreif/ring/wiki/FFmpeg for details.');
|
|
45
|
+
}
|
|
46
|
+
return supported;
|
|
47
|
+
})
|
|
48
|
+
.catch(() => {
|
|
49
|
+
(0, util_1.logError)('Streaming video only - ffmpeg was not found. See https://github.com/dgreif/ring/wiki/FFmpeg for details.');
|
|
50
|
+
return false;
|
|
51
|
+
});
|
|
30
52
|
constructor(streamingSession, prepareStreamRequest, ringCamera, start) {
|
|
31
53
|
this.streamingSession = streamingSession;
|
|
32
54
|
this.prepareStreamRequest = prepareStreamRequest;
|
|
33
55
|
this.ringCamera = ringCamera;
|
|
34
56
|
this.start = start;
|
|
35
|
-
this.audioSsrc = hap_1.hap.CameraController.generateSynchronisationSource();
|
|
36
|
-
this.videoSsrc = hap_1.hap.CameraController.generateSynchronisationSource();
|
|
37
|
-
this.audioSrtp = (0, camera_utils_1.generateSrtpOptions)();
|
|
38
|
-
this.videoSrtp = (0, camera_utils_1.generateSrtpOptions)();
|
|
39
|
-
this.audioSplitter = new camera_utils_1.RtpSplitter();
|
|
40
|
-
this.videoSplitter = new camera_utils_1.RtpSplitter();
|
|
41
|
-
this.repacketizeAudioSplitter = new camera_utils_1.RtpSplitter();
|
|
42
|
-
this.libfdkAacInstalledPromise = (0, camera_utils_1.doesFfmpegSupportCodec)('libfdk_aac', (0, ffmpeg_1.getFfmpegPath)())
|
|
43
|
-
.then((supported) => {
|
|
44
|
-
if (!supported) {
|
|
45
|
-
(0, util_1.logError)('Streaming video only - found ffmpeg, but libfdk_aac is not installed. See https://github.com/dgreif/ring/wiki/FFmpeg for details.');
|
|
46
|
-
}
|
|
47
|
-
return supported;
|
|
48
|
-
})
|
|
49
|
-
.catch(() => {
|
|
50
|
-
(0, util_1.logError)('Streaming video only - ffmpeg was not found. See https://github.com/dgreif/ring/wiki/FFmpeg for details.');
|
|
51
|
-
return false;
|
|
52
|
-
});
|
|
53
57
|
const { targetAddress, video: { port: videoPort }, } = prepareStreamRequest,
|
|
54
58
|
// used to encrypt rtcp to HomeKit for keepalive
|
|
55
59
|
videoSrtcpSession = new werift_1.SrtcpSession(getSessionConfig(this.videoSrtp)), onReturnPacketReceived = new rxjs_1.Subject();
|
|
@@ -281,6 +285,11 @@ class StreamingSessionWrapper {
|
|
|
281
285
|
}
|
|
282
286
|
}
|
|
283
287
|
class CameraSource {
|
|
288
|
+
ringCamera;
|
|
289
|
+
useOpus;
|
|
290
|
+
controller;
|
|
291
|
+
sessions = {};
|
|
292
|
+
cachedSnapshot;
|
|
284
293
|
constructor(ringCamera, useOpus = false) {
|
|
285
294
|
this.ringCamera = ringCamera;
|
|
286
295
|
this.useOpus = useOpus;
|
|
@@ -332,9 +341,8 @@ class CameraSource {
|
|
|
332
341
|
},
|
|
333
342
|
},
|
|
334
343
|
});
|
|
335
|
-
this.sessions = {};
|
|
336
|
-
this.fn = 1;
|
|
337
344
|
}
|
|
345
|
+
previousLoadSnapshotPromise;
|
|
338
346
|
async loadSnapshot(imageUuid) {
|
|
339
347
|
// cache a promise of the snapshot load
|
|
340
348
|
// This prevents multiple concurrent requests for snapshot from pilling up and creating lots of logs
|
|
@@ -353,6 +361,7 @@ class CameraSource {
|
|
|
353
361
|
this.previousLoadSnapshotPromise = undefined;
|
|
354
362
|
}
|
|
355
363
|
}
|
|
364
|
+
fn = 1;
|
|
356
365
|
async loadAndCacheSnapshot(imageUuid) {
|
|
357
366
|
const start = Date.now();
|
|
358
367
|
(0, util_1.logDebug)(`Loading new snapshot into cache for ${this.ringCamera.name}${imageUuid ? ' by uuid' : ''}`);
|
package/lib/camera.js
CHANGED
|
@@ -9,6 +9,11 @@ const target_value_timer_1 = require("./target-value-timer");
|
|
|
9
9
|
const util_1 = require("ring-client-api/util");
|
|
10
10
|
const rxjs_1 = require("rxjs");
|
|
11
11
|
class Camera extends base_data_accessory_1.BaseDataAccessory {
|
|
12
|
+
device;
|
|
13
|
+
accessory;
|
|
14
|
+
config;
|
|
15
|
+
inHomeDoorbellStatus;
|
|
16
|
+
cameraSource;
|
|
12
17
|
constructor(device, accessory, config) {
|
|
13
18
|
super();
|
|
14
19
|
this.device = device;
|
package/lib/chime.js
CHANGED
|
@@ -6,6 +6,9 @@ const base_data_accessory_1 = require("./base-data-accessory");
|
|
|
6
6
|
const util_1 = require("ring-client-api/util");
|
|
7
7
|
const minutesFor24Hours = 24 * 60;
|
|
8
8
|
class Chime extends base_data_accessory_1.BaseDataAccessory {
|
|
9
|
+
device;
|
|
10
|
+
accessory;
|
|
11
|
+
config;
|
|
9
12
|
constructor(device, accessory, config) {
|
|
10
13
|
super();
|
|
11
14
|
this.device = device;
|
package/lib/co-alarm.js
CHANGED
|
@@ -4,6 +4,9 @@ exports.CoAlarm = void 0;
|
|
|
4
4
|
const base_device_accessory_1 = require("./base-device-accessory");
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
class CoAlarm extends base_device_accessory_1.BaseDeviceAccessory {
|
|
7
|
+
device;
|
|
8
|
+
accessory;
|
|
9
|
+
config;
|
|
7
10
|
constructor(device, accessory, config) {
|
|
8
11
|
super();
|
|
9
12
|
this.device = device;
|
package/lib/contact-sensor.js
CHANGED
|
@@ -4,6 +4,9 @@ exports.ContactSensor = void 0;
|
|
|
4
4
|
const base_device_accessory_1 = require("./base-device-accessory");
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
class ContactSensor extends base_device_accessory_1.BaseDeviceAccessory {
|
|
7
|
+
device;
|
|
8
|
+
accessory;
|
|
9
|
+
config;
|
|
7
10
|
constructor(device, accessory, config) {
|
|
8
11
|
super();
|
|
9
12
|
this.device = device;
|
package/lib/fan.js
CHANGED
|
@@ -5,6 +5,9 @@ const base_device_accessory_1 = require("./base-device-accessory");
|
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
const util_1 = require("ring-client-api/util");
|
|
7
7
|
class Fan extends base_device_accessory_1.BaseDeviceAccessory {
|
|
8
|
+
device;
|
|
9
|
+
accessory;
|
|
10
|
+
config;
|
|
8
11
|
constructor(device, accessory, config) {
|
|
9
12
|
super();
|
|
10
13
|
this.device = device;
|
|
@@ -6,6 +6,9 @@ const hap_1 = require("./hap");
|
|
|
6
6
|
const operators_1 = require("rxjs/operators");
|
|
7
7
|
const util_1 = require("ring-client-api/util");
|
|
8
8
|
class FloodFreezeSensor extends base_device_accessory_1.BaseDeviceAccessory {
|
|
9
|
+
device;
|
|
10
|
+
accessory;
|
|
11
|
+
config;
|
|
9
12
|
constructor(device, accessory, config) {
|
|
10
13
|
super();
|
|
11
14
|
this.device = device;
|
package/lib/freeze-sensor.js
CHANGED
|
@@ -6,6 +6,9 @@ const hap_1 = require("./hap");
|
|
|
6
6
|
const operators_1 = require("rxjs/operators");
|
|
7
7
|
const util_1 = require("ring-client-api/util");
|
|
8
8
|
class FreezeSensor extends base_device_accessory_1.BaseDeviceAccessory {
|
|
9
|
+
device;
|
|
10
|
+
accessory;
|
|
11
|
+
config;
|
|
9
12
|
constructor(device, accessory, config) {
|
|
10
13
|
super();
|
|
11
14
|
this.device = device;
|
|
@@ -7,16 +7,11 @@
|
|
|
7
7
|
Link Ring Account
|
|
8
8
|
</h4>
|
|
9
9
|
|
|
10
|
-
<script>
|
|
10
|
+
<script type="module">
|
|
11
11
|
// Show the spinner while the JS is loading
|
|
12
12
|
homebridge.showSpinner()
|
|
13
13
|
|
|
14
|
-
//
|
|
15
|
-
const script = document.createElement('script')
|
|
16
|
-
|
|
14
|
+
// import the JS module for the custom UI
|
|
17
15
|
// Use the installed version of homebridge to bust the cache for the script
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// Append the script to the head of the page to load it
|
|
21
|
-
document.head.appendChild(script)
|
|
16
|
+
import(`./homebridge-ring-ui.js?v=${homebridge.plugin.installedVersion}`)
|
|
22
17
|
</script>
|
|
@@ -5,48 +5,49 @@ const plugin_ui_utils_1 = require("@homebridge/plugin-ui-utils");
|
|
|
5
5
|
const rest_client_1 = require("ring-client-api/rest-client");
|
|
6
6
|
const config_1 = require("../config");
|
|
7
7
|
class PluginUiServer extends plugin_ui_utils_1.HomebridgePluginUiServer {
|
|
8
|
+
restClient;
|
|
8
9
|
constructor() {
|
|
9
10
|
super();
|
|
10
|
-
this.generateCode = async ({ email, password }) => {
|
|
11
|
-
console.log(`Logging in with email '${email}'`);
|
|
12
|
-
const storagePath = this.homebridgeStoragePath;
|
|
13
|
-
this.restClient = new rest_client_1.RingRestClient({
|
|
14
|
-
email,
|
|
15
|
-
password,
|
|
16
|
-
controlCenterDisplayName: config_1.controlCenterDisplayName,
|
|
17
|
-
systemId: storagePath ? (0, config_1.getSystemId)(storagePath) : undefined,
|
|
18
|
-
});
|
|
19
|
-
try {
|
|
20
|
-
const { refresh_token } = await this.restClient.getCurrentAuth();
|
|
21
|
-
// If we get here, 2fa was not required. I'm not sure this is possible anymore, but it's here just in case
|
|
22
|
-
return { refreshToken: refresh_token };
|
|
23
|
-
}
|
|
24
|
-
catch (e) {
|
|
25
|
-
if (this.restClient.promptFor2fa) {
|
|
26
|
-
console.log(this.restClient.promptFor2fa);
|
|
27
|
-
return { codePrompt: this.restClient.promptFor2fa };
|
|
28
|
-
}
|
|
29
|
-
console.error(e);
|
|
30
|
-
throw new plugin_ui_utils_1.RequestError(e.message, e);
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
this.generateToken = async ({ email, password, code }) => {
|
|
34
|
-
// use the existing restClient to avoid sending a token again
|
|
35
|
-
this.restClient = this.restClient || new rest_client_1.RingRestClient({ email, password });
|
|
36
|
-
console.log(`Getting token for ${email} with code ${code}`);
|
|
37
|
-
try {
|
|
38
|
-
const authResponse = await this.restClient.getAuth(code);
|
|
39
|
-
return { refreshToken: authResponse.refresh_token };
|
|
40
|
-
}
|
|
41
|
-
catch (e) {
|
|
42
|
-
console.error('Incorrect 2fa Code');
|
|
43
|
-
throw new plugin_ui_utils_1.RequestError('Please check the code and try again', e);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
11
|
this.onRequest('/send-code', this.generateCode);
|
|
47
12
|
this.onRequest('/token', this.generateToken);
|
|
48
13
|
this.ready();
|
|
49
14
|
}
|
|
15
|
+
generateCode = async ({ email, password }) => {
|
|
16
|
+
console.log(`Logging in with email '${email}'`);
|
|
17
|
+
const storagePath = this.homebridgeStoragePath;
|
|
18
|
+
this.restClient = new rest_client_1.RingRestClient({
|
|
19
|
+
email,
|
|
20
|
+
password,
|
|
21
|
+
controlCenterDisplayName: config_1.controlCenterDisplayName,
|
|
22
|
+
systemId: storagePath ? (0, config_1.getSystemId)(storagePath) : undefined,
|
|
23
|
+
});
|
|
24
|
+
try {
|
|
25
|
+
const { refresh_token } = await this.restClient.getCurrentAuth();
|
|
26
|
+
// If we get here, 2fa was not required. I'm not sure this is possible anymore, but it's here just in case
|
|
27
|
+
return { refreshToken: refresh_token };
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
if (this.restClient.promptFor2fa) {
|
|
31
|
+
console.log(this.restClient.promptFor2fa);
|
|
32
|
+
return { codePrompt: this.restClient.promptFor2fa };
|
|
33
|
+
}
|
|
34
|
+
console.error(e);
|
|
35
|
+
throw new plugin_ui_utils_1.RequestError(e.message, e);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
generateToken = async ({ email, password, code }) => {
|
|
39
|
+
// use the existing restClient to avoid sending a token again
|
|
40
|
+
this.restClient = this.restClient || new rest_client_1.RingRestClient({ email, password });
|
|
41
|
+
console.log(`Getting token for ${email} with code ${code}`);
|
|
42
|
+
try {
|
|
43
|
+
const authResponse = await this.restClient.getAuth(code);
|
|
44
|
+
return { refreshToken: authResponse.refresh_token };
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
console.error('Incorrect 2fa Code');
|
|
48
|
+
throw new plugin_ui_utils_1.RequestError('Please check the code and try again', e);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
50
51
|
}
|
|
51
52
|
function startPluginUiServer() {
|
|
52
53
|
return new PluginUiServer();
|
package/lib/intercom.js
CHANGED
|
@@ -6,12 +6,16 @@ const base_data_accessory_1 = require("./base-data-accessory");
|
|
|
6
6
|
const util_1 = require("ring-client-api/util");
|
|
7
7
|
const operators_1 = require("rxjs/operators");
|
|
8
8
|
class Intercom extends base_data_accessory_1.BaseDataAccessory {
|
|
9
|
+
device;
|
|
10
|
+
accessory;
|
|
11
|
+
config;
|
|
12
|
+
unlocking = false;
|
|
13
|
+
unlockTimeout;
|
|
9
14
|
constructor(device, accessory, config) {
|
|
10
15
|
super();
|
|
11
16
|
this.device = device;
|
|
12
17
|
this.accessory = accessory;
|
|
13
18
|
this.config = config;
|
|
14
|
-
this.unlocking = false;
|
|
15
19
|
const { Characteristic, Service } = hap_1.hap, lockService = this.getService(Service.LockMechanism), { LockCurrentState, LockTargetState, ProgrammableSwitchEvent } = Characteristic, programableSwitchService = this.getService(Service.StatelessProgrammableSwitch), onDoorbellPressed = device.onDing.pipe((0, operators_1.throttleTime)(15000), (0, operators_1.map)(() => ProgrammableSwitchEvent.SINGLE_PRESS)), syncLockState = () => {
|
|
16
20
|
const state = this.getLockState();
|
|
17
21
|
lockService
|
|
@@ -20,12 +20,17 @@ function getStateFromMode(mode) {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
class LocationModeSwitch extends base_accessory_1.BaseAccessory {
|
|
23
|
+
location;
|
|
24
|
+
accessory;
|
|
25
|
+
config;
|
|
26
|
+
targetState;
|
|
27
|
+
device;
|
|
23
28
|
constructor(location, accessory, config) {
|
|
24
29
|
super();
|
|
25
30
|
this.location = location;
|
|
26
31
|
this.accessory = accessory;
|
|
27
32
|
this.config = config;
|
|
28
|
-
this.device =
|
|
33
|
+
this.device = location; // for use in BaseAccessory
|
|
29
34
|
const { Characteristic, Service: { SecuritySystem, AccessoryInformation }, } = hap_1.hap, accessoryName = location.name + ' Mode', service = this.getService(SecuritySystem, accessoryName), currentState = service.getCharacteristic(Characteristic.SecuritySystemCurrentState), targetState = service.getCharacteristic(Characteristic.SecuritySystemTargetState), getCurrentMode = () => {
|
|
30
35
|
return (0, rxjs_1.firstValueFrom)(location.onLocationMode);
|
|
31
36
|
}, getCurrentState = async () => getStateFromMode(await getCurrentMode());
|
package/lib/lock.js
CHANGED
package/lib/motion-sensor.js
CHANGED
|
@@ -4,6 +4,9 @@ exports.MotionSensor = void 0;
|
|
|
4
4
|
const base_device_accessory_1 = require("./base-device-accessory");
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
class MotionSensor extends base_device_accessory_1.BaseDeviceAccessory {
|
|
7
|
+
device;
|
|
8
|
+
accessory;
|
|
9
|
+
config;
|
|
7
10
|
constructor(device, accessory, config) {
|
|
8
11
|
super();
|
|
9
12
|
this.device = device;
|
|
@@ -5,6 +5,9 @@ const base_device_accessory_1 = require("./base-device-accessory");
|
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
const util_1 = require("ring-client-api/util");
|
|
7
7
|
class MultiLevelSwitch extends base_device_accessory_1.BaseDeviceAccessory {
|
|
8
|
+
device;
|
|
9
|
+
accessory;
|
|
10
|
+
config;
|
|
8
11
|
constructor(device, accessory, config) {
|
|
9
12
|
super();
|
|
10
13
|
this.device = device;
|
package/lib/opus-repacketizer.js
CHANGED
|
@@ -56,9 +56,10 @@ exports.OpusRepacketizer = void 0;
|
|
|
56
56
|
// signaled length of the padding MUST be no larger than N, the total
|
|
57
57
|
// size of the packet.
|
|
58
58
|
class OpusRepacketizer {
|
|
59
|
+
framesPerPacket;
|
|
60
|
+
depacketized = [];
|
|
59
61
|
constructor(framesPerPacket) {
|
|
60
62
|
this.framesPerPacket = framesPerPacket;
|
|
61
|
-
this.depacketized = [];
|
|
62
63
|
}
|
|
63
64
|
// repacketize a packet with a single frame into a packet with multiple frames.
|
|
64
65
|
repacketize(packet) {
|
package/lib/outlet.js
CHANGED
|
@@ -5,6 +5,9 @@ const base_device_accessory_1 = require("./base-device-accessory");
|
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
const util_1 = require("ring-client-api/util");
|
|
7
7
|
class Outlet extends base_device_accessory_1.BaseDeviceAccessory {
|
|
8
|
+
device;
|
|
9
|
+
accessory;
|
|
10
|
+
config;
|
|
8
11
|
constructor(device, accessory, config) {
|
|
9
12
|
super();
|
|
10
13
|
this.device = device;
|
package/lib/panic-buttons.js
CHANGED
|
@@ -18,6 +18,9 @@ function matchesAnyAlarmState({ alarmInfo }, targetStates) {
|
|
|
18
18
|
}
|
|
19
19
|
const burglarAlarmName = 'Burglar Alarm', fireAlarmName = 'Fire Alarm';
|
|
20
20
|
class PanicButtons extends base_data_accessory_1.BaseDataAccessory {
|
|
21
|
+
device;
|
|
22
|
+
accessory;
|
|
23
|
+
config;
|
|
21
24
|
constructor(device, accessory, config) {
|
|
22
25
|
super();
|
|
23
26
|
this.device = device;
|
package/lib/ring-platform.js
CHANGED
|
@@ -30,6 +30,7 @@ const thermostat_1 = require("./thermostat");
|
|
|
30
30
|
const unknown_zwave_switch_1 = require("./unknown-zwave-switch");
|
|
31
31
|
const util_2 = require("./util");
|
|
32
32
|
const intercom_1 = require("./intercom");
|
|
33
|
+
const valve_1 = require("./valve");
|
|
33
34
|
const ignoreHiddenDeviceTypes = [
|
|
34
35
|
ring_client_api_1.RingDeviceType.RingNetAdapter,
|
|
35
36
|
ring_client_api_1.RingDeviceType.ZigbeeAdapter,
|
|
@@ -95,6 +96,8 @@ function getAccessoryClass(device) {
|
|
|
95
96
|
return water_sensor_1.WaterSensor;
|
|
96
97
|
case ring_client_api_1.RingDeviceType.Thermostat:
|
|
97
98
|
return thermostat_1.Thermostat;
|
|
99
|
+
case ring_client_api_1.RingDeviceType.WaterValve:
|
|
100
|
+
return valve_1.Valve;
|
|
98
101
|
case ring_client_api_1.RingDeviceType.UnknownZWave:
|
|
99
102
|
return unknown_zwave_switch_1.UnknownZWaveSwitchSwitch;
|
|
100
103
|
}
|
|
@@ -111,11 +114,14 @@ function getAccessoryClass(device) {
|
|
|
111
114
|
return null;
|
|
112
115
|
}
|
|
113
116
|
class RingPlatform {
|
|
117
|
+
log;
|
|
118
|
+
config;
|
|
119
|
+
api;
|
|
120
|
+
homebridgeAccessories = {};
|
|
114
121
|
constructor(log, config, api) {
|
|
115
122
|
this.log = log;
|
|
116
123
|
this.config = config;
|
|
117
124
|
this.api = api;
|
|
118
|
-
this.homebridgeAccessories = {};
|
|
119
125
|
if (!config.disableLogs) {
|
|
120
126
|
(0, util_1.useLogger)({
|
|
121
127
|
logInfo(message) {
|
package/lib/security-panel.js
CHANGED
|
@@ -9,6 +9,10 @@ function isValidNightModeBypass(mode) {
|
|
|
9
9
|
return mode && (mode === 'all' || mode === 'some');
|
|
10
10
|
}
|
|
11
11
|
class SecurityPanel extends base_device_accessory_1.BaseDeviceAccessory {
|
|
12
|
+
device;
|
|
13
|
+
accessory;
|
|
14
|
+
config;
|
|
15
|
+
alarmStates;
|
|
12
16
|
constructor(device, accessory, config) {
|
|
13
17
|
super();
|
|
14
18
|
this.device = device;
|
package/lib/smoke-alarm.js
CHANGED
|
@@ -4,6 +4,9 @@ exports.SmokeAlarm = void 0;
|
|
|
4
4
|
const base_device_accessory_1 = require("./base-device-accessory");
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
class SmokeAlarm extends base_device_accessory_1.BaseDeviceAccessory {
|
|
7
|
+
device;
|
|
8
|
+
accessory;
|
|
9
|
+
config;
|
|
7
10
|
constructor(device, accessory, config) {
|
|
8
11
|
super();
|
|
9
12
|
this.device = device;
|
package/lib/smoke-co-listener.js
CHANGED
|
@@ -4,6 +4,9 @@ exports.SmokeCoListener = void 0;
|
|
|
4
4
|
const base_device_accessory_1 = require("./base-device-accessory");
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
class SmokeCoListener extends base_device_accessory_1.BaseDeviceAccessory {
|
|
7
|
+
device;
|
|
8
|
+
accessory;
|
|
9
|
+
config;
|
|
7
10
|
constructor(device, accessory, config) {
|
|
8
11
|
super();
|
|
9
12
|
this.device = device;
|
package/lib/switch.js
CHANGED
|
@@ -5,6 +5,9 @@ const base_device_accessory_1 = require("./base-device-accessory");
|
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
const util_1 = require("ring-client-api/util");
|
|
7
7
|
class Switch extends base_device_accessory_1.BaseDeviceAccessory {
|
|
8
|
+
device;
|
|
9
|
+
accessory;
|
|
10
|
+
config;
|
|
8
11
|
constructor(device, accessory, config) {
|
|
9
12
|
super();
|
|
10
13
|
this.device = device;
|
|
@@ -5,6 +5,9 @@ const base_device_accessory_1 = require("./base-device-accessory");
|
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
const operators_1 = require("rxjs/operators");
|
|
7
7
|
class TemperatureSensor extends base_device_accessory_1.BaseDeviceAccessory {
|
|
8
|
+
device;
|
|
9
|
+
accessory;
|
|
10
|
+
config;
|
|
8
11
|
constructor(device, accessory, config) {
|
|
9
12
|
super();
|
|
10
13
|
this.device = device;
|
package/lib/thermostat.js
CHANGED
|
@@ -8,6 +8,10 @@ const util_1 = require("ring-client-api/util");
|
|
|
8
8
|
const base_device_accessory_1 = require("./base-device-accessory");
|
|
9
9
|
const hap_1 = require("./hap");
|
|
10
10
|
class Thermostat extends base_device_accessory_1.BaseDeviceAccessory {
|
|
11
|
+
device;
|
|
12
|
+
accessory;
|
|
13
|
+
config;
|
|
14
|
+
onTemperature;
|
|
11
15
|
constructor(device, accessory, config) {
|
|
12
16
|
super();
|
|
13
17
|
this.device = device;
|
|
@@ -5,6 +5,9 @@ const base_device_accessory_1 = require("./base-device-accessory");
|
|
|
5
5
|
const hap_1 = require("./hap");
|
|
6
6
|
const util_1 = require("ring-client-api/util");
|
|
7
7
|
class UnknownZWaveSwitchSwitch extends base_device_accessory_1.BaseDeviceAccessory {
|
|
8
|
+
device;
|
|
9
|
+
accessory;
|
|
10
|
+
config;
|
|
8
11
|
constructor(device, accessory, config) {
|
|
9
12
|
super();
|
|
10
13
|
this.device = device;
|
package/lib/valve.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Valve = void 0;
|
|
4
|
+
const base_device_accessory_1 = require("./base-device-accessory");
|
|
5
|
+
const hap_1 = require("./hap");
|
|
6
|
+
const util_1 = require("ring-client-api/util");
|
|
7
|
+
class Valve extends base_device_accessory_1.BaseDeviceAccessory {
|
|
8
|
+
device;
|
|
9
|
+
accessory;
|
|
10
|
+
config;
|
|
11
|
+
constructor(device, accessory, config) {
|
|
12
|
+
super();
|
|
13
|
+
this.device = device;
|
|
14
|
+
this.accessory = accessory;
|
|
15
|
+
this.config = config;
|
|
16
|
+
const { Characteristic, Service } = hap_1.hap;
|
|
17
|
+
this.registerCharacteristic({
|
|
18
|
+
characteristicType: Characteristic.On,
|
|
19
|
+
serviceType: Service.Switch,
|
|
20
|
+
getValue: (data) => this.isOpen(data.valveState),
|
|
21
|
+
setValue: (value) => this.setOnState(value),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
isOpen(status) {
|
|
25
|
+
if (status === 'open') {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
setOnState(on) {
|
|
31
|
+
(0, util_1.logInfo)(`Turning ${this.device.name} ${on ? 'On' : 'Off'}`);
|
|
32
|
+
if (on) {
|
|
33
|
+
return this.device.sendCommand('valve.open');
|
|
34
|
+
}
|
|
35
|
+
return this.device.sendCommand('valve.close');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.Valve = Valve;
|
package/lib/water-sensor.js
CHANGED
|
@@ -6,6 +6,9 @@ const hap_1 = require("./hap");
|
|
|
6
6
|
const operators_1 = require("rxjs/operators");
|
|
7
7
|
const util_1 = require("ring-client-api/util");
|
|
8
8
|
class WaterSensor extends base_device_accessory_1.BaseDeviceAccessory {
|
|
9
|
+
device;
|
|
10
|
+
accessory;
|
|
11
|
+
config;
|
|
9
12
|
constructor(device, accessory, config) {
|
|
10
13
|
super();
|
|
11
14
|
this.device = device;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-ring",
|
|
3
3
|
"displayName": "Ring",
|
|
4
|
-
"version": "13.0.
|
|
4
|
+
"version": "13.2.0-beta.0",
|
|
5
5
|
"description": "Homebridge plugin for Ring doorbells, cameras, security alarm system and smart lighting",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"scripts": {
|
|
@@ -9,24 +9,23 @@
|
|
|
9
9
|
"lint": "eslint . --ext .ts && tsc --noEmit",
|
|
10
10
|
"dev": "concurrently -c yellow,blue --kill-others \"npm:dev:build\" \"npm:dev:run\" ",
|
|
11
11
|
"dev:build": "tsc --watch --preserveWatchOutput",
|
|
12
|
-
"dev:run": "
|
|
12
|
+
"dev:run": "RING_DEBUG=true node --watch ../../node_modules/.bin/homebridge -U ../../.homebridge"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@homebridge/camera-utils": "^2.2.6",
|
|
16
16
|
"@homebridge/plugin-ui-utils": "^1.0.3",
|
|
17
|
-
"ring-client-api": "13.0.
|
|
17
|
+
"ring-client-api": "13.2.0-beta.0",
|
|
18
18
|
"werift": "0.19.4"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"concurrently": "^
|
|
21
|
+
"concurrently": "^9.0.1",
|
|
22
22
|
"eslint-config-shared": "*",
|
|
23
23
|
"homebridge": "1.8.4",
|
|
24
|
-
"nodemon": "^3.1.4",
|
|
25
24
|
"tsconfig": "*",
|
|
26
|
-
"typescript": "5.
|
|
25
|
+
"typescript": "5.6.3"
|
|
27
26
|
},
|
|
28
27
|
"engines": {
|
|
29
|
-
"node": "^18 || ^20",
|
|
28
|
+
"node": "^18 || ^20 || ^22",
|
|
30
29
|
"homebridge": ">=1.4.0"
|
|
31
30
|
},
|
|
32
31
|
"repository": {
|