@riddix/hamh 2.1.0-alpha.740 → 2.1.0-alpha.741

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.
@@ -124034,6 +124034,154 @@ var init_clusters = __esm({
124034
124034
  }
124035
124035
  });
124036
124036
 
124037
+ // ../common/dist/controller-compat.js
124038
+ function classifyController(vendorId3) {
124039
+ return controllerByVendorId[vendorId3];
124040
+ }
124041
+ function computeControllerWarnings(controllers, exposed) {
124042
+ const seen = /* @__PURE__ */ new Set();
124043
+ const warnings = [];
124044
+ for (const { entityId, deviceTypeId } of exposed) {
124045
+ const support = deviceTypeIdSupport[deviceTypeId];
124046
+ if (!support)
124047
+ continue;
124048
+ for (const controller of controllers) {
124049
+ if (support[controller] !== "no")
124050
+ continue;
124051
+ const key = `${entityId}:${deviceTypeId}:${controller}`;
124052
+ if (seen.has(key))
124053
+ continue;
124054
+ seen.add(key);
124055
+ warnings.push({
124056
+ entityId,
124057
+ deviceTypeId,
124058
+ controller,
124059
+ controllerLabel: controllerLabels[controller],
124060
+ note: support.note
124061
+ });
124062
+ }
124063
+ }
124064
+ return warnings;
124065
+ }
124066
+ var controllerByVendorId, deviceTypeIdSupport, controllerLabels;
124067
+ var init_controller_compat = __esm({
124068
+ "../common/dist/controller-compat.js"() {
124069
+ "use strict";
124070
+ controllerByVendorId = {
124071
+ 4937: "apple",
124072
+ // 0x1349 Apple Home
124073
+ 4996: "apple",
124074
+ // 0x1384 Apple (iCloud Keychain)
124075
+ 24582: "google",
124076
+ // 0x6006 Google Home
124077
+ 4631: "alexa",
124078
+ // 0x1217 Amazon Alexa
124079
+ 4448: "alexa"
124080
+ // 0x1160 Amazon (some Alexa ecosystems)
124081
+ };
124082
+ deviceTypeIdSupport = {
124083
+ 43: {
124084
+ apple: "no",
124085
+ google: "yes",
124086
+ alexa: "yes",
124087
+ note: "Apple Home has no standalone fan."
124088
+ },
124089
+ 45: {
124090
+ apple: "no",
124091
+ google: "yes",
124092
+ alexa: "yes",
124093
+ note: "Apple Home does not list air purifiers."
124094
+ },
124095
+ 34: {
124096
+ apple: "no",
124097
+ google: "yes",
124098
+ alexa: "no",
124099
+ note: "Only Google Home shows Matter speakers."
124100
+ },
124101
+ 40: {
124102
+ apple: "no",
124103
+ google: "no",
124104
+ alexa: "no",
124105
+ note: "TV/media types are not shown by these controllers."
124106
+ },
124107
+ 773: {
124108
+ apple: "no",
124109
+ google: "yes",
124110
+ alexa: "no",
124111
+ note: "Only Google Home shows pressure sensors."
124112
+ },
124113
+ 774: {
124114
+ apple: "no",
124115
+ google: "yes",
124116
+ alexa: "no",
124117
+ note: "Only Google Home shows flow sensors."
124118
+ },
124119
+ 44: {
124120
+ apple: "no",
124121
+ google: "yes",
124122
+ alexa: "yes",
124123
+ note: "Apple Home does not show air quality."
124124
+ },
124125
+ 23: {
124126
+ apple: "no",
124127
+ google: "no",
124128
+ alexa: "unknown",
124129
+ note: "Power/energy is rarely shown unless it is on a smart plug."
124130
+ },
124131
+ 24: {
124132
+ apple: "no",
124133
+ google: "no",
124134
+ alexa: "no",
124135
+ note: "Battery is usually shown inside a device, not on its own."
124136
+ },
124137
+ 39: {
124138
+ apple: "no",
124139
+ google: "no",
124140
+ alexa: "no",
124141
+ note: "Mode Select is not supported here (Google #356)."
124142
+ },
124143
+ 66: { apple: "no", google: "no", alexa: "no" },
124144
+ 771: {
124145
+ apple: "no",
124146
+ google: "yes",
124147
+ alexa: "no",
124148
+ note: "Only Google Home shows pumps."
124149
+ },
124150
+ 68: {
124151
+ apple: "no",
124152
+ google: "no",
124153
+ alexa: "no",
124154
+ note: "Newer Matter detector, thin support; Alexa may reject it (#365)."
124155
+ },
124156
+ 65: {
124157
+ apple: "no",
124158
+ google: "no",
124159
+ alexa: "no",
124160
+ note: "Newer Matter detector, thin support; Alexa may reject it (#365)."
124161
+ },
124162
+ 67: {
124163
+ apple: "yes",
124164
+ google: "no",
124165
+ alexa: "yes",
124166
+ note: "Newer Matter detector, can be risky on Alexa bridges (#365)."
124167
+ },
124168
+ 118: { apple: "yes", google: "no", alexa: "yes" },
124169
+ 117: {
124170
+ apple: "no",
124171
+ google: "no",
124172
+ alexa: "unknown",
124173
+ note: "Appliance types have little controller support."
124174
+ },
124175
+ 15: { apple: "partial", google: "no", alexa: "yes" }
124176
+ };
124177
+ controllerLabels = {
124178
+ apple: "Apple Home",
124179
+ google: "Google Home",
124180
+ alexa: "Alexa"
124181
+ };
124182
+ }
124183
+ });
124184
+
124037
124185
  // ../common/dist/controller-profiles.js
124038
124186
  var init_controller_profiles = __esm({
124039
124187
  "../common/dist/controller-profiles.js"() {
@@ -125070,6 +125218,7 @@ var init_dist = __esm({
125070
125218
  init_bridge_export();
125071
125219
  init_bridge_templates();
125072
125220
  init_clusters();
125221
+ init_controller_compat();
125073
125222
  init_controller_profiles();
125074
125223
  init_diagnostic_event();
125075
125224
  init_domains();
@@ -126858,6 +127007,7 @@ function entityMappingApi(mappingStorage) {
126858
127007
  }
126859
127008
 
126860
127009
  // src/api/health-api.ts
127010
+ init_dist();
126861
127011
  import express8 from "express";
126862
127012
  function healthApi(bridgeService, haClient, version2, startTime) {
126863
127013
  const router = express8.Router();
@@ -126903,6 +127053,12 @@ function healthApi(bridgeService, haClient, version2, startTime) {
126903
127053
  const data = b.data;
126904
127054
  const fabrics = data.commissioning?.fabrics ?? [];
126905
127055
  const sessionInfo = b.getSessionInfo();
127056
+ const controllers = [
127057
+ ...new Set(
127058
+ fabrics.map((f) => classifyController(f.rootVendorId)).filter((c) => c !== void 0)
127059
+ )
127060
+ ];
127061
+ const controllerWarnings = controllers.length > 0 ? computeControllerWarnings(controllers, b.getExposedDeviceTypes()) : [];
126906
127062
  return {
126907
127063
  id: data.id,
126908
127064
  name: data.name,
@@ -126921,6 +127077,7 @@ function healthApi(bridgeService, haClient, version2, startTime) {
126921
127077
  rootVendorId: f.rootVendorId
126922
127078
  })),
126923
127079
  failedEntityCount: data.failedEntities?.length ?? 0,
127080
+ controllerWarnings,
126924
127081
  connectivity: {
126925
127082
  totalSessions: sessionInfo.totalSessions,
126926
127083
  totalSubscriptions: sessionInfo.totalSubscriptions,
@@ -148310,6 +148467,28 @@ var Bridge = class {
148310
148467
  get aggregator() {
148311
148468
  return this.endpointManager.root;
148312
148469
  }
148470
+ /**
148471
+ * The entity id and numeric Matter device type of every exposed endpoint,
148472
+ * walking composed sub-endpoints. Used to warn when a device type is not
148473
+ * supported by a commissioned controller (#365 class).
148474
+ */
148475
+ getExposedDeviceTypes() {
148476
+ const out = [];
148477
+ const collect = (ep, inheritedEntityId) => {
148478
+ const entityId = ep.entityId ?? inheritedEntityId;
148479
+ const deviceTypeId = ep.type?.deviceType;
148480
+ if (typeof deviceTypeId === "number" && entityId) {
148481
+ out.push({ entityId, deviceTypeId });
148482
+ }
148483
+ for (const child of ep.parts) {
148484
+ collect(child, entityId);
148485
+ }
148486
+ };
148487
+ for (const ep of this.aggregator.parts) {
148488
+ collect(ep);
148489
+ }
148490
+ return out;
148491
+ }
148313
148492
  get pluginInfo() {
148314
148493
  return this.endpointManager.getPluginInfo();
148315
148494
  }
@@ -163435,6 +163614,28 @@ var ServerModeBridge = class {
163435
163614
  this.endpointManager.failedEntities
163436
163615
  );
163437
163616
  }
163617
+ /**
163618
+ * The entity id and numeric Matter device type of every exposed device, so a
163619
+ * controller-support warning can be raised per bridge (#365 class). Server
163620
+ * mode is flat, but walk parts anyway to stay correct.
163621
+ */
163622
+ getExposedDeviceTypes() {
163623
+ const out = [];
163624
+ const collect = (ep, inheritedEntityId) => {
163625
+ const entityId = ep.entityId ?? inheritedEntityId;
163626
+ const deviceTypeId = ep.type?.deviceType;
163627
+ if (typeof deviceTypeId === "number" && entityId) {
163628
+ out.push({ entityId, deviceTypeId });
163629
+ }
163630
+ for (const child of ep.parts) {
163631
+ collect(child, entityId);
163632
+ }
163633
+ };
163634
+ for (const device of this.endpointManager.devices) {
163635
+ collect(device);
163636
+ }
163637
+ return out;
163638
+ }
163438
163639
  getSessionInfo() {
163439
163640
  try {
163440
163641
  const sessionManager = this.server.env.get(SessionManager);