diff --git a/src/protect-camera.ts b/src/protect-camera.ts index 81aecb6..3282ad1 100644 --- a/src/protect-camera.ts +++ b/src/protect-camera.ts @@ -279,14 +279,15 @@ export class ProtectCamera extends ProtectDevice { // Add individual contact sensors for each object detection type, if needed. for(const smartDetectType of this.ufp.featureFlags.smartDetectTypes) { + const contactName = this.accessory.displayName + " " + smartDetectType.charAt(0).toUpperCase() + smartDetectType.slice(1); + // See if we already have this contact sensor configured. let contactService = this.accessory.getServiceById(this.hap.Service.ContactSensor, ProtectReservedNames.CONTACT_MOTION_SMARTDETECT + "." + smartDetectType); // If not, let's add it. if(!contactService) { - contactService = new this.hap.Service.ContactSensor(this.accessory.displayName + " " + smartDetectType.charAt(0).toUpperCase() + smartDetectType.slice(1), - ProtectReservedNames.CONTACT_MOTION_SMARTDETECT + "." + smartDetectType); + contactService = new this.hap.Service.ContactSensor(contactName, ProtectReservedNames.CONTACT_MOTION_SMARTDETECT + "." + smartDetectType); // Something went wrong, we're done here. if(!contactService) { @@ -299,6 +300,8 @@ export class ProtectCamera extends ProtectDevice { } // Initialize the sensor. + contactService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName); + contactService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, contactName); contactService.updateCharacteristic(this.hap.Characteristic.ContactSensorState, false); } @@ -351,9 +354,11 @@ export class ProtectCamera extends ProtectDevice { } } + const triggerName = this.accessory.displayName + " Doorbell Trigger"; + // Add the switch to the camera, if needed. if(!triggerService) { - triggerService = new this.hap.Service.Switch(this.accessory.displayName + " Doorbell Trigger", ProtectReservedNames.SWITCH_DOORBELL_TRIGGER); + triggerService = new this.hap.Service.Switch(triggerName, ProtectReservedNames.SWITCH_DOORBELL_TRIGGER); if(!triggerService) { this.log.error("Unable to add the doorbell trigger."); @@ -391,6 +396,8 @@ export class ProtectCamera extends ProtectDevice { }); // Initialize the switch. + triggerService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName); + triggerService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, triggerName); triggerService.updateCharacteristic(this.hap.Characteristic.On, false); this.log.info("Enabling doorbell automation trigger."); @@ -735,10 +742,12 @@ export class ProtectCamera extends ProtectDevice { return false; } + const switchName = this.accessory.displayName + " HKSV Recording"; + // Add the switch to the camera, if needed. if(!switchService) { - switchService = new this.hap.Service.Switch(this.accessory.displayName + " HKSV Recording", ProtectReservedNames.SWITCH_HKSV_RECORDING); + switchService = new this.hap.Service.Switch(switchName, ProtectReservedNames.SWITCH_HKSV_RECORDING); if(!switchService) { @@ -767,6 +776,8 @@ export class ProtectCamera extends ProtectDevice { }); // Initialize the switch. + switchService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName); + switchService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, switchName); switchService.updateCharacteristic(this.hap.Characteristic.On, this.accessory.context.hksvRecording as boolean); this.log.info("Enabling HomeKit Secure Video recording switch."); @@ -794,10 +805,12 @@ export class ProtectCamera extends ProtectDevice { return false; } + const switchName = this.accessory.displayName + " Dynamic Bitrate"; + // Add the switch to the camera, if needed. if(!switchService) { - switchService = new this.hap.Service.Switch(this.accessory.displayName + " Dynamic Bitrate", ProtectReservedNames.SWITCH_DYNAMIC_BITRATE); + switchService = new this.hap.Service.Switch(switchName, ProtectReservedNames.SWITCH_DYNAMIC_BITRATE); if(!switchService) { @@ -856,6 +869,8 @@ export class ProtectCamera extends ProtectDevice { }); // Initialize the switch. + switchService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName); + switchService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, switchName); switchService.updateCharacteristic(this.hap.Characteristic.On, this.accessory.context.dynamicBitrate as boolean); this.log.info("Enabling the dynamic streaming bitrate adjustment switch."); @@ -888,12 +903,12 @@ export class ProtectCamera extends ProtectDevice { continue; } + const switchName = this.accessory.displayName + " UFP Recording " + ufpRecordingSetting.charAt(0).toUpperCase() + ufpRecordingSetting.slice(1); + // Add the switch to the camera, if needed. if(!switchService) { - switchService = new this.hap.Service.Switch( - this.accessory.displayName + " UFP Recording " + ufpRecordingSetting.charAt(0).toUpperCase() + ufpRecordingSetting.slice(1), - ufpRecordingSwitchType); + switchService = new this.hap.Service.Switch(switchName, ufpRecordingSwitchType); if(!switchService) { @@ -960,6 +975,8 @@ export class ProtectCamera extends ProtectDevice { }); // Initialize the recording switch state. + switchService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName); + switchService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, switchName); switchService.updateCharacteristic(this.hap.Characteristic.On, this.ufp.recordingSettings.mode === ufpRecordingSetting); switchesEnabled.push(ufpRecordingSetting); } diff --git a/src/protect-device.ts b/src/protect-device.ts index 89f18df..96657e2 100644 --- a/src/protect-device.ts +++ b/src/protect-device.ts @@ -253,10 +253,12 @@ export abstract class ProtectDevice extends ProtectBase { this.log.info("Enabling motion sensor switch."); + const switchName = this.accessory.displayName + " Motion Events"; + // Add the switch to the camera, if needed. if(!switchService) { - switchService = new this.hap.Service.Switch(this.accessory.displayName + " Motion Events", ProtectReservedNames.SWITCH_MOTION_SENSOR); + switchService = new this.hap.Service.Switch(switchName, ProtectReservedNames.SWITCH_MOTION_SENSOR); if(!switchService) { @@ -289,6 +291,8 @@ export abstract class ProtectDevice extends ProtectBase { this.accessory.context.detectMotion = true; } + switchService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName); + switchService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, switchName); switchService.updateCharacteristic(this.hap.Characteristic.On, this.accessory.context.detectMotion as boolean); return true; @@ -310,10 +314,12 @@ export abstract class ProtectDevice extends ProtectBase { return false; } + const triggerName = this.accessory.displayName + " Motion Trigger"; + // Add the switch to the camera, if needed. if(!triggerService) { - triggerService = new this.hap.Service.Switch(this.accessory.displayName + " Motion Trigger", ProtectReservedNames.SWITCH_MOTION_TRIGGER); + triggerService = new this.hap.Service.Switch(triggerName, ProtectReservedNames.SWITCH_MOTION_TRIGGER); if(!triggerService) { this.log.error("Unable to add motion sensor trigger."); @@ -365,6 +371,8 @@ export abstract class ProtectDevice extends ProtectBase { }); // Initialize the switch. + triggerService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName); + triggerService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, triggerName); triggerService.updateCharacteristic(this.hap.Characteristic.On, false); this.log.info("Enabling motion sensor automation trigger."); @@ -393,7 +401,8 @@ export abstract class ProtectDevice extends ProtectBase { return true; } - public isOptionEnabled(option: string, defaultReturnValue = true, address = "", addressOnly = false): boolean { + // Utility for checking feature options on a device. + public hasFeature(option: string, defaultReturnValue = true, address = "", addressOnly = false): boolean { return optionEnabled(this.platform.configOptions, this.nvr.ufp, this.ufp, option, defaultReturnValue, address, addressOnly); } diff --git a/src/protect-doorbell.ts b/src/protect-doorbell.ts index 2ab5c7c..08b2523 100644 --- a/src/protect-doorbell.ts +++ b/src/protect-doorbell.ts @@ -97,7 +97,7 @@ export class ProtectDoorbell extends ProtectCamera { continue; } - this.log.info("Discovered doorbell message switch%s: %s.", entry.duration ? " (" + (entry.duration / 1000).toString() + " seconds)" : "", entry.text); + this.log.info("Enabled doorbell message switch%s: %s.", entry.duration ? " (" + (entry.duration / 1000).toString() + " seconds)" : "", entry.text); // Use the message switch, if it already exists. let switchService = this.accessory.getServiceById(this.hap.Service.Switch, entry.type + "." + entry.text); @@ -123,6 +123,8 @@ export class ProtectDoorbell extends ProtectCamera { this.messageSwitches.push({ duration: duration, service: switchService, state: false, text: entry.text, type: entry.type }) - 1; // Configure the message switch. + switchService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName); + switchService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, entry.text); switchService .getCharacteristic(this.hap.Characteristic.On) ?.onGet(this.getSwitchState.bind(this, this.messageSwitches[this.messageSwitches.length - 1])) diff --git a/src/protect-liveviews.ts b/src/protect-liveviews.ts index a092035..a949fbe 100644 --- a/src/protect-liveviews.ts +++ b/src/protect-liveviews.ts @@ -65,6 +65,7 @@ export class ProtectLiveviews extends ProtectBase { if(!this.liveviews?.some(x => regexSecuritySystemLiveview.test(x.name))) { if(this.securityAccessory) { + this.log.info("No plugin-specific liveviews found. Disabling the security system accessory associated with this UniFi Protect controller."); // Unregister the accessory and delete it's remnants from HomeKit and the plugin. diff --git a/src/protect-securitysystem.ts b/src/protect-securitysystem.ts index 63f4259..4fff09c 100644 --- a/src/protect-securitysystem.ts +++ b/src/protect-securitysystem.ts @@ -233,10 +233,12 @@ export class ProtectSecuritySystem extends ProtectBase { } + const switchName = this.accessory.displayName + " Security Alarm"; + // Add the security alarm switch to the security system. if(!switchService) { - switchService = new this.hap.Service.Switch(this.accessory.displayName + " Security Alarm"); + switchService = new this.hap.Service.Switch(switchName); if(!switchService) { @@ -263,6 +265,8 @@ export class ProtectSecuritySystem extends ProtectBase { }); // Initialize the value. + switchService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName); + switchService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, switchName); switchService.updateCharacteristic(this.hap.Characteristic.On, this.isAlarmTriggered); return true; diff --git a/src/protect-sensor.ts b/src/protect-sensor.ts index 08217a6..4afcff2 100644 --- a/src/protect-sensor.ts +++ b/src/protect-sensor.ts @@ -131,7 +131,8 @@ export class ProtectSensor extends ProtectDevice { // Add the service to the accessory, if needed. if(!contactService) { - contactService = new this.hap.Service.ContactSensor(this.accessory.displayName + " Alarm Sound", ProtectReservedNames.CONTACT_SENSOR_ALARM_SOUND); + const contactName = this.accessory.displayName + " Alarm Sound"; + contactService = new this.hap.Service.ContactSensor(contactName, ProtectReservedNames.CONTACT_SENSOR_ALARM_SOUND); if(!contactService) { @@ -139,7 +140,10 @@ export class ProtectSensor extends ProtectDevice { return false; } + contactService.addOptionalCharacteristic(this.hap.Characteristic.ConfiguredName); + contactService.updateCharacteristic(this.hap.Characteristic.ConfiguredName, contactName); this.accessory.addService(contactService); + this.log.info("Enabling alarm sound contact sensor."); }