matterbridge 3.2.8-dev-20250916-da71182 → 3.2.8-dev-20250919-e967b55

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 (105) hide show
  1. package/CHANGELOG.md +12 -2
  2. package/dist/frontend.js +190 -256
  3. package/dist/frontendTypes.js +25 -0
  4. package/dist/matterbridge.js +18 -54
  5. package/dist/shelly.js +4 -5
  6. package/dist/update.js +0 -2
  7. package/dist/utils/spawn.js +4 -4
  8. package/frontend/build/assets/index.css +1 -0
  9. package/frontend/build/assets/index.js +23 -0
  10. package/frontend/build/assets/vendor_emotion.js +1 -0
  11. package/frontend/build/assets/vendor_lodash.js +1 -0
  12. package/frontend/build/assets/vendor_mdi.js +1 -0
  13. package/frontend/build/assets/vendor_mui.js +137 -0
  14. package/frontend/build/assets/vendor_node_modules.js +100 -0
  15. package/frontend/build/assets/vendor_notistack.js +5 -0
  16. package/frontend/build/assets/vendor_qrcode.js +9 -0
  17. package/frontend/build/assets/vendor_react_table.js +1 -0
  18. package/frontend/build/assets/vendor_rjsf.js +10 -0
  19. package/frontend/build/index.html +27 -1
  20. package/frontend/index.html +17 -0
  21. package/frontend/package-lock.json +5678 -17171
  22. package/frontend/package.json +60 -53
  23. package/npm-shrinkwrap.json +5 -5
  24. package/package.json +1 -1
  25. package/frontend/build/asset-manifest.json +0 -85
  26. package/frontend/build/favicon.ico +0 -0
  27. package/frontend/build/manifest.json +0 -15
  28. package/frontend/build/robots.txt +0 -3
  29. package/frontend/build/static/css/main.56c16a87.css +0 -2
  30. package/frontend/build/static/css/main.56c16a87.css.map +0 -1
  31. package/frontend/build/static/js/main.565f820c.js +0 -3
  32. package/frontend/build/static/js/main.565f820c.js.LICENSE.txt +0 -97
  33. package/frontend/build/static/js/main.565f820c.js.map +0 -1
  34. package/frontend/build/static/media/roboto-cyrillic-300-normal.44340549d94d10899346.woff +0 -0
  35. package/frontend/build/static/media/roboto-cyrillic-300-normal.89d0351bce4bc857dba6.woff2 +0 -0
  36. package/frontend/build/static/media/roboto-cyrillic-400-normal.86d5c52f4588f9f221d7.woff2 +0 -0
  37. package/frontend/build/static/media/roboto-cyrillic-400-normal.d67ac585bb6a05dbf71c.woff +0 -0
  38. package/frontend/build/static/media/roboto-cyrillic-500-normal.1fb2c6d685bfb888cfa3.woff2 +0 -0
  39. package/frontend/build/static/media/roboto-cyrillic-500-normal.36f79cc7e73a69da4438.woff +0 -0
  40. package/frontend/build/static/media/roboto-cyrillic-700-normal.e00802373a2c2db6b30d.woff +0 -0
  41. package/frontend/build/static/media/roboto-cyrillic-700-normal.fd3dfdd6cb1a9175b63d.woff2 +0 -0
  42. package/frontend/build/static/media/roboto-cyrillic-ext-300-normal.a80c0d0719b1acb8f731.woff +0 -0
  43. package/frontend/build/static/media/roboto-cyrillic-ext-300-normal.b9d87b04a9119d8d2fdf.woff2 +0 -0
  44. package/frontend/build/static/media/roboto-cyrillic-ext-400-normal.31476620b88eec076438.woff2 +0 -0
  45. package/frontend/build/static/media/roboto-cyrillic-ext-400-normal.5e3f232f89080810567d.woff +0 -0
  46. package/frontend/build/static/media/roboto-cyrillic-ext-500-normal.634ee2238bf30f362d52.woff2 +0 -0
  47. package/frontend/build/static/media/roboto-cyrillic-ext-500-normal.d6c661248da2fde17768.woff +0 -0
  48. package/frontend/build/static/media/roboto-cyrillic-ext-700-normal.361cdfd3a3f9c4bb09ca.woff2 +0 -0
  49. package/frontend/build/static/media/roboto-cyrillic-ext-700-normal.6b08bc756cd72f5af9e8.woff +0 -0
  50. package/frontend/build/static/media/roboto-greek-300-normal.8300b541aa89b8301a6f.woff +0 -0
  51. package/frontend/build/static/media/roboto-greek-300-normal.fdd1f928a606aa116a44.woff2 +0 -0
  52. package/frontend/build/static/media/roboto-greek-400-normal.98a717d5a38e77c0f657.woff2 +0 -0
  53. package/frontend/build/static/media/roboto-greek-400-normal.ecd8572d631f20ff5bd5.woff +0 -0
  54. package/frontend/build/static/media/roboto-greek-500-normal.4fe733bc436afc295c24.woff +0 -0
  55. package/frontend/build/static/media/roboto-greek-500-normal.5c8100481d4e784afbf2.woff2 +0 -0
  56. package/frontend/build/static/media/roboto-greek-700-normal.d23e03cf87ba44e5af6f.woff +0 -0
  57. package/frontend/build/static/media/roboto-greek-700-normal.d7dfd0b02cd8311e2a97.woff2 +0 -0
  58. package/frontend/build/static/media/roboto-greek-ext-300-normal.60729cafbded24073dfb.woff +0 -0
  59. package/frontend/build/static/media/roboto-greek-ext-300-normal.a88b77bb10633a8045e3.woff2 +0 -0
  60. package/frontend/build/static/media/roboto-greek-ext-400-normal.2d5875b032a1cca91eb2.woff2 +0 -0
  61. package/frontend/build/static/media/roboto-greek-ext-400-normal.a0baf7d6726d8f751a27.woff +0 -0
  62. package/frontend/build/static/media/roboto-greek-ext-500-normal.1964239c2800b6bd7e39.woff +0 -0
  63. package/frontend/build/static/media/roboto-greek-ext-500-normal.bef9c15c7164d6435aad.woff2 +0 -0
  64. package/frontend/build/static/media/roboto-greek-ext-700-normal.1aff9f4cd71608489b9a.woff +0 -0
  65. package/frontend/build/static/media/roboto-greek-ext-700-normal.eb28a447335ba6d54fcb.woff2 +0 -0
  66. package/frontend/build/static/media/roboto-latin-300-normal.cb14f8e80cc69ddbac34.woff +0 -0
  67. package/frontend/build/static/media/roboto-latin-300-normal.db56943a88e4852343ae.woff2 +0 -0
  68. package/frontend/build/static/media/roboto-latin-400-normal.50a0a61e29c19a2f05cb.woff +0 -0
  69. package/frontend/build/static/media/roboto-latin-400-normal.df1be0be92f6f19b8115.woff2 +0 -0
  70. package/frontend/build/static/media/roboto-latin-500-normal.599f66a60bdf974e578e.woff2 +0 -0
  71. package/frontend/build/static/media/roboto-latin-500-normal.c320def131b39bceabd8.woff +0 -0
  72. package/frontend/build/static/media/roboto-latin-700-normal.bcfbe8accc968a375a8e.woff +0 -0
  73. package/frontend/build/static/media/roboto-latin-700-normal.c4d6cab43bec89049809.woff2 +0 -0
  74. package/frontend/build/static/media/roboto-latin-ext-300-normal.6ddd1cfdbc5e74bcdab8.woff +0 -0
  75. package/frontend/build/static/media/roboto-latin-ext-300-normal.948c05192b1e64d931b1.woff2 +0 -0
  76. package/frontend/build/static/media/roboto-latin-ext-400-normal.0f86a30ca7e981fcfc99.woff2 +0 -0
  77. package/frontend/build/static/media/roboto-latin-ext-400-normal.2bfbba2d51a85c8702dd.woff +0 -0
  78. package/frontend/build/static/media/roboto-latin-ext-500-normal.8f02573e78730021ef49.woff2 +0 -0
  79. package/frontend/build/static/media/roboto-latin-ext-500-normal.aecaab4c4da2bf91377a.woff +0 -0
  80. package/frontend/build/static/media/roboto-latin-ext-700-normal.2d3c3ba6fe2d9c1026a5.woff +0 -0
  81. package/frontend/build/static/media/roboto-latin-ext-700-normal.8e656eff240311c6050a.woff2 +0 -0
  82. package/frontend/build/static/media/roboto-math-300-normal.90364ecfad5101ceb1a0.woff +0 -0
  83. package/frontend/build/static/media/roboto-math-300-normal.acc9c7c1d1fe3a1c7d44.woff2 +0 -0
  84. package/frontend/build/static/media/roboto-math-400-normal.3d3a272e5233c5fb1969.woff +0 -0
  85. package/frontend/build/static/media/roboto-math-400-normal.b60d9fba1e21da7497e6.woff2 +0 -0
  86. package/frontend/build/static/media/roboto-math-500-normal.41db483cb764343fca71.woff2 +0 -0
  87. package/frontend/build/static/media/roboto-math-500-normal.c3014a611cd9d8fa6252.woff +0 -0
  88. package/frontend/build/static/media/roboto-math-700-normal.a6fde3ddcb1629fd58b7.woff +0 -0
  89. package/frontend/build/static/media/roboto-math-700-normal.f6f4b54add6ab9d60a0f.woff2 +0 -0
  90. package/frontend/build/static/media/roboto-symbols-300-normal.52cdf8344b378f0c4580.woff +0 -0
  91. package/frontend/build/static/media/roboto-symbols-300-normal.616638ec44336b3da884.woff2 +0 -0
  92. package/frontend/build/static/media/roboto-symbols-400-normal.bb5b5d1459beb07bd3d5.woff2 +0 -0
  93. package/frontend/build/static/media/roboto-symbols-400-normal.f4f7e3bd8264f1a640cb.woff +0 -0
  94. package/frontend/build/static/media/roboto-symbols-500-normal.09b674875029289fd9a7.woff +0 -0
  95. package/frontend/build/static/media/roboto-symbols-500-normal.a5457b0ec984fd4cc8da.woff2 +0 -0
  96. package/frontend/build/static/media/roboto-symbols-700-normal.017e476ef02f62144169.woff +0 -0
  97. package/frontend/build/static/media/roboto-symbols-700-normal.634070e045ac99822c21.woff2 +0 -0
  98. package/frontend/build/static/media/roboto-vietnamese-300-normal.53f399e4522b647bafa7.woff +0 -0
  99. package/frontend/build/static/media/roboto-vietnamese-300-normal.6f0bf63e956c09377ef8.woff2 +0 -0
  100. package/frontend/build/static/media/roboto-vietnamese-400-normal.1cffe58e71a9109191a2.woff +0 -0
  101. package/frontend/build/static/media/roboto-vietnamese-400-normal.b1b8baa94fbcaa57d098.woff2 +0 -0
  102. package/frontend/build/static/media/roboto-vietnamese-500-normal.148734d63bd96c6e964f.woff2 +0 -0
  103. package/frontend/build/static/media/roboto-vietnamese-500-normal.72dbf2a25dd55b80b137.woff +0 -0
  104. package/frontend/build/static/media/roboto-vietnamese-700-normal.44a103f706f3ffe6a041.woff2 +0 -0
  105. package/frontend/build/static/media/roboto-vietnamese-700-normal.fa58a041a3336692af1e.woff +0 -0
@@ -0,0 +1,25 @@
1
+ export var WsBroadcastMessageId;
2
+ (function (WsBroadcastMessageId) {
3
+ WsBroadcastMessageId[WsBroadcastMessageId["Log"] = 0] = "Log";
4
+ WsBroadcastMessageId[WsBroadcastMessageId["RefreshRequired"] = 1] = "RefreshRequired";
5
+ WsBroadcastMessageId[WsBroadcastMessageId["RestartRequired"] = 2] = "RestartRequired";
6
+ WsBroadcastMessageId[WsBroadcastMessageId["RestartNotRequired"] = 3] = "RestartNotRequired";
7
+ WsBroadcastMessageId[WsBroadcastMessageId["CpuUpdate"] = 4] = "CpuUpdate";
8
+ WsBroadcastMessageId[WsBroadcastMessageId["MemoryUpdate"] = 5] = "MemoryUpdate";
9
+ WsBroadcastMessageId[WsBroadcastMessageId["UptimeUpdate"] = 6] = "UptimeUpdate";
10
+ WsBroadcastMessageId[WsBroadcastMessageId["Snackbar"] = 7] = "Snackbar";
11
+ WsBroadcastMessageId[WsBroadcastMessageId["UpdateRequired"] = 8] = "UpdateRequired";
12
+ WsBroadcastMessageId[WsBroadcastMessageId["StateUpdate"] = 9] = "StateUpdate";
13
+ WsBroadcastMessageId[WsBroadcastMessageId["CloseSnackbar"] = 10] = "CloseSnackbar";
14
+ WsBroadcastMessageId[WsBroadcastMessageId["ShellySysUpdate"] = 100] = "ShellySysUpdate";
15
+ WsBroadcastMessageId[WsBroadcastMessageId["ShellyMainUpdate"] = 101] = "ShellyMainUpdate";
16
+ })(WsBroadcastMessageId || (WsBroadcastMessageId = {}));
17
+ export function isBroadcast(msg) {
18
+ return msg.id >= 0 && msg.id <= 101;
19
+ }
20
+ export function isApiRequest(msg) {
21
+ return msg.id > 101 && msg.src === 'Frontend' && msg.dst === 'Matterbridge' && !('success' in msg) && !('error' in msg);
22
+ }
23
+ export function isApiResponse(msg) {
24
+ return msg.id > 101 && msg.src === 'Matterbridge' && msg.dst === 'Frontend' && ('success' in msg || 'error' in msg);
25
+ }
@@ -51,14 +51,6 @@ export class Matterbridge extends EventEmitter {
51
51
  matterbridgeVersion: '',
52
52
  matterbridgeLatestVersion: '',
53
53
  matterbridgeDevVersion: '',
54
- matterbridgeSerialNumber: '',
55
- matterbridgeQrPairingCode: undefined,
56
- matterbridgeManualPairingCode: undefined,
57
- matterbridgeFabricInformations: [],
58
- matterbridgeSessionInformations: [],
59
- matterbridgePaired: false,
60
- matterbridgeAdvertise: false,
61
- matterbridgeEndAdvertise: false,
62
54
  bridgeMode: '',
63
55
  restartMode: '',
64
56
  virtualMode: 'outlet',
@@ -71,9 +63,9 @@ export class Matterbridge extends EventEmitter {
71
63
  fileLogger: false,
72
64
  matterLoggerLevel: MatterLogLevel.INFO,
73
65
  matterFileLogger: false,
74
- mattermdnsinterface: undefined,
75
- matteripv4address: undefined,
76
- matteripv6address: undefined,
66
+ matterMdnsInterface: undefined,
67
+ matterIpv4Address: undefined,
68
+ matterIpv6Address: undefined,
77
69
  matterPort: 5540,
78
70
  matterDiscriminator: undefined,
79
71
  matterPasscode: undefined,
@@ -112,7 +104,6 @@ export class Matterbridge extends EventEmitter {
112
104
  checkUpdateTimeout;
113
105
  configureTimeout;
114
106
  reachabilityTimeout;
115
- endAdvertiseTimeout;
116
107
  sigintHandler;
117
108
  sigtermHandler;
118
109
  exceptionHandler;
@@ -173,7 +164,7 @@ export class Matterbridge extends EventEmitter {
173
164
  callbackLogLevel = "info";
174
165
  if (this.matterbridgeInformation.loggerLevel === "debug" || this.matterbridgeInformation.matterLoggerLevel === MatterLogLevel.DEBUG)
175
166
  callbackLogLevel = "debug";
176
- AnsiLogger.setGlobalCallback(this.frontend.wssSendMessage.bind(this.frontend), callbackLogLevel);
167
+ AnsiLogger.setGlobalCallback(this.frontend.wssSendLogMessage.bind(this.frontend), callbackLogLevel);
177
168
  this.log.debug(`WebSocketServer logger global callback set to ${callbackLogLevel}`);
178
169
  }
179
170
  static async loadInstance(initialize = false) {
@@ -673,7 +664,6 @@ export class Matterbridge extends EventEmitter {
673
664
  await storageContext?.set('serialNumber', this.aggregatorSerialNumber);
674
665
  if (this.aggregatorUniqueId)
675
666
  await storageContext?.set('uniqueId', this.aggregatorUniqueId);
676
- this.matterbridgeInformation.matterbridgeSerialNumber = this.aggregatorSerialNumber;
677
667
  }
678
668
  }
679
669
  catch (error) {
@@ -1082,12 +1072,6 @@ export class Matterbridge extends EventEmitter {
1082
1072
  }
1083
1073
  await this.stopMatterStorage();
1084
1074
  await this.frontend.stop();
1085
- try {
1086
- Logger.removeLogger('matterfilelogger');
1087
- }
1088
- catch (error) {
1089
- this.log.debug(`Error removing the matterfilelogger for file ${CYAN}${path.join(this.matterbridgeDirectory, this.matterLoggerFile)}${db}: ${error instanceof Error ? error.message : String(error)}`);
1090
- }
1091
1075
  if (this.nodeStorage && this.nodeContext) {
1092
1076
  this.log.debug(`Closing node storage context for ${plg}Matterbridge${db}...`);
1093
1077
  await this.nodeContext.close();
@@ -1259,7 +1243,6 @@ export class Matterbridge extends EventEmitter {
1259
1243
  this.log.info(`Setting reachability to true for ${plg}Matterbridge${db}`);
1260
1244
  if (this.aggregatorNode)
1261
1245
  this.setAggregatorReachability(this.aggregatorNode, true);
1262
- this.frontend.wssSendRefreshRequired('reachability');
1263
1246
  }, 60 * 1000).unref();
1264
1247
  this.emit('bridge_started');
1265
1248
  this.log.notice('Matterbridge bridge started successfully');
@@ -1348,7 +1331,6 @@ export class Matterbridge extends EventEmitter {
1348
1331
  this.log.info(`Setting reachability to true for ${plg}${plugin.name}${nf} type ${plugin.type} server node ${plugin.serverNode !== undefined} aggregator node ${plugin.aggregatorNode !== undefined} device ${plugin.device !== undefined}`);
1349
1332
  if (plugin.type === 'DynamicPlatform' && plugin.aggregatorNode)
1350
1333
  this.setAggregatorReachability(plugin.aggregatorNode, true);
1351
- this.frontend.wssSendRefreshRequired('reachability');
1352
1334
  }, 60 * 1000).unref();
1353
1335
  }
1354
1336
  for (const device of this.devices.array()) {
@@ -1370,7 +1352,6 @@ export class Matterbridge extends EventEmitter {
1370
1352
  this.matterStorageManager = await this.matterStorageService.open('Matterbridge');
1371
1353
  this.log.info('Matter node storage manager "Matterbridge" created');
1372
1354
  this.matterbridgeContext = await this.createServerNodeContext('Matterbridge', 'Matterbridge', this.aggregatorDeviceType, this.aggregatorVendorId, this.aggregatorVendorName, this.aggregatorProductId, this.aggregatorProductName, this.aggregatorSerialNumber, this.aggregatorUniqueId);
1373
- this.matterbridgeInformation.matterbridgeSerialNumber = await this.matterbridgeContext.get('serialNumber', '');
1374
1355
  this.log.info('Matter node storage started');
1375
1356
  await this.backupMatterStorage(path.join(this.matterbridgeDirectory, this.matterStorageName), path.join(this.matterbridgeDirectory, this.matterStorageName + '.backup'));
1376
1357
  }
@@ -1476,21 +1457,29 @@ export class Matterbridge extends EventEmitter {
1476
1457
  });
1477
1458
  serverNode.lifecycle.commissioned.on(() => {
1478
1459
  this.log.notice(`Server node for ${storeId} was initially commissioned successfully!`);
1479
- clearTimeout(this.endAdvertiseTimeout);
1460
+ this.advertisingNodes.delete(storeId);
1461
+ this.frontend.wssSendRefreshRequired('settings');
1462
+ this.frontend.wssSendRefreshRequired('plugins');
1463
+ this.frontend.wssSendRefreshRequired('devices');
1464
+ this.frontend.wssSendRefreshRequired('matter', { matter: { ...this.getServerNodeData(serverNode) } });
1480
1465
  });
1481
1466
  serverNode.lifecycle.decommissioned.on(() => {
1482
1467
  this.log.notice(`Server node for ${storeId} was fully decommissioned successfully!`);
1483
- clearTimeout(this.endAdvertiseTimeout);
1468
+ this.advertisingNodes.delete(storeId);
1469
+ this.frontend.wssSendRefreshRequired('settings');
1470
+ this.frontend.wssSendRefreshRequired('plugins');
1471
+ this.frontend.wssSendRefreshRequired('devices');
1472
+ this.frontend.wssSendRefreshRequired('matter', { matter: { ...this.getServerNodeData(serverNode) } });
1473
+ this.frontend.wssSendSnackbarMessage(`${storeId} is offline`, 5, 'warning');
1484
1474
  });
1485
1475
  serverNode.lifecycle.online.on(async () => {
1486
1476
  this.log.notice(`Server node for ${storeId} is online`);
1487
1477
  if (!serverNode.lifecycle.isCommissioned) {
1488
1478
  this.log.notice(`Server node for ${storeId} is not commissioned. Pair to commission ...`);
1479
+ this.advertisingNodes.set(storeId, Date.now());
1489
1480
  const { qrPairingCode, manualPairingCode } = serverNode.state.commissioning.pairingCodes;
1490
1481
  this.log.notice(`QR Code URL: https://project-chip.github.io/connectedhomeip/qrcode.html?data=${qrPairingCode}`);
1491
1482
  this.log.notice(`Manual pairing code: ${manualPairingCode}`);
1492
- this.startEndAdvertiseTimer(serverNode);
1493
- this.advertisingNodes.set(storeId, Date.now());
1494
1483
  }
1495
1484
  else {
1496
1485
  this.log.notice(`Server node for ${storeId} is already commissioned. Waiting for controllers to connect ...`);
@@ -1504,7 +1493,6 @@ export class Matterbridge extends EventEmitter {
1504
1493
  });
1505
1494
  serverNode.lifecycle.offline.on(() => {
1506
1495
  this.log.notice(`Server node for ${storeId} is offline`);
1507
- this.matterbridgeInformation.matterbridgeEndAdvertise = true;
1508
1496
  this.frontend.wssSendRefreshRequired('plugins');
1509
1497
  this.frontend.wssSendRefreshRequired('settings');
1510
1498
  this.frontend.wssSendRefreshRequired('matter', { matter: { ...this.getServerNodeData(serverNode) } });
@@ -1516,9 +1504,6 @@ export class Matterbridge extends EventEmitter {
1516
1504
  switch (fabricAction) {
1517
1505
  case FabricAction.Added:
1518
1506
  this.advertisingNodes.delete(storeId);
1519
- clearTimeout(this.endAdvertiseTimeout);
1520
- this.endAdvertiseTimeout = undefined;
1521
- this.matterbridgeInformation.matterbridgeEndAdvertise = true;
1522
1507
  action = 'added';
1523
1508
  break;
1524
1509
  case FabricAction.Removed:
@@ -1529,46 +1514,23 @@ export class Matterbridge extends EventEmitter {
1529
1514
  break;
1530
1515
  }
1531
1516
  this.log.notice(`Commissioned fabric index ${fabricIndex} ${action} on server node for ${storeId}: ${debugStringify(serverNode.state.commissioning.fabrics[fabricIndex])}`);
1532
- this.frontend.wssSendRefreshRequired('fabrics');
1533
1517
  this.frontend.wssSendRefreshRequired('matter', { matter: { ...this.getServerNodeData(serverNode) } });
1534
1518
  });
1535
1519
  serverNode.events.sessions.opened.on((session) => {
1536
1520
  this.log.notice(`Session opened on server node for ${storeId}: ${debugStringify(session)}`);
1537
- this.frontend.wssSendRefreshRequired('sessions');
1538
1521
  this.frontend.wssSendRefreshRequired('matter', { matter: { ...this.getServerNodeData(serverNode) } });
1539
1522
  });
1540
1523
  serverNode.events.sessions.closed.on((session) => {
1541
1524
  this.log.notice(`Session closed on server node for ${storeId}: ${debugStringify(session)}`);
1542
- this.frontend.wssSendRefreshRequired('sessions');
1543
1525
  this.frontend.wssSendRefreshRequired('matter', { matter: { ...this.getServerNodeData(serverNode) } });
1544
1526
  });
1545
1527
  serverNode.events.sessions.subscriptionsChanged.on((session) => {
1546
1528
  this.log.notice(`Session subscriptions changed on server node for ${storeId}: ${debugStringify(session)}`);
1547
- this.frontend.wssSendRefreshRequired('sessions');
1548
1529
  this.frontend.wssSendRefreshRequired('matter', { matter: { ...this.getServerNodeData(serverNode) } });
1549
1530
  });
1550
1531
  this.log.info(`Created server node for ${storeId}`);
1551
1532
  return serverNode;
1552
1533
  }
1553
- startEndAdvertiseTimer(matterServerNode) {
1554
- if (this.endAdvertiseTimeout) {
1555
- this.log.debug(`Clear ${matterServerNode.id} server node end advertise timer`);
1556
- clearTimeout(this.endAdvertiseTimeout);
1557
- }
1558
- this.log.debug(`Starting ${matterServerNode.id} server node end advertise timer`);
1559
- this.endAdvertiseTimeout = setTimeout(() => {
1560
- if (matterServerNode.lifecycle.isCommissioned)
1561
- return;
1562
- this.matterbridgeInformation.matterbridgeEndAdvertise = true;
1563
- this.frontend.wssSendRefreshRequired('plugins');
1564
- this.frontend.wssSendRefreshRequired('settings');
1565
- this.frontend.wssSendRefreshRequired('fabrics');
1566
- this.frontend.wssSendRefreshRequired('sessions');
1567
- this.frontend.wssSendRefreshRequired('matter', { matter: { ...this.getServerNodeData(matterServerNode) } });
1568
- this.frontend.wssSendSnackbarMessage(`Advertising stopped.`, 0);
1569
- this.log.notice(`Advertising stopped.`);
1570
- }, 15 * 60 * 1000).unref();
1571
- }
1572
1534
  getServerNodeData(serverNode) {
1573
1535
  const advertiseTime = this.advertisingNodes.get(serverNode.id) || 0;
1574
1536
  return {
@@ -1756,6 +1718,8 @@ export class Matterbridge extends EventEmitter {
1756
1718
  await wait(2000);
1757
1719
  }
1758
1720
  async subscribeAttributeChanged(plugin, device) {
1721
+ if (!plugin || !device || !device.plugin || !device.serialNumber || !device.uniqueId)
1722
+ return;
1759
1723
  this.log.info(`Subscribing attributes for endpoint ${dev}${device.deviceName}${nf} (${dev}${device.id}${nf}) plugin ${plg}${plugin.name}${nf}`);
1760
1724
  if (this.bridgeMode === 'childbridge' && plugin.type === 'AccessoryPlatform' && plugin.serverNode) {
1761
1725
  plugin.serverNode.eventsOf(BasicInformationServer).reachable$Changed?.on((reachable) => {
package/dist/shelly.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { debugStringify } from 'node-ansi-logger';
2
- import { WS_ID_SHELLY_MAIN_UPDATE, WS_ID_SHELLY_SYS_UPDATE } from './frontend.js';
3
2
  let verifyIntervalSecs = 15;
4
3
  let verifyTimeoutSecs = 600;
5
4
  export function setVerifyIntervalSecs(seconds) {
@@ -14,7 +13,7 @@ export async function getShellySysUpdate(matterbridge) {
14
13
  if (updates.length === 0)
15
14
  return;
16
15
  matterbridge.matterbridgeInformation.shellySysUpdate = true;
17
- matterbridge.frontend.wssBroadcastMessage(WS_ID_SHELLY_SYS_UPDATE, 'shelly-sys-update', { available: true });
16
+ matterbridge.frontend.wssBroadcastMessage({ id: 100, src: 'Matterbridge', dst: 'Frontend', method: 'shelly_sys_update', params: { available: true } });
18
17
  for (const { name } of updates) {
19
18
  if (!name)
20
19
  continue;
@@ -32,7 +31,7 @@ export async function triggerShellySysUpdate(matterbridge) {
32
31
  matterbridge.log.notice('Installing Shelly system update...');
33
32
  matterbridge.matterbridgeInformation.shellySysUpdate = false;
34
33
  matterbridge.frontend.wssSendSnackbarMessage('Installing Shelly system update...', 15);
35
- matterbridge.frontend.wssBroadcastMessage(WS_ID_SHELLY_SYS_UPDATE, 'shelly-sys-update', { available: false });
34
+ matterbridge.frontend.wssBroadcastMessage({ id: 100, src: 'Matterbridge', dst: 'Frontend', method: 'shelly_sys_update', params: { available: false } });
36
35
  await verifyShellyUpdate(matterbridge, '/api/updates/sys/status', 'Shelly system update');
37
36
  }
38
37
  catch (err) {
@@ -45,7 +44,7 @@ export async function getShellyMainUpdate(matterbridge) {
45
44
  if (updates.length === 0)
46
45
  return;
47
46
  matterbridge.matterbridgeInformation.shellyMainUpdate = true;
48
- matterbridge.frontend.wssBroadcastMessage(WS_ID_SHELLY_MAIN_UPDATE, 'shelly-main-update', { available: true });
47
+ matterbridge.frontend.wssBroadcastMessage({ id: 101, src: 'Matterbridge', dst: 'Frontend', method: 'shelly_main_update', params: { available: true } });
49
48
  for (const { name } of updates) {
50
49
  if (!name)
51
50
  continue;
@@ -63,7 +62,7 @@ export async function triggerShellyMainUpdate(matterbridge) {
63
62
  matterbridge.log.notice('Installing Shelly software update...');
64
63
  matterbridge.matterbridgeInformation.shellyMainUpdate = false;
65
64
  matterbridge.frontend.wssSendSnackbarMessage('Installing Shelly software update...', 15);
66
- matterbridge.frontend.wssBroadcastMessage(WS_ID_SHELLY_MAIN_UPDATE, 'shelly-main-update', { available: false });
65
+ matterbridge.frontend.wssBroadcastMessage({ id: 101, src: 'Matterbridge', dst: 'Frontend', method: 'shelly_main_update', params: { available: false } });
67
66
  await verifyShellyUpdate(matterbridge, '/api/updates/main/status', 'Shelly software update');
68
67
  }
69
68
  catch (err) {
package/dist/update.js CHANGED
@@ -51,7 +51,6 @@ export async function getMatterbridgeLatestVersion(matterbridge) {
51
51
  if (matterbridge.matterbridgeVersion !== matterbridge.matterbridgeLatestVersion) {
52
52
  matterbridge.log.notice(`Matterbridge is out of date. Current version: ${matterbridge.matterbridgeVersion}. Latest version: ${matterbridge.matterbridgeLatestVersion}.`);
53
53
  matterbridge.frontend.wssSendSnackbarMessage('Matterbridge latest update available', 0, 'info');
54
- matterbridge.frontend.wssSendRefreshRequired('matterbridgeLatestVersion');
55
54
  matterbridge.frontend.wssSendUpdateRequired();
56
55
  }
57
56
  else {
@@ -73,7 +72,6 @@ export async function getMatterbridgeDevVersion(matterbridge) {
73
72
  if (matterbridge.matterbridgeVersion.includes('-dev-') && matterbridge.matterbridgeVersion !== version) {
74
73
  matterbridge.log.notice(`Matterbridge@dev is out of date. Current version: ${matterbridge.matterbridgeVersion}. Latest dev version: ${matterbridge.matterbridgeDevVersion}.`);
75
74
  matterbridge.frontend.wssSendSnackbarMessage('Matterbridge dev update available', 0, 'info');
76
- matterbridge.frontend.wssSendRefreshRequired('matterbridgeDevVersion');
77
75
  matterbridge.frontend.wssSendUpdateRequired(true);
78
76
  }
79
77
  else if (matterbridge.matterbridgeVersion.includes('-dev-') && matterbridge.matterbridgeVersion === version) {
@@ -21,7 +21,7 @@ export async function spawnCommand(matterbridge, command, args) {
21
21
  reject(err);
22
22
  });
23
23
  childProcess.on('close', (code, signal) => {
24
- matterbridge.frontend.wssSendMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', `child process closed with code ${code} and signal ${signal}`);
24
+ matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', `child process closed with code ${code} and signal ${signal}`);
25
25
  if (code === 0) {
26
26
  if (cmdLine.startsWith('npm install -g'))
27
27
  matterbridge.log.notice(`Package ${cmdLine.replace('npm install -g ', '').replace('--verbose', '').replace('--omit=dev', '')} installed correctly`);
@@ -34,7 +34,7 @@ export async function spawnCommand(matterbridge, command, args) {
34
34
  }
35
35
  });
36
36
  childProcess.on('exit', (code, signal) => {
37
- matterbridge.frontend.wssSendMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', `child process exited with code ${code} and signal ${signal}`);
37
+ matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', `child process exited with code ${code} and signal ${signal}`);
38
38
  if (code === 0) {
39
39
  matterbridge.log.debug(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`);
40
40
  resolve(true);
@@ -52,14 +52,14 @@ export async function spawnCommand(matterbridge, command, args) {
52
52
  childProcess.stdout.on('data', (data) => {
53
53
  const message = data.toString().trim();
54
54
  matterbridge.log.debug(`Spawn output (stdout): ${message}`);
55
- matterbridge.frontend.wssSendMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', message);
55
+ matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', message);
56
56
  });
57
57
  }
58
58
  if (childProcess.stderr) {
59
59
  childProcess.stderr.on('data', (data) => {
60
60
  const message = data.toString().trim();
61
61
  matterbridge.log.debug(`Spawn verbose (stderr): ${message}`);
62
- matterbridge.frontend.wssSendMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', message);
62
+ matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', message);
63
63
  });
64
64
  }
65
65
  });
@@ -0,0 +1 @@
1
+ body{font-family:Roboto,sans-serif}[frontend-theme=classic]{--main-bg-color: #c4c2c2;--main-text-color: black;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: #4d4d4d;--main-log-color: var(--main-text-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: #26292d;--main-menu-bg-color: #e2e2e2;--main-menu-hover-color: #959595;--main-label-color: var(--main-grey-color);--primary-color: #009a00;--secondary-color: #92771f;--header-bg-color: var(--primary-color);--header-text-color: white;--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: #ddd;--table-text-color: black;--table-even-bg-color: #bdbdbd;--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #5f8c9e;--table-selected-bg-color: #5f8c9e;--div-bg-color: #adadad;--div-text-color: black;--div-shadow-color: #888;--div-border-color: rgb(139, 139, 139);--div-border-radius: 0px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: black;background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=dark]{--main-bg-color: #26292d;--main-text-color: #ffffff;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: var(--main-light-color);--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-light-color);--main-menu-bg-color: var(--main-bg-color);--main-menu-hover-color: var(--div-bg-color);--main-label-color: var(--main-grey-color);--primary-color: #1976d2;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--primary-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: var(--main-bg-color);--table-selected-bg-color: var(--main-bg-color);--div-bg-color: #1b1d21;--div-text-color: var(--main-light-color);--div-shadow-color: #34373d;--div-border-color: #1b1d21;--div-border-radius: 5px;--div-title-bg-color: #1b1d21;--div-title-text-color: var(--primary-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=light]{--main-bg-color: #f0f0f0;--main-text-color: #212121;--main-grey-color: #616161;--main-light-color: #363636;--main-icon-color: #7a7a7a;--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-text-color);--main-menu-bg-color: var(--div-bg-color);--main-menu-hover-color: #85c0d8;--main-label-color: var(--main-grey-color);--primary-color: #2196f3;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--div-text-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #85c0d8;--table-selected-bg-color: #85c0d8;--div-bg-color: #ffffff;--div-text-color: #212121;--div-shadow-color: #bfbfbf;--div-border-color: var(--div-bg-color);--div-border-radius: 5px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: var(--div-text-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}::-webkit-scrollbar{width:10px}::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-thumb:hover{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-track{background:"inherit"}html,.thin-scroll{scrollbar-width:thin;scrollbar-color:var(--primary-color) var(--div-bg-color)}.thin-scroll::-webkit-scrollbar{width:5px;height:5px}.thin-scroll::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}.tooltip-container{position:relative;display:inline-block;z-index:10}.tooltip-text{visibility:hidden;background-color:var(--ttip-bg-color);color:var(--ttip-text-color);text-align:center;padding:5px;border-radius:6px;position:absolute;z-index:10;bottom:calc(100% + 10px);left:50%;margin-left:-60px;opacity:0;transition:opacity .3s;font-size:12px}.tooltip-container:hover{cursor:pointer;z-index:10}.tooltip-container:hover .tooltip-text{visibility:visible;opacity:1;z-index:10}.status-enabled{background-color:green;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-disabled{background-color:red;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-information{background-color:#9e9e9e;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-warning{background-color:#e9db18;color:#000;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-sponsor{background-color:#b6409c;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-blue{background-color:#5f8c9e;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:20px;margin:0;padding:0;height:40px}.sub-header{flex:0 0 auto;display:flex;flex-direction:row;align-items:center;gap:20px;margin:0;padding:0;height:40px}nav{display:flex;align-items:center}.nav-link{margin:0 10px;font-size:20px;text-decoration:none;color:var(--main-icon-color);transition:color .3s ease}.nav-link:hover{color:var(--primary-color)}table{border-collapse:collapse;width:100%;table-layout:auto}thead{position:sticky;top:0;border:1px solid var(--table-border-color);z-index:10}thead th{border:1px solid var(--table-border-color);padding:5px 10px;color:var(--header-text-color);background:var(--header-bg-color);text-align:left;z-index:10}tbody td{border:1px solid var(--table-border-color);margin:0;padding:5px 10px;text-align:left;font-size:14px}tbody tr:hover{color:var(--table-text-color);background-color:var(--table-hover-bg-color)}.table-content-even{color:var(--table-text-color);background-color:var(--table-even-bg-color)}.table-content-odd{color:var(--table-text-color);background-color:var(--table-odd-bg-color)}.table-content-selected{color:var(--table-text-color);background-color:var(--table-selected-bg-color)}h3{margin:0}.MbfScreen{display:flex;flex-direction:column;width:calc(100vw - 40px);height:calc(100vh - 40px);gap:20px;margin:0;padding:20px;background-color:var(--main-bg-color)}.MbfPageDiv{display:flex;flex-direction:column;height:calc(100% - 60px);width:100%;margin:0;padding:0;gap:20px}.MbfWindowDiv{display:flex;flex-direction:column;box-shadow:5px 5px 10px var(--div-shadow-color);border:1px solid var(--table-border-color);border-radius:var(--div-border-radius);box-sizing:border-box;background-color:var(--div-bg-color)}.MbfWindowDivTable{display:flex;flex-direction:column;flex:1 1 auto;margin:-1px;padding:0;gap:0;overflow:auto;display:block}.MbfWindowHeaderFooterIcons{display:flex;flex-direction:row;margin:0;padding:0 10px;gap:10px}.MbfWindowHeader{display:flex;flex-direction:row;align-items:center;width:100%;border-bottom:1px solid var(--table-border-color);color:var(--header-text-color);background-color:var(--header-bg-color);margin:0;padding:0;box-sizing:border-box}.MbfWindowHeaderText{color:var(--header-text-color);font-weight:700;margin:0;padding:5px 10px}.MbfWindowFooter{display:flex;flex-direction:row;align-items:center;justify-content:center;color:var(--footer-text-color);background-color:var(--footer-bg-color);margin:0;padding:0}.MbfWindowFooterText{color:var(--footer-text-color);background-color:var(--footer-bg-color);font-weight:700;text-align:center;margin:0;padding:5px 10px}.MbfWindowBody{display:flex;flex:1 1 auto;margin:0;padding:10px;gap:10px}.MbfWindowBodyColumn{display:flex;flex-direction:column;flex:1 1 auto;width:100%;margin:0;padding:10px 0;gap:0px;overflow:auto}.MbfWindowBodyRow{display:flex;flex-direction:row;flex:1 1 auto;height:100%;margin:0;padding:0 10px;gap:0px;overflow:auto}.configSubmitButton{display:flex;flex-direction:row;justify-content:center;width:auto;margin:20px}.configSubmitButton button{width:auto}@media (max-width: 1300px){.MbfScreen{width:1300px;height:1024px}.xxxheader{flex-direction:column;align-items:start;justify-content:start}.xxxsub-header{align-items:start;justify-content:start}}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}