matterbridge 3.0.0-edge.1 → 3.0.0-edge.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
@@ -52,21 +52,32 @@ Modified clusters:
52
52
 
53
53
  - [deviceTypes]: Updated device types to Matter 1.4
54
54
  - [matter.js]: Update to 0.13.0-alpha.0-20250405-7fc7db48.
55
+ - [matter.js]: Update to 0.13.0-alpha.0-20250408-c916c7e8.
55
56
 
56
57
  ### Fixed
57
58
 
58
59
  - [doorLock]: Fixed supportedOperatingModes inverted bitmap (Thanks Apollon).
60
+ - [DevicesIcon]: Fixed rendering of leak freeze and rain sensors.
59
61
 
60
- ## [2.2.8] - 2025-04-08
62
+ ## [2.2.8] - 2025-04-10
61
63
 
62
64
  ### Added
63
65
 
64
- - [platform]: Added stack to errors messages.
66
+ - [platform]: Added stack to error messages.
67
+ - [endpoint]: Added createLevelControlClusterServer()
65
68
  - [endpoint]: Added createLevelTvocMeasurementClusterServer()
69
+ - [frontend]: Added a restart button on the QRCode panel when the advertising for a not paired node is expired.
66
70
 
67
71
  ### Changed
68
72
 
69
73
  - [package]: Update dependencies.
74
+ - [package]: Use node:https.
75
+ - [endpoint]: Modified createOnOffClusterServer().
76
+
77
+ ### Fixed
78
+
79
+ - [homepage]: Fixed warning log for homepage property in package.json.
80
+ - [DevicesIcon]: Fixed rendering of rain, freeze and leak sensors.
70
81
 
71
82
  <a href="https://www.buymeacoffee.com/luligugithub">
72
83
  <img src="bmc-button.svg" alt="Buy me a coffee" width="80">
package/dist/frontend.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { EndpointServer, Logger, LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, Lifecycle } from '@matter/main';
2
2
  import { createServer } from 'node:http';
3
+ import https from 'node:https';
3
4
  import os from 'node:os';
4
5
  import path from 'node:path';
5
6
  import { promises as fs } from 'node:fs';
6
- import https from 'https';
7
7
  import express from 'express';
8
8
  import WebSocket, { WebSocketServer } from 'ws';
9
9
  import multer from 'multer';
@@ -56,29 +56,25 @@ import { ServiceArea } from '@matter/main/clusters';
56
56
  export var DeviceClasses;
57
57
  (function (DeviceClasses) {
58
58
  DeviceClasses["Node"] = "Node";
59
- DeviceClasses["Utility"] = "Utility";
60
59
  DeviceClasses["App"] = "App";
60
+ DeviceClasses["Utility"] = "Utility";
61
61
  DeviceClasses["Simple"] = "Simple";
62
62
  DeviceClasses["Dynamic"] = "Dynamic";
63
63
  DeviceClasses["Client"] = "Client";
64
64
  DeviceClasses["Server"] = "Server";
65
65
  DeviceClasses["Composed"] = "Composed";
66
- DeviceClasses["Multiple"] = "Multiple";
67
- DeviceClasses["EZInitiator"] = "EZ-Initiator";
68
- DeviceClasses["EZTarget"] = "EZ-Target";
66
+ DeviceClasses["Duplicate"] = "Duplicate";
69
67
  DeviceClasses["BridgedPowerSourceInfo"] = "BridgedPowerSourceInfo";
70
68
  })(DeviceClasses || (DeviceClasses = {}));
71
- export const DeviceTypeDefinition = ({ name, code, deviceClass, superSet, revision, requiredServerClusters = [], optionalServerClusters = [], requiredClientClusters = [], optionalClientClusters = [], unknown = false, }) => ({
69
+ export const DeviceTypeDefinition = ({ name, code, deviceClass, revision, requiredServerClusters = [], optionalServerClusters = [], requiredClientClusters = [], optionalClientClusters = [], }) => ({
72
70
  name,
73
71
  code: DeviceTypeId(code),
74
72
  deviceClass,
75
- superSet,
76
73
  revision,
77
74
  requiredServerClusters,
78
75
  optionalServerClusters,
79
76
  requiredClientClusters,
80
77
  optionalClientClusters,
81
- unknown,
82
78
  });
83
79
  export const powerSource = DeviceTypeDefinition({
84
80
  name: 'MA-powerSource',
@@ -4,7 +4,7 @@ import { isValidNumber, isValidObject } from './utils/export.js';
4
4
  import { MatterbridgeBehavior, MatterbridgeBehaviorDevice, MatterbridgeIdentifyServer, MatterbridgeOnOffServer, MatterbridgeLevelControlServer, MatterbridgeColorControlServer, MatterbridgeWindowCoveringServer, MatterbridgeThermostatServer, MatterbridgeFanControlServer, MatterbridgeDoorLockServer, MatterbridgeModeSelectServer, MatterbridgeValveConfigurationAndControlServer, MatterbridgeSmokeCoAlarmServer, MatterbridgeBooleanStateConfigurationServer, MatterbridgeSwitchServer, } from './matterbridgeBehaviors.js';
5
5
  import { addClusterServers, addFixedLabel, addOptionalClusterServers, addRequiredClusterServers, addUserLabel, capitalizeFirstLetter, createUniqueId, getBehavior, getBehaviourTypesFromClusterClientIds, getBehaviourTypesFromClusterServerIds, getDefaultFlowMeasurementClusterServer, getDefaultIlluminanceMeasurementClusterServer, getDefaultPressureMeasurementClusterServer, getDefaultRelativeHumidityMeasurementClusterServer, getDefaultTemperatureMeasurementClusterServer, getDefaultOccupancySensingClusterServer, lowercaseFirstLetter, updateAttribute, getClusterId, getAttributeId, setAttribute, getAttribute, checkNotLatinCharacters, generateUniqueId, subscribeAttribute, } from './matterbridgeEndpointHelpers.js';
6
6
  import { Endpoint, Lifecycle, MutableEndpoint, NamedHandler, SupportedBehaviors, VendorId } from '@matter/main';
7
- import { ClusterType, getClusterNameById, MeasurementType } from '@matter/main/types';
7
+ import { getClusterNameById, MeasurementType } from '@matter/main/types';
8
8
  import { Descriptor } from '@matter/main/clusters/descriptor';
9
9
  import { PowerSource } from '@matter/main/clusters/power-source';
10
10
  import { BridgedDeviceBasicInformation } from '@matter/main/clusters/bridged-device-basic-information';
@@ -26,8 +26,6 @@ import { ElectricalPowerMeasurement } from '@matter/main/clusters/electrical-pow
26
26
  import { ElectricalEnergyMeasurement } from '@matter/main/clusters/electrical-energy-measurement';
27
27
  import { AirQuality } from '@matter/main/clusters/air-quality';
28
28
  import { ConcentrationMeasurement } from '@matter/main/clusters/concentration-measurement';
29
- import { RvcRunMode } from '@matter/main/clusters/rvc-run-mode';
30
- import { RvcOperationalState } from '@matter/main/clusters/rvc-operational-state';
31
29
  import { OccupancySensing } from '@matter/main/clusters/occupancy-sensing';
32
30
  import { DescriptorServer } from '@matter/main/behaviors/descriptor';
33
31
  import { PowerSourceServer } from '@matter/main/behaviors/power-source';
@@ -57,9 +55,6 @@ import { Pm25ConcentrationMeasurementServer } from '@matter/main/behaviors/pm25-
57
55
  import { Pm10ConcentrationMeasurementServer } from '@matter/main/behaviors/pm10-concentration-measurement';
58
56
  import { RadonConcentrationMeasurementServer } from '@matter/main/behaviors/radon-concentration-measurement';
59
57
  import { TotalVolatileOrganicCompoundsConcentrationMeasurementServer } from '@matter/main/behaviors/total-volatile-organic-compounds-concentration-measurement';
60
- import { RvcRunModeServer } from '@matter/main/behaviors/rvc-run-mode';
61
- import { RvcOperationalStateServer } from '@matter/main/behaviors/rvc-operational-state';
62
- import { RvcCleanModeServer } from '@matter/main/behaviors/rvc-clean-mode';
63
58
  export class MatterbridgeEndpoint extends Endpoint {
64
59
  static bridgeMode = '';
65
60
  static logLevel = "info";
@@ -524,7 +519,7 @@ export class MatterbridgeEndpoint extends Endpoint {
524
519
  return this;
525
520
  }
526
521
  createOnOffClusterServer(onOff = false) {
527
- this.behaviors.require(MatterbridgeOnOffServer.for(ClusterType(OnOff.Base)), {
522
+ this.behaviors.require(MatterbridgeOnOffServer, {
528
523
  onOff,
529
524
  });
530
525
  return this;
@@ -550,6 +545,17 @@ export class MatterbridgeEndpoint extends Endpoint {
550
545
  });
551
546
  return this;
552
547
  }
548
+ createLevelControlClusterServer(currentLevel = 254, onLevel = null) {
549
+ this.behaviors.require(MatterbridgeLevelControlServer, {
550
+ currentLevel,
551
+ onLevel,
552
+ options: {
553
+ executeIfOff: false,
554
+ coupleColorTempToLevel: false,
555
+ },
556
+ });
557
+ return this;
558
+ }
553
559
  createDefaultColorControlClusterServer(currentX = 0, currentY = 0, currentHue = 0, currentSaturation = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
554
560
  this.behaviors.require(MatterbridgeColorControlServer.with(ColorControl.Feature.Xy, ColorControl.Feature.HueSaturation, ColorControl.Feature.ColorTemperature), {
555
561
  colorMode: ColorControl.ColorMode.CurrentHueAndCurrentSaturation,
@@ -1156,43 +1162,4 @@ export class MatterbridgeEndpoint extends Endpoint {
1156
1162
  });
1157
1163
  return this;
1158
1164
  }
1159
- createDefaultRvcRunModeClusterServer() {
1160
- this.behaviors.require(RvcRunModeServer, {
1161
- supportedModes: [
1162
- { label: 'Idle', mode: 1, modeTags: [{ value: RvcRunMode.ModeTag.Idle }] },
1163
- { label: 'Cleaning', mode: 2, modeTags: [{ value: RvcRunMode.ModeTag.Cleaning }] },
1164
- ],
1165
- currentMode: 1,
1166
- });
1167
- return this;
1168
- }
1169
- createDefaultRvcOperationalStateClusterServer() {
1170
- this.behaviors.require(RvcOperationalStateServer, {
1171
- phaseList: [],
1172
- currentPhase: null,
1173
- operationalStateList: [
1174
- { operationalStateId: RvcOperationalState.OperationalState.Stopped, operationalStateLabel: 'Stopped' },
1175
- { operationalStateId: RvcOperationalState.OperationalState.Running, operationalStateLabel: 'Running' },
1176
- { operationalStateId: RvcOperationalState.OperationalState.Paused, operationalStateLabel: 'Paused' },
1177
- { operationalStateId: RvcOperationalState.OperationalState.Error, operationalStateLabel: 'Error' },
1178
- { operationalStateId: RvcOperationalState.OperationalState.SeekingCharger, operationalStateLabel: 'SeekingCharger' },
1179
- { operationalStateId: RvcOperationalState.OperationalState.Charging, operationalStateLabel: 'Charging' },
1180
- { operationalStateId: RvcOperationalState.OperationalState.Docked, operationalStateLabel: 'Docked' },
1181
- ],
1182
- operationalState: RvcOperationalState.OperationalState.Stopped,
1183
- operationalError: { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateLabel: 'No Error' },
1184
- });
1185
- return this;
1186
- }
1187
- createDefaultRvcCleanModeClusterServer() {
1188
- this.behaviors.require(RvcCleanModeServer, {
1189
- supportedModes: [
1190
- { label: 'Idle', mode: 1, modeTags: [] },
1191
- { label: 'Cleaning', mode: 2, modeTags: [] },
1192
- { label: 'SpotCleaning', mode: 3, modeTags: [] },
1193
- ],
1194
- currentMode: 1,
1195
- });
1196
- return this;
1197
- }
1198
1165
  }
@@ -226,7 +226,7 @@ export class PluginManager {
226
226
  if (!packageJson.author)
227
227
  this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no author in package.json`);
228
228
  if (!packageJson.homepage)
229
- this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no homepage in package.json`);
229
+ this.log.info(`Plugin ${plg}${plugin.name}${nf} has no homepage in package.json`);
230
230
  if (!packageJson.type || packageJson.type !== 'module')
231
231
  this.log.error(`Plugin ${plg}${plugin.name}${er} is not a module`);
232
232
  if (!packageJson.main)
@@ -748,7 +748,13 @@ export class PluginManager {
748
748
  return schema;
749
749
  }
750
750
  catch (err) {
751
- this.log.debug(`Schema file ${schemaFile} for plugin ${plg}${plugin.name}${db} not found. Loading default schema. Error: ${err instanceof Error ? err.message + '\n' + err.stack : err}`);
751
+ const nodeErr = err;
752
+ if (nodeErr.code === 'ENOENT') {
753
+ this.log.debug(`Schema file ${schemaFile} for plugin ${plg}${plugin.name}${db} not found. Loading default schema.`);
754
+ }
755
+ else {
756
+ this.log.debug(`Schema file ${schemaFile} for plugin ${plg}${plugin.name}${db} not found. Loading default schema. Error: ${err instanceof Error ? err.message + '\n' + err.stack : err}`);
757
+ }
752
758
  return this.getDefaultSchema(plugin);
753
759
  }
754
760
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "files": {
3
3
  "main.css": "./static/css/main.ea7910e9.css",
4
- "main.js": "./static/js/main.1fa50342.js",
4
+ "main.js": "./static/js/main.e11d6bb4.js",
5
5
  "static/js/453.d855a71b.chunk.js": "./static/js/453.d855a71b.chunk.js",
6
6
  "static/media/roboto-latin-700-normal.woff2": "./static/media/roboto-latin-700-normal.c4d6cab43bec89049809.woff2",
7
7
  "static/media/roboto-latin-500-normal.woff2": "./static/media/roboto-latin-500-normal.599f66a60bdf974e578e.woff2",
@@ -77,11 +77,11 @@
77
77
  "static/media/roboto-greek-ext-300-normal.woff": "./static/media/roboto-greek-ext-300-normal.60729cafbded24073dfb.woff",
78
78
  "index.html": "./index.html",
79
79
  "main.ea7910e9.css.map": "./static/css/main.ea7910e9.css.map",
80
- "main.1fa50342.js.map": "./static/js/main.1fa50342.js.map",
80
+ "main.e11d6bb4.js.map": "./static/js/main.e11d6bb4.js.map",
81
81
  "453.d855a71b.chunk.js.map": "./static/js/453.d855a71b.chunk.js.map"
82
82
  },
83
83
  "entrypoints": [
84
84
  "static/css/main.ea7910e9.css",
85
- "static/js/main.1fa50342.js"
85
+ "static/js/main.e11d6bb4.js"
86
86
  ]
87
87
  }
@@ -1 +1 @@
1
- <!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="./"><link rel="icon" href="./matterbridge 32x32.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><title>Matterbridge</title><link rel="manifest" href="./manifest.json"/><script defer="defer" src="./static/js/main.1fa50342.js"></script><link href="./static/css/main.ea7910e9.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1
+ <!doctype html><html lang="en"><head><meta charset="utf-8"/><base href="./"><link rel="icon" href="./matterbridge 32x32.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><title>Matterbridge</title><link rel="manifest" href="./manifest.json"/><script defer="defer" src="./static/js/main.e11d6bb4.js"></script><link href="./static/css/main.ea7910e9.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>