myio-js-library 0.1.13 → 0.1.15

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/README.md CHANGED
@@ -570,16 +570,17 @@ calcDeltaPercent(100, 100); // { value: 0, type: "neutral" }
570
570
  calcDeltaPercent(0, 100); // { value: 100, type: "increase" }
571
571
  ```
572
572
 
573
- ##### `formatEnergyByGroup(value: number, group: string): string`
573
+ ##### `formatWaterByGroup(value: number, group: string): string`
574
574
 
575
- Formats energy/water values based on group type (from MAIN_WATER controller).
575
+ Formats water group totals in m³. For values 1000, it returns the value in thousands of m³ with a simplified `x 10³` suffix.
576
576
 
577
+ **Examples**
577
578
  ```javascript
578
- import { formatEnergyByGroup } from 'myio-js-library';
579
+ import { formatWaterByGroup } from 'myio-js-library';
579
580
 
580
- formatEnergyByGroup(178, "Caixas D'Água"); // "1,78 m.c.a."
581
- formatEnergyByGroup(12.345, "Lojas"); // "12,35 M³"
582
- formatEnergyByGroup(1000000, "Lojas"); // "1,00(GWh scale)"
581
+ formatWaterByGroup(178, "Caixas D'Água"); // "1,78 m.c.a."
582
+ formatWaterByGroup(750, "Lojas"); // "750,00 M³"
583
+ formatWaterByGroup(2500, "Lojas"); // "2,50x 10³ "
583
584
  ```
584
585
 
585
586
  #### Water Date Utilities
package/dist/index.cjs CHANGED
@@ -43,9 +43,9 @@ __export(index_exports, {
43
43
  formatDateToYMD: () => formatDateToYMD,
44
44
  formatDateWithTimezoneOffset: () => formatDateWithTimezoneOffset,
45
45
  formatEnergy: () => formatEnergy,
46
- formatEnergyByGroup: () => formatEnergyByGroup,
47
46
  formatNumberReadable: () => formatNumberReadable,
48
47
  formatTankHeadFromCm: () => formatTankHeadFromCm,
48
+ formatWaterByGroup: () => formatWaterByGroup,
49
49
  formatWaterVolumeM3: () => formatWaterVolumeM3,
50
50
  getAvailableContexts: () => getAvailableContexts,
51
51
  getDateRangeArray: () => getDateRangeArray,
@@ -189,18 +189,15 @@ function calcDeltaPercent(prev, current) {
189
189
  return { value: 0, type: "neutral" };
190
190
  }
191
191
  }
192
- function formatEnergyByGroup(value, group) {
192
+ function formatWaterByGroup(value, group) {
193
193
  if (value === null || value === void 0 || isNaN(value)) {
194
194
  return "-";
195
195
  }
196
196
  if (group === "Caixas D'\xC1gua") {
197
197
  return formatTankHeadFromCm(value);
198
198
  }
199
- if (value >= 1e6) {
200
- return formatWaterVolumeM3(value / 1e6) + " (GWh scale)";
201
- }
202
199
  if (value >= 1e3) {
203
- return formatWaterVolumeM3(value / 1e3) + " (MWh scale)";
200
+ return formatWaterVolumeM3(value / 1e3) + " x 10\xB3 ";
204
201
  }
205
202
  return formatWaterVolumeM3(value);
206
203
  }
@@ -736,39 +733,77 @@ function findValue(data, keyOrPath, legacyDataKey) {
736
733
  }
737
734
 
738
735
  // src/utils/deviceType.js
736
+ function normalize(str) {
737
+ if (typeof str !== "string") return "";
738
+ let normalized = str.toUpperCase().trim();
739
+ normalized = normalized.replace(/[ÀÁÂÃÄÅ]/g, "A").replace(/[ÈÉÊË]/g, "E").replace(/[ÌÍÎÏ]/g, "I").replace(/[ÒÓÔÕÖ]/g, "O").replace(/[ÙÚÛÜ]/g, "U").replace(/[Ç]/g, "C").replace(/[Ñ]/g, "N");
740
+ normalized = normalized.replace(/\s+/g, " ");
741
+ return normalized;
742
+ }
743
+ function matchCaixaDAgua(normalizedStr) {
744
+ if (normalizedStr.includes("SCD")) return true;
745
+ const caixaVariants = [
746
+ "CAIXA D'AGUA",
747
+ "CAIXA D AGUA",
748
+ "CAIXA_D_AGUA",
749
+ "CAIXA DAGUA"
750
+ ];
751
+ return caixaVariants.some((variant) => normalizedStr.includes(variant));
752
+ }
739
753
  var contexts = {
740
754
  building: (name) => {
741
- const upper = name.toUpperCase();
742
- if (upper.includes("COMPRESSOR")) return "COMPRESSOR";
743
- if (upper.includes("VENT")) return "VENTILADOR";
744
- if (upper.includes("AUTOMATICO") || upper.includes("AUTOM\xC1TICO")) return "SELETOR_AUTO_MANUAL";
745
- if (upper.includes("TERMOSTATO")) return "TERMOSTATO";
746
- if (upper.includes("3F")) return "3F_MEDIDOR";
747
- if (upper.includes("TERMO") || upper.includes("TEMP")) return "TERMOSTATO";
748
- if (upper.includes("HIDR")) return "HIDROMETRO";
749
- if (upper.includes("ABRE")) return "SOLENOIDE";
750
- if (upper.includes("RECALQUE")) return "MOTOR";
751
- if (upper.includes("AUTOMACAO") || upper.includes("AUTOMA\xC7\xC3O")) return "GLOBAL_AUTOMACAO";
752
- if (upper.includes("AC")) return "CONTROLE REMOTO";
753
- if (upper.includes("SCD")) return "CAIXA_D_AGUA";
755
+ const normalized = normalize(name);
756
+ const rules = [
757
+ { test: (s) => s.includes("COMPRESSOR"), type: "COMPRESSOR" },
758
+ { test: (s) => s.includes("VENT"), type: "VENTILADOR" },
759
+ { test: (s) => s.includes("AUTOMATICO"), type: "SELETOR_AUTO_MANUAL" },
760
+ { test: (s) => s.includes("ESRL"), type: "ESCADA_ROLANTE" },
761
+ { test: (s) => s.includes("ESCADA"), type: "ESCADA_ROLANTE" },
762
+ { test: (s) => s.includes("ELEV"), type: "ELEVADOR" },
763
+ { test: (s) => s.includes("MOTR") || s.includes("RECALQUE"), type: "MOTOR" },
764
+ { test: (s) => s.includes("TERMOSTATO"), type: "TERMOSTATO" },
765
+ { test: (s) => s.includes("TERMO") || s.includes("TEMP"), type: "TERMOSTATO" },
766
+ { test: (s) => s.includes("3F"), type: "3F_MEDIDOR" },
767
+ { test: (s) => s.includes("HIDR"), type: "HIDROMETRO" },
768
+ { test: (s) => s.includes("ABRE"), type: "SOLENOIDE" },
769
+ { test: (s) => matchCaixaDAgua(s), type: "CAIXA_D_AGUA" },
770
+ { test: (s) => s.includes("AUTOMACAO") || s.includes("GW_AUTO"), type: "GLOBAL_AUTOMACAO" },
771
+ { test: (s) => s.includes("AC"), type: "CONTROLE REMOTO" }
772
+ ];
773
+ for (const rule of rules) {
774
+ if (rule.test(normalized)) {
775
+ return rule.type;
776
+ }
777
+ }
754
778
  return "default";
755
779
  },
756
780
  mall: (name) => {
757
- const upper = name.toUpperCase();
758
- if (upper.includes("CHILLER")) return "CHILLER";
759
- if (upper.includes("ESCADA")) return "ESCADA_ROLANTE";
760
- if (upper.includes("LOJA")) return "LOJA_SENSOR";
761
- if (upper.includes("ILUMINACAO") || upper.includes("ILUMINA\xC7\xC3O")) return "ILUMINACAO";
781
+ const normalized = normalize(name);
782
+ const rules = [
783
+ { test: (s) => s.includes("CHILLER"), type: "CHILLER" },
784
+ { test: (s) => s.includes("ESCADA"), type: "ESCADA_ROLANTE" },
785
+ { test: (s) => s.includes("LOJA"), type: "LOJA_SENSOR" },
786
+ { test: (s) => s.includes("ILUMINACAO"), type: "ILUMINACAO" }
787
+ ];
788
+ for (const rule of rules) {
789
+ if (rule.test(normalized)) {
790
+ return rule.type;
791
+ }
792
+ }
762
793
  return "default";
763
794
  }
764
795
  };
796
+ var warnedContexts = /* @__PURE__ */ new Set();
765
797
  function detectDeviceType(name, context = "building") {
766
798
  if (typeof name !== "string") {
767
799
  throw new Error("Device name must be a string.");
768
800
  }
769
801
  const detectFunction = contexts[context];
770
802
  if (!detectFunction) {
771
- console.warn(`[myio-js-library] Context "${context}" not found. Using default fallback.`);
803
+ if (!warnedContexts.has(context)) {
804
+ console.warn(`[myio-js-library] Context "${context}" not found. Using default fallback.`);
805
+ warnedContexts.add(context);
806
+ }
772
807
  return contexts.building(name);
773
808
  }
774
809
  return detectFunction(name);
@@ -896,6 +931,7 @@ function renderCardComponent({
896
931
  const {
897
932
  entityId,
898
933
  labelOrName,
934
+ deviceIdentifier,
899
935
  entityType,
900
936
  deviceType,
901
937
  slaveId,
@@ -903,22 +939,43 @@ function renderCardComponent({
903
939
  val,
904
940
  centralId,
905
941
  updatedIdentifiers = {},
906
- isOn = false,
907
942
  perc = 0,
908
- group,
909
943
  connectionStatus,
910
944
  centralName,
911
945
  connectionStatusTime,
912
946
  timaVal,
913
947
  valType
914
948
  } = entityObject;
949
+ const DeviceStatus = {
950
+ CONNECTED: "connected",
951
+ OFFLINE: "offline",
952
+ POWER_ON: "power_on",
953
+ STANDBY: "standby",
954
+ POWER_OFF: "power_off",
955
+ WARNING: "warning",
956
+ DANGER: "danger",
957
+ MAINTENANCE: "maintenance"
958
+ };
959
+ const statusIcons = {
960
+ [DeviceStatus.CONNECTED]: "\u2705",
961
+ [DeviceStatus.OFFLINE]: "\u{1F50C}",
962
+ [DeviceStatus.POWER_ON]: "\u26A1",
963
+ [DeviceStatus.STANDBY]: "\u23F8\uFE0F",
964
+ [DeviceStatus.POWER_OFF]: "\u23F9\uFE0F",
965
+ [DeviceStatus.WARNING]: "\u26A0\uFE0F",
966
+ [DeviceStatus.DANGER]: "\u{1F6A8}",
967
+ [DeviceStatus.MAINTENANCE]: "\u{1F6E0}\uFE0F"
968
+ };
969
+ const isOfflineOrDanger = connectionStatus === DeviceStatus.OFFLINE || connectionStatus === DeviceStatus.DANGER;
970
+ const shouldFlashIcon = connectionStatus === DeviceStatus.OFFLINE || connectionStatus === DeviceStatus.WARNING || connectionStatus === DeviceStatus.DANGER || connectionStatus === DeviceStatus.MAINTENANCE;
971
+ const icon = statusIcons[connectionStatus] || statusIcons[DeviceStatus.POWER_ON];
915
972
  const MyIO = typeof MyIOLibrary !== "undefined" && MyIOLibrary || typeof window !== "undefined" && window.MyIOLibrary || {
916
- formatEnergyByGroup: (v, g) => `${v} kWh`,
973
+ formatEnergy: (v, g) => `${v} kWh`,
917
974
  formatNumberReadable: (n) => Number(n ?? 0).toFixed(1)
918
975
  };
919
- let valFormatted = MyIO.formatEnergyByGroup(val);
976
+ let valFormatted = MyIO.formatEnergy(val);
920
977
  if (valType === "ENERGY") {
921
- valFormatted = MyIO.formatEnergyByGroup(val);
978
+ valFormatted = MyIO.formatEnergy(val);
922
979
  } else if (valType === "WATER") {
923
980
  valFormatted = `${val} m\xB3`;
924
981
  } else if (valType === "TANK") {
@@ -938,12 +995,12 @@ function renderCardComponent({
938
995
  padding: 8px 12px;
939
996
  background: #fff;
940
997
  box-shadow: 0 4px 10px rgba(0, 0, 0, .05);
941
- display: flex;
942
- align-items: center;
943
- justify-content: center;
998
+ /* display: flex; REMOVIDO */
999
+ /* align-items: center; REMOVIDO */
1000
+ /* justify-content: center; REMOVIDO */
944
1001
  cursor: pointer;
945
1002
  transition: transform .2s;
946
- min-height: 140px;
1003
+ /* min-height: 140px; REMOVIDO (movido para .device-card-inner) */
947
1004
  box-sizing: border-box;
948
1005
  overflow: hidden;
949
1006
  }
@@ -974,6 +1031,19 @@ function renderCardComponent({
974
1031
  line-height: 1.1;
975
1032
  }
976
1033
 
1034
+ .device-subtitle {
1035
+ font-size: 0.7rem;
1036
+ font-weight: 500;
1037
+ color: #888; /* Cinza */
1038
+ text-align: center;
1039
+ white-space: nowrap;
1040
+ overflow: hidden;
1041
+ text-overflow: ellipsis;
1042
+ max-width: 90%;
1043
+ line-height: 1.1;
1044
+ margin-top: 2px;
1045
+ }
1046
+
977
1047
  .device-image {
978
1048
  max-height: 44px;
979
1049
  width: auto;
@@ -1014,19 +1084,13 @@ function renderCardComponent({
1014
1084
  }
1015
1085
 
1016
1086
  @keyframes flash {
1017
- 0% {
1018
- opacity: 1;
1019
- }
1020
- 50% {
1021
- opacity: .2;
1022
- }
1023
- 100% {
1024
- opacity: 1;
1025
- }
1087
+ 0% { opacity: 1; }
1088
+ 50% { opacity: .2; }
1089
+ 100% { opacity: 1; }
1026
1090
  }
1027
1091
 
1028
1092
  .card-actions {
1029
- width: 10%;
1093
+ flex-shrink: 0;
1030
1094
  height: 100%;
1031
1095
  box-shadow: 1px 0 2px rgba(0, 0, 0, .1);
1032
1096
  display: flex;
@@ -1052,23 +1116,6 @@ function renderCardComponent({
1052
1116
  animation: border-blink 1s infinite;
1053
1117
  }
1054
1118
 
1055
-
1056
- .device-info {
1057
- position: absolute;
1058
- top: 8px; /* dist\xE2ncia do topo */
1059
- right: 8px; /* dist\xE2ncia da direita */
1060
- background: none;
1061
- border: none;
1062
- cursor: pointer;
1063
- padding: 4px;
1064
- border-radius: 50%;
1065
- transition: background 0.2s;
1066
- }
1067
-
1068
- .device-info:hover {
1069
- background: rgba(0, 0, 0, 0.05);
1070
- }
1071
-
1072
1119
  .device-card-centered.flipped .device-card-inner {
1073
1120
  transform: rotateY(180deg);
1074
1121
  }
@@ -1083,7 +1130,7 @@ function renderCardComponent({
1083
1130
  font-size: 1.2rem;
1084
1131
  }
1085
1132
  .device-card-centered {
1086
- perspective: 1000px; /* perspectiva para 3D */
1133
+ perspective: 1000px;
1087
1134
  }
1088
1135
 
1089
1136
  .device-card-inner {
@@ -1091,100 +1138,94 @@ function renderCardComponent({
1091
1138
  width: 100%;
1092
1139
  height: 100%;
1093
1140
  transform-style: preserve-3d;
1141
+ min-height: 140px; /* ATUALIZADO: A altura m\xEDnima agora \xE9 controlada aqui */
1094
1142
  }
1095
1143
 
1096
1144
  .device-card-front {
1097
1145
  display: flex;
1098
1146
  flex-direction: row;
1099
1147
  justify-content: flex-start;
1100
- align-items: flex-start; /* topo */
1148
+ align-items: flex-start; /* Agora isso vai funcionar */
1101
1149
  position: absolute;
1102
1150
  width: 100%;
1103
1151
  height: 100%;
1104
1152
  top: 0;
1105
1153
  left: 0;
1106
1154
  backface-visibility: hidden;
1155
+ gap: 4px;
1107
1156
  }
1108
1157
 
1109
1158
  .device-card-back {
1110
- display: flex;
1111
- flex-direction: column; /* muda para coluna se quiser empilhar elementos verticalmente */
1112
- justify-content: flex-start; /* conte\xFAdo come\xE7a do topo */
1113
- align-items: center; /* centraliza horizontalmente */
1114
- position: absolute;
1115
- width: 100%;
1116
- height: 100%;
1117
- top: 0;
1118
- left: 0;
1119
- backface-visibility: hidden;
1120
- transform: rotateY(180deg); /* mant\xE9m flip */
1121
- padding: 10px; /* opcional: espa\xE7o interno */
1122
- gap: 10px; /* opcional: espa\xE7o entre elementos */
1159
+ transform: rotateY(180deg);
1123
1160
  }
1124
1161
 
1125
-
1126
-
1127
- .device-info {
1162
+ .device-card-front .device-info,
1163
+ .device-card-back .device-info {
1128
1164
  position: absolute;
1129
- top: 8px; /* dist\xE2ncia do topo */
1130
- right: 8px; /* dist\xE2ncia da direita */
1131
- background: none;
1132
- border: none;
1133
- cursor: pointer;
1165
+ top: 8px;
1166
+ right: 12px;
1167
+ margin: 0;
1168
+ display: flex;
1169
+ align-items: center;
1170
+ justify-content: center;
1134
1171
  padding: 4px;
1135
1172
  border-radius: 50%;
1136
- transition: background 0.2s;l
1137
- }
1138
- .device-card-back {
1139
- transform: rotateY(180deg); /* faz o flip funcionar */
1140
- }
1141
-
1142
- .device-card-front .device-info,
1143
- .device-card-back .device-info {
1144
- position: absolute; /* tira do fluxo do flex */
1145
- top: 0; /* topo do card */
1146
- right: 8px; /* canto direito */
1147
- margin: 0; /* remove qualquer margem que empurre o bot\xE3o */
1148
- display: flex; /* mant\xE9m o conte\xFAdo do bot\xE3o centralizado */
1149
- align-items: center;
1150
- justify-content: center;
1151
- padding: 4px;
1152
- border-radius: 50%;
1153
1173
  cursor: pointer;
1154
- z-index: 10;
1174
+ z-index: 10;
1175
+ background: none;
1176
+ border: none;
1177
+ transition: background 0.2s;
1178
+ }
1179
+ .device-card-front .device-info:hover,
1180
+ .device-card-back .device-info:hover {
1181
+ background: rgba(0, 0, 0, 0.05);
1155
1182
  }
1156
1183
 
1157
1184
 
1158
1185
  .device-card-back {
1159
-
1160
1186
  display: flex;
1161
- flex-direction: column; /* empilha os elementos */
1162
- justify-content: flex-start;
1163
- align-items: flex-start; /* tudo \xE0 esquerda por padr\xE3o */
1187
+ flex-direction: column;
1188
+ justify-content: space-around; /* Mantido para preencher o verso */
1189
+ align-items: stretch;
1164
1190
  padding: 10px;
1165
- gap: 10px;
1191
+ gap: 5px;
1166
1192
  height: 100%;
1167
- margin-left: -10px;
1193
+ width: 100%;
1194
+ box-sizing: border-box;
1195
+
1196
+ /* Posi\xE7\xF5es para o flip */
1197
+ position: absolute;
1198
+ top: 0;
1199
+ left: 0;
1200
+ backface-visibility: hidden;
1201
+ transform: rotateY(180deg);
1202
+ }
1203
+
1204
+ .device-card-back #status-bar {
1205
+ position: relative;
1206
+ width: 100%;
1207
+ padding-top: 10px;
1168
1208
  }
1169
1209
 
1170
1210
  .device-card-back .value-container {
1171
1211
  display: flex;
1172
- flex-direction: row; /* \xEDcone e valor lado a lado */
1212
+ flex-direction: row;
1173
1213
  align-items: center;
1174
1214
  gap: 5px;
1175
- color: #c19efc; /* roxo clarinho */
1176
- align-self: center; /* centraliza horizontalmente no card */
1215
+ color: #c19efc;
1216
+ align-self: center;
1177
1217
  }
1178
1218
 
1179
1219
  .device-card-back #lastconsumptionTime {
1180
-
1181
1220
  display: flex;
1182
1221
  flex-direction: column;
1183
- align-items: flex-start; /* mant\xE9m \xE0 esquerda */
1222
+ align-items: flex-start;
1184
1223
  gap: 2px;
1185
1224
  font-size: 11px;
1186
1225
  font-weight: bold;
1187
1226
  color: black;
1227
+ width: 100%;
1228
+ padding-bottom: 10px;
1188
1229
  }
1189
1230
 
1190
1231
 
@@ -1206,7 +1247,7 @@ function renderCardComponent({
1206
1247
  }
1207
1248
 
1208
1249
  .device-card-centered.online .flash-icon {
1209
- color: #28a745 !important; /* verde premium para online */
1250
+ color: #28a745 !important;
1210
1251
  }
1211
1252
  `;
1212
1253
  document.head.appendChild(style);
@@ -1251,6 +1292,9 @@ function renderCardComponent({
1251
1292
  Infcolor = "#d6dcdd";
1252
1293
  }
1253
1294
  function normalizeString(str) {
1295
+ if (typeof str !== "string") {
1296
+ str = "";
1297
+ }
1254
1298
  return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toUpperCase();
1255
1299
  }
1256
1300
  const deviceImages = {
@@ -1265,7 +1309,7 @@ function renderCardComponent({
1265
1309
  const nameType = normalizeString(deviceType);
1266
1310
  const img = deviceImages[nameType] || defaultImage;
1267
1311
  const html = `
1268
- <div class="device-card-centered clickable ${connectionStatus === "offline" ? "offline" : ""}"
1312
+ <div class="device-card-centered clickable ${isOfflineOrDanger ? "offline" : ""}"
1269
1313
  data-entity-id="${entityId}"
1270
1314
  data-entity-label="${labelOrName}"
1271
1315
  data-entity-type="${entityType}"
@@ -1294,18 +1338,27 @@ function renderCardComponent({
1294
1338
  <input class="card-action action-checker" data-action="checker" title="Selecionar" type="checkbox">` : ``}
1295
1339
  </div>
1296
1340
 
1297
- <div style="display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;width:85%">
1298
- <div class="device-title-row">
1341
+ <div style="display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%; flex-grow: 1; min-width: 0; padding: 0 12px;">
1342
+
1343
+ <div class="device-title-row" style="flex-direction: column; min-height: 38px;">
1299
1344
  <span class="device-title" title="${labelOrName}">
1300
1345
  ${String(labelOrName ?? "").length > 15 ? String(labelOrName).slice(0, 15) + "\u2026" : String(labelOrName ?? "")}
1301
1346
  </span>
1347
+ ${deviceIdentifier ? `
1348
+ <span class="device-subtitle" title="${deviceIdentifier}">
1349
+ ${deviceIdentifier}
1350
+ </span>
1351
+ ` : ""}
1302
1352
  </div>
1353
+
1303
1354
  <img class="device-image" src="${img || ""}" />
1304
1355
  <div class="device-data-row">
1305
1356
  <div class="consumption-main">
1306
- <span class="flash-icon ${connectionStatus === "offline" ? "flash" : isOn ? "flash" : ""}">
1307
- ${connectionStatus === "offline" ? "\u{1F6A8}" : "\u26A1"}
1357
+
1358
+ <span class="flash-icon ${shouldFlashIcon ? "flash" : ""}">
1359
+ ${icon}
1308
1360
  </span>
1361
+
1309
1362
  <span class="consumption-value" data-entity-consumption="${val}">${valFormatted}</span>
1310
1363
  <span class="device-title-percent">(${percFormatted}%)</span>
1311
1364
  </div>
@@ -1339,7 +1392,7 @@ function renderCardComponent({
1339
1392
  <svg xmlns="http://www.w3.org/2000/svg" height="30px" viewBox="0 -960 960 960" width="30px" fill="#dea404">
1340
1393
  <path d="m456-200 174-340H510v-220L330-420h126v220Zm24 120q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/>
1341
1394
  </svg>
1342
- <div><span>${MyIO.formatEnergyByGroup(val / 1e3) || "-"}</span></div>
1395
+ <div><span>${MyIO.formatEnergy(val / 1e3) || "-"}</span></div>
1343
1396
  </div>
1344
1397
 
1345
1398
  <div id="lastconsumptionTime">
@@ -1428,9 +1481,9 @@ function renderCardComponent({
1428
1481
  formatDateToYMD,
1429
1482
  formatDateWithTimezoneOffset,
1430
1483
  formatEnergy,
1431
- formatEnergyByGroup,
1432
1484
  formatNumberReadable,
1433
1485
  formatTankHeadFromCm,
1486
+ formatWaterByGroup,
1434
1487
  formatWaterVolumeM3,
1435
1488
  getAvailableContexts,
1436
1489
  getDateRangeArray,
package/dist/index.d.cts CHANGED
@@ -59,12 +59,12 @@ declare function calcDeltaPercent(prev: number, current: number): {
59
59
  type: 'increase' | 'decrease' | 'neutral';
60
60
  };
61
61
  /**
62
- * Formats energy/water values based on group type (from MAIN_WATER controller)
63
- * @param value - The value to format
62
+ * Formats water values based on group type (from MAIN_WATER controller)
63
+ * @param value - The value to format in cubic meters
64
64
  * @param group - The group type ('Caixas D\'Água', 'Lojas', 'Área Comum')
65
65
  * @returns Formatted string with appropriate unit
66
66
  */
67
- declare function formatEnergyByGroup(value: number, group: string): string;
67
+ declare function formatWaterByGroup(value: number, group: string): string;
68
68
  /**
69
69
  * Formats all values in the same unit for consistent display
70
70
  * @param values - Array of values to format
@@ -386,4 +386,4 @@ declare function renderCardComponent({ entityObject, handleActionDashboard, hand
386
386
  handleClickCard: any;
387
387
  }): any;
388
388
 
389
- export { type StoreRow, type TimedValue, type WaterRow, addDetectionContext, addNamespace, averageByDay, buildWaterReportCSV, buildWaterStoresCSV, calcDeltaPercent, classify, classifyWaterLabel, classifyWaterLabels, decodePayload, decodePayloadBase64Xor, detectDeviceType, determineInterval, exportToCSV, exportToCSVAll, findValue, fmtPerc$1 as fmtPerc, fmtPerc as fmtPercLegacy, formatAllInSameUnit, formatAllInSameWaterUnit, formatDateForInput, formatDateToYMD, formatDateWithTimezoneOffset, formatEnergy, formatEnergyByGroup, formatNumberReadable, formatTankHeadFromCm, formatWaterVolumeM3, getAvailableContexts, getDateRangeArray, getSaoPauloISOString, getSaoPauloISOStringFixed, getValueByDatakey, getValueByDatakeyLegacy, getWaterCategories, groupByDay, isWaterCategory, normalizeRecipients, numbers, parseInputDateToDate, renderCardComponent, strings, timeWindowFromInputYMD, toCSV, toFixedSafe };
389
+ export { type StoreRow, type TimedValue, type WaterRow, addDetectionContext, addNamespace, averageByDay, buildWaterReportCSV, buildWaterStoresCSV, calcDeltaPercent, classify, classifyWaterLabel, classifyWaterLabels, decodePayload, decodePayloadBase64Xor, detectDeviceType, determineInterval, exportToCSV, exportToCSVAll, findValue, fmtPerc$1 as fmtPerc, fmtPerc as fmtPercLegacy, formatAllInSameUnit, formatAllInSameWaterUnit, formatDateForInput, formatDateToYMD, formatDateWithTimezoneOffset, formatEnergy, formatNumberReadable, formatTankHeadFromCm, formatWaterByGroup, formatWaterVolumeM3, getAvailableContexts, getDateRangeArray, getSaoPauloISOString, getSaoPauloISOStringFixed, getValueByDatakey, getValueByDatakeyLegacy, getWaterCategories, groupByDay, isWaterCategory, normalizeRecipients, numbers, parseInputDateToDate, renderCardComponent, strings, timeWindowFromInputYMD, toCSV, toFixedSafe };