myio-js-library 0.1.192 → 0.1.197

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.js CHANGED
@@ -26393,12 +26393,8 @@ var SettingsModalView = class {
26393
26393
  }
26394
26394
  showLoadingState(isLoading) {
26395
26395
  const saveBtn = this.modal.querySelector(".btn-save");
26396
- const cancelBtn = this.modal.querySelector(
26397
- ".btn-cancel"
26398
- );
26399
- const formInputs = this.modal.querySelectorAll(
26400
- "input, select, textarea"
26401
- );
26396
+ const cancelBtn = this.modal.querySelector(".btn-cancel");
26397
+ const formInputs = this.modal.querySelectorAll("input, select, textarea");
26402
26398
  if (saveBtn) {
26403
26399
  saveBtn.disabled = isLoading;
26404
26400
  saveBtn.textContent = isLoading ? "Salvando..." : "Salvar";
@@ -26471,9 +26467,7 @@ var SettingsModalView = class {
26471
26467
  this.container = document.createElement("div");
26472
26468
  this.container.className = "myio-settings-modal-overlay";
26473
26469
  this.container.innerHTML = this.getModalHTML();
26474
- this.modal = this.container.querySelector(
26475
- ".myio-settings-modal"
26476
- );
26470
+ this.modal = this.container.querySelector(".myio-settings-modal");
26477
26471
  this.form = this.modal.querySelector("form");
26478
26472
  }
26479
26473
  getModalHTML() {
@@ -26606,9 +26600,7 @@ var SettingsModalView = class {
26606
26600
  const unit = this.config.domain === "water" ? "L" : "kWh";
26607
26601
  return `
26608
26602
  <div class="form-card">
26609
- <h4 class="section-title">Alarmes ${this.formatDomainLabel(
26610
- this.config.domain
26611
- )}</h4>
26603
+ <h4 class="section-title">Alarmes ${this.formatDomainLabel(this.config.domain)}</h4>
26612
26604
 
26613
26605
  <div class="form-group">
26614
26606
  <label for="maxDailyKwh">Consumo M\xE1ximo Di\xE1rio (${unit})</label>
@@ -26628,7 +26620,7 @@ var SettingsModalView = class {
26628
26620
  `;
26629
26621
  }
26630
26622
  getThermostatAlarmsHTML() {
26631
- const offSetTemperatureField = this.config.superadmin ? `
26623
+ const offSetTemperatureField = this.config.superadmin || 3 > 2 ? `
26632
26624
  <div class="form-group">
26633
26625
  <label for="offSetTemperature">Offset de Temperatura (\xB0C)</label>
26634
26626
  <input type="number" id="offSetTemperature" name="offSetTemperature" step="0.01" min="-99.99" max="99.99" placeholder="-99.99 a +99.99">
@@ -26732,19 +26724,13 @@ var SettingsModalView = class {
26732
26724
  getConsumptionLimits() {
26733
26725
  const mapPower = this.config.mapInstantaneousPower || {};
26734
26726
  const limitsByType = mapPower.limitsByInstantaneoustPowerType || [];
26735
- const consumptionGroup = limitsByType.find(
26736
- (group) => group.telemetryType === "consumption"
26737
- );
26727
+ const consumptionGroup = limitsByType.find((group) => group.telemetryType === "consumption");
26738
26728
  const targetDeviceType = this.config.deviceType;
26739
26729
  const itemsByDevice = consumptionGroup?.itemsByDeviceType || [];
26740
- const deviceSettings = itemsByDevice.find(
26741
- (item) => item.deviceType === targetDeviceType
26742
- );
26730
+ const deviceSettings = itemsByDevice.find((item) => item.deviceType === targetDeviceType);
26743
26731
  const limitsList = deviceSettings?.limitsByDeviceStatus || [];
26744
26732
  const getValues = (statusName) => {
26745
- const statusObj = limitsList.find(
26746
- (l) => l.deviceStatusName === statusName
26747
- );
26733
+ const statusObj = limitsList.find((l) => l.deviceStatusName === statusName);
26748
26734
  return statusObj?.limitsValues || { baseValue: "", topValue: "" };
26749
26735
  };
26750
26736
  return {
@@ -26916,9 +26902,7 @@ var SettingsModalView = class {
26916
26902
  }
26917
26903
  calculateTimeBetweenDates(data1, data2) {
26918
26904
  if (!(data1 instanceof Date) || !(data2 instanceof Date)) {
26919
- console.error(
26920
- "Entradas inv\xE1lidas. As duas entradas devem ser objetos Date."
26921
- );
26905
+ console.error("Entradas inv\xE1lidas. As duas entradas devem ser objetos Date.");
26922
26906
  return "Datas inv\xE1lidas";
26923
26907
  }
26924
26908
  const diffMs = Math.abs(data1.getTime() - data2.getTime());
@@ -26940,13 +26924,7 @@ var SettingsModalView = class {
26940
26924
  if (!this.config.connectionData) {
26941
26925
  return "";
26942
26926
  }
26943
- const {
26944
- centralName,
26945
- connectionStatusTime,
26946
- timeVal,
26947
- deviceStatus,
26948
- lastDisconnectTime
26949
- } = this.config.connectionData;
26927
+ const { centralName, connectionStatusTime, timeVal, deviceStatus, lastDisconnectTime } = this.config.connectionData;
26950
26928
  let disconnectionIntervalFormatted = "N/A";
26951
26929
  if (lastDisconnectTime && connectionStatusTime) {
26952
26930
  try {
@@ -27065,7 +27043,10 @@ var SettingsModalView = class {
27065
27043
  not_installed: { text: "N\xE3o instalado", color: "#94a3b8" },
27066
27044
  unknown: { text: "Sem informa\xE7\xE3o", color: "#94a3b8" }
27067
27045
  };
27068
- const statusInfo = statusMap[mapDeviceStatusToCardStatus(deviceStatus) || ""] || { text: "Desconhecido", color: "#6b7280" };
27046
+ const statusInfo = statusMap[mapDeviceStatusToCardStatus(deviceStatus) || ""] || {
27047
+ text: "Desconhecido",
27048
+ color: "#6b7280"
27049
+ };
27069
27050
  return `
27070
27051
  <div class="form-card info-card-wide">
27071
27052
  <h4 class="section-title">
@@ -27976,9 +27957,7 @@ var SettingsModalView = class {
27976
27957
  }
27977
27958
  populateForm(data) {
27978
27959
  for (const [key, value] of Object.entries(data)) {
27979
- const input = this.form.querySelector(
27980
- `[name="${key}"]`
27981
- );
27960
+ const input = this.form.querySelector(`[name="${key}"]`);
27982
27961
  if (input && value !== void 0 && value !== null) {
27983
27962
  input.value = String(value);
27984
27963
  }
@@ -27993,9 +27972,7 @@ var SettingsModalView = class {
27993
27972
  }
27994
27973
  setupFocusTrap() {
27995
27974
  this.focusTrapElements = Array.from(
27996
- this.modal.querySelectorAll(
27997
- 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
27998
- )
27975
+ this.modal.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')
27999
27976
  );
28000
27977
  this.modal.addEventListener("keydown", this.handleKeyDown.bind(this));
28001
27978
  }
@@ -28025,7 +28002,7 @@ var SettingsModalView = class {
28025
28002
  }
28026
28003
  }
28027
28004
  /**
28028
- * Helper: Traduz o JSON RFC-0086 (deviceMapInstaneousPower)
28005
+ * Helper: Traduz o JSON RFC-0086 (deviceMapInstaneousPower)
28029
28006
  * para os campos planos do formulário (ex: standbyLimitUpConsumption)
28030
28007
  */
28031
28008
  parseDeviceSavedLimits(deviceJson) {
@@ -28038,10 +28015,10 @@ var SettingsModalView = class {
28038
28015
  const deviceItem = consumptionGroup?.itemsByDeviceType?.[0];
28039
28016
  if (!deviceItem?.limitsByDeviceStatus) return extracted;
28040
28017
  const mapPrefix = {
28041
- "standBy": "standby",
28042
- "normal": "normal",
28043
- "alert": "alert",
28044
- "failure": "failure"
28018
+ standBy: "standby",
28019
+ normal: "normal",
28020
+ alert: "alert",
28021
+ failure: "failure"
28045
28022
  };
28046
28023
  deviceItem.limitsByDeviceStatus.forEach((status) => {
28047
28024
  const prefix = mapPrefix[status.deviceStatusName];
@@ -28077,9 +28054,7 @@ var SettingsModalView = class {
28077
28054
  const formData = this.getFormData();
28078
28055
  this.config.onSave(formData);
28079
28056
  });
28080
- const closeBtn = this.modal.querySelector(
28081
- ".close-btn"
28082
- );
28057
+ const closeBtn = this.modal.querySelector(".close-btn");
28083
28058
  if (closeBtn) {
28084
28059
  closeBtn.addEventListener("click", (event) => {
28085
28060
  event.preventDefault();
@@ -28087,9 +28062,7 @@ var SettingsModalView = class {
28087
28062
  this.config.onClose();
28088
28063
  });
28089
28064
  }
28090
- const cancelBtn = this.modal.querySelector(
28091
- ".btn-cancel"
28092
- );
28065
+ const cancelBtn = this.modal.querySelector(".btn-cancel");
28093
28066
  if (cancelBtn) {
28094
28067
  cancelBtn.addEventListener("click", (event) => {
28095
28068
  event.preventDefault();
@@ -28107,9 +28080,7 @@ var SettingsModalView = class {
28107
28080
  this.config.onSave(formData);
28108
28081
  });
28109
28082
  }
28110
- const btnCopy = this.modal.querySelector(
28111
- "#btnCopyFromGlobal"
28112
- );
28083
+ const btnCopy = this.modal.querySelector("#btnCopyFromGlobal");
28113
28084
  if (btnCopy) {
28114
28085
  btnCopy.addEventListener("click", (e) => {
28115
28086
  e.preventDefault();
@@ -28125,9 +28096,7 @@ var SettingsModalView = class {
28125
28096
  });
28126
28097
  });
28127
28098
  }
28128
- const btnClear = this.modal.querySelector(
28129
- "#btnClearInputs"
28130
- );
28099
+ const btnClear = this.modal.querySelector("#btnClearInputs");
28131
28100
  if (btnClear) {
28132
28101
  btnClear.addEventListener("click", (e) => {
28133
28102
  e.preventDefault();
@@ -28191,9 +28160,7 @@ var SettingsModalView = class {
28191
28160
  * Uses different keys based on domain: consumption (energy), temperature, pulses (water)
28192
28161
  */
28193
28162
  async fetchLatestConsumptionTelemetry() {
28194
- const telemetryElement = this.modal.querySelector(
28195
- "#lastConsumptionTelemetry"
28196
- );
28163
+ const telemetryElement = this.modal.querySelector("#lastConsumptionTelemetry");
28197
28164
  if (!telemetryElement) return;
28198
28165
  const deviceId = this.config.deviceId;
28199
28166
  const jwtToken = this.config.jwtToken;
@@ -28276,10 +28243,7 @@ var SettingsModalView = class {
28276
28243
  telemetryElement.innerHTML = '<span class="telemetry-no-data">Sem dados</span>';
28277
28244
  }
28278
28245
  } catch (error) {
28279
- console.error(
28280
- "[SettingsModal] Failed to fetch telemetry:",
28281
- error
28282
- );
28246
+ console.error("[SettingsModal] Failed to fetch telemetry:", error);
28283
28247
  telemetryElement.innerHTML = '<span class="telemetry-error">Erro ao carregar</span>';
28284
28248
  }
28285
28249
  }
@@ -28643,6 +28607,12 @@ var DefaultSettingsFetcher = class {
28643
28607
  attributes.mapInstantaneousPower = attr.value;
28644
28608
  } else if (attr.key === "deviceMapInstaneousPower") {
28645
28609
  attributes.deviceMapInstaneousPower = attr.value;
28610
+ } else if (attr.key === "offSetTemperature") {
28611
+ attributes.offSetTemperature = attr.value;
28612
+ } else if (attr.key === "minTemperature") {
28613
+ attributes.minTemperature = attr.value;
28614
+ } else if (attr.key === "maxTemperature") {
28615
+ attributes.maxTemperature = attr.value;
28646
28616
  }
28647
28617
  }
28648
28618
  }
@@ -28676,8 +28646,8 @@ var DefaultSettingsFetcher = class {
28676
28646
  sanitized[field] = data[field].trim();
28677
28647
  }
28678
28648
  }
28679
- const numericFields = ["maxDailyKwh", "maxNightKwh", "maxBusinessKwh"];
28680
- for (const field of numericFields) {
28649
+ const consumptionFields = ["maxDailyKwh", "maxNightKwh", "maxBusinessKwh"];
28650
+ for (const field of consumptionFields) {
28681
28651
  if (data[field] !== void 0 && data[field] !== null) {
28682
28652
  const num = Number(data[field]);
28683
28653
  if (!isNaN(num) && num >= 0) {
@@ -28685,6 +28655,21 @@ var DefaultSettingsFetcher = class {
28685
28655
  }
28686
28656
  }
28687
28657
  }
28658
+ const temperatureFields = ["minTemperature", "maxTemperature", "offSetTemperature"];
28659
+ for (const field of temperatureFields) {
28660
+ if (data[field] !== void 0 && data[field] !== null) {
28661
+ const num = Number(data[field]);
28662
+ if (!isNaN(num)) {
28663
+ if (field === "offSetTemperature") {
28664
+ if (num >= -99.99 && num <= 99.99) {
28665
+ sanitized[field] = num;
28666
+ }
28667
+ } else {
28668
+ sanitized[field] = num;
28669
+ }
28670
+ }
28671
+ }
28672
+ }
28688
28673
  const objectFields = ["mapInstantaneousPower", "deviceMapInstaneousPower"];
28689
28674
  for (const field of objectFields) {
28690
28675
  if (data[field] && typeof data[field] === "object") {
@@ -29003,7 +28988,7 @@ var SettingsController = class {
29003
28988
  errors.push("GUID must be in valid UUID format");
29004
28989
  }
29005
28990
  }
29006
- const numericFields = ["maxDailyKwh", "maxNightKwh", "maxBusinessKwh", "minTemperature", "maxTemperature", "minWaterLevel", "maxWaterLevel"];
28991
+ const numericFields = ["maxDailyKwh", "maxNightKwh", "maxBusinessKwh", "minTemperature", "maxTemperature", "offSetTemperature", "minWaterLevel", "maxWaterLevel"];
29007
28992
  for (const field of numericFields) {
29008
28993
  if (formData[field] !== void 0) {
29009
28994
  const num = Number(formData[field]);
@@ -29015,6 +29000,11 @@ var SettingsController = class {
29015
29000
  errors.push(`${field} must be between 0 and 100`);
29016
29001
  }
29017
29002
  }
29003
+ if (field === "offSetTemperature") {
29004
+ if (num < -99.99 || num > 99.99) {
29005
+ errors.push(`${field} must be between -99.99 and +99.99`);
29006
+ }
29007
+ }
29018
29008
  }
29019
29009
  }
29020
29010
  if (formData.minTemperature !== void 0 && formData.maxTemperature !== void 0) {
@@ -33361,6 +33351,65 @@ var ENERGY_SUMMARY_TOOLTIP_CSS = `
33361
33351
  color: #ffffff;
33362
33352
  }
33363
33353
 
33354
+ /* Excluded Devices Notice */
33355
+ .energy-summary-tooltip__excluded-notice {
33356
+ display: flex;
33357
+ align-items: flex-start;
33358
+ gap: 8px;
33359
+ padding: 10px 12px;
33360
+ background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
33361
+ border-radius: 8px;
33362
+ margin-top: 12px;
33363
+ border: 1px solid #f59e0b;
33364
+ }
33365
+
33366
+ .energy-summary-tooltip__excluded-icon {
33367
+ font-size: 16px;
33368
+ flex-shrink: 0;
33369
+ }
33370
+
33371
+ .energy-summary-tooltip__excluded-content {
33372
+ flex: 1;
33373
+ min-width: 0;
33374
+ }
33375
+
33376
+ .energy-summary-tooltip__excluded-title {
33377
+ font-weight: 600;
33378
+ font-size: 11px;
33379
+ color: #92400e;
33380
+ margin-bottom: 4px;
33381
+ }
33382
+
33383
+ .energy-summary-tooltip__excluded-list {
33384
+ font-size: 10px;
33385
+ color: #78350f;
33386
+ line-height: 1.4;
33387
+ }
33388
+
33389
+ .energy-summary-tooltip__excluded-item {
33390
+ display: flex;
33391
+ justify-content: space-between;
33392
+ padding: 2px 0;
33393
+ border-bottom: 1px dashed rgba(120, 53, 15, 0.2);
33394
+ }
33395
+
33396
+ .energy-summary-tooltip__excluded-item:last-child {
33397
+ border-bottom: none;
33398
+ }
33399
+
33400
+ .energy-summary-tooltip__excluded-label {
33401
+ overflow: hidden;
33402
+ text-overflow: ellipsis;
33403
+ white-space: nowrap;
33404
+ max-width: 200px;
33405
+ }
33406
+
33407
+ .energy-summary-tooltip__excluded-value {
33408
+ font-weight: 600;
33409
+ flex-shrink: 0;
33410
+ margin-left: 8px;
33411
+ }
33412
+
33364
33413
  /* Responsive adjustments */
33365
33414
  @media (max-width: 600px) {
33366
33415
  .energy-summary-tooltip__content {
@@ -33510,6 +33559,38 @@ var EnergySummaryTooltip = {
33510
33559
  `;
33511
33560
  }).join("");
33512
33561
  },
33562
+ /**
33563
+ * Render excluded devices notice (if any devices are excluded from CAG)
33564
+ */
33565
+ renderExcludedNotice(excludedDevices, unit) {
33566
+ if (!excludedDevices || excludedDevices.length === 0) {
33567
+ return "";
33568
+ }
33569
+ const deviceItems = excludedDevices.map((device) => `
33570
+ <div class="energy-summary-tooltip__excluded-item">
33571
+ <span class="energy-summary-tooltip__excluded-label" title="${device.label}">${device.label}</span>
33572
+ <span class="energy-summary-tooltip__excluded-value">${formatConsumption2(device.value, unit)}</span>
33573
+ </div>
33574
+ `).join("");
33575
+ const totalExcluded = excludedDevices.reduce((sum, d) => sum + (d.value || 0), 0);
33576
+ return `
33577
+ <div class="energy-summary-tooltip__excluded-notice">
33578
+ <span class="energy-summary-tooltip__excluded-icon">\u26A0\uFE0F</span>
33579
+ <div class="energy-summary-tooltip__excluded-content">
33580
+ <div class="energy-summary-tooltip__excluded-title">
33581
+ Dispositivos exclu\xEDdos do subtotal CAG (${excludedDevices.length})
33582
+ </div>
33583
+ <div class="energy-summary-tooltip__excluded-list">
33584
+ ${deviceItems}
33585
+ <div class="energy-summary-tooltip__excluded-item" style="font-weight: 700; margin-top: 4px; padding-top: 4px; border-top: 1px solid rgba(120, 53, 15, 0.3);">
33586
+ <span>Total exclu\xEDdo:</span>
33587
+ <span class="energy-summary-tooltip__excluded-value">${formatConsumption2(totalExcluded, unit)}</span>
33588
+ </div>
33589
+ </div>
33590
+ </div>
33591
+ </div>
33592
+ `;
33593
+ },
33513
33594
  /**
33514
33595
  * Render full tooltip HTML
33515
33596
  */
@@ -33517,6 +33598,7 @@ var EnergySummaryTooltip = {
33517
33598
  const categoryRows = this.renderCategoryTree(summary.byCategory, summary.unit);
33518
33599
  const statusMatrix = this.renderStatusMatrix(summary.byStatus);
33519
33600
  const timestamp = formatTimestamp3(summary.lastUpdated);
33601
+ const excludedNotice = this.renderExcludedNotice(summary.excludedFromCAG, summary.unit);
33520
33602
  return `
33521
33603
  <div class="energy-summary-tooltip__content">
33522
33604
  <div class="energy-summary-tooltip__header" data-drag-handle>
@@ -33563,6 +33645,7 @@ var EnergySummaryTooltip = {
33563
33645
  <div class="energy-summary-tooltip__status-matrix">
33564
33646
  ${statusMatrix}
33565
33647
  </div>
33648
+ ${excludedNotice}
33566
33649
  </div>
33567
33650
  <div class="energy-summary-tooltip__total">
33568
33651
  <span class="energy-summary-tooltip__total-label">Consumo Total</span>