myio-js-library 0.1.143 → 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
@@ -4811,6 +4811,12 @@ function normalizeParams(params) {
4811
4811
  function getIconSvg(deviceType) {
4812
4812
  return ICON_MAP[deviceType] || ICON_MAP.DEFAULT;
4813
4813
  }
4814
+ function formatValueByDomain(value, domain) {
4815
+ if (domain === "water") {
4816
+ return formatWaterVolumeM3(value);
4817
+ }
4818
+ return formatEnergy(value);
4819
+ }
4814
4820
  function formatUpdateDate(timeVal) {
4815
4821
  let telemetryTimeFormatted = "N/A";
4816
4822
  let timeSinceLastTelemetry = "";
@@ -5059,7 +5065,7 @@ function paint(root, state) {
5059
5065
  const chip = root.querySelector(".chip");
5060
5066
  chip.className = `chip ${statusInfo.chipClass}`;
5061
5067
  chip.textContent = statusInfo.label;
5062
- const primaryValue = formatEnergy(entityObject.val);
5068
+ const primaryValue = formatValueByDomain(entityObject.val, entityObject.domain);
5063
5069
  const numSpan = root.querySelector(".myio-ho-card__value .num");
5064
5070
  const unitSpan = root.querySelector(".myio-ho-card__value .unit");
5065
5071
  numSpan.textContent = primaryValue;
@@ -15397,7 +15403,13 @@ var SettingsModalView = class {
15397
15403
  render(initialData) {
15398
15404
  this.originalActiveElement = document.activeElement;
15399
15405
  document.body.appendChild(this.container);
15400
- 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);
15401
15413
  this.attachEventListeners();
15402
15414
  this.setupAccessibility();
15403
15415
  this.setupFocusTrap();
@@ -16966,6 +16978,42 @@ var SettingsModalView = class {
16966
16978
  }
16967
16979
  }
16968
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
+ }
16969
17017
  attachEventListeners() {
16970
17018
  this.form.addEventListener("submit", (event) => {
16971
17019
  event.preventDefault();
@@ -17237,11 +17285,25 @@ var DefaultSettingsPersister = class {
17237
17285
  }
17238
17286
  async saveServerScopeAttributes(deviceId, attributes) {
17239
17287
  try {
17240
- const mapInstantaneousPower = this.buildMapInstantaneousPower(attributes);
17241
- const payload = {
17242
- mapInstantaneousPower
17243
- };
17244
- 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);
17245
17307
  const res = await fetch(
17246
17308
  `${this.tbBaseUrl}/api/plugins/telemetry/DEVICE/${deviceId}/attributes/SERVER_SCOPE`,
17247
17309
  {
@@ -17258,13 +17320,70 @@ var DefaultSettingsPersister = class {
17258
17320
  }
17259
17321
  return {
17260
17322
  ok: true,
17261
- updatedKeys: ["mapInstantaneousPower"]
17323
+ updatedKeys: Object.keys(payload)
17262
17324
  };
17263
17325
  } catch (error) {
17264
17326
  console.error("[SettingsPersister] Attributes save failed:", error);
17265
17327
  return { ok: false, error: this.mapError(error) };
17266
17328
  }
17267
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
+ }
17268
17387
  /**
17269
17388
  * RFC-0086: Build mapInstantaneousPower JSON structure from form data
17270
17389
  * IMPORTANT: When saving to a DEVICE, only include entries for the specific deviceType
@@ -17321,25 +17440,6 @@ var DefaultSettingsPersister = class {
17321
17440
  console.log(`[SettingsPersister] RFC-0086: Built mapInstantaneousPower for deviceType=${effectiveDeviceType}:`, result);
17322
17441
  return result;
17323
17442
  }
17324
- /**
17325
- * Format device type name for display (e.g., ELEVADOR -> Elevador)
17326
- */
17327
- formatDeviceTypeName(deviceType) {
17328
- const map = {
17329
- "ELEVADOR": "Elevator",
17330
- "ESCADA_ROLANTE": "Escalator",
17331
- "MOTOR": "Motor",
17332
- "BOMBA": "Pump",
17333
- "3F_MEDIDOR": "3FMedidor",
17334
- "CHILLER": "Chiller",
17335
- "FANCOIL": "Fancoil",
17336
- "AR_CONDICIONADO": "AirConditioner",
17337
- "HVAC": "HVAC",
17338
- "HIDROMETRO": "Hidrometro",
17339
- "TERMOSTATO": "Termostato"
17340
- };
17341
- return map[deviceType] || deviceType;
17342
- }
17343
17443
  sanitizeLabel(label) {
17344
17444
  return label.trim().slice(0, 255).replace(/[\x00-\x1F\x7F]/g, "");
17345
17445
  }
@@ -17476,18 +17576,16 @@ var DefaultSettingsFetcher = class {
17476
17576
  }
17477
17577
  const attributesArray = await response.json();
17478
17578
  const attributes = {};
17479
- const settingsNamespace = "myio.settings.energy.";
17480
17579
  for (const attr of attributesArray) {
17481
17580
  if (attr.key && attr.value !== void 0 && attr.value !== null && attr.value !== "") {
17482
- if (attr.key.startsWith(settingsNamespace)) {
17483
- const key = attr.key.replace(settingsNamespace, "");
17484
- if (key !== "__version") {
17485
- attributes[key] = attr.value;
17486
- }
17487
- } else if (attr.key === "floor") {
17581
+ if (attr.key === "floor") {
17488
17582
  attributes.floor = attr.value;
17489
17583
  } else if (attr.key === "identifier") {
17490
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;
17491
17589
  }
17492
17590
  }
17493
17591
  }
@@ -17509,23 +17607,12 @@ var DefaultSettingsFetcher = class {
17509
17607
  }
17510
17608
  return merged;
17511
17609
  }
17512
- /**
17513
- * Utility method to validate and sanitize fetched data
17514
- */
17515
17610
  static sanitizeFetchedData(data) {
17516
17611
  const sanitized = {};
17517
17612
  const stringFields = [
17518
17613
  "label",
17519
17614
  "floor",
17520
- "identifier",
17521
- "alertLimitDownConsumption",
17522
- "alertLimitUpConsumption",
17523
- "failureLimitDownConsumption",
17524
- "failureLimitUpConsumption",
17525
- "normalLimitDownConsumption",
17526
- "normalLimitUpConsumption",
17527
- "standbyLimitDownConsumption",
17528
- "standbyLimitUpConsumption"
17615
+ "identifier"
17529
17616
  ];
17530
17617
  for (const field of stringFields) {
17531
17618
  if (data[field] && typeof data[field] === "string") {
@@ -17541,6 +17628,12 @@ var DefaultSettingsFetcher = class {
17541
17628
  }
17542
17629
  }
17543
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
+ }
17544
17637
  return sanitized;
17545
17638
  }
17546
17639
  };
@@ -17590,8 +17683,9 @@ var SettingsController = class {
17590
17683
  // Pass connection info for display
17591
17684
  onSave: this.handleSave.bind(this),
17592
17685
  onClose: this.handleClose.bind(this),
17593
- mapInstantaneousPower: params.mapInstantaneousPower
17594
- // 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
17595
17689
  });
17596
17690
  }
17597
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
@@ -4703,6 +4703,12 @@ function normalizeParams(params) {
4703
4703
  function getIconSvg(deviceType) {
4704
4704
  return ICON_MAP[deviceType] || ICON_MAP.DEFAULT;
4705
4705
  }
4706
+ function formatValueByDomain(value, domain) {
4707
+ if (domain === "water") {
4708
+ return formatWaterVolumeM3(value);
4709
+ }
4710
+ return formatEnergy(value);
4711
+ }
4706
4712
  function formatUpdateDate(timeVal) {
4707
4713
  let telemetryTimeFormatted = "N/A";
4708
4714
  let timeSinceLastTelemetry = "";
@@ -4951,7 +4957,7 @@ function paint(root, state) {
4951
4957
  const chip = root.querySelector(".chip");
4952
4958
  chip.className = `chip ${statusInfo.chipClass}`;
4953
4959
  chip.textContent = statusInfo.label;
4954
- const primaryValue = formatEnergy(entityObject.val);
4960
+ const primaryValue = formatValueByDomain(entityObject.val, entityObject.domain);
4955
4961
  const numSpan = root.querySelector(".myio-ho-card__value .num");
4956
4962
  const unitSpan = root.querySelector(".myio-ho-card__value .unit");
4957
4963
  numSpan.textContent = primaryValue;
@@ -15289,7 +15295,13 @@ var SettingsModalView = class {
15289
15295
  render(initialData) {
15290
15296
  this.originalActiveElement = document.activeElement;
15291
15297
  document.body.appendChild(this.container);
15292
- 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);
15293
15305
  this.attachEventListeners();
15294
15306
  this.setupAccessibility();
15295
15307
  this.setupFocusTrap();
@@ -16858,6 +16870,42 @@ var SettingsModalView = class {
16858
16870
  }
16859
16871
  }
16860
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
+ }
16861
16909
  attachEventListeners() {
16862
16910
  this.form.addEventListener("submit", (event) => {
16863
16911
  event.preventDefault();
@@ -17129,11 +17177,25 @@ var DefaultSettingsPersister = class {
17129
17177
  }
17130
17178
  async saveServerScopeAttributes(deviceId, attributes) {
17131
17179
  try {
17132
- const mapInstantaneousPower = this.buildMapInstantaneousPower(attributes);
17133
- const payload = {
17134
- mapInstantaneousPower
17135
- };
17136
- 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);
17137
17199
  const res = await fetch(
17138
17200
  `${this.tbBaseUrl}/api/plugins/telemetry/DEVICE/${deviceId}/attributes/SERVER_SCOPE`,
17139
17201
  {
@@ -17150,13 +17212,70 @@ var DefaultSettingsPersister = class {
17150
17212
  }
17151
17213
  return {
17152
17214
  ok: true,
17153
- updatedKeys: ["mapInstantaneousPower"]
17215
+ updatedKeys: Object.keys(payload)
17154
17216
  };
17155
17217
  } catch (error) {
17156
17218
  console.error("[SettingsPersister] Attributes save failed:", error);
17157
17219
  return { ok: false, error: this.mapError(error) };
17158
17220
  }
17159
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
+ }
17160
17279
  /**
17161
17280
  * RFC-0086: Build mapInstantaneousPower JSON structure from form data
17162
17281
  * IMPORTANT: When saving to a DEVICE, only include entries for the specific deviceType
@@ -17213,25 +17332,6 @@ var DefaultSettingsPersister = class {
17213
17332
  console.log(`[SettingsPersister] RFC-0086: Built mapInstantaneousPower for deviceType=${effectiveDeviceType}:`, result);
17214
17333
  return result;
17215
17334
  }
17216
- /**
17217
- * Format device type name for display (e.g., ELEVADOR -> Elevador)
17218
- */
17219
- formatDeviceTypeName(deviceType) {
17220
- const map = {
17221
- "ELEVADOR": "Elevator",
17222
- "ESCADA_ROLANTE": "Escalator",
17223
- "MOTOR": "Motor",
17224
- "BOMBA": "Pump",
17225
- "3F_MEDIDOR": "3FMedidor",
17226
- "CHILLER": "Chiller",
17227
- "FANCOIL": "Fancoil",
17228
- "AR_CONDICIONADO": "AirConditioner",
17229
- "HVAC": "HVAC",
17230
- "HIDROMETRO": "Hidrometro",
17231
- "TERMOSTATO": "Termostato"
17232
- };
17233
- return map[deviceType] || deviceType;
17234
- }
17235
17335
  sanitizeLabel(label) {
17236
17336
  return label.trim().slice(0, 255).replace(/[\x00-\x1F\x7F]/g, "");
17237
17337
  }
@@ -17368,18 +17468,16 @@ var DefaultSettingsFetcher = class {
17368
17468
  }
17369
17469
  const attributesArray = await response.json();
17370
17470
  const attributes = {};
17371
- const settingsNamespace = "myio.settings.energy.";
17372
17471
  for (const attr of attributesArray) {
17373
17472
  if (attr.key && attr.value !== void 0 && attr.value !== null && attr.value !== "") {
17374
- if (attr.key.startsWith(settingsNamespace)) {
17375
- const key = attr.key.replace(settingsNamespace, "");
17376
- if (key !== "__version") {
17377
- attributes[key] = attr.value;
17378
- }
17379
- } else if (attr.key === "floor") {
17473
+ if (attr.key === "floor") {
17380
17474
  attributes.floor = attr.value;
17381
17475
  } else if (attr.key === "identifier") {
17382
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;
17383
17481
  }
17384
17482
  }
17385
17483
  }
@@ -17401,23 +17499,12 @@ var DefaultSettingsFetcher = class {
17401
17499
  }
17402
17500
  return merged;
17403
17501
  }
17404
- /**
17405
- * Utility method to validate and sanitize fetched data
17406
- */
17407
17502
  static sanitizeFetchedData(data) {
17408
17503
  const sanitized = {};
17409
17504
  const stringFields = [
17410
17505
  "label",
17411
17506
  "floor",
17412
- "identifier",
17413
- "alertLimitDownConsumption",
17414
- "alertLimitUpConsumption",
17415
- "failureLimitDownConsumption",
17416
- "failureLimitUpConsumption",
17417
- "normalLimitDownConsumption",
17418
- "normalLimitUpConsumption",
17419
- "standbyLimitDownConsumption",
17420
- "standbyLimitUpConsumption"
17507
+ "identifier"
17421
17508
  ];
17422
17509
  for (const field of stringFields) {
17423
17510
  if (data[field] && typeof data[field] === "string") {
@@ -17433,6 +17520,12 @@ var DefaultSettingsFetcher = class {
17433
17520
  }
17434
17521
  }
17435
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
+ }
17436
17529
  return sanitized;
17437
17530
  }
17438
17531
  };
@@ -17482,8 +17575,9 @@ var SettingsController = class {
17482
17575
  // Pass connection info for display
17483
17576
  onSave: this.handleSave.bind(this),
17484
17577
  onClose: this.handleClose.bind(this),
17485
- mapInstantaneousPower: params.mapInstantaneousPower
17486
- // 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
17487
17581
  });
17488
17582
  }
17489
17583
  async show() {