UNPKG

homebridge

Version:
354 lines 14.8 kB
/** * Matter Types for Homebridge Plugin API * * This module provides types and interfaces for plugin developers * to create Matter-compatible accessories. */ /** * Optimized Matter.js Device and Cluster Imports * * Imports Matter.js devices and clusters from individual files instead of barrel exports, * which dramatically reduces startup time. * * Why this matters: * - Barrel import: `import * as devices from '@matter/main/devices'` loads ALL 186+ exports (~800ms) * - Individual imports: Only loads the 23 devices we actually use (~50-100ms) * - Result: 50-100x faster on powerful machines, even more improvement on Raspberry Pi * * This optimization is especially important for users on resource-constrained devices like * Raspberry Pi where the difference can be several minutes of startup time. */ // Direct imports from individual cluster files import { AirQuality } from '@matter/main/clusters/air-quality'; import { BooleanState } from '@matter/main/clusters/boolean-state'; import { CarbonMonoxideConcentrationMeasurement } from '@matter/main/clusters/carbon-monoxide-concentration-measurement'; import { ColorControl } from '@matter/main/clusters/color-control'; import { DoorLock } from '@matter/main/clusters/door-lock'; import { FanControl } from '@matter/main/clusters/fan-control'; import { LevelControl } from '@matter/main/clusters/level-control'; import { NitrogenDioxideConcentrationMeasurement } from '@matter/main/clusters/nitrogen-dioxide-concentration-measurement'; import { OnOff } from '@matter/main/clusters/on-off'; import { OzoneConcentrationMeasurement } from '@matter/main/clusters/ozone-concentration-measurement'; import { Pm10ConcentrationMeasurement } from '@matter/main/clusters/pm10-concentration-measurement'; import { Pm25ConcentrationMeasurement } from '@matter/main/clusters/pm25-concentration-measurement'; import { RvcOperationalState } from '@matter/main/clusters/rvc-operational-state'; import { Thermostat } from '@matter/main/clusters/thermostat'; import { ValveConfigurationAndControl } from '@matter/main/clusters/valve-configuration-and-control'; import { WindowCovering } from '@matter/main/clusters/window-covering'; // Direct imports from individual device files import { AirQualitySensorDevice } from '@matter/main/devices/air-quality-sensor'; import { ColorTemperatureLightDevice } from '@matter/main/devices/color-temperature-light'; import { ContactSensorDevice } from '@matter/main/devices/contact-sensor'; import { DimmableLightDevice } from '@matter/main/devices/dimmable-light'; import { DimmablePlugInUnitDevice } from '@matter/main/devices/dimmable-plug-in-unit'; import { DoorLockDevice } from '@matter/main/devices/door-lock'; import { ExtendedColorLightDevice } from '@matter/main/devices/extended-color-light'; import { FanDevice } from '@matter/main/devices/fan'; import { GenericSwitchDevice } from '@matter/main/devices/generic-switch'; import { HumiditySensorDevice } from '@matter/main/devices/humidity-sensor'; import { LightSensorDevice } from '@matter/main/devices/light-sensor'; import { OccupancySensorDevice } from '@matter/main/devices/occupancy-sensor'; import { OnOffLightDevice } from '@matter/main/devices/on-off-light'; import { OnOffLightSwitchDevice } from '@matter/main/devices/on-off-light-switch'; import { OnOffPlugInUnitDevice } from '@matter/main/devices/on-off-plug-in-unit'; import { PumpDevice } from '@matter/main/devices/pump'; import { RoboticVacuumCleanerDevice, RoboticVacuumCleanerRequirements } from '@matter/main/devices/robotic-vacuum-cleaner'; import { RoomAirConditionerDevice } from '@matter/main/devices/room-air-conditioner'; import { SmokeCoAlarmDevice } from '@matter/main/devices/smoke-co-alarm'; import { TemperatureSensorDevice } from '@matter/main/devices/temperature-sensor'; import { ThermostatDevice, ThermostatRequirements } from '@matter/main/devices/thermostat'; import { WaterLeakDetectorDevice } from '@matter/main/devices/water-leak-detector'; import { WaterValveDevice, WaterValveRequirements } from '@matter/main/devices/water-valve'; import { WindowCoveringDevice } from '@matter/main/devices/window-covering'; import { BridgedNodeEndpoint } from '@matter/main/endpoints/bridged-node'; // Note: the canonical MatterServerEvents declaration is at the bottom of this file. // A second declaration here is unnecessary; TypeScript would merge it silently and // the comment ("Currently empty - all events removed") was misleading because the // file's other declaration adds two events. /** * Matter Accessory Event Types * * Events that can be emitted by Matter accessories during their lifecycle. * * @example * ```typescript * Listen for when a Matter accessory is ready * const accessory: MatterAccessory = { ... }; * api.matter?.publishExternalAccessories('plugin-name', [accessory]); * * const internal = accessory as any; * internal._eventEmitter?.on(MatterAccessoryEventTypes.READY, (port: number) => { * console.log(`Accessory ready on port ${port}`); * }); * ``` * * @group Matter Accessory */ export var MatterAccessoryEventTypes; (function (MatterAccessoryEventTypes) { /** * Emitted when the Matter server is ready and the accessory is available on the network. * This is the main event to listen for to know when an external accessory is ready. * * **HAP Equivalent:** `AccessoryEventTypes.ADVERTISED` * * @param port - The port number the Matter server is listening on */ MatterAccessoryEventTypes["READY"] = "ready"; })(MatterAccessoryEventTypes || (MatterAccessoryEventTypes = {})); /** * Matter error type enum (for error handler categorization) */ export var MatterErrorType; (function (MatterErrorType) { MatterErrorType["INITIALIZATION"] = "INITIALIZATION"; MatterErrorType["NETWORK"] = "NETWORK"; MatterErrorType["COMMISSIONING"] = "COMMISSIONING"; MatterErrorType["DEVICE_SYNC"] = "DEVICE_SYNC"; MatterErrorType["SERVER"] = "SERVER"; MatterErrorType["STORAGE"] = "STORAGE"; MatterErrorType["CONFIGURATION"] = "CONFIGURATION"; MatterErrorType["DEVICE_ERROR"] = "DEVICE_ERROR"; MatterErrorType["UNKNOWN"] = "UNKNOWN"; })(MatterErrorType || (MatterErrorType = {})); /** * Matter error types */ export class MatterError extends Error { code; details; type; timestamp; recoverable; constructor(message, code, details) { super(message); this.code = code; this.details = details; this.name = 'MatterError'; this.type = details?.type ?? MatterErrorType.UNKNOWN; this.timestamp = new Date(); this.recoverable = details?.recoverable ?? true; } } export class MatterCommissioningError extends MatterError { constructor(message, details) { super(message, 'COMMISSIONING_ERROR', { ...details, type: MatterErrorType.COMMISSIONING }); this.name = 'MatterCommissioningError'; } } export class MatterStorageError extends MatterError { constructor(message, details) { super(message, 'STORAGE_ERROR', { ...details, type: MatterErrorType.STORAGE }); this.name = 'MatterStorageError'; } } export class MatterDeviceError extends MatterError { constructor(message, details) { super(message, 'DEVICE_ERROR', { ...details, type: MatterErrorType.DEVICE_ERROR }); this.name = 'MatterDeviceError'; } } export class MatterNetworkError extends MatterError { constructor(message, details) { super(message, 'NETWORK_ERROR', { ...details, type: MatterErrorType.NETWORK }); this.name = 'MatterNetworkError'; } } /** * Matter device types * * All supported Matter device types, imported from individual files for optimal performance. */ const devices = { AirQualitySensorDevice, ColorTemperatureLightDevice, ContactSensorDevice, DimmableLightDevice, DimmablePlugInUnitDevice, DoorLockDevice, ExtendedColorLightDevice, FanDevice, GenericSwitchDevice, HumiditySensorDevice, LightSensorDevice, OccupancySensorDevice, OnOffLightDevice, OnOffLightSwitchDevice, OnOffPlugInUnitDevice, PumpDevice, RoboticVacuumCleanerDevice, RoboticVacuumCleanerRequirements, RoomAirConditionerDevice, SmokeCoAlarmDevice, TemperatureSensorDevice, ThermostatDevice, ThermostatRequirements, WaterLeakDetectorDevice, WaterValveDevice, WaterValveRequirements, WindowCoveringDevice, }; /** * Matter cluster types * * All supported Matter cluster types, imported from individual files for optimal performance. */ const clusters = { AirQuality, BooleanState, CarbonMonoxideConcentrationMeasurement, ColorControl, DoorLock, FanControl, LevelControl, NitrogenDioxideConcentrationMeasurement, OnOff, OzoneConcentrationMeasurement, Pm10ConcentrationMeasurement, Pm25ConcentrationMeasurement, RvcOperationalState, Thermostat, ValveConfigurationAndControl, WindowCovering, }; // Export Matter.js clusters and devices for direct access // Note: types.ts is only imported by MatterServer, MatterBridgeManager, etc. // which are themselves lazy-loaded, so these imports only happen when Matter is used export { clusters, devices }; /** * Friendly device type names for the Plugin API * Maps simplified names to actual Matter.js device types */ export const deviceTypes = { // Lighting OnOffLight: devices.OnOffLightDevice, DimmableLight: devices.DimmableLightDevice, ColorTemperatureLight: devices.ColorTemperatureLightDevice, ExtendedColorLight: devices.ExtendedColorLightDevice, // Switches & Outlets OnOffSwitch: devices.OnOffLightSwitchDevice, OnOffOutlet: devices.OnOffPlugInUnitDevice, DimmableOutlet: devices.DimmablePlugInUnitDevice, // Sensors AirQualitySensor: devices.AirQualitySensorDevice, TemperatureSensor: devices.TemperatureSensorDevice, HumiditySensor: devices.HumiditySensorDevice, LightSensor: devices.LightSensorDevice, MotionSensor: devices.OccupancySensorDevice, ContactSensor: devices.ContactSensorDevice, LeakSensor: devices.WaterLeakDetectorDevice, SmokeSensor: devices.SmokeCoAlarmDevice, // HVAC Thermostat: devices.ThermostatDevice.with(devices.ThermostatRequirements.ThermostatServer.with('Heating', 'Cooling', 'AutoMode', 'Occupancy')), Fan: devices.FanDevice, // Security DoorLock: devices.DoorLockDevice, // Window Coverings (features will be auto-detected based on accessory attributes) WindowCovering: devices.WindowCoveringDevice, // Appliances // RVC optional clusters (RvcCleanMode, ServiceArea) are added dynamically in matterServer // based on whether they're defined in the accessory configuration RoboticVacuumCleaner: devices.RoboticVacuumCleanerDevice, // Water Valve WaterValve: devices.WaterValveDevice.with(devices.WaterValveRequirements.ValveConfigurationAndControlServer), // Other GenericSwitch: devices.GenericSwitchDevice, Pump: devices.PumpDevice, RoomAirConditioner: devices.RoomAirConditionerDevice, // Composed device container — use as parent for accessories with parts. // Children appear as a single accessory in Apple Home, expandable into separate tiles. BridgedNode: BridgedNodeEndpoint, }; /** * Matter Cluster Names * Commonly used cluster names for type safety and autocomplete * Use these with api.updateMatterAccessoryState() and api.getAccessoryState() * * @example * ```typescript * With autocomplete and type safety: * api.updateMatterAccessoryState(uuid, api.matterClusterNames.OnOff, { onOff: true }) * api.getAccessoryState(uuid, api.matterClusterNames.LevelControl) * ``` */ export const clusterNames = { // Control Clusters OnOff: 'onOff', LevelControl: 'levelControl', ColorControl: 'colorControl', DoorLock: 'doorLock', WindowCovering: 'windowCovering', Thermostat: 'thermostat', FanControl: 'fanControl', // Sensor Clusters AirQuality: 'airQuality', CarbonMonoxideConcentrationMeasurement: 'carbonMonoxideConcentrationMeasurement', NitrogenDioxideConcentrationMeasurement: 'nitrogenDioxideConcentrationMeasurement', OzoneConcentrationMeasurement: 'ozoneConcentrationMeasurement', Pm10ConcentrationMeasurement: 'pm10ConcentrationMeasurement', Pm25ConcentrationMeasurement: 'pm25ConcentrationMeasurement', TemperatureMeasurement: 'temperatureMeasurement', RelativeHumidityMeasurement: 'relativeHumidityMeasurement', IlluminanceMeasurement: 'illuminanceMeasurement', OccupancySensing: 'occupancySensing', BooleanState: 'booleanState', SmokeCoAlarm: 'smokeCoAlarm', // Robotic Vacuum Cleaner Clusters RvcRunMode: 'rvcRunMode', RvcOperationalState: 'rvcOperationalState', RvcCleanMode: 'rvcCleanMode', ServiceArea: 'serviceArea', // Power PowerSource: 'powerSource', // Pump & Other PumpConfigurationAndControl: 'pumpConfigurationAndControl', // Valve ValveConfigurationAndControl: 'valveConfigurationAndControl', // Identification Identify: 'identify', // Switch (GenericSwitch - stateless remotes and buttons) Switch: 'switch', // Device Information (read-only, set during registration) BasicInformation: 'basicInformation', BridgedDeviceBasicInformation: 'bridgedDeviceBasicInformation', }; /** * Check if endpoint has state property (type guard) * * We use a runtime check to determine if an endpoint has a settable state. * This is necessary because Endpoint's state structure is complex and varies * based on device type. * * @param endpoint - The endpoint to check * @returns True if endpoint has state and set method */ export function hasEndpointState(endpoint) { return 'state' in endpoint && typeof endpoint.state === 'object' && endpoint.state !== null && 'set' in endpoint && typeof endpoint.set === 'function'; } /** * Safely update endpoint state * Uses the Endpoint's set method to update cluster attributes * * @param endpoint - The Matter endpoint * @param cluster - Cluster name * @param attributes - Attributes to update * @throws {Error} If endpoint does not support state updates */ export async function updateEndpointState(endpoint, cluster, attributes) { if (!hasEndpointState(endpoint)) { throw new Error('Endpoint does not support state updates'); } const updateObject = { [cluster]: attributes }; await endpoint.set(updateObject); } /** * Type-safe cluster access for WindowCovering */ export function getWindowCoveringCluster(accessory) { return accessory.clusters?.windowCovering; } //# sourceMappingURL=types.js.map