homebridge-unifi-protect 6.22.0 → 7.0.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.
Files changed (82) hide show
  1. package/README.md +29 -29
  2. package/config.schema.json +5 -15
  3. package/dist/devices/protect-camera-package.d.ts +0 -2
  4. package/dist/devices/protect-camera-package.js +4 -12
  5. package/dist/devices/protect-camera-package.js.map +1 -1
  6. package/dist/devices/protect-camera.d.ts +0 -3
  7. package/dist/devices/protect-camera.js +21 -119
  8. package/dist/devices/protect-camera.js.map +1 -1
  9. package/dist/devices/protect-chime.js +2 -6
  10. package/dist/devices/protect-chime.js.map +1 -1
  11. package/dist/devices/protect-device.d.ts +9 -5
  12. package/dist/devices/protect-device.js +17 -20
  13. package/dist/devices/protect-device.js.map +1 -1
  14. package/dist/devices/protect-doorbell.d.ts +0 -2
  15. package/dist/devices/protect-doorbell.js +39 -58
  16. package/dist/devices/protect-doorbell.js.map +1 -1
  17. package/dist/devices/protect-light.js +1 -3
  18. package/dist/devices/protect-light.js.map +1 -1
  19. package/dist/devices/protect-liveviews.js +2 -1
  20. package/dist/devices/protect-liveviews.js.map +1 -1
  21. package/dist/devices/protect-nvr-systeminfo.js +1 -1
  22. package/dist/devices/protect-nvr-systeminfo.js.map +1 -1
  23. package/dist/devices/protect-securitysystem.js +4 -4
  24. package/dist/devices/protect-securitysystem.js.map +1 -1
  25. package/dist/devices/protect-sensor.js +2 -6
  26. package/dist/devices/protect-sensor.js.map +1 -1
  27. package/dist/ffmpeg/protect-ffmpeg-codecs.js.map +1 -1
  28. package/dist/ffmpeg/protect-ffmpeg-exec.js.map +1 -1
  29. package/dist/ffmpeg/protect-ffmpeg-options.js +2 -20
  30. package/dist/ffmpeg/protect-ffmpeg-options.js.map +1 -1
  31. package/dist/ffmpeg/protect-ffmpeg-record.js +2 -1
  32. package/dist/ffmpeg/protect-ffmpeg-record.js.map +1 -1
  33. package/dist/ffmpeg/protect-ffmpeg-stream.js +14 -8
  34. package/dist/ffmpeg/protect-ffmpeg-stream.js.map +1 -1
  35. package/dist/ffmpeg/protect-ffmpeg.d.ts +2 -2
  36. package/dist/ffmpeg/protect-ffmpeg.js.map +1 -1
  37. package/dist/protect-events.d.ts +1 -1
  38. package/dist/protect-events.js +36 -33
  39. package/dist/protect-events.js.map +1 -1
  40. package/dist/protect-nvr.d.ts +7 -11
  41. package/dist/protect-nvr.js +14 -60
  42. package/dist/protect-nvr.js.map +1 -1
  43. package/dist/protect-options.d.ts +8 -23
  44. package/dist/protect-options.js +4 -128
  45. package/dist/protect-options.js.map +1 -1
  46. package/dist/protect-platform.d.ts +2 -4
  47. package/dist/protect-platform.js +3 -28
  48. package/dist/protect-platform.js.map +1 -1
  49. package/dist/protect-record.d.ts +2 -1
  50. package/dist/protect-record.js +21 -27
  51. package/dist/protect-record.js.map +1 -1
  52. package/dist/protect-snapshot.d.ts +2 -2
  53. package/dist/protect-snapshot.js +7 -3
  54. package/dist/protect-snapshot.js.map +1 -1
  55. package/dist/protect-stream.d.ts +3 -3
  56. package/dist/protect-stream.js +87 -90
  57. package/dist/protect-stream.js.map +1 -1
  58. package/dist/protect-timeshift.d.ts +9 -3
  59. package/dist/protect-timeshift.js +76 -24
  60. package/dist/protect-timeshift.js.map +1 -1
  61. package/dist/protect-types.d.ts +0 -7
  62. package/dist/protect-types.js +0 -1
  63. package/dist/protect-types.js.map +1 -1
  64. package/dist/settings.d.ts +2 -1
  65. package/dist/settings.js +4 -2
  66. package/dist/settings.js.map +1 -1
  67. package/homebridge-ui/public/index.html +42 -21
  68. package/homebridge-ui/public/lib/featureoptions.js +376 -0
  69. package/homebridge-ui/public/lib/featureoptions.js.map +1 -0
  70. package/homebridge-ui/public/lib/webUi-featureoptions.mjs +836 -0
  71. package/homebridge-ui/public/lib/webUi.mjs +184 -0
  72. package/homebridge-ui/public/ui.mjs +208 -124
  73. package/homebridge-ui/server.js +13 -39
  74. package/package.json +22 -21
  75. package/dist/protect-mqtt.d.ts +0 -20
  76. package/dist/protect-mqtt.js +0 -177
  77. package/dist/protect-mqtt.js.map +0 -1
  78. package/dist/protect-rtp.d.ts +0 -26
  79. package/dist/protect-rtp.js +0 -180
  80. package/dist/protect-rtp.js.map +0 -1
  81. package/homebridge-ui/public/lib/featureoptions.mjs +0 -201
  82. package/homebridge-ui/public/protect-featureoptions.mjs +0 -736
package/README.md CHANGED
@@ -75,35 +75,35 @@ I hope to continue to work on this one to get AEC working for two-way audio. [Yo
75
75
  * [Plugin Configuration Reference](https://github.com/hjdhjd/homebridge-unifi-protect/blob/main/docs/ConfigurationReference.md): complete list of configuration options available in this plugin.
76
76
 
77
77
  ## Installation
78
- ### Prerequisites:
79
78
 
80
- * Ensure you are using a machine that can handle the CPU and GPU requirements of `homebridge-unifi-protect`. The more cameras you have, the higher the performance requirements. If you intend to use HomeKit Secure Video, in particular, you will need a capable, modern CPU. Raspberry Pi 4 is a great piece of hardware, but it cannot keep up with the demands of more than a few Protect cameras, and definitely not the higher end members of the Protect camera ecosystem.
81
- * If you are new to Homebridge, please first read the [Homebridge](https://homebridge.io) [documentation](https://github.com/homebridge/homebridge/wiki) and installation instructions before proceeding. Ensure you've installed Homebridge and the [Homebridge Config UI](https://github.com/homebridge/homebridge-config-ui-x) before proceeding.
82
- * Ensure you have a ***local user*** account on your UniFi console dedicated to `homebridge-unifi-protect`. To create a local user account on your UniFi console:
83
- * Go to the ***OS Settings*** tab on the Protect controller web interface. This is typicaly near the top left of the Protect controller UI page.
84
- * Click ***Add Admin*** located near the top right of the ***OS Settings*** page.
85
- * Click ***Restrict to local access only*** and then enter in a username and password for the new local user.
86
- * Optionally customize the role of the user to adjust the roles. HBUP requires the ***Full Management*** role for all of it's capabilities to work, although it will work in a more limited form without administrative privileges.
87
-
88
- ### Getting Started
89
- To install `homebridge-unifi-protect`:
90
-
91
- 1. Go to the `Plugins` tab in the Homebridge Config UI and searching for `homebridge-unifi-protect` and install it.
92
- 2. Click on the ***Set Up*** icon located in the top right corner of the Homebridge UniFi Protect tile and then enter the hostname or IP address of the Protect controller as well as the username and password you created in the steps above and then login to the Protect controller.
93
- 3. For the moment, don't make any other configuration changes and click ***Save*** and then click ***Restart Homebridge***.
94
- 4. After restarting Homebridge, click on the ***Set Up Child Bridge*** icon located in the top right corner of the Homebridge UniFi Protect tile. Toggle the child bridge setting for UniFi Protect to ***on*** and then save and restart Homebridge.
95
- 5. After restarting Homebridge, click on the ***Connect to HomeKit*** icon located in the top right corner of the Homebridge UniFi Protect tile. Use the Home app on your iPhone and scan the QR code to connect UniFi Protect to HomeKit. The Home app may ask questions about where to locate your cameras and whether you want to enable HomeKit Secure Video. Answer according to your preferences.
96
- 6. That's it! You should now be able to access all your UniFi Protect devices in HomeKit. You can further tailor your experience by going to the Homebridge UniFi Protect webUI and exploring the various features and options that are available to you.
97
-
98
- ### Technical Considerations
99
-
100
- HBUP includes everything required to get up and running on many of the [more popular platforms and operating systems](https://github.com/homebridge/ffmpeg-for-homebridge#supported-platforms). **If you're running on an unsupported platform, you will need to install a working version of *FFmpeg* for `homebridge-unifi-protect` to work correctly with your cameras. Additionally, your FFmpeg will need to support the *fdk-aac* codec if you want audio support to work. Setting up and configuring FFmpeg is beyond the scope of this documentation.**
101
-
102
- ### Things To Be Aware Of
103
- - Only official releases of UniFi Protect and UniFi OS firmwares are supported. **No beta, early access, or release candidate versions of any kind are supported**.
104
- - Only official hardware releases for UniFi Protect are supported. Early access or beta hardware is unsupported.
105
- - No support is provided for any beta versions of Apple operating systems (iOS, iPadOS, macOS, tvOS, etc.).
106
- - **My philosophy is to aggressively adopt the capability and features (that make sense in a HomeKit context) in the latest official Ubiquiti firmware releases and to deprecate old functionality that's been superceded by newer, richer, or more performant capabilities - either by HomeKit or Ubiquiti. Read the [Changelog](https://github.com/hjdhjd/homebridge-unifi-protect/blob/main/docs/Changelog.md) carefully for the latest information on what's new.**
79
+ > [!IMPORTANT]
80
+ > ### Prerequisites
81
+ > * Ensure you are using a machine that can handle the CPU and GPU requirements of `homebridge-unifi-protect`. The more cameras you have, the higher the performance requirements. If you intend to use HomeKit Secure Video, in particular, you will need a capable, modern CPU. Raspberry Pi 4 is a great piece of hardware, but it cannot keep up with the demands of more than a few Protect cameras, and definitely not the higher end members of the Protect camera ecosystem.
82
+ > * If you are new to Homebridge, please first read the [Homebridge](https://homebridge.io) [documentation](https://github.com/homebridge/homebridge/wiki) and installation instructions before proceeding. Ensure you've installed Homebridge and the [Homebridge Config UI](https://github.com/homebridge/homebridge-config-ui-x) before proceeding.
83
+ > * Ensure you have a ***local user*** account on your UniFi console dedicated to `homebridge-unifi-protect`. To create a local user account on your UniFi console:
84
+ > * Go to the ***OS Settings*** tab on the Protect controller web interface. This is typicaly near the top left of the Protect controller UI page.
85
+ > * Click ***Add Admin*** located near the top right of the ***OS Settings*** page.
86
+ > * Click ***Restrict to local access only*** and then enter in a username and password for the new local user.
87
+ > * Optionally customize the role of the user to adjust the roles. HBUP requires the ***Full Management*** role for all of it's capabilities to work, although it will work in a more limited form without administrative privileges.
88
+ >
89
+ > ### Getting Started
90
+ > To install `homebridge-unifi-protect`:
91
+ >
92
+ > 1. Go to the `Plugins` tab in the Homebridge Config UI and searching for `homebridge-unifi-protect` and install it.
93
+ > 2. Click on the ***Set Up*** icon located in the top right corner of the Homebridge UniFi Protect tile and then enter the hostname or IP address of the Protect controller as well as the username and password you created in the steps above and then login to the Protect controller.
94
+ > 3. For the moment, don't make any other configuration changes and click ***Save*** and then click ***Restart Homebridge***.
95
+ > 4. After restarting Homebridge, click on the ***Set Up Child Bridge*** icon located in the top right corner of the Homebridge UniFi Protect tile. Toggle the child bridge setting for UniFi Protect to ***on*** and then save and restart Homebridge.
96
+ > 5. After restarting Homebridge, click on the ***Connect to HomeKit*** icon located in the top right corner of the Homebridge UniFi Protect tile. Use the Home app on your iPhone and scan the QR code to connect UniFi Protect to HomeKit. The Home app may ask questions about where to locate your cameras and whether you want to enable HomeKit Secure Video. Answer according to your preferences.
97
+ > 6. That's it! You should now be able to access all your UniFi Protect devices in HomeKit. You can further tailor your experience by going to the Homebridge UniFi Protect webUI and exploring the various features and options that are available to you.
98
+
99
+ > [!NOTE]
100
+ > HBUP includes everything required to get up and running on many of the [more popular platforms and operating systems](https://github.com/homebridge/ffmpeg-for-homebridge#supported-platforms). **If you're running on an unsupported platform, you will need to install a working version of *FFmpeg* for `homebridge-unifi-protect` to work correctly with your cameras. Additionally, your FFmpeg will need to support the *fdk-aac* codec if you want audio support to work. Setting up and configuring FFmpeg is beyond the scope of this documentation.**
101
+
102
+ > [!TIP]
103
+ > - Only official releases of UniFi Protect and UniFi OS firmwares are supported. **No beta, early access, or release candidate versions of any kind are supported**.
104
+ > - Only official hardware releases for UniFi Protect are supported. Early access or beta hardware is unsupported.
105
+ > - No support is provided for any beta versions of Apple operating systems (iOS, iPadOS, macOS, tvOS, etc.).
106
+ > - **My philosophy is to aggressively adopt the capability and features (that make sense in a HomeKit context) in the latest official Ubiquiti firmware releases and to deprecate old functionality that's been superceded by newer, richer, or more performant capabilities - either by HomeKit or Ubiquiti. Read the [Changelog](https://github.com/hjdhjd/homebridge-unifi-protect/blob/main/docs/Changelog.md) carefully for the latest information on what's new.**
107
107
 
108
108
  ## Plugin Development Dashboard
109
109
  This is mostly of interest to the true developer nerds amongst us.
@@ -111,4 +111,4 @@ This is mostly of interest to the true developer nerds amongst us.
111
111
  [![License](https://img.shields.io/npm/l/homebridge-unifi-protect?color=%230559C9&logo=open%20source%20initiative&logoColor=%23FFFFFF&style=for-the-badge)](https://github.com/hjdhjd/homebridge-unifi-protect/blob/main/LICENSE.md)
112
112
  [![Build Status](https://img.shields.io/github/actions/workflow/status/hjdhjd/homebridge-unifi-protect/ci.yml?branch=main&color=%230559C9&logo=github-actions&logoColor=%23FFFFFF&style=for-the-badge)](https://github.com/hjdhjd/homebridge-unifi-protect/actions?query=workflow%3A%22Continuous+Integration%22)
113
113
  [![Dependencies](https://img.shields.io/librariesio/release/npm/homebridge-unifi-protect?color=%230559C9&logo=dependabot&style=for-the-badge)](https://libraries.io/npm/homebridge-unifi-protect)
114
- [![GitHub commits since latest release (by SemVer)](https://img.shields.io/github/commits-since/hjdhjd/homebridge-unifi-protect/latest?color=%230559C9&logo=github&sort=semver&style=for-the-badge)](https://github.com/hjdhjd/homebridge-unifi-protect/commits/master)
114
+ [![GitHub commits since latest release (by SemVer)](https://img.shields.io/github/commits-since/hjdhjd/homebridge-unifi-protect/latest?color=%230559C9&logo=github&sort=semver&style=for-the-badge)](https://github.com/hjdhjd/homebridge-unifi-protect/commits/main)
@@ -2,7 +2,7 @@
2
2
  "pluginAlias": "UniFi Protect",
3
3
  "pluginType": "platform",
4
4
  "headerDisplay": "Full HomeKit support UniFi Protect devices. See the [homebridge-unifi-protect](https://github.com/hjdhjd/homebridge-unifi-protect) developer page for detailed documentation.",
5
- "footerDisplay": "A working **ffmpeg** installation is required for this plugin to work. For audio support, make sure your version of ffmpeg is compiled with support for **fdk-aac**.",
5
+ "footerDisplay": "A working **FFmpeg** installation is required for this plugin to work. For audio support, make sure your version of ffmpeg is compiled with support for the **fdk-aac** codec.",
6
6
  "singular": true,
7
7
  "customUi": true,
8
8
 
@@ -28,15 +28,6 @@
28
28
  "description": "Hostname or IP address of your UniFi Protect controller."
29
29
  },
30
30
 
31
- "defaultDoorbellMessage": {
32
- "type": "string",
33
- "title": "Default doorbell message",
34
- "required": false,
35
- "maxLength": 30,
36
- "placeholder": "e.g. WELCOME",
37
- "description": "Default message to be used on UniFi Protect doorbells. Default: WELCOME."
38
- },
39
-
40
31
  "doorbellMessages": {
41
32
  "type": "array",
42
33
  "title": "Doorbell Messages",
@@ -138,8 +129,8 @@
138
129
  "type": "string",
139
130
  "title": "Feature Option",
140
131
  "required": false,
141
- "description": "Enter only one option per entry. See the plugin documentation for the complete list of available options or use the feature options webUI tab above.",
142
- "placeholder": "e.g. Disable.Video.Transcode"
132
+ "description": "Enter only one option per entry. Use the feature options webUI tab above unless you know what you're doing.",
133
+ "placeholder": "e.g. Disable.Device"
143
134
  }
144
135
  },
145
136
 
@@ -210,7 +201,6 @@
210
201
  "expanded": false,
211
202
  "items": [
212
203
 
213
- "controllers[].defaultDoorbellMessage",
214
204
  {
215
205
  "key": "controllers[].doorbellMessages",
216
206
  "type": "array",
@@ -273,8 +263,8 @@
273
263
  "key": "options",
274
264
  "type": "array",
275
265
  "name": " ",
276
- "description": "Feature options allow you to further customize the behavior of this plugin such as the ability to show or hide cameras or specify stream quality. You can use the the feature options tab above (recommended) to customize these settings or enter them manually below.",
277
- "orderable": false,
266
+ "description": "Use the feature options webUI tab above instead of manually configuring feature options here.",
267
+ "orderable": true,
278
268
  "buttonText": "Add Feature Option",
279
269
  "items": [
280
270
  "options[]"
@@ -4,6 +4,4 @@ export declare class ProtectCameraPackage extends ProtectCamera {
4
4
  get id(): string;
5
5
  findRtsp(): RtspEntry | null;
6
6
  findRecordingRtsp(): RtspEntry | null;
7
- getBitrate(channelId: number): number;
8
- setBitrate(): Promise<boolean>;
9
7
  }
@@ -13,10 +13,12 @@ export class ProtectCameraPackage extends ProtectCamera {
13
13
  this.hasHksv = true;
14
14
  this.hints.probesize = 32768;
15
15
  if (parentCamera) {
16
- this.hints.timeshift = parentCamera.hints.timeshift;
16
+ this.hints.apiStreaming = parentCamera.hints.apiStreaming;
17
17
  this.hints.hardwareDecoding = parentCamera.hints.hardwareDecoding;
18
- this.hints.hardwareTranscoding = false;
18
+ this.hints.hardwareTranscoding = parentCamera.hints.hardwareTranscoding;
19
+ this.hints.highResSnapshots = parentCamera.hints.highResSnapshots;
19
20
  this.hints.logHksv = parentCamera.hints.logHksv;
21
+ this.hints.timeshift = parentCamera.hints.timeshift;
20
22
  }
21
23
  // Clean out the context object in case it's been polluted somehow.
22
24
  this.accessory.context = {};
@@ -102,15 +104,5 @@ export class ProtectCameraPackage extends ProtectCamera {
102
104
  findRecordingRtsp() {
103
105
  return this.findRtsp();
104
106
  }
105
- // Get the current bitrate for a specific camera channel.
106
- getBitrate(channelId) {
107
- // Find the right channel.
108
- const channel = this.ufp.channels.find(x => x.id === channelId);
109
- return channel?.bitrate ?? -1;
110
- }
111
- // Set the bitrate for a specific camera channel.
112
- setBitrate() {
113
- return Promise.resolve(true);
114
- }
115
107
  }
116
108
  //# sourceMappingURL=protect-camera-package.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"protect-camera-package.js","sourceRoot":"","sources":["../../src/devices/protect-camera-package.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protect-camera-package.js","sourceRoot":"","sources":["../../src/devices/protect-camera-package.ts"],"names":[],"mappings":"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"}
@@ -39,12 +39,9 @@ export declare class ProtectCamera extends ProtectDevice {
39
39
  private configureVideoStream;
40
40
  private configureHksv;
41
41
  private configureHksvRecordingSwitch;
42
- private configureDynamicBitrateSwitch;
43
42
  private configureNvrRecordingSwitch;
44
43
  protected configureMqtt(): boolean;
45
44
  updateDevice(): boolean;
46
- getBitrate(channelId: number): number;
47
- setBitrate(channelId: number, value: number): Promise<boolean>;
48
45
  private findRtspEntry;
49
46
  findRtsp(width: number, height: number, options?: RtspOptions): RtspEntry | null;
50
47
  findRecordingRtsp(width: number, height: number): RtspEntry | null;
@@ -1,5 +1,5 @@
1
1
  import { ProtectReservedNames, toCamelCase } from "../protect-types.js";
2
- import { PROTECT_HOMEKIT_IDR_INTERVAL } from "../settings.js";
2
+ import { PROTECT_HKSV_IDR_INTERVAL } from "../settings.js";
3
3
  import { ProtectDevice } from "./protect-device.js";
4
4
  import { ProtectStreamingDelegate } from "../protect-stream.js";
5
5
  export class ProtectCamera extends ProtectDevice {
@@ -28,6 +28,7 @@ export class ProtectCamera extends ProtectDevice {
28
28
  configureHints() {
29
29
  // Configure our parent's hints.
30
30
  super.configureHints();
31
+ this.hints.apiStreaming = this.hasFeature("Video.Stream.UseApi");
31
32
  this.hints.crop = this.hasFeature("Video.Crop");
32
33
  this.hints.hardwareDecoding = true;
33
34
  this.hints.hardwareTranscoding = this.hasFeature("Video.Transcode.Hardware");
@@ -59,17 +60,12 @@ export class ProtectCamera extends ProtectDevice {
59
60
  // Clean out the context object in case it's been polluted somehow.
60
61
  this.accessory.context = {};
61
62
  this.accessory.context.detectMotion = savedContext.detectMotion ?? true;
62
- this.accessory.context.dynamicBitrate = savedContext.dynamicBitrate ?? false;
63
63
  this.accessory.context.hksvRecording = savedContext.hksvRecording ?? true;
64
64
  this.accessory.context.mac = this.ufp.mac;
65
65
  this.accessory.context.nvr = this.nvr.ufp.mac;
66
66
  // Inform the user that motion detection will suck.
67
67
  if (this.ufp.recordingSettings.mode === "never") {
68
- this.log.info("WARNING: motion events will not be generated by the Protect controller when the controller's camera recording options are set to \"never\".");
69
- }
70
- // Inform the user if we have enabled the dynamic bitrate setting.
71
- if (this.hasFeature("Video.DynamicBitrate")) {
72
- this.log.info("Dynamic streaming bitrate adjustment on the UniFi Protect controller enabled.");
68
+ this.log.warn("Motion events will not be generated by the Protect controller when the controller's camera recording options are set to \"never\".");
73
69
  }
74
70
  // Check to see if we have smart motion events enabled on a supported camera.
75
71
  if (this.hints.smartDetect) {
@@ -81,6 +77,9 @@ export class ProtectCamera extends ProtectDevice {
81
77
  this.log.info("Smart motion detection enabled%s.", this.ufp.featureFlags.smartDetectTypes.length ?
82
78
  ": " + this.ufp.featureFlags.smartDetectTypes.sort().join(", ") : "");
83
79
  }
80
+ if (this.hints.apiStreaming) {
81
+ this.log.warn("API streaming enabled. This feature is experimental and provided without support. Any related support requests will be closed without comment.");
82
+ }
84
83
  // Configure accessory information.
85
84
  this.configureInfo();
86
85
  // Configure MQTT services.
@@ -100,8 +99,6 @@ export class ProtectCamera extends ProtectDevice {
100
99
  await this.configureVideoStream();
101
100
  // Configure our camera details.
102
101
  this.configureCameraDetails();
103
- // Configure our bitrate switch.
104
- this.configureDynamicBitrateSwitch();
105
102
  // Configure our NVR recording switches.
106
103
  this.configureNvrRecordingSwitch();
107
104
  // Configure the doorbell trigger.
@@ -277,9 +274,7 @@ export class ProtectCamera extends ProtectDevice {
277
274
  else {
278
275
  // If the doorbell ring event is still going, we should be as well.
279
276
  if (this.isRinging) {
280
- setTimeout(() => {
281
- triggerService?.updateCharacteristic(this.hap.Characteristic.On, true);
282
- }, 50);
277
+ setTimeout(() => triggerService?.updateCharacteristic(this.hap.Characteristic.On, true), 50);
283
278
  }
284
279
  }
285
280
  });
@@ -379,12 +374,12 @@ export class ProtectCamera extends ProtectDevice {
379
374
  // Enable RTSP on the camera if needed and get the list of RTSP streams we have ultimately configured.
380
375
  this.ufp = await this.nvr.ufpApi.enableRtsp(this.ufp) ?? this.ufp;
381
376
  // Figure out which camera channels are RTSP-enabled, and user-enabled.
382
- let cameraChannels = this.ufp.channels.filter(x => x.isRtspEnabled && this.hasFeature("Video.Stream." + x.name, true));
377
+ let cameraChannels = this.ufp.channels.filter(x => x.isRtspEnabled);
383
378
  // Make sure we've got a HomeKit compatible IDR frame interval. If not, let's take care of that.
384
- const idrChannels = cameraChannels.filter(x => x.idrInterval !== PROTECT_HOMEKIT_IDR_INTERVAL);
379
+ const idrChannels = cameraChannels.filter(x => x.idrInterval !== PROTECT_HKSV_IDR_INTERVAL);
385
380
  if (idrChannels.length) {
386
381
  // Edit the channel map and update the Protect controller.
387
- this.ufp = await this.nvr.ufpApi.updateDevice(this.ufp, { channels: idrChannels.map(x => Object.assign(x, { idrInterval: PROTECT_HOMEKIT_IDR_INTERVAL })) }) ??
382
+ this.ufp = await this.nvr.ufpApi.updateDevice(this.ufp, { channels: idrChannels.map(x => Object.assign(x, { idrInterval: PROTECT_HKSV_IDR_INTERVAL })) }) ??
388
383
  this.ufp;
389
384
  }
390
385
  // Set the camera and shapshot URLs.
@@ -393,9 +388,8 @@ export class ProtectCamera extends ProtectDevice {
393
388
  cameraChannels = cameraChannels.filter(x => x.name !== "Package Camera");
394
389
  // No RTSP streams are available that meet our criteria - we're done.
395
390
  if (!cameraChannels.length) {
396
- this.log.info("No RTSP stream profiles have been configured for this camera. " +
397
- "Enable at least one RTSP stream profile in the UniFi Protect webUI to resolve this issue or " +
398
- "assign the Administrator role to the user configured for this plugin to allow it to automatically configure itself.");
391
+ this.log.info("No RTSP streaming profiles have been configured for this camera. You can resolve this issue by either enabling at least one RTSP profile in the " +
392
+ "UniFi Protect webUI or assigning an admin role to the local Protect user account you configured for this plugin.");
399
393
  return false;
400
394
  }
401
395
  // Now that we have our RTSP streams, create a list of supported resolutions for HomeKit.
@@ -494,24 +488,24 @@ export class ProtectCamera extends ProtectDevice {
494
488
  for (const rtspProfile of ["LOW", "MEDIUM", "HIGH"]) {
495
489
  // Check to see if the user has requested a specific streaming profile for this camera.
496
490
  if (this.hasFeature("Video.Stream.Only." + rtspProfile)) {
497
- this.rtspQuality.streamingDefault = rtspProfile;
491
+ this.hints.streamingDefault = rtspProfile;
498
492
  }
499
493
  // Check to see if the user has requested a specific recording profile for this camera.
500
494
  if (this.hasFeature("Video.HKSV.Record.Only." + rtspProfile)) {
501
- this.rtspQuality.recordingDefault = rtspProfile;
495
+ this.hints.recordingDefault = rtspProfile;
502
496
  }
503
497
  }
504
498
  // Inform the user if we've set a streaming default.
505
- if (this.rtspQuality.streamingDefault) {
506
- this.log.info("Video streaming configured to use only: %s.", toCamelCase(this.rtspQuality.streamingDefault.toLowerCase()));
499
+ if (this.hints.streamingDefault) {
500
+ this.log.info("Video streaming configured to use only: %s.", toCamelCase(this.hints.streamingDefault.toLowerCase()));
507
501
  }
508
502
  // Inform the user if they've selected the legacy snapshot API.
509
503
  if (!this.hints.highResSnapshots) {
510
504
  this.log.info("Disabling the use of higher quality snapshots.");
511
505
  }
512
506
  // Inform the user if we've set a recording default.
513
- if (this.rtspQuality.recordingDefault) {
514
- this.log.info("HomeKit Secure Video event recording configured to use only: %s.", toCamelCase(this.rtspQuality.recordingDefault.toLowerCase()));
507
+ if (this.hints.recordingDefault) {
508
+ this.log.info("HomeKit Secure Video event recording configured to use only: %s.", toCamelCase(this.hints.recordingDefault.toLowerCase()));
515
509
  }
516
510
  // Configure the video stream with our resolutions.
517
511
  this.stream = new ProtectStreamingDelegate(this, this.rtspEntries.map(x => x.resolution));
@@ -566,60 +560,6 @@ export class ProtectCamera extends ProtectDevice {
566
560
  this.log.info("Enabling HKSV recording switch.");
567
561
  return true;
568
562
  }
569
- // Configure a switch to manually enable or disable dynamic bitrate capabilities for a camera.
570
- configureDynamicBitrateSwitch() {
571
- // Validate whether we should have this service enabled.
572
- if (!this.validService(this.hap.Service.Switch, () => {
573
- // If we don't want a dynamic bitrate switch, disable it and we're done.
574
- if (!this.hasFeature("Video.DynamicBitrate.Switch")) {
575
- return false;
576
- }
577
- return true;
578
- }, ProtectReservedNames.SWITCH_DYNAMIC_BITRATE)) {
579
- // We want to default this back to off by default whenever we disable the dynamic bitrate switch.
580
- this.accessory.context.dynamicBitrate = false;
581
- return false;
582
- }
583
- // Acquire the service.
584
- const service = this.acquireService(this.hap.Service.Switch, this.accessoryName + " Dynamic Bitrate", ProtectReservedNames.SWITCH_DYNAMIC_BITRATE);
585
- // Fail gracefully.
586
- if (!service) {
587
- this.log.error("Unable to add dynamic bitrate switch.");
588
- return false;
589
- }
590
- // Activate or deactivate dynamic bitrate for this device.
591
- service.getCharacteristic(this.hap.Characteristic.On)?.onGet(() => {
592
- return this.accessory.context.dynamicBitrate ?? false;
593
- });
594
- service.getCharacteristic(this.hap.Characteristic.On)?.onSet(async (value) => {
595
- if (this.accessory.context.dynamicBitrate === value) {
596
- return;
597
- }
598
- // We're enabling dynamic bitrate for this device.
599
- if (value) {
600
- this.accessory.context.dynamicBitrate = true;
601
- this.log.info("Dynamic streaming bitrate adjustment on the UniFi Protect controller enabled.");
602
- return;
603
- }
604
- // We're disabling dynamic bitrate for this device. Update the channels JSON to revert to the maximum bitrate we can.
605
- const updatedChannels = this.ufp.channels.map(channel => ({ ...channel, bitrate: channel.maxBitrate }));
606
- // Send the channels JSON to Protect.
607
- const newDevice = await this.nvr.ufpApi.updateDevice(this.ufp, { channels: updatedChannels });
608
- // We failed.
609
- if (!newDevice) {
610
- this.log.error("Unable to set the streaming bitrate to %s.", value);
611
- }
612
- else {
613
- this.ufp = newDevice;
614
- }
615
- this.accessory.context.dynamicBitrate = false;
616
- this.log.info("Dynamic streaming bitrate adjustment on the UniFi Protect controller disabled.");
617
- });
618
- // Initialize the switch.
619
- service.updateCharacteristic(this.hap.Characteristic.On, this.accessory.context.dynamicBitrate);
620
- this.log.info("Enabling the dynamic streaming bitrate adjustment switch.");
621
- return true;
622
- }
623
563
  // Configure a series of switches to manually enable or disable recording on the UniFi Protect controller for a camera.
624
564
  configureNvrRecordingSwitch() {
625
565
  const switchesEnabled = [];
@@ -652,9 +592,7 @@ export class ProtectCamera extends ProtectDevice {
652
592
  // We only want to do something if we're being activated. Turning off the switch would really be an undefined state given that there are three different
653
593
  // settings one can choose from. Instead, we do nothing and leave it to the user to choose what state they really want to set.
654
594
  if (!value) {
655
- setTimeout(() => {
656
- this.updateDevice();
657
- }, 50);
595
+ setTimeout(() => this.updateDevice(), 50);
658
596
  return;
659
597
  }
660
598
  // Set our recording mode.
@@ -738,42 +676,6 @@ export class ProtectCamera extends ProtectDevice {
738
676
  }
739
677
  return true;
740
678
  }
741
- // Get the current bitrate for a specific camera channel.
742
- getBitrate(channelId) {
743
- // Find the right channel.
744
- const channel = this.ufp.channels.find(x => x.id === channelId);
745
- return channel?.bitrate ?? -1;
746
- }
747
- // Set the bitrate for a specific camera channel.
748
- async setBitrate(channelId, value) {
749
- // If we've disabled the ability to set the bitrate dynamically, silently fail. We prioritize switches over the global setting here, in case the user enabled both,
750
- // using the principle that the most specific setting always wins. If the user has both the global setting and the switch enabled, the switch will take precedence.
751
- if ((!this.accessory.context.dynamicBitrate && !this.hasFeature("Video.DynamicBitrate")) ||
752
- (!this.accessory.context.dynamicBitrate && this.hasFeature("Video.DynamicBitrate") && this.hasFeature("Video.DynamicBitrate.Switch"))) {
753
- return true;
754
- }
755
- // Find the right channel.
756
- const channel = this.ufp.channels.find(x => x.id === channelId);
757
- // No channel, we're done.
758
- if (!channel) {
759
- return false;
760
- }
761
- // If our correct bitrate is already set, we're done.
762
- if (channel.bitrate === value) {
763
- return true;
764
- }
765
- // Make sure the requested bitrate fits within the constraints of what this channel can do.
766
- channel.bitrate = Math.min(channel.maxBitrate, Math.max(channel.minBitrate, value));
767
- // Tell Protect about it.
768
- const newDevice = await this.nvr.ufpApi.updateDevice(this.ufp, { channels: this.ufp.channels });
769
- if (!newDevice) {
770
- this.log.error("Unable to set the streaming bitrate to %s.", value);
771
- return false;
772
- }
773
- // Save our updated device context.
774
- this.ufp = newDevice;
775
- return true;
776
- }
777
679
  // Find an RTSP configuration for a given target resolution.
778
680
  findRtspEntry(width, height, options) {
779
681
  const rtspEntries = options?.rtspEntries ?? this.rtspEntries;
@@ -804,7 +706,7 @@ export class ProtectCamera extends ProtectDevice {
804
706
  // Create our options JSON if needed.
805
707
  options = options ?? {};
806
708
  // Set our default stream, if we've configured one.
807
- options.default = this.rtspQuality.streamingDefault;
709
+ options.default = this.hints.streamingDefault;
808
710
  // See if we've been given RTSP entries or whether we should default to our own.
809
711
  options.rtspEntries = options.rtspEntries ?? this.rtspEntries;
810
712
  // If we've imposed a constraint on the maximum dimensions of what we want due to a hardware limitation, filter out those entries.
@@ -816,7 +718,7 @@ export class ProtectCamera extends ProtectDevice {
816
718
  }
817
719
  // Find a recording RTSP configuration for a given target resolution.
818
720
  findRecordingRtsp(width, height) {
819
- return this.findRtspEntry(width, height, { biasHigher: true, default: this.rtspQuality.recordingDefault ?? this.stream.ffmpegOptions.recordingDefaultChannel });
721
+ return this.findRtspEntry(width, height, { biasHigher: true, default: this.hints.recordingDefault ?? this.stream.ffmpegOptions.recordingDefaultChannel });
820
722
  }
821
723
  // Utility function for sorting by resolution.
822
724
  sortByResolutions(a, b) {