matterbridge 1.6.6-dev.1 → 1.6.6-dev.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
@@ -16,10 +16,23 @@ Tamer (https://github.com/tammeryousef1006) has created the Matterbridge Discord
16
16
 
17
17
  ## [1.6.6] - 2024-12-05
18
18
 
19
+ ### Added
20
+
21
+ - [deviceTypes]: Add device type airConditioner.
22
+ - [docker]: Add matterbridge-hass to docker dev.
23
+ - [platform]: Added validateDeviceWhiteBlackList and validateEntityBlackList to be use consistently by all plugins.
24
+
19
25
  ### Changed
20
26
 
21
- - [plugin]: Removed check on types since we are moving to production plugins.
27
+ - [plugin]: Removed check on package types since we are moving to production plugins.
28
+ - [package]: Set node version to 18, 20 and 22.
22
29
  - [package]: Update dependencies.
30
+ - [levelControl]: Set default to OnOff.Feature.Lighting.
31
+ - [jest]: Update Jest tests.
32
+
33
+ ### Fixed
34
+
35
+ - [device]: Fix typos in Device and Endpoint.
23
36
 
24
37
  <a href="https://www.buymeacoffee.com/luligugithub">
25
38
  <img src="./yellow-button.png" alt="Buy me a coffee" width="120">
@@ -41,6 +41,7 @@ export class MatterbridgeEndpoint extends Endpoint {
41
41
  deviceType;
42
42
  uniqueStorageKey = undefined;
43
43
  tagList = undefined;
44
+ subType = '';
44
45
  deviceTypes = new Map();
45
46
  clusterServers = new Map();
46
47
  clusterClients = new Map();
@@ -115,7 +116,7 @@ export class MatterbridgeEndpoint extends Endpoint {
115
116
  });
116
117
  return behaviorTypes;
117
118
  }
118
- static getBehaviourTypeFromClusterServerId(clusterId, type) {
119
+ static getBehaviourTypeFromClusterServerId(clusterId, subType) {
119
120
  if (clusterId === Identify.Cluster.id)
120
121
  return MatterbridgeIdentifyServer;
121
122
  if (clusterId === Groups.Cluster.id)
@@ -124,29 +125,35 @@ export class MatterbridgeEndpoint extends Endpoint {
124
125
  return MatterbridgeOnOffServer.with('Lighting');
125
126
  if (clusterId === LevelControl.Cluster.id)
126
127
  return MatterbridgeLevelControlServer;
127
- if (clusterId === ColorControl.Cluster.id && type === 'CompleteColorControl')
128
+ if (clusterId === ColorControl.Cluster.id && subType === undefined)
128
129
  return MatterbridgeColorControlServer;
129
- if (clusterId === ColorControl.Cluster.id && type === 'XyColorControl')
130
+ if (clusterId === ColorControl.Cluster.id && subType === 'CompleteColorControl')
131
+ return MatterbridgeColorControlServer;
132
+ if (clusterId === ColorControl.Cluster.id && subType === 'XyColorControl')
130
133
  return MatterbridgeColorControlServer.with('Xy');
131
- if (clusterId === ColorControl.Cluster.id && type === 'HueSaturationColorControl')
134
+ if (clusterId === ColorControl.Cluster.id && subType === 'HueSaturationColorControl')
132
135
  return MatterbridgeColorControlServer.with('HueSaturation');
133
- if (clusterId === ColorControl.Cluster.id && type === 'ColorTemperatureColorControl')
136
+ if (clusterId === ColorControl.Cluster.id && subType === 'ColorTemperatureColorControl')
134
137
  return MatterbridgeColorControlServer.with('ColorTemperature');
135
138
  if (clusterId === DoorLock.Cluster.id)
136
139
  return MatterbridgeDoorLockServer;
137
- if (clusterId === Thermostat.Cluster.id && type === 'AutoModeThermostat')
140
+ if (clusterId === Thermostat.Cluster.id && subType === undefined)
141
+ return MatterbridgeThermostatServer.with('AutoMode', 'Heating', 'Cooling');
142
+ if (clusterId === Thermostat.Cluster.id && subType === 'AutoModeThermostat')
138
143
  return MatterbridgeThermostatServer.with('AutoMode', 'Heating', 'Cooling');
139
- if (clusterId === Thermostat.Cluster.id && type === 'HeatingThermostat')
144
+ if (clusterId === Thermostat.Cluster.id && subType === 'HeatingThermostat')
140
145
  return MatterbridgeThermostatServer.with('Heating');
141
- if (clusterId === Thermostat.Cluster.id && type === 'CoolingThermostat')
146
+ if (clusterId === Thermostat.Cluster.id && subType === 'CoolingThermostat')
142
147
  return MatterbridgeThermostatServer.with('Cooling');
143
148
  if (clusterId === WindowCovering.Cluster.id)
144
149
  return MatterbridgeWindowCoveringServer;
145
150
  if (clusterId === FanControl.Cluster.id)
146
151
  return MatterbridgeFanControlServer;
147
- if (clusterId === Switch.Cluster.id && type === 'MomentarySwitch')
152
+ if (clusterId === Switch.Cluster.id && subType === undefined)
148
153
  return SwitchServer.with('MomentarySwitch', 'MomentarySwitchRelease', 'MomentarySwitchLongPress', 'MomentarySwitchMultiPress');
149
- if (clusterId === Switch.Cluster.id && type === 'LatchingSwitch')
154
+ if (clusterId === Switch.Cluster.id && subType === 'MomentarySwitch')
155
+ return SwitchServer.with('MomentarySwitch', 'MomentarySwitchRelease', 'MomentarySwitchLongPress', 'MomentarySwitchMultiPress');
156
+ if (clusterId === Switch.Cluster.id && subType === 'LatchingSwitch')
150
157
  return SwitchServer.with('LatchingSwitch');
151
158
  if (clusterId === TemperatureMeasurement.Cluster.id)
152
159
  return TemperatureMeasurementServer;
@@ -200,11 +207,13 @@ export class MatterbridgeEndpoint extends Endpoint {
200
207
  return ElectricalPowerMeasurementServer.with('AlternatingCurrent');
201
208
  if (clusterId === ElectricalEnergyMeasurement.Cluster.id)
202
209
  return ElectricalEnergyMeasurementServer.with('ImportedEnergy', 'ExportedEnergy', 'CumulativeEnergy');
203
- if (clusterId === PowerSource.Cluster.id && type === 'WiredPowerSource')
210
+ if (clusterId === PowerSource.Cluster.id && subType === undefined)
211
+ return PowerSourceServer;
212
+ if (clusterId === PowerSource.Cluster.id && subType === 'WiredPowerSource')
204
213
  return PowerSourceServer.with(PowerSource.Feature.Wired);
205
- if (clusterId === PowerSource.Cluster.id && type === 'BatteryReplaceablePowerSource')
214
+ if (clusterId === PowerSource.Cluster.id && subType === 'BatteryReplaceablePowerSource')
206
215
  return PowerSourceServer.with(PowerSource.Feature.Battery, PowerSource.Feature.Replaceable);
207
- if (clusterId === PowerSource.Cluster.id && type === 'BatteryRechargeablePowerSource')
216
+ if (clusterId === PowerSource.Cluster.id && subType === 'BatteryRechargeablePowerSource')
208
217
  return PowerSourceServer.with(PowerSource.Feature.Battery, PowerSource.Feature.Rechargeable);
209
218
  if (clusterId === BasicInformation.Cluster.id)
210
219
  return BasicInformationServer;
@@ -410,40 +419,32 @@ export class MatterbridgeEndpoint extends Endpoint {
410
419
  if (this.clusterServers.has(cluster.id)) {
411
420
  this.log.debug(`****cluster ${hk}${'0x' + cluster.id.toString(16).padStart(4, '0')}${db}-${hk}${getClusterNameById(cluster.id)}${db} already added`);
412
421
  }
413
- let type = undefined;
422
+ this.subType = '';
414
423
  if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('currentX') && !cluster.isAttributeSupportedByName('currentHue') && !cluster.isAttributeSupportedByName('colorTemperatureMireds'))
415
- type = 'XyColorControl';
424
+ this.subType = 'XyColorControl';
416
425
  else if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('currentHue') && !cluster.isAttributeSupportedByName('currentX') && !cluster.isAttributeSupportedByName('colorTemperatureMireds'))
417
- type = 'HueSaturationColorControl';
426
+ this.subType = 'HueSaturationColorControl';
418
427
  else if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('colorTemperatureMireds') && !cluster.isAttributeSupportedByName('currentHue') && !cluster.isAttributeSupportedByName('currentX'))
419
- type = 'ColorTemperatureColorControl';
428
+ this.subType = 'ColorTemperatureColorControl';
420
429
  else
421
- type = 'CompleteColorControl';
430
+ this.subType = 'CompleteColorControl';
422
431
  if (cluster.id === SwitchCluster.id && cluster.isEventSupportedByName('multiPressComplete'))
423
- type = 'MomentarySwitch';
432
+ this.subType = 'MomentarySwitch';
424
433
  if (cluster.id === SwitchCluster.id && cluster.isEventSupportedByName('switchLatched'))
425
- type = 'LatchingSwitch';
434
+ this.subType = 'LatchingSwitch';
426
435
  if (cluster.id === PowerSourceCluster.id && cluster.isAttributeSupportedByName('wiredCurrentType'))
427
- type = 'WiredPowerSource';
436
+ this.subType = 'WiredPowerSource';
428
437
  if (cluster.id === PowerSourceCluster.id && cluster.isAttributeSupportedByName('batReplacementDescription'))
429
- type = 'BatteryReplaceablePowerSource';
438
+ this.subType = 'BatteryReplaceablePowerSource';
430
439
  if (cluster.id === PowerSourceCluster.id && cluster.isAttributeSupportedByName('batChargeState'))
431
- type = 'BatteryRechargeablePowerSource';
440
+ this.subType = 'BatteryRechargeablePowerSource';
432
441
  if (cluster.id === ThermostatCluster.id && cluster.isAttributeSupportedByName('occupiedCoolingSetpoint'))
433
- type = 'CoolingThermostat';
442
+ this.subType = 'CoolingThermostat';
434
443
  if (cluster.id === ThermostatCluster.id && cluster.isAttributeSupportedByName('occupiedHeatingSetpoint'))
435
- type = 'HeatingThermostat';
444
+ this.subType = 'HeatingThermostat';
436
445
  if (cluster.id === ThermostatCluster.id && cluster.isAttributeSupportedByName('minSetpointDeadBand'))
437
- type = 'AutoModeThermostat';
438
- const behavior = MatterbridgeEndpoint.getBehaviourTypeFromClusterServerId(cluster.id, type);
439
- if (cluster.id === PowerTopologyCluster.id && this.clusterServers.has(cluster.id))
440
- return;
441
- if (cluster.id === ElectricalPowerMeasurementCluster.id && this.clusterServers.has(cluster.id))
442
- return;
443
- if (cluster.id === ElectricalEnergyMeasurementCluster.id && this.clusterServers.has(cluster.id))
444
- return;
445
- if (cluster.id === ThermostatCluster.id && this.clusterServers.has(cluster.id))
446
- return;
446
+ this.subType = 'AutoModeThermostat';
447
+ const behavior = MatterbridgeEndpoint.getBehaviourTypeFromClusterServerId(cluster.id, this.subType);
447
448
  this.clusterServers.set(cluster.id, cluster);
448
449
  if (cluster.id === BasicInformationCluster.id)
449
450
  return;
@@ -1,5 +1,7 @@
1
1
  import { MatterbridgeDevice } from './matterbridgeDevice.js';
2
+ import { CYAN, nf, wr } from 'node-ansi-logger';
2
3
  import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
4
+ import { isValidArray, isValidObject } from './utils/utils.js';
3
5
  export class MatterbridgePlatform {
4
6
  matterbridge;
5
7
  log;
@@ -39,13 +41,16 @@ export class MatterbridgePlatform {
39
41
  await this.matterbridge.removeBridgedEndpoint(this.name, device);
40
42
  }
41
43
  async unregisterAllDevices() {
42
- await this.matterbridge.removeAllBridgedDevices(this.name);
44
+ if (this.matterbridge.edge)
45
+ await this.matterbridge.removeAllBridgedEndpoints(this.name);
46
+ else
47
+ await this.matterbridge.removeAllBridgedDevices(this.name);
43
48
  }
44
49
  verifyMatterbridgeVersion(requiredVersion) {
45
50
  const compareVersions = (matterbridgeVersion, requiredVersion) => {
46
51
  const stripTag = (v) => {
47
52
  const parts = v.split('-');
48
- return parts.length > 0 ? parts[0] : v;
53
+ return parts[0];
49
54
  };
50
55
  const v1Parts = stripTag(matterbridgeVersion).split('.').map(Number);
51
56
  const v2Parts = stripTag(requiredVersion).split('.').map(Number);
@@ -65,4 +70,26 @@ export class MatterbridgePlatform {
65
70
  return false;
66
71
  return true;
67
72
  }
73
+ validateDeviceWhiteBlackList(device) {
74
+ if (isValidArray(this.config.whiteList, 1) && !this.config.whiteList.includes(device)) {
75
+ this.log.info(`Skipping device ${CYAN}${device}${nf} because not in whitelist`);
76
+ return false;
77
+ }
78
+ if (isValidArray(this.config.blackList, 1) && this.config.blackList.includes(device)) {
79
+ this.log.info(`Skipping device ${CYAN}${device}${nf} because in blacklist`);
80
+ return false;
81
+ }
82
+ return true;
83
+ }
84
+ validateEntityBlackList(device, entity) {
85
+ if (isValidArray(this.config.entityBlackList, 1) && this.config.entityBlackList.find((e) => e === entity)) {
86
+ this.log.info(`Skipping entity ${CYAN}${entity}${nf} because in entityBlackList`);
87
+ return false;
88
+ }
89
+ if (isValidObject(this.config.deviceEntityBlackList, 1) && device in this.config.deviceEntityBlackList && this.config.deviceEntityBlackList[device].includes(entity)) {
90
+ this.log.info(`Skipping entity ${CYAN}${entity}${wr} for device ${CYAN}${device}${nf} because in deviceEntityBlackList`);
91
+ return false;
92
+ }
93
+ return true;
94
+ }
68
95
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "1.6.6-dev.1",
3
+ "version": "1.6.6-dev.3",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "1.6.6-dev.1",
9
+ "version": "1.6.6-dev.3",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@matter/main": "0.11.8",
@@ -945,13 +945,10 @@
945
945
  }
946
946
  },
947
947
  "node_modules/gopd": {
948
- "version": "1.1.0",
949
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.1.0.tgz",
950
- "integrity": "sha512-FQoVQnqcdk4hVM4JN1eromaun4iuS34oStkdlLENLdpULsuQcTyXj8w7ayhuUfPwEYZ1ZOooOTT6fdA9Vmx/RA==",
948
+ "version": "1.2.0",
949
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
950
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
951
951
  "license": "MIT",
952
- "dependencies": {
953
- "get-intrinsic": "^1.2.4"
954
- },
955
952
  "engines": {
956
953
  "node": ">= 0.4"
957
954
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "1.6.6-dev.1",
3
+ "version": "1.6.6-dev.3",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",