@homebridge-plugins/homebridge-lutron-caseta-leap
Version:
Homebridge support for Lutron
107 lines • 5.59 kB
JavaScript
import { OccupancySensorRouter } from './OccupancySensorRouter.js';
import { DeviceWireResultType } from './Platform.HAP.js';
export class OccupancySensor {
platform;
accessory;
bridge;
/**
* Returns a Matter clusters object for this occupancy sensor.
* Matches Matter spec: occupancySensing cluster per homebridge-matter wiki §7.3.
*/
static getMatterClusters() {
return {
occupancySensing: {
occupancy: { occupied: false },
// 0 = PIR sensor type per Matter §7.3
occupancySensorType: 0,
occupancySensorTypeBitmap: { pir: true, ultrasonic: false, physicalContact: false },
},
};
}
service;
state;
fullName;
constructor(platform, accessory, bridge) {
this.platform = platform;
this.accessory = accessory;
this.bridge = bridge;
this.fullName = accessory.context.device.FullyQualifiedName.join(' ');
this.state = 'Unknown';
this.accessory
.getService(this.platform.api.hap.Service.AccessoryInformation)
.setCharacteristic(this.platform.api.hap.Characteristic.Manufacturer, 'Lutron Electronics Co., Inc')
.setCharacteristic(this.platform.api.hap.Characteristic.Model, this.accessory.context.device.ModelNumber)
.setCharacteristic(this.platform.api.hap.Characteristic.Name, this.fullName)
.setCharacteristic(this.platform.api.hap.Characteristic.ConfiguredName, this.fullName)
.setCharacteristic(this.platform.api.hap.Characteristic.SerialNumber, this.accessory.context.device.SerialNumber.toString());
this.service
= this.accessory.getService(this.platform.api.hap.Service.OccupancySensor)
|| this.accessory.addService(this.platform.api.hap.Service.OccupancySensor);
this.service.setCharacteristic(this.platform.api.hap.Characteristic.Name, this.fullName);
// If the status is 'Occupied', the sensor is occupied. If 'Unoccupied'
// or 'Unknown', unoccupied.
this.service.setCharacteristic(this.platform.api.hap.Characteristic.OccupancyDetected, this.platform.api.hap.Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED);
this.service.getCharacteristic(this.platform.api.hap.Characteristic.OccupancyDetected).on("get" /* this.platform.api.hap.CharacteristicEventTypes.GET */, (cb) => {
if (this.state === 'Occupied') {
cb(null, this.platform.api.hap.Characteristic.OccupancyDetected.OCCUPANCY_DETECTED);
}
else {
cb(null, this.platform.api.hap.Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED);
}
});
// If the status is 'Unknown', the sensor is not active. If 'Occupied'
// or 'Unoccupied', active.
this.service.setCharacteristic(this.platform.api.hap.Characteristic.StatusActive, false);
this.service.getCharacteristic(this.platform.api.hap.Characteristic.StatusActive).on("get" /* this.platform.api.hap.CharacteristicEventTypes.GET */, (cb) => {
if (this.state === 'Unknown') {
cb(null, false);
}
else {
cb(null, true);
}
});
}
update(update) {
// This method contains the logic that manages mapping the three LEAP
// occupancy sensor states to the two Homekit characteristics.
//
// If the status is 'Occupied', the sensor is occupied. If 'Unoccupied'
// or 'Unknown', unoccupied.
//
// If the status is 'Unknown', the sensor is not active. If 'Occupied'
// or 'Unoccupied', active.
this.state = update;
switch (update) {
case 'Occupied':
this.service.setCharacteristic(this.platform.api.hap.Characteristic.OccupancyDetected, this.platform.api.hap.Characteristic.OccupancyDetected.OCCUPANCY_DETECTED);
this.service.setCharacteristic(this.platform.api.hap.Characteristic.StatusActive, true);
break;
case 'Unoccupied':
this.service.setCharacteristic(this.platform.api.hap.Characteristic.OccupancyDetected, this.platform.api.hap.Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED);
this.service.setCharacteristic(this.platform.api.hap.Characteristic.StatusActive, true);
break;
case 'Unknown':
default: {
this.service.setCharacteristic(this.platform.api.hap.Characteristic.OccupancyDetected, this.platform.api.hap.Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED);
this.service.setCharacteristic(this.platform.api.hap.Characteristic.StatusActive, false);
}
}
const matterApi = this.platform.api.matter;
if (matterApi && this.accessory?.UUID) {
const occupied = update === 'Occupied';
void matterApi.updateAccessoryState(this.accessory.UUID, 'occupancySensing', {
occupancy: { occupied },
});
}
}
async initialize() {
const area = (await this.bridge.getHref(this.accessory.context.device.AssociatedArea));
const router = OccupancySensorRouter.getInstance();
await router.register(this.bridge, area.Area.AssociatedOccupancyGroups[0], this.update.bind(this));
return {
kind: DeviceWireResultType.Success,
name: this.fullName,
};
}
}
//# sourceMappingURL=OccupancySensor.js.map