homebridge 2.0.0-beta.44 → 2.0.0-beta.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +3 -365
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +13 -85
- package/dist/api.js.map +1 -1
- package/dist/bridgeService.d.ts +0 -25
- package/dist/bridgeService.d.ts.map +1 -1
- package/dist/bridgeService.js +32 -85
- package/dist/bridgeService.js.map +1 -1
- package/dist/childBridgeFork.d.ts +12 -15
- package/dist/childBridgeFork.d.ts.map +1 -1
- package/dist/childBridgeFork.js +126 -80
- package/dist/childBridgeFork.js.map +1 -1
- package/dist/childBridgeService.d.ts +21 -105
- package/dist/childBridgeService.d.ts.map +1 -1
- package/dist/childBridgeService.js +57 -134
- package/dist/childBridgeService.js.map +1 -1
- package/dist/cli.js +0 -2
- package/dist/cli.js.map +1 -1
- package/dist/externalPortService.d.ts +0 -21
- package/dist/externalPortService.d.ts.map +1 -1
- package/dist/externalPortService.js +0 -28
- package/dist/externalPortService.js.map +1 -1
- package/dist/index.d.ts +0 -112
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -44
- package/dist/index.js.map +1 -1
- package/dist/ipcService.d.ts +23 -15
- package/dist/ipcService.d.ts.map +1 -1
- package/dist/ipcService.js +6 -12
- package/dist/ipcService.js.map +1 -1
- package/dist/logger.d.ts +0 -46
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +13 -57
- package/dist/logger.js.map +1 -1
- package/dist/matter/BaseMatterManager.d.ts +19 -0
- package/dist/matter/BaseMatterManager.d.ts.map +1 -0
- package/dist/matter/BaseMatterManager.js +170 -0
- package/dist/matter/BaseMatterManager.js.map +1 -0
- package/dist/matter/ChildBridgeMatterManager.d.ts +5 -69
- package/dist/matter/ChildBridgeMatterManager.d.ts.map +1 -1
- package/dist/matter/ChildBridgeMatterManager.js +36 -227
- package/dist/matter/ChildBridgeMatterManager.js.map +1 -1
- package/dist/matter/ClusterCommandMapper.d.ts +5 -0
- package/dist/matter/ClusterCommandMapper.d.ts.map +1 -0
- package/dist/matter/ClusterCommandMapper.js +203 -0
- package/dist/matter/ClusterCommandMapper.js.map +1 -0
- package/dist/matter/ExternalMatterAccessoryPublisher.d.ts +0 -27
- package/dist/matter/ExternalMatterAccessoryPublisher.d.ts.map +1 -1
- package/dist/matter/ExternalMatterAccessoryPublisher.js +2 -27
- package/dist/matter/ExternalMatterAccessoryPublisher.js.map +1 -1
- package/dist/matter/MatterAPIImpl.d.ts +0 -68
- package/dist/matter/MatterAPIImpl.d.ts.map +1 -1
- package/dist/matter/MatterAPIImpl.js +6 -106
- package/dist/matter/MatterAPIImpl.js.map +1 -1
- package/dist/matter/MatterBridgeManager.d.ts +9 -60
- package/dist/matter/MatterBridgeManager.d.ts.map +1 -1
- package/dist/matter/MatterBridgeManager.js +139 -215
- package/dist/matter/MatterBridgeManager.js.map +1 -1
- package/dist/matter/MatterConfigCollector.d.ts +1 -20
- package/dist/matter/MatterConfigCollector.d.ts.map +1 -1
- package/dist/matter/MatterConfigCollector.js +14 -27
- package/dist/matter/MatterConfigCollector.js.map +1 -1
- package/dist/matter/accessoryCache.d.ts +0 -48
- package/dist/matter/accessoryCache.d.ts.map +1 -1
- package/dist/matter/accessoryCache.js +1 -60
- package/dist/matter/accessoryCache.js.map +1 -1
- package/dist/matter/behaviors/AirQualityBehavior.d.ts +0 -42
- package/dist/matter/behaviors/AirQualityBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/AirQualityBehavior.js +0 -44
- package/dist/matter/behaviors/AirQualityBehavior.js.map +1 -1
- package/dist/matter/behaviors/BehaviorRegistry.d.ts +4 -42
- package/dist/matter/behaviors/BehaviorRegistry.d.ts.map +1 -1
- package/dist/matter/behaviors/BehaviorRegistry.js +12 -42
- package/dist/matter/behaviors/BehaviorRegistry.js.map +1 -1
- package/dist/matter/behaviors/ColorControlBehavior.d.ts +0 -49
- package/dist/matter/behaviors/ColorControlBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/ColorControlBehavior.js +0 -90
- package/dist/matter/behaviors/ColorControlBehavior.js.map +1 -1
- package/dist/matter/behaviors/ConcentrationMeasurementBehavior.d.ts +0 -91
- package/dist/matter/behaviors/ConcentrationMeasurementBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/ConcentrationMeasurementBehavior.js +0 -96
- package/dist/matter/behaviors/ConcentrationMeasurementBehavior.js.map +1 -1
- package/dist/matter/behaviors/DoorLockBehavior.d.ts +0 -11
- package/dist/matter/behaviors/DoorLockBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/DoorLockBehavior.js +0 -25
- package/dist/matter/behaviors/DoorLockBehavior.js.map +1 -1
- package/dist/matter/behaviors/FanControlBehavior.d.ts +0 -11
- package/dist/matter/behaviors/FanControlBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/FanControlBehavior.js +0 -25
- package/dist/matter/behaviors/FanControlBehavior.js.map +1 -1
- package/dist/matter/behaviors/IdentifyBehavior.d.ts +0 -11
- package/dist/matter/behaviors/IdentifyBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/IdentifyBehavior.js +0 -17
- package/dist/matter/behaviors/IdentifyBehavior.js.map +1 -1
- package/dist/matter/behaviors/LevelControlBehavior.d.ts +0 -20
- package/dist/matter/behaviors/LevelControlBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/LevelControlBehavior.js +0 -52
- package/dist/matter/behaviors/LevelControlBehavior.js.map +1 -1
- package/dist/matter/behaviors/OnOffBehavior.d.ts +0 -17
- package/dist/matter/behaviors/OnOffBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/OnOffBehavior.js +0 -38
- package/dist/matter/behaviors/OnOffBehavior.js.map +1 -1
- package/dist/matter/behaviors/RvcCleanModeBehavior.d.ts +0 -11
- package/dist/matter/behaviors/RvcCleanModeBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/RvcCleanModeBehavior.js +0 -17
- package/dist/matter/behaviors/RvcCleanModeBehavior.js.map +1 -1
- package/dist/matter/behaviors/RvcOperationalStateBehavior.d.ts +0 -11
- package/dist/matter/behaviors/RvcOperationalStateBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/RvcOperationalStateBehavior.js +0 -29
- package/dist/matter/behaviors/RvcOperationalStateBehavior.js.map +1 -1
- package/dist/matter/behaviors/RvcRunModeBehavior.d.ts +0 -11
- package/dist/matter/behaviors/RvcRunModeBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/RvcRunModeBehavior.js +0 -17
- package/dist/matter/behaviors/RvcRunModeBehavior.js.map +1 -1
- package/dist/matter/behaviors/ServiceAreaBehavior.d.ts +0 -11
- package/dist/matter/behaviors/ServiceAreaBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/ServiceAreaBehavior.js +0 -23
- package/dist/matter/behaviors/ServiceAreaBehavior.js.map +1 -1
- package/dist/matter/behaviors/ThermostatBehavior.d.ts +0 -11
- package/dist/matter/behaviors/ThermostatBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/ThermostatBehavior.js +0 -39
- package/dist/matter/behaviors/ThermostatBehavior.js.map +1 -1
- package/dist/matter/behaviors/WindowCoveringBehavior.d.ts +0 -17
- package/dist/matter/behaviors/WindowCoveringBehavior.d.ts.map +1 -1
- package/dist/matter/behaviors/WindowCoveringBehavior.js +0 -56
- package/dist/matter/behaviors/WindowCoveringBehavior.js.map +1 -1
- package/dist/matter/behaviors/index.d.ts +0 -5
- package/dist/matter/behaviors/index.d.ts.map +1 -1
- package/dist/matter/behaviors/index.js +0 -5
- package/dist/matter/behaviors/index.js.map +1 -1
- package/dist/matter/configValidator.d.ts +0 -55
- package/dist/matter/configValidator.d.ts.map +1 -1
- package/dist/matter/configValidator.js +1 -68
- package/dist/matter/configValidator.js.map +1 -1
- package/dist/matter/errorHandler.d.ts +0 -22
- package/dist/matter/errorHandler.d.ts.map +1 -1
- package/dist/matter/errorHandler.js +0 -32
- package/dist/matter/errorHandler.js.map +1 -1
- package/dist/matter/errors.d.ts +0 -132
- package/dist/matter/errors.d.ts.map +1 -1
- package/dist/matter/errors.js +0 -132
- package/dist/matter/errors.js.map +1 -1
- package/dist/matter/index.d.ts +0 -30
- package/dist/matter/index.d.ts.map +1 -1
- package/dist/matter/index.js +0 -13
- package/dist/matter/index.js.map +1 -1
- package/dist/matter/logFormatter.d.ts +0 -17
- package/dist/matter/logFormatter.d.ts.map +1 -1
- package/dist/matter/logFormatter.js +5 -63
- package/dist/matter/logFormatter.js.map +1 -1
- package/dist/matter/server.d.ts +12 -236
- package/dist/matter/server.d.ts.map +1 -1
- package/dist/matter/server.js +177 -488
- package/dist/matter/server.js.map +1 -1
- package/dist/matter/serverHelpers.d.ts +0 -56
- package/dist/matter/serverHelpers.d.ts.map +1 -1
- package/dist/matter/serverHelpers.js +1 -66
- package/dist/matter/serverHelpers.js.map +1 -1
- package/dist/matter/sharedTypes.d.ts +0 -83
- package/dist/matter/sharedTypes.d.ts.map +1 -1
- package/dist/matter/sharedTypes.js +0 -26
- package/dist/matter/sharedTypes.js.map +1 -1
- package/dist/matter/storage.d.ts +0 -90
- package/dist/matter/storage.d.ts.map +1 -1
- package/dist/matter/storage.js +2 -130
- package/dist/matter/storage.js.map +1 -1
- package/dist/matter/typeHelpers.d.ts +0 -30
- package/dist/matter/typeHelpers.d.ts.map +1 -1
- package/dist/matter/typeHelpers.js +0 -24
- package/dist/matter/typeHelpers.js.map +1 -1
- package/dist/matter/types.d.ts +0 -273
- package/dist/matter/types.d.ts.map +1 -1
- package/dist/matter/types.js +0 -83
- package/dist/matter/types.js.map +1 -1
- package/dist/platformAccessory.d.ts +0 -15
- package/dist/platformAccessory.d.ts.map +1 -1
- package/dist/platformAccessory.js +6 -32
- package/dist/platformAccessory.js.map +1 -1
- package/dist/plugin.d.ts +0 -3
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +6 -29
- package/dist/plugin.js.map +1 -1
- package/dist/pluginManager.d.ts +0 -22
- package/dist/pluginManager.d.ts.map +1 -1
- package/dist/pluginManager.js +18 -41
- package/dist/pluginManager.js.map +1 -1
- package/dist/server.d.ts +9 -29
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +304 -157
- package/dist/server.js.map +1 -1
- package/dist/user.d.ts +0 -3
- package/dist/user.d.ts.map +1 -1
- package/dist/user.js +2 -5
- package/dist/user.js.map +1 -1
- package/dist/util/mac.js +0 -1
- package/dist/util/mac.js.map +1 -1
- package/package.json +4 -4
- package/dist/api.spec.d.ts +0 -2
- package/dist/api.spec.d.ts.map +0 -1
- package/dist/api.spec.js +0 -413
- package/dist/api.spec.js.map +0 -1
- package/dist/logger.spec.d.ts +0 -2
- package/dist/logger.spec.d.ts.map +0 -1
- package/dist/logger.spec.js +0 -95
- package/dist/logger.spec.js.map +0 -1
- package/dist/matter/ExternalMatterAccessoryPublisher.spec.d.ts +0 -2
- package/dist/matter/ExternalMatterAccessoryPublisher.spec.d.ts.map +0 -1
- package/dist/matter/ExternalMatterAccessoryPublisher.spec.js +0 -293
- package/dist/matter/ExternalMatterAccessoryPublisher.spec.js.map +0 -1
- package/dist/matter/accessoryCache.spec.d.ts +0 -2
- package/dist/matter/accessoryCache.spec.d.ts.map +0 -1
- package/dist/matter/accessoryCache.spec.js +0 -452
- package/dist/matter/accessoryCache.spec.js.map +0 -1
- package/dist/matter/behaviors/AirQualityBehavior.spec.d.ts +0 -5
- package/dist/matter/behaviors/AirQualityBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/AirQualityBehavior.spec.js +0 -46
- package/dist/matter/behaviors/AirQualityBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/BehaviorRegistry.spec.d.ts +0 -2
- package/dist/matter/behaviors/BehaviorRegistry.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/BehaviorRegistry.spec.js +0 -307
- package/dist/matter/behaviors/BehaviorRegistry.spec.js.map +0 -1
- package/dist/matter/behaviors/ColorControlBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/ColorControlBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/ColorControlBehavior.spec.js +0 -29
- package/dist/matter/behaviors/ColorControlBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/ConcentrationMeasurementBehavior.spec.d.ts +0 -5
- package/dist/matter/behaviors/ConcentrationMeasurementBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/ConcentrationMeasurementBehavior.spec.js +0 -95
- package/dist/matter/behaviors/ConcentrationMeasurementBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/DoorLockBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/DoorLockBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/DoorLockBehavior.spec.js +0 -120
- package/dist/matter/behaviors/DoorLockBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/FanControlBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/FanControlBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/FanControlBehavior.spec.js +0 -23
- package/dist/matter/behaviors/FanControlBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/IdentifyBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/IdentifyBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/IdentifyBehavior.spec.js +0 -64
- package/dist/matter/behaviors/IdentifyBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/LevelControlBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/LevelControlBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/LevelControlBehavior.spec.js +0 -145
- package/dist/matter/behaviors/LevelControlBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/OnOffBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/OnOffBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/OnOffBehavior.spec.js +0 -128
- package/dist/matter/behaviors/OnOffBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/RvcCleanModeBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/RvcCleanModeBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/RvcCleanModeBehavior.spec.js +0 -57
- package/dist/matter/behaviors/RvcCleanModeBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/RvcOperationalStateBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/RvcOperationalStateBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/RvcOperationalStateBehavior.spec.js +0 -55
- package/dist/matter/behaviors/RvcOperationalStateBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/RvcRunModeBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/RvcRunModeBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/RvcRunModeBehavior.spec.js +0 -57
- package/dist/matter/behaviors/RvcRunModeBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/ServiceAreaBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/ServiceAreaBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/ServiceAreaBehavior.spec.js +0 -53
- package/dist/matter/behaviors/ServiceAreaBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/ThermostatBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/ThermostatBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/ThermostatBehavior.spec.js +0 -23
- package/dist/matter/behaviors/ThermostatBehavior.spec.js.map +0 -1
- package/dist/matter/behaviors/WindowCoveringBehavior.spec.d.ts +0 -2
- package/dist/matter/behaviors/WindowCoveringBehavior.spec.d.ts.map +0 -1
- package/dist/matter/behaviors/WindowCoveringBehavior.spec.js +0 -27
- package/dist/matter/behaviors/WindowCoveringBehavior.spec.js.map +0 -1
- package/dist/matter/configValidator.spec.d.ts +0 -2
- package/dist/matter/configValidator.spec.d.ts.map +0 -1
- package/dist/matter/configValidator.spec.js +0 -390
- package/dist/matter/configValidator.spec.js.map +0 -1
- package/dist/matter/errorHandler.spec.d.ts +0 -2
- package/dist/matter/errorHandler.spec.d.ts.map +0 -1
- package/dist/matter/errorHandler.spec.js +0 -159
- package/dist/matter/errorHandler.spec.js.map +0 -1
- package/dist/matter/logFormatter.spec.d.ts +0 -2
- package/dist/matter/logFormatter.spec.d.ts.map +0 -1
- package/dist/matter/logFormatter.spec.js +0 -252
- package/dist/matter/logFormatter.spec.js.map +0 -1
- package/dist/matter/serverHelpers.spec.d.ts +0 -2
- package/dist/matter/serverHelpers.spec.d.ts.map +0 -1
- package/dist/matter/serverHelpers.spec.js +0 -527
- package/dist/matter/serverHelpers.spec.js.map +0 -1
- package/dist/matter/storage.spec.d.ts +0 -2
- package/dist/matter/storage.spec.d.ts.map +0 -1
- package/dist/matter/storage.spec.js +0 -570
- package/dist/matter/storage.spec.js.map +0 -1
- package/dist/matter/typeHelpers.spec.d.ts +0 -2
- package/dist/matter/typeHelpers.spec.d.ts.map +0 -1
- package/dist/matter/typeHelpers.spec.js +0 -127
- package/dist/matter/typeHelpers.spec.js.map +0 -1
- package/dist/platformAccessory.spec.d.ts +0 -2
- package/dist/platformAccessory.spec.d.ts.map +0 -1
- package/dist/platformAccessory.spec.js +0 -126
- package/dist/platformAccessory.spec.js.map +0 -1
- package/dist/pluginManager.spec.d.ts +0 -2
- package/dist/pluginManager.spec.d.ts.map +0 -1
- package/dist/pluginManager.spec.js +0 -43
- package/dist/pluginManager.spec.js.map +0 -1
- package/dist/server.spec.d.ts +0 -2
- package/dist/server.spec.d.ts.map +0 -1
- package/dist/server.spec.js +0 -57
- package/dist/server.spec.js.map +0 -1
- package/dist/user.spec.d.ts +0 -2
- package/dist/user.spec.d.ts.map +0 -1
- package/dist/user.spec.js +0 -31
- package/dist/user.spec.js.map +0 -1
- package/dist/util/mac.spec.d.ts +0 -2
- package/dist/util/mac.spec.d.ts.map +0 -1
- package/dist/util/mac.spec.js +0 -36
- package/dist/util/mac.spec.js.map +0 -1
- package/dist/version.spec.d.ts +0 -2
- package/dist/version.spec.d.ts.map +0 -1
- package/dist/version.spec.js +0 -20
- package/dist/version.spec.js.map +0 -1
package/dist/server.js
CHANGED
|
@@ -13,20 +13,10 @@ import { PluginManager } from './pluginManager.js';
|
|
|
13
13
|
import { User } from './user.js';
|
|
14
14
|
import { validMacAddress } from './util/mac.js';
|
|
15
15
|
const log = Logger.internal;
|
|
16
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
17
16
|
export var ServerStatus;
|
|
18
17
|
(function (ServerStatus) {
|
|
19
|
-
/**
|
|
20
|
-
* When the server is starting up
|
|
21
|
-
*/
|
|
22
18
|
ServerStatus["PENDING"] = "pending";
|
|
23
|
-
/**
|
|
24
|
-
* When the server is online and has published the main bridge
|
|
25
|
-
*/
|
|
26
19
|
ServerStatus["OK"] = "ok";
|
|
27
|
-
/**
|
|
28
|
-
* When the server is shutting down
|
|
29
|
-
*/
|
|
30
20
|
ServerStatus["DOWN"] = "down";
|
|
31
21
|
})(ServerStatus || (ServerStatus = {}));
|
|
32
22
|
export class Server {
|
|
@@ -37,26 +27,19 @@ export class Server {
|
|
|
37
27
|
ipcService;
|
|
38
28
|
externalPortService;
|
|
39
29
|
config;
|
|
40
|
-
// used to keep track of child bridges
|
|
41
|
-
// Key is HAP username (MAC address)
|
|
42
30
|
childBridges = new Map();
|
|
43
|
-
// Matter bridge manager (handles Matter server lifecycle)
|
|
44
|
-
// Made optional to handle initialization order - gets created in constructor after first setServerStatus call
|
|
45
31
|
matterManager;
|
|
46
|
-
|
|
47
|
-
|
|
32
|
+
matterMonitoringActive = false;
|
|
33
|
+
matterMonitoringClients = 0;
|
|
34
|
+
serverStatus = "pending";
|
|
48
35
|
constructor(options = {}) {
|
|
49
36
|
this.options = options;
|
|
50
37
|
this.config = Server.loadConfig();
|
|
51
|
-
// object we feed to Plugins and BridgeService
|
|
52
38
|
this.api = new HomebridgeAPI();
|
|
53
39
|
this.ipcService = new IpcService();
|
|
54
|
-
// Collect all configured Matter ports to avoid conflicts
|
|
55
40
|
const configuredMatterPorts = MatterBridgeManager.collectConfiguredMatterPorts(this.config);
|
|
56
41
|
this.externalPortService = new ExternalPortService(this.config.ports, this.config.matterPorts, configuredMatterPorts);
|
|
57
|
-
|
|
58
|
-
this.setServerStatus("pending" /* ServerStatus.PENDING */);
|
|
59
|
-
// create new plugin manager
|
|
42
|
+
this.setServerStatus("pending");
|
|
60
43
|
const pluginManagerOptions = {
|
|
61
44
|
activePlugins: this.config.plugins,
|
|
62
45
|
disabledPlugins: this.config.disabledPlugins,
|
|
@@ -64,47 +47,27 @@ export class Server {
|
|
|
64
47
|
strictPluginResolution: options.strictPluginResolution,
|
|
65
48
|
};
|
|
66
49
|
this.pluginManager = new PluginManager(this.api, pluginManagerOptions);
|
|
67
|
-
// create new bridge service
|
|
68
50
|
const bridgeConfig = {
|
|
69
51
|
cachedAccessoriesDir: User.cachedAccessoryPath(),
|
|
70
52
|
cachedAccessoriesItemName: 'cachedAccessories',
|
|
71
53
|
};
|
|
72
|
-
// shallow copy the homebridge options to the bridge options object
|
|
73
54
|
Object.assign(bridgeConfig, this.options);
|
|
74
55
|
this.bridgeService = new BridgeService(this.api, this.pluginManager, this.externalPortService, bridgeConfig, this.config.bridge);
|
|
75
|
-
// Create Matter bridge manager
|
|
76
56
|
this.matterManager = new MatterBridgeManager(this.config, this.api, this.externalPortService, this.pluginManager, this.options);
|
|
77
|
-
// Set manager reference on API for getAccessoryState
|
|
78
57
|
this.api._setMatterManager(this.matterManager);
|
|
79
|
-
|
|
80
|
-
this.api.on("
|
|
81
|
-
this.api.on("
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// Handle Matter accessory registration (matching HAP pattern)
|
|
85
|
-
this.api.on("publishExternalMatterAccessories" /* InternalAPIEvent.PUBLISH_EXTERNAL_MATTER_ACCESSORIES */, this.handlePublishExternalMatterAccessories.bind(this));
|
|
86
|
-
this.api.on("registerMatterPlatformAccessories" /* InternalAPIEvent.REGISTER_MATTER_PLATFORM_ACCESSORIES */, this.handleRegisterMatterPlatformAccessories.bind(this));
|
|
87
|
-
this.api.on("updateMatterPlatformAccessories" /* InternalAPIEvent.UPDATE_MATTER_PLATFORM_ACCESSORIES */, this.handleUpdateMatterPlatformAccessories.bind(this));
|
|
88
|
-
this.api.on("unregisterMatterPlatformAccessories" /* InternalAPIEvent.UNREGISTER_MATTER_PLATFORM_ACCESSORIES */, this.handleUnregisterMatterPlatformAccessories.bind(this));
|
|
89
|
-
this.api.on("unregisterExternalMatterAccessories" /* InternalAPIEvent.UNREGISTER_EXTERNAL_MATTER_ACCESSORIES */, this.handleUnregisterExternalMatterAccessories.bind(this));
|
|
90
|
-
this.api.on("updateMatterAccessoryState" /* InternalAPIEvent.UPDATE_MATTER_ACCESSORY_STATE */, this.handleUpdateMatterAccessoryState.bind(this));
|
|
91
|
-
// watch bridge events to check when server is online
|
|
92
|
-
this.bridgeService.bridge.on("advertised" /* AccessoryEventTypes.ADVERTISED */, () => {
|
|
93
|
-
this.setServerStatus("ok" /* ServerStatus.OK */);
|
|
58
|
+
this.api.on("registerPlatformAccessories", this.handleRegisterPlatformAccessories.bind(this));
|
|
59
|
+
this.api.on("unregisterPlatformAccessories", this.handleUnregisterPlatformAccessories.bind(this));
|
|
60
|
+
this.api.on("publishExternalAccessories", this.handlePublishExternalAccessories.bind(this));
|
|
61
|
+
this.bridgeService.bridge.on("advertised", () => {
|
|
62
|
+
this.setServerStatus("ok");
|
|
94
63
|
});
|
|
95
|
-
|
|
96
|
-
this.bridgeService.bridge.on("paired" /* AccessoryEventTypes.PAIRED */, () => {
|
|
64
|
+
this.bridgeService.bridge.on("paired", () => {
|
|
97
65
|
this.setServerStatus(this.serverStatus);
|
|
98
66
|
});
|
|
99
|
-
|
|
100
|
-
this.bridgeService.bridge.on("unpaired" /* AccessoryEventTypes.UNPAIRED */, () => {
|
|
67
|
+
this.bridgeService.bridge.on("unpaired", () => {
|
|
101
68
|
this.setServerStatus(this.serverStatus);
|
|
102
69
|
});
|
|
103
70
|
}
|
|
104
|
-
/**
|
|
105
|
-
* Set the current server status and update parent via IPC
|
|
106
|
-
* @param status
|
|
107
|
-
*/
|
|
108
71
|
setServerStatus(status) {
|
|
109
72
|
this.serverStatus = status;
|
|
110
73
|
const statusUpdate = {
|
|
@@ -116,18 +79,15 @@ export class Server {
|
|
|
116
79
|
pin: this.config.bridge.pin,
|
|
117
80
|
matter: this.matterManager?.getMatterStatus() ?? { enabled: false },
|
|
118
81
|
};
|
|
119
|
-
this.ipcService.sendMessage("serverStatusUpdate"
|
|
82
|
+
this.ipcService.sendMessage("serverStatusUpdate", statusUpdate);
|
|
120
83
|
}
|
|
121
84
|
async start() {
|
|
122
85
|
if (this.config.bridge.disableIpc !== true) {
|
|
123
86
|
this.initializeIpcEventHandlers();
|
|
124
87
|
}
|
|
125
88
|
const promises = [];
|
|
126
|
-
// load the cached accessories
|
|
127
89
|
await this.bridgeService.loadCachedPlatformAccessoriesFromDisk();
|
|
128
|
-
// initialize plugins
|
|
129
90
|
await this.pluginManager.initializeInstalledPlugins();
|
|
130
|
-
// Initialize Matter server for main bridge if enabled
|
|
131
91
|
await this.matterManager?.initialize();
|
|
132
92
|
if (this.config.platforms.length > 0) {
|
|
133
93
|
promises.push(...this.loadPlatforms());
|
|
@@ -135,78 +95,40 @@ export class Server {
|
|
|
135
95
|
if (this.config.accessories.length > 0) {
|
|
136
96
|
this.loadAccessories();
|
|
137
97
|
}
|
|
138
|
-
// start child bridges
|
|
139
98
|
for (const childBridge of this.childBridges.values()) {
|
|
140
99
|
childBridge.start();
|
|
141
100
|
}
|
|
142
|
-
// restore cached accessories
|
|
143
101
|
this.bridgeService.restoreCachedPlatformAccessories();
|
|
144
102
|
this.matterManager?.restoreCachedAccessories(this.options.keepOrphanedCachedAccessories ?? false);
|
|
145
103
|
this.api.signalFinished();
|
|
146
|
-
// wait for all platforms to publish their accessories before we publish the bridge
|
|
147
104
|
await Promise.all(promises)
|
|
148
105
|
.then(() => this.publishBridge());
|
|
149
106
|
}
|
|
150
107
|
async teardown() {
|
|
151
108
|
this.bridgeService.teardown();
|
|
152
|
-
// Teardown Matter servers (main bridge and external accessories)
|
|
153
109
|
await this.matterManager?.teardown();
|
|
154
|
-
this.setServerStatus("down"
|
|
110
|
+
this.setServerStatus("down");
|
|
155
111
|
}
|
|
156
112
|
publishBridge() {
|
|
157
113
|
this.bridgeService.publishBridge();
|
|
158
114
|
this.printSetupInfo(this.config.bridge.pin);
|
|
159
115
|
}
|
|
160
116
|
handlePublishExternalAccessories(accessories) {
|
|
161
|
-
// External accessories are published via HAP
|
|
162
|
-
// Plugins should use api.matter to register Matter accessories explicitly
|
|
163
117
|
log.info(`Publishing ${accessories.length} external accessories`);
|
|
164
118
|
}
|
|
165
|
-
/**
|
|
166
|
-
* Handle external Matter accessories - delegates to MatterBridgeManager
|
|
167
|
-
*/
|
|
168
|
-
handlePublishExternalMatterAccessories(accessories, registrationId) {
|
|
169
|
-
this.matterManager?.handlePublishExternalAccessories(accessories, registrationId).catch((error) => {
|
|
170
|
-
log.error('Failed to publish external Matter accessories:', error);
|
|
171
|
-
// Make sure to resolve the registration even on error
|
|
172
|
-
this.api._resolveExternalRegistration(registrationId);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
119
|
handleRegisterPlatformAccessories(accessories) {
|
|
176
|
-
// Route to HAP bridge
|
|
177
120
|
this.bridgeService.handleRegisterPlatformAccessories(accessories);
|
|
178
121
|
}
|
|
179
122
|
handleUnregisterPlatformAccessories(accessories) {
|
|
180
|
-
// Route to HAP bridge
|
|
181
123
|
this.bridgeService.handleUnregisterPlatformAccessories(accessories);
|
|
182
124
|
}
|
|
183
|
-
|
|
184
|
-
this.matterManager
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
handleUpdateMatterPlatformAccessories(accessories) {
|
|
189
|
-
this.matterManager?.handleUpdatePlatformAccessories(accessories).catch((error) => {
|
|
190
|
-
log.error('Failed to update Matter platform accessories:', error);
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
handleUnregisterMatterPlatformAccessories(pluginIdentifier, platformName, accessories) {
|
|
194
|
-
this.matterManager?.handleUnregisterPlatformAccessories(pluginIdentifier, platformName, accessories).catch((error) => {
|
|
195
|
-
log.error(`Failed to unregister Matter accessories for ${pluginIdentifier}:`, error);
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
handleUnregisterExternalMatterAccessories(accessories) {
|
|
199
|
-
this.matterManager?.handleUnregisterExternalAccessories(accessories).catch((error) => {
|
|
200
|
-
log.error('Failed to unregister external Matter accessories:', error);
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
handleUpdateMatterAccessoryState(uuid, cluster, attributes, partId) {
|
|
204
|
-
this.matterManager?.handleUpdateAccessoryState(uuid, cluster, attributes, partId).catch((error) => {
|
|
205
|
-
log.error(`Failed to update Matter accessory state for ${uuid}:`, error);
|
|
206
|
-
});
|
|
125
|
+
async handleTriggerMatterCommand(uuid, cluster, attributes, partId) {
|
|
126
|
+
if (!this.matterManager) {
|
|
127
|
+
throw new Error('Matter manager not initialized');
|
|
128
|
+
}
|
|
129
|
+
await this.matterManager.handleTriggerCommand(uuid, cluster, attributes, partId);
|
|
207
130
|
}
|
|
208
131
|
static loadConfig() {
|
|
209
|
-
// Look for the configuration file
|
|
210
132
|
const configPath = User.configPath();
|
|
211
133
|
const defaultBridge = {
|
|
212
134
|
name: 'Homebridge',
|
|
@@ -243,18 +165,7 @@ export class Server {
|
|
|
243
165
|
config.ports = undefined;
|
|
244
166
|
}
|
|
245
167
|
}
|
|
246
|
-
|
|
247
|
-
if (config.matterPorts.start && config.matterPorts.end) {
|
|
248
|
-
if (config.matterPorts.start > config.matterPorts.end) {
|
|
249
|
-
log.error('Invalid Matter port pool configuration. End should be greater than or equal to start.');
|
|
250
|
-
config.matterPorts = undefined;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
log.error('Invalid configuration for \'matterPorts\'. Missing \'start\' and \'end\' properties! Ignoring it!');
|
|
255
|
-
config.matterPorts = undefined;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
168
|
+
MatterConfigCollector.validateMatterPortsPool(config);
|
|
258
169
|
const bridge = config.bridge || defaultBridge;
|
|
259
170
|
bridge.name = bridge.name || defaultBridge.name;
|
|
260
171
|
bridge.username = bridge.username || defaultBridge.username;
|
|
@@ -275,14 +186,13 @@ export class Server {
|
|
|
275
186
|
config.platforms = [];
|
|
276
187
|
}
|
|
277
188
|
log.info('Loaded config.json with %s accessories and %s platforms.', config.accessories.length, config.platforms.length);
|
|
278
|
-
// Validate Matter configuration for port conflicts
|
|
279
189
|
MatterConfigCollector.validateMatterConfig(config);
|
|
280
190
|
if (config.bridge.advertiser) {
|
|
281
191
|
if (![
|
|
282
|
-
"bonjour-hap"
|
|
283
|
-
"ciao"
|
|
284
|
-
"avahi"
|
|
285
|
-
"resolved"
|
|
192
|
+
"bonjour-hap",
|
|
193
|
+
"ciao",
|
|
194
|
+
"avahi",
|
|
195
|
+
"resolved",
|
|
286
196
|
].includes(config.bridge.advertiser)) {
|
|
287
197
|
config.bridge.advertiser = undefined;
|
|
288
198
|
log.error('Value provided in bridge.advertiser is not valid, reverting to platform default.');
|
|
@@ -298,7 +208,7 @@ export class Server {
|
|
|
298
208
|
this.config.accessories.forEach((accessoryConfig, index) => {
|
|
299
209
|
if (!accessoryConfig.accessory) {
|
|
300
210
|
log.warn('Your config.json contains an illegal accessory configuration object at position %d. '
|
|
301
|
-
+ 'Missing property \'accessory\'. Skipping entry...', index + 1);
|
|
211
|
+
+ 'Missing property \'accessory\'. Skipping entry...', index + 1);
|
|
302
212
|
return;
|
|
303
213
|
}
|
|
304
214
|
const accessoryIdentifier = accessoryConfig.accessory;
|
|
@@ -316,7 +226,6 @@ export class Server {
|
|
|
316
226
|
log.error(error.message);
|
|
317
227
|
return;
|
|
318
228
|
}
|
|
319
|
-
// check the plugin is not disabled
|
|
320
229
|
if (plugin.disabled) {
|
|
321
230
|
log.warn(`Ignoring config for the accessory "${accessoryIdentifier}" in your config.json as the plugin "${plugin.getPluginIdentifier()}" has been disabled.`);
|
|
322
231
|
return;
|
|
@@ -326,16 +235,15 @@ export class Server {
|
|
|
326
235
|
}
|
|
327
236
|
catch (error) {
|
|
328
237
|
log.error(`Error loading the accessory "${accessoryIdentifier}" requested in your config.json at position ${index + 1} - this is likely an issue with the "${plugin.getPluginIdentifier()}" plugin.`);
|
|
329
|
-
log.error(error);
|
|
238
|
+
log.error(error);
|
|
330
239
|
return;
|
|
331
240
|
}
|
|
332
241
|
const logger = Logger.withPrefix(displayName);
|
|
333
242
|
logger('Initializing %s accessory...', accessoryIdentifier);
|
|
334
243
|
if (accessoryConfig._bridge) {
|
|
335
|
-
// ensure the username is always uppercase
|
|
336
244
|
accessoryConfig._bridge.username = accessoryConfig._bridge.username.toUpperCase();
|
|
337
245
|
try {
|
|
338
|
-
this.validateChildBridgeConfig("accessory"
|
|
246
|
+
this.validateChildBridgeConfig("accessory", accessoryIdentifier, accessoryConfig._bridge);
|
|
339
247
|
}
|
|
340
248
|
catch (error) {
|
|
341
249
|
log.error(error.message);
|
|
@@ -348,15 +256,13 @@ export class Server {
|
|
|
348
256
|
}
|
|
349
257
|
else {
|
|
350
258
|
logger(`Initializing child bridge ${accessoryConfig._bridge.username}`);
|
|
351
|
-
childBridge = new ChildBridgeService("accessory"
|
|
259
|
+
childBridge = new ChildBridgeService("accessory", accessoryIdentifier, plugin, accessoryConfig._bridge, this.config, this.options, this.api, this.ipcService, this.externalPortService);
|
|
352
260
|
this.childBridges.set(accessoryConfig._bridge.username, childBridge);
|
|
353
261
|
}
|
|
354
|
-
// add config to child bridge service
|
|
355
262
|
childBridge.addConfig(accessoryConfig);
|
|
356
263
|
return;
|
|
357
264
|
}
|
|
358
265
|
const accessoryInstance = new constructor(logger, accessoryConfig, this.api);
|
|
359
|
-
// pass accessoryIdentifier for UUID generation, and optional parameter uuid_base which can be used instead of displayName for UUID generation
|
|
360
266
|
const accessory = this.bridgeService.createHAPAccessory(plugin, accessoryInstance, displayName, accessoryIdentifier, accessoryConfig.uuid_base);
|
|
361
267
|
if (accessory) {
|
|
362
268
|
try {
|
|
@@ -377,14 +283,13 @@ export class Server {
|
|
|
377
283
|
this.config.platforms.forEach((platformConfig, index) => {
|
|
378
284
|
if (!platformConfig.platform) {
|
|
379
285
|
log.warn('Your config.json contains an illegal platform configuration object at position %d. '
|
|
380
|
-
+ 'Missing property \'platform\'. Skipping entry...', index + 1);
|
|
286
|
+
+ 'Missing property \'platform\'. Skipping entry...', index + 1);
|
|
381
287
|
return;
|
|
382
288
|
}
|
|
383
289
|
const platformIdentifier = platformConfig.platform;
|
|
384
290
|
const displayName = platformConfig.name || platformIdentifier;
|
|
385
291
|
let plugin;
|
|
386
292
|
let constructor;
|
|
387
|
-
// do not load homebridge-config-ui-x when running in service mode
|
|
388
293
|
if (platformIdentifier === 'config' && process.env.UIX_SERVICE_MODE === '1') {
|
|
389
294
|
return;
|
|
390
295
|
}
|
|
@@ -395,7 +300,6 @@ export class Server {
|
|
|
395
300
|
log.error(error.message);
|
|
396
301
|
return;
|
|
397
302
|
}
|
|
398
|
-
// check the plugin is not disabled
|
|
399
303
|
if (plugin.disabled) {
|
|
400
304
|
log.warn(`Ignoring config for the platform "${platformIdentifier}" in your config.json as the plugin "${plugin.getPluginIdentifier()}" has been disabled.`);
|
|
401
305
|
return;
|
|
@@ -405,25 +309,23 @@ export class Server {
|
|
|
405
309
|
}
|
|
406
310
|
catch (error) {
|
|
407
311
|
log.error(`Error loading the platform "${platformIdentifier}" requested in your config.json at position ${index + 1} - this is likely an issue with the "${plugin.getPluginIdentifier()}" plugin.`);
|
|
408
|
-
log.error(error);
|
|
312
|
+
log.error(error);
|
|
409
313
|
return;
|
|
410
314
|
}
|
|
411
315
|
const logger = Logger.withPrefix(displayName);
|
|
412
316
|
logger('Initializing %s platform...', platformIdentifier);
|
|
413
317
|
if (platformConfig._bridge) {
|
|
414
|
-
// ensure the username is always uppercase
|
|
415
318
|
platformConfig._bridge.username = platformConfig._bridge.username.toUpperCase();
|
|
416
319
|
try {
|
|
417
|
-
this.validateChildBridgeConfig("platform"
|
|
320
|
+
this.validateChildBridgeConfig("platform", platformIdentifier, platformConfig._bridge);
|
|
418
321
|
}
|
|
419
322
|
catch (error) {
|
|
420
323
|
log.error(error.message);
|
|
421
324
|
return;
|
|
422
325
|
}
|
|
423
326
|
logger(`Initializing child bridge ${platformConfig._bridge.username}`);
|
|
424
|
-
const childBridge = new ChildBridgeService("platform"
|
|
327
|
+
const childBridge = new ChildBridgeService("platform", platformIdentifier, plugin, platformConfig._bridge, this.config, this.options, this.api, this.ipcService, this.externalPortService);
|
|
425
328
|
this.childBridges.set(platformConfig._bridge.username, childBridge);
|
|
426
|
-
// add config to child bridge service
|
|
427
329
|
childBridge.addConfig(platformConfig);
|
|
428
330
|
return;
|
|
429
331
|
}
|
|
@@ -431,21 +333,15 @@ export class Server {
|
|
|
431
333
|
if (HomebridgeAPI.isDynamicPlatformPlugin(platform)) {
|
|
432
334
|
plugin.assignDynamicPlatform(platformIdentifier, platform);
|
|
433
335
|
}
|
|
434
|
-
else if (HomebridgeAPI.isStaticPlatformPlugin(platform)) {
|
|
336
|
+
else if (HomebridgeAPI.isStaticPlatformPlugin(platform)) {
|
|
435
337
|
promises.push(this.bridgeService.loadPlatformAccessories(plugin, platform, platformIdentifier, logger));
|
|
436
338
|
}
|
|
437
339
|
else {
|
|
438
|
-
// otherwise it's a IndependentPlatformPlugin which doesn't expose any methods at all.
|
|
439
|
-
// We just call the constructor and let it be enabled.
|
|
440
340
|
}
|
|
441
341
|
});
|
|
442
342
|
return promises;
|
|
443
343
|
}
|
|
444
|
-
/**
|
|
445
|
-
* Validate an external bridge config
|
|
446
|
-
*/
|
|
447
344
|
validateChildBridgeConfig(type, identifier, bridgeConfig) {
|
|
448
|
-
// All child bridges require username
|
|
449
345
|
if (!bridgeConfig.username) {
|
|
450
346
|
throw new Error(`Error loading the ${type} "${identifier}" requested in your config.json - `
|
|
451
347
|
+ 'Missing required field "_bridge.username".');
|
|
@@ -456,13 +352,11 @@ export class Server {
|
|
|
456
352
|
}
|
|
457
353
|
if (this.childBridges.has(bridgeConfig.username)) {
|
|
458
354
|
const childBridge = this.childBridges.get(bridgeConfig.username);
|
|
459
|
-
if (type === "platform"
|
|
460
|
-
// only a single platform can exist on one child bridge
|
|
355
|
+
if (type === "platform") {
|
|
461
356
|
throw new Error(`Error loading the ${type} "${identifier}" requested in your config.json - `
|
|
462
357
|
+ `Duplicate username found in _bridge.username: "${bridgeConfig.username}". Each platform child bridge must have it's own unique username.`);
|
|
463
358
|
}
|
|
464
359
|
else if (childBridge?.identifier !== identifier) {
|
|
465
|
-
// only accessories of the same type can be added to the same child bridge
|
|
466
360
|
throw new Error(`Error loading the ${type} "${identifier}" requested in your config.json - `
|
|
467
361
|
+ `Duplicate username found in _bridge.username: "${bridgeConfig.username}". You can only group accessories of the same type in a child bridge.`);
|
|
468
362
|
}
|
|
@@ -472,47 +366,301 @@ export class Server {
|
|
|
472
366
|
+ `Username found in _bridge.username: "${bridgeConfig.username}" is the same as the main bridge. Each child bridge platform/accessory must have it's own unique username.`);
|
|
473
367
|
}
|
|
474
368
|
}
|
|
475
|
-
/**
|
|
476
|
-
* Takes care of the IPC Events sent to Homebridge
|
|
477
|
-
*/
|
|
478
369
|
initializeIpcEventHandlers() {
|
|
479
|
-
// start ipc service
|
|
480
370
|
this.ipcService.start();
|
|
481
|
-
|
|
482
|
-
this.ipcService.on("restartChildBridge" /* IpcIncomingEvent.RESTART_CHILD_BRIDGE */, (username) => {
|
|
483
|
-
// noinspection SuspiciousTypeOfGuard
|
|
371
|
+
this.ipcService.on("restartChildBridge", (username) => {
|
|
484
372
|
if (typeof username === 'string') {
|
|
485
373
|
const childBridge = this.childBridges.get(username.toUpperCase());
|
|
486
374
|
childBridge?.restartChildBridge();
|
|
487
375
|
}
|
|
488
376
|
});
|
|
489
|
-
|
|
490
|
-
this.ipcService.on("stopChildBridge" /* IpcIncomingEvent.STOP_CHILD_BRIDGE */, (username) => {
|
|
491
|
-
// noinspection SuspiciousTypeOfGuard
|
|
377
|
+
this.ipcService.on("stopChildBridge", (username) => {
|
|
492
378
|
if (typeof username === 'string') {
|
|
493
379
|
const childBridge = this.childBridges.get(username.toUpperCase());
|
|
494
380
|
childBridge?.stopChildBridge();
|
|
495
381
|
}
|
|
496
382
|
});
|
|
497
|
-
|
|
498
|
-
this.ipcService.on("startChildBridge" /* IpcIncomingEvent.START_CHILD_BRIDGE */, (username) => {
|
|
499
|
-
// noinspection SuspiciousTypeOfGuard
|
|
383
|
+
this.ipcService.on("startChildBridge", (username) => {
|
|
500
384
|
if (typeof username === 'string') {
|
|
501
385
|
const childBridge = this.childBridges.get(username.toUpperCase());
|
|
502
386
|
childBridge?.startChildBridge();
|
|
503
387
|
}
|
|
504
388
|
});
|
|
505
|
-
this.ipcService.on("childBridgeMetadataRequest"
|
|
506
|
-
this.ipcService.sendMessage("childBridgeMetadataResponse"
|
|
389
|
+
this.ipcService.on("childBridgeMetadataRequest", () => {
|
|
390
|
+
this.ipcService.sendMessage("childBridgeMetadataResponse", Array.from(this.childBridges.values()).map(x => x.getMetadata()));
|
|
391
|
+
});
|
|
392
|
+
this.ipcService.on("startMatterMonitoring", () => {
|
|
393
|
+
this.handleStartMatterMonitoring();
|
|
394
|
+
});
|
|
395
|
+
this.ipcService.on("stopMatterMonitoring", () => {
|
|
396
|
+
this.handleStopMatterMonitoring();
|
|
397
|
+
});
|
|
398
|
+
this.ipcService.on("getMatterAccessories", (data) => {
|
|
399
|
+
this.handleGetMatterAccessories(data?.bridgeUsername);
|
|
400
|
+
});
|
|
401
|
+
this.ipcService.on("getMatterAccessoryInfo", (data) => {
|
|
402
|
+
this.handleGetMatterAccessoryInfo(data?.uuid);
|
|
403
|
+
});
|
|
404
|
+
this.ipcService.on("matterAccessoryControl", (data) => {
|
|
405
|
+
this.handleMatterAccessoryControl(data);
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
handleStartMatterMonitoring() {
|
|
409
|
+
this.matterMonitoringClients++;
|
|
410
|
+
if (this.matterMonitoringClients === 1) {
|
|
411
|
+
log.debug('Starting Matter accessory monitoring');
|
|
412
|
+
this.matterMonitoringActive = true;
|
|
413
|
+
this.matterManager?.enableStateMonitoring();
|
|
414
|
+
for (const childBridge of this.childBridges.values()) {
|
|
415
|
+
childBridge.startMatterMonitoring();
|
|
416
|
+
}
|
|
417
|
+
const event = {
|
|
418
|
+
type: 'monitoringStarted',
|
|
419
|
+
data: { success: true },
|
|
420
|
+
};
|
|
421
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
const event = {
|
|
425
|
+
type: 'monitoringStarted',
|
|
426
|
+
data: { success: true, alreadyActive: true },
|
|
427
|
+
};
|
|
428
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
handleStopMatterMonitoring() {
|
|
432
|
+
this.matterMonitoringClients--;
|
|
433
|
+
if (this.matterMonitoringClients <= 0) {
|
|
434
|
+
log.debug('Stopping Matter accessory monitoring');
|
|
435
|
+
this.matterMonitoringClients = 0;
|
|
436
|
+
this.matterMonitoringActive = false;
|
|
437
|
+
this.matterManager?.disableStateMonitoring();
|
|
438
|
+
for (const childBridge of this.childBridges.values()) {
|
|
439
|
+
childBridge.stopMatterMonitoring();
|
|
440
|
+
}
|
|
441
|
+
const event = {
|
|
442
|
+
type: 'monitoringStopped',
|
|
443
|
+
data: { success: true },
|
|
444
|
+
};
|
|
445
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
const event = {
|
|
449
|
+
type: 'monitoringStopped',
|
|
450
|
+
data: { success: true, othersActive: true },
|
|
451
|
+
};
|
|
452
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
async handleGetMatterAccessories(bridgeUsername) {
|
|
456
|
+
log.debug(`Getting Matter accessories${bridgeUsername ? ` for bridge ${bridgeUsername}` : ' for all bridges'}`);
|
|
457
|
+
if (!this.matterMonitoringActive) {
|
|
458
|
+
log.warn('Matter monitoring not active - cannot get accessories');
|
|
459
|
+
const event = {
|
|
460
|
+
type: 'accessoriesData',
|
|
461
|
+
data: {
|
|
462
|
+
bridgeUsername,
|
|
463
|
+
error: 'Matter monitoring not active',
|
|
464
|
+
},
|
|
465
|
+
};
|
|
466
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
if (!this.api.isMatterEnabled() && this.childBridges.size === 0) {
|
|
470
|
+
log.debug('Matter not enabled and no child bridges');
|
|
471
|
+
const event = {
|
|
472
|
+
type: 'accessoriesData',
|
|
473
|
+
data: {
|
|
474
|
+
bridgeUsername,
|
|
475
|
+
accessories: [],
|
|
476
|
+
},
|
|
477
|
+
};
|
|
478
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
try {
|
|
482
|
+
const allAccessories = this.matterManager?.collectAllAccessories(bridgeUsername) || [];
|
|
483
|
+
log.debug(`Collected ${allAccessories.length} accessories from main bridge`);
|
|
484
|
+
if (this.childBridges.size > 0) {
|
|
485
|
+
log.debug(`Requesting accessories from ${this.childBridges.size} child bridge(s)`);
|
|
486
|
+
for (const childBridge of this.childBridges.values()) {
|
|
487
|
+
childBridge.lastMatterAccessoriesResponse = undefined;
|
|
488
|
+
}
|
|
489
|
+
for (const childBridge of this.childBridges.values()) {
|
|
490
|
+
childBridge.getMatterAccessories();
|
|
491
|
+
}
|
|
492
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
493
|
+
let responsesCollected = 0;
|
|
494
|
+
for (const childBridge of this.childBridges.values()) {
|
|
495
|
+
if (childBridge.lastMatterAccessoriesResponse?.accessories) {
|
|
496
|
+
const accessories = childBridge.lastMatterAccessoriesResponse.accessories;
|
|
497
|
+
allAccessories.push(...accessories);
|
|
498
|
+
responsesCollected++;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
log.debug(`Collected responses from ${responsesCollected} of ${this.childBridges.size} child bridge(s)`);
|
|
502
|
+
}
|
|
503
|
+
log.debug(`Sending ${allAccessories.length} total Matter accessories`);
|
|
504
|
+
const event = {
|
|
505
|
+
type: 'accessoriesData',
|
|
506
|
+
data: {
|
|
507
|
+
bridgeUsername: bridgeUsername || 'all',
|
|
508
|
+
accessories: allAccessories,
|
|
509
|
+
},
|
|
510
|
+
};
|
|
511
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
512
|
+
}
|
|
513
|
+
catch (error) {
|
|
514
|
+
log.error('Failed to get Matter accessories:', error);
|
|
515
|
+
const event = {
|
|
516
|
+
type: 'accessoriesData',
|
|
517
|
+
data: {
|
|
518
|
+
bridgeUsername,
|
|
519
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
520
|
+
},
|
|
521
|
+
};
|
|
522
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
handleGetMatterAccessoryInfo(uuid) {
|
|
526
|
+
if (!uuid) {
|
|
527
|
+
const event = {
|
|
528
|
+
type: 'accessoryInfoData',
|
|
529
|
+
data: {
|
|
530
|
+
error: 'UUID is required',
|
|
531
|
+
},
|
|
532
|
+
};
|
|
533
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
try {
|
|
537
|
+
const accessoryInfo = this.matterManager?.getAccessoryInfo(uuid);
|
|
538
|
+
if (accessoryInfo) {
|
|
539
|
+
const event = {
|
|
540
|
+
type: 'accessoryInfoData',
|
|
541
|
+
data: accessoryInfo,
|
|
542
|
+
};
|
|
543
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
for (const childBridge of this.childBridges.values()) {
|
|
547
|
+
childBridge.getMatterAccessoryInfo(uuid);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
catch (error) {
|
|
551
|
+
log.error('Failed to get Matter accessory info:', error);
|
|
552
|
+
const event = {
|
|
553
|
+
type: 'accessoryInfoData',
|
|
554
|
+
data: {
|
|
555
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
556
|
+
},
|
|
557
|
+
};
|
|
558
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
handleMatterAccessoryControl(data) {
|
|
562
|
+
log.debug(`Matter control request: uuid=${data?.uuid}, cluster=${data?.cluster}, bridge=${data?.bridgeUsername || 'auto'}, part=${data?.partId || 'main'}`);
|
|
563
|
+
if (!data?.uuid || !data?.cluster || !data?.attributes) {
|
|
564
|
+
log.error('Missing required parameters for Matter control');
|
|
565
|
+
const event = {
|
|
566
|
+
type: 'accessoryControlResponse',
|
|
567
|
+
data: {
|
|
568
|
+
success: false,
|
|
569
|
+
error: 'Missing required parameters',
|
|
570
|
+
},
|
|
571
|
+
};
|
|
572
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
if (data.bridgeUsername) {
|
|
576
|
+
const targetUsername = data.bridgeUsername.toUpperCase();
|
|
577
|
+
if (targetUsername === this.config.bridge.username.toUpperCase()) {
|
|
578
|
+
log.debug(`Routing to main bridge (${targetUsername})`);
|
|
579
|
+
this.handleTriggerMatterCommand(data.uuid, data.cluster, data.attributes, data.partId)
|
|
580
|
+
.then(() => {
|
|
581
|
+
log.debug(`Main bridge successfully controlled accessory ${data.uuid}`);
|
|
582
|
+
const event = {
|
|
583
|
+
type: 'accessoryControlResponse',
|
|
584
|
+
data: {
|
|
585
|
+
success: true,
|
|
586
|
+
uuid: data.uuid,
|
|
587
|
+
},
|
|
588
|
+
};
|
|
589
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
590
|
+
})
|
|
591
|
+
.catch((error) => {
|
|
592
|
+
log.error(`Main bridge failed to control ${data.uuid}: ${error.message}`);
|
|
593
|
+
const event = {
|
|
594
|
+
type: 'accessoryControlResponse',
|
|
595
|
+
data: {
|
|
596
|
+
success: false,
|
|
597
|
+
error: error.message,
|
|
598
|
+
uuid: data.uuid,
|
|
599
|
+
},
|
|
600
|
+
};
|
|
601
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
602
|
+
});
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
for (const childBridge of this.childBridges.values()) {
|
|
606
|
+
if (childBridge.getMetadata().username.toUpperCase() === targetUsername) {
|
|
607
|
+
log.debug(`Routing to child bridge ${childBridge.identifier} (${targetUsername})`);
|
|
608
|
+
childBridge.controlMatterAccessory(data);
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
log.warn(`Bridge ${targetUsername} not found`);
|
|
613
|
+
const event = {
|
|
614
|
+
type: 'accessoryControlResponse',
|
|
615
|
+
data: {
|
|
616
|
+
success: false,
|
|
617
|
+
error: `Bridge ${targetUsername} not found`,
|
|
618
|
+
uuid: data.uuid,
|
|
619
|
+
},
|
|
620
|
+
};
|
|
621
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
log.debug(`Broadcast mode: trying main bridge for accessory ${data.uuid}`);
|
|
625
|
+
this.handleTriggerMatterCommand(data.uuid, data.cluster, data.attributes, data.partId)
|
|
626
|
+
.then(() => {
|
|
627
|
+
log.debug(`Main bridge successfully controlled accessory ${data.uuid}`);
|
|
628
|
+
const event = {
|
|
629
|
+
type: 'accessoryControlResponse',
|
|
630
|
+
data: {
|
|
631
|
+
success: true,
|
|
632
|
+
uuid: data.uuid,
|
|
633
|
+
},
|
|
634
|
+
};
|
|
635
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
636
|
+
})
|
|
637
|
+
.catch(() => {
|
|
638
|
+
log.debug(`Main bridge doesn't have accessory ${data.uuid}, forwarding to ${this.childBridges.size} child bridge(s)`);
|
|
639
|
+
if (this.childBridges.size > 0) {
|
|
640
|
+
for (const childBridge of this.childBridges.values()) {
|
|
641
|
+
childBridge.controlMatterAccessory(data);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
else {
|
|
645
|
+
log.warn(`Accessory ${data.uuid} not found - not on main bridge and no child bridges available`);
|
|
646
|
+
const event = {
|
|
647
|
+
type: 'accessoryControlResponse',
|
|
648
|
+
data: {
|
|
649
|
+
success: false,
|
|
650
|
+
error: 'Accessory not found',
|
|
651
|
+
uuid: data.uuid,
|
|
652
|
+
},
|
|
653
|
+
};
|
|
654
|
+
this.ipcService.sendMessage("matterEvent", event);
|
|
655
|
+
}
|
|
507
656
|
});
|
|
508
657
|
}
|
|
509
658
|
printSetupInfo(pin) {
|
|
510
|
-
/* eslint-disable no-console */
|
|
511
659
|
console.log('Setup Payload:');
|
|
512
660
|
console.log(this.bridgeService.bridge.setupURI());
|
|
513
661
|
if (!this.options.hideQRCode) {
|
|
514
662
|
console.log('Scan this code with your HomeKit app on your iOS device to pair with Homebridge:');
|
|
515
|
-
qrcode.setErrorLevel('M');
|
|
663
|
+
qrcode.setErrorLevel('M');
|
|
516
664
|
qrcode.generate(this.bridgeService.bridge.setupURI());
|
|
517
665
|
console.log('Or enter this code with your HomeKit app on your iOS device to pair with Homebridge:');
|
|
518
666
|
}
|
|
@@ -524,7 +672,6 @@ export class Server {
|
|
|
524
672
|
console.log(chalk.black.bgWhite(` │ ${pin} │ `));
|
|
525
673
|
console.log(chalk.black.bgWhite(' └────────────┘ '));
|
|
526
674
|
console.log(chalk.black.bgWhite(' '));
|
|
527
|
-
/* eslint-enable no-console */
|
|
528
675
|
}
|
|
529
676
|
}
|
|
530
677
|
//# sourceMappingURL=server.js.map
|