homebridge 2.0.0-beta.5 → 2.0.0-beta.50

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.
Files changed (286) hide show
  1. package/README.md +16 -17
  2. package/bin/homebridge.js +22 -0
  3. package/config-sample.json +3 -3
  4. package/dist/api.d.ts +137 -0
  5. package/dist/api.d.ts.map +1 -0
  6. package/dist/api.js +151 -0
  7. package/dist/api.js.map +1 -0
  8. package/{lib → dist}/bridgeService.d.ts +16 -32
  9. package/dist/bridgeService.d.ts.map +1 -0
  10. package/dist/bridgeService.js +341 -0
  11. package/dist/bridgeService.js.map +1 -0
  12. package/dist/childBridgeFork.d.ts +40 -0
  13. package/dist/childBridgeFork.d.ts.map +1 -0
  14. package/dist/childBridgeFork.js +362 -0
  15. package/dist/childBridgeFork.js.map +1 -0
  16. package/dist/childBridgeService.d.ts +146 -0
  17. package/dist/childBridgeService.d.ts.map +1 -0
  18. package/dist/childBridgeService.js +416 -0
  19. package/dist/childBridgeService.js.map +1 -0
  20. package/dist/cli.d.ts +3 -0
  21. package/dist/cli.d.ts.map +1 -0
  22. package/dist/cli.js +88 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/externalPortService.d.ts +26 -0
  25. package/dist/externalPortService.d.ts.map +1 -0
  26. package/dist/externalPortService.js +77 -0
  27. package/dist/externalPortService.js.map +1 -0
  28. package/dist/index.d.ts +29 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +9 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/ipcService.d.ts +58 -0
  33. package/dist/ipcService.d.ts.map +1 -0
  34. package/dist/ipcService.js +43 -0
  35. package/dist/ipcService.js.map +1 -0
  36. package/dist/logger.d.ts +38 -0
  37. package/dist/logger.d.ts.map +1 -0
  38. package/dist/logger.js +102 -0
  39. package/dist/logger.js.map +1 -0
  40. package/dist/matter/BaseMatterManager.d.ts +20 -0
  41. package/dist/matter/BaseMatterManager.d.ts.map +1 -0
  42. package/dist/matter/BaseMatterManager.js +183 -0
  43. package/dist/matter/BaseMatterManager.js.map +1 -0
  44. package/dist/matter/ChildBridgeMatterManager.d.ts +35 -0
  45. package/dist/matter/ChildBridgeMatterManager.d.ts.map +1 -0
  46. package/dist/matter/ChildBridgeMatterManager.js +222 -0
  47. package/dist/matter/ChildBridgeMatterManager.js.map +1 -0
  48. package/dist/matter/ClusterCommandMapper.d.ts +5 -0
  49. package/dist/matter/ClusterCommandMapper.d.ts.map +1 -0
  50. package/dist/matter/ClusterCommandMapper.js +222 -0
  51. package/dist/matter/ClusterCommandMapper.js.map +1 -0
  52. package/dist/matter/ExternalMatterAccessoryPublisher.d.ts +22 -0
  53. package/dist/matter/ExternalMatterAccessoryPublisher.d.ts.map +1 -0
  54. package/dist/matter/ExternalMatterAccessoryPublisher.js +49 -0
  55. package/dist/matter/ExternalMatterAccessoryPublisher.js.map +1 -0
  56. package/dist/matter/MatterAPIImpl.d.ts +443 -0
  57. package/dist/matter/MatterAPIImpl.d.ts.map +1 -0
  58. package/dist/matter/MatterAPIImpl.js +210 -0
  59. package/dist/matter/MatterAPIImpl.js.map +1 -0
  60. package/dist/matter/MatterBridgeManager.d.ts +40 -0
  61. package/dist/matter/MatterBridgeManager.d.ts.map +1 -0
  62. package/dist/matter/MatterBridgeManager.js +340 -0
  63. package/dist/matter/MatterBridgeManager.js.map +1 -0
  64. package/dist/matter/MatterConfigCollector.d.ts +7 -0
  65. package/dist/matter/MatterConfigCollector.d.ts.map +1 -0
  66. package/dist/matter/MatterConfigCollector.js +65 -0
  67. package/dist/matter/MatterConfigCollector.js.map +1 -0
  68. package/dist/matter/accessoryCache.d.ts +57 -0
  69. package/dist/matter/accessoryCache.d.ts.map +1 -0
  70. package/dist/matter/accessoryCache.js +155 -0
  71. package/dist/matter/accessoryCache.js.map +1 -0
  72. package/dist/matter/behaviors/AirQualityBehavior.d.ts +8 -0
  73. package/dist/matter/behaviors/AirQualityBehavior.d.ts.map +1 -0
  74. package/dist/matter/behaviors/AirQualityBehavior.js +11 -0
  75. package/dist/matter/behaviors/AirQualityBehavior.js.map +1 -0
  76. package/dist/matter/behaviors/BehaviorRegistry.d.ts +27 -0
  77. package/dist/matter/behaviors/BehaviorRegistry.d.ts.map +1 -0
  78. package/dist/matter/behaviors/BehaviorRegistry.js +110 -0
  79. package/dist/matter/behaviors/BehaviorRegistry.js.map +1 -0
  80. package/dist/matter/behaviors/ColorControlBehavior.d.ts +12 -0
  81. package/dist/matter/behaviors/ColorControlBehavior.d.ts.map +1 -0
  82. package/dist/matter/behaviors/ColorControlBehavior.js +139 -0
  83. package/dist/matter/behaviors/ColorControlBehavior.js.map +1 -0
  84. package/dist/matter/behaviors/ConcentrationMeasurementBehavior.d.ts +32 -0
  85. package/dist/matter/behaviors/ConcentrationMeasurementBehavior.d.ts.map +1 -0
  86. package/dist/matter/behaviors/ConcentrationMeasurementBehavior.js +51 -0
  87. package/dist/matter/behaviors/ConcentrationMeasurementBehavior.js.map +1 -0
  88. package/dist/matter/behaviors/DoorLockBehavior.d.ts +7 -0
  89. package/dist/matter/behaviors/DoorLockBehavior.d.ts.map +1 -0
  90. package/dist/matter/behaviors/DoorLockBehavior.js +48 -0
  91. package/dist/matter/behaviors/DoorLockBehavior.js.map +1 -0
  92. package/dist/matter/behaviors/FanControlBehavior.d.ts +7 -0
  93. package/dist/matter/behaviors/FanControlBehavior.d.ts.map +1 -0
  94. package/dist/matter/behaviors/FanControlBehavior.js +48 -0
  95. package/dist/matter/behaviors/FanControlBehavior.js.map +1 -0
  96. package/dist/matter/behaviors/IdentifyBehavior.d.ts +7 -0
  97. package/dist/matter/behaviors/IdentifyBehavior.d.ts.map +1 -0
  98. package/dist/matter/behaviors/IdentifyBehavior.js +25 -0
  99. package/dist/matter/behaviors/IdentifyBehavior.js.map +1 -0
  100. package/dist/matter/behaviors/LevelControlBehavior.d.ts +11 -0
  101. package/dist/matter/behaviors/LevelControlBehavior.d.ts.map +1 -0
  102. package/dist/matter/behaviors/LevelControlBehavior.js +100 -0
  103. package/dist/matter/behaviors/LevelControlBehavior.js.map +1 -0
  104. package/dist/matter/behaviors/OnOffBehavior.d.ts +8 -0
  105. package/dist/matter/behaviors/OnOffBehavior.d.ts.map +1 -0
  106. package/dist/matter/behaviors/OnOffBehavior.js +60 -0
  107. package/dist/matter/behaviors/OnOffBehavior.js.map +1 -0
  108. package/dist/matter/behaviors/RegistryManager.d.ts +15 -0
  109. package/dist/matter/behaviors/RegistryManager.d.ts.map +1 -0
  110. package/dist/matter/behaviors/RegistryManager.js +31 -0
  111. package/dist/matter/behaviors/RegistryManager.js.map +1 -0
  112. package/dist/matter/behaviors/RvcCleanModeBehavior.d.ts +14 -0
  113. package/dist/matter/behaviors/RvcCleanModeBehavior.d.ts.map +1 -0
  114. package/dist/matter/behaviors/RvcCleanModeBehavior.js +29 -0
  115. package/dist/matter/behaviors/RvcCleanModeBehavior.js.map +1 -0
  116. package/dist/matter/behaviors/RvcOperationalStateBehavior.d.ts +10 -0
  117. package/dist/matter/behaviors/RvcOperationalStateBehavior.d.ts.map +1 -0
  118. package/dist/matter/behaviors/RvcOperationalStateBehavior.js +81 -0
  119. package/dist/matter/behaviors/RvcOperationalStateBehavior.js.map +1 -0
  120. package/dist/matter/behaviors/RvcRunModeBehavior.d.ts +14 -0
  121. package/dist/matter/behaviors/RvcRunModeBehavior.d.ts.map +1 -0
  122. package/dist/matter/behaviors/RvcRunModeBehavior.js +29 -0
  123. package/dist/matter/behaviors/RvcRunModeBehavior.js.map +1 -0
  124. package/dist/matter/behaviors/ServiceAreaBehavior.d.ts +9 -0
  125. package/dist/matter/behaviors/ServiceAreaBehavior.d.ts.map +1 -0
  126. package/dist/matter/behaviors/ServiceAreaBehavior.js +62 -0
  127. package/dist/matter/behaviors/ServiceAreaBehavior.js.map +1 -0
  128. package/dist/matter/behaviors/ThermostatBehavior.d.ts +9 -0
  129. package/dist/matter/behaviors/ThermostatBehavior.d.ts.map +1 -0
  130. package/dist/matter/behaviors/ThermostatBehavior.js +92 -0
  131. package/dist/matter/behaviors/ThermostatBehavior.js.map +1 -0
  132. package/dist/matter/behaviors/WindowCoveringBehavior.d.ts +12 -0
  133. package/dist/matter/behaviors/WindowCoveringBehavior.d.ts.map +1 -0
  134. package/dist/matter/behaviors/WindowCoveringBehavior.js +108 -0
  135. package/dist/matter/behaviors/WindowCoveringBehavior.js.map +1 -0
  136. package/dist/matter/behaviors/index.d.ts +18 -0
  137. package/dist/matter/behaviors/index.d.ts.map +1 -0
  138. package/dist/matter/behaviors/index.js +17 -0
  139. package/dist/matter/behaviors/index.js.map +1 -0
  140. package/dist/matter/clusterTypes.d.ts +178 -0
  141. package/dist/matter/clusterTypes.d.ts.map +1 -0
  142. package/dist/matter/clusterTypes.js +2 -0
  143. package/dist/matter/clusterTypes.js.map +1 -0
  144. package/dist/matter/configValidator.d.ts +26 -0
  145. package/dist/matter/configValidator.d.ts.map +1 -0
  146. package/dist/matter/configValidator.js +173 -0
  147. package/dist/matter/configValidator.js.map +1 -0
  148. package/dist/matter/errorHandler.d.ts +11 -0
  149. package/dist/matter/errorHandler.d.ts.map +1 -0
  150. package/dist/matter/errorHandler.js +81 -0
  151. package/dist/matter/errorHandler.js.map +1 -0
  152. package/dist/matter/errors.d.ts +46 -0
  153. package/dist/matter/errors.d.ts.map +1 -0
  154. package/dist/matter/errors.js +68 -0
  155. package/dist/matter/errors.js.map +1 -0
  156. package/dist/matter/index.d.ts +97 -0
  157. package/dist/matter/index.d.ts.map +1 -0
  158. package/dist/matter/index.js +10 -0
  159. package/dist/matter/index.js.map +1 -0
  160. package/dist/matter/logFormatter.d.ts +2 -0
  161. package/dist/matter/logFormatter.d.ts.map +1 -0
  162. package/dist/matter/logFormatter.js +100 -0
  163. package/dist/matter/logFormatter.js.map +1 -0
  164. package/dist/matter/managerTypes.d.ts +57 -0
  165. package/dist/matter/managerTypes.d.ts.map +1 -0
  166. package/dist/matter/managerTypes.js +2 -0
  167. package/dist/matter/managerTypes.js.map +1 -0
  168. package/dist/matter/server.d.ts +112 -0
  169. package/dist/matter/server.d.ts.map +1 -0
  170. package/dist/matter/server.js +1508 -0
  171. package/dist/matter/server.js.map +1 -0
  172. package/dist/matter/serverHelpers.d.ts +31 -0
  173. package/dist/matter/serverHelpers.d.ts.map +1 -0
  174. package/dist/matter/serverHelpers.js +273 -0
  175. package/dist/matter/serverHelpers.js.map +1 -0
  176. package/dist/matter/sharedTypes.d.ts +93 -0
  177. package/dist/matter/sharedTypes.d.ts.map +1 -0
  178. package/dist/matter/sharedTypes.js +20 -0
  179. package/dist/matter/sharedTypes.js.map +1 -0
  180. package/dist/matter/storage.d.ts +45 -0
  181. package/dist/matter/storage.d.ts.map +1 -0
  182. package/dist/matter/storage.js +325 -0
  183. package/dist/matter/storage.js.map +1 -0
  184. package/dist/matter/typeHelpers.d.ts +15 -0
  185. package/dist/matter/typeHelpers.d.ts.map +1 -0
  186. package/dist/matter/typeHelpers.js +33 -0
  187. package/dist/matter/typeHelpers.js.map +1 -0
  188. package/dist/matter/types.d.ts +565 -0
  189. package/dist/matter/types.d.ts.map +1 -0
  190. package/dist/matter/types.js +132 -0
  191. package/dist/matter/types.js.map +1 -0
  192. package/dist/matter/utils.d.ts +13 -0
  193. package/dist/matter/utils.d.ts.map +1 -0
  194. package/dist/matter/utils.js +21 -0
  195. package/dist/matter/utils.js.map +1 -0
  196. package/{lib → dist}/platformAccessory.d.ts +8 -21
  197. package/dist/platformAccessory.d.ts.map +1 -0
  198. package/dist/platformAccessory.js +79 -0
  199. package/dist/platformAccessory.js.map +1 -0
  200. package/{lib → dist}/plugin.d.ts +2 -6
  201. package/dist/plugin.d.ts.map +1 -0
  202. package/dist/plugin.js +159 -0
  203. package/dist/plugin.js.map +1 -0
  204. package/{lib → dist}/pluginManager.d.ts +3 -25
  205. package/dist/pluginManager.d.ts.map +1 -0
  206. package/{lib → dist}/pluginManager.js +87 -115
  207. package/dist/pluginManager.js.map +1 -0
  208. package/{lib → dist}/server.d.ts +15 -20
  209. package/dist/server.d.ts.map +1 -0
  210. package/dist/server.js +732 -0
  211. package/dist/server.js.map +1 -0
  212. package/{lib → dist}/storageService.d.ts.map +1 -1
  213. package/dist/storageService.js +41 -0
  214. package/dist/storageService.js.map +1 -0
  215. package/{lib → dist}/user.d.ts +1 -3
  216. package/dist/user.d.ts.map +1 -0
  217. package/dist/user.js +29 -0
  218. package/dist/user.js.map +1 -0
  219. package/{lib → dist}/util/mac.d.ts +1 -0
  220. package/dist/util/mac.d.ts.map +1 -0
  221. package/dist/util/mac.js +13 -0
  222. package/dist/util/mac.js.map +1 -0
  223. package/dist/version.d.ts.map +1 -0
  224. package/dist/version.js +16 -0
  225. package/dist/version.js.map +1 -0
  226. package/package.json +49 -50
  227. package/bin/homebridge +0 -17
  228. package/lib/api.d.ts +0 -210
  229. package/lib/api.d.ts.map +0 -1
  230. package/lib/api.js +0 -155
  231. package/lib/api.js.map +0 -1
  232. package/lib/bridgeService.d.ts.map +0 -1
  233. package/lib/bridgeService.js +0 -426
  234. package/lib/bridgeService.js.map +0 -1
  235. package/lib/childBridgeFork.d.ts +0 -37
  236. package/lib/childBridgeFork.d.ts.map +0 -1
  237. package/lib/childBridgeFork.js +0 -244
  238. package/lib/childBridgeFork.js.map +0 -1
  239. package/lib/childBridgeService.d.ts +0 -199
  240. package/lib/childBridgeService.d.ts.map +0 -1
  241. package/lib/childBridgeService.js +0 -428
  242. package/lib/childBridgeService.js.map +0 -1
  243. package/lib/cli.d.ts +0 -4
  244. package/lib/cli.d.ts.map +0 -1
  245. package/lib/cli.js +0 -111
  246. package/lib/cli.js.map +0 -1
  247. package/lib/externalPortService.d.ts +0 -33
  248. package/lib/externalPortService.d.ts.map +0 -1
  249. package/lib/externalPortService.js +0 -64
  250. package/lib/externalPortService.js.map +0 -1
  251. package/lib/index.d.ts +0 -76
  252. package/lib/index.d.ts.map +0 -1
  253. package/lib/index.js +0 -72
  254. package/lib/index.js.map +0 -1
  255. package/lib/ipcService.d.ts +0 -33
  256. package/lib/ipcService.d.ts.map +0 -1
  257. package/lib/ipcService.js +0 -49
  258. package/lib/ipcService.js.map +0 -1
  259. package/lib/logger.d.ts +0 -78
  260. package/lib/logger.d.ts.map +0 -1
  261. package/lib/logger.js +0 -147
  262. package/lib/logger.js.map +0 -1
  263. package/lib/platformAccessory.d.ts.map +0 -1
  264. package/lib/platformAccessory.js +0 -102
  265. package/lib/platformAccessory.js.map +0 -1
  266. package/lib/plugin.d.ts.map +0 -1
  267. package/lib/plugin.js +0 -194
  268. package/lib/plugin.js.map +0 -1
  269. package/lib/pluginManager.d.ts.map +0 -1
  270. package/lib/pluginManager.js.map +0 -1
  271. package/lib/server.d.ts.map +0 -1
  272. package/lib/server.js +0 -457
  273. package/lib/server.js.map +0 -1
  274. package/lib/storageService.js +0 -70
  275. package/lib/storageService.js.map +0 -1
  276. package/lib/user.d.ts.map +0 -1
  277. package/lib/user.js +0 -36
  278. package/lib/user.js.map +0 -1
  279. package/lib/util/mac.d.ts.map +0 -1
  280. package/lib/util/mac.js +0 -20
  281. package/lib/util/mac.js.map +0 -1
  282. package/lib/version.d.ts.map +0 -1
  283. package/lib/version.js +0 -21
  284. package/lib/version.js.map +0 -1
  285. /package/{lib → dist}/storageService.d.ts +0 -0
  286. /package/{lib → dist}/version.d.ts +0 -0
package/dist/server.js ADDED
@@ -0,0 +1,732 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import process from 'node:process';
3
+ import chalk from 'chalk';
4
+ import qrcode from 'qrcode-terminal';
5
+ import { HomebridgeAPI } from './api.js';
6
+ import { BridgeService } from './bridgeService.js';
7
+ import { ChildBridgeService } from './childBridgeService.js';
8
+ import { ExternalPortService } from './externalPortService.js';
9
+ import { IpcService } from './ipcService.js';
10
+ import { Logger } from './logger.js';
11
+ import { MatterBridgeManager, MatterConfigCollector } from './matter/index.js';
12
+ import { PluginManager } from './pluginManager.js';
13
+ import { User } from './user.js';
14
+ import { validMacAddress } from './util/mac.js';
15
+ const log = Logger.internal;
16
+ const matterLogger = Logger.withPrefix('Matter/MainManager');
17
+ export var ServerStatus;
18
+ (function (ServerStatus) {
19
+ ServerStatus["PENDING"] = "pending";
20
+ ServerStatus["OK"] = "ok";
21
+ ServerStatus["DOWN"] = "down";
22
+ })(ServerStatus || (ServerStatus = {}));
23
+ export class Server {
24
+ options;
25
+ api;
26
+ pluginManager;
27
+ bridgeService;
28
+ ipcService;
29
+ externalPortService;
30
+ config;
31
+ childBridges = new Map();
32
+ matterManager;
33
+ externalMatterBridgeRegistry = new Map();
34
+ matterMonitoringActive = false;
35
+ matterMonitoringClients = 0;
36
+ serverStatus = "pending";
37
+ constructor(options = {}) {
38
+ this.options = options;
39
+ this.config = Server.loadConfig();
40
+ this.api = new HomebridgeAPI();
41
+ this.ipcService = new IpcService();
42
+ const configuredMatterPorts = MatterBridgeManager.collectConfiguredMatterPorts(this.config);
43
+ this.externalPortService = new ExternalPortService(this.config.ports, this.config.matterPorts, configuredMatterPorts);
44
+ this.setServerStatus("pending");
45
+ const pluginManagerOptions = {
46
+ activePlugins: this.config.plugins,
47
+ disabledPlugins: this.config.disabledPlugins,
48
+ customPluginPath: options.customPluginPath,
49
+ strictPluginResolution: options.strictPluginResolution,
50
+ };
51
+ this.pluginManager = new PluginManager(this.api, pluginManagerOptions);
52
+ const bridgeConfig = {
53
+ cachedAccessoriesDir: User.cachedAccessoryPath(),
54
+ cachedAccessoriesItemName: 'cachedAccessories',
55
+ };
56
+ Object.assign(bridgeConfig, this.options);
57
+ this.bridgeService = new BridgeService(this.api, this.pluginManager, this.externalPortService, bridgeConfig, this.config.bridge);
58
+ this.matterManager = new MatterBridgeManager(this.config, this.api, this.externalPortService, this.pluginManager, this.options, this);
59
+ this.api._setMatterManager(this.matterManager);
60
+ this.api.on("registerPlatformAccessories", this.handleRegisterPlatformAccessories.bind(this));
61
+ this.api.on("unregisterPlatformAccessories", this.handleUnregisterPlatformAccessories.bind(this));
62
+ this.api.on("publishExternalAccessories", this.handlePublishExternalAccessories.bind(this));
63
+ this.bridgeService.bridge.on("advertised", () => {
64
+ this.setServerStatus("ok");
65
+ });
66
+ this.bridgeService.bridge.on("paired", () => {
67
+ this.setServerStatus(this.serverStatus);
68
+ });
69
+ this.bridgeService.bridge.on("unpaired", () => {
70
+ this.setServerStatus(this.serverStatus);
71
+ });
72
+ }
73
+ setServerStatus(status) {
74
+ this.serverStatus = status;
75
+ const statusUpdate = {
76
+ status: this.serverStatus,
77
+ paired: this.bridgeService?.bridge?._accessoryInfo?.paired() ?? null,
78
+ setupUri: this.bridgeService?.bridge?.setupURI() ?? null,
79
+ name: this.config.bridge.name,
80
+ username: this.config.bridge.username,
81
+ pin: this.config.bridge.pin,
82
+ matter: this.matterManager?.getMatterStatus() ?? { enabled: false },
83
+ };
84
+ this.ipcService.sendMessage("serverStatusUpdate", statusUpdate);
85
+ }
86
+ async start() {
87
+ if (this.config.bridge.disableIpc !== true) {
88
+ this.initializeIpcEventHandlers();
89
+ }
90
+ const promises = [];
91
+ await this.bridgeService.loadCachedPlatformAccessoriesFromDisk();
92
+ await this.pluginManager.initializeInstalledPlugins();
93
+ await this.matterManager?.initialize();
94
+ if (this.config.platforms.length > 0) {
95
+ promises.push(...this.loadPlatforms());
96
+ }
97
+ if (this.config.accessories.length > 0) {
98
+ this.loadAccessories();
99
+ }
100
+ for (const childBridge of this.childBridges.values()) {
101
+ childBridge.start();
102
+ }
103
+ this.bridgeService.restoreCachedPlatformAccessories();
104
+ this.matterManager?.restoreCachedAccessories(this.options.keepOrphanedCachedAccessories ?? false);
105
+ this.api.signalFinished();
106
+ await Promise.all(promises);
107
+ await this.publishBridge();
108
+ }
109
+ async teardown() {
110
+ this.bridgeService.teardown();
111
+ await this.matterManager?.teardown();
112
+ this.setServerStatus("down");
113
+ }
114
+ publishBridge() {
115
+ this.bridgeService.publishBridge();
116
+ this.printSetupInfo(this.config.bridge.pin);
117
+ }
118
+ handlePublishExternalAccessories(accessories) {
119
+ log.info(`Publishing ${accessories.length} external accessories`);
120
+ }
121
+ handleRegisterPlatformAccessories(accessories) {
122
+ this.bridgeService.handleRegisterPlatformAccessories(accessories);
123
+ }
124
+ handleUnregisterPlatformAccessories(accessories) {
125
+ this.bridgeService.handleUnregisterPlatformAccessories(accessories);
126
+ }
127
+ async handleTriggerMatterCommand(uuid, cluster, attributes, partId) {
128
+ if (!this.matterManager) {
129
+ throw new Error('Matter manager not initialized');
130
+ }
131
+ await this.matterManager.handleTriggerCommand(uuid, cluster, attributes, partId);
132
+ }
133
+ static loadConfig() {
134
+ const configPath = User.configPath();
135
+ const defaultBridge = {
136
+ name: 'Homebridge',
137
+ username: 'CC:22:3D:E3:CE:30',
138
+ pin: '031-45-154',
139
+ };
140
+ if (!existsSync(configPath)) {
141
+ log.warn('config.json (%s) not found.', configPath);
142
+ return {
143
+ bridge: defaultBridge,
144
+ accessories: [],
145
+ platforms: [],
146
+ };
147
+ }
148
+ let config;
149
+ try {
150
+ config = JSON.parse(readFileSync(configPath, { encoding: 'utf8' }));
151
+ }
152
+ catch (error) {
153
+ log.error('There was a problem reading your config.json file.');
154
+ log.error('Please try pasting your config.json file here to validate it: https://jsonlint.com');
155
+ log.error('');
156
+ throw error;
157
+ }
158
+ if (config.ports !== undefined) {
159
+ if (config.ports.start && config.ports.end) {
160
+ if (config.ports.start > config.ports.end) {
161
+ log.error('Invalid port pool configuration. End should be greater than or equal to start.');
162
+ config.ports = undefined;
163
+ }
164
+ }
165
+ else {
166
+ log.error('Invalid configuration for \'ports\'. Missing \'start\' and \'end\' properties! Ignoring it!');
167
+ config.ports = undefined;
168
+ }
169
+ }
170
+ MatterConfigCollector.validateMatterPortsPool(config);
171
+ const bridge = config.bridge || defaultBridge;
172
+ bridge.name = bridge.name || defaultBridge.name;
173
+ bridge.username = bridge.username || defaultBridge.username;
174
+ bridge.pin = bridge.pin || defaultBridge.pin;
175
+ config.bridge = bridge;
176
+ const username = config.bridge.username;
177
+ if (!validMacAddress(username)) {
178
+ throw new Error(`Not a valid username: ${username}. Must be 6 pairs of colon-separated hexadecimal chars (A-F 0-9), like a MAC address.`);
179
+ }
180
+ config.accessories = config.accessories || [];
181
+ config.platforms = config.platforms || [];
182
+ if (!Array.isArray(config.accessories)) {
183
+ log.error('Value provided for accessories must be an array[]');
184
+ config.accessories = [];
185
+ }
186
+ if (!Array.isArray(config.platforms)) {
187
+ log.error('Value provided for platforms must be an array[]');
188
+ config.platforms = [];
189
+ }
190
+ log.info('Loaded config.json with %s accessories and %s platforms.', config.accessories.length, config.platforms.length);
191
+ MatterConfigCollector.validateMatterConfig(config);
192
+ if (config.bridge.advertiser) {
193
+ if (![
194
+ "bonjour-hap",
195
+ "ciao",
196
+ "avahi",
197
+ "resolved",
198
+ ].includes(config.bridge.advertiser)) {
199
+ config.bridge.advertiser = undefined;
200
+ log.error('Value provided in bridge.advertiser is not valid, reverting to platform default.');
201
+ }
202
+ }
203
+ else {
204
+ config.bridge.advertiser = undefined;
205
+ }
206
+ return config;
207
+ }
208
+ loadAccessories() {
209
+ log.info(`Loading ${this.config.accessories.length} accessories...`);
210
+ this.config.accessories.forEach((accessoryConfig, index) => {
211
+ if (!accessoryConfig.accessory) {
212
+ log.warn('Your config.json contains an illegal accessory configuration object at position %d. '
213
+ + 'Missing property \'accessory\'. Skipping entry...', index + 1);
214
+ return;
215
+ }
216
+ const accessoryIdentifier = accessoryConfig.accessory;
217
+ const displayName = accessoryConfig.name;
218
+ if (!displayName) {
219
+ log.warn('Could not load accessory %s at position %d as it is missing the required \'name\' property!', accessoryIdentifier, index + 1);
220
+ return;
221
+ }
222
+ let plugin;
223
+ let constructor;
224
+ try {
225
+ plugin = this.pluginManager.getPluginForAccessory(accessoryIdentifier);
226
+ }
227
+ catch (error) {
228
+ log.error(error.message);
229
+ return;
230
+ }
231
+ if (plugin.disabled) {
232
+ log.warn(`Ignoring config for the accessory "${accessoryIdentifier}" in your config.json as the plugin "${plugin.getPluginIdentifier()}" has been disabled.`);
233
+ return;
234
+ }
235
+ try {
236
+ constructor = plugin.getAccessoryConstructor(accessoryIdentifier);
237
+ }
238
+ catch (error) {
239
+ 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.`);
240
+ log.error(error);
241
+ return;
242
+ }
243
+ const logger = Logger.withPrefix(displayName);
244
+ logger('Initializing %s accessory...', accessoryIdentifier);
245
+ if (accessoryConfig._bridge) {
246
+ accessoryConfig._bridge.username = accessoryConfig._bridge.username.toUpperCase();
247
+ try {
248
+ this.validateChildBridgeConfig("accessory", accessoryIdentifier, accessoryConfig._bridge);
249
+ }
250
+ catch (error) {
251
+ log.error(error.message);
252
+ return;
253
+ }
254
+ let childBridge;
255
+ if (this.childBridges.has(accessoryConfig._bridge.username)) {
256
+ childBridge = this.childBridges.get(accessoryConfig._bridge.username);
257
+ logger(`Adding to existing child bridge ${accessoryConfig._bridge.username}`);
258
+ }
259
+ else {
260
+ logger(`Initializing child bridge ${accessoryConfig._bridge.username}`);
261
+ childBridge = new ChildBridgeService("accessory", accessoryIdentifier, plugin, accessoryConfig._bridge, this.config, this.options, this.api, this.ipcService, this.externalPortService);
262
+ childBridge.onExternalBridgeRegistered = this.registerExternalMatterBridge.bind(this);
263
+ this.childBridges.set(accessoryConfig._bridge.username, childBridge);
264
+ }
265
+ childBridge.addConfig(accessoryConfig);
266
+ return;
267
+ }
268
+ const accessoryInstance = new constructor(logger, accessoryConfig, this.api);
269
+ const accessory = this.bridgeService.createHAPAccessory(plugin, accessoryInstance, displayName, accessoryIdentifier, accessoryConfig.uuid_base);
270
+ if (accessory) {
271
+ try {
272
+ this.bridgeService.bridge.addBridgedAccessory(accessory);
273
+ }
274
+ catch (error) {
275
+ logger.error(`Error loading the accessory "${accessoryIdentifier}" from "${plugin.getPluginIdentifier()}" requested in your config.json:`, error.message);
276
+ }
277
+ }
278
+ else {
279
+ logger.info('Accessory %s returned empty set of services; not adding it to the bridge.', accessoryIdentifier);
280
+ }
281
+ });
282
+ }
283
+ loadPlatforms() {
284
+ log.info(`Loading ${this.config.platforms.length} platforms...`);
285
+ const promises = [];
286
+ this.config.platforms.forEach((platformConfig, index) => {
287
+ if (!platformConfig.platform) {
288
+ log.warn('Your config.json contains an illegal platform configuration object at position %d. '
289
+ + 'Missing property \'platform\'. Skipping entry...', index + 1);
290
+ return;
291
+ }
292
+ const platformIdentifier = platformConfig.platform;
293
+ const displayName = platformConfig.name || platformIdentifier;
294
+ let plugin;
295
+ let constructor;
296
+ if (platformIdentifier === 'config' && process.env.UIX_SERVICE_MODE === '1') {
297
+ return;
298
+ }
299
+ try {
300
+ plugin = this.pluginManager.getPluginForPlatform(platformIdentifier);
301
+ }
302
+ catch (error) {
303
+ log.error(error.message);
304
+ return;
305
+ }
306
+ if (plugin.disabled) {
307
+ log.warn(`Ignoring config for the platform "${platformIdentifier}" in your config.json as the plugin "${plugin.getPluginIdentifier()}" has been disabled.`);
308
+ return;
309
+ }
310
+ try {
311
+ constructor = plugin.getPlatformConstructor(platformIdentifier);
312
+ }
313
+ catch (error) {
314
+ 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.`);
315
+ log.error(error);
316
+ return;
317
+ }
318
+ const logger = Logger.withPrefix(displayName);
319
+ logger('Initializing %s platform...', platformIdentifier);
320
+ if (platformConfig._bridge) {
321
+ platformConfig._bridge.username = platformConfig._bridge.username.toUpperCase();
322
+ try {
323
+ this.validateChildBridgeConfig("platform", platformIdentifier, platformConfig._bridge);
324
+ }
325
+ catch (error) {
326
+ log.error(error.message);
327
+ return;
328
+ }
329
+ logger(`Initializing child bridge ${platformConfig._bridge.username}`);
330
+ const childBridge = new ChildBridgeService("platform", platformIdentifier, plugin, platformConfig._bridge, this.config, this.options, this.api, this.ipcService, this.externalPortService);
331
+ childBridge.onExternalBridgeRegistered = this.registerExternalMatterBridge.bind(this);
332
+ this.childBridges.set(platformConfig._bridge.username, childBridge);
333
+ childBridge.addConfig(platformConfig);
334
+ return;
335
+ }
336
+ const platform = new constructor(logger, platformConfig, this.api);
337
+ if (HomebridgeAPI.isDynamicPlatformPlugin(platform)) {
338
+ plugin.assignDynamicPlatform(platformIdentifier, platform);
339
+ }
340
+ else if (HomebridgeAPI.isStaticPlatformPlugin(platform)) {
341
+ promises.push(this.bridgeService.loadPlatformAccessories(plugin, platform, platformIdentifier, logger));
342
+ }
343
+ else {
344
+ }
345
+ });
346
+ return promises;
347
+ }
348
+ validateChildBridgeConfig(type, identifier, bridgeConfig) {
349
+ if (!bridgeConfig.username) {
350
+ throw new Error(`Error loading the ${type} "${identifier}" requested in your config.json - `
351
+ + 'Missing required field "_bridge.username".');
352
+ }
353
+ if (!validMacAddress(bridgeConfig.username)) {
354
+ throw new Error(`Error loading the ${type} "${identifier}" requested in your config.json - `
355
+ + `not a valid username in _bridge.username: "${bridgeConfig.username}". Must be 6 pairs of colon-separated hexadecimal chars (A-F 0-9), like a MAC address.`);
356
+ }
357
+ if (this.childBridges.has(bridgeConfig.username)) {
358
+ const childBridge = this.childBridges.get(bridgeConfig.username);
359
+ if (type === "platform") {
360
+ throw new Error(`Error loading the ${type} "${identifier}" requested in your config.json - `
361
+ + `Duplicate username found in _bridge.username: "${bridgeConfig.username}". Each platform child bridge must have it's own unique username.`);
362
+ }
363
+ else if (childBridge?.identifier !== identifier) {
364
+ throw new Error(`Error loading the ${type} "${identifier}" requested in your config.json - `
365
+ + `Duplicate username found in _bridge.username: "${bridgeConfig.username}". You can only group accessories of the same type in a child bridge.`);
366
+ }
367
+ }
368
+ if (bridgeConfig.username === this.config.bridge.username.toUpperCase()) {
369
+ throw new Error(`Error loading the ${type} "${identifier}" requested in your config.json - `
370
+ + `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.`);
371
+ }
372
+ }
373
+ initializeIpcEventHandlers() {
374
+ this.ipcService.start();
375
+ this.ipcService.on("restartChildBridge", (username) => {
376
+ if (typeof username === 'string') {
377
+ const childBridge = this.childBridges.get(username.toUpperCase());
378
+ childBridge?.restartChildBridge();
379
+ }
380
+ });
381
+ this.ipcService.on("stopChildBridge", (username) => {
382
+ if (typeof username === 'string') {
383
+ const childBridge = this.childBridges.get(username.toUpperCase());
384
+ childBridge?.stopChildBridge();
385
+ }
386
+ });
387
+ this.ipcService.on("startChildBridge", (username) => {
388
+ if (typeof username === 'string') {
389
+ const childBridge = this.childBridges.get(username.toUpperCase());
390
+ childBridge?.startChildBridge();
391
+ }
392
+ });
393
+ this.ipcService.on("childBridgeMetadataRequest", () => {
394
+ this.ipcService.sendMessage("childBridgeMetadataResponse", Array.from(this.childBridges.values()).map(x => x.getMetadata()));
395
+ });
396
+ this.ipcService.on("startMatterMonitoring", () => {
397
+ this.handleStartMatterMonitoring();
398
+ });
399
+ this.ipcService.on("stopMatterMonitoring", () => {
400
+ this.handleStopMatterMonitoring();
401
+ });
402
+ this.ipcService.on("getMatterAccessories", (data) => {
403
+ this.handleGetMatterAccessories(data?.bridgeUsername);
404
+ });
405
+ this.ipcService.on("getMatterAccessoryInfo", (data) => {
406
+ this.handleGetMatterAccessoryInfo(data?.uuid);
407
+ });
408
+ this.ipcService.on("matterAccessoryControl", (data) => {
409
+ this.handleMatterAccessoryControl(data);
410
+ });
411
+ }
412
+ handleStartMatterMonitoring() {
413
+ this.matterMonitoringClients++;
414
+ if (this.matterMonitoringClients === 1) {
415
+ matterLogger.debug('Starting Matter accessory monitoring');
416
+ this.matterMonitoringActive = true;
417
+ this.matterManager?.enableStateMonitoring();
418
+ for (const childBridge of this.childBridges.values()) {
419
+ childBridge.startMatterMonitoring();
420
+ }
421
+ const event = {
422
+ type: 'monitoringStarted',
423
+ data: { success: true },
424
+ };
425
+ this.ipcService.sendMessage("matterEvent", event);
426
+ }
427
+ else {
428
+ const event = {
429
+ type: 'monitoringStarted',
430
+ data: { success: true, alreadyActive: true },
431
+ };
432
+ this.ipcService.sendMessage("matterEvent", event);
433
+ }
434
+ }
435
+ handleStopMatterMonitoring() {
436
+ this.matterMonitoringClients--;
437
+ if (this.matterMonitoringClients <= 0) {
438
+ matterLogger.debug('Stopping Matter accessory monitoring');
439
+ this.matterMonitoringClients = 0;
440
+ this.matterMonitoringActive = false;
441
+ this.matterManager?.disableStateMonitoring();
442
+ for (const childBridge of this.childBridges.values()) {
443
+ childBridge.stopMatterMonitoring();
444
+ }
445
+ const event = {
446
+ type: 'monitoringStopped',
447
+ data: { success: true },
448
+ };
449
+ this.ipcService.sendMessage("matterEvent", event);
450
+ }
451
+ else {
452
+ const event = {
453
+ type: 'monitoringStopped',
454
+ data: { success: true, othersActive: true },
455
+ };
456
+ this.ipcService.sendMessage("matterEvent", event);
457
+ }
458
+ }
459
+ registerExternalMatterBridge(externalBridgeUsername, ownerUsername) {
460
+ const normalizedExternal = externalBridgeUsername.toUpperCase();
461
+ const normalizedOwner = ownerUsername.toUpperCase();
462
+ matterLogger.debug(`Registering external Matter bridge ${normalizedExternal} → owner: ${normalizedOwner}`);
463
+ this.externalMatterBridgeRegistry.set(normalizedExternal, normalizedOwner);
464
+ }
465
+ async handleGetMatterAccessories(bridgeUsername) {
466
+ matterLogger.debug(`Getting Matter accessories${bridgeUsername ? ` for bridge ${bridgeUsername}` : ' for all bridges'}`);
467
+ if (!this.matterMonitoringActive) {
468
+ matterLogger.warn('Matter monitoring not active - cannot get accessories');
469
+ const event = {
470
+ type: 'accessoriesData',
471
+ data: {
472
+ bridgeUsername,
473
+ error: 'Matter monitoring not active',
474
+ },
475
+ };
476
+ this.ipcService.sendMessage("matterEvent", event);
477
+ return;
478
+ }
479
+ if (!this.api.isMatterEnabled() && this.childBridges.size === 0) {
480
+ matterLogger.debug('Matter not enabled and no child bridges');
481
+ const event = {
482
+ type: 'accessoriesData',
483
+ data: {
484
+ bridgeUsername,
485
+ accessories: [],
486
+ },
487
+ };
488
+ this.ipcService.sendMessage("matterEvent", event);
489
+ return;
490
+ }
491
+ try {
492
+ const allAccessories = this.matterManager?.collectAllAccessories(bridgeUsername) || [];
493
+ matterLogger.debug(`Collected ${allAccessories.length} accessories from main bridge`);
494
+ if (this.childBridges.size > 0) {
495
+ matterLogger.debug(`Requesting accessories from ${this.childBridges.size} child bridge(s)`);
496
+ for (const childBridge of this.childBridges.values()) {
497
+ childBridge.lastMatterAccessoriesResponse = undefined;
498
+ }
499
+ for (const childBridge of this.childBridges.values()) {
500
+ childBridge.getMatterAccessories();
501
+ }
502
+ await new Promise(resolve => setTimeout(resolve, 500));
503
+ let responsesCollected = 0;
504
+ for (const childBridge of this.childBridges.values()) {
505
+ if (childBridge.lastMatterAccessoriesResponse?.accessories) {
506
+ const accessories = childBridge.lastMatterAccessoriesResponse.accessories;
507
+ allAccessories.push(...accessories);
508
+ responsesCollected++;
509
+ }
510
+ }
511
+ matterLogger.debug(`Collected responses from ${responsesCollected} of ${this.childBridges.size} child bridge(s)`);
512
+ }
513
+ matterLogger.debug(`Sending ${allAccessories.length} total Matter accessories`);
514
+ const event = {
515
+ type: 'accessoriesData',
516
+ data: {
517
+ bridgeUsername: bridgeUsername || 'all',
518
+ accessories: allAccessories,
519
+ },
520
+ };
521
+ this.ipcService.sendMessage("matterEvent", event);
522
+ }
523
+ catch (error) {
524
+ matterLogger.error('Failed to get Matter accessories:', error);
525
+ const event = {
526
+ type: 'accessoriesData',
527
+ data: {
528
+ bridgeUsername,
529
+ error: error instanceof Error ? error.message : 'Unknown error',
530
+ },
531
+ };
532
+ this.ipcService.sendMessage("matterEvent", event);
533
+ }
534
+ }
535
+ handleGetMatterAccessoryInfo(uuid) {
536
+ if (!uuid) {
537
+ const event = {
538
+ type: 'accessoryInfoData',
539
+ data: {
540
+ error: 'UUID is required',
541
+ },
542
+ };
543
+ this.ipcService.sendMessage("matterEvent", event);
544
+ return;
545
+ }
546
+ try {
547
+ const accessoryInfo = this.matterManager?.getAccessoryInfo(uuid);
548
+ if (accessoryInfo) {
549
+ const event = {
550
+ type: 'accessoryInfoData',
551
+ data: accessoryInfo,
552
+ };
553
+ this.ipcService.sendMessage("matterEvent", event);
554
+ return;
555
+ }
556
+ for (const childBridge of this.childBridges.values()) {
557
+ if (childBridge.getMetadata().matterConfig) {
558
+ childBridge.getMatterAccessoryInfo(uuid);
559
+ }
560
+ }
561
+ }
562
+ catch (error) {
563
+ matterLogger.error('Failed to get Matter accessory info:', error);
564
+ const event = {
565
+ type: 'accessoryInfoData',
566
+ data: {
567
+ error: error instanceof Error ? error.message : 'Unknown error',
568
+ },
569
+ };
570
+ this.ipcService.sendMessage("matterEvent", event);
571
+ }
572
+ }
573
+ async handleMatterAccessoryControl(data) {
574
+ matterLogger.debug(`Matter control request: uuid=${data?.uuid}, cluster=${data?.cluster}, bridge=${data?.bridgeUsername || 'auto'}, part=${data?.partId || 'main'}`);
575
+ if (!data?.uuid || !data?.cluster || !data?.attributes) {
576
+ matterLogger.error('Missing required parameters for Matter control');
577
+ this.ipcService.sendMessage("matterEvent", {
578
+ type: 'accessoryControlResponse',
579
+ data: {
580
+ success: false,
581
+ error: 'Missing required parameters',
582
+ },
583
+ });
584
+ return;
585
+ }
586
+ if (data.bridgeUsername) {
587
+ const targetUsername = data.bridgeUsername.toUpperCase();
588
+ if (targetUsername === this.config.bridge.username.toUpperCase()) {
589
+ matterLogger.debug(`Routing to main bridge (${targetUsername})`);
590
+ try {
591
+ await this.handleTriggerMatterCommand(data.uuid, data.cluster, data.attributes, data.partId);
592
+ matterLogger.debug(`Main bridge successfully controlled accessory ${data.uuid}`);
593
+ this.ipcService.sendMessage("matterEvent", {
594
+ type: 'accessoryControlResponse',
595
+ data: {
596
+ success: true,
597
+ uuid: data.uuid,
598
+ },
599
+ });
600
+ }
601
+ catch (error) {
602
+ matterLogger.error(`Main bridge failed to control ${data.uuid}: ${error.message}`);
603
+ this.ipcService.sendMessage("matterEvent", {
604
+ type: 'accessoryControlResponse',
605
+ data: {
606
+ success: false,
607
+ error: error.message,
608
+ uuid: data.uuid,
609
+ },
610
+ });
611
+ }
612
+ return;
613
+ }
614
+ for (const childBridge of this.childBridges.values()) {
615
+ if (childBridge.getMetadata().username.toUpperCase() === targetUsername) {
616
+ matterLogger.debug(`Routing to child bridge ${childBridge.identifier} (${targetUsername})`);
617
+ childBridge.controlMatterAccessory(data);
618
+ return;
619
+ }
620
+ }
621
+ const ownerUsername = this.externalMatterBridgeRegistry.get(targetUsername);
622
+ if (ownerUsername) {
623
+ matterLogger.debug(`Found external bridge ${targetUsername} in registry, owned by ${ownerUsername}`);
624
+ if (ownerUsername === this.config.bridge.username.toUpperCase()) {
625
+ matterLogger.debug(`Routing to main bridge's external accessories for ${data.uuid}`);
626
+ try {
627
+ await this.handleTriggerMatterCommand(data.uuid, data.cluster, data.attributes, data.partId);
628
+ matterLogger.debug(`External accessory ${data.uuid} successfully controlled via main bridge`);
629
+ this.ipcService.sendMessage("matterEvent", {
630
+ type: 'accessoryControlResponse',
631
+ data: {
632
+ success: true,
633
+ uuid: data.uuid,
634
+ },
635
+ });
636
+ }
637
+ catch (error) {
638
+ matterLogger.error(`Main bridge failed to control external accessory ${data.uuid}: ${error.message}`);
639
+ this.ipcService.sendMessage("matterEvent", {
640
+ type: 'accessoryControlResponse',
641
+ data: {
642
+ success: false,
643
+ error: error.message,
644
+ uuid: data.uuid,
645
+ },
646
+ });
647
+ }
648
+ }
649
+ else {
650
+ const childBridge = this.childBridges.get(ownerUsername);
651
+ if (childBridge) {
652
+ matterLogger.debug(`Routing to child bridge ${childBridge.identifier} (${ownerUsername}) for external accessory ${data.uuid}`);
653
+ childBridge.controlMatterAccessory(data);
654
+ }
655
+ else {
656
+ matterLogger.error(`Owner bridge ${ownerUsername} not found for external bridge ${targetUsername}`);
657
+ this.ipcService.sendMessage("matterEvent", {
658
+ type: 'accessoryControlResponse',
659
+ data: {
660
+ success: false,
661
+ error: `Owner bridge ${ownerUsername} not found`,
662
+ uuid: data.uuid,
663
+ },
664
+ });
665
+ }
666
+ }
667
+ return;
668
+ }
669
+ matterLogger.error(`Bridge ${targetUsername} not found in main/child bridges or registry`);
670
+ this.ipcService.sendMessage("matterEvent", {
671
+ type: 'accessoryControlResponse',
672
+ data: {
673
+ success: false,
674
+ error: `Bridge ${targetUsername} not found`,
675
+ uuid: data.uuid,
676
+ },
677
+ });
678
+ return;
679
+ }
680
+ matterLogger.debug(`Broadcast mode: trying main bridge for accessory ${data.uuid}`);
681
+ try {
682
+ await this.handleTriggerMatterCommand(data.uuid, data.cluster, data.attributes, data.partId);
683
+ matterLogger.debug(`Main bridge successfully controlled accessory ${data.uuid}`);
684
+ this.ipcService.sendMessage("matterEvent", {
685
+ type: 'accessoryControlResponse',
686
+ data: {
687
+ success: true,
688
+ uuid: data.uuid,
689
+ },
690
+ });
691
+ }
692
+ catch (error) {
693
+ const matterChildBridges = Array.from(this.childBridges.values()).filter(bridge => bridge.getMetadata().matterConfig);
694
+ if (matterChildBridges.length > 0) {
695
+ matterLogger.debug(`Main bridge doesn't have accessory ${data.uuid}, forwarding to ${matterChildBridges.length} child bridge(s) with Matter enabled`);
696
+ for (const childBridge of matterChildBridges) {
697
+ childBridge.controlMatterAccessory(data);
698
+ }
699
+ }
700
+ else {
701
+ matterLogger.warn(`Accessory ${data.uuid} not found - not on main bridge and no child bridges with Matter available`);
702
+ this.ipcService.sendMessage("matterEvent", {
703
+ type: 'accessoryControlResponse',
704
+ data: {
705
+ success: false,
706
+ error: 'Accessory not found',
707
+ uuid: data.uuid,
708
+ },
709
+ });
710
+ }
711
+ }
712
+ }
713
+ printSetupInfo(pin) {
714
+ console.log('Setup Payload:');
715
+ console.log(this.bridgeService.bridge.setupURI());
716
+ if (!this.options.hideQRCode) {
717
+ console.log('Scan this code with your HomeKit app on your iOS device to pair with Homebridge:');
718
+ qrcode.setErrorLevel('M');
719
+ qrcode.generate(this.bridgeService.bridge.setupURI());
720
+ console.log('Or enter this code with your HomeKit app on your iOS device to pair with Homebridge:');
721
+ }
722
+ else {
723
+ console.log('Enter this code with your HomeKit app on your iOS device to pair with Homebridge:');
724
+ }
725
+ console.log(chalk.black.bgWhite(' '));
726
+ console.log(chalk.black.bgWhite(' ┌────────────┐ '));
727
+ console.log(chalk.black.bgWhite(` │ ${pin} │ `));
728
+ console.log(chalk.black.bgWhite(' └────────────┘ '));
729
+ console.log(chalk.black.bgWhite(' '));
730
+ }
731
+ }
732
+ //# sourceMappingURL=server.js.map