matterbridge 1.4.2 → 1.4.3

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
@@ -4,6 +4,28 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  If you like this project and find it useful, please consider giving it a star on GitHub at https://github.com/Luligu/matterbridge and sponsoring it.
6
6
 
7
+ ## [1.4.3] - 2024-08-22
8
+
9
+ ### Added
10
+
11
+ - [frontend]: Added menu with Update, Restart and Shutdown.
12
+ - [frontend]: Added menu item Download matterbridge.log.
13
+ - [frontend]: Added menu item Download matter.log.
14
+ - [frontend]: Added menu item Download matter storage.
15
+ - [frontend]: Added menu item Download node storage.
16
+ - [frontend]: Added menu item Download plugin storage.
17
+ - [frontend]: Added the option to write the logs on file.
18
+
19
+ ### Changed
20
+
21
+ - [package]: Update dependencies.
22
+ - [package]: Update node-ansi-logger to 3.0.0.
23
+ - [package]: Update matter-history to 1.1.7.
24
+
25
+ <a href="https://www.buymeacoffee.com/luligugithub">
26
+ <img src="./yellow-button.png" alt="Buy me a coffee" width="120">
27
+ </a>
28
+
7
29
  ## [1.4.2] - 2024-08-20
8
30
 
9
31
  ### Added
@@ -156,7 +156,20 @@ export declare class Matterbridge extends EventEmitter {
156
156
  * @returns {Promise<void>} A promise that resolves when the latest version is retrieved and actions are performed.
157
157
  */
158
158
  private getPluginLatestVersion;
159
+ /**
160
+ * Creates a MatterLogger function to show the matter.js log messages in AnsiLogger (for the frontend).
161
+ *
162
+ * @returns {Function} The MatterLogger function.
163
+ */
159
164
  private createMatterLogger;
165
+ /**
166
+ * Creates a Matter File Logger.
167
+ *
168
+ * @param {string} filePath - The path to the log file.
169
+ * @param {boolean} [unlink=false] - Whether to unlink the log file before creating a new one.
170
+ * @returns {Function} - A function that logs formatted messages to the log file.
171
+ */
172
+ private createMatterFileLogger;
160
173
  /**
161
174
  * Update matterbridge and cleanup.
162
175
  */
@@ -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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"}
@@ -35,13 +35,13 @@ import WebSocket, { WebSocketServer } from 'ws';
35
35
  // Matterbridge
36
36
  import { MatterbridgeDevice } from './matterbridgeDevice.js';
37
37
  import { BridgedDeviceBasicInformation, BridgedDeviceBasicInformationCluster } from './cluster/BridgedDeviceBasicInformationCluster.js';
38
- import { logInterfaces, wait, waiter } from './utils/utils.js';
38
+ import { logInterfaces, wait, waiter, zipDirectory } from './utils/utils.js';
39
39
  // @project-chip/matter-node.js
40
40
  import { CommissioningController, CommissioningServer, MatterServer } from '@project-chip/matter-node.js';
41
41
  import { BasicInformationCluster, ClusterServer, FixedLabelCluster, GeneralCommissioning, PowerSourceCluster, SwitchCluster, ThreadNetworkDiagnosticsCluster, getClusterNameById } from '@project-chip/matter-node.js/cluster';
42
42
  import { DeviceTypeId, VendorId } from '@project-chip/matter-node.js/datatype';
43
43
  import { Aggregator, DeviceTypes, NodeStateInformation } from '@project-chip/matter-node.js/device';
44
- import { createFileLogger, Format, Level, Logger } from '@project-chip/matter-node.js/log';
44
+ import { Format, Level, Logger } from '@project-chip/matter-node.js/log';
45
45
  import { ManualPairingCodeCodec, QrCodeSchema } from '@project-chip/matter-node.js/schema';
46
46
  import { StorageBackendDisk, StorageBackendJsonFile, StorageManager } from '@project-chip/matter-node.js/storage';
47
47
  import { requireMinNodeVersion, getParameter, getIntParameter, hasParameter } from '@project-chip/matter-node.js/util';
@@ -87,7 +87,9 @@ export class Matterbridge extends EventEmitter {
87
87
  bridgeMode: '',
88
88
  restartMode: '',
89
89
  loggerLevel: "info" /* LogLevel.INFO */,
90
+ fileLogger: false,
90
91
  matterLoggerLevel: Level.INFO,
92
+ matterFileLogger: false,
91
93
  };
92
94
  homeDirectory = '';
93
95
  rootDirectory = '';
@@ -209,8 +211,10 @@ export class Matterbridge extends EventEmitter {
209
211
  this.homeDirectory = os.homedir();
210
212
  this.matterbridgeDirectory = path.join(this.homeDirectory, '.matterbridge');
211
213
  // Create the file logger for matterbridge
212
- if (hasParameter('filelogger'))
214
+ if (hasParameter('filelogger')) {
213
215
  AnsiLogger.setGlobalLogfile(path.join(this.matterbridgeDirectory, this.matterbrideLoggerFile), "debug" /* LogLevel.DEBUG */, true);
216
+ this.matterbridgeInformation.fileLogger = true;
217
+ }
214
218
  // Create matterbridge logger
215
219
  this.log = new AnsiLogger({ logName: 'Matterbridge', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: "info" /* LogLevel.INFO */ });
216
220
  // Set matterbridge logger level
@@ -277,13 +281,15 @@ export class Matterbridge extends EventEmitter {
277
281
  Logger.setLogger('default', this.createMatterLogger());
278
282
  // Create the file logger for matter.js
279
283
  if (hasParameter('matterfilelogger')) {
284
+ this.matterbridgeInformation.matterFileLogger = true;
285
+ /*
280
286
  try {
281
- await fs.unlink(path.join(this.matterbridgeDirectory, this.matterLoggerFile));
282
- }
283
- catch (error) {
284
- this.log.debug(`Error unlinking the log file ${CYAN}${path.join(this.matterbridgeDirectory, this.matterLoggerFile)}${er}: ${error instanceof Error ? error.message : error}`);
287
+ await fs.unlink(path.join(this.matterbridgeDirectory, this.matterLoggerFile));
288
+ } catch (error) {
289
+ this.log.debug(`Error unlinking the log file ${CYAN}${path.join(this.matterbridgeDirectory, this.matterLoggerFile)}${er}: ${error instanceof Error ? error.message : error}`);
285
290
  }
286
- Logger.addLogger('filelogger', await createFileLogger(path.join(this.matterbridgeDirectory, this.matterLoggerFile)), {
291
+ */
292
+ Logger.addLogger('matterfilelogger', await this.createMatterFileLogger(path.join(this.matterbridgeDirectory, this.matterLoggerFile), true), {
287
293
  defaultLogLevel: Level.DEBUG,
288
294
  logFormat: Format.PLAIN,
289
295
  });
@@ -879,6 +885,11 @@ export class Matterbridge extends EventEmitter {
879
885
  // error.stack && this.log.debug(error.stack);
880
886
  });
881
887
  }
888
+ /**
889
+ * Creates a MatterLogger function to show the matter.js log messages in AnsiLogger (for the frontend).
890
+ *
891
+ * @returns {Function} The MatterLogger function.
892
+ */
882
893
  createMatterLogger() {
883
894
  const matterLogger = new AnsiLogger({ logName: 'Matter', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: "debug" /* LogLevel.DEBUG */ });
884
895
  return (_level, formattedLog) => {
@@ -910,6 +921,60 @@ export class Matterbridge extends EventEmitter {
910
921
  }
911
922
  };
912
923
  }
924
+ /**
925
+ * Creates a Matter File Logger.
926
+ *
927
+ * @param {string} filePath - The path to the log file.
928
+ * @param {boolean} [unlink=false] - Whether to unlink the log file before creating a new one.
929
+ * @returns {Function} - A function that logs formatted messages to the log file.
930
+ */
931
+ async createMatterFileLogger(filePath, unlink = false) {
932
+ // 2024-08-21 08:55:19.488 DEBUG InteractionMessenger Sending DataReport chunk with 28 attributes and 0 events: 1004 bytes
933
+ let fileSize = 0;
934
+ if (unlink) {
935
+ try {
936
+ await fs.unlink(filePath);
937
+ }
938
+ catch (error) {
939
+ this.log.debug(`Error unlinking the log file ${CYAN}${filePath}${er}: ${error instanceof Error ? error.message : error}`);
940
+ }
941
+ }
942
+ return async (_level, formattedLog) => {
943
+ fileSize += formattedLog.length;
944
+ if (fileSize > 100000000) {
945
+ return;
946
+ }
947
+ const now = new Date();
948
+ const timestamp = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}.${now.getMilliseconds().toString().padStart(3, '0')}`;
949
+ const message = formattedLog.slice(24);
950
+ const parts = message.split(' ');
951
+ const logger = parts[1];
952
+ const finalMessage = parts.slice(2).join(' ') + os.EOL;
953
+ switch (_level) {
954
+ case Level.DEBUG:
955
+ await fs.appendFile(filePath, `[${timestamp}] [${logger}] [debug] ${finalMessage}`);
956
+ break;
957
+ case Level.INFO:
958
+ await fs.appendFile(filePath, `[${timestamp}] [${logger}] [info] ${finalMessage}`);
959
+ break;
960
+ case Level.NOTICE:
961
+ await fs.appendFile(filePath, `[${timestamp}] [${logger}] [notice] ${finalMessage}`);
962
+ break;
963
+ case Level.WARN:
964
+ await fs.appendFile(filePath, `[${timestamp}] [${logger}] [warn] ${finalMessage}`);
965
+ break;
966
+ case Level.ERROR:
967
+ await fs.appendFile(filePath, `[${timestamp}] [${logger}] [error] ${finalMessage}`);
968
+ break;
969
+ case Level.FATAL:
970
+ await fs.appendFile(filePath, `[${timestamp}] [${logger}] [fatal] ${finalMessage}`);
971
+ break;
972
+ default:
973
+ await fs.appendFile(filePath, `[${timestamp}] [${logger}] ${finalMessage}`);
974
+ break;
975
+ }
976
+ };
977
+ }
913
978
  /**
914
979
  * Update matterbridge and cleanup.
915
980
  */
@@ -1033,6 +1098,14 @@ export class Matterbridge extends EventEmitter {
1033
1098
  await this.stopMatterServer();
1034
1099
  // Closing matter storage
1035
1100
  await this.stopMatterStorage();
1101
+ // Remove the matterfilelogger
1102
+ try {
1103
+ Logger.removeLogger('matterfilelogger');
1104
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1105
+ }
1106
+ catch (error) {
1107
+ // this.log.debug(`Error removing the matterfilelogger for file ${CYAN}${path.join(this.matterbridgeDirectory, this.matterLoggerFile)}${er}: ${error instanceof Error ? error.message : error}`);
1108
+ }
1036
1109
  // Serialize registeredDevices
1037
1110
  if (this.nodeStorage && this.nodeContext) {
1038
1111
  this.log.info('Saving registered devices...');
@@ -2681,9 +2754,16 @@ export class Matterbridge extends EventEmitter {
2681
2754
  res.status(500).send('Error reading log file');
2682
2755
  }
2683
2756
  });
2684
- // Endpoint to download the log
2685
- this.expressApp.get('/api/download-mblog', (req, res) => {
2757
+ // Endpoint to download the matterbridge log
2758
+ this.expressApp.get('/api/download-mblog', async (req, res) => {
2686
2759
  this.log.debug('The frontend sent /api/download-mblog');
2760
+ try {
2761
+ await fs.access(path.join(this.matterbridgeDirectory, this.matterbrideLoggerFile), fs.constants.F_OK);
2762
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2763
+ }
2764
+ catch (error) {
2765
+ fs.appendFile(path.join(this.matterbridgeDirectory, this.matterbrideLoggerFile), 'Enable the log on file in the settings to enable the file logger');
2766
+ }
2687
2767
  res.download(path.join(this.matterbridgeDirectory, this.matterbrideLoggerFile), 'matterbridge.log', (error) => {
2688
2768
  if (error) {
2689
2769
  this.log.error(`Error downloading log file ${this.matterbrideLoggerFile}: ${error instanceof Error ? error.message : error}`);
@@ -2691,9 +2771,16 @@ export class Matterbridge extends EventEmitter {
2691
2771
  }
2692
2772
  });
2693
2773
  });
2694
- // Endpoint to download the log
2695
- this.expressApp.get('/api/download-mjlog', (req, res) => {
2774
+ // Endpoint to download the matter log
2775
+ this.expressApp.get('/api/download-mjlog', async (req, res) => {
2696
2776
  this.log.debug('The frontend sent /api/download-mjlog');
2777
+ try {
2778
+ await fs.access(path.join(this.matterbridgeDirectory, this.matterLoggerFile), fs.constants.F_OK);
2779
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2780
+ }
2781
+ catch (error) {
2782
+ fs.appendFile(path.join(this.matterbridgeDirectory, this.matterLoggerFile), 'Enable the log on file in the settings to enable the file logger');
2783
+ }
2697
2784
  res.download(path.join(this.matterbridgeDirectory, this.matterLoggerFile), 'matter.log', (error) => {
2698
2785
  if (error) {
2699
2786
  this.log.error(`Error downloading log file ${this.matterLoggerFile}: ${error instanceof Error ? error.message : error}`);
@@ -2701,6 +2788,38 @@ export class Matterbridge extends EventEmitter {
2701
2788
  }
2702
2789
  });
2703
2790
  });
2791
+ // Endpoint to download the matter storage file
2792
+ this.expressApp.get('/api/download-mjstorage', (req, res) => {
2793
+ this.log.debug('The frontend sent /api/download-mjstorage');
2794
+ res.download(path.join(this.matterbridgeDirectory, this.matterStorageName), 'matterbridge.json', (error) => {
2795
+ if (error) {
2796
+ this.log.error(`Error downloading log file ${this.matterStorageName}: ${error instanceof Error ? error.message : error}`);
2797
+ res.status(500).send('Error downloading the matter storage file');
2798
+ }
2799
+ });
2800
+ });
2801
+ // Endpoint to download the matterbridge storage directory
2802
+ this.expressApp.get('/api/download-mbstorage', async (req, res) => {
2803
+ this.log.debug('The frontend sent /api/download-mbstorage');
2804
+ await zipDirectory(path.join(this.matterbridgeDirectory, `matterbridge.${this.nodeStorageName}.zip`), path.join(this.matterbridgeDirectory, this.nodeStorageName));
2805
+ res.download(path.join(this.matterbridgeDirectory, `matterbridge.${this.nodeStorageName}.zip`), `matterbridge.${this.nodeStorageName}.zip`, (error) => {
2806
+ if (error) {
2807
+ this.log.error(`Error downloading file ${`matterbridge.${this.nodeStorageName}.zip`}: ${error instanceof Error ? error.message : error}`);
2808
+ res.status(500).send('Error downloading the matterbridge storage file');
2809
+ }
2810
+ });
2811
+ });
2812
+ // Endpoint to download the matterbridge plugin directory
2813
+ this.expressApp.get('/api/download-pluginstorage', async (req, res) => {
2814
+ this.log.debug('The frontend sent /api/download-pluginstorage');
2815
+ await zipDirectory(path.join(this.matterbridgeDirectory, `matterbridge.pluginstorage.zip`), this.matterbridgePluginDirectory);
2816
+ res.download(path.join(this.matterbridgeDirectory, `matterbridge.pluginstorage.zip`), `matterbridge.pluginstorage.zip`, (error) => {
2817
+ if (error) {
2818
+ this.log.error(`Error downloading file matterbridge.pluginstorage.zip: ${error instanceof Error ? error.message : error}`);
2819
+ res.status(500).send('Error downloading the matterbridge plugin storage file');
2820
+ }
2821
+ });
2822
+ });
2704
2823
  // Endpoint to receive commands
2705
2824
  this.expressApp.post('/api/command/:command/:param', express.json(), async (req, res) => {
2706
2825
  const command = req.params.command;
@@ -2777,6 +2896,53 @@ export class Matterbridge extends EventEmitter {
2777
2896
  res.json({ message: 'Command received' });
2778
2897
  return;
2779
2898
  }
2899
+ // Handle the command setmbloglevel from Settings
2900
+ if (command === 'setmblogfile') {
2901
+ this.log.debug('Matterbridge file log:', param);
2902
+ this.matterbridgeInformation.fileLogger = param === 'true';
2903
+ await this.nodeContext?.set('matterbridgeFileLog', param === 'true');
2904
+ // Create the file logger for matterbridge
2905
+ if (param === 'true')
2906
+ AnsiLogger.setGlobalLogfile(path.join(this.matterbridgeDirectory, this.matterbrideLoggerFile), "debug" /* LogLevel.DEBUG */, true);
2907
+ else
2908
+ AnsiLogger.setGlobalLogfile(undefined);
2909
+ res.json({ message: 'Command received' });
2910
+ return;
2911
+ }
2912
+ // Handle the command setmbloglevel from Settings
2913
+ if (command === 'setmjlogfile') {
2914
+ this.log.debug('Matter file log:', param);
2915
+ this.matterbridgeInformation.matterFileLogger = param === 'true';
2916
+ await this.nodeContext?.set('matterFileLog', param === 'true');
2917
+ if (param === 'true') {
2918
+ /*
2919
+ try {
2920
+ await fs.unlink(path.join(this.matterbridgeDirectory, this.matterLoggerFile));
2921
+ } catch (error) {
2922
+ this.log.debug(`Error unlinking the log file ${CYAN}${path.join(this.matterbridgeDirectory, this.matterLoggerFile)}${er}: ${error instanceof Error ? error.message : error}`);
2923
+ }
2924
+ */
2925
+ try {
2926
+ Logger.addLogger('matterfilelogger', await this.createMatterFileLogger(path.join(this.matterbridgeDirectory, this.matterLoggerFile), true), {
2927
+ defaultLogLevel: Level.DEBUG,
2928
+ logFormat: Format.PLAIN,
2929
+ });
2930
+ }
2931
+ catch (error) {
2932
+ this.log.debug(`Error adding the matterfilelogger for file ${CYAN}${path.join(this.matterbridgeDirectory, this.matterLoggerFile)}${er}: ${error instanceof Error ? error.message : error}`);
2933
+ }
2934
+ }
2935
+ else {
2936
+ try {
2937
+ Logger.removeLogger('matterfilelogger');
2938
+ }
2939
+ catch (error) {
2940
+ this.log.debug(`Error removing the matterfilelogger for file ${CYAN}${path.join(this.matterbridgeDirectory, this.matterLoggerFile)}${er}: ${error instanceof Error ? error.message : error}`);
2941
+ }
2942
+ }
2943
+ res.json({ message: 'Command received' });
2944
+ return;
2945
+ }
2780
2946
  // Handle the command unregister from Settings
2781
2947
  if (command === 'unregister') {
2782
2948
  await this.unregisterAndShutdownProcess();