UNPKG

homebridge

Version:
236 lines 10.4 kB
import { EventEmitter } from 'node:events'; import hapNodeJs from '@homebridge/hap-nodejs'; import semver from 'semver'; import { Logger } from './logger.js'; import { PlatformAccessory } from './platformAccessory.js'; import { PluginManager } from './pluginManager.js'; import { User } from './user.js'; import getVersion from './version.js'; const log = Logger.internal; // eslint-disable-next-line no-restricted-syntax export var PluginType; (function (PluginType) { PluginType["ACCESSORY"] = "accessory"; PluginType["PLATFORM"] = "platform"; })(PluginType || (PluginType = {})); // eslint-disable-next-line no-restricted-syntax export var APIEvent; (function (APIEvent) { /** * Event is fired once homebridge has finished with booting up and initializing all components and plugins. * When this event is fired it is possible that the Bridge accessory isn't published yet, if homebridge still needs * to wait for some {@see StaticPlatformPlugin | StaticPlatformPlugins} to finish accessory creation. */ APIEvent["DID_FINISH_LAUNCHING"] = "didFinishLaunching"; /** * This event is fired when homebridge gets shutdown. This could be a regular shutdown or an unexpected crash. * At this stage all Accessories are already unpublished and all PlatformAccessories are already saved to disk! */ APIEvent["SHUTDOWN"] = "shutdown"; })(APIEvent || (APIEvent = {})); // eslint-disable-next-line no-restricted-syntax export var InternalAPIEvent; (function (InternalAPIEvent) { InternalAPIEvent["REGISTER_ACCESSORY"] = "registerAccessory"; InternalAPIEvent["REGISTER_PLATFORM"] = "registerPlatform"; InternalAPIEvent["PUBLISH_EXTERNAL_ACCESSORIES"] = "publishExternalAccessories"; InternalAPIEvent["REGISTER_PLATFORM_ACCESSORIES"] = "registerPlatformAccessories"; InternalAPIEvent["UPDATE_PLATFORM_ACCESSORIES"] = "updatePlatformAccessories"; InternalAPIEvent["UNREGISTER_PLATFORM_ACCESSORIES"] = "unregisterPlatformAccessories"; // Matter events (matching HAP pattern) InternalAPIEvent["PUBLISH_EXTERNAL_MATTER_ACCESSORIES"] = "publishExternalMatterAccessories"; InternalAPIEvent["REGISTER_MATTER_PLATFORM_ACCESSORIES"] = "registerMatterPlatformAccessories"; InternalAPIEvent["UPDATE_MATTER_PLATFORM_ACCESSORIES"] = "updateMatterPlatformAccessories"; InternalAPIEvent["UNREGISTER_MATTER_PLATFORM_ACCESSORIES"] = "unregisterMatterPlatformAccessories"; InternalAPIEvent["UNREGISTER_EXTERNAL_MATTER_ACCESSORIES"] = "unregisterExternalMatterAccessories"; InternalAPIEvent["UPDATE_MATTER_ACCESSORY_STATE"] = "updateMatterAccessoryState"; })(InternalAPIEvent || (InternalAPIEvent = {})); // eslint-disable-next-line ts/no-unsafe-declaration-merging export class HomebridgeAPI extends EventEmitter { version = 2.7; // homebridge API version serverVersion = getVersion(); // homebridge node module version // ------------------ LEGACY EXPORTS FOR PRE TYPESCRIPT ------------------ user = User; hap = hapNodeJs; hapLegacyTypes = hapNodeJs.LegacyTypes; // used for older accessories/platforms platformAccessory = PlatformAccessory; // ------------------------------------------------------------------------ /** * Internal state tracking whether Matter is enabled for this bridge */ matterEnabled = false; /** * Internal reference to MatterServer for API methods that need return values * @internal */ _matterServer = null; /** * Internal reference to MatterBridgeManager for checking external servers * @internal */ _matterManager = null; /** * Pending external accessory registrations * Map of registration ID to resolve function * @internal */ _pendingExternalRegistrations = new Map(); /** * Lazy-loaded Matter API implementation */ _matterAPI; /** * Matter Protocol API (lazy-loaded). * * Returns the loaded MatterAPI instance, or `undefined` when Matter is not * configured for this bridge. Server / ChildBridgeFork call * {@link loadMatterAPI} before plugins run on Matter-enabled bridges, so * plugins observe a defined value here whenever {@link isMatterEnabled} * returns true. */ get matter() { return this._matterAPI; } /** * Load Matter API implementation. Idempotent. * * Called by Server / ChildBridgeFork during startup when Matter is * configured for the bridge, before plugin initialization. Plugins should * not call this directly — use {@link matter} instead. * * @internal */ async loadMatterAPI() { if (!this._matterAPI) { const { MatterAPIImpl } = await import('./matter/MatterAPIImpl.js'); this._matterAPI = new MatterAPIImpl(this); } } constructor() { super(); } /** * Internal method to set Matter enabled status * Called by Server or ChildBridgeFork after Matter initialization * @internal */ _setMatterEnabled(enabled) { this.matterEnabled = enabled; } /** * Internal method to set MatterServer reference * Called by Server or ChildBridgeFork after creating MatterServer * @internal */ _setMatterServer(server) { this._matterServer = server; } /** * Internal method to set MatterBridgeManager reference * Called by Server or ChildBridgeFork to allow API access to external servers * @internal */ _setMatterManager(manager) { this._matterManager = manager; } /** * Internal method to resolve pending external accessory registrations * Called by MatterBridgeManager when external accessories finish publishing * @internal */ _resolveExternalRegistration(registrationId) { const resolve = this._pendingExternalRegistrations.get(registrationId); if (resolve) { resolve(); this._pendingExternalRegistrations.delete(registrationId); } } versionGreaterOrEqual(version) { return semver.gte(this.serverVersion, version); } static isDynamicPlatformPlugin(platformPlugin) { return 'configureAccessory' in platformPlugin; } static isStaticPlatformPlugin(platformPlugin) { return 'accessories' in platformPlugin; } signalFinished() { this.emit("didFinishLaunching" /* APIEvent.DID_FINISH_LAUNCHING */); } signalShutdown() { this.emit("shutdown" /* APIEvent.SHUTDOWN */); } registerAccessory(pluginIdentifier, accessoryName, constructor) { if (typeof accessoryName === 'function') { constructor = accessoryName; accessoryName = pluginIdentifier; this.emit("registerAccessory" /* InternalAPIEvent.REGISTER_ACCESSORY */, accessoryName, constructor); } else { this.emit("registerAccessory" /* InternalAPIEvent.REGISTER_ACCESSORY */, accessoryName, constructor, pluginIdentifier); } } registerPlatform(pluginIdentifier, platformName, constructor) { if (typeof platformName === 'function') { constructor = platformName; platformName = pluginIdentifier; this.emit("registerPlatform" /* InternalAPIEvent.REGISTER_PLATFORM */, platformName, constructor); } else { this.emit("registerPlatform" /* InternalAPIEvent.REGISTER_PLATFORM */, platformName, constructor, pluginIdentifier); } } publishExternalAccessories(pluginIdentifier, accessories) { if (!PluginManager.isQualifiedPluginIdentifier(pluginIdentifier)) { log.info(`One of your plugins incorrectly registered an external accessory using the platform name (${pluginIdentifier}) and not the plugin identifier. Please report this to the developer!`); } accessories.forEach((accessory) => { // noinspection SuspiciousTypeOfGuard if (!(accessory instanceof PlatformAccessory)) { throw new TypeError(`${pluginIdentifier} attempt to register an accessory that isn't PlatformAccessory!`); } accessory._associatedPlugin = pluginIdentifier; }); this.emit("publishExternalAccessories" /* InternalAPIEvent.PUBLISH_EXTERNAL_ACCESSORIES */, accessories); } registerPlatformAccessories(pluginIdentifier, platformName, accessories) { accessories.forEach((accessory) => { // noinspection SuspiciousTypeOfGuard if (!(accessory instanceof PlatformAccessory)) { throw new TypeError(`${pluginIdentifier} - ${platformName} attempt to register an accessory that isn't PlatformAccessory!`); } accessory._associatedPlugin = pluginIdentifier; accessory._associatedPlatform = platformName; }); this.emit("registerPlatformAccessories" /* InternalAPIEvent.REGISTER_PLATFORM_ACCESSORIES */, accessories); } updatePlatformAccessories(accessories) { this.emit("updatePlatformAccessories" /* InternalAPIEvent.UPDATE_PLATFORM_ACCESSORIES */, accessories); } unregisterPlatformAccessories(pluginIdentifier, platformName, accessories) { accessories.forEach((accessory) => { // noinspection SuspiciousTypeOfGuard if (!(accessory instanceof PlatformAccessory)) { throw new TypeError(`${pluginIdentifier} - ${platformName} attempt to unregister an accessory that isn't PlatformAccessory!`); } }); this.emit("unregisterPlatformAccessories" /* InternalAPIEvent.UNREGISTER_PLATFORM_ACCESSORIES */, accessories); } /** * Check if Matter is available in this version of Homebridge * @returns true if Homebridge version satisfies >= 2.0.0-alpha.0 */ isMatterAvailable() { return semver.gte(this.serverVersion, '2.0.0-alpha.0'); } /** * Check if Matter is enabled for this bridge * For main bridge: returns true if Matter is enabled in `bridge.matter` config * For child bridge: returns true if Matter is enabled in the `_bridge.matter` config * @returns true if Matter is enabled */ isMatterEnabled() { return this.matterEnabled; } } //# sourceMappingURL=api.js.map