matterbridge 1.2.0 → 1.2.1

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,21 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.2.1] - 2024-03-25
6
+
7
+ ### Added
8
+
9
+ - [frontend]: Remove plugin from frontend.
10
+ - [frontend]: Add plugin from frontend.
11
+ - [workflow]: All packages now have a workflow on GitHub.
12
+ - [frontend]: Frontend got updated to 0.8.4.
13
+
14
+ ### Fixed
15
+
16
+ - [frontend]: Fixed the restart needed message.
17
+ - [matterbridge]: Fixed the delay of loading from the cli.
18
+ - [matterbridge]: Fixed the count of devices removed.
19
+
5
20
  ## [1.2.0] - 2024-03-23
6
21
 
7
22
  ### Breaking change on plugin default entry point and platform constructor!
package/README.md CHANGED
@@ -33,12 +33,12 @@ A special thank to Apollon77 for his incredible work.
33
33
  Follow these steps to install Matterbridge:
34
34
 
35
35
  on Windows:
36
- ``` powershell
36
+ ```
37
37
  npm install -g matterbridge
38
38
  ```
39
39
 
40
40
  on Linux (you need the necessary permissions):
41
- ``` bash
41
+ ```
42
42
  sudo npm install -g matterbridge
43
43
  ```
44
44
 
@@ -46,6 +46,7 @@ Test the installation with:
46
46
  ```
47
47
  matterbridge -bridge
48
48
  ```
49
+
49
50
  Now it is possible to open the frontend at the link provided (default: http://localhost:3000)
50
51
 
51
52
  ## Usage
@@ -87,10 +88,10 @@ matterbridge -childbridge -frontend [port number]
87
88
  ```
88
89
 
89
90
  Home page:
90
- ![See the screenshot here](https://github.com/Luligu/matterbridge/blob/main/Screenshot%20home%20page.png)
91
+ ![See the screenshot here](https://github.com/Luligu/matterbridge/blob/main/Screenshot%20home.jpg)
91
92
 
92
93
  Devices page:
93
- ![See the screenshot here](https://github.com/Luligu/matterbridge/blob/main/Screenshot%20devices%20page.png)
94
+ ![See the screenshot here](https://github.com/Luligu/matterbridge/blob/main/Screenshot%20devices.jpg)
94
95
 
95
96
  ## Plugins
96
97
 
@@ -130,6 +131,10 @@ Matterbridge can run as many plugins as you want.
130
131
 
131
132
  [Room plugin with history](https://github.com/Luligu/matterbridge-eve-room)
132
133
 
134
+ ### Production-level plugins
135
+
136
+ [zigbee2mqtt](https://github.com/Luligu/matterbridge-zigbee2mqtt)
137
+
133
138
  ## How to install and register a production-level plugin (from npm)
134
139
 
135
140
  To install i.e. https://github.com/Luligu/matterbridge-zigbee2mqtt
@@ -148,7 +153,7 @@ sudo npm install -g matterbridge-zigbee2mqtt
148
153
  matterbridge -add matterbridge-zigbee2mqtt
149
154
  ```
150
155
 
151
- ## How to install and register a plugin for development (from git)
156
+ ## How to install and register a plugin for development (from github)
152
157
 
153
158
  To install i.e. https://github.com/Luligu/matterbridge-example-accessory-platform
154
159
 
@@ -162,15 +167,16 @@ On linux:
162
167
  cd ~/Matterbridge
163
168
  ```
164
169
 
165
- then
170
+ then clone the plugin
166
171
 
167
172
  ```
168
173
  git clone https://github.com/Luligu/matterbridge-example-accessory-platform
169
174
  cd matterbridge-example-accessory-platform
170
175
  npm install
176
+ npm run build
171
177
  ```
172
178
 
173
- Then add the plugin to Matterbridge
179
+ then add the plugin to Matterbridge
174
180
  ```
175
181
  matterbridge -add .\
176
182
  ```
@@ -221,7 +227,8 @@ The plugin name.
221
227
  The plugin platform type.
222
228
 
223
229
  ### config: object
224
- The plugin config (loaded before onStart() is called and saved after onShutdown() is called).
230
+ The plugin config (loaded before the platform constructor is called and saved after onShutdown() is called).
231
+ Here you can store your plugin configuration (see matterbridge-zigbee2mqtt for example)
225
232
 
226
233
  ### async onStart(reason?: string)
227
234
  The method onStart() is where you have to create your MatterbridgeDevice and add all needed clusters and command handlers.
@@ -253,3 +260,37 @@ It can be useful to call this method from onShutdown() if you don't want to keep
253
260
 
254
261
  ## MatterbridgeDevice api
255
262
 
263
+
264
+ # Contribution Guidelines
265
+
266
+ Thank you for your interest in contributing to my project!
267
+
268
+ I warmly welcome contributions to this project! Whether it's reporting bugs, proposing new features, updating documentation, or writing code, your help is greatly appreciated.
269
+
270
+ ## Getting Started
271
+
272
+ - Fork this repository to your own GitHub account and clone it to your local device.
273
+ - Make the necessary changes and test them out
274
+ - Commit your changes and push to your forked repository
275
+
276
+ ## Submitting Changes
277
+
278
+ - Create a new pull request from my repository and I'll be glad to check it out
279
+ - Be sure to follow the existing code style
280
+ - Add unit tests for any new or changed functionality if possible
281
+ - In your pull request, do describe what your changes do and how they work
282
+
283
+ ## Code of Conduct
284
+
285
+ We believe in a welcoming and respectful community for all. Please make sure to follow our [Code of Conduct](LINK_TO_CODE_OF_CONDUCT) in all your interactions with the project.
286
+
287
+ ## Support
288
+
289
+ If you find this project helpful and you wish to support the ongoing development, you can do so by buying me a coffee.
290
+ Click on the badge below to get started:
291
+
292
+ <a href="https://www.buymeacoffee.com/luligugithub">
293
+ <img src="./yellow-button.png" alt="Buy me a coffee" width="120">
294
+ </a>
295
+
296
+ Thank you for your support!
@@ -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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"}
@@ -109,15 +109,11 @@ export class Matterbridge extends EventEmitter {
109
109
  static async loadInstance(initialize = false) {
110
110
  if (!Matterbridge.instance) {
111
111
  // eslint-disable-next-line no-console
112
- console.log('Matterbridge instance does not exists');
112
+ console.log(wr + 'Matterbridge instance does not exists!', initialize ? 'Initializing...' : 'Not initializing...', rs);
113
113
  Matterbridge.instance = new Matterbridge();
114
114
  if (initialize)
115
115
  await Matterbridge.instance.initialize();
116
116
  }
117
- else {
118
- // eslint-disable-next-line no-console
119
- console.log('Matterbridge instance already exists');
120
- }
121
117
  return Matterbridge.instance;
122
118
  }
123
119
  /**
@@ -152,28 +148,19 @@ export class Matterbridge extends EventEmitter {
152
148
  - disable [plugin name]: disable the globally installed plugin with the given name\n`);
153
149
  process.exit(0);
154
150
  }
155
- // set Matterbridge logger
151
+ // Set Matterbridge logger
156
152
  if (hasParameter('debug'))
157
153
  this.debugEnabled = true;
158
154
  this.log = new AnsiLogger({ logName: 'Matterbridge', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logDebug: this.debugEnabled });
159
155
  this.log.debug('Matterbridge is starting...');
160
- // log system info and create .matterbridge directory
161
- await this.logNodeAndSystemInfo();
162
- this.log.info(
163
- // eslint-disable-next-line max-len
164
- `Matterbridge version ${this.matterbridgeVersion} mode ${hasParameter('bridge') ? 'bridge' : ''}${hasParameter('childbridge') ? 'childbridge' : ''}${hasParameter('controller') ? 'controller' : ''} running on ${this.systemInformation.osType} ${this.systemInformation.osRelease} ${this.systemInformation.osPlatform} ${this.systemInformation.osArch}`);
165
- // check node version and throw error
166
- requireMinNodeVersion(18);
167
- // register SIGINT SIGTERM signal handlers
168
- this.registerSignalHandlers();
169
- // set matter.js logger level and format
170
- Logger.defaultLogLevel = this.debugEnabled ? Level.DEBUG : Level.INFO;
171
- Logger.format = Format.ANSI;
172
156
  // Initialize NodeStorage
157
+ this.homeDirectory = os.homedir();
158
+ this.matterbridgeDirectory = path.join(this.homeDirectory, '.matterbridge');
173
159
  this.log.debug('Creating node storage manager');
174
160
  this.nodeStorage = new NodeStorageManager({ dir: path.join(this.matterbridgeDirectory, 'storage'), logging: false });
175
161
  this.log.debug('Creating node storage context for matterbridge');
176
162
  this.nodeContext = await this.nodeStorage.createStorage('matterbridge');
163
+ // Get the plugins from node storage
177
164
  this.registeredPlugins = await this.nodeContext.get('plugins', []);
178
165
  for (const plugin of this.registeredPlugins) {
179
166
  this.log.debug(`Creating node storage context for plugin ${plugin.name}`);
@@ -185,6 +172,43 @@ export class Matterbridge extends EventEmitter {
185
172
  await plugin.nodeContext.set('description', plugin.description);
186
173
  await plugin.nodeContext.set('author', plugin.author);
187
174
  }
175
+ if (hasParameter('logstorage')) {
176
+ await this.nodeContext.logStorage();
177
+ for (const plugin of this.registeredPlugins) {
178
+ await plugin.nodeContext?.logStorage();
179
+ }
180
+ }
181
+ // Log system info and create .matterbridge directory
182
+ await this.logNodeAndSystemInfo();
183
+ this.log.info(
184
+ // eslint-disable-next-line max-len
185
+ `Matterbridge version ${this.matterbridgeVersion} mode ${hasParameter('bridge') ? 'bridge' : ''}${hasParameter('childbridge') ? 'childbridge' : ''}${hasParameter('controller') ? 'controller' : ''} running on ${this.systemInformation.osType} ${this.systemInformation.osRelease} ${this.systemInformation.osPlatform} ${this.systemInformation.osArch}`);
186
+ // Check node version and throw error
187
+ requireMinNodeVersion(18);
188
+ // Register SIGINT SIGTERM signal handlers
189
+ this.registerSignalHandlers();
190
+ // Set matter.js logger level and format
191
+ Logger.defaultLogLevel = this.debugEnabled ? Level.DEBUG : Level.INFO;
192
+ Logger.format = Format.ANSI;
193
+ // Initialize NodeStorage
194
+ /*
195
+ this.log.debug('Creating node storage manager');
196
+ this.nodeStorage = new NodeStorageManager({ dir: path.join(this.matterbridgeDirectory, 'storage'), logging: false });
197
+ this.log.debug('Creating node storage context for matterbridge');
198
+ this.nodeContext = await this.nodeStorage.createStorage('matterbridge');
199
+ // Get the plugins from node storage
200
+ this.registeredPlugins = await this.nodeContext.get<RegisteredPlugin[]>('plugins', []);
201
+ for (const plugin of this.registeredPlugins) {
202
+ this.log.debug(`Creating node storage context for plugin ${plugin.name}`);
203
+ plugin.nodeContext = await this.nodeStorage.createStorage(plugin.name);
204
+ await plugin.nodeContext.set<string>('name', plugin.name);
205
+ await plugin.nodeContext.set<string>('type', plugin.type);
206
+ await plugin.nodeContext.set<string>('path', plugin.path);
207
+ await plugin.nodeContext.set<string>('version', plugin.version);
208
+ await plugin.nodeContext.set<string>('description', plugin.description);
209
+ await plugin.nodeContext.set<string>('author', plugin.author);
210
+ }
211
+ */
188
212
  // Parse command line
189
213
  this.parseCommandLine();
190
214
  }
@@ -661,7 +685,7 @@ export class Matterbridge extends EventEmitter {
661
685
  return;
662
686
  }
663
687
  if (this.bridgeMode === 'childbridge' && !plugin.connected) {
664
- this.log.warn(`Not removing bridged device ${dev}${device.deviceName}${wr} (${dev}${device.name}${wr}) plugin ${plg}${pluginName}${wr} not connected`);
688
+ this.log.warn(`Error removing bridged device ${dev}${device.deviceName}${wr} (${dev}${device.name}${wr}) plugin ${plg}${pluginName}${wr} not connected`);
665
689
  return;
666
690
  }
667
691
  // Register and add the device to matterbridge aggregator in bridge mode
@@ -673,11 +697,11 @@ export class Matterbridge extends EventEmitter {
673
697
  return;
674
698
  }
675
699
  });
700
+ this.log.info(`Removed bridged device(${plugin.registeredDevices}/${plugin.addedDevices}) ${dev}${device.deviceName}${nf} (${dev}${device.name}${nf}) for plugin ${plg}${pluginName}${nf}`);
676
701
  if (plugin.registeredDevices !== undefined)
677
702
  plugin.registeredDevices--;
678
703
  if (plugin.addedDevices !== undefined)
679
704
  plugin.addedDevices--;
680
- this.log.info(`Removed bridged device(${plugin.registeredDevices}/${plugin.addedDevices}) ${dev}${device.deviceName}${nf} (${dev}${device.name}${nf}) for plugin ${plg}${pluginName}${nf}`);
681
705
  }
682
706
  // Only register the device in childbridge mode
683
707
  if (this.bridgeMode === 'childbridge') {
@@ -1643,9 +1667,24 @@ export class Matterbridge extends EventEmitter {
1643
1667
  this.matterbridgeInformation.rootDirectory = this.rootDirectory;
1644
1668
  this.log.debug(`Root Directory: ${this.rootDirectory}`);
1645
1669
  // Global node_modules directory
1670
+ /*
1646
1671
  this.globalModulesDirectory = await this.getGlobalNodeModules();
1647
1672
  this.matterbridgeInformation.globalModulesDirectory = this.globalModulesDirectory;
1648
1673
  this.log.debug(`Global node_modules Directory: ${this.globalModulesDirectory}`);
1674
+ */
1675
+ if (this.nodeContext)
1676
+ this.globalModulesDirectory = await this.nodeContext.get('globalModulesDirectory', '');
1677
+ this.log.debug(`Global node_modules Directory: ${this.globalModulesDirectory}`);
1678
+ this.getGlobalNodeModules()
1679
+ .then(async (globalModulesDirectory) => {
1680
+ this.globalModulesDirectory = globalModulesDirectory;
1681
+ this.matterbridgeInformation.globalModulesDirectory = this.globalModulesDirectory;
1682
+ this.log.debug(`Global node_modules Directory: ${this.globalModulesDirectory}`);
1683
+ await this.nodeContext?.set('globalModulesDirectory', this.globalModulesDirectory);
1684
+ })
1685
+ .catch((error) => {
1686
+ this.log.error(`Error getting global node_modules directory: ${error}`);
1687
+ });
1649
1688
  // Create the data directory .matterbridge in the home directory
1650
1689
  this.matterbridgeDirectory = path.join(this.homeDirectory, '.matterbridge');
1651
1690
  this.matterbridgeInformation.matterbridgeDirectory = this.matterbridgeDirectory;
@@ -1699,12 +1738,28 @@ export class Matterbridge extends EventEmitter {
1699
1738
  this.matterbridgeVersion = packageJson.version;
1700
1739
  this.matterbridgeInformation.matterbridgeVersion = this.matterbridgeVersion;
1701
1740
  this.log.debug(`Matterbridge Version: ${this.matterbridgeVersion}`);
1741
+ // Matterbridge latest version
1742
+ /*
1702
1743
  this.matterbridgeLatestVersion = await this.getLatestVersion('matterbridge');
1703
1744
  this.matterbridgeInformation.matterbridgeLatestVersion = this.matterbridgeLatestVersion;
1704
1745
  this.log.debug(`Matterbridge Latest Version: ${this.matterbridgeLatestVersion}`);
1705
- if (this.matterbridgeVersion !== this.matterbridgeLatestVersion) {
1706
- this.log.warn(`Matterbridge is out of date. Current version: ${this.matterbridgeVersion}, Latest version: ${this.matterbridgeLatestVersion}`);
1707
- }
1746
+ */
1747
+ if (this.nodeContext)
1748
+ this.matterbridgeLatestVersion = await this.nodeContext.get('matterbridgeLatestVersion', '');
1749
+ this.log.debug(`Matterbridge Latest Version: ${this.matterbridgeLatestVersion}`);
1750
+ this.getLatestVersion('matterbridge')
1751
+ .then(async (matterbridgeLatestVersion) => {
1752
+ this.matterbridgeLatestVersion = matterbridgeLatestVersion;
1753
+ this.matterbridgeInformation.matterbridgeLatestVersion = this.matterbridgeLatestVersion;
1754
+ this.log.debug(`Matterbridge Latest Version: ${this.matterbridgeLatestVersion}`);
1755
+ await this.nodeContext?.set('matterbridgeLatestVersion', this.matterbridgeLatestVersion);
1756
+ if (this.matterbridgeVersion !== this.matterbridgeLatestVersion) {
1757
+ this.log.warn(`Matterbridge is out of date. Current version: ${this.matterbridgeVersion}, Latest version: ${this.matterbridgeLatestVersion}`);
1758
+ }
1759
+ })
1760
+ .catch((error) => {
1761
+ this.log.error(`Error getting Matterbridge latest version: ${error}`);
1762
+ });
1708
1763
  // Current working directory
1709
1764
  const currentDir = process.cwd();
1710
1765
  this.log.debug(`Current Working Directory: ${currentDir}`);
@@ -1876,7 +1931,7 @@ export class Matterbridge extends EventEmitter {
1876
1931
  // Endpoint to receive commands
1877
1932
  this.expressApp.post('/api/command/:command/:param', async (req, res) => {
1878
1933
  const command = req.params.command;
1879
- const param = req.params.param;
1934
+ let param = req.params.param;
1880
1935
  this.log.debug(`The frontend sent /api/command/${command}/${param}`);
1881
1936
  if (!command) {
1882
1937
  res.status(400).json({ error: 'No command provided' });
@@ -1912,9 +1967,55 @@ export class Matterbridge extends EventEmitter {
1912
1967
  if (command === 'update') {
1913
1968
  this.log.warn(`The /api/command/${command} is not yet implemented`);
1914
1969
  }
1915
- // Handle the command addplugin from Header
1970
+ // Handle the command addplugin from Home C:\Users\lligu\GitHub\matterbridge-example-accessory-platform
1916
1971
  if (command === 'addplugin') {
1917
- this.log.warn(`The /api/command/${command}/${param} is not yet implemented`);
1972
+ param = param.replace(/\*/g, '\\');
1973
+ if (this.registeredPlugins.find((plugin) => plugin.name === param)) {
1974
+ this.log.warn(`Plugin ${plg}${param}${wr} already added to matterbridge`);
1975
+ res.json({ message: 'Command received' });
1976
+ return;
1977
+ }
1978
+ const packageJsonPath = await this.resolvePluginName(param);
1979
+ if (!packageJsonPath) {
1980
+ this.log.error(`Error resolving plugin ${plg}${param}${er}`);
1981
+ res.json({ message: 'Command received' });
1982
+ return;
1983
+ }
1984
+ this.log.debug(`Loading plugin from ${plg}${packageJsonPath}${db}`);
1985
+ try {
1986
+ // Load the package.json of the plugin
1987
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
1988
+ const plugin = { path: packageJsonPath, type: '', name: packageJson.name, version: packageJson.version, description: packageJson.description, author: packageJson.author, enabled: true };
1989
+ if (await this.loadPlugin(plugin)) {
1990
+ this.registeredPlugins.push(plugin);
1991
+ await this.nodeContext?.set('plugins', this.getBaseRegisteredPlugins());
1992
+ this.log.info(`Plugin ${plg}${packageJsonPath}${nf} type ${plugin.type} added to matterbridge. Restart required.`);
1993
+ }
1994
+ else {
1995
+ this.log.error(`Error adding plugin ${plg}${packageJsonPath}${er}`);
1996
+ }
1997
+ }
1998
+ catch (error) {
1999
+ this.log.error(`Error adding plugin ${plg}${packageJsonPath}${er}`);
2000
+ res.json({ message: 'Command received' });
2001
+ return;
2002
+ }
2003
+ }
2004
+ // Handle the command removeplugin from Home
2005
+ if (command === 'removeplugin') {
2006
+ const index = this.registeredPlugins.findIndex((registeredPlugin) => registeredPlugin.name === param);
2007
+ if (index !== -1) {
2008
+ if (this.registeredPlugins[index].platform) {
2009
+ await this.registeredPlugins[index].platform?.onShutdown('The plugin has been removed.');
2010
+ await this.savePluginConfig(this.registeredPlugins[index]);
2011
+ }
2012
+ this.registeredPlugins.splice(index, 1);
2013
+ await this.nodeContext?.set('plugins', this.getBaseRegisteredPlugins());
2014
+ this.log.info(`Plugin ${plg}${param}${nf} removed from matterbridge`);
2015
+ }
2016
+ else {
2017
+ this.log.warn(`Plugin ${plg}${param}${wr} not registered in matterbridge`);
2018
+ }
1918
2019
  }
1919
2020
  // Handle the command enableplugin from Home
1920
2021
  if (command === 'enableplugin') {