matterbridge 1.1.7 → 1.1.8

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/CHANGELOG.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.1.8] - 2024-03-15
6
+
7
+ ### Added
8
+
9
+ - [cli]: Resolve the plugin name from absolute or relative path or from globally installed modules (see the help).
10
+ - [frontend]: Added some fancy stuff still not visible.
11
+
12
+ ### Fixed
13
+
14
+ - [install]: Fixed the error caused when the controllers disconnect and connect again.
15
+
16
+ ## [1.1.7] - 2024-03-14
17
+
18
+ ### Fixed
19
+
20
+ - [install]: Fixed the install error (thanks https://github.com/khaidakin).
21
+
5
22
  ## [1.1.6] - 2024-03-14
6
23
 
7
24
  ### Added
package/README.md CHANGED
@@ -114,7 +114,7 @@ Matterbridge can run as many plugins as you want.
114
114
 
115
115
  ### Example plugins to show the usage of history in matter
116
116
 
117
- [Contact plugin with history](https://github.com/Luligu/matterbridge-eve-door)
117
+ [Door plugin with history](https://github.com/Luligu/matterbridge-eve-door)
118
118
 
119
119
  [Motion plugin with history](https://github.com/Luligu/matterbridge-eve-motion)
120
120
 
@@ -43,6 +43,7 @@ export declare class Matterbridge {
43
43
  rootDirectory: string;
44
44
  matterbridgeDirectory: string;
45
45
  matterbridgeVersion: string;
46
+ globalModulesDir: string;
46
47
  bridgeMode: 'bridge' | 'childbridge' | 'controller' | '';
47
48
  debugEnabled: boolean;
48
49
  private log;
@@ -84,6 +85,7 @@ export declare class Matterbridge {
84
85
  * @returns {Promise<void>} A promise that resolves when the command line arguments have been processed.
85
86
  */
86
87
  private parseCommandLine;
88
+ private resolvePluginName;
87
89
  /**
88
90
  * Loads a plugin from the specified package.json file path.
89
91
  * @param packageJsonPath - The path to the package.json file of the plugin.
@@ -1 +1 @@
1
- {"version":3,"file":"matterbridge.d.ts","sourceRoot":"","sources":["../src/matterbridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"matterbridge.d.ts","sourceRoot":"","sources":["../src/matterbridge.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,7 @@ import { NodeStorageManager } from 'node-persist-manager';
25
25
  import { AnsiLogger, BRIGHT, RESET, UNDERLINE, UNDERLINEOFF, YELLOW, db, debugStringify, stringify, er, nf, rs, wr } from 'node-ansi-logger';
26
26
  import { fileURLToPath, pathToFileURL } from 'url';
27
27
  import { promises as fs } from 'fs';
28
+ import { execSync } from 'child_process';
28
29
  import express from 'express';
29
30
  import os from 'os';
30
31
  import path from 'path';
@@ -61,6 +62,7 @@ export class Matterbridge {
61
62
  rootDirectory = '';
62
63
  matterbridgeDirectory = '';
63
64
  matterbridgeVersion = '';
65
+ globalModulesDir = '';
64
66
  bridgeMode = '';
65
67
  debugEnabled = false;
66
68
  log;
@@ -124,10 +126,14 @@ export class Matterbridge {
124
126
  - frontend [port]: start the frontend on the given port (default 3000)
125
127
  - debug: enable debug mode (default false)
126
128
  - list: list the registered plugins
127
- - add [plugin path]: register the plugin
128
- - remove [plugin path]: remove the plugin
129
- - enable [plugin path]: enable the plugin
130
- - disable [plugin path]: disable the plugin\n`);
129
+ - add [plugin path]: register the plugin from the given absolute or relative path
130
+ - add [plugin name]: register the globally installed plugin with the given name
131
+ - remove [plugin path]: remove the plugin from the given absolute or relative path
132
+ - remove [plugin name]: remove the globally installed plugin with the given name
133
+ - enable [plugin path]: enable the plugin from the given absolute or relative path
134
+ - enable [plugin name]: enable the globally installed plugin with the given name
135
+ - disable [plugin path]: disable the plugin from the given absolute or relative path
136
+ - disable [plugin name]: disable the globally installed plugin with the given name\n`);
131
137
  process.exit(0);
132
138
  }
133
139
  // set Matterbridge logger
@@ -215,7 +221,7 @@ export class Matterbridge {
215
221
  if (hasParameter('test')) {
216
222
  this.bridgeMode = 'childbridge';
217
223
  MatterbridgeDevice.bridgeMode = 'childbridge';
218
- this.testStartMatterBridge(); // No await do it asyncronously
224
+ await this.testStartMatterBridge(); // No await do it asyncronously
219
225
  }
220
226
  if (hasParameter('bridge')) {
221
227
  this.bridgeMode = 'bridge';
@@ -227,6 +233,8 @@ export class Matterbridge {
227
233
  plugin.started = false;
228
234
  plugin.configured = false;
229
235
  plugin.connected = undefined;
236
+ plugin.qrPairingCode = undefined;
237
+ plugin.manualPairingCode = undefined;
230
238
  this.loadPlugin(plugin); // No await do it asyncronously
231
239
  }
232
240
  await this.startMatterBridge();
@@ -241,11 +249,49 @@ export class Matterbridge {
241
249
  plugin.started = false;
242
250
  plugin.configured = false;
243
251
  plugin.connected = false;
252
+ plugin.qrPairingCode = (await plugin.nodeContext?.get('qrPairingCode', undefined)) ?? undefined;
253
+ plugin.manualPairingCode = (await plugin.nodeContext?.get('manualPairingCode', undefined)) ?? undefined;
244
254
  this.loadPlugin(plugin, true, 'Matterbridge is starting'); // No await do it asyncronously
245
255
  }
246
256
  await this.startMatterBridge();
247
257
  }
248
258
  }
259
+ async resolvePluginName(pluginPath) {
260
+ if (!pluginPath.endsWith('package.json'))
261
+ pluginPath = path.join(pluginPath, 'package.json');
262
+ // Resolve the package.json of the plugin
263
+ let packageJsonPath = path.resolve(pluginPath);
264
+ this.log.debug(`Loading plugin from ${plg}${packageJsonPath}${db}`);
265
+ // Check if the package.json file exists
266
+ let packageJsonExists = false;
267
+ try {
268
+ await fs.access(packageJsonPath);
269
+ packageJsonExists = true;
270
+ }
271
+ catch {
272
+ packageJsonExists = false;
273
+ }
274
+ if (!packageJsonExists) {
275
+ this.log.debug(`Package.json not found at ${packageJsonPath}`);
276
+ this.log.debug(`Trying at ${this.globalModulesDir}`);
277
+ packageJsonPath = path.join(this.globalModulesDir, pluginPath);
278
+ this.log.debug(`Got ${packageJsonPath}`);
279
+ }
280
+ try {
281
+ // Load the package.json of the plugin
282
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
283
+ if (!packageJson.name) {
284
+ this.log.debug(`Package.json name not found at ${packageJsonPath}`);
285
+ return null;
286
+ }
287
+ this.log.debug(`Package.json name: ${plg}${packageJson.name}${db} description: "${nf}${packageJson.description}${db}" found at "${nf}${packageJsonPath}${db}"`);
288
+ return packageJsonPath;
289
+ }
290
+ catch (err) {
291
+ this.log.debug(`Failed to load plugin from ${plg}${packageJsonPath}${er}: ${err}`);
292
+ return null;
293
+ }
294
+ }
249
295
  /**
250
296
  * Loads a plugin from the specified package.json file path.
251
297
  * @param packageJsonPath - The path to the package.json file of the plugin.
@@ -253,10 +299,7 @@ export class Matterbridge {
253
299
  * @returns A Promise that resolves when the plugin is loaded successfully, or rejects with an error if loading fails.
254
300
  */
255
301
  async executeCommandLine(packageJsonPath, mode) {
256
- if (!packageJsonPath.endsWith('package.json'))
257
- packageJsonPath = path.join(packageJsonPath, 'package.json');
258
- // Resolve the package.json of the plugin
259
- packageJsonPath = path.resolve(packageJsonPath);
302
+ packageJsonPath = (await this.resolvePluginName(packageJsonPath)) ?? packageJsonPath;
260
303
  this.log.debug(`Loading plugin from ${plg}${packageJsonPath}${db}`);
261
304
  try {
262
305
  // Load the package.json of the plugin
@@ -405,14 +448,14 @@ export class Matterbridge {
405
448
  * @returns A Promise that resolves when the device is added successfully.
406
449
  */
407
450
  async addDevice(pluginName, device) {
408
- this.log.info(`Adding device ${dev}${device.name}${nf} for plugin ${plg}${pluginName}${nf}`);
451
+ this.log.debug(`Adding device ${dev}${device.name}${db} for plugin ${plg}${pluginName}${db}`);
409
452
  // Check if the plugin is registered
410
453
  const plugin = this.registeredPlugins.find((plugin) => plugin.name === pluginName);
411
454
  if (!plugin) {
412
455
  this.log.error(`addDevice error: device ${dev}${device.name}${nf} plugin ${plg}${pluginName}${er} not found`);
413
456
  return;
414
457
  }
415
- // Add and register the device to the matterbridge in bridge mode
458
+ // Register and add the device to matterbridge aggregator in bridge mode
416
459
  if (this.bridgeMode === 'bridge') {
417
460
  this.matterAggregator.addBridgedDevice(device);
418
461
  this.registeredDevices.push({ plugin: pluginName, device, added: true });
@@ -437,14 +480,14 @@ export class Matterbridge {
437
480
  * @returns {Promise<void>} - A promise that resolves when the storage process is started.
438
481
  */
439
482
  async addBridgedDevice(pluginName, device) {
440
- this.log.info(`Adding bridged device ${dev}${device.name}${nf} for plugin ${plg}${pluginName}${nf}`);
483
+ this.log.debug(`Adding bridged device ${db}${device.name}${nf} for plugin ${plg}${pluginName}${db}`);
441
484
  // Check if the plugin is registered
442
485
  const plugin = this.registeredPlugins.find((plugin) => plugin.name === pluginName);
443
486
  if (!plugin) {
444
487
  this.log.error(`addBridgedDevice error: device ${dev}${device.name}${nf} plugin ${plg}${pluginName}${er} not found`);
445
488
  return;
446
489
  }
447
- // Add and register the device to the matterbridge in bridge mode
490
+ // Register and add the device to matterbridge aggregator in bridge mode
448
491
  if (this.bridgeMode === 'bridge') {
449
492
  this.matterAggregator.addBridgedDevice(device);
450
493
  this.registeredDevices.push({ plugin: pluginName, device, added: true });
@@ -529,37 +572,50 @@ export class Matterbridge {
529
572
  this.log.debug('Storage closed');
530
573
  }
531
574
  async testStartMatterBridge() {
575
+ /*
576
+ this.log.error('****Start forEach registeredPlugin');
577
+ this.registeredPlugins
578
+ .filter((plugin) => plugin.enabled === true)
579
+ .forEach(async (plugin) => {
580
+ plugin.loaded = false;
581
+ plugin.started = false;
582
+ plugin.configured = false;
583
+ plugin.connected = undefined;
584
+ this.log.error(`****Starting registeredPlugin ${plugin.name}`);
585
+ this.loadPlugin(plugin, true, 'Matterbridge is starting');
586
+ });
587
+ this.log.error('****Stop forEach registeredPlugin');
588
+ */
589
+ /*
532
590
  for (const plugin of this.registeredPlugins) {
533
- if (!plugin.enabled)
534
- continue;
535
- // No await do it asyncronously
536
- this.loadPlugin(plugin)
537
- .then(() => {
538
- // No await do it asyncronously
539
- this.startPlugin(plugin)
540
- .then(() => { })
541
- .catch((err) => {
542
- this.log.error(`Failed to start plugin ${plg}${plugin.name}${er}: ${err}`);
591
+ if (!plugin.enabled) continue;
592
+ // No await do it asyncronously
593
+ this.loadPlugin(plugin)
594
+ .then(() => {
595
+ // No await do it asyncronously
596
+ this.startPlugin(plugin)
597
+ .then(() => {})
598
+ .catch((err) => {
599
+ this.log.error(`Failed to start plugin ${plg}${plugin.name}${er}: ${err}`);
543
600
  });
544
601
  })
545
- .catch((err) => {
546
- this.log.error(`Failed to load plugin ${plg}${plugin.name}${er}: ${err}`);
602
+ .catch((err) => {
603
+ this.log.error(`Failed to load plugin ${plg}${plugin.name}${er}: ${err}`);
547
604
  });
548
605
  }
549
606
  for (const plugin of this.registeredPlugins) {
550
- if (!plugin.enabled)
551
- continue;
552
- // Start the interval to check if the plugin is loaded and started
553
- let times = 0;
554
- const interval = setInterval(() => {
555
- times++;
556
- this.log.info(`Waiting ${times} secs for plugin ${plg}${plugin.name}${db} to load (${plugin.loaded}) and start (${plugin.started}) and send devices ...`);
557
- if (!plugin.loaded || !plugin.started)
558
- return;
559
- this.log.info(`Plugin ${plg}${plugin.name}${db} sent ${plugin.registeredDevices} devices`);
560
- clearInterval(interval);
561
- }, 1000);
607
+ if (!plugin.enabled) continue;
608
+ // Start the interval to check if the plugin is loaded and started
609
+ let times = 0;
610
+ const interval = setInterval(() => {
611
+ times++;
612
+ this.log.info(`Waiting ${times} secs for plugin ${plg}${plugin.name}${db} to load (${plugin.loaded}) and start (${plugin.started}) and send devices ...`);
613
+ if (!plugin.loaded || !plugin.started) return;
614
+ this.log.info(`Plugin ${plg}${plugin.name}${db} sent ${plugin.registeredDevices} devices`);
615
+ clearInterval(interval);
616
+ }, 1000);
562
617
  }
618
+ */
563
619
  }
564
620
  async startPlugin(plugin, message, configure = false) {
565
621
  if (!plugin.loaded || !plugin.platform) {
@@ -707,10 +763,10 @@ export class Matterbridge {
707
763
  return;
708
764
  // Start the interval to check if the plugins is started
709
765
  // TODO set a counter or a timeout
710
- this.log.info(`**Starting startMatterBridge interval for plugin ${plg}${plugin.name}${db} loaded: ${plugin.loaded} started: ${plugin.started}...`);
766
+ this.log.debug(`*Starting startMatterBridge interval for plugin ${plg}${plugin.name}${db} loaded: ${plugin.loaded} started: ${plugin.started}...`);
711
767
  const startInterval = setInterval(async () => {
712
768
  if (!plugin.loaded || !plugin.started) {
713
- this.log.info(`***Returning in startMatterBridge interval for plugin ${plg}${plugin.name}${db} loaded: ${plugin.loaded} started: ${plugin.started}...`);
769
+ this.log.info(`**Waiting in startMatterBridge interval for plugin ${plg}${plugin.name}${db} loaded: ${plugin.loaded} started: ${plugin.started}...`);
714
770
  return;
715
771
  }
716
772
  if (plugin.type === 'AccessoryPlatform') {
@@ -744,19 +800,20 @@ export class Matterbridge {
744
800
  });
745
801
  // Start the interval to check if all plugins are loaded and started and so start the matter server
746
802
  // TODO set a counter or a timeout
747
- this.log.info('**Starting start matter interval...');
803
+ this.log.debug('*Starting start matter interval...');
748
804
  const startMatterInterval = setInterval(async () => {
749
805
  let allStarted = true;
750
806
  this.registeredPlugins.forEach((plugin) => {
751
807
  if (!plugin.enabled)
752
808
  return;
753
- this.log.info(`**Waiting in start matter server interval for plugin ${plg}${plugin.name}${db} to load (${plugin.loaded}) and start (${plugin.started}) ...`);
754
809
  if (plugin.enabled && (!plugin.loaded || !plugin.started))
755
810
  allStarted = false;
811
+ if (!allStarted)
812
+ this.log.info(`**Waiting in start matter server interval for plugin ${plg}${plugin.name}${db} to load (${plugin.loaded}) and start (${plugin.started}) ...`);
756
813
  });
757
814
  if (!allStarted)
758
815
  return;
759
- this.log.info('**Starting matter server in start matter server interval...');
816
+ this.log.info('Starting matter server');
760
817
  // Setting reachability to true
761
818
  this.registeredPlugins.forEach((plugin) => {
762
819
  if (!plugin.enabled)
@@ -862,9 +919,15 @@ export class Matterbridge {
862
919
  storageContext.set('manualPairingCode', manualPairingCode);
863
920
  const QrCode = new QrCodeSchema();
864
921
  this.log.info(`Pairing code:\n\n${QrCode.encode(qrPairingCode)}\nManual pairing code: ${manualPairingCode}\n`);
922
+ if (this.bridgeMode === 'bridge') {
923
+ await this.nodeContext?.set('qrPairingCode', qrPairingCode);
924
+ await this.nodeContext?.set('manualPairingCode', manualPairingCode);
925
+ }
865
926
  if (this.bridgeMode === 'childbridge') {
866
927
  const plugin = this.findPlugin(pluginName);
867
928
  if (plugin) {
929
+ await plugin.nodeContext?.set('qrPairingCode', qrPairingCode);
930
+ await plugin.nodeContext?.set('manualPairingCode', manualPairingCode);
868
931
  await this.nodeContext?.set('plugins', this.getBaseRegisteredPlugins());
869
932
  plugin.paired = false;
870
933
  }
@@ -872,9 +935,19 @@ export class Matterbridge {
872
935
  }
873
936
  else {
874
937
  this.log.info(`***The commissioning server for ${plg}${pluginName}${nf} is already commissioned. Waiting for controllers to connect ...`);
938
+ if (this.bridgeMode === 'bridge') {
939
+ const qrPairingCode = storageContext.get('qrPairingCode', '');
940
+ const manualPairingCode = storageContext.get('manualPairingCode', '');
941
+ await this.nodeContext?.set('qrPairingCode', qrPairingCode);
942
+ await this.nodeContext?.set('manualPairingCode', manualPairingCode);
943
+ }
875
944
  if (this.bridgeMode === 'childbridge') {
876
945
  const plugin = this.findPlugin(pluginName);
877
- if (plugin) {
946
+ if (plugin && plugin.storageContext && plugin.nodeContext) {
947
+ plugin.qrPairingCode = plugin.storageContext.get('qrPairingCode', '');
948
+ plugin.manualPairingCode = plugin.storageContext.get('manualPairingCode', '');
949
+ await plugin.nodeContext.set('qrPairingCode', plugin.qrPairingCode);
950
+ await plugin.nodeContext.set('manualPairingCode', plugin.manualPairingCode);
878
951
  await this.nodeContext?.set('plugins', this.getBaseRegisteredPlugins());
879
952
  plugin.paired = true;
880
953
  }
@@ -960,7 +1033,7 @@ export class Matterbridge {
960
1033
  for (const plugin of this.registeredPlugins) {
961
1034
  if (!plugin.enabled)
962
1035
  continue;
963
- this.startPlugin(plugin, 'Matterbridge is commissioned and controllers are connected', true); // No await do it asyncronously
1036
+ this.startPlugin(plugin, 'Matterbridge is commissioned and controllers are connected', true); // No await do it asyncronously with also configurePlugin
964
1037
  //this.configurePlugin(plugin); // No await do it asyncronously
965
1038
  }
966
1039
  Logger.defaultLogLevel = this.debugEnabled ? Level.DEBUG : Level.INFO;
@@ -968,7 +1041,7 @@ export class Matterbridge {
968
1041
  if (this.bridgeMode === 'childbridge') {
969
1042
  //Logger.defaultLogLevel = Level.INFO;
970
1043
  const plugin = this.findPlugin(name);
971
- if (plugin && plugin.type === 'DynamicPlatform') {
1044
+ if (plugin && plugin.type === 'DynamicPlatform' && plugin.configured !== true) {
972
1045
  for (const registeredDevice of this.registeredDevices) {
973
1046
  if (registeredDevice.plugin === name) {
974
1047
  this.log.info(`Adding bridged device ${dev}${registeredDevice.device.name}${nf} to aggregator for plugin ${plg}${plugin.name}${db}`);
@@ -985,7 +1058,7 @@ export class Matterbridge {
985
1058
  }
986
1059
  }
987
1060
  for (const plugin of this.registeredPlugins) {
988
- if (plugin.name === name && plugin.platform) {
1061
+ if (plugin.name === name && plugin.platform && plugin.configured !== true) {
989
1062
  this.configurePlugin(plugin); // No await do it asyncronously
990
1063
  }
991
1064
  }
@@ -1122,6 +1195,9 @@ export class Matterbridge {
1122
1195
  const currentFileDirectory = path.dirname(fileURLToPath(import.meta.url));
1123
1196
  this.rootDirectory = path.resolve(currentFileDirectory, '../');
1124
1197
  this.log.debug(`Root Directory: ${this.rootDirectory}`);
1198
+ // Global node_modules directory
1199
+ this.globalModulesDir = execSync('npm root -g').toString().trim();
1200
+ this.log.debug(`Global node_modules Directory: ${this.globalModulesDir}`);
1125
1201
  // Create the data directory .matterbridge in the home directory
1126
1202
  this.matterbridgeDirectory = path.join(this.homeDirectory, '.matterbridge');
1127
1203
  try {
@@ -1157,6 +1233,8 @@ export class Matterbridge {
1157
1233
  paired: plugin.paired,
1158
1234
  connected: plugin.connected,
1159
1235
  registeredDevices: plugin.registeredDevices,
1236
+ qrPairingCode: plugin.qrPairingCode,
1237
+ manualPairingCode: plugin.manualPairingCode,
1160
1238
  }));
1161
1239
  return baseRegisteredPlugins;
1162
1240
  }
@@ -1336,6 +1414,7 @@ export class Matterbridge {
1336
1414
  /*
1337
1415
  TO IMPLEMENT
1338
1416
  import * as WebSocket from 'ws';
1417
+ const globalModulesDir = require('global-modules');
1339
1418
 
1340
1419
  const wss = new WebSocket.Server({ port: 8080 });
1341
1420