myio-js-library 0.1.144 → 0.1.145

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/dist/index.cjs CHANGED
@@ -15403,7 +15403,13 @@ var SettingsModalView = class {
15403
15403
  render(initialData) {
15404
15404
  this.originalActiveElement = document.activeElement;
15405
15405
  document.body.appendChild(this.container);
15406
- this.populateForm(initialData);
15406
+ let formData = { ...initialData };
15407
+ if (initialData.deviceMapInstaneousPower && typeof initialData.deviceMapInstaneousPower === "object") {
15408
+ console.log("[SettingsModalView] Configura\xE7\xE3o salva encontrada (Device Scope). Processando...");
15409
+ const flatLimits = this.parseDeviceSavedLimits(initialData.deviceMapInstaneousPower);
15410
+ formData = { ...formData, ...flatLimits };
15411
+ }
15412
+ this.populateForm(formData);
15407
15413
  this.attachEventListeners();
15408
15414
  this.setupAccessibility();
15409
15415
  this.setupFocusTrap();
@@ -16972,6 +16978,42 @@ var SettingsModalView = class {
16972
16978
  }
16973
16979
  }
16974
16980
  }
16981
+ /**
16982
+ * Helper: Traduz o JSON RFC-0086 (deviceMapInstaneousPower)
16983
+ * para os campos planos do formulário (ex: standbyLimitUpConsumption)
16984
+ */
16985
+ parseDeviceSavedLimits(deviceJson) {
16986
+ const extracted = {};
16987
+ try {
16988
+ if (!deviceJson || !deviceJson.limitsByInstantaneoustPowerType) return extracted;
16989
+ const consumptionGroup = deviceJson.limitsByInstantaneoustPowerType.find(
16990
+ (g) => g.telemetryType === "consumption"
16991
+ );
16992
+ const deviceItem = consumptionGroup?.itemsByDeviceType?.[0];
16993
+ if (!deviceItem?.limitsByDeviceStatus) return extracted;
16994
+ const mapPrefix = {
16995
+ "standBy": "standby",
16996
+ "normal": "normal",
16997
+ "alert": "alert",
16998
+ "failure": "failure"
16999
+ };
17000
+ deviceItem.limitsByDeviceStatus.forEach((status) => {
17001
+ const prefix = mapPrefix[status.deviceStatusName];
17002
+ if (prefix && status.limitsValues) {
17003
+ const { baseValue, topValue } = status.limitsValues;
17004
+ if (baseValue !== null && baseValue !== void 0) {
17005
+ extracted[`${prefix}LimitDownConsumption`] = baseValue;
17006
+ }
17007
+ if (topValue !== null && topValue !== void 0) {
17008
+ extracted[`${prefix}LimitUpConsumption`] = topValue;
17009
+ }
17010
+ }
17011
+ });
17012
+ } catch (e) {
17013
+ console.warn("[SettingsModalView] Erro ao processar deviceMapInstaneousPower:", e);
17014
+ }
17015
+ return extracted;
17016
+ }
16975
17017
  attachEventListeners() {
16976
17018
  this.form.addEventListener("submit", (event) => {
16977
17019
  event.preventDefault();
@@ -17243,11 +17285,25 @@ var DefaultSettingsPersister = class {
17243
17285
  }
17244
17286
  async saveServerScopeAttributes(deviceId, attributes) {
17245
17287
  try {
17246
- const mapInstantaneousPower = this.buildMapInstantaneousPower(attributes);
17247
- const payload = {
17248
- mapInstantaneousPower
17249
- };
17250
- console.log("[SettingsPersister] RFC-0080: Saving mapInstantaneousPower as JSON:", payload);
17288
+ const payload = { ...attributes };
17289
+ const effectiveDeviceType = this.getEffectiveDeviceType();
17290
+ const deviceJson = this.buildDevicePowerJson(payload, effectiveDeviceType);
17291
+ if (deviceJson) {
17292
+ payload.deviceMapInstaneousPower = deviceJson;
17293
+ }
17294
+ const flatKeysToRemove = [
17295
+ "telemetryType",
17296
+ "standbyLimitDownConsumption",
17297
+ "standbyLimitUpConsumption",
17298
+ "normalLimitDownConsumption",
17299
+ "normalLimitUpConsumption",
17300
+ "alertLimitDownConsumption",
17301
+ "alertLimitUpConsumption",
17302
+ "failureLimitDownConsumption",
17303
+ "failureLimitUpConsumption"
17304
+ ];
17305
+ flatKeysToRemove.forEach((key) => delete payload[key]);
17306
+ console.log("[SettingsPersister] Saving Server Scope Attributes:", payload);
17251
17307
  const res = await fetch(
17252
17308
  `${this.tbBaseUrl}/api/plugins/telemetry/DEVICE/${deviceId}/attributes/SERVER_SCOPE`,
17253
17309
  {
@@ -17264,13 +17320,70 @@ var DefaultSettingsPersister = class {
17264
17320
  }
17265
17321
  return {
17266
17322
  ok: true,
17267
- updatedKeys: ["mapInstantaneousPower"]
17323
+ updatedKeys: Object.keys(payload)
17268
17324
  };
17269
17325
  } catch (error) {
17270
17326
  console.error("[SettingsPersister] Attributes save failed:", error);
17271
17327
  return { ok: false, error: this.mapError(error) };
17272
17328
  }
17273
17329
  }
17330
+ /**
17331
+ * Constrói o JSON Reduzido (apenas o deviceType atual) para salvar no Device.
17332
+ * Retorna null se nenhum campo de potência estiver presente.
17333
+ */
17334
+ buildDevicePowerJson(formData, deviceType) {
17335
+ const statuses = ["standby", "normal", "alert", "failure"];
17336
+ const hasPowerData = statuses.some(
17337
+ (status) => formData[`${status}LimitDownConsumption`] !== void 0 && formData[`${status}LimitDownConsumption`] !== "" || formData[`${status}LimitUpConsumption`] !== void 0 && formData[`${status}LimitUpConsumption`] !== ""
17338
+ );
17339
+ if (!hasPowerData) return null;
17340
+ const statusMap = {
17341
+ "standby": "standBy",
17342
+ "normal": "normal",
17343
+ "alert": "alert",
17344
+ "failure": "failure"
17345
+ };
17346
+ const limitsList = [];
17347
+ statuses.forEach((statusKey) => {
17348
+ const down = formData[`${statusKey}LimitDownConsumption`];
17349
+ const up = formData[`${statusKey}LimitUpConsumption`];
17350
+ if (down !== void 0 && down !== "" || up !== void 0 && up !== "") {
17351
+ limitsList.push({
17352
+ deviceStatusName: statusMap[statusKey],
17353
+ limitsValues: {
17354
+ // Converte para Number ou null
17355
+ baseValue: down !== "" && down !== void 0 ? Number(down) : null,
17356
+ topValue: up !== "" && up !== void 0 ? Number(up) : null
17357
+ }
17358
+ });
17359
+ }
17360
+ });
17361
+ if (limitsList.length === 0) return null;
17362
+ return {
17363
+ version: "1.0.0",
17364
+ limitsByInstantaneoustPowerType: [
17365
+ {
17366
+ telemetryType: "consumption",
17367
+ itemsByDeviceType: [
17368
+ {
17369
+ deviceType,
17370
+ // Gera um nome descritivo interno
17371
+ name: `deviceMapInstaneousPower${this.formatDeviceTypeName(deviceType)}`,
17372
+ description: "Override manual configurado via Dashboard",
17373
+ limitsByDeviceStatus: limitsList
17374
+ }
17375
+ ]
17376
+ }
17377
+ ]
17378
+ };
17379
+ }
17380
+ /**
17381
+ * Helper para formatar o nome do tipo (PascalCase) para uso no campo "name" do JSON
17382
+ */
17383
+ formatDeviceTypeName(deviceType) {
17384
+ if (!deviceType) return "";
17385
+ return deviceType.charAt(0).toUpperCase() + deviceType.slice(1).toLowerCase();
17386
+ }
17274
17387
  /**
17275
17388
  * RFC-0086: Build mapInstantaneousPower JSON structure from form data
17276
17389
  * IMPORTANT: When saving to a DEVICE, only include entries for the specific deviceType
@@ -17327,25 +17440,6 @@ var DefaultSettingsPersister = class {
17327
17440
  console.log(`[SettingsPersister] RFC-0086: Built mapInstantaneousPower for deviceType=${effectiveDeviceType}:`, result);
17328
17441
  return result;
17329
17442
  }
17330
- /**
17331
- * Format device type name for display (e.g., ELEVADOR -> Elevador)
17332
- */
17333
- formatDeviceTypeName(deviceType) {
17334
- const map = {
17335
- "ELEVADOR": "Elevator",
17336
- "ESCADA_ROLANTE": "Escalator",
17337
- "MOTOR": "Motor",
17338
- "BOMBA": "Pump",
17339
- "3F_MEDIDOR": "3FMedidor",
17340
- "CHILLER": "Chiller",
17341
- "FANCOIL": "Fancoil",
17342
- "AR_CONDICIONADO": "AirConditioner",
17343
- "HVAC": "HVAC",
17344
- "HIDROMETRO": "Hidrometro",
17345
- "TERMOSTATO": "Termostato"
17346
- };
17347
- return map[deviceType] || deviceType;
17348
- }
17349
17443
  sanitizeLabel(label) {
17350
17444
  return label.trim().slice(0, 255).replace(/[\x00-\x1F\x7F]/g, "");
17351
17445
  }
@@ -17482,18 +17576,16 @@ var DefaultSettingsFetcher = class {
17482
17576
  }
17483
17577
  const attributesArray = await response.json();
17484
17578
  const attributes = {};
17485
- const settingsNamespace = "myio.settings.energy.";
17486
17579
  for (const attr of attributesArray) {
17487
17580
  if (attr.key && attr.value !== void 0 && attr.value !== null && attr.value !== "") {
17488
- if (attr.key.startsWith(settingsNamespace)) {
17489
- const key = attr.key.replace(settingsNamespace, "");
17490
- if (key !== "__version") {
17491
- attributes[key] = attr.value;
17492
- }
17493
- } else if (attr.key === "floor") {
17581
+ if (attr.key === "floor") {
17494
17582
  attributes.floor = attr.value;
17495
17583
  } else if (attr.key === "identifier") {
17496
17584
  attributes.identifier = attr.value;
17585
+ } else if (attr.key === "mapInstantaneousPower") {
17586
+ attributes.mapInstantaneousPower = attr.value;
17587
+ } else if (attr.key === "deviceMapInstaneousPower") {
17588
+ attributes.deviceMapInstaneousPower = attr.value;
17497
17589
  }
17498
17590
  }
17499
17591
  }
@@ -17515,23 +17607,12 @@ var DefaultSettingsFetcher = class {
17515
17607
  }
17516
17608
  return merged;
17517
17609
  }
17518
- /**
17519
- * Utility method to validate and sanitize fetched data
17520
- */
17521
17610
  static sanitizeFetchedData(data) {
17522
17611
  const sanitized = {};
17523
17612
  const stringFields = [
17524
17613
  "label",
17525
17614
  "floor",
17526
- "identifier",
17527
- "alertLimitDownConsumption",
17528
- "alertLimitUpConsumption",
17529
- "failureLimitDownConsumption",
17530
- "failureLimitUpConsumption",
17531
- "normalLimitDownConsumption",
17532
- "normalLimitUpConsumption",
17533
- "standbyLimitDownConsumption",
17534
- "standbyLimitUpConsumption"
17615
+ "identifier"
17535
17616
  ];
17536
17617
  for (const field of stringFields) {
17537
17618
  if (data[field] && typeof data[field] === "string") {
@@ -17547,6 +17628,12 @@ var DefaultSettingsFetcher = class {
17547
17628
  }
17548
17629
  }
17549
17630
  }
17631
+ const objectFields = ["mapInstantaneousPower", "deviceMapInstaneousPower"];
17632
+ for (const field of objectFields) {
17633
+ if (data[field] && typeof data[field] === "object") {
17634
+ sanitized[field] = data[field];
17635
+ }
17636
+ }
17550
17637
  return sanitized;
17551
17638
  }
17552
17639
  };
@@ -17596,8 +17683,9 @@ var SettingsController = class {
17596
17683
  // Pass connection info for display
17597
17684
  onSave: this.handleSave.bind(this),
17598
17685
  onClose: this.handleClose.bind(this),
17599
- mapInstantaneousPower: params.mapInstantaneousPower
17600
- // RFC-0077: Pass instantaneous power map for Power Limits feature
17686
+ mapInstantaneousPower: params.mapInstantaneousPower,
17687
+ // RFC-0077: Pass instantaneous power map for Power Limits feature,
17688
+ deviceMapInstaneousPower: params.deviceMapInstaneousPower
17601
17689
  });
17602
17690
  }
17603
17691
  async show() {
package/dist/index.d.cts CHANGED
@@ -1634,6 +1634,7 @@ interface OpenDashboardPopupSettingsParams {
1634
1634
  customerName?: string;
1635
1635
  customerId?: string;
1636
1636
  mapInstantaneousPower?: object;
1637
+ deviceMapInstaneousPower?: object;
1637
1638
  connectionData?: {
1638
1639
  centralName?: string;
1639
1640
  connectionStatusTime?: string;
package/dist/index.js CHANGED
@@ -15295,7 +15295,13 @@ var SettingsModalView = class {
15295
15295
  render(initialData) {
15296
15296
  this.originalActiveElement = document.activeElement;
15297
15297
  document.body.appendChild(this.container);
15298
- this.populateForm(initialData);
15298
+ let formData = { ...initialData };
15299
+ if (initialData.deviceMapInstaneousPower && typeof initialData.deviceMapInstaneousPower === "object") {
15300
+ console.log("[SettingsModalView] Configura\xE7\xE3o salva encontrada (Device Scope). Processando...");
15301
+ const flatLimits = this.parseDeviceSavedLimits(initialData.deviceMapInstaneousPower);
15302
+ formData = { ...formData, ...flatLimits };
15303
+ }
15304
+ this.populateForm(formData);
15299
15305
  this.attachEventListeners();
15300
15306
  this.setupAccessibility();
15301
15307
  this.setupFocusTrap();
@@ -16864,6 +16870,42 @@ var SettingsModalView = class {
16864
16870
  }
16865
16871
  }
16866
16872
  }
16873
+ /**
16874
+ * Helper: Traduz o JSON RFC-0086 (deviceMapInstaneousPower)
16875
+ * para os campos planos do formulário (ex: standbyLimitUpConsumption)
16876
+ */
16877
+ parseDeviceSavedLimits(deviceJson) {
16878
+ const extracted = {};
16879
+ try {
16880
+ if (!deviceJson || !deviceJson.limitsByInstantaneoustPowerType) return extracted;
16881
+ const consumptionGroup = deviceJson.limitsByInstantaneoustPowerType.find(
16882
+ (g) => g.telemetryType === "consumption"
16883
+ );
16884
+ const deviceItem = consumptionGroup?.itemsByDeviceType?.[0];
16885
+ if (!deviceItem?.limitsByDeviceStatus) return extracted;
16886
+ const mapPrefix = {
16887
+ "standBy": "standby",
16888
+ "normal": "normal",
16889
+ "alert": "alert",
16890
+ "failure": "failure"
16891
+ };
16892
+ deviceItem.limitsByDeviceStatus.forEach((status) => {
16893
+ const prefix = mapPrefix[status.deviceStatusName];
16894
+ if (prefix && status.limitsValues) {
16895
+ const { baseValue, topValue } = status.limitsValues;
16896
+ if (baseValue !== null && baseValue !== void 0) {
16897
+ extracted[`${prefix}LimitDownConsumption`] = baseValue;
16898
+ }
16899
+ if (topValue !== null && topValue !== void 0) {
16900
+ extracted[`${prefix}LimitUpConsumption`] = topValue;
16901
+ }
16902
+ }
16903
+ });
16904
+ } catch (e) {
16905
+ console.warn("[SettingsModalView] Erro ao processar deviceMapInstaneousPower:", e);
16906
+ }
16907
+ return extracted;
16908
+ }
16867
16909
  attachEventListeners() {
16868
16910
  this.form.addEventListener("submit", (event) => {
16869
16911
  event.preventDefault();
@@ -17135,11 +17177,25 @@ var DefaultSettingsPersister = class {
17135
17177
  }
17136
17178
  async saveServerScopeAttributes(deviceId, attributes) {
17137
17179
  try {
17138
- const mapInstantaneousPower = this.buildMapInstantaneousPower(attributes);
17139
- const payload = {
17140
- mapInstantaneousPower
17141
- };
17142
- console.log("[SettingsPersister] RFC-0080: Saving mapInstantaneousPower as JSON:", payload);
17180
+ const payload = { ...attributes };
17181
+ const effectiveDeviceType = this.getEffectiveDeviceType();
17182
+ const deviceJson = this.buildDevicePowerJson(payload, effectiveDeviceType);
17183
+ if (deviceJson) {
17184
+ payload.deviceMapInstaneousPower = deviceJson;
17185
+ }
17186
+ const flatKeysToRemove = [
17187
+ "telemetryType",
17188
+ "standbyLimitDownConsumption",
17189
+ "standbyLimitUpConsumption",
17190
+ "normalLimitDownConsumption",
17191
+ "normalLimitUpConsumption",
17192
+ "alertLimitDownConsumption",
17193
+ "alertLimitUpConsumption",
17194
+ "failureLimitDownConsumption",
17195
+ "failureLimitUpConsumption"
17196
+ ];
17197
+ flatKeysToRemove.forEach((key) => delete payload[key]);
17198
+ console.log("[SettingsPersister] Saving Server Scope Attributes:", payload);
17143
17199
  const res = await fetch(
17144
17200
  `${this.tbBaseUrl}/api/plugins/telemetry/DEVICE/${deviceId}/attributes/SERVER_SCOPE`,
17145
17201
  {
@@ -17156,13 +17212,70 @@ var DefaultSettingsPersister = class {
17156
17212
  }
17157
17213
  return {
17158
17214
  ok: true,
17159
- updatedKeys: ["mapInstantaneousPower"]
17215
+ updatedKeys: Object.keys(payload)
17160
17216
  };
17161
17217
  } catch (error) {
17162
17218
  console.error("[SettingsPersister] Attributes save failed:", error);
17163
17219
  return { ok: false, error: this.mapError(error) };
17164
17220
  }
17165
17221
  }
17222
+ /**
17223
+ * Constrói o JSON Reduzido (apenas o deviceType atual) para salvar no Device.
17224
+ * Retorna null se nenhum campo de potência estiver presente.
17225
+ */
17226
+ buildDevicePowerJson(formData, deviceType) {
17227
+ const statuses = ["standby", "normal", "alert", "failure"];
17228
+ const hasPowerData = statuses.some(
17229
+ (status) => formData[`${status}LimitDownConsumption`] !== void 0 && formData[`${status}LimitDownConsumption`] !== "" || formData[`${status}LimitUpConsumption`] !== void 0 && formData[`${status}LimitUpConsumption`] !== ""
17230
+ );
17231
+ if (!hasPowerData) return null;
17232
+ const statusMap = {
17233
+ "standby": "standBy",
17234
+ "normal": "normal",
17235
+ "alert": "alert",
17236
+ "failure": "failure"
17237
+ };
17238
+ const limitsList = [];
17239
+ statuses.forEach((statusKey) => {
17240
+ const down = formData[`${statusKey}LimitDownConsumption`];
17241
+ const up = formData[`${statusKey}LimitUpConsumption`];
17242
+ if (down !== void 0 && down !== "" || up !== void 0 && up !== "") {
17243
+ limitsList.push({
17244
+ deviceStatusName: statusMap[statusKey],
17245
+ limitsValues: {
17246
+ // Converte para Number ou null
17247
+ baseValue: down !== "" && down !== void 0 ? Number(down) : null,
17248
+ topValue: up !== "" && up !== void 0 ? Number(up) : null
17249
+ }
17250
+ });
17251
+ }
17252
+ });
17253
+ if (limitsList.length === 0) return null;
17254
+ return {
17255
+ version: "1.0.0",
17256
+ limitsByInstantaneoustPowerType: [
17257
+ {
17258
+ telemetryType: "consumption",
17259
+ itemsByDeviceType: [
17260
+ {
17261
+ deviceType,
17262
+ // Gera um nome descritivo interno
17263
+ name: `deviceMapInstaneousPower${this.formatDeviceTypeName(deviceType)}`,
17264
+ description: "Override manual configurado via Dashboard",
17265
+ limitsByDeviceStatus: limitsList
17266
+ }
17267
+ ]
17268
+ }
17269
+ ]
17270
+ };
17271
+ }
17272
+ /**
17273
+ * Helper para formatar o nome do tipo (PascalCase) para uso no campo "name" do JSON
17274
+ */
17275
+ formatDeviceTypeName(deviceType) {
17276
+ if (!deviceType) return "";
17277
+ return deviceType.charAt(0).toUpperCase() + deviceType.slice(1).toLowerCase();
17278
+ }
17166
17279
  /**
17167
17280
  * RFC-0086: Build mapInstantaneousPower JSON structure from form data
17168
17281
  * IMPORTANT: When saving to a DEVICE, only include entries for the specific deviceType
@@ -17219,25 +17332,6 @@ var DefaultSettingsPersister = class {
17219
17332
  console.log(`[SettingsPersister] RFC-0086: Built mapInstantaneousPower for deviceType=${effectiveDeviceType}:`, result);
17220
17333
  return result;
17221
17334
  }
17222
- /**
17223
- * Format device type name for display (e.g., ELEVADOR -> Elevador)
17224
- */
17225
- formatDeviceTypeName(deviceType) {
17226
- const map = {
17227
- "ELEVADOR": "Elevator",
17228
- "ESCADA_ROLANTE": "Escalator",
17229
- "MOTOR": "Motor",
17230
- "BOMBA": "Pump",
17231
- "3F_MEDIDOR": "3FMedidor",
17232
- "CHILLER": "Chiller",
17233
- "FANCOIL": "Fancoil",
17234
- "AR_CONDICIONADO": "AirConditioner",
17235
- "HVAC": "HVAC",
17236
- "HIDROMETRO": "Hidrometro",
17237
- "TERMOSTATO": "Termostato"
17238
- };
17239
- return map[deviceType] || deviceType;
17240
- }
17241
17335
  sanitizeLabel(label) {
17242
17336
  return label.trim().slice(0, 255).replace(/[\x00-\x1F\x7F]/g, "");
17243
17337
  }
@@ -17374,18 +17468,16 @@ var DefaultSettingsFetcher = class {
17374
17468
  }
17375
17469
  const attributesArray = await response.json();
17376
17470
  const attributes = {};
17377
- const settingsNamespace = "myio.settings.energy.";
17378
17471
  for (const attr of attributesArray) {
17379
17472
  if (attr.key && attr.value !== void 0 && attr.value !== null && attr.value !== "") {
17380
- if (attr.key.startsWith(settingsNamespace)) {
17381
- const key = attr.key.replace(settingsNamespace, "");
17382
- if (key !== "__version") {
17383
- attributes[key] = attr.value;
17384
- }
17385
- } else if (attr.key === "floor") {
17473
+ if (attr.key === "floor") {
17386
17474
  attributes.floor = attr.value;
17387
17475
  } else if (attr.key === "identifier") {
17388
17476
  attributes.identifier = attr.value;
17477
+ } else if (attr.key === "mapInstantaneousPower") {
17478
+ attributes.mapInstantaneousPower = attr.value;
17479
+ } else if (attr.key === "deviceMapInstaneousPower") {
17480
+ attributes.deviceMapInstaneousPower = attr.value;
17389
17481
  }
17390
17482
  }
17391
17483
  }
@@ -17407,23 +17499,12 @@ var DefaultSettingsFetcher = class {
17407
17499
  }
17408
17500
  return merged;
17409
17501
  }
17410
- /**
17411
- * Utility method to validate and sanitize fetched data
17412
- */
17413
17502
  static sanitizeFetchedData(data) {
17414
17503
  const sanitized = {};
17415
17504
  const stringFields = [
17416
17505
  "label",
17417
17506
  "floor",
17418
- "identifier",
17419
- "alertLimitDownConsumption",
17420
- "alertLimitUpConsumption",
17421
- "failureLimitDownConsumption",
17422
- "failureLimitUpConsumption",
17423
- "normalLimitDownConsumption",
17424
- "normalLimitUpConsumption",
17425
- "standbyLimitDownConsumption",
17426
- "standbyLimitUpConsumption"
17507
+ "identifier"
17427
17508
  ];
17428
17509
  for (const field of stringFields) {
17429
17510
  if (data[field] && typeof data[field] === "string") {
@@ -17439,6 +17520,12 @@ var DefaultSettingsFetcher = class {
17439
17520
  }
17440
17521
  }
17441
17522
  }
17523
+ const objectFields = ["mapInstantaneousPower", "deviceMapInstaneousPower"];
17524
+ for (const field of objectFields) {
17525
+ if (data[field] && typeof data[field] === "object") {
17526
+ sanitized[field] = data[field];
17527
+ }
17528
+ }
17442
17529
  return sanitized;
17443
17530
  }
17444
17531
  };
@@ -17488,8 +17575,9 @@ var SettingsController = class {
17488
17575
  // Pass connection info for display
17489
17576
  onSave: this.handleSave.bind(this),
17490
17577
  onClose: this.handleClose.bind(this),
17491
- mapInstantaneousPower: params.mapInstantaneousPower
17492
- // RFC-0077: Pass instantaneous power map for Power Limits feature
17578
+ mapInstantaneousPower: params.mapInstantaneousPower,
17579
+ // RFC-0077: Pass instantaneous power map for Power Limits feature,
17580
+ deviceMapInstaneousPower: params.deviceMapInstaneousPower
17493
17581
  });
17494
17582
  }
17495
17583
  async show() {