@dotwee/homebridge-z2m
Version:
Expose your Zigbee devices to HomeKit with ease, by integrating Zigbee2MQTT with Homebridge.
103 lines • 5.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LockCreator = void 0;
const z2mModels_1 = require("../z2mModels");
const hap_1 = require("../hap");
const helpers_1 = require("../helpers");
const monitor_1 = require("./monitor");
class LockCreator {
createServicesFromExposes(accessory, exposes) {
exposes
.filter((e) => e.type === z2mModels_1.ExposesKnownTypes.LOCK &&
(0, z2mModels_1.exposesHasFeatures)(e) &&
(0, z2mModels_1.exposesHasAllRequiredFeatures)(e, [LockHandler.PREDICATE_LOCK_STATE, LockHandler.PREDICATE_STATE]) &&
!accessory.isServiceHandlerIdKnown(LockHandler.generateIdentifier(e.endpoint)))
.forEach((e) => this.createService(e, accessory));
}
createService(expose, accessory) {
try {
const handler = new LockHandler(expose, accessory);
accessory.registerServiceHandler(handler);
}
catch (error) {
accessory.log.warn(`Failed to setup lock for accessory ${accessory.displayName} from expose "${JSON.stringify(expose)}": ${error}`);
}
}
}
exports.LockCreator = LockCreator;
class LockHandler {
constructor(expose, accessory) {
this.accessory = accessory;
this.monitors = [];
const endpoint = expose.endpoint;
this.identifier = LockHandler.generateIdentifier(endpoint);
const potentialStateExpose = expose.features.find((e) => LockHandler.PREDICATE_STATE(e));
if (potentialStateExpose === undefined) {
throw new Error(`Required "${LockHandler.NAME_STATE}" property not found for Lock.`);
}
this.stateExpose = potentialStateExpose;
const potentialLockStateExpose = expose.features.find((e) => LockHandler.PREDICATE_LOCK_STATE(e));
if (potentialLockStateExpose === undefined) {
throw new Error(`Required "${LockHandler.NAME_LOCK_STATE}" property not found for Lock.`);
}
this.lockStateExpose = potentialLockStateExpose;
const lockStateMapping = LockHandler.BASIC_MAPPING;
const missingValues = this.lockStateExpose.values.filter((v) => !lockStateMapping.has(v));
if (missingValues.length > 0) {
throw new Error(`Property "${LockHandler.NAME_LOCK_STATE}" of Lock does not support value(s): ${missingValues.join(', ')}`);
}
const serviceName = accessory.getDefaultServiceDisplayName(endpoint);
accessory.log.debug(`Configuring LockMechanism for ${serviceName}`);
const service = accessory.getOrAddService(new hap_1.hap.Service.LockMechanism(serviceName, endpoint));
(0, helpers_1.getOrAddCharacteristic)(service, hap_1.hap.Characteristic.LockTargetState).on('set', this.handleSetState.bind(this));
const stateValues = new Map();
stateValues.set(this.stateExpose.value_on, hap_1.hap.Characteristic.LockTargetState.SECURED);
stateValues.set(this.stateExpose.value_off, hap_1.hap.Characteristic.LockTargetState.UNSECURED);
this.monitors.push(new monitor_1.MappingCharacteristicMonitor(this.stateExpose.property, service, hap_1.hap.Characteristic.LockTargetState, stateValues));
(0, helpers_1.getOrAddCharacteristic)(service, hap_1.hap.Characteristic.LockCurrentState);
for (const value of this.lockStateExpose.values) {
if (!lockStateMapping.has(value)) {
lockStateMapping.set(value, hap_1.hap.Characteristic.LockCurrentState.UNKNOWN);
}
}
this.monitors.push(new monitor_1.MappingCharacteristicMonitor(this.lockStateExpose.property, service, hap_1.hap.Characteristic.LockCurrentState, lockStateMapping));
}
static get BASIC_MAPPING() {
const map = new Map();
map.set('locked', hap_1.hap.Characteristic.LockCurrentState.SECURED);
map.set('unlocked', hap_1.hap.Characteristic.LockCurrentState.UNSECURED);
map.set('not_fully_locked', hap_1.hap.Characteristic.LockCurrentState.JAMMED);
return map;
}
get getableKeys() {
const keys = [];
if ((0, z2mModels_1.exposesCanBeGet)(this.stateExpose)) {
keys.push(this.stateExpose.property);
}
if ((0, z2mModels_1.exposesCanBeGet)(this.lockStateExpose)) {
keys.push(this.lockStateExpose.property);
}
return keys;
}
updateState(state) {
this.monitors.forEach((m) => m.callback(state));
}
handleSetState(value, callback) {
const data = {};
data[this.stateExpose.property] = value ? this.stateExpose.value_on : this.stateExpose.value_off;
this.accessory.queueDataForSetAction(data);
callback(null);
}
static generateIdentifier(endpoint) {
let identifier = hap_1.hap.Service.LockMechanism.UUID;
if (endpoint !== undefined) {
identifier += '_' + endpoint.trim();
}
return identifier;
}
}
LockHandler.PREDICATE_STATE = (e) => (0, z2mModels_1.exposesHasBinaryProperty)(e) && e.name === LockHandler.NAME_STATE && (0, z2mModels_1.exposesCanBeSet)(e) && (0, z2mModels_1.exposesIsPublished)(e);
LockHandler.PREDICATE_LOCK_STATE = (e) => (0, z2mModels_1.exposesHasEnumProperty)(e) && e.name === LockHandler.NAME_LOCK_STATE && (0, z2mModels_1.exposesIsPublished)(e);
LockHandler.NAME_STATE = 'state';
LockHandler.NAME_LOCK_STATE = 'lock_state';
//# sourceMappingURL=lock.js.map