@matterbridge/core 3.9.2-dev-20260620-2b9580a → 3.9.2-dev-20260622-2bad6bf
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/backendWsServer.d.ts +3 -1
- package/dist/backendWsServer.js +16 -2
- package/dist/frontend.d.ts +3 -1
- package/dist/frontend.js +27 -2
- package/dist/helpers.js +1 -1
- package/dist/matterbridge.d.ts +7 -4
- package/dist/matterbridge.js +55 -16
- package/package.json +6 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EndpointNumber } from '@matter/types/datatype';
|
|
2
|
-
import type { ApiMatter, RefreshRequiredChanged, SharedMatterbridge, WsMessageBroadcast } from '@matterbridge/types';
|
|
2
|
+
import type { ApiMatter, BridgeStatus, PluginStatusUpdate, RefreshRequiredChanged, SharedMatterbridge, WsMessageBroadcast } from '@matterbridge/types';
|
|
3
3
|
import { WebSocketServer } from 'ws';
|
|
4
4
|
import type { Backend } from './backend.js';
|
|
5
5
|
export declare class BackendWsServer {
|
|
@@ -27,6 +27,8 @@ export declare class BackendWsServer {
|
|
|
27
27
|
wssSendRestartNotRequired(snackbar?: boolean): void;
|
|
28
28
|
wssSendUpdateRequired(version: string, devVersion?: boolean): void;
|
|
29
29
|
wssSendPluginUpdateRequired(plugin: string, version: string, devVersion?: boolean): void;
|
|
30
|
+
wssSendPluginStatusUpdate(plugin: string, status: PluginStatusUpdate): void;
|
|
31
|
+
wssSendMatterbridgeStatusUpdate(status: BridgeStatus): void;
|
|
30
32
|
wssSendCpuUpdate(cpuUsage: number, processCpuUsage: number): void;
|
|
31
33
|
wssSendMemoryUpdate(totalMemory: string, freeMemory: string, rss: string, heapTotal: string, heapUsed: string, external: string, arrayBuffers: string): void;
|
|
32
34
|
wssSendUptimeUpdate(systemUptime: string, processUptime: string): void;
|
package/dist/backendWsServer.js
CHANGED
|
@@ -236,16 +236,30 @@ export class BackendWsServer {
|
|
|
236
236
|
if (!this.hasActiveClients())
|
|
237
237
|
return;
|
|
238
238
|
if (this.verbose)
|
|
239
|
-
this.log.debug('Sending
|
|
239
|
+
this.log.debug('Sending a matterbridge version update required message to all connected clients');
|
|
240
240
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'update_required', success: true, response: { version, devVersion } });
|
|
241
241
|
}
|
|
242
242
|
wssSendPluginUpdateRequired(plugin, version, devVersion = false) {
|
|
243
243
|
if (!this.hasActiveClients())
|
|
244
244
|
return;
|
|
245
245
|
if (this.verbose)
|
|
246
|
-
this.log.debug('Sending a plugin update required message to all connected clients');
|
|
246
|
+
this.log.debug('Sending a plugin version update required message to all connected clients');
|
|
247
247
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'plugin_update_required', success: true, response: { plugin, version, devVersion } });
|
|
248
248
|
}
|
|
249
|
+
wssSendPluginStatusUpdate(plugin, status) {
|
|
250
|
+
if (!this.hasActiveClients())
|
|
251
|
+
return;
|
|
252
|
+
if (this.verbose)
|
|
253
|
+
this.log.debug('Sending a plugin status update message to all connected clients');
|
|
254
|
+
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'plugin_status_update', success: true, response: { plugin, status } });
|
|
255
|
+
}
|
|
256
|
+
wssSendMatterbridgeStatusUpdate(status) {
|
|
257
|
+
if (!this.hasActiveClients())
|
|
258
|
+
return;
|
|
259
|
+
if (this.verbose)
|
|
260
|
+
this.log.debug('Sending a matterbridge status update message to all connected clients');
|
|
261
|
+
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'matterbridge_status_update', success: true, response: { status } });
|
|
262
|
+
}
|
|
249
263
|
wssSendCpuUpdate(cpuUsage, processCpuUsage) {
|
|
250
264
|
if (!this.hasActiveClients())
|
|
251
265
|
return;
|
package/dist/frontend.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import EventEmitter from 'node:events';
|
|
2
2
|
import { type EndpointNumber } from '@matter/types/datatype';
|
|
3
|
-
import type { ApiClusters, ApiDevice, ApiMatter, ApiPlugin, ApiSettings, RefreshRequiredChanged, WsMessageBroadcast } from '@matterbridge/types';
|
|
3
|
+
import type { ApiClusters, ApiDevice, ApiMatter, ApiPlugin, ApiSettings, BridgeStatus, PluginStatusUpdate, RefreshRequiredChanged, WsMessageBroadcast } from '@matterbridge/types';
|
|
4
4
|
import { LogLevel } from 'node-ansi-logger';
|
|
5
5
|
import type { Matterbridge } from './matterbridge.js';
|
|
6
6
|
interface FrontendEvents {
|
|
@@ -59,6 +59,8 @@ export declare class Frontend extends EventEmitter<FrontendEvents> {
|
|
|
59
59
|
wssSendRestartNotRequired(snackbar?: boolean): void;
|
|
60
60
|
wssSendUpdateRequired(version: string, devVersion?: boolean): void;
|
|
61
61
|
wssSendPluginUpdateRequired(plugin: string, version: string, devVersion?: boolean): void;
|
|
62
|
+
wssSendPluginStatusUpdate(plugin: string, status: PluginStatusUpdate): void;
|
|
63
|
+
wssSendMatterbridgeStatusUpdate(status: BridgeStatus): void;
|
|
62
64
|
wssSendCpuUpdate(cpuUsage: number, processCpuUsage: number): void;
|
|
63
65
|
wssSendMemoryUpdate(totalMemory: string, freeMemory: string, rss: string, heapTotal: string, heapUsed: string, external: string, arrayBuffers: string): void;
|
|
64
66
|
wssSendUptimeUpdate(systemUptime: string, processUptime: string): void;
|
package/dist/frontend.js
CHANGED
|
@@ -100,10 +100,22 @@ export class Frontend extends EventEmitter {
|
|
|
100
100
|
this.wssSendPluginUpdateRequired(msg.params.plugin, msg.params.version, msg.params.devVersion);
|
|
101
101
|
this.server.respond({ ...msg, result: { success: true } });
|
|
102
102
|
break;
|
|
103
|
+
case 'frontend_pluginstatusupdate':
|
|
104
|
+
this.wssSendPluginStatusUpdate(msg.params.plugin, msg.params.status);
|
|
105
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
106
|
+
break;
|
|
107
|
+
case 'frontend_matterbridgestatusupdate':
|
|
108
|
+
this.wssSendMatterbridgeStatusUpdate(msg.params.status);
|
|
109
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
110
|
+
break;
|
|
103
111
|
case 'frontend_snackbarmessage':
|
|
104
112
|
this.wssSendSnackbarMessage(msg.params.message, msg.params.timeout, msg.params.severity);
|
|
105
113
|
this.server.respond({ ...msg, result: { success: true } });
|
|
106
114
|
break;
|
|
115
|
+
case 'frontend_closesnackbarmessage':
|
|
116
|
+
this.wssSendCloseSnackbarMessage(msg.params.message);
|
|
117
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
118
|
+
break;
|
|
107
119
|
case 'frontend_attributechanged':
|
|
108
120
|
this.wssSendAttributeChangedMessage(msg.params.plugin, msg.params.serialNumber, msg.params.uniqueId, msg.params.number, msg.params.id, msg.params.cluster, msg.params.attribute, msg.params.value);
|
|
109
121
|
this.server.respond({ ...msg, result: { success: true } });
|
|
@@ -935,6 +947,7 @@ export class Frontend extends EventEmitter {
|
|
|
935
947
|
bridgeMode: this.matterbridge.bridgeMode,
|
|
936
948
|
restartMode: this.matterbridge.restartMode,
|
|
937
949
|
virtualMode: this.matterbridge.virtualMode,
|
|
950
|
+
bridgeStatus: this.matterbridge.bridgeStatus,
|
|
938
951
|
profile: this.matterbridge.profile,
|
|
939
952
|
loggerLevel: this.matterbridge.logLevel,
|
|
940
953
|
fileLogger: this.matterbridge.fileLogger,
|
|
@@ -2120,16 +2133,28 @@ export class Frontend extends EventEmitter {
|
|
|
2120
2133
|
wssSendUpdateRequired(version, devVersion = false) {
|
|
2121
2134
|
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
2122
2135
|
return;
|
|
2123
|
-
this.log.debug('Sending
|
|
2136
|
+
this.log.debug('Sending a matterbridge version update required message to all connected clients');
|
|
2124
2137
|
this.updateRequired = true;
|
|
2125
2138
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'update_required', success: true, response: { version, devVersion } });
|
|
2126
2139
|
}
|
|
2127
2140
|
wssSendPluginUpdateRequired(plugin, version, devVersion = false) {
|
|
2128
2141
|
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
2129
2142
|
return;
|
|
2130
|
-
this.log.debug('Sending a plugin update required message to all connected clients');
|
|
2143
|
+
this.log.debug('Sending a plugin version update required message to all connected clients');
|
|
2131
2144
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'plugin_update_required', success: true, response: { plugin, version, devVersion } });
|
|
2132
2145
|
}
|
|
2146
|
+
wssSendPluginStatusUpdate(plugin, status) {
|
|
2147
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
2148
|
+
return;
|
|
2149
|
+
this.log.debug('Sending a plugin status update message to all connected clients');
|
|
2150
|
+
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'plugin_status_update', success: true, response: { plugin, status } });
|
|
2151
|
+
}
|
|
2152
|
+
wssSendMatterbridgeStatusUpdate(status) {
|
|
2153
|
+
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
2154
|
+
return;
|
|
2155
|
+
this.log.debug('Sending a matterbridge status update message to all connected clients');
|
|
2156
|
+
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'matterbridge_status_update', success: true, response: { status } });
|
|
2157
|
+
}
|
|
2133
2158
|
wssSendCpuUpdate(cpuUsage, processCpuUsage) {
|
|
2134
2159
|
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
2135
2160
|
return;
|
package/dist/helpers.js
CHANGED
|
@@ -61,7 +61,7 @@ export async function addVirtualDevices(matterbridge, aggregatorEndpoint) {
|
|
|
61
61
|
if (matterbridge.virtualMode !== 'disabled' && matterbridge.bridgeMode === 'bridge' && aggregatorEndpoint) {
|
|
62
62
|
matterbridge.log.notice(`Creating virtual devices for Matterbridge server node...`);
|
|
63
63
|
await addVirtualDevice(aggregatorEndpoint, 'Restart Matterbridge', matterbridge.virtualMode, async () => {
|
|
64
|
-
if (matterbridge.restartMode === '')
|
|
64
|
+
if (matterbridge.restartMode === 'none')
|
|
65
65
|
await matterbridge.restartProcess();
|
|
66
66
|
else
|
|
67
67
|
await matterbridge.shutdownProcess();
|
package/dist/matterbridge.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { Endpoint, ServerNode } from '@matter/node';
|
|
|
5
5
|
import { AggregatorEndpoint } from '@matter/node/endpoints/aggregator';
|
|
6
6
|
import { type DeviceCertification } from '@matter/protocol';
|
|
7
7
|
import { DeviceTypeId, VendorId } from '@matter/types/datatype';
|
|
8
|
-
import type { ApiMatter, ApiSettings, MaybePromise, PlatformMatterbridge, SharedMatterbridge, SystemInformation } from '@matterbridge/types';
|
|
8
|
+
import type { ApiMatter, ApiSettings, BridgeMode, BridgeStatus, MaybePromise, PlatformMatterbridge, RestartMode, SharedMatterbridge, SystemInformation, VirtualMode } from '@matterbridge/types';
|
|
9
9
|
import { AnsiLogger, LogLevel } from 'node-ansi-logger';
|
|
10
10
|
import { type NodeStorage, NodeStorageManager } from 'node-persist-manager';
|
|
11
11
|
import { DeviceManager } from './deviceManager.js';
|
|
@@ -50,9 +50,10 @@ export declare class Matterbridge extends EventEmitter<MatterbridgeEvents> {
|
|
|
50
50
|
dockerVersion: string | undefined;
|
|
51
51
|
dockerLatestVersion: string | undefined;
|
|
52
52
|
dockerDevVersion: string | undefined;
|
|
53
|
-
bridgeMode:
|
|
54
|
-
restartMode:
|
|
55
|
-
virtualMode:
|
|
53
|
+
bridgeMode: BridgeMode;
|
|
54
|
+
restartMode: RestartMode;
|
|
55
|
+
virtualMode: VirtualMode;
|
|
56
|
+
bridgeStatus: BridgeStatus;
|
|
56
57
|
readonly profile: string | undefined;
|
|
57
58
|
readonly log: AnsiLogger;
|
|
58
59
|
logLevel: LogLevel;
|
|
@@ -84,6 +85,7 @@ export declare class Matterbridge extends EventEmitter<MatterbridgeEvents> {
|
|
|
84
85
|
private readonly environment;
|
|
85
86
|
matterStorageService: StorageService | undefined;
|
|
86
87
|
matterStorageManager: StorageManager | undefined;
|
|
88
|
+
private serverNodeStorageManagers;
|
|
87
89
|
matterbridgeContext: StorageContext | undefined;
|
|
88
90
|
controllerContext: StorageContext | undefined;
|
|
89
91
|
mdnsInterface: string | undefined;
|
|
@@ -135,6 +137,7 @@ export declare class Matterbridge extends EventEmitter<MatterbridgeEvents> {
|
|
|
135
137
|
shutdownProcessAndReset(): Promise<void>;
|
|
136
138
|
shutdownProcessAndFactoryReset(): Promise<void>;
|
|
137
139
|
private cleanup;
|
|
140
|
+
private sendPluginStatusUpdate;
|
|
138
141
|
private startBridge;
|
|
139
142
|
private startChildbridge;
|
|
140
143
|
private startController;
|
package/dist/matterbridge.js
CHANGED
|
@@ -72,9 +72,10 @@ export class Matterbridge extends EventEmitter {
|
|
|
72
72
|
dockerVersion;
|
|
73
73
|
dockerLatestVersion;
|
|
74
74
|
dockerDevVersion;
|
|
75
|
-
bridgeMode = '';
|
|
76
|
-
restartMode = '';
|
|
75
|
+
bridgeMode = 'none';
|
|
76
|
+
restartMode = 'none';
|
|
77
77
|
virtualMode = 'outlet';
|
|
78
|
+
bridgeStatus = 'inactive';
|
|
78
79
|
profile = getParameter('profile');
|
|
79
80
|
log = new AnsiLogger({
|
|
80
81
|
logName: 'Matterbridge',
|
|
@@ -116,6 +117,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
116
117
|
environment = Environment.default;
|
|
117
118
|
matterStorageService;
|
|
118
119
|
matterStorageManager;
|
|
120
|
+
serverNodeStorageManagers = new Map();
|
|
119
121
|
matterbridgeContext;
|
|
120
122
|
controllerContext;
|
|
121
123
|
mdnsInterface;
|
|
@@ -230,6 +232,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
230
232
|
bridgeMode: this.bridgeMode,
|
|
231
233
|
restartMode: this.restartMode,
|
|
232
234
|
virtualMode: this.virtualMode,
|
|
235
|
+
bridgeStatus: this.bridgeStatus,
|
|
233
236
|
profile: this.profile,
|
|
234
237
|
readOnly: hasParameter('readonly'),
|
|
235
238
|
shellyBoard: false,
|
|
@@ -344,7 +347,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
344
347
|
const packageName = msg.result.packageName.replace(/@.*$/, '');
|
|
345
348
|
if (packageName === 'matterbridge') {
|
|
346
349
|
this.log.info('Matterbridge has been updated. Full restart required.');
|
|
347
|
-
if (this.restartMode !== '')
|
|
350
|
+
if (this.restartMode !== 'none')
|
|
348
351
|
await this.cleanup('updating...', false);
|
|
349
352
|
}
|
|
350
353
|
}
|
|
@@ -732,7 +735,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
732
735
|
(hasParameter('bridge') || (!hasParameter('childbridge') && (await this.nodeContext?.get('bridgeMode', '')) === 'bridge') ? 'mode bridge ' : '') +
|
|
733
736
|
(hasParameter('childbridge') || (!hasParameter('bridge') && (await this.nodeContext?.get('bridgeMode', '')) === 'childbridge') ? 'mode childbridge ' : '') +
|
|
734
737
|
(hasParameter('controller') ? 'mode controller ' : '') +
|
|
735
|
-
(this.restartMode === '' ? '' : 'restart mode ' + this.restartMode + ' ') +
|
|
738
|
+
(this.restartMode === 'none' ? '' : 'restart mode ' + this.restartMode + ' ') +
|
|
736
739
|
'running on ' + this.systemInformation.osType + ' (v.' + this.systemInformation.osRelease + ') platform ' + this.systemInformation.osPlatform + ' arch ' + this.systemInformation.osArch);
|
|
737
740
|
const minNodeVersion = 20;
|
|
738
741
|
const nodeVersion = process.versions.node;
|
|
@@ -829,6 +832,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
829
832
|
const storageContext = storageManager?.createContext('persist');
|
|
830
833
|
await storageContext?.set('serialNumber', this.aggregatorSerialNumber);
|
|
831
834
|
await storageContext?.set('uniqueId', this.aggregatorUniqueId);
|
|
835
|
+
await storageManager.close();
|
|
832
836
|
}
|
|
833
837
|
}
|
|
834
838
|
catch (error) {
|
|
@@ -853,6 +857,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
853
857
|
await matterStorageManager.createContext('root')?.clearAll();
|
|
854
858
|
await matterStorageManager.createContext('sessions')?.clearAll();
|
|
855
859
|
await matterStorageManager.createContext('persist')?.clearAll();
|
|
860
|
+
await matterStorageManager.close();
|
|
856
861
|
this.log.notice(`Reset commissioning for plugin ${plg}${plugin.name}${nt} done! Remove the device from the controller.`);
|
|
857
862
|
}
|
|
858
863
|
else {
|
|
@@ -1206,6 +1211,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1206
1211
|
this.emit('cleanup_started');
|
|
1207
1212
|
this.hasCleanupStarted = true;
|
|
1208
1213
|
this.log.info(message);
|
|
1214
|
+
this.server.request({ type: 'frontend_matterbridgestatusupdate', src: 'matterbridge', dst: 'frontend', params: { status: (this.bridgeStatus = 'stopping') } });
|
|
1209
1215
|
if (this.startMatterInterval) {
|
|
1210
1216
|
clearInterval(this.startMatterInterval);
|
|
1211
1217
|
this.startMatterInterval = undefined;
|
|
@@ -1296,6 +1302,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1296
1302
|
await storageManager?.createContext('fabrics')?.clearAll();
|
|
1297
1303
|
await storageManager?.createContext('root')?.clearAll();
|
|
1298
1304
|
await storageManager?.createContext('sessions')?.clearAll();
|
|
1305
|
+
await storageManager?.close();
|
|
1299
1306
|
}
|
|
1300
1307
|
}
|
|
1301
1308
|
for (const device of this.devices.array()) {
|
|
@@ -1306,6 +1313,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1306
1313
|
await storageManager?.createContext('fabrics')?.clearAll();
|
|
1307
1314
|
await storageManager?.createContext('root')?.clearAll();
|
|
1308
1315
|
await storageManager?.createContext('sessions')?.clearAll();
|
|
1316
|
+
await storageManager?.close();
|
|
1309
1317
|
}
|
|
1310
1318
|
}
|
|
1311
1319
|
this.log.info('Matter storage reset done! Remove the bridge from the controller.');
|
|
@@ -1354,6 +1362,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1354
1362
|
unlinkSafe(path.join(this.matterbridgeDirectory, MATTER_STORAGE_DIR, device.deviceName.replace(/[ .]/g, ''), 'root.subscriptions.subscriptions'), this.log);
|
|
1355
1363
|
}
|
|
1356
1364
|
}
|
|
1365
|
+
this.server.request({ type: 'frontend_matterbridgestatusupdate', src: 'matterbridge', dst: 'frontend', params: { status: (this.bridgeStatus = 'stopped') } });
|
|
1357
1366
|
await this.frontend.stop();
|
|
1358
1367
|
this.frontend.destroy();
|
|
1359
1368
|
this.plugins.destroy();
|
|
@@ -1442,16 +1451,36 @@ export class Matterbridge extends EventEmitter {
|
|
|
1442
1451
|
this.log.debug('Cleanup already started...');
|
|
1443
1452
|
}
|
|
1444
1453
|
}
|
|
1454
|
+
sendPluginStatusUpdate(plugin) {
|
|
1455
|
+
this.server.request({
|
|
1456
|
+
type: 'frontend_pluginstatusupdate',
|
|
1457
|
+
src: 'matterbridge',
|
|
1458
|
+
dst: 'frontend',
|
|
1459
|
+
params: {
|
|
1460
|
+
plugin: plugin.name,
|
|
1461
|
+
status: {
|
|
1462
|
+
locked: plugin.locked,
|
|
1463
|
+
error: plugin.error,
|
|
1464
|
+
enabled: plugin.enabled,
|
|
1465
|
+
loaded: plugin.loaded,
|
|
1466
|
+
started: plugin.started,
|
|
1467
|
+
configured: plugin.configured,
|
|
1468
|
+
registeredDevices: plugin.registeredDevices,
|
|
1469
|
+
},
|
|
1470
|
+
},
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1445
1473
|
async startBridge() {
|
|
1446
1474
|
if (!this.matterStorageManager)
|
|
1447
1475
|
throw new Error('No storage manager initialized');
|
|
1448
1476
|
if (!this.matterbridgeContext)
|
|
1449
1477
|
throw new Error('No storage context initialized');
|
|
1478
|
+
this.server.request({ type: 'frontend_matterbridgestatusupdate', src: 'matterbridge', dst: 'frontend', params: { status: (this.bridgeStatus = 'starting') } });
|
|
1450
1479
|
this.serverNode = await this.createServerNode(this.matterbridgeContext, this.port ? this.port++ : undefined, this.passcode ? this.passcode++ : undefined, this.discriminator ? this.discriminator++ : undefined);
|
|
1451
1480
|
this.aggregatorNode = await this.createAggregatorNode(this.matterbridgeContext);
|
|
1452
1481
|
await this.serverNode.add(this.aggregatorNode);
|
|
1453
1482
|
await addVirtualDevices(this, this.aggregatorNode);
|
|
1454
|
-
await this.startPlugins();
|
|
1483
|
+
await this.startPlugins(false, true);
|
|
1455
1484
|
this.log.debug('Starting start matter interval in bridge mode...');
|
|
1456
1485
|
this.frontend.wssSendSnackbarMessage(`The bridge is starting...`, 0, 'info');
|
|
1457
1486
|
let failCount = 0;
|
|
@@ -1459,7 +1488,6 @@ export class Matterbridge extends EventEmitter {
|
|
|
1459
1488
|
void (async () => {
|
|
1460
1489
|
if (failCount && failCount % 10 === 0) {
|
|
1461
1490
|
this.frontend.wssSendSnackbarMessage(`The bridge is still starting...`, 10, 'info');
|
|
1462
|
-
this.frontend.wssSendRefreshRequired('plugins');
|
|
1463
1491
|
}
|
|
1464
1492
|
for (const plugin of this.plugins) {
|
|
1465
1493
|
if (!plugin.enabled)
|
|
@@ -1475,8 +1503,10 @@ export class Matterbridge extends EventEmitter {
|
|
|
1475
1503
|
this.frontend.wssSendSnackbarMessage(`The bridge is offline. Startup halted due to plugin errors.`, 0, 'error');
|
|
1476
1504
|
this.frontend.wssSendRefreshRequired('plugins');
|
|
1477
1505
|
this.frontend.wssSendCloseSnackbarMessage(`The bridge is starting...`);
|
|
1506
|
+
this.server.request({ type: 'frontend_matterbridgestatusupdate', src: 'matterbridge', dst: 'frontend', params: { status: (this.bridgeStatus = 'error') } });
|
|
1478
1507
|
return;
|
|
1479
1508
|
}
|
|
1509
|
+
this.sendPluginStatusUpdate(plugin);
|
|
1480
1510
|
if (!plugin.loaded || !plugin.started) {
|
|
1481
1511
|
this.log.debug(`Waiting (failSafeCount=${failCount}/${this.failCountLimit}) in startMatterInterval interval for plugin ${plg}${plugin.name}${db} loaded: ${plugin.loaded} started: ${plugin.started}...`);
|
|
1482
1512
|
failCount++;
|
|
@@ -1512,20 +1542,20 @@ export class Matterbridge extends EventEmitter {
|
|
|
1512
1542
|
plugin.error = true;
|
|
1513
1543
|
this.log.error(`Error configuring plugin ${plg}${plugin.name}${er}`, error);
|
|
1514
1544
|
}
|
|
1545
|
+
this.sendPluginStatusUpdate(plugin);
|
|
1515
1546
|
}
|
|
1516
|
-
this.frontend.wssSendRefreshRequired('plugins');
|
|
1517
1547
|
})();
|
|
1518
1548
|
}, 30 * 1000).unref();
|
|
1519
1549
|
this.reachabilityTimeout = setTimeout(() => {
|
|
1520
1550
|
this.log.info(`Setting reachability to true for ${plg}Matterbridge${db}`);
|
|
1521
1551
|
if (this.aggregatorNode)
|
|
1522
|
-
fireAndForget(this.setAggregatorReachability(this.aggregatorNode, true), this.log, `
|
|
1552
|
+
fireAndForget(this.setAggregatorReachability(this.aggregatorNode, true), this.log, `Failed to set aggregator node reachability for Matterbridge`);
|
|
1523
1553
|
}, 60 * 1000).unref();
|
|
1524
1554
|
this.emit('bridge_started');
|
|
1525
1555
|
this.log.notice('Matterbridge bridge started successfully');
|
|
1526
|
-
this.
|
|
1527
|
-
this.
|
|
1528
|
-
this.
|
|
1556
|
+
this.server.request({ type: 'frontend_matterbridgestatusupdate', src: 'matterbridge', dst: 'frontend', params: { status: (this.bridgeStatus = 'started') } });
|
|
1557
|
+
this.server.request({ type: 'frontend_refreshrequired', src: 'matterbridge', dst: 'frontend', params: { changed: 'plugins' } });
|
|
1558
|
+
this.server.request({ type: 'frontend_closesnackbarmessage', src: 'matterbridge', dst: 'frontend', params: { message: `The bridge is starting...` } });
|
|
1529
1559
|
})();
|
|
1530
1560
|
}, Number(process.env['MATTERBRIDGE_START_MATTER_INTERVAL_MS']) || this.startMatterIntervalMs);
|
|
1531
1561
|
}
|
|
@@ -1533,6 +1563,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
1533
1563
|
if (!this.matterStorageManager)
|
|
1534
1564
|
throw new Error('No storage manager initialized');
|
|
1535
1565
|
const { wait } = await import('@matterbridge/utils/wait');
|
|
1566
|
+
this.server.request({ type: 'frontend_matterbridgestatusupdate', src: 'matterbridge', dst: 'frontend', params: { status: (this.bridgeStatus = 'starting') } });
|
|
1536
1567
|
this.log.debug('Loading all plugins in childbridge mode...');
|
|
1537
1568
|
await this.startPlugins(true, false);
|
|
1538
1569
|
this.log.debug('Creating server nodes for DynamicPlatform plugins and starting all plugins in childbridge mode...');
|
|
@@ -1548,7 +1579,6 @@ export class Matterbridge extends EventEmitter {
|
|
|
1548
1579
|
void (async () => {
|
|
1549
1580
|
if (failCount && failCount % 10 === 0) {
|
|
1550
1581
|
this.frontend.wssSendSnackbarMessage(`The bridge is still starting...`, 10, 'info');
|
|
1551
|
-
this.frontend.wssSendRefreshRequired('plugins');
|
|
1552
1582
|
}
|
|
1553
1583
|
let allStarted = true;
|
|
1554
1584
|
for (const plugin of this.plugins.array()) {
|
|
@@ -1565,8 +1595,10 @@ export class Matterbridge extends EventEmitter {
|
|
|
1565
1595
|
this.frontend.wssSendSnackbarMessage(`The bridge is offline. Startup halted due to plugin errors.`, 0, 'error');
|
|
1566
1596
|
this.frontend.wssSendRefreshRequired('plugins');
|
|
1567
1597
|
this.frontend.wssSendCloseSnackbarMessage(`The bridge is starting...`);
|
|
1598
|
+
this.server.request({ type: 'frontend_matterbridgestatusupdate', src: 'matterbridge', dst: 'frontend', params: { status: (this.bridgeStatus = 'error') } });
|
|
1568
1599
|
return;
|
|
1569
1600
|
}
|
|
1601
|
+
this.sendPluginStatusUpdate(plugin);
|
|
1570
1602
|
this.log.debug(`Checking plugin ${plg}${plugin.name}${db} to start matter in childbridge mode...`);
|
|
1571
1603
|
if (!plugin.loaded || !plugin.started) {
|
|
1572
1604
|
allStarted = false;
|
|
@@ -1600,8 +1632,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
1600
1632
|
plugin.error = true;
|
|
1601
1633
|
this.log.error(`Error configuring plugin ${plg}${plugin.name}${er}`, error);
|
|
1602
1634
|
}
|
|
1635
|
+
this.sendPluginStatusUpdate(plugin);
|
|
1603
1636
|
}
|
|
1604
|
-
this.frontend.wssSendRefreshRequired('plugins');
|
|
1605
1637
|
})();
|
|
1606
1638
|
}, 30 * 1000).unref();
|
|
1607
1639
|
for (const plugin of this.plugins.array()) {
|
|
@@ -1638,9 +1670,9 @@ export class Matterbridge extends EventEmitter {
|
|
|
1638
1670
|
}
|
|
1639
1671
|
this.emit('childbridge_started');
|
|
1640
1672
|
this.log.notice('Matterbridge childbridge started successfully');
|
|
1641
|
-
this.
|
|
1642
|
-
this.
|
|
1643
|
-
this.
|
|
1673
|
+
this.server.request({ type: 'frontend_matterbridgestatusupdate', src: 'matterbridge', dst: 'frontend', params: { status: (this.bridgeStatus = 'started') } });
|
|
1674
|
+
this.server.request({ type: 'frontend_refreshrequired', src: 'matterbridge', dst: 'frontend', params: { changed: 'plugins' } });
|
|
1675
|
+
this.server.request({ type: 'frontend_closesnackbarmessage', src: 'matterbridge', dst: 'frontend', params: { message: `The bridge is starting...` } });
|
|
1644
1676
|
})();
|
|
1645
1677
|
}, Number(process.env['MATTERBRIDGE_START_MATTER_INTERVAL_MS']) || this.startMatterIntervalMs);
|
|
1646
1678
|
}
|
|
@@ -1670,6 +1702,11 @@ export class Matterbridge extends EventEmitter {
|
|
|
1670
1702
|
async stopMatterStorage() {
|
|
1671
1703
|
this.log.info('Closing matter node storage...');
|
|
1672
1704
|
await this.matterStorageManager?.close();
|
|
1705
|
+
for (const [storeId, storageManager] of this.serverNodeStorageManagers) {
|
|
1706
|
+
this.log.debug(`Closing server node storage context manager for ${plg}${storeId}${db}...`);
|
|
1707
|
+
await storageManager.close();
|
|
1708
|
+
}
|
|
1709
|
+
this.serverNodeStorageManagers.clear();
|
|
1673
1710
|
this.matterStorageService = undefined;
|
|
1674
1711
|
this.matterStorageManager = undefined;
|
|
1675
1712
|
this.matterbridgeContext = undefined;
|
|
@@ -1683,6 +1720,8 @@ export class Matterbridge extends EventEmitter {
|
|
|
1683
1720
|
this.log.info(`Creating server node storage context "${storeId}.persist" for ${storeId}...`);
|
|
1684
1721
|
await createDirectory(path.join(this.matterbridgeDirectory, MATTER_STORAGE_DIR, storeId), `Matter node storage directory for ${storeId}`, this.log);
|
|
1685
1722
|
const storageManager = await this.matterStorageService.open(storeId);
|
|
1723
|
+
await this.serverNodeStorageManagers.get(storeId)?.close();
|
|
1724
|
+
this.serverNodeStorageManagers.set(storeId, storageManager);
|
|
1686
1725
|
const storageContext = storageManager.createContext('persist');
|
|
1687
1726
|
const random = randomBytes(8).toString('hex');
|
|
1688
1727
|
await storageContext.set('storeId', storeId);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.9.2-dev-
|
|
3
|
+
"version": "3.9.2-dev-20260622-2bad6bf",
|
|
4
4
|
"description": "Matterbridge core library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -129,11 +129,11 @@
|
|
|
129
129
|
"CHANGELOG.md"
|
|
130
130
|
],
|
|
131
131
|
"dependencies": {
|
|
132
|
-
"@matter/main": "0.17.
|
|
133
|
-
"@matterbridge/dgram": "3.9.2-dev-
|
|
134
|
-
"@matterbridge/thread": "3.9.2-dev-
|
|
135
|
-
"@matterbridge/types": "3.9.2-dev-
|
|
136
|
-
"@matterbridge/utils": "3.9.2-dev-
|
|
132
|
+
"@matter/main": "0.17.4-alpha.0-20260621-81ba50a6a",
|
|
133
|
+
"@matterbridge/dgram": "3.9.2-dev-20260622-2bad6bf",
|
|
134
|
+
"@matterbridge/thread": "3.9.2-dev-20260622-2bad6bf",
|
|
135
|
+
"@matterbridge/types": "3.9.2-dev-20260622-2bad6bf",
|
|
136
|
+
"@matterbridge/utils": "3.9.2-dev-20260622-2bad6bf",
|
|
137
137
|
"escape-html": "1.0.3",
|
|
138
138
|
"express": "5.2.1",
|
|
139
139
|
"express-rate-limit": "8.5.2",
|