matterbridge 1.6.6-dev.9 → 1.6.7-dev.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.
@@ -26,6 +26,7 @@ export class MatterbridgeEndpoint extends Endpoint {
26
26
  static logLevel = "info";
27
27
  log;
28
28
  plugin = undefined;
29
+ configUrl = undefined;
29
30
  deviceName = undefined;
30
31
  serialNumber = undefined;
31
32
  uniqueId = undefined;
@@ -124,15 +125,15 @@ export class MatterbridgeEndpoint extends Endpoint {
124
125
  if (clusterId === OnOff.Cluster.id)
125
126
  return MatterbridgeOnOffServer.with('Lighting');
126
127
  if (clusterId === LevelControl.Cluster.id)
127
- return MatterbridgeLevelControlServer;
128
+ return MatterbridgeLevelControlServer.with('OnOff', 'Lighting');
128
129
  if (clusterId === ColorControl.Cluster.id && subType === undefined)
129
130
  return MatterbridgeColorControlServer;
130
131
  if (clusterId === ColorControl.Cluster.id && subType === 'CompleteColorControl')
131
132
  return MatterbridgeColorControlServer;
132
133
  if (clusterId === ColorControl.Cluster.id && subType === 'XyColorControl')
133
- return MatterbridgeColorControlServer.with('Xy');
134
+ return MatterbridgeColorControlServer.with('Xy', 'ColorTemperature');
134
135
  if (clusterId === ColorControl.Cluster.id && subType === 'HueSaturationColorControl')
135
- return MatterbridgeColorControlServer.with('HueSaturation');
136
+ return MatterbridgeColorControlServer.with('HueSaturation', 'ColorTemperature');
136
137
  if (clusterId === ColorControl.Cluster.id && subType === 'ColorTemperatureColorControl')
137
138
  return MatterbridgeColorControlServer.with('ColorTemperature');
138
139
  if (clusterId === DoorLock.Cluster.id)
@@ -420,9 +421,9 @@ export class MatterbridgeEndpoint extends Endpoint {
420
421
  this.log.debug(`****cluster ${hk}${'0x' + cluster.id.toString(16).padStart(4, '0')}${db}-${hk}${getClusterNameById(cluster.id)}${db} already added`);
421
422
  }
422
423
  this.subType = '';
423
- if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('currentX') && !cluster.isAttributeSupportedByName('currentHue') && !cluster.isAttributeSupportedByName('colorTemperatureMireds'))
424
+ if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('currentX') && !cluster.isAttributeSupportedByName('currentHue'))
424
425
  this.subType = 'XyColorControl';
425
- else if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('currentHue') && !cluster.isAttributeSupportedByName('currentX') && !cluster.isAttributeSupportedByName('colorTemperatureMireds'))
426
+ else if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('currentHue') && !cluster.isAttributeSupportedByName('currentX'))
426
427
  this.subType = 'HueSaturationColorControl';
427
428
  else if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('colorTemperatureMireds') && !cluster.isAttributeSupportedByName('currentHue') && !cluster.isAttributeSupportedByName('currentX'))
428
429
  this.subType = 'ColorTemperatureColorControl';
@@ -708,6 +709,7 @@ export class MatterbridgeEndpoint extends Endpoint {
708
709
  vendorName: vendorName.slice(0, 32),
709
710
  productId: productId,
710
711
  productName: productName.slice(0, 32),
712
+ productUrl: 'https://www.npmjs.com/package/matterbridge',
711
713
  productLabel: deviceName.slice(0, 64),
712
714
  nodeLabel: deviceName.slice(0, 32),
713
715
  serialNumber: serialNumber.slice(0, 32),
@@ -752,6 +754,7 @@ export class MatterbridgeEndpoint extends Endpoint {
752
754
  vendorId: vendorId !== undefined ? VendorId(vendorId) : undefined,
753
755
  vendorName: vendorName.slice(0, 32),
754
756
  productName: productName.slice(0, 32),
757
+ productUrl: 'https://www.npmjs.com/package/matterbridge',
755
758
  productLabel: deviceName.slice(0, 64),
756
759
  nodeLabel: deviceName.slice(0, 32),
757
760
  serialNumber: serialNumber.slice(0, 32),
@@ -855,47 +858,39 @@ export class MatterbridgeEndpoint extends Endpoint {
855
858
  createDefaultOnOffClusterServer(onOff = false, globalSceneControl = false, onTime = 0, offWaitTime = 0, startUpOnOff = null) {
856
859
  this.addClusterServer(this.getDefaultOnOffClusterServer(onOff, globalSceneControl, onTime, offWaitTime, startUpOnOff));
857
860
  }
858
- getDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 0, maxLevel = 254, onLevel = 254) {
859
- return ClusterServer(LevelControlCluster.with(LevelControl.Feature.OnOff), {
861
+ getDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 1, maxLevel = 254, onLevel = null, startUpCurrentLevel = null) {
862
+ return ClusterServer(LevelControlCluster.with(LevelControl.Feature.OnOff, LevelControl.Feature.Lighting), {
860
863
  currentLevel,
861
864
  minLevel,
862
865
  maxLevel,
863
866
  onLevel,
867
+ remainingTime: 0,
868
+ startUpCurrentLevel,
864
869
  options: {
865
870
  executeIfOff: false,
866
871
  coupleColorTempToLevel: false,
867
872
  },
868
873
  }, {
869
874
  moveToLevel: async (data) => {
870
- this.log.debug('Matter command: moveToLevel request:', data.request, 'attributes.currentLevel:', data.attributes.currentLevel.getLocal());
871
- await this.commandHandler.executeHandler('moveToLevel', data);
872
875
  },
873
876
  move: async () => {
874
- this.log.error('Matter command: move not implemented');
875
877
  },
876
878
  step: async () => {
877
- this.log.error('Matter command: step not implemented');
878
879
  },
879
880
  stop: async () => {
880
- this.log.error('Matter command: stop not implemented');
881
881
  },
882
882
  moveToLevelWithOnOff: async (data) => {
883
- this.log.debug('Matter command: moveToLevelWithOnOff request:', data.request, 'attributes.currentLevel:', data.attributes.currentLevel.getLocal());
884
- await this.commandHandler.executeHandler('moveToLevelWithOnOff', data);
885
883
  },
886
884
  moveWithOnOff: async () => {
887
- this.log.error('Matter command: moveWithOnOff not implemented');
888
885
  },
889
886
  stepWithOnOff: async () => {
890
- this.log.error('Matter command: stepWithOnOff not implemented');
891
887
  },
892
888
  stopWithOnOff: async () => {
893
- this.log.error('Matter command: stopWithOnOff not implemented');
894
889
  },
895
890
  });
896
891
  }
897
- createDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 0, maxLevel = 254, onLevel = 254) {
898
- this.addClusterServer(this.getDefaultLevelControlClusterServer(currentLevel, minLevel, maxLevel, onLevel));
892
+ createDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 1, maxLevel = 254, onLevel = null, startUpCurrentLevel = null) {
893
+ this.addClusterServer(this.getDefaultLevelControlClusterServer(currentLevel, minLevel, maxLevel, onLevel, startUpCurrentLevel));
899
894
  }
900
895
  getDefaultColorControlClusterServer(currentX = 0, currentY = 0, currentHue = 0, currentSaturation = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
901
896
  return ClusterServer(ColorControlCluster.with(ColorControl.Feature.Xy, ColorControl.Feature.HueSaturation, ColorControl.Feature.ColorTemperature), {
@@ -914,71 +909,59 @@ export class MatterbridgeEndpoint extends Endpoint {
914
909
  colorTempPhysicalMinMireds,
915
910
  colorTempPhysicalMaxMireds,
916
911
  coupleColorTempToLevelMinMireds: colorTempPhysicalMinMireds,
912
+ remainingTime: 0,
917
913
  startUpColorTemperatureMireds: null,
918
914
  }, {
919
915
  moveToColor: async (data) => {
920
- this.log.debug('Matter command: moveToColor request:', data.request, 'attributes.currentX:', data.attributes.currentX.getLocal(), 'attributes.currentY:', data.attributes.currentY.getLocal());
921
- this.commandHandler.executeHandler('moveToColor', data);
922
916
  },
923
917
  moveColor: async () => {
924
- this.log.error('Matter command: moveColor not implemented');
925
918
  },
926
919
  stepColor: async () => {
927
- this.log.error('Matter command: stepColor not implemented');
928
920
  },
929
921
  moveToHue: async (data) => {
930
- this.log.debug('Matter command: moveToHue request:', data.request, 'attributes.currentHue:', data.attributes.currentHue.getLocal());
931
- this.commandHandler.executeHandler('moveToHue', data);
932
922
  },
933
923
  moveHue: async () => {
934
- this.log.error('Matter command: moveHue not implemented');
935
924
  },
936
925
  stepHue: async () => {
937
- this.log.error('Matter command: stepHue not implemented');
938
926
  },
939
927
  moveToSaturation: async (data) => {
940
- this.log.debug('Matter command: moveToSaturation request:', data.request, 'attributes.currentSaturation:', data.attributes.currentSaturation.getLocal());
941
- this.commandHandler.executeHandler('moveToSaturation', data);
942
928
  },
943
929
  moveSaturation: async () => {
944
- this.log.error('Matter command: moveSaturation not implemented');
945
930
  },
946
931
  stepSaturation: async () => {
947
- this.log.error('Matter command: stepSaturation not implemented');
948
932
  },
949
933
  moveToHueAndSaturation: async (data) => {
950
- this.log.debug('Matter command: moveToHueAndSaturation request:', data.request, 'attributes.currentHue:', data.attributes.currentHue.getLocal(), 'attributes.currentSaturation:', data.attributes.currentSaturation.getLocal());
951
- this.commandHandler.executeHandler('moveToHueAndSaturation', data);
952
934
  },
953
935
  stopMoveStep: async () => {
954
- this.log.error('Matter command: stopMoveStep not implemented');
955
936
  },
956
937
  moveToColorTemperature: async (data) => {
957
- this.log.debug('Matter command: moveToColorTemperature request:', data.request, 'attributes.colorTemperatureMireds:', data.attributes.colorTemperatureMireds.getLocal());
958
- this.commandHandler.executeHandler('moveToColorTemperature', data);
959
938
  },
960
939
  moveColorTemperature: async () => {
961
- this.log.error('Matter command: moveColorTemperature not implemented');
962
940
  },
963
941
  stepColorTemperature: async () => {
964
- this.log.error('Matter command: stepColorTemperature not implemented');
965
942
  },
966
943
  }, {});
967
944
  }
968
945
  createDefaultColorControlClusterServer(currentX = 0, currentY = 0, currentHue = 0, currentSaturation = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
969
946
  this.addClusterServer(this.getDefaultColorControlClusterServer(currentX, currentY, currentHue, currentSaturation, colorTemperatureMireds, colorTempPhysicalMinMireds, colorTempPhysicalMaxMireds));
970
947
  }
971
- getXyColorControlClusterServer(currentX = 0, currentY = 0) {
972
- return ClusterServer(ColorControlCluster.with(ColorControl.Feature.Xy), {
948
+ getXyColorControlClusterServer(currentX = 0, currentY = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
949
+ return ClusterServer(ColorControlCluster.with(ColorControl.Feature.Xy, ColorControl.Feature.ColorTemperature), {
973
950
  colorMode: ColorControl.ColorMode.CurrentXAndCurrentY,
974
951
  enhancedColorMode: ColorControl.EnhancedColorMode.CurrentXAndCurrentY,
975
- colorCapabilities: { xy: true, hueSaturation: false, colorLoop: false, enhancedHue: false, colorTemperature: false },
952
+ colorCapabilities: { xy: true, hueSaturation: false, colorLoop: false, enhancedHue: false, colorTemperature: true },
976
953
  options: {
977
954
  executeIfOff: false,
978
955
  },
979
956
  numberOfPrimaries: null,
980
957
  currentX,
981
958
  currentY,
959
+ colorTemperatureMireds,
960
+ colorTempPhysicalMinMireds,
961
+ colorTempPhysicalMaxMireds,
962
+ coupleColorTempToLevelMinMireds: colorTempPhysicalMinMireds,
963
+ startUpColorTemperatureMireds: null,
964
+ remainingTime: 0,
982
965
  }, {
983
966
  moveToColor: async () => {
984
967
  },
@@ -988,43 +971,61 @@ export class MatterbridgeEndpoint extends Endpoint {
988
971
  },
989
972
  stopMoveStep: async () => {
990
973
  },
974
+ moveToColorTemperature: async () => {
975
+ },
976
+ moveColorTemperature: async () => {
977
+ },
978
+ stepColorTemperature: async () => {
979
+ },
991
980
  }, {});
992
981
  }
993
- createXyColorControlClusterServer(currentX = 0, currentY = 0) {
994
- this.addClusterServer(this.getXyColorControlClusterServer(currentX, currentY));
982
+ createXyColorControlClusterServer(currentX = 0, currentY = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
983
+ this.addClusterServer(this.getXyColorControlClusterServer(currentX, currentY, colorTemperatureMireds, colorTempPhysicalMinMireds, colorTempPhysicalMaxMireds));
995
984
  }
996
- getHsColorControlClusterServer(currentHue = 0, currentSaturation = 0) {
997
- return ClusterServer(ColorControlCluster.with(ColorControl.Feature.HueSaturation), {
985
+ getHsColorControlClusterServer(currentHue = 0, currentSaturation = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
986
+ return ClusterServer(ColorControlCluster.with(ColorControl.Feature.HueSaturation, ColorControl.Feature.ColorTemperature), {
998
987
  colorMode: ColorControl.ColorMode.CurrentHueAndCurrentSaturation,
999
988
  enhancedColorMode: ColorControl.EnhancedColorMode.CurrentHueAndCurrentSaturation,
1000
- colorCapabilities: { xy: false, hueSaturation: true, colorLoop: false, enhancedHue: false, colorTemperature: false },
989
+ colorCapabilities: { xy: false, hueSaturation: true, colorLoop: false, enhancedHue: false, colorTemperature: true },
1001
990
  options: {
1002
991
  executeIfOff: false,
1003
992
  },
1004
993
  numberOfPrimaries: null,
1005
994
  currentHue,
1006
995
  currentSaturation,
996
+ colorTemperatureMireds,
997
+ colorTempPhysicalMinMireds,
998
+ colorTempPhysicalMaxMireds,
999
+ coupleColorTempToLevelMinMireds: colorTempPhysicalMinMireds,
1000
+ startUpColorTemperatureMireds: null,
1001
+ remainingTime: 0,
1007
1002
  }, {
1008
- moveToHue: async ({ request, attributes, endpoint }) => {
1003
+ moveToHue: async () => {
1009
1004
  },
1010
1005
  moveHue: async () => {
1011
1006
  },
1012
1007
  stepHue: async () => {
1013
1008
  },
1014
- moveToSaturation: async ({ request, attributes, endpoint }) => {
1009
+ moveToSaturation: async () => {
1015
1010
  },
1016
1011
  moveSaturation: async () => {
1017
1012
  },
1018
1013
  stepSaturation: async () => {
1019
1014
  },
1020
- moveToHueAndSaturation: async ({ request, attributes, endpoint }) => {
1015
+ moveToHueAndSaturation: async () => {
1021
1016
  },
1022
1017
  stopMoveStep: async () => {
1023
1018
  },
1019
+ moveToColorTemperature: async () => {
1020
+ },
1021
+ moveColorTemperature: async () => {
1022
+ },
1023
+ stepColorTemperature: async () => {
1024
+ },
1024
1025
  }, {});
1025
1026
  }
1026
- createHsColorControlClusterServer(currentHue = 0, currentSaturation = 0) {
1027
- this.addClusterServer(this.getHsColorControlClusterServer(currentHue, currentSaturation));
1027
+ createHsColorControlClusterServer(currentHue = 0, currentSaturation = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
1028
+ this.addClusterServer(this.getHsColorControlClusterServer(currentHue, currentSaturation, colorTemperatureMireds, colorTempPhysicalMinMireds, colorTempPhysicalMaxMireds));
1028
1029
  }
1029
1030
  getCtColorControlClusterServer(colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
1030
1031
  return ClusterServer(ColorControlCluster.with(ColorControl.Feature.ColorTemperature), {
@@ -1039,11 +1040,12 @@ export class MatterbridgeEndpoint extends Endpoint {
1039
1040
  colorTempPhysicalMinMireds,
1040
1041
  colorTempPhysicalMaxMireds,
1041
1042
  coupleColorTempToLevelMinMireds: colorTempPhysicalMinMireds,
1043
+ remainingTime: 0,
1042
1044
  startUpColorTemperatureMireds: null,
1043
1045
  }, {
1044
1046
  stopMoveStep: async () => {
1045
1047
  },
1046
- moveToColorTemperature: async ({ request, attributes, endpoint }) => {
1048
+ moveToColorTemperature: async () => {
1047
1049
  },
1048
1050
  moveColorTemperature: async () => {
1049
1051
  },
@@ -1104,21 +1106,12 @@ export class MatterbridgeEndpoint extends Endpoint {
1104
1106
  currentPositionLiftPercent100ths: positionPercent100ths ?? 0,
1105
1107
  }, {
1106
1108
  upOrOpen: async (data) => {
1107
- this.log.debug('Matter command: upOrOpen');
1108
- await this.commandHandler.executeHandler('upOrOpen', data);
1109
1109
  },
1110
1110
  downOrClose: async (data) => {
1111
- this.log.debug('Matter command: downOrClose');
1112
- await this.commandHandler.executeHandler('downOrClose', data);
1113
1111
  },
1114
1112
  stopMotion: async (data) => {
1115
- this.log.debug('Matter command: stopMotion');
1116
- await this.commandHandler.executeHandler('stopMotion', data);
1117
1113
  },
1118
1114
  goToLiftPercentage: async (data) => {
1119
- this.log.debug(`Matter command: goToLiftPercentage: ${data.request.liftPercent100thsValue} current: ${data.attributes.currentPositionLiftPercent100ths?.getLocal()} ` +
1120
- `target: ${data.attributes.targetPositionLiftPercent100ths?.getLocal()} status: ${data.attributes.operationalStatus.getLocal().lift}`);
1121
- await this.commandHandler.executeHandler('goToLiftPercentage', data);
1122
1115
  },
1123
1116
  }, {});
1124
1117
  }
@@ -1184,12 +1177,8 @@ export class MatterbridgeEndpoint extends Endpoint {
1184
1177
  supportedOperatingModes: { normal: true, vacation: false, privacy: false, noRemoteLockUnlock: false, passage: false },
1185
1178
  }, {
1186
1179
  lockDoor: async (data) => {
1187
- this.log.debug('Matter command: lockDoor', data.request);
1188
- await this.commandHandler.executeHandler('lockDoor', data);
1189
1180
  },
1190
1181
  unlockDoor: async (data) => {
1191
- this.log.debug('Matter command: unlockDoor', data.request);
1192
- await this.commandHandler.executeHandler('unlockDoor', data);
1193
1182
  },
1194
1183
  }, {
1195
1184
  doorLockAlarm: true,
@@ -1304,8 +1293,6 @@ export class MatterbridgeEndpoint extends Endpoint {
1304
1293
  startUpMode: startUpMode,
1305
1294
  }, {
1306
1295
  changeToMode: async (data) => {
1307
- this.log.debug('Matter command: ModeSelectCluster.changeToMode', data.request);
1308
- await this.commandHandler.executeHandler('changeToMode', data);
1309
1296
  },
1310
1297
  });
1311
1298
  }
@@ -1401,8 +1388,6 @@ export class MatterbridgeEndpoint extends Endpoint {
1401
1388
  sensorFault: { generalFault: sensorFault },
1402
1389
  }, {
1403
1390
  enableDisableAlarm: async (data) => {
1404
- this.log.debug('Matter command: enableDisableAlarm', data.request);
1405
- await this.commandHandler.executeHandler('enableDisableAlarm', data);
1406
1391
  },
1407
1392
  }, {
1408
1393
  alarmsStateChanged: true,
@@ -1501,8 +1486,6 @@ export class MatterbridgeEndpoint extends Endpoint {
1501
1486
  absMaxHeatSetpointLimit: maxHeatSetpointLimit * 100,
1502
1487
  }, {
1503
1488
  setpointRaiseLower: async (data) => {
1504
- this.log.debug('Matter command: setpointRaiseLower', data.request);
1505
- await this.commandHandler.executeHandler('setpointRaiseLower', data);
1506
1489
  },
1507
1490
  }, {});
1508
1491
  }
@@ -1521,8 +1504,6 @@ export class MatterbridgeEndpoint extends Endpoint {
1521
1504
  absMaxCoolSetpointLimit: maxCoolSetpointLimit * 100,
1522
1505
  }, {
1523
1506
  setpointRaiseLower: async (data) => {
1524
- this.log.debug('Matter command: setpointRaiseLower', data.request);
1525
- await this.commandHandler.executeHandler('setpointRaiseLower', data);
1526
1507
  },
1527
1508
  }, {});
1528
1509
  }
@@ -1548,8 +1529,6 @@ export class MatterbridgeEndpoint extends Endpoint {
1548
1529
  thermostatRunningMode: Thermostat.ThermostatRunningMode.Off,
1549
1530
  }, {
1550
1531
  setpointRaiseLower: async (data) => {
1551
- this.log.debug('Matter command: setpointRaiseLower', data.request);
1552
- await this.commandHandler.executeHandler('setpointRaiseLower', data);
1553
1532
  },
1554
1533
  }, {});
1555
1534
  }
@@ -1570,8 +1549,6 @@ export class MatterbridgeEndpoint extends Endpoint {
1570
1549
  interconnectCoAlarm: SmokeCoAlarm.AlarmState.Normal,
1571
1550
  }, {
1572
1551
  selfTestRequest: async (data) => {
1573
- this.log.debug('Matter command: selfTestRequest');
1574
- await this.commandHandler.executeHandler('selfTestRequest', data);
1575
1552
  },
1576
1553
  }, {
1577
1554
  smokeAlarm: true,
@@ -1718,8 +1695,6 @@ export class MatterbridgeEndpoint extends Endpoint {
1718
1695
  speedCurrent: 0,
1719
1696
  }, {
1720
1697
  step: async (data) => {
1721
- this.log.debug('Matter command: step', data.request);
1722
- await this.commandHandler.executeHandler('step', data);
1723
1698
  },
1724
1699
  }, {});
1725
1700
  }
@@ -1,5 +1,5 @@
1
1
  import { MatterbridgeDevice } from './matterbridgeDevice.js';
2
- import { CYAN, nf, wr } from 'node-ansi-logger';
2
+ import { CYAN, nf } from 'node-ansi-logger';
3
3
  import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
4
4
  import { isValidArray, isValidObject } from './utils/utils.js';
5
5
  export class MatterbridgePlatform {
@@ -71,17 +71,33 @@ export class MatterbridgePlatform {
71
71
  return true;
72
72
  }
73
73
  validateDeviceWhiteBlackList(device, log = true) {
74
- if (isValidArray(this.config.whiteList, 1) && !this.config.whiteList.includes(device)) {
75
- if (log)
76
- this.log.info(`Skipping device ${CYAN}${device}${nf} because not in whitelist`);
77
- return false;
74
+ if (!Array.isArray(device))
75
+ device = [device];
76
+ let blackListBlocked = 0;
77
+ if (isValidArray(this.config.blackList, 1)) {
78
+ for (const d of device)
79
+ if (this.config.blackList.includes(d))
80
+ blackListBlocked++;
78
81
  }
79
- if (isValidArray(this.config.blackList, 1) && this.config.blackList.includes(device)) {
82
+ if (blackListBlocked > 0) {
80
83
  if (log)
81
- this.log.info(`Skipping device ${CYAN}${device}${nf} because in blacklist`);
84
+ this.log.info(`Skipping device ${CYAN}${device.join(', ')}${nf} because in blacklist`);
82
85
  return false;
83
86
  }
84
- return true;
87
+ let whiteListPassed = 0;
88
+ if (isValidArray(this.config.whiteList, 1)) {
89
+ for (const d of device)
90
+ if (this.config.whiteList.includes(d))
91
+ whiteListPassed++;
92
+ }
93
+ else
94
+ whiteListPassed++;
95
+ if (whiteListPassed > 0) {
96
+ return true;
97
+ }
98
+ if (log)
99
+ this.log.info(`Skipping device ${CYAN}${device.join(', ')}${nf} because not in whitelist`);
100
+ return false;
85
101
  }
86
102
  validateEntityBlackList(device, entity, log = true) {
87
103
  if (isValidArray(this.config.entityBlackList, 1) && this.config.entityBlackList.find((e) => e === entity)) {
@@ -91,7 +107,7 @@ export class MatterbridgePlatform {
91
107
  }
92
108
  if (isValidObject(this.config.deviceEntityBlackList, 1) && device in this.config.deviceEntityBlackList && this.config.deviceEntityBlackList[device].includes(entity)) {
93
109
  if (log)
94
- this.log.info(`Skipping entity ${CYAN}${entity}${wr} for device ${CYAN}${device}${nf} because in deviceEntityBlackList`);
110
+ this.log.info(`Skipping entity ${CYAN}${entity}${nf} for device ${CYAN}${device}${nf} because in deviceEntityBlackList`);
95
111
  return false;
96
112
  }
97
113
  return true;
@@ -111,6 +111,9 @@ export async function wsMessageHandler(client, message) {
111
111
  let serial = device.getClusterServer(BasicInformationCluster)?.attributes.serialNumber?.getLocal();
112
112
  if (!serial)
113
113
  serial = device.getClusterServer(BridgedDeviceBasicInformationCluster)?.attributes.serialNumber?.getLocal() ?? 'Unknown';
114
+ let productUrl = device.getClusterServer(BasicInformationCluster)?.attributes.productUrl?.getLocal();
115
+ if (!productUrl)
116
+ productUrl = device.getClusterServer(BridgedDeviceBasicInformationCluster)?.attributes.productUrl?.getLocal() ?? 'Unknown';
114
117
  let uniqueId = device.getClusterServer(BasicInformationCluster)?.attributes.uniqueId?.getLocal();
115
118
  if (!uniqueId)
116
119
  uniqueId = device.getClusterServer(BridgedDeviceBasicInformationCluster)?.attributes.uniqueId?.getLocal() ?? 'Unknown';
@@ -121,6 +124,8 @@ export async function wsMessageHandler(client, message) {
121
124
  endpoint: device.number,
122
125
  name,
123
126
  serial,
127
+ productUrl,
128
+ configUrl: device.configUrl,
124
129
  uniqueId,
125
130
  cluster: cluster,
126
131
  });
@@ -558,8 +558,14 @@ export class PluginManager {
558
558
  plugin.connected = undefined;
559
559
  plugin.platform = undefined;
560
560
  if (removeAllDevices) {
561
- this.log.info(`Removing all devices for plugin ${plg}${plugin.name}${nf}: ${reason}...`);
562
- await this.matterbridge.removeAllBridgedDevices(plugin.name);
561
+ if (this.matterbridge.edge) {
562
+ this.log.info(`Removing all endpoints for plugin ${plg}${plugin.name}${nf}: ${reason}...`);
563
+ await this.matterbridge.removeAllBridgedEndpoints(plugin.name);
564
+ }
565
+ else {
566
+ this.log.info(`Removing all devices for plugin ${plg}${plugin.name}${nf}: ${reason}...`);
567
+ await this.matterbridge.removeAllBridgedDevices(plugin.name);
568
+ }
563
569
  }
564
570
  plugin.registeredDevices = undefined;
565
571
  plugin.addedDevices = undefined;
@@ -139,99 +139,43 @@ export function xyToHsl(x, y) {
139
139
  const rgb = xyColorToRgbColor(x, y);
140
140
  return rgbColorToHslColor(rgb);
141
141
  }
142
- export function testColors() {
143
- const colors = [
144
- { name: 'Pure Red 0', hsl: { h: 0, s: 100, l: 50 }, rgb: { r: 255, g: 0, b: 0 }, xy: { x: 0.7006, y: 0.2993 } },
145
- { name: 'Bright Orange 30', hsl: { h: 30, s: 100, l: 50 }, rgb: { r: 255, g: 128, b: 0 }, xy: { x: 0.6112, y: 0.375 } },
146
- { name: 'Pure Yellow 60', hsl: { h: 60, s: 100, l: 50 }, rgb: { r: 255, g: 255, b: 0 }, xy: { x: 0.4442, y: 0.5166 } },
147
- { name: 'Lime Green 90', hsl: { h: 90, s: 100, l: 50 }, rgb: { r: 128, g: 255, b: 0 }, xy: { x: 0.2707, y: 0.6635 } },
148
- { name: 'Pure Green 120', hsl: { h: 120, s: 100, l: 50 }, rgb: { r: 0, g: 255, b: 0 }, xy: { x: 0.1724, y: 0.7468 } },
149
- { name: 'Light Sea Green 150', hsl: { h: 150, s: 100, l: 50 }, rgb: { r: 0, g: 255, b: 128 }, xy: { x: 0.1642, y: 0.5886 } },
150
- { name: 'Pure Cyan 180', hsl: { h: 180, s: 100, l: 50 }, rgb: { r: 0, g: 255, b: 255 }, xy: { x: 0.1513, y: 0.3425 } },
151
- { name: 'Deep Sky Blue 210', hsl: { h: 210, s: 100, l: 50 }, rgb: { r: 0, g: 128, b: 255 }, xy: { x: 0.1406, y: 0.1382 } },
152
- { name: 'Pure Blue 240', hsl: { h: 240, s: 100, l: 50 }, rgb: { r: 0, g: 0, b: 255 }, xy: { x: 0.1355, y: 0.0399 } },
153
- { name: 'Blue Violet 270', hsl: { h: 270, s: 100, l: 50 }, rgb: { r: 128, g: 0, b: 255 }, xy: { x: 0.2181, y: 0.0778 } },
154
- { name: 'Pure Magenta 300', hsl: { h: 300, s: 100, l: 50 }, rgb: { r: 255, g: 0, b: 255 }, xy: { x: 0.3855, y: 0.1546 } },
155
- { name: 'Deep Pink 330', hsl: { h: 330, s: 100, l: 50 }, rgb: { r: 255, g: 0, b: 128 }, xy: { x: 0.5797, y: 0.2438 } },
156
- { name: 'Pure Red 50% 0', hsl: { h: 0, s: 50, l: 50 }, rgb: { r: 192, g: 64, b: 64 }, xy: { x: 0.6036, y: 0.3069 } },
157
- { name: 'Bright Orange 50% 30', hsl: { h: 30, s: 50, l: 50 }, rgb: { r: 192, g: 128, b: 64 }, xy: { x: 0.5194, y: 0.3928 } },
158
- { name: 'Pure Yellow 50% 60', hsl: { h: 60, s: 50, l: 50 }, rgb: { r: 192, g: 192, b: 64 }, xy: { x: 0.4258, y: 0.4883 } },
159
- { name: 'Lime Green 50% 90', hsl: { h: 90, s: 50, l: 50 }, rgb: { r: 128, g: 192, b: 64 }, xy: { x: 0.3159, y: 0.5639 } },
160
- { name: 'Pure Green 50% 120', hsl: { h: 120, s: 50, l: 50 }, rgb: { r: 64, g: 192, b: 64 }, xy: { x: 0.2127, y: 0.6349 } },
161
- { name: 'Light Sea Green 50% 150', hsl: { h: 150, s: 50, l: 50 }, rgb: { r: 64, g: 192, b: 128 }, xy: { x: 0.1932, y: 0.4845 } },
162
- { name: 'Pure Cyan 50% 180', hsl: { h: 180, s: 50, l: 50 }, rgb: { r: 64, g: 192, b: 192 }, xy: { x: 0.1745, y: 0.3407 } },
163
- { name: 'Deep Sky Blue 50% 210', hsl: { h: 210, s: 50, l: 50 }, rgb: { r: 64, g: 128, b: 192 }, xy: { x: 0.1752, y: 0.211 } },
164
- { name: 'Pure Blue 50% 240', hsl: { h: 240, s: 50, l: 50 }, rgb: { r: 64, g: 64, b: 192 }, xy: { x: 0.1758, y: 0.102 } },
165
- { name: 'Blue Violet 50% 270', hsl: { h: 270, s: 50, l: 50 }, rgb: { r: 128, g: 64, b: 192 }, xy: { x: 0.2688, y: 0.137 } },
166
- { name: 'Pure Magenta 50% 300', hsl: { h: 300, s: 50, l: 50 }, rgb: { r: 192, g: 64, b: 192 }, xy: { x: 0.3772, y: 0.1777 } },
167
- { name: 'Deep Pink 50% 330', hsl: { h: 330, s: 50, l: 50 }, rgb: { r: 192, g: 64, b: 128 }, xy: { x: 0.489, y: 0.2416 } },
168
- ];
169
- colors.forEach((color) => {
170
- console.log(`\x1b[48;2;${color.rgb.r};${color.rgb.g};${color.rgb.b}mColor: ${color.name}\x1b[0m, hsl: { h: ${color.hsl.h}, s: ${color.hsl.s}, l: ${color.hsl.l} }, rgb: { r: ${color.rgb.r}, g: ${color.rgb.g}, b: ${color.rgb.b} }, xy: { x: ${color.xy.x}, y: ${color.xy.y} }`);
171
- const rgb = hslColorToRgbColor(color.hsl.h, color.hsl.s, color.hsl.l);
172
- assert(rgb.r === color.rgb.r && rgb.g === color.rgb.g && rgb.b === color.rgb.b, `\x1b[48;2;${rgb.r};${rgb.g};${rgb.b}mColor: ${color.name}\x1b[0m hslColorToRgbColor { r: ${rgb.r}, g: ${rgb.g}, b: ${rgb.b} } conversion error`);
173
- const hsl = rgbColorToHslColor({ r: color.rgb.r, g: color.rgb.g, b: color.rgb.b });
174
- assert(hsl.h === color.hsl.h && hsl.s === color.hsl.s && hsl.l === color.hsl.l, `Color: ${color.name} rgbColorToHslColor conversion error`);
175
- const xy = rgbColorToXYColor({ r: color.rgb.r, g: color.rgb.g, b: color.rgb.b });
176
- assert(xy.x === color.xy.x && xy.y === color.xy.y, `Color: ${color.name} rgbColorToXYColor conversion error got x ${xy.x} y ${xy.y}`);
177
- const rgb2 = xyColorToRgbColor(color.xy.x, color.xy.y);
178
- assert(rgb2.r === color.rgb.r && rgb2.g === color.rgb.g && rgb2.b === color.rgb.b, `\x1b[48;2;${rgb2.r};${rgb2.g};${rgb2.b}mColor: ${color.name}\x1b[0m xyColorToRgbColor(${color.xy.x}, ${color.xy.y}) conversion error -> r: ${rgb2.r} g: ${rgb2.g} b: ${rgb2.g}`);
179
- });
142
+ export function miredToKelvin(mired) {
143
+ return Math.round(1000000 / mired);
180
144
  }
181
- export function cie_to_rgb(x, y, brightness = 254) {
182
- const z = 1.0 - x - y;
183
- const Y = (brightness / 254).toFixed(2);
184
- const X = (Number(Y) / y) * x;
185
- const Z = (Number(Y) / y) * z;
186
- let red = X * 1.656492 - Number(Y) * 0.354851 - Z * 0.255038;
187
- let green = -X * 0.707196 + Number(Y) * 1.655397 + Z * 0.036152;
188
- let blue = X * 0.051713 - Number(Y) * 0.121364 + Z * 1.01153;
189
- if (red > blue && red > green && red > 1.0) {
190
- green = green / red;
191
- blue = blue / red;
192
- red = 1.0;
145
+ export function kelvinToMired(kelvin) {
146
+ return Math.round(1000000 / kelvin);
147
+ }
148
+ export function kelvinToRGB(kelvin) {
149
+ kelvin = Math.max(1000, Math.min(40000, kelvin)) / 100;
150
+ let r, g, b;
151
+ if (kelvin <= 66) {
152
+ r = 255;
193
153
  }
194
- else if (green > blue && green > red && green > 1.0) {
195
- red = red / green;
196
- blue = blue / green;
197
- green = 1.0;
154
+ else {
155
+ r = kelvin - 60;
156
+ r = 329.698727446 * Math.pow(r, -0.1332047592);
157
+ r = Math.max(0, Math.min(255, r));
198
158
  }
199
- else if (blue > red && blue > green && blue > 1.0) {
200
- red = red / blue;
201
- green = green / blue;
202
- blue = 1.0;
159
+ if (kelvin <= 66) {
160
+ g = kelvin;
161
+ g = 99.4708025861 * Math.log(g) - 161.1195681661;
162
+ g = Math.max(0, Math.min(255, g));
203
163
  }
204
- red = red <= 0.0031308 ? 12.92 * red : (1.0 + 0.055) * Math.pow(red, 1.0 / 2.4) - 0.055;
205
- green = green <= 0.0031308 ? 12.92 * green : (1.0 + 0.055) * Math.pow(green, 1.0 / 2.4) - 0.055;
206
- blue = blue <= 0.0031308 ? 12.92 * blue : (1.0 + 0.055) * Math.pow(blue, 1.0 / 2.4) - 0.055;
207
- red = Math.round(red * 255);
208
- green = Math.round(green * 255);
209
- blue = Math.round(blue * 255);
210
- if (isNaN(red) || red < 0) {
211
- red = 0;
164
+ else {
165
+ g = kelvin - 60;
166
+ g = 288.1221695283 * Math.pow(g, -0.0755148492);
167
+ g = Math.max(0, Math.min(255, g));
212
168
  }
213
- if (isNaN(green) || green < 0) {
214
- green = 0;
169
+ if (kelvin >= 66) {
170
+ b = 255;
215
171
  }
216
- if (isNaN(blue) || blue < 0) {
217
- blue = 0;
172
+ else if (kelvin <= 19) {
173
+ b = 0;
218
174
  }
219
- return { r: red, g: green, b: blue };
220
- }
221
- export function rgb_to_cie(red, green, blue) {
222
- red = red > 0.04045 ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : red / 12.92;
223
- green = green > 0.04045 ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : green / 12.92;
224
- blue = blue > 0.04045 ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : blue / 12.92;
225
- const X = red * 0.664511 + green * 0.154324 + blue * 0.162028;
226
- const Y = red * 0.283881 + green * 0.668433 + blue * 0.047685;
227
- const Z = red * 0.000088 + green * 0.07231 + blue * 0.986039;
228
- let x = (X / (X + Y + Z)).toFixed(4);
229
- let y = (Y / (X + Y + Z)).toFixed(4);
230
- if (isNaN(Number(x))) {
231
- x = '0';
232
- }
233
- if (isNaN(Number(y))) {
234
- y = '0';
235
- }
236
- return { x: Number(x), y: Number(y) };
175
+ else {
176
+ b = kelvin - 10;
177
+ b = 138.5177312231 * Math.log(b) - 305.0447927307;
178
+ b = Math.max(0, Math.min(255, b));
179
+ }
180
+ return { r: Math.round(r), g: Math.round(g), b: Math.round(b) };
237
181
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "files": {
3
3
  "main.css": "./static/css/main.823e08b6.css",
4
- "main.js": "./static/js/main.565ff6ba.js",
4
+ "main.js": "./static/js/main.4dd7e165.js",
5
5
  "static/js/453.abd36b29.chunk.js": "./static/js/453.abd36b29.chunk.js",
6
6
  "static/media/roboto-latin-700-normal.woff2": "./static/media/roboto-latin-700-normal.4535474e1cf8598695ad.woff2",
7
7
  "static/media/roboto-latin-500-normal.woff2": "./static/media/roboto-latin-500-normal.7077203b1982951ecf76.woff2",
@@ -61,11 +61,11 @@
61
61
  "static/media/roboto-greek-ext-400-normal.woff": "./static/media/roboto-greek-ext-400-normal.16eb83b4a3b1ea994243.woff",
62
62
  "index.html": "./index.html",
63
63
  "main.823e08b6.css.map": "./static/css/main.823e08b6.css.map",
64
- "main.565ff6ba.js.map": "./static/js/main.565ff6ba.js.map",
64
+ "main.4dd7e165.js.map": "./static/js/main.4dd7e165.js.map",
65
65
  "453.abd36b29.chunk.js.map": "./static/js/453.abd36b29.chunk.js.map"
66
66
  },
67
67
  "entrypoints": [
68
68
  "static/css/main.823e08b6.css",
69
- "static/js/main.565ff6ba.js"
69
+ "static/js/main.4dd7e165.js"
70
70
  ]
71
71
  }
@@ -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.565ff6ba.js"></script><link href="./static/css/main.823e08b6.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.4dd7e165.js"></script><link href="./static/css/main.823e08b6.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>