matterbridge 3.4.1-dev-20251130-17ef5f4 → 3.4.1-dev-20251130-cfb291e

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
@@ -34,7 +34,7 @@ Advantages:
34
34
  - [matterbridge.io]: Updated website https://matterbridge.io with all guides.
35
35
  - [matterbridge]: Added addVirtualEndpoint() to match Matterbridge thread module.
36
36
  - [BroadcastServer]: Backport BroadcastServer v.2.0.0 from Matterbridge thread module.
37
- - [MatterbridgePrefix]: Added worker thread to get global node_modules.
37
+ - [MatterbridgePrefix]: Added worker **thread** to get global node_modules.
38
38
  - [PluginManager]: Improved the resolve method to resolve automatically also in the plugin directory Usefull for developing with DevContainer.
39
39
 
40
40
  ### Changed
@@ -44,6 +44,7 @@ Advantages:
44
44
  - [frontend]: Bumped `frontend` version to 3.3.2.
45
45
  - [platform]: Bumped MatterbridgePlatform v.1.5.0.
46
46
  - [thread]: Bump BroadcastServer to v1.0.4.
47
+ - [updates]: The update availability check now starts after 5 minutes and each 12 hours. It can also be triggered from the frontend.
47
48
 
48
49
  ### Fixed
49
50
 
@@ -20,6 +20,8 @@
20
20
 
21
21
  The advantage of this setup is that the global node_modules are private for the user and sudo is not required.
22
22
 
23
+ This configuration uses a private separate npm cache.
24
+
23
25
  The service runs rootless like the current user.
24
26
 
25
27
  The storage position is compatible with the traditional setup (~/Matterbridge ~/.matterbridge ~/.mattercert).
@@ -30,18 +32,30 @@ This will create the required directories if they don't exist
30
32
 
31
33
  ```bash
32
34
  cd ~
33
- sudo systemctl stop matterbridge # ✅ Safe precaution if matterbridge was already running with the traditional setup
34
- sudo npm uninstall matterbridge -g # ✅ We need to uninstall from the global node_modules
35
- mkdir -p ~/Matterbridge ~/.matterbridge ~/.mattercert ~/.npm-global # Creates all needed dirs
36
- chown -R $USER:$USER ~/Matterbridge ~/.matterbridge ~/.mattercert ~/.npm-global # ✅ Ensures ownership
37
- chmod -R 755 ~/Matterbridge ~/.matterbridge ~/.mattercert ~/.npm-global # ✅ Secure permissions
38
- NPM_CONFIG_PREFIX=~/.npm-global npm install matterbridge --omit=dev --verbose --global # ✅ Install matterbridge in the local global node_modules, no sudo
39
- sudo ln -sf /home/$USER/.npm-global/bin/matterbridge /usr/local/bin/matterbridge # ✅ Create a link to matterbridge bin
40
- sudo ln -sf /home/$USER/.npm-global/bin/mb_mdns /usr/local/bin/mb_mdns # Create a link to mb_mdns bin
41
- sudo ln -sf /home/$USER/.npm-global/bin/mb_coap /usr/local/bin/mb_coap # ✅ Create a link to mb_coap bin
42
- hash -r # Clear bash command cache as a precaution
43
- which matterbridge # ✅ Check it
44
- matterbridge --version # Will output the matterbridge version
35
+ # ✅ Safe precaution if matterbridge was already running with the traditional setup
36
+ sudo systemctl stop matterbridge
37
+ # We need to uninstall from the global node_modules
38
+ sudo npm uninstall matterbridge -g
39
+ # Creates all needed dirs
40
+ mkdir -p ~/Matterbridge ~/.matterbridge ~/.mattercert ~/.npm-global ~/.npm-cache
41
+ # ✅ Ensures ownership
42
+ chown -R $USER:$USER ~/Matterbridge ~/.matterbridge ~/.mattercert ~/.npm-global ~/.npm-cache
43
+ # ✅ Secure permissions
44
+ chmod -R 755 ~/Matterbridge ~/.matterbridge ~/.mattercert ~/.npm-global ~/.npm-cache
45
+ # ✅ Install matterbridge in the local global node_modules, with the local cache and no sudo
46
+ npm install matterbridge --omit=dev --verbose --global --prefix=~/.npm-global --cache=~/.npm-cache
47
+ # ✅ Create a link to matterbridge bin
48
+ sudo ln -sf /home/$USER/.npm-global/bin/matterbridge /usr/local/bin/matterbridge
49
+ # ✅ Create a link to mb_mdns bin
50
+ sudo ln -sf /home/$USER/.npm-global/bin/mb_mdns /usr/local/bin/mb_mdns
51
+ # ✅ Create a link to mb_coap bin
52
+ sudo ln -sf /home/$USER/.npm-global/bin/mb_coap /usr/local/bin/mb_coap
53
+ # ✅ Clear bash command cache as a precaution
54
+ hash -r
55
+ # ✅ Check which matterbridge
56
+ which matterbridge
57
+ # ✅ Will output the matterbridge version
58
+ matterbridge --version
45
59
  ```
46
60
 
47
61
  ### Then create a systemctl configuration file for Matterbridge
@@ -52,7 +66,7 @@ Create a systemctl configuration file for Matterbridge
52
66
  sudo nano /etc/systemd/system/matterbridge.service
53
67
  ```
54
68
 
55
- Add the following to this file, **replacing 4 times (!) USER with your user name** (e.g. WorkingDirectory=/home/pi/Matterbridge, User=pi and Group=pi and Environment="NPM_CONFIG_PREFIX=/home/pi/.npm-global"):
69
+ Add the following to this file, **replacing 5 times (!) USER with your user name** (e.g. WorkingDirectory=/home/pi/Matterbridge, User=pi and Group=pi, Environment="NPM_CONFIG_PREFIX=/home/pi/.npm-global" and Environment="NPM_CONFIG_CACHE=/home/pi/.npm-cache"):
56
70
 
57
71
  ```
58
72
  [Unit]
@@ -63,6 +77,7 @@ Wants=network.target
63
77
  [Service]
64
78
  Type=simple
65
79
  Environment="NPM_CONFIG_PREFIX=/home/<USER>/.npm-global"
80
+ Environment="NPM_CONFIG_CACHE=/home/<USER>/.npm-cache"
66
81
  ExecStart=matterbridge --service --nosudo
67
82
  WorkingDirectory=/home/<USER>/Matterbridge
68
83
  StandardOutput=inherit
@@ -20,6 +20,8 @@
20
20
 
21
21
  The advantage of this setup is that the global node_modules are private for matterbridge and sudo is not required.
22
22
 
23
+ This configuration uses a private separate npm cache.
24
+
23
25
  The service runs with group and user matterbridge and the system has full protection.
24
26
 
25
27
  ### Important
@@ -52,15 +54,15 @@ sudo systemctl stop matterbridge 2>/dev/null || true
52
54
  # ✅ Safe precaution we need to uninstall from the global node_modules
53
55
  sudo npm uninstall matterbridge -g 2>/dev/null || true
54
56
  # ✅ Creates all required directories
55
- sudo mkdir -p /opt/matterbridge /opt/matterbridge/Matterbridge /opt/matterbridge/.matterbridge /opt/matterbridge/.mattercert /opt/matterbridge/.npm-global
57
+ sudo mkdir -p /opt/matterbridge /opt/matterbridge/Matterbridge /opt/matterbridge/.matterbridge /opt/matterbridge/.mattercert /opt/matterbridge/.npm-global /opt/matterbridge/.npm-cache
56
58
  # ✅ Ensures ownership
57
- sudo chown -R matterbridge:matterbridge /opt/matterbridge /opt/matterbridge/Matterbridge /opt/matterbridge/.matterbridge /opt/matterbridge/.mattercert /opt/matterbridge/.npm-global
59
+ sudo chown -R matterbridge:matterbridge /opt/matterbridge /opt/matterbridge/Matterbridge /opt/matterbridge/.matterbridge /opt/matterbridge/.mattercert /opt/matterbridge/.npm-global /opt/matterbridge/.npm-cache
58
60
  # ✅ Secure permissions
59
- sudo chmod -R 755 /opt/matterbridge /opt/matterbridge/Matterbridge /opt/matterbridge/.matterbridge /opt/matterbridge/.mattercert /opt/matterbridge/.npm-global
61
+ sudo chmod -R 755 /opt/matterbridge /opt/matterbridge/Matterbridge /opt/matterbridge/.matterbridge /opt/matterbridge/.mattercert /opt/matterbridge/.npm-global /opt/matterbridge/.npm-cache
60
62
  # make sure the “bin” dir exists for global executables
61
63
  sudo -u matterbridge mkdir -p /opt/matterbridge/.npm-global/bin
62
- # ✅ Install matterbridge in the private global node_modules
63
- sudo -u matterbridge NPM_CONFIG_PREFIX=/opt/matterbridge/.npm-global npm install matterbridge --omit=dev --verbose --global
64
+ # ✅ Install matterbridge in the private global node_modules using the private npm cache
65
+ sudo -u matterbridge NPM_CONFIG_PREFIX=/opt/matterbridge/.npm-global NPM_CONFIG_CACHE=/opt/matterbridge/.npm-cache npm install matterbridge --omit=dev --verbose --global
64
66
  # ✅ Create a link to matterbridge bins
65
67
  sudo ln -sf /opt/matterbridge/.npm-global/bin/matterbridge /usr/bin/matterbridge
66
68
  sudo ln -sf /opt/matterbridge/.npm-global/bin/mb_mdns /usr/bin/mb_mdns
@@ -18,6 +18,7 @@ export class BroadcastServer extends EventEmitter {
18
18
  this.log = log;
19
19
  this.channel = channel;
20
20
  this.broadcastChannel = new BroadcastChannel(this.channel);
21
+ this.broadcastChannel.unref();
21
22
  this.broadcastChannel.onmessage = this.broadcastMessageHandler.bind(this);
22
23
  }
23
24
  close() {
@@ -290,9 +290,10 @@ export async function startMatterbridgeEnvironment(port = 5540) {
290
290
  return [server, aggregator];
291
291
  }
292
292
  export function addMatterbridgePlatform(platform, name) {
293
+ expect(platform).toBeDefined();
294
+ platform.setMatterNode?.(matterbridge.addBridgedEndpoint.bind(matterbridge), matterbridge.removeBridgedEndpoint.bind(matterbridge), matterbridge.removeAllBridgedEndpoints.bind(matterbridge), matterbridge.addVirtualEndpoint.bind(matterbridge));
293
295
  if (name)
294
296
  platform.config.name = name;
295
- expect(platform).toBeDefined();
296
297
  expect(platform.config.name).toBeDefined();
297
298
  expect(platform.config.type).toBeDefined();
298
299
  expect(platform.type).toBeDefined();
@@ -1700,6 +1700,7 @@ export class Matterbridge extends EventEmitter {
1700
1700
  await wait(2000);
1701
1701
  }
1702
1702
  async addVirtualEndpoint(pluginName, name, type, callback) {
1703
+ this.log.debug(`Adding virtual endpoint ${plg}${pluginName}${db}:${dev}${name}${db}...`);
1703
1704
  const plugin = this.plugins.get(pluginName);
1704
1705
  if (!plugin) {
1705
1706
  this.log.error(`Error adding virtual endpoint ${dev}${name}${er} for plugin ${plg}${pluginName}${er}: plugin not found`);
@@ -33,6 +33,17 @@ export class MatterbridgePlatform {
33
33
  #server;
34
34
  #debug = hasParameter('debug') || hasParameter('verbose');
35
35
  #verbose = hasParameter('verbose');
36
+ #addBridgedEndpoint;
37
+ #removeBridgedEndpoint;
38
+ #removeAllBridgedEndpoints;
39
+ #addVirtualEndpoint;
40
+ setMatterNode = (addBridgedEndpoint, removeBridgedEndpoint, removeAllBridgedEndpoints, addVirtualEndpoint) => {
41
+ this.#addBridgedEndpoint = addBridgedEndpoint;
42
+ this.#removeBridgedEndpoint = removeBridgedEndpoint;
43
+ this.#removeAllBridgedEndpoints = removeAllBridgedEndpoints;
44
+ this.#addVirtualEndpoint = addVirtualEndpoint;
45
+ this.setMatterNode = undefined;
46
+ };
36
47
  constructor(matterbridge, log, config) {
37
48
  this.matterbridge = matterbridge;
38
49
  this.log = log;
@@ -166,7 +177,7 @@ export class MatterbridgePlatform {
166
177
  return this.#registeredEndpoints.has(deviceUniqueId);
167
178
  }
168
179
  async registerVirtualDevice(name, type, callback) {
169
- return await this.matterbridge.addVirtualEndpoint(this.name, name, type, callback);
180
+ return (await this.#addVirtualEndpoint?.(this.name, name, type, callback)) ?? false;
170
181
  }
171
182
  async registerDevice(device) {
172
183
  device.plugin = this.name;
@@ -206,16 +217,16 @@ export class MatterbridgePlatform {
206
217
  device.createDefaultBridgedDeviceBasicInformationClusterServer(device.deviceName, device.serialNumber, device.vendorId, device.vendorName, device.productName, device.softwareVersion, device.softwareVersionString, device.hardwareVersion, device.hardwareVersionString);
207
218
  }
208
219
  }
209
- await this.matterbridge.addBridgedEndpoint(this.name, device);
220
+ await this.#addBridgedEndpoint?.(this.name, device);
210
221
  this.#registeredEndpoints.set(device.uniqueId, device);
211
222
  }
212
223
  async unregisterDevice(device) {
213
- await this.matterbridge.removeBridgedEndpoint(this.name, device);
224
+ await this.#removeBridgedEndpoint?.(this.name, device);
214
225
  if (device.uniqueId)
215
226
  this.#registeredEndpoints.delete(device.uniqueId);
216
227
  }
217
228
  async unregisterAllDevices(delay = 0) {
218
- await this.matterbridge.removeAllBridgedEndpoints(this.name, delay);
229
+ await this.#removeAllBridgedEndpoints?.(this.name, delay);
219
230
  this.#registeredEndpoints.clear();
220
231
  }
221
232
  async saveSelects() {
@@ -291,7 +302,7 @@ export class MatterbridgePlatform {
291
302
  }
292
303
  return selectEntities;
293
304
  }
294
- verifyMatterbridgeVersion(requiredVersion) {
305
+ verifyMatterbridgeVersion(requiredVersion, destroy = true) {
295
306
  const compareVersions = (matterbridgeVersion, requiredVersion) => {
296
307
  const stripTag = (v) => {
297
308
  const parts = v.split('-');
@@ -311,8 +322,11 @@ export class MatterbridgePlatform {
311
322
  }
312
323
  return true;
313
324
  };
314
- if (!compareVersions(this.matterbridge.matterbridgeVersion, requiredVersion))
325
+ if (!compareVersions(this.matterbridge.matterbridgeVersion, requiredVersion)) {
326
+ if (destroy)
327
+ this.destroy();
315
328
  return false;
329
+ }
316
330
  return true;
317
331
  }
318
332
  validateDevice(device, log = true) {
@@ -816,6 +816,7 @@ export class PluginManager extends EventEmitter {
816
816
  platform.config = config;
817
817
  platform.version = packageJson.version;
818
818
  platform.isLoaded = true;
819
+ platform.setMatterNode?.(this.matterbridge.addBridgedEndpoint.bind(this.matterbridge), this.matterbridge.removeBridgedEndpoint.bind(this.matterbridge), this.matterbridge.removeAllBridgedEndpoints.bind(this.matterbridge), this.matterbridge.addVirtualEndpoint.bind(this.matterbridge));
819
820
  plugin.name = packageJson.name;
820
821
  plugin.description = packageJson.description ?? 'No description';
821
822
  plugin.version = packageJson.version;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.4.1-dev-20251130-17ef5f4",
3
+ "version": "3.4.1-dev-20251130-cfb291e",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "3.4.1-dev-20251130-17ef5f4",
9
+ "version": "3.4.1-dev-20251130-cfb291e",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@matter/main": "0.15.6",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.4.1-dev-20251130-17ef5f4",
3
+ "version": "3.4.1-dev-20251130-cfb291e",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",