matterbridge 3.2.9-dev-20250924-c639a33 → 3.2.9-dev-20250926-bb89bea

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/frontend.js CHANGED
@@ -21,6 +21,7 @@ export class Frontend extends EventEmitter {
21
21
  matterbridge;
22
22
  log;
23
23
  port = 8283;
24
+ listening = false;
24
25
  expressApp;
25
26
  httpServer;
26
27
  httpsServer;
@@ -63,6 +64,7 @@ export class Frontend extends EventEmitter {
63
64
  if (hasParameter('ingress')) {
64
65
  this.httpServer.listen(this.port, '0.0.0.0', () => {
65
66
  this.log.info(`The frontend http server is listening on ${UNDERLINE}http://0.0.0.0:${this.port}${UNDERLINEOFF}${rs}`);
67
+ this.listening = true;
66
68
  this.emit('server_listening', 'http', this.port, '0.0.0.0');
67
69
  });
68
70
  }
@@ -72,6 +74,7 @@ export class Frontend extends EventEmitter {
72
74
  this.log.info(`The frontend http server is listening on ${UNDERLINE}http://${this.matterbridge.systemInformation.ipv4Address}:${this.port}${UNDERLINEOFF}${rs}`);
73
75
  if (this.matterbridge.systemInformation.ipv6Address !== '')
74
76
  this.log.info(`The frontend http server is listening on ${UNDERLINE}http://[${this.matterbridge.systemInformation.ipv6Address}]:${this.port}${UNDERLINEOFF}${rs}`);
77
+ this.listening = true;
75
78
  this.emit('server_listening', 'http', this.port);
76
79
  });
77
80
  }
@@ -164,6 +167,7 @@ export class Frontend extends EventEmitter {
164
167
  if (hasParameter('ingress')) {
165
168
  this.httpsServer.listen(this.port, '0.0.0.0', () => {
166
169
  this.log.info(`The frontend https server is listening on ${UNDERLINE}https://0.0.0.0:${this.port}${UNDERLINEOFF}${rs}`);
170
+ this.listening = true;
167
171
  this.emit('server_listening', 'https', this.port, '0.0.0.0');
168
172
  });
169
173
  }
@@ -173,6 +177,7 @@ export class Frontend extends EventEmitter {
173
177
  this.log.info(`The frontend https server is listening on ${UNDERLINE}https://${this.matterbridge.systemInformation.ipv4Address}:${this.port}${UNDERLINEOFF}${rs}`);
174
178
  if (this.matterbridge.systemInformation.ipv6Address !== '')
175
179
  this.log.info(`The frontend https server is listening on ${UNDERLINE}https://[${this.matterbridge.systemInformation.ipv6Address}]:${this.port}${UNDERLINEOFF}${rs}`);
180
+ this.listening = true;
176
181
  this.emit('server_listening', 'https', this.port);
177
182
  });
178
183
  }
@@ -581,6 +586,7 @@ export class Frontend extends EventEmitter {
581
586
  this.log.debug('Closing http server...');
582
587
  this.httpServer.close();
583
588
  this.log.debug('Http server closed successfully');
589
+ this.listening = false;
584
590
  this.emit('server_stopped');
585
591
  this.httpServer.removeAllListeners();
586
592
  this.httpServer = undefined;
@@ -590,6 +596,7 @@ export class Frontend extends EventEmitter {
590
596
  this.log.debug('Closing https server...');
591
597
  this.httpsServer.close();
592
598
  this.log.debug('Https server closed successfully');
599
+ this.listening = false;
593
600
  this.emit('server_stopped');
594
601
  this.httpsServer.removeAllListeners();
595
602
  this.httpsServer = undefined;
@@ -1709,15 +1716,17 @@ export class Frontend extends EventEmitter {
1709
1716
  const maxContinuousLength = 100;
1710
1717
  const keepStartLength = 20;
1711
1718
  const keepEndLength = 20;
1712
- message = message
1713
- .split(' ')
1714
- .map((word) => {
1715
- if (word.length > maxContinuousLength) {
1716
- return word.slice(0, keepStartLength) + ' ... ' + word.slice(-keepEndLength);
1717
- }
1718
- return word;
1719
- })
1720
- .join(' ');
1719
+ if (level !== 'spawn') {
1720
+ message = message
1721
+ .split(' ')
1722
+ .map((word) => {
1723
+ if (word.length > maxContinuousLength) {
1724
+ return word.slice(0, keepStartLength) + ' ... ' + word.slice(-keepEndLength);
1725
+ }
1726
+ return word;
1727
+ })
1728
+ .join(' ');
1729
+ }
1721
1730
  this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'log', success: true, response: { level, time, name, message } });
1722
1731
  }
1723
1732
  wssSendRefreshRequired(changed, params) {
@@ -654,6 +654,8 @@ export class Matterbridge extends EventEmitter {
654
654
  this.shutdown = true;
655
655
  return;
656
656
  }
657
+ if (getIntParameter('frontend') !== 0 || getIntParameter('frontend') === undefined)
658
+ await this.frontend.start(getIntParameter('frontend'));
657
659
  try {
658
660
  await this.startMatterStorage();
659
661
  if (this.aggregatorSerialNumber && this.aggregatorUniqueId && this.matterStorageService) {
@@ -699,8 +701,6 @@ export class Matterbridge extends EventEmitter {
699
701
  this.shutdown = true;
700
702
  return;
701
703
  }
702
- if (getIntParameter('frontend') !== 0 || getIntParameter('frontend') === undefined)
703
- await this.frontend.start(getIntParameter('frontend'));
704
704
  clearTimeout(this.checkUpdateTimeout);
705
705
  this.checkUpdateTimeout = setTimeout(async () => {
706
706
  const { checkUpdates } = await import('./update.js');
@@ -737,7 +737,7 @@ export class Matterbridge extends EventEmitter {
737
737
  return;
738
738
  }
739
739
  }
740
- async startPlugins() {
740
+ async startPlugins(wait = false, start = true) {
741
741
  for (const plugin of this.plugins) {
742
742
  plugin.configJson = await this.plugins.loadConfig(plugin);
743
743
  plugin.schemaJson = await this.plugins.loadSchema(plugin);
@@ -757,7 +757,10 @@ export class Matterbridge extends EventEmitter {
757
757
  plugin.started = false;
758
758
  plugin.configured = false;
759
759
  plugin.registeredDevices = undefined;
760
- this.plugins.load(plugin, true, 'Matterbridge is starting');
760
+ if (wait)
761
+ await this.plugins.load(plugin, start, 'Matterbridge is starting');
762
+ else
763
+ this.plugins.load(plugin, start, 'Matterbridge is starting');
761
764
  }
762
765
  this.frontend.wssSendRefreshRequired('plugins');
763
766
  }
@@ -1252,7 +1255,14 @@ export class Matterbridge extends EventEmitter {
1252
1255
  async startChildbridge(delay = 1000) {
1253
1256
  if (!this.matterStorageManager)
1254
1257
  throw new Error('No storage manager initialized');
1255
- await this.startPlugins();
1258
+ this.log.debug('Loading all plugins in childbridge mode...');
1259
+ await this.startPlugins(true, false);
1260
+ this.log.debug('Creating server nodes for DynamicPlatform plugins and starting all plugins in childbridge mode...');
1261
+ for (const plugin of this.plugins.array().filter((p) => p.enabled && !p.error)) {
1262
+ if (plugin.type === 'DynamicPlatform')
1263
+ await this.createDynamicPlugin(plugin);
1264
+ this.plugins.start(plugin, 'Matterbridge is starting');
1265
+ }
1256
1266
  this.log.debug('Starting start matter interval in childbridge mode...');
1257
1267
  let failCount = 0;
1258
1268
  this.startMatterInterval = setInterval(async () => {
@@ -1280,9 +1290,6 @@ export class Matterbridge extends EventEmitter {
1280
1290
  plugin.error = true;
1281
1291
  }
1282
1292
  }
1283
- if (plugin.type === 'DynamicPlatform' && !plugin.locked) {
1284
- await this.createDynamicPlugin(plugin);
1285
- }
1286
1293
  }
1287
1294
  if (!allStarted)
1288
1295
  return;
@@ -19,31 +19,34 @@ export async function spawnCommand(matterbridge, command, args, packageName) {
19
19
  });
20
20
  childProcess.on('error', (err) => {
21
21
  matterbridge.log.error(`Failed to start child process "${cmdLine}": ${err.message}`);
22
+ matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit-error', 'Spawn process error');
22
23
  reject(err);
23
24
  });
24
25
  childProcess.on('close', (code, signal) => {
25
26
  matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', `child process closed with code ${code} and signal ${signal}`);
26
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit', 'Child process closed');
27
27
  if (code === 0) {
28
28
  if (cmdLine.startsWith('npm install -g'))
29
29
  matterbridge.log.notice(`Package ${cmdLine.replace('npm install -g ', '').replace('--verbose', '').replace('--omit=dev', '')} installed correctly`);
30
30
  matterbridge.log.debug(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`);
31
+ matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit-success', 'Child process closed');
31
32
  resolve(true);
32
33
  }
33
34
  else {
34
35
  matterbridge.log.error(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`);
36
+ matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit-error', 'Child process closed');
35
37
  reject(new Error(`Child process "${cmdLine}" closed with code ${code} and signal ${signal}`));
36
38
  }
37
39
  });
38
40
  childProcess.on('exit', (code, signal) => {
39
41
  matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', `child process exited with code ${code} and signal ${signal}`);
40
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit', 'Child process exited');
41
42
  if (code === 0) {
42
43
  matterbridge.log.debug(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`);
44
+ matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit-success', 'Child process exited');
43
45
  resolve(true);
44
46
  }
45
47
  else {
46
48
  matterbridge.log.error(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`);
49
+ matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn-exit-error', 'Child process exited');
47
50
  reject(new Error(`Child process "${cmdLine}" exited with code ${code} and signal ${signal}`));
48
51
  }
49
52
  });
@@ -54,15 +57,21 @@ export async function spawnCommand(matterbridge, command, args, packageName) {
54
57
  if (childProcess.stdout) {
55
58
  childProcess.stdout.on('data', (data) => {
56
59
  const message = data.toString().trim();
57
- matterbridge.log.debug(`Spawn output (stdout): ${message}`);
58
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', message);
60
+ const lines = message.split('\n');
61
+ for (const line of lines) {
62
+ matterbridge.log.debug(`Spawn output (stdout): ${line}`);
63
+ matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', line);
64
+ }
59
65
  });
60
66
  }
61
67
  if (childProcess.stderr) {
62
68
  childProcess.stderr.on('data', (data) => {
63
69
  const message = data.toString().trim();
64
- matterbridge.log.debug(`Spawn verbose (stderr): ${message}`);
65
- matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', message);
70
+ const lines = message.split('\n');
71
+ for (const line of lines) {
72
+ matterbridge.log.debug(`Spawn verbose (stderr): ${line}`);
73
+ matterbridge.frontend.wssSendLogMessage('spawn', matterbridge.log.now(), 'Matterbridge:spawn', line);
74
+ }
66
75
  });
67
76
  }
68
77
  });