homebridge
Version:
HomeKit support for the impatient
74 lines • 3.5 kB
JavaScript
/**
* DoorLock Cluster Behavior
*
* Handles door lock commands for smart locks.
* Uses the featureless DoorLockBehavior base to avoid advertising credential
* features (PIN, RFID, etc.) that cause issues with Apple Home.
*/
import { DoorLockBehavior } from '@matter/main/behaviors/door-lock';
import { DoorLock } from '@matter/main/clusters/door-lock';
import { Status, StatusResponseError } from '@matter/main/types';
import { MatterStatus } from '../errors.js';
import { getRegistryManager } from './EndpointContext.js';
/**
* Custom DoorLock Server that calls plugin handlers.
*
* Extends DoorLockBehavior (no credential features) instead of DoorLockServer
* (which includes PinCredential, RfidCredential, etc.). This prevents Apple Home
* from seeing credential capabilities that aren't fully implemented.
*/
export class HomebridgeDoorLockServer extends DoorLockBehavior {
/**
* Get the registry for this behavior's endpoint
*/
getRegistry() {
return getRegistryManager(this.endpoint).getRegistry(this.endpoint.id);
}
async lockDoor(request) {
const endpointId = this.endpoint.id;
const registry = this.getRegistry();
try {
// Execute user handler
await registry.executeHandler(endpointId, 'doorLock', 'lockDoor', request);
// Only reached if handler succeeded - update Matter state via super
await super.lockDoor(request);
// Sync lock state to cache
registry.syncStateToCache(endpointId, 'doorLock', { lockState: DoorLock.LockState.Locked });
}
catch (error) {
// If user handler already threw a StatusResponseError, propagate it as-is
// This sends a proper Matter protocol error response to the controller
if (MatterStatus.isMatterProtocolError(error)) {
throw error;
}
// For other errors, wrap in appropriate StatusResponseError
// This prevents the endpoint from crashing and keeps the device online
const message = error instanceof Error ? error.message : String(error);
throw new StatusResponseError(`Failed to lock door: ${message}`, Status.Failure);
}
}
async unlockDoor(request) {
const endpointId = this.endpoint.id;
const registry = this.getRegistry();
try {
// Execute user handler
await registry.executeHandler(endpointId, 'doorLock', 'unlockDoor', request);
// Only reached if handler succeeded - update Matter state via super
await super.unlockDoor(request);
// Sync lock state to cache
registry.syncStateToCache(endpointId, 'doorLock', { lockState: DoorLock.LockState.Unlocked });
}
catch (error) {
// If user handler already threw a StatusResponseError, propagate it as-is
// This sends a proper Matter protocol error response to the controller
if (MatterStatus.isMatterProtocolError(error)) {
throw error;
}
// For other errors, wrap in appropriate StatusResponseError
// This prevents the endpoint from crashing and keeps the device online
const message = error instanceof Error ? error.message : String(error);
throw new StatusResponseError(`Failed to unlock door: ${message}`, Status.Failure);
}
}
}
//# sourceMappingURL=DoorLockBehavior.js.map