UNPKG

homebridge

Version:
113 lines 4.99 kB
/** * OnOff Cluster Behavior * * Handles on/off commands for lights, switches, and outlets */ import { OnOffServer } from '@matter/main/behaviors/on-off'; import { Status, StatusResponseError } from '@matter/main/types'; import { MatterStatus } from '../errors.js'; import { getRegistryManager } from './EndpointContext.js'; export class HomebridgeOnOffServer extends OnOffServer { /** * Get the registry for this behavior's endpoint */ getRegistry() { return getRegistryManager(this.endpoint).getRegistry(this.endpoint.id); } initialize() { super.initialize(); // Report every change to this cluster, not only the ones its own on/off // commands made. A brightness command can turn a light on or off through // the LevelControl cluster's coupling, and that change is made by // matter.js rather than by any handler here - so without this the cache // and the UI would still show the old on/off state. this.reactTo(this.events.onOff$Changed, this.syncOnOffToCache); } /** * Mirror the cluster's own state into the accessory cache, whatever changed * it. Reading the value from the event means the cache follows what matter * actually committed, rather than a value predicted before the fact. */ syncOnOffToCache(onOff) { this.getRegistry().syncStateToCache(this.endpoint.id, 'onOff', { onOff }); } /** * Handle 'on' command */ async on() { const endpointId = this.endpoint.id; const registry = this.getRegistry(); try { // Execute user handler await registry.executeHandler(endpointId, 'onOff', 'on'); // Only reached if handler succeeded - update Matter state await super.on(); // Sync state to cache registry.syncStateToCache(endpointId, 'onOff', { onOff: true }); } 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 turn on: ${message}`, Status.Failure); } } /** * Handle 'off' command */ async off() { const endpointId = this.endpoint.id; const registry = this.getRegistry(); try { // Execute user handler await registry.executeHandler(endpointId, 'onOff', 'off'); // Only reached if handler succeeded - update Matter state await super.off(); // Sync state to cache registry.syncStateToCache(endpointId, 'onOff', { onOff: false }); } 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 turn off: ${message}`, Status.Failure); } } /** * Handle 'toggle' command */ async toggle() { const endpointId = this.endpoint.id; const registry = this.getRegistry(); try { // Execute user handler await registry.executeHandler(endpointId, 'onOff', 'toggle'); // Only reached if handler succeeded - update Matter state await super.toggle(); // Sync state to cache (super.toggle() already updated this.state.onOff) registry.syncStateToCache(endpointId, 'onOff', { onOff: this.state.onOff }); } 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 toggle: ${message}`, Status.Failure); } } } //# sourceMappingURL=OnOffBehavior.js.map