matterbridge 3.4.4-dev-20251215-216dfc3 → 3.4.4-dev-20251216-bf81437

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
@@ -32,11 +32,13 @@ Advantages:
32
32
 
33
33
  ### Added
34
34
 
35
- - [frontend]: Set autoScroll to false in mobileMode.
35
+ - [frontend]: Set automatically autoScroll to false in mobileMode.
36
36
  - [frontend]: Added Log length: 100, 200, 500, 1000.
37
- - [frontend]: Added Log search with case-insensitive regex: use /text/ in the search field.
37
+ - [frontend]: Added Log search with case-insensitive regex: use /text/ in the search field to activate the regex search mode.
38
38
  - [frontend]: Differentiated update icon color: primary color for latest and secondary color for dev.
39
- - [MbfTable]: Added ConditionalTooltip to show clipped column cells.
39
+ - [frontend]: Added `Reset the frontend UI` in the Reset menu. It will reset the frontend local storage to the default and reload the page.
40
+ - [MbfTable]: Added ConditionalTooltip to show clipped column cells. Used in the Cluster table for a better user experience.
41
+ - [frontend]: Added battery level to Devices panel in the Home page. Thanks [Tamer Salah](https://github.com/tammeryousef1006).
40
42
 
41
43
  ### Changed
42
44
 
@@ -47,6 +49,7 @@ Advantages:
47
49
 
48
50
  - [doorLock]: Fixed DoorLock.supportedOperatingModes. Thanks Ludovic BOUÉ (https://github.com/Luligu/matterbridge/issues/454).
49
51
  - [frontend]: Fixed mobileMode menu navigation. Thanks Calimerorulez (https://github.com/Luligu/matterbridge/issues/457).
52
+ - [matterbridge]: Fixed debug level of matter logger.
50
53
 
51
54
  <a href="https://www.buymeacoffee.com/luligugithub"><img src="https://matterbridge.io/bmc-button.svg" alt="Buy me a coffee" width="80"></a>
52
55
 
package/README-DOCKER.md CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  ## Run matterbridge with docker and docker compose
20
20
 
21
- The Matterbridge Docker image, which includes a manifest list for the linux/amd64, linux/arm64 and linux/arm/v7 architectures, is published on **Docker Hub**.
21
+ The Matterbridge Docker image, which includes a manifest list for the linux/amd64, linux/arm64 and linux/arm/v7 architectures, is published on [**Docker Hub**](https://hub.docker.com/r/luligu/matterbridge).
22
22
 
23
23
  The image (tag **latest**) includes matterbridge and all official plugins with the latest release (as published on npm). You can just pull the new image and matterbridge with all plugins will be the latest release published on npm.
24
24
 
@@ -30,11 +30,11 @@ It is based on node:22-bookworm-slim and integrates the health check.
30
30
 
31
31
  How Health Checks Work in Different Scenarios
32
32
 
33
- With docker-compose
33
+ With docker-compose:
34
34
 
35
35
  Docker monitors the health check and can restart the container if needed.
36
36
 
37
- With docker run
37
+ With docker run:
38
38
 
39
39
  The health check still runs in the background, but:
40
40
  The container doesn’t restart automatically if it becomes unhealthy.
@@ -45,6 +45,8 @@ You can manually check the health status:
45
45
  docker exec -it matterbridge curl -v http://localhost:8283/health
46
46
  ```
47
47
 
48
+ If you use the docker image, please consider giving it a star on [**Docker Hub**](https://hub.docker.com/r/luligu/matterbridge).
49
+
48
50
  ### First create the Matterbridge directories
49
51
 
50
52
  This will create the required directories in your home directory if they don't exist
@@ -84,11 +86,24 @@ sudo docker run --name matterbridge \
84
86
 
85
87
  You may need to adapt the script to your setup.
86
88
 
89
+ ### Run the Docker container and start it adding different parameters (i.e. frontend on port 8585)
90
+
91
+ ```bash
92
+ sudo docker run --name matterbridge \
93
+ -v ~/Matterbridge:/root/Matterbridge \
94
+ -v ~/.matterbridge:/root/.matterbridge \
95
+ -v ~/.mattercert:/root/.mattercert \
96
+ --network host --restart always -d luligu/matterbridge:latest \
97
+ matterbridge --docker --frontend 8585
98
+ ```
99
+
100
+ If you override, always use `matterbridge --docker` like first part of the command.
101
+
87
102
  ### Run with docker compose
88
103
 
89
104
  The docker-compose.yml file is available in the docker directory of the package
90
105
 
91
- ```
106
+ ```yaml
92
107
  services:
93
108
  matterbridge:
94
109
  container_name: matterbridge
@@ -115,6 +130,17 @@ or start only the matterbridge container with:
115
130
  docker compose up -d matterbridge
116
131
  ```
117
132
 
133
+ If you need to start matterbridge adding different parameters (i.e. frontend on port 8585), you can override the default command adding the line command to the service:
134
+
135
+ ```yaml
136
+ services:
137
+ matterbridge:
138
+ ...
139
+ command: ["matterbridge", "--docker", "--frontend", "8585"]
140
+ ```
141
+
142
+ If you override, always use `["matterbridge", "--docker"]` like first part of the command.
143
+
118
144
  ### Stop with docker compose
119
145
 
120
146
  ```bash
package/README.md CHANGED
@@ -15,7 +15,7 @@
15
15
 
16
16
  ---
17
17
 
18
- Matterbridge is a Matter plugin manager.
18
+ [Matterbridge](https://matterbridge.io) is a Matter plugin manager.
19
19
 
20
20
  It allows you to have all your Matter devices up and running in a couple of minutes without having to deal with the pairing process for each individual device.
21
21
 
@@ -27,7 +27,7 @@ This project aims to enable porting Homebridge plugins to Matterbridge plugins w
27
27
 
28
28
  The easiest way to start create a new plugin is to clone the [Matterbridge Plugin Template](https://github.com/Luligu/matterbridge-plugin-template) which has **Dev Container support for instant development environment** and all tools and extensions (like Node.js, npm, TypeScript, ESLint, Prettier, Jest and Vitest) already loaded and configured.
29
29
 
30
- Matterbridge creates a device that can be paired with any ecosystem, such as Apple Home, Google Home, Amazon Alexa, Home Assistant, or any other platform supporting Matter.
30
+ Matterbridge creates a [Matter device](https://csa-iot.org/all-solutions/matter/) that can be paired with any ecosystem, such as Apple Home, Google Home, Amazon Alexa, Home Assistant, or any other platform supporting Matter.
31
31
 
32
32
  You don't need a hub or a dedicated new machine.
33
33
 
package/dist/frontend.js CHANGED
@@ -163,11 +163,11 @@ export class Frontend extends EventEmitter {
163
163
  this.wsMessageHandler(ws, message);
164
164
  });
165
165
  ws.on('ping', () => {
166
- this.log.debug('WebSocket client ping');
166
+ this.log.debug('WebSocket client ping received');
167
167
  ws.pong();
168
168
  });
169
169
  ws.on('pong', () => {
170
- this.log.debug('WebSocket client pong');
170
+ this.log.debug('WebSocket client pong received');
171
171
  });
172
172
  ws.on('close', () => {
173
173
  this.log.info('WebSocket client disconnected');
@@ -836,7 +836,7 @@ export class Frontend extends EventEmitter {
836
836
  }
837
837
  getPowerSource(endpoint) {
838
838
  if (this.matterbridge.hasCleanupStarted)
839
- return;
839
+ return undefined;
840
840
  if (!endpoint.lifecycle.isReady || endpoint.construction.status !== Lifecycle.Status.Active)
841
841
  return undefined;
842
842
  const powerSource = (device) => {
@@ -858,6 +858,26 @@ export class Frontend extends EventEmitter {
858
858
  return powerSource(child);
859
859
  }
860
860
  }
861
+ getBatteryLevel(endpoint) {
862
+ if (this.matterbridge.hasCleanupStarted)
863
+ return undefined;
864
+ if (!endpoint.lifecycle.isReady || endpoint.construction.status !== Lifecycle.Status.Active)
865
+ return undefined;
866
+ const batteryLevel = (device) => {
867
+ const featureMap = device.getAttribute(PowerSource.Cluster.id, 'featureMap');
868
+ if (featureMap.battery) {
869
+ const batChargeLevel = device.getAttribute(PowerSource.Cluster.id, 'batPercentRemaining');
870
+ return isValidNumber(batChargeLevel) ? batChargeLevel / 2 : undefined;
871
+ }
872
+ return undefined;
873
+ };
874
+ if (endpoint.hasClusterServer(PowerSource.Cluster.id))
875
+ return batteryLevel(endpoint);
876
+ for (const child of endpoint.getChildEndpoints()) {
877
+ if (child.hasClusterServer(PowerSource.Cluster.id))
878
+ return batteryLevel(child);
879
+ }
880
+ }
861
881
  getClusterTextFromDevice(device) {
862
882
  if (this.matterbridge.hasCleanupStarted)
863
883
  return '';
@@ -1030,6 +1050,7 @@ export class Frontend extends EventEmitter {
1030
1050
  uniqueId: device.uniqueId,
1031
1051
  reachable: this.getReachability(device),
1032
1052
  powerSource: this.getPowerSource(device),
1053
+ batteryLevel: this.getBatteryLevel(device),
1033
1054
  matter: device.mode === 'server' && device.serverNode ? this.matterbridge.getServerNodeData(device.serverNode) : undefined,
1034
1055
  cluster: this.getClusterTextFromDevice(device),
1035
1056
  });
@@ -1228,8 +1249,7 @@ export class Frontend extends EventEmitter {
1228
1249
  this.wssSendSnackbarMessage(`Loaded plugin ${localData.params.pluginNameOrPath}`, 5, 'success');
1229
1250
  return;
1230
1251
  })
1231
- .catch((_error) => {
1232
- });
1252
+ .catch((_error) => { });
1233
1253
  }
1234
1254
  else {
1235
1255
  sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: `Plugin ${data.params.pluginNameOrPath} not added` });
@@ -1277,8 +1297,7 @@ export class Frontend extends EventEmitter {
1277
1297
  this.wssSendSnackbarMessage(`Started plugin ${localData.params.pluginName}`, 5, 'success');
1278
1298
  return;
1279
1299
  })
1280
- .catch((_error) => {
1281
- });
1300
+ .catch((_error) => { });
1282
1301
  }
1283
1302
  sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
1284
1303
  }
@@ -67,7 +67,7 @@ export class Matterbridge extends EventEmitter {
67
67
  log = new AnsiLogger({ logName: 'Matterbridge', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
68
68
  logLevel = this.log.logLevel;
69
69
  fileLogger = false;
70
- matterLog = new AnsiLogger({ logName: 'Matter', logTimestampFormat: 4, logLevel: hasParameter('debug') ? "debug" : "info" });
70
+ matterLog = new AnsiLogger({ logName: 'Matter', logTimestampFormat: 4, logLevel: "debug" });
71
71
  matterLogLevel = this.matterLog.logLevel;
72
72
  matterFileLogger = false;
73
73
  readOnly = hasParameter('readonly') || hasParameter('shelly');
@@ -1147,6 +1147,7 @@ export class Matterbridge extends EventEmitter {
1147
1147
  await addVirtualDevices(this, this.aggregatorNode);
1148
1148
  await this.startPlugins();
1149
1149
  this.log.debug('Starting start matter interval in bridge mode...');
1150
+ this.frontend.wssSendSnackbarMessage(`The bridge is starting...`, 0, 'info');
1150
1151
  let failCount = 0;
1151
1152
  this.startMatterInterval = setInterval(async () => {
1152
1153
  if (failCount && failCount % 10 === 0) {
@@ -1214,6 +1215,7 @@ export class Matterbridge extends EventEmitter {
1214
1215
  this.log.notice('Matterbridge bridge started successfully');
1215
1216
  this.frontend.wssSendRefreshRequired('settings');
1216
1217
  this.frontend.wssSendRefreshRequired('plugins');
1218
+ this.frontend.wssSendCloseSnackbarMessage(`The bridge is starting...`);
1217
1219
  }, Number(process.env['MATTERBRIDGE_START_MATTER_INTERVAL_MS']) || this.startMatterIntervalMs);
1218
1220
  }
1219
1221
  async startChildbridge(delay = 1000) {
@@ -1229,6 +1231,7 @@ export class Matterbridge extends EventEmitter {
1229
1231
  this.plugins.start(plugin, 'Matterbridge is starting');
1230
1232
  }
1231
1233
  this.log.debug('Starting start matter interval in childbridge mode...');
1234
+ this.frontend.wssSendSnackbarMessage(`The bridge is starting...`, 0, 'info');
1232
1235
  let failCount = 0;
1233
1236
  this.startMatterInterval = setInterval(async () => {
1234
1237
  if (failCount && failCount % 10 === 0) {
@@ -1322,6 +1325,7 @@ export class Matterbridge extends EventEmitter {
1322
1325
  this.log.notice('Matterbridge childbridge started successfully');
1323
1326
  this.frontend.wssSendRefreshRequired('settings');
1324
1327
  this.frontend.wssSendRefreshRequired('plugins');
1328
+ this.frontend.wssSendCloseSnackbarMessage(`The bridge is starting...`);
1325
1329
  }, Number(process.env['MATTERBRIDGE_START_MATTER_INTERVAL_MS']) || this.startMatterIntervalMs);
1326
1330
  }
1327
1331
  async startController() {