myio-js-library 0.1.180 → 0.1.182
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 +939 -328
- package/dist/index.d.cts +151 -1
- package/dist/index.js +937 -328
- package/dist/myio-js-library.umd.js +977 -363
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -583,6 +583,7 @@ __export(index_exports, {
|
|
|
583
583
|
EXPORT_DOMAIN_ICONS: () => EXPORT_DOMAIN_ICONS,
|
|
584
584
|
EXPORT_DOMAIN_LABELS: () => EXPORT_DOMAIN_LABELS,
|
|
585
585
|
EXPORT_DOMAIN_UNITS: () => EXPORT_DOMAIN_UNITS,
|
|
586
|
+
EnergyRangeTooltip: () => EnergyRangeTooltip,
|
|
586
587
|
MyIOChartModal: () => MyIOChartModal,
|
|
587
588
|
MyIODraggableCard: () => MyIODraggableCard,
|
|
588
589
|
MyIOSelectionStore: () => MyIOSelectionStore,
|
|
@@ -591,6 +592,7 @@ __export(index_exports, {
|
|
|
591
592
|
POWER_LIMITS_DEVICE_TYPES: () => DEVICE_TYPES,
|
|
592
593
|
POWER_LIMITS_STATUS_CONFIG: () => STATUS_CONFIG,
|
|
593
594
|
POWER_LIMITS_TELEMETRY_TYPES: () => TELEMETRY_TYPES2,
|
|
595
|
+
TempRangeTooltip: () => TempRangeTooltip,
|
|
594
596
|
addDetectionContext: () => addDetectionContext,
|
|
595
597
|
addNamespace: () => addNamespace,
|
|
596
598
|
aggregateByDay: () => aggregateByDay,
|
|
@@ -6064,214 +6066,283 @@ function createLogHelper(debugActive = false) {
|
|
|
6064
6066
|
}
|
|
6065
6067
|
var LogHelper = createLogHelper(false);
|
|
6066
6068
|
|
|
6067
|
-
// src/
|
|
6068
|
-
var
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
document.head.appendChild(style);
|
|
6077
|
-
}
|
|
6069
|
+
// src/utils/TempRangeTooltip.ts
|
|
6070
|
+
var TOOLTIP_STYLES = `
|
|
6071
|
+
.temp-range-tooltip {
|
|
6072
|
+
position: fixed;
|
|
6073
|
+
z-index: 99999;
|
|
6074
|
+
pointer-events: none;
|
|
6075
|
+
opacity: 0;
|
|
6076
|
+
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
6077
|
+
transform: translateY(5px);
|
|
6078
6078
|
}
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
const entityObject = params.entityObject;
|
|
6085
|
-
if (!entityObject.entityId) {
|
|
6086
|
-
LogHelper2.warn("[CardHeadOffice] entityId is missing, generating temporary ID");
|
|
6087
|
-
entityObject.entityId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
6088
|
-
}
|
|
6089
|
-
if (!params.delayTimeConnectionInMins) {
|
|
6090
|
-
LogHelper2.warn(
|
|
6091
|
-
`[CardHeadOffice] delayTimeConnectionInMins is missing, defaulting to ${DEFAUL_DELAY_TIME_CONNECTION_IN_MINS} mins`
|
|
6092
|
-
);
|
|
6093
|
-
}
|
|
6094
|
-
return {
|
|
6095
|
-
entityObject,
|
|
6096
|
-
i18n: { ...DEFAULT_I18N, ...params.i18n || {} },
|
|
6097
|
-
enableSelection: Boolean(params.enableSelection),
|
|
6098
|
-
enableDragDrop: Boolean(params.enableDragDrop),
|
|
6099
|
-
useNewComponents: Boolean(params.useNewComponents),
|
|
6100
|
-
// RFC-0091: Configurable delay time for connection status check (default 15 minutes)
|
|
6101
|
-
delayTimeConnectionInMins: params.delayTimeConnectionInMins ?? DEFAUL_DELAY_TIME_CONNECTION_IN_MINS,
|
|
6102
|
-
// Debug options
|
|
6103
|
-
debugActive: params.debugActive ?? false,
|
|
6104
|
-
activeTooltipDebug: params.activeTooltipDebug ?? false,
|
|
6105
|
-
// LogHelper instance for this card
|
|
6106
|
-
LogHelper: LogHelper2,
|
|
6107
|
-
callbacks: {
|
|
6108
|
-
handleActionDashboard: params.handleActionDashboard,
|
|
6109
|
-
handleActionReport: params.handleActionReport,
|
|
6110
|
-
handleActionSettings: params.handleActionSettings,
|
|
6111
|
-
handleSelect: params.handleSelect,
|
|
6112
|
-
handInfo: params.handInfo,
|
|
6113
|
-
handleClickCard: params.handleClickCard
|
|
6114
|
-
}
|
|
6115
|
-
};
|
|
6079
|
+
|
|
6080
|
+
.temp-range-tooltip.visible {
|
|
6081
|
+
opacity: 1;
|
|
6082
|
+
pointer-events: auto;
|
|
6083
|
+
transform: translateY(0);
|
|
6116
6084
|
}
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6085
|
+
|
|
6086
|
+
.temp-range-tooltip__content {
|
|
6087
|
+
background: #ffffff;
|
|
6088
|
+
border: 1px solid #e2e8f0;
|
|
6089
|
+
border-radius: 12px;
|
|
6090
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15), 0 2px 10px rgba(0, 0, 0, 0.08);
|
|
6091
|
+
min-width: 280px;
|
|
6092
|
+
max-width: 320px;
|
|
6093
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
6094
|
+
font-size: 12px;
|
|
6095
|
+
color: #1e293b;
|
|
6096
|
+
overflow: hidden;
|
|
6125
6097
|
}
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
} else {
|
|
6135
|
-
const w = Math.ceil(val);
|
|
6136
|
-
return { num: w.toString(), unit: "W" };
|
|
6137
|
-
}
|
|
6098
|
+
|
|
6099
|
+
.temp-range-tooltip__header {
|
|
6100
|
+
display: flex;
|
|
6101
|
+
align-items: center;
|
|
6102
|
+
gap: 8px;
|
|
6103
|
+
padding: 12px 16px;
|
|
6104
|
+
background: linear-gradient(90deg, #fff7ed 0%, #fed7aa 100%);
|
|
6105
|
+
border-bottom: 1px solid #fdba74;
|
|
6138
6106
|
}
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
}
|
|
6143
|
-
if (domain === "temperature") {
|
|
6144
|
-
return formatTemperature(value, 0);
|
|
6145
|
-
}
|
|
6146
|
-
return formatEnergy(value);
|
|
6107
|
+
|
|
6108
|
+
.temp-range-tooltip__icon {
|
|
6109
|
+
font-size: 18px;
|
|
6147
6110
|
}
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
6154
|
-
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
6155
|
-
const year = date.getFullYear();
|
|
6156
|
-
return `${hours}:${minutes} ${day}/${month}/${year}`;
|
|
6111
|
+
|
|
6112
|
+
.temp-range-tooltip__title {
|
|
6113
|
+
font-weight: 700;
|
|
6114
|
+
font-size: 13px;
|
|
6115
|
+
color: #c2410c;
|
|
6157
6116
|
}
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
if (isNaN(numericTarget) || isNaN(numericConsumption) || numericTarget <= 0) {
|
|
6162
|
-
return 0;
|
|
6163
|
-
}
|
|
6164
|
-
const percentage = numericConsumption / numericTarget * 100;
|
|
6165
|
-
return percentage;
|
|
6117
|
+
|
|
6118
|
+
.temp-range-tooltip__body {
|
|
6119
|
+
padding: 16px;
|
|
6166
6120
|
}
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
return { chipClass: "chip--standby", label: "Frio" };
|
|
6174
|
-
case "hot":
|
|
6175
|
-
return { chipClass: "chip--alert", label: "Quente" };
|
|
6176
|
-
// --- Status Existentes (aligned with getCardStateClass) ---
|
|
6177
|
-
case DeviceStatusType.POWER_ON:
|
|
6178
|
-
if (domain === "water") {
|
|
6179
|
-
return { chipClass: "chip--power-on", label: i18n.in_operation_water };
|
|
6180
|
-
}
|
|
6181
|
-
return { chipClass: "chip--power-on", label: i18n.in_operation };
|
|
6182
|
-
case DeviceStatusType.STANDBY:
|
|
6183
|
-
return { chipClass: "chip--standby", label: i18n.standby };
|
|
6184
|
-
case DeviceStatusType.WARNING:
|
|
6185
|
-
return { chipClass: "chip--warning", label: i18n.alert };
|
|
6186
|
-
case DeviceStatusType.MAINTENANCE:
|
|
6187
|
-
return { chipClass: "chip--maintenance", label: i18n.maintenance };
|
|
6188
|
-
case DeviceStatusType.FAILURE:
|
|
6189
|
-
return { chipClass: "chip--failure", label: i18n.failure };
|
|
6190
|
-
case DeviceStatusType.POWER_OFF:
|
|
6191
|
-
return { chipClass: "chip--power-off", label: i18n.power_off || i18n.failure };
|
|
6192
|
-
case DeviceStatusType.OFFLINE:
|
|
6193
|
-
return { chipClass: "chip--offline", label: i18n.offline };
|
|
6194
|
-
case DeviceStatusType.NO_INFO:
|
|
6195
|
-
return { chipClass: "chip--no-info", label: i18n.no_info || i18n.offline };
|
|
6196
|
-
case DeviceStatusType.NOT_INSTALLED:
|
|
6197
|
-
return { chipClass: "chip--not-installed", label: i18n.not_installed };
|
|
6198
|
-
default:
|
|
6199
|
-
return { chipClass: "chip--offline", label: i18n.offline };
|
|
6200
|
-
}
|
|
6121
|
+
|
|
6122
|
+
.temp-range-tooltip__value-row {
|
|
6123
|
+
display: flex;
|
|
6124
|
+
justify-content: space-between;
|
|
6125
|
+
align-items: center;
|
|
6126
|
+
margin-bottom: 16px;
|
|
6201
6127
|
}
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
case DeviceStatusType.STANDBY:
|
|
6208
|
-
return "is-standby";
|
|
6209
|
-
// Green border
|
|
6210
|
-
case DeviceStatusType.WARNING:
|
|
6211
|
-
return "is-warning";
|
|
6212
|
-
// Yellow border
|
|
6213
|
-
case DeviceStatusType.MAINTENANCE:
|
|
6214
|
-
return "is-maintenance";
|
|
6215
|
-
// Yellow border
|
|
6216
|
-
case DeviceStatusType.FAILURE:
|
|
6217
|
-
return "is-failure";
|
|
6218
|
-
// Dark Red border
|
|
6219
|
-
case DeviceStatusType.POWER_OFF:
|
|
6220
|
-
return "is-power-off";
|
|
6221
|
-
// Light Red border
|
|
6222
|
-
case DeviceStatusType.OFFLINE:
|
|
6223
|
-
return "is-offline";
|
|
6224
|
-
// Dark Gray border
|
|
6225
|
-
case DeviceStatusType.NO_INFO:
|
|
6226
|
-
return "is-no-info";
|
|
6227
|
-
// Dark Orange border
|
|
6228
|
-
case DeviceStatusType.NOT_INSTALLED:
|
|
6229
|
-
return "is-not-installed";
|
|
6230
|
-
// Purple border
|
|
6231
|
-
default:
|
|
6232
|
-
return "";
|
|
6233
|
-
}
|
|
6128
|
+
|
|
6129
|
+
.temp-range-tooltip__current {
|
|
6130
|
+
font-size: 28px;
|
|
6131
|
+
font-weight: 700;
|
|
6132
|
+
color: #1e293b;
|
|
6234
6133
|
}
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
const tempMax = entityObject.temperatureMax ?? entityObject.maxTemperature;
|
|
6240
|
-
if (tempMin === void 0 || tempMax === void 0 || tempMin === null || tempMax === null) {
|
|
6241
|
-
return "";
|
|
6242
|
-
}
|
|
6243
|
-
if (currentTemp > tempMax) return "is-temp-hot";
|
|
6244
|
-
if (currentTemp < tempMin) return "is-temp-cold";
|
|
6245
|
-
return "is-temp-ok";
|
|
6134
|
+
|
|
6135
|
+
.temp-range-tooltip__current sup {
|
|
6136
|
+
font-size: 14px;
|
|
6137
|
+
color: #64748b;
|
|
6246
6138
|
}
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6139
|
+
|
|
6140
|
+
.temp-range-tooltip__deviation {
|
|
6141
|
+
text-align: right;
|
|
6142
|
+
}
|
|
6143
|
+
|
|
6144
|
+
.temp-range-tooltip__deviation-value {
|
|
6145
|
+
font-size: 16px;
|
|
6146
|
+
font-weight: 700;
|
|
6147
|
+
}
|
|
6148
|
+
|
|
6149
|
+
.temp-range-tooltip__deviation-value.cold {
|
|
6150
|
+
color: #2563eb;
|
|
6151
|
+
}
|
|
6152
|
+
|
|
6153
|
+
.temp-range-tooltip__deviation-value.ok {
|
|
6154
|
+
color: #16a34a;
|
|
6155
|
+
}
|
|
6156
|
+
|
|
6157
|
+
.temp-range-tooltip__deviation-value.hot {
|
|
6158
|
+
color: #dc2626;
|
|
6159
|
+
}
|
|
6160
|
+
|
|
6161
|
+
.temp-range-tooltip__deviation-label {
|
|
6162
|
+
font-size: 10px;
|
|
6163
|
+
color: #64748b;
|
|
6164
|
+
text-transform: uppercase;
|
|
6165
|
+
letter-spacing: 0.5px;
|
|
6166
|
+
}
|
|
6167
|
+
|
|
6168
|
+
.temp-range-tooltip__ruler {
|
|
6169
|
+
position: relative;
|
|
6170
|
+
height: 32px;
|
|
6171
|
+
margin: 12px 0;
|
|
6172
|
+
border-radius: 8px;
|
|
6173
|
+
overflow: visible;
|
|
6174
|
+
}
|
|
6175
|
+
|
|
6176
|
+
.temp-range-tooltip__ruler-track {
|
|
6177
|
+
position: absolute;
|
|
6178
|
+
top: 12px;
|
|
6179
|
+
left: 0;
|
|
6180
|
+
right: 0;
|
|
6181
|
+
height: 8px;
|
|
6182
|
+
background: linear-gradient(90deg, #dbeafe 0%, #dcfce7 50%, #fee2e2 100%);
|
|
6183
|
+
border-radius: 4px;
|
|
6184
|
+
border: 1px solid #e2e8f0;
|
|
6185
|
+
}
|
|
6186
|
+
|
|
6187
|
+
.temp-range-tooltip__ruler-range {
|
|
6188
|
+
position: absolute;
|
|
6189
|
+
top: 12px;
|
|
6190
|
+
height: 8px;
|
|
6191
|
+
background: #22c55e;
|
|
6192
|
+
border-radius: 4px;
|
|
6193
|
+
opacity: 0.6;
|
|
6194
|
+
}
|
|
6195
|
+
|
|
6196
|
+
.temp-range-tooltip__ruler-marker {
|
|
6197
|
+
position: absolute;
|
|
6198
|
+
top: 4px;
|
|
6199
|
+
width: 4px;
|
|
6200
|
+
height: 24px;
|
|
6201
|
+
background: #1e293b;
|
|
6202
|
+
border-radius: 2px;
|
|
6203
|
+
transform: translateX(-50%);
|
|
6204
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
6205
|
+
}
|
|
6206
|
+
|
|
6207
|
+
.temp-range-tooltip__ruler-marker::after {
|
|
6208
|
+
content: '';
|
|
6209
|
+
position: absolute;
|
|
6210
|
+
top: -4px;
|
|
6211
|
+
left: 50%;
|
|
6212
|
+
transform: translateX(-50%);
|
|
6213
|
+
width: 12px;
|
|
6214
|
+
height: 12px;
|
|
6215
|
+
background: #1e293b;
|
|
6216
|
+
border-radius: 50%;
|
|
6217
|
+
border: 2px solid #fff;
|
|
6218
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
6219
|
+
}
|
|
6220
|
+
|
|
6221
|
+
.temp-range-tooltip__ruler-labels {
|
|
6222
|
+
display: flex;
|
|
6223
|
+
justify-content: space-between;
|
|
6224
|
+
margin-top: 8px;
|
|
6225
|
+
font-size: 10px;
|
|
6226
|
+
color: #64748b;
|
|
6227
|
+
}
|
|
6228
|
+
|
|
6229
|
+
.temp-range-tooltip__ruler-min,
|
|
6230
|
+
.temp-range-tooltip__ruler-max {
|
|
6231
|
+
font-weight: 600;
|
|
6232
|
+
}
|
|
6233
|
+
|
|
6234
|
+
.temp-range-tooltip__range-info {
|
|
6235
|
+
display: flex;
|
|
6236
|
+
justify-content: space-between;
|
|
6237
|
+
padding: 10px 12px;
|
|
6238
|
+
background: #f8fafc;
|
|
6239
|
+
border-radius: 8px;
|
|
6240
|
+
margin-top: 12px;
|
|
6241
|
+
}
|
|
6242
|
+
|
|
6243
|
+
.temp-range-tooltip__range-item {
|
|
6244
|
+
text-align: center;
|
|
6245
|
+
}
|
|
6246
|
+
|
|
6247
|
+
.temp-range-tooltip__range-label {
|
|
6248
|
+
font-size: 10px;
|
|
6249
|
+
color: #64748b;
|
|
6250
|
+
text-transform: uppercase;
|
|
6251
|
+
letter-spacing: 0.3px;
|
|
6252
|
+
margin-bottom: 2px;
|
|
6253
|
+
}
|
|
6254
|
+
|
|
6255
|
+
.temp-range-tooltip__range-value {
|
|
6256
|
+
font-size: 14px;
|
|
6257
|
+
font-weight: 600;
|
|
6258
|
+
color: #334155;
|
|
6259
|
+
}
|
|
6260
|
+
|
|
6261
|
+
.temp-range-tooltip__status {
|
|
6262
|
+
display: flex;
|
|
6263
|
+
align-items: center;
|
|
6264
|
+
justify-content: center;
|
|
6265
|
+
gap: 6px;
|
|
6266
|
+
margin-top: 12px;
|
|
6267
|
+
padding: 8px 12px;
|
|
6268
|
+
border-radius: 6px;
|
|
6269
|
+
font-size: 11px;
|
|
6270
|
+
font-weight: 600;
|
|
6271
|
+
}
|
|
6272
|
+
|
|
6273
|
+
.temp-range-tooltip__status.cold {
|
|
6274
|
+
background: #dbeafe;
|
|
6275
|
+
color: #1d4ed8;
|
|
6276
|
+
border: 1px solid #93c5fd;
|
|
6277
|
+
}
|
|
6278
|
+
|
|
6279
|
+
.temp-range-tooltip__status.ok {
|
|
6280
|
+
background: #dcfce7;
|
|
6281
|
+
color: #15803d;
|
|
6282
|
+
border: 1px solid #86efac;
|
|
6283
|
+
}
|
|
6284
|
+
|
|
6285
|
+
.temp-range-tooltip__status.hot {
|
|
6286
|
+
background: #fee2e2;
|
|
6287
|
+
color: #b91c1c;
|
|
6288
|
+
border: 1px solid #fca5a5;
|
|
6289
|
+
}
|
|
6290
|
+
|
|
6291
|
+
.temp-range-tooltip__status.unknown {
|
|
6292
|
+
background: #f3f4f6;
|
|
6293
|
+
color: #6b7280;
|
|
6294
|
+
border: 1px solid #d1d5db;
|
|
6295
|
+
}
|
|
6296
|
+
`;
|
|
6297
|
+
function injectStyles() {
|
|
6298
|
+
if (typeof document === "undefined") return;
|
|
6299
|
+
const styleId = "myio-temp-range-tooltip-styles";
|
|
6300
|
+
if (document.getElementById(styleId)) return;
|
|
6301
|
+
const style = document.createElement("style");
|
|
6302
|
+
style.id = styleId;
|
|
6303
|
+
style.textContent = TOOLTIP_STYLES;
|
|
6304
|
+
document.head.appendChild(style);
|
|
6305
|
+
}
|
|
6306
|
+
function extractTemperature(entityData) {
|
|
6307
|
+
return Number(entityData.val ?? entityData.currentTemperature ?? entityData.temperature) || 0;
|
|
6308
|
+
}
|
|
6309
|
+
function extractRange(entityData) {
|
|
6310
|
+
const tempMin = entityData.temperatureMin ?? entityData.minTemperature ?? null;
|
|
6311
|
+
const tempMax = entityData.temperatureMax ?? entityData.maxTemperature ?? null;
|
|
6312
|
+
return { tempMin, tempMax };
|
|
6313
|
+
}
|
|
6314
|
+
function extractLabel(entityData) {
|
|
6315
|
+
return entityData.labelOrName || entityData.name || entityData.label || "Sensor";
|
|
6316
|
+
}
|
|
6317
|
+
var TempRangeTooltip = {
|
|
6318
|
+
containerId: "myio-temp-range-tooltip",
|
|
6319
|
+
/**
|
|
6320
|
+
* Create or get the tooltip container
|
|
6321
|
+
*/
|
|
6322
|
+
getContainer() {
|
|
6323
|
+
injectStyles();
|
|
6324
|
+
let container = document.getElementById(this.containerId);
|
|
6325
|
+
if (!container) {
|
|
6326
|
+
container = document.createElement("div");
|
|
6327
|
+
container.id = this.containerId;
|
|
6328
|
+
container.className = "temp-range-tooltip";
|
|
6329
|
+
document.body.appendChild(container);
|
|
6330
|
+
}
|
|
6331
|
+
return container;
|
|
6332
|
+
},
|
|
6333
|
+
/**
|
|
6334
|
+
* Calculate temperature status and deviation
|
|
6335
|
+
*/
|
|
6336
|
+
calculateStatus(currentTemp, tempMin, tempMax) {
|
|
6337
|
+
if (tempMin == null || tempMax == null) {
|
|
6338
|
+
return { status: "unknown", deviation: null, deviationPercent: null };
|
|
6339
|
+
}
|
|
6340
|
+
const rangeSize = tempMax - tempMin;
|
|
6341
|
+
const midPoint = (tempMin + tempMax) / 2;
|
|
6342
|
+
if (currentTemp < tempMin) {
|
|
6343
|
+
const deviation = tempMin - currentTemp;
|
|
6344
|
+
const deviationPercent = rangeSize > 0 ? deviation / rangeSize * 100 : 0;
|
|
6345
|
+
return { status: "cold", deviation: -deviation, deviationPercent: -deviationPercent };
|
|
6275
6346
|
} else if (currentTemp > tempMax) {
|
|
6276
6347
|
const deviation = currentTemp - tempMax;
|
|
6277
6348
|
const deviationPercent = rangeSize > 0 ? deviation / rangeSize * 100 : 0;
|
|
@@ -6299,20 +6370,20 @@ var TempRangeTooltip = {
|
|
|
6299
6370
|
},
|
|
6300
6371
|
/**
|
|
6301
6372
|
* Show tooltip for a temperature card
|
|
6302
|
-
* @param
|
|
6303
|
-
* @param
|
|
6304
|
-
* @param
|
|
6373
|
+
* @param triggerElement - The card element
|
|
6374
|
+
* @param entityData - Entity data with temperature info
|
|
6375
|
+
* @param event - Mouse event for cursor position
|
|
6305
6376
|
*/
|
|
6306
|
-
show(triggerElement,
|
|
6377
|
+
show(triggerElement, entityData, event) {
|
|
6307
6378
|
const container = this.getContainer();
|
|
6308
|
-
const currentTemp =
|
|
6309
|
-
const tempMin
|
|
6310
|
-
const
|
|
6379
|
+
const currentTemp = extractTemperature(entityData);
|
|
6380
|
+
const { tempMin, tempMax } = extractRange(entityData);
|
|
6381
|
+
const label = extractLabel(entityData);
|
|
6311
6382
|
const hasRange = tempMin != null && tempMax != null;
|
|
6312
|
-
const { status,
|
|
6383
|
+
const { status, deviationPercent } = this.calculateStatus(currentTemp, tempMin, tempMax);
|
|
6313
6384
|
const markerPos = this.calculateMarkerPosition(currentTemp, tempMin, tempMax);
|
|
6314
6385
|
let rangeLeft = 0, rangeWidth = 100;
|
|
6315
|
-
if (hasRange) {
|
|
6386
|
+
if (hasRange && tempMin != null && tempMax != null) {
|
|
6316
6387
|
const rangeSize = tempMax - tempMin;
|
|
6317
6388
|
const extension = rangeSize * 0.3;
|
|
6318
6389
|
const visibleMin = tempMin - extension;
|
|
@@ -6321,28 +6392,23 @@ var TempRangeTooltip = {
|
|
|
6321
6392
|
rangeLeft = (tempMin - visibleMin) / visibleRange * 100;
|
|
6322
6393
|
rangeWidth = rangeSize / visibleRange * 100;
|
|
6323
6394
|
}
|
|
6324
|
-
let deviationText = "";
|
|
6325
|
-
let deviationClass = status;
|
|
6326
|
-
if (status === "cold") {
|
|
6327
|
-
deviationText = `${Math.abs(deviation).toFixed(1)}\xB0C abaixo`;
|
|
6328
|
-
} else if (status === "hot") {
|
|
6329
|
-
deviationText = `+${deviation.toFixed(1)}\xB0C acima`;
|
|
6330
|
-
} else if (status === "ok") {
|
|
6331
|
-
deviationText = "Na faixa ideal";
|
|
6332
|
-
} else {
|
|
6333
|
-
deviationText = "Faixa n\xE3o configurada";
|
|
6334
|
-
}
|
|
6335
6395
|
const statusLabels = {
|
|
6336
6396
|
cold: "\u2744\uFE0F Abaixo da Faixa Ideal",
|
|
6337
6397
|
ok: "\u2714\uFE0F Dentro da Faixa Ideal",
|
|
6338
6398
|
hot: "\u{1F525} Acima da Faixa Ideal",
|
|
6339
6399
|
unknown: "\u2753 Faixa N\xE3o Configurada"
|
|
6340
6400
|
};
|
|
6401
|
+
const statusColors = {
|
|
6402
|
+
cold: "#2563eb",
|
|
6403
|
+
ok: "#16a34a",
|
|
6404
|
+
hot: "#dc2626",
|
|
6405
|
+
unknown: "#64748b"
|
|
6406
|
+
};
|
|
6341
6407
|
container.innerHTML = `
|
|
6342
6408
|
<div class="temp-range-tooltip__content">
|
|
6343
6409
|
<div class="temp-range-tooltip__header">
|
|
6344
6410
|
<span class="temp-range-tooltip__icon">\u{1F321}\uFE0F</span>
|
|
6345
|
-
<span class="temp-range-tooltip__title">${
|
|
6411
|
+
<span class="temp-range-tooltip__title">${label}</span>
|
|
6346
6412
|
</div>
|
|
6347
6413
|
<div class="temp-range-tooltip__body">
|
|
6348
6414
|
<div class="temp-range-tooltip__value-row">
|
|
@@ -6350,7 +6416,7 @@ var TempRangeTooltip = {
|
|
|
6350
6416
|
${currentTemp.toFixed(1)}<sup>\xB0C</sup>
|
|
6351
6417
|
</div>
|
|
6352
6418
|
<div class="temp-range-tooltip__deviation">
|
|
6353
|
-
<div class="temp-range-tooltip__deviation-value ${
|
|
6419
|
+
<div class="temp-range-tooltip__deviation-value ${status}">
|
|
6354
6420
|
${status === "ok" ? "\u2713" : status === "cold" ? "\u2193" : status === "hot" ? "\u2191" : "?"} ${Math.abs(deviationPercent || 0).toFixed(0)}%
|
|
6355
6421
|
</div>
|
|
6356
6422
|
<div class="temp-range-tooltip__deviation-label">Desvio</div>
|
|
@@ -6377,7 +6443,7 @@ var TempRangeTooltip = {
|
|
|
6377
6443
|
</div>
|
|
6378
6444
|
<div class="temp-range-tooltip__range-item">
|
|
6379
6445
|
<div class="temp-range-tooltip__range-label">Atual</div>
|
|
6380
|
-
<div class="temp-range-tooltip__range-value" style="color: ${status
|
|
6446
|
+
<div class="temp-range-tooltip__range-value" style="color: ${statusColors[status]}">${currentTemp.toFixed(1)}\xB0C</div>
|
|
6381
6447
|
</div>
|
|
6382
6448
|
<div class="temp-range-tooltip__range-item">
|
|
6383
6449
|
<div class="temp-range-tooltip__range-label">M\xE1ximo</div>
|
|
@@ -6422,7 +6488,320 @@ var TempRangeTooltip = {
|
|
|
6422
6488
|
if (container) {
|
|
6423
6489
|
container.classList.remove("visible");
|
|
6424
6490
|
}
|
|
6491
|
+
},
|
|
6492
|
+
/**
|
|
6493
|
+
* Attach tooltip to an element
|
|
6494
|
+
* Returns cleanup function
|
|
6495
|
+
*/
|
|
6496
|
+
attach(element, entityData) {
|
|
6497
|
+
const showHandler = (e) => this.show(element, entityData, e);
|
|
6498
|
+
const hideHandler = () => this.hide();
|
|
6499
|
+
element.style.cursor = "help";
|
|
6500
|
+
element.addEventListener("mouseenter", showHandler);
|
|
6501
|
+
element.addEventListener("mouseleave", hideHandler);
|
|
6502
|
+
return () => {
|
|
6503
|
+
element.removeEventListener("mouseenter", showHandler);
|
|
6504
|
+
element.removeEventListener("mouseleave", hideHandler);
|
|
6505
|
+
element.style.cursor = "";
|
|
6506
|
+
this.hide();
|
|
6507
|
+
};
|
|
6508
|
+
}
|
|
6509
|
+
};
|
|
6510
|
+
|
|
6511
|
+
// src/utils/EnergyRangeTooltip.ts
|
|
6512
|
+
var ENERGY_RANGE_TOOLTIP_CSS = `
|
|
6513
|
+
/* ============================================
|
|
6514
|
+
Energy Range Tooltip (for domain=energy)
|
|
6515
|
+
Shows power ruler with current position and status ranges
|
|
6516
|
+
============================================ */
|
|
6517
|
+
.energy-range-tooltip {
|
|
6518
|
+
position: fixed;
|
|
6519
|
+
z-index: 99999;
|
|
6520
|
+
pointer-events: none;
|
|
6521
|
+
opacity: 0;
|
|
6522
|
+
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
6523
|
+
transform: translateY(5px);
|
|
6524
|
+
}
|
|
6525
|
+
|
|
6526
|
+
.energy-range-tooltip.visible {
|
|
6527
|
+
opacity: 1;
|
|
6528
|
+
pointer-events: auto;
|
|
6529
|
+
transform: translateY(0);
|
|
6530
|
+
}
|
|
6531
|
+
|
|
6532
|
+
.energy-range-tooltip__content {
|
|
6533
|
+
background: #ffffff;
|
|
6534
|
+
border: 1px solid #e2e8f0;
|
|
6535
|
+
border-radius: 12px;
|
|
6536
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15), 0 2px 10px rgba(0, 0, 0, 0.08);
|
|
6537
|
+
min-width: 300px;
|
|
6538
|
+
max-width: 360px;
|
|
6539
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
6540
|
+
font-size: 12px;
|
|
6541
|
+
color: #1e293b;
|
|
6542
|
+
overflow: hidden;
|
|
6543
|
+
}
|
|
6544
|
+
|
|
6545
|
+
.energy-range-tooltip__header {
|
|
6546
|
+
display: flex;
|
|
6547
|
+
align-items: center;
|
|
6548
|
+
gap: 8px;
|
|
6549
|
+
padding: 12px 16px;
|
|
6550
|
+
background: linear-gradient(90deg, #ecfdf5 0%, #d1fae5 100%);
|
|
6551
|
+
border-bottom: 1px solid #6ee7b7;
|
|
6552
|
+
}
|
|
6553
|
+
|
|
6554
|
+
.energy-range-tooltip__icon {
|
|
6555
|
+
font-size: 18px;
|
|
6556
|
+
}
|
|
6557
|
+
|
|
6558
|
+
.energy-range-tooltip__title {
|
|
6559
|
+
font-weight: 700;
|
|
6560
|
+
font-size: 13px;
|
|
6561
|
+
color: #047857;
|
|
6562
|
+
}
|
|
6563
|
+
|
|
6564
|
+
.energy-range-tooltip__body {
|
|
6565
|
+
padding: 16px;
|
|
6566
|
+
}
|
|
6567
|
+
|
|
6568
|
+
/* Power value display */
|
|
6569
|
+
.energy-range-tooltip__value-row {
|
|
6570
|
+
display: flex;
|
|
6571
|
+
justify-content: space-between;
|
|
6572
|
+
align-items: center;
|
|
6573
|
+
margin-bottom: 16px;
|
|
6574
|
+
}
|
|
6575
|
+
|
|
6576
|
+
.energy-range-tooltip__current {
|
|
6577
|
+
font-size: 28px;
|
|
6578
|
+
font-weight: 700;
|
|
6579
|
+
color: #1e293b;
|
|
6580
|
+
}
|
|
6581
|
+
|
|
6582
|
+
.energy-range-tooltip__current sup {
|
|
6583
|
+
font-size: 14px;
|
|
6584
|
+
color: #64748b;
|
|
6585
|
+
}
|
|
6586
|
+
|
|
6587
|
+
.energy-range-tooltip__status-badge {
|
|
6588
|
+
text-align: right;
|
|
6589
|
+
}
|
|
6590
|
+
|
|
6591
|
+
.energy-range-tooltip__status-value {
|
|
6592
|
+
font-size: 14px;
|
|
6593
|
+
font-weight: 700;
|
|
6594
|
+
padding: 4px 10px;
|
|
6595
|
+
border-radius: 6px;
|
|
6596
|
+
}
|
|
6597
|
+
|
|
6598
|
+
.energy-range-tooltip__status-value.standby {
|
|
6599
|
+
background: #dbeafe;
|
|
6600
|
+
color: #1d4ed8;
|
|
6601
|
+
}
|
|
6602
|
+
|
|
6603
|
+
.energy-range-tooltip__status-value.normal {
|
|
6604
|
+
background: #dcfce7;
|
|
6605
|
+
color: #15803d;
|
|
6606
|
+
}
|
|
6607
|
+
|
|
6608
|
+
.energy-range-tooltip__status-value.alert {
|
|
6609
|
+
background: #fef3c7;
|
|
6610
|
+
color: #b45309;
|
|
6611
|
+
}
|
|
6612
|
+
|
|
6613
|
+
.energy-range-tooltip__status-value.failure {
|
|
6614
|
+
background: #fee2e2;
|
|
6615
|
+
color: #b91c1c;
|
|
6616
|
+
}
|
|
6617
|
+
|
|
6618
|
+
.energy-range-tooltip__status-value.offline {
|
|
6619
|
+
background: #f3f4f6;
|
|
6620
|
+
color: #6b7280;
|
|
6621
|
+
}
|
|
6622
|
+
|
|
6623
|
+
/* Power ruler/gauge */
|
|
6624
|
+
.energy-range-tooltip__ruler {
|
|
6625
|
+
position: relative;
|
|
6626
|
+
height: 40px;
|
|
6627
|
+
margin: 12px 0;
|
|
6628
|
+
border-radius: 8px;
|
|
6629
|
+
overflow: visible;
|
|
6630
|
+
}
|
|
6631
|
+
|
|
6632
|
+
.energy-range-tooltip__ruler-track {
|
|
6633
|
+
position: absolute;
|
|
6634
|
+
top: 16px;
|
|
6635
|
+
left: 0;
|
|
6636
|
+
right: 0;
|
|
6637
|
+
height: 8px;
|
|
6638
|
+
display: flex;
|
|
6639
|
+
border-radius: 4px;
|
|
6640
|
+
overflow: hidden;
|
|
6641
|
+
border: 1px solid #e2e8f0;
|
|
6642
|
+
}
|
|
6643
|
+
|
|
6644
|
+
.energy-range-tooltip__ruler-segment {
|
|
6645
|
+
height: 100%;
|
|
6646
|
+
}
|
|
6647
|
+
|
|
6648
|
+
.energy-range-tooltip__ruler-segment.standby {
|
|
6649
|
+
background: #dbeafe;
|
|
6650
|
+
}
|
|
6651
|
+
|
|
6652
|
+
.energy-range-tooltip__ruler-segment.normal {
|
|
6653
|
+
background: #dcfce7;
|
|
6654
|
+
}
|
|
6655
|
+
|
|
6656
|
+
.energy-range-tooltip__ruler-segment.alert {
|
|
6657
|
+
background: #fef3c7;
|
|
6658
|
+
}
|
|
6659
|
+
|
|
6660
|
+
.energy-range-tooltip__ruler-segment.failure {
|
|
6661
|
+
background: #fee2e2;
|
|
6662
|
+
}
|
|
6663
|
+
|
|
6664
|
+
.energy-range-tooltip__ruler-marker {
|
|
6665
|
+
position: absolute;
|
|
6666
|
+
top: 8px;
|
|
6667
|
+
width: 4px;
|
|
6668
|
+
height: 24px;
|
|
6669
|
+
background: #1e293b;
|
|
6670
|
+
border-radius: 2px;
|
|
6671
|
+
transform: translateX(-50%);
|
|
6672
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
6673
|
+
}
|
|
6674
|
+
|
|
6675
|
+
.energy-range-tooltip__ruler-marker::after {
|
|
6676
|
+
content: '';
|
|
6677
|
+
position: absolute;
|
|
6678
|
+
top: -4px;
|
|
6679
|
+
left: 50%;
|
|
6680
|
+
transform: translateX(-50%);
|
|
6681
|
+
width: 12px;
|
|
6682
|
+
height: 12px;
|
|
6683
|
+
background: #1e293b;
|
|
6684
|
+
border-radius: 50%;
|
|
6685
|
+
border: 2px solid #fff;
|
|
6686
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
6687
|
+
}
|
|
6688
|
+
|
|
6689
|
+
/* Range info grid */
|
|
6690
|
+
.energy-range-tooltip__ranges {
|
|
6691
|
+
display: grid;
|
|
6692
|
+
grid-template-columns: repeat(4, 1fr);
|
|
6693
|
+
gap: 8px;
|
|
6694
|
+
margin-top: 16px;
|
|
6695
|
+
}
|
|
6696
|
+
|
|
6697
|
+
.energy-range-tooltip__range-item {
|
|
6698
|
+
text-align: center;
|
|
6699
|
+
padding: 8px 4px;
|
|
6700
|
+
border-radius: 6px;
|
|
6701
|
+
background: #f8fafc;
|
|
6702
|
+
}
|
|
6703
|
+
|
|
6704
|
+
.energy-range-tooltip__range-item.standby {
|
|
6705
|
+
border-left: 3px solid #3b82f6;
|
|
6706
|
+
}
|
|
6707
|
+
|
|
6708
|
+
.energy-range-tooltip__range-item.normal {
|
|
6709
|
+
border-left: 3px solid #22c55e;
|
|
6710
|
+
}
|
|
6711
|
+
|
|
6712
|
+
.energy-range-tooltip__range-item.alert {
|
|
6713
|
+
border-left: 3px solid #f59e0b;
|
|
6714
|
+
}
|
|
6715
|
+
|
|
6716
|
+
.energy-range-tooltip__range-item.failure {
|
|
6717
|
+
border-left: 3px solid #ef4444;
|
|
6718
|
+
}
|
|
6719
|
+
|
|
6720
|
+
.energy-range-tooltip__range-label {
|
|
6721
|
+
font-size: 9px;
|
|
6722
|
+
color: #64748b;
|
|
6723
|
+
text-transform: uppercase;
|
|
6724
|
+
letter-spacing: 0.3px;
|
|
6725
|
+
margin-bottom: 2px;
|
|
6726
|
+
}
|
|
6727
|
+
|
|
6728
|
+
.energy-range-tooltip__range-value {
|
|
6729
|
+
font-size: 11px;
|
|
6730
|
+
font-weight: 600;
|
|
6731
|
+
color: #334155;
|
|
6732
|
+
}
|
|
6733
|
+
|
|
6734
|
+
/* Status info */
|
|
6735
|
+
.energy-range-tooltip__status-info {
|
|
6736
|
+
display: flex;
|
|
6737
|
+
align-items: center;
|
|
6738
|
+
justify-content: center;
|
|
6739
|
+
gap: 6px;
|
|
6740
|
+
margin-top: 12px;
|
|
6741
|
+
padding: 8px 12px;
|
|
6742
|
+
border-radius: 6px;
|
|
6743
|
+
font-size: 11px;
|
|
6744
|
+
font-weight: 600;
|
|
6745
|
+
}
|
|
6746
|
+
|
|
6747
|
+
.energy-range-tooltip__status-info.standby {
|
|
6748
|
+
background: #dbeafe;
|
|
6749
|
+
color: #1d4ed8;
|
|
6750
|
+
border: 1px solid #93c5fd;
|
|
6751
|
+
}
|
|
6752
|
+
|
|
6753
|
+
.energy-range-tooltip__status-info.normal {
|
|
6754
|
+
background: #dcfce7;
|
|
6755
|
+
color: #15803d;
|
|
6756
|
+
border: 1px solid #86efac;
|
|
6757
|
+
}
|
|
6758
|
+
|
|
6759
|
+
.energy-range-tooltip__status-info.alert {
|
|
6760
|
+
background: #fef3c7;
|
|
6761
|
+
color: #b45309;
|
|
6762
|
+
border: 1px solid #fcd34d;
|
|
6763
|
+
}
|
|
6764
|
+
|
|
6765
|
+
.energy-range-tooltip__status-info.failure {
|
|
6766
|
+
background: #fee2e2;
|
|
6767
|
+
color: #b91c1c;
|
|
6768
|
+
border: 1px solid #fca5a5;
|
|
6769
|
+
}
|
|
6770
|
+
|
|
6771
|
+
.energy-range-tooltip__status-info.offline {
|
|
6772
|
+
background: #f3f4f6;
|
|
6773
|
+
color: #6b7280;
|
|
6774
|
+
border: 1px solid #d1d5db;
|
|
6775
|
+
}
|
|
6776
|
+
`;
|
|
6777
|
+
var cssInjected = false;
|
|
6778
|
+
function injectCSS() {
|
|
6779
|
+
if (cssInjected) return;
|
|
6780
|
+
if (typeof document === "undefined") return;
|
|
6781
|
+
const styleId = "myio-energy-range-tooltip-styles";
|
|
6782
|
+
if (document.getElementById(styleId)) {
|
|
6783
|
+
cssInjected = true;
|
|
6784
|
+
return;
|
|
6425
6785
|
}
|
|
6786
|
+
const style = document.createElement("style");
|
|
6787
|
+
style.id = styleId;
|
|
6788
|
+
style.textContent = ENERGY_RANGE_TOOLTIP_CSS;
|
|
6789
|
+
document.head.appendChild(style);
|
|
6790
|
+
cssInjected = true;
|
|
6791
|
+
}
|
|
6792
|
+
var STATUS_LABELS = {
|
|
6793
|
+
standby: "Standby",
|
|
6794
|
+
normal: "Operacao Normal",
|
|
6795
|
+
alert: "Alerta",
|
|
6796
|
+
failure: "Falha",
|
|
6797
|
+
offline: "Fora da faixa"
|
|
6798
|
+
};
|
|
6799
|
+
var STATUS_INFO_LABELS = {
|
|
6800
|
+
standby: "\u{1F535} Standby",
|
|
6801
|
+
normal: "\u2705 Operacao Normal",
|
|
6802
|
+
alert: "\u26A0\uFE0F Alerta",
|
|
6803
|
+
failure: "\u{1F534} Falha",
|
|
6804
|
+
offline: "\u26AB Offline / Sem dados"
|
|
6426
6805
|
};
|
|
6427
6806
|
var EnergyRangeTooltip = {
|
|
6428
6807
|
containerId: "myio-energy-range-tooltip",
|
|
@@ -6430,6 +6809,7 @@ var EnergyRangeTooltip = {
|
|
|
6430
6809
|
* Create or get the tooltip container
|
|
6431
6810
|
*/
|
|
6432
6811
|
getContainer() {
|
|
6812
|
+
injectCSS();
|
|
6433
6813
|
let container = document.getElementById(this.containerId);
|
|
6434
6814
|
if (!container) {
|
|
6435
6815
|
container = document.createElement("div");
|
|
@@ -6449,18 +6829,18 @@ var EnergyRangeTooltip = {
|
|
|
6449
6829
|
const power = Number(powerValue) || 0;
|
|
6450
6830
|
const { standbyRange, normalRange, alertRange, failureRange } = ranges;
|
|
6451
6831
|
if (standbyRange && power >= standbyRange.down && power <= standbyRange.up) {
|
|
6452
|
-
return { status: "standby", label:
|
|
6832
|
+
return { status: "standby", label: STATUS_LABELS.standby };
|
|
6453
6833
|
}
|
|
6454
6834
|
if (normalRange && power >= normalRange.down && power <= normalRange.up) {
|
|
6455
|
-
return { status: "normal", label:
|
|
6835
|
+
return { status: "normal", label: STATUS_LABELS.normal };
|
|
6456
6836
|
}
|
|
6457
6837
|
if (alertRange && power >= alertRange.down && power <= alertRange.up) {
|
|
6458
|
-
return { status: "alert", label:
|
|
6838
|
+
return { status: "alert", label: STATUS_LABELS.alert };
|
|
6459
6839
|
}
|
|
6460
6840
|
if (failureRange && power >= failureRange.down && power <= failureRange.up) {
|
|
6461
|
-
return { status: "failure", label:
|
|
6841
|
+
return { status: "failure", label: STATUS_LABELS.failure };
|
|
6462
6842
|
}
|
|
6463
|
-
return { status: "offline", label:
|
|
6843
|
+
return { status: "offline", label: STATUS_LABELS.offline };
|
|
6464
6844
|
},
|
|
6465
6845
|
/**
|
|
6466
6846
|
* Calculate marker position on ruler (0-100%)
|
|
@@ -6491,7 +6871,7 @@ var EnergyRangeTooltip = {
|
|
|
6491
6871
|
* Format power value for display
|
|
6492
6872
|
*/
|
|
6493
6873
|
formatPower(value) {
|
|
6494
|
-
if (value == null || isNaN(value)) return "-";
|
|
6874
|
+
if (value == null || isNaN(Number(value))) return "-";
|
|
6495
6875
|
const num = Number(value);
|
|
6496
6876
|
if (num >= 1e3) {
|
|
6497
6877
|
return `${(num / 1e3).toFixed(2)} kW`;
|
|
@@ -6509,13 +6889,40 @@ var EnergyRangeTooltip = {
|
|
|
6509
6889
|
const { status, label } = this.calculateStatus(powerValue, ranges);
|
|
6510
6890
|
const markerPos = this.calculateMarkerPosition(powerValue, ranges);
|
|
6511
6891
|
const segmentWidths = this.calculateSegmentWidths(ranges);
|
|
6512
|
-
const
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6892
|
+
const rangesHtml = hasRanges && ranges ? `
|
|
6893
|
+
<div class="energy-range-tooltip__ruler">
|
|
6894
|
+
<div class="energy-range-tooltip__ruler-track">
|
|
6895
|
+
<div class="energy-range-tooltip__ruler-segment standby" style="width: ${segmentWidths.standby}%"></div>
|
|
6896
|
+
<div class="energy-range-tooltip__ruler-segment normal" style="width: ${segmentWidths.normal}%"></div>
|
|
6897
|
+
<div class="energy-range-tooltip__ruler-segment alert" style="width: ${segmentWidths.alert}%"></div>
|
|
6898
|
+
<div class="energy-range-tooltip__ruler-segment failure" style="width: ${segmentWidths.failure}%"></div>
|
|
6899
|
+
</div>
|
|
6900
|
+
<div class="energy-range-tooltip__ruler-marker" style="left: ${markerPos}%;"></div>
|
|
6901
|
+
</div>
|
|
6902
|
+
|
|
6903
|
+
<div class="energy-range-tooltip__ranges">
|
|
6904
|
+
<div class="energy-range-tooltip__range-item standby">
|
|
6905
|
+
<div class="energy-range-tooltip__range-label">Standby</div>
|
|
6906
|
+
<div class="energy-range-tooltip__range-value">${ranges.standbyRange?.down || 0}-${ranges.standbyRange?.up || 0}W</div>
|
|
6907
|
+
</div>
|
|
6908
|
+
<div class="energy-range-tooltip__range-item normal">
|
|
6909
|
+
<div class="energy-range-tooltip__range-label">Normal</div>
|
|
6910
|
+
<div class="energy-range-tooltip__range-value">${ranges.normalRange?.down || 0}-${ranges.normalRange?.up || 0}W</div>
|
|
6911
|
+
</div>
|
|
6912
|
+
<div class="energy-range-tooltip__range-item alert">
|
|
6913
|
+
<div class="energy-range-tooltip__range-label">Alerta</div>
|
|
6914
|
+
<div class="energy-range-tooltip__range-value">${ranges.alertRange?.down || 0}-${ranges.alertRange?.up || 0}W</div>
|
|
6915
|
+
</div>
|
|
6916
|
+
<div class="energy-range-tooltip__range-item failure">
|
|
6917
|
+
<div class="energy-range-tooltip__range-label">Falha</div>
|
|
6918
|
+
<div class="energy-range-tooltip__range-value">>${ranges.failureRange?.down || 0}W</div>
|
|
6919
|
+
</div>
|
|
6920
|
+
</div>
|
|
6921
|
+
` : `
|
|
6922
|
+
<div style="text-align: center; padding: 16px; color: #64748b; font-size: 12px;">
|
|
6923
|
+
Ranges de potencia nao configurados
|
|
6924
|
+
</div>
|
|
6925
|
+
`;
|
|
6519
6926
|
container.innerHTML = `
|
|
6520
6927
|
<div class="energy-range-tooltip__content">
|
|
6521
6928
|
<div class="energy-range-tooltip__header">
|
|
@@ -6532,51 +6939,18 @@ var EnergyRangeTooltip = {
|
|
|
6532
6939
|
</div>
|
|
6533
6940
|
</div>
|
|
6534
6941
|
|
|
6535
|
-
${
|
|
6536
|
-
<div class="energy-range-tooltip__ruler">
|
|
6537
|
-
<div class="energy-range-tooltip__ruler-track">
|
|
6538
|
-
<div class="energy-range-tooltip__ruler-segment standby" style="width: ${segmentWidths.standby}%"></div>
|
|
6539
|
-
<div class="energy-range-tooltip__ruler-segment normal" style="width: ${segmentWidths.normal}%"></div>
|
|
6540
|
-
<div class="energy-range-tooltip__ruler-segment alert" style="width: ${segmentWidths.alert}%"></div>
|
|
6541
|
-
<div class="energy-range-tooltip__ruler-segment failure" style="width: ${segmentWidths.failure}%"></div>
|
|
6542
|
-
</div>
|
|
6543
|
-
<div class="energy-range-tooltip__ruler-marker" style="left: ${markerPos}%;"></div>
|
|
6544
|
-
</div>
|
|
6545
|
-
|
|
6546
|
-
<div class="energy-range-tooltip__ranges">
|
|
6547
|
-
<div class="energy-range-tooltip__range-item standby">
|
|
6548
|
-
<div class="energy-range-tooltip__range-label">Standby</div>
|
|
6549
|
-
<div class="energy-range-tooltip__range-value">${ranges.standbyRange?.down || 0}-${ranges.standbyRange?.up || 0}W</div>
|
|
6550
|
-
</div>
|
|
6551
|
-
<div class="energy-range-tooltip__range-item normal">
|
|
6552
|
-
<div class="energy-range-tooltip__range-label">Normal</div>
|
|
6553
|
-
<div class="energy-range-tooltip__range-value">${ranges.normalRange?.down || 0}-${ranges.normalRange?.up || 0}W</div>
|
|
6554
|
-
</div>
|
|
6555
|
-
<div class="energy-range-tooltip__range-item alert">
|
|
6556
|
-
<div class="energy-range-tooltip__range-label">Alerta</div>
|
|
6557
|
-
<div class="energy-range-tooltip__range-value">${ranges.alertRange?.down || 0}-${ranges.alertRange?.up || 0}W</div>
|
|
6558
|
-
</div>
|
|
6559
|
-
<div class="energy-range-tooltip__range-item failure">
|
|
6560
|
-
<div class="energy-range-tooltip__range-label">Falha</div>
|
|
6561
|
-
<div class="energy-range-tooltip__range-value">>${ranges.failureRange?.down || 0}W</div>
|
|
6562
|
-
</div>
|
|
6563
|
-
</div>
|
|
6564
|
-
` : `
|
|
6565
|
-
<div style="text-align: center; padding: 16px; color: #64748b; font-size: 12px;">
|
|
6566
|
-
Ranges de pot\xEAncia n\xE3o configurados
|
|
6567
|
-
</div>
|
|
6568
|
-
`}
|
|
6942
|
+
${rangesHtml}
|
|
6569
6943
|
|
|
6570
6944
|
<div class="energy-range-tooltip__status-info ${status}">
|
|
6571
|
-
${
|
|
6945
|
+
${STATUS_INFO_LABELS[status] || STATUS_INFO_LABELS.offline}
|
|
6572
6946
|
</div>
|
|
6573
6947
|
</div>
|
|
6574
6948
|
</div>
|
|
6575
6949
|
`;
|
|
6576
6950
|
let left, top;
|
|
6577
6951
|
if (event && event.clientX && event.clientY) {
|
|
6578
|
-
left = event.clientX +
|
|
6579
|
-
top = event.clientY +
|
|
6952
|
+
left = event.clientX + 8;
|
|
6953
|
+
top = event.clientY + 8;
|
|
6580
6954
|
} else {
|
|
6581
6955
|
const rect = triggerElement.getBoundingClientRect();
|
|
6582
6956
|
left = rect.left + rect.width / 2 - 150;
|
|
@@ -6585,11 +6959,11 @@ var EnergyRangeTooltip = {
|
|
|
6585
6959
|
const tooltipWidth = 320;
|
|
6586
6960
|
const tooltipHeight = 380;
|
|
6587
6961
|
if (left + tooltipWidth > window.innerWidth - 10) {
|
|
6588
|
-
left = (event?.clientX || left) - tooltipWidth -
|
|
6962
|
+
left = (event?.clientX || left) - tooltipWidth - 8;
|
|
6589
6963
|
}
|
|
6590
6964
|
if (left < 10) left = 10;
|
|
6591
6965
|
if (top + tooltipHeight > window.innerHeight - 10) {
|
|
6592
|
-
top = (event?.clientY || top) - tooltipHeight -
|
|
6966
|
+
top = (event?.clientY || top) - tooltipHeight - 8;
|
|
6593
6967
|
}
|
|
6594
6968
|
if (top < 10) top = 10;
|
|
6595
6969
|
container.style.left = left + "px";
|
|
@@ -6604,8 +6978,229 @@ var EnergyRangeTooltip = {
|
|
|
6604
6978
|
if (container) {
|
|
6605
6979
|
container.classList.remove("visible");
|
|
6606
6980
|
}
|
|
6981
|
+
},
|
|
6982
|
+
/**
|
|
6983
|
+
* Attach tooltip to an element with automatic show/hide on hover
|
|
6984
|
+
* Returns cleanup function to remove event listeners
|
|
6985
|
+
*/
|
|
6986
|
+
attach(element, entityData) {
|
|
6987
|
+
const handleMouseEnter = (e) => {
|
|
6988
|
+
this.show(element, entityData, e);
|
|
6989
|
+
};
|
|
6990
|
+
const handleMouseLeave = () => {
|
|
6991
|
+
this.hide();
|
|
6992
|
+
};
|
|
6993
|
+
const handleMouseMove = (e) => {
|
|
6994
|
+
const container = document.getElementById(this.containerId);
|
|
6995
|
+
if (container && container.classList.contains("visible")) {
|
|
6996
|
+
let left = e.clientX + 8;
|
|
6997
|
+
let top = e.clientY + 8;
|
|
6998
|
+
const tooltipWidth = 320;
|
|
6999
|
+
const tooltipHeight = 380;
|
|
7000
|
+
if (left + tooltipWidth > window.innerWidth - 10) {
|
|
7001
|
+
left = e.clientX - tooltipWidth - 8;
|
|
7002
|
+
}
|
|
7003
|
+
if (left < 10) left = 10;
|
|
7004
|
+
if (top + tooltipHeight > window.innerHeight - 10) {
|
|
7005
|
+
top = e.clientY - tooltipHeight - 8;
|
|
7006
|
+
}
|
|
7007
|
+
if (top < 10) top = 10;
|
|
7008
|
+
container.style.left = left + "px";
|
|
7009
|
+
container.style.top = top + "px";
|
|
7010
|
+
}
|
|
7011
|
+
};
|
|
7012
|
+
element.addEventListener("mouseenter", handleMouseEnter);
|
|
7013
|
+
element.addEventListener("mouseleave", handleMouseLeave);
|
|
7014
|
+
element.addEventListener("mousemove", handleMouseMove);
|
|
7015
|
+
return () => {
|
|
7016
|
+
element.removeEventListener("mouseenter", handleMouseEnter);
|
|
7017
|
+
element.removeEventListener("mouseleave", handleMouseLeave);
|
|
7018
|
+
element.removeEventListener("mousemove", handleMouseMove);
|
|
7019
|
+
this.hide();
|
|
7020
|
+
};
|
|
6607
7021
|
}
|
|
6608
7022
|
};
|
|
7023
|
+
|
|
7024
|
+
// src/thingsboard/main-dashboard-shopping/v-4.0.0/card/head-office/card-head-office.js
|
|
7025
|
+
var LABEL_CHAR_LIMIT = 18;
|
|
7026
|
+
var DEFAUL_DELAY_TIME_CONNECTION_IN_MINS = 1440;
|
|
7027
|
+
var CSS_TAG = "head-office-card-v1";
|
|
7028
|
+
function ensureCss() {
|
|
7029
|
+
if (!document.querySelector(`style[data-myio-css="${CSS_TAG}"]`)) {
|
|
7030
|
+
const style = document.createElement("style");
|
|
7031
|
+
style.setAttribute("data-myio-css", CSS_TAG);
|
|
7032
|
+
style.textContent = CSS_STRING;
|
|
7033
|
+
document.head.appendChild(style);
|
|
7034
|
+
}
|
|
7035
|
+
}
|
|
7036
|
+
function normalizeParams(params) {
|
|
7037
|
+
if (!params || !params.entityObject) {
|
|
7038
|
+
throw new Error("renderCardCompenteHeadOffice: entityObject is required");
|
|
7039
|
+
}
|
|
7040
|
+
const LogHelper2 = createLogHelper(params.debugActive ?? false);
|
|
7041
|
+
const entityObject = params.entityObject;
|
|
7042
|
+
if (!entityObject.entityId) {
|
|
7043
|
+
LogHelper2.warn("[CardHeadOffice] entityId is missing, generating temporary ID");
|
|
7044
|
+
entityObject.entityId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
7045
|
+
}
|
|
7046
|
+
if (!params.delayTimeConnectionInMins) {
|
|
7047
|
+
LogHelper2.warn(
|
|
7048
|
+
`[CardHeadOffice] delayTimeConnectionInMins is missing, defaulting to ${DEFAUL_DELAY_TIME_CONNECTION_IN_MINS} mins`
|
|
7049
|
+
);
|
|
7050
|
+
}
|
|
7051
|
+
return {
|
|
7052
|
+
entityObject,
|
|
7053
|
+
i18n: { ...DEFAULT_I18N, ...params.i18n || {} },
|
|
7054
|
+
enableSelection: Boolean(params.enableSelection),
|
|
7055
|
+
enableDragDrop: Boolean(params.enableDragDrop),
|
|
7056
|
+
useNewComponents: Boolean(params.useNewComponents),
|
|
7057
|
+
// RFC-0091: Configurable delay time for connection status check (default 15 minutes)
|
|
7058
|
+
delayTimeConnectionInMins: params.delayTimeConnectionInMins ?? DEFAUL_DELAY_TIME_CONNECTION_IN_MINS,
|
|
7059
|
+
// Debug options
|
|
7060
|
+
debugActive: params.debugActive ?? false,
|
|
7061
|
+
activeTooltipDebug: params.activeTooltipDebug ?? false,
|
|
7062
|
+
// LogHelper instance for this card
|
|
7063
|
+
LogHelper: LogHelper2,
|
|
7064
|
+
callbacks: {
|
|
7065
|
+
handleActionDashboard: params.handleActionDashboard,
|
|
7066
|
+
handleActionReport: params.handleActionReport,
|
|
7067
|
+
handleActionSettings: params.handleActionSettings,
|
|
7068
|
+
handleSelect: params.handleSelect,
|
|
7069
|
+
handInfo: params.handInfo,
|
|
7070
|
+
handleClickCard: params.handleClickCard
|
|
7071
|
+
}
|
|
7072
|
+
};
|
|
7073
|
+
}
|
|
7074
|
+
function getIconSvg(deviceType, domain) {
|
|
7075
|
+
if (domain === "water") {
|
|
7076
|
+
return Icons.waterDrop;
|
|
7077
|
+
}
|
|
7078
|
+
if (domain === "temperature") {
|
|
7079
|
+
return Icons.thermometer;
|
|
7080
|
+
}
|
|
7081
|
+
return ICON_MAP[deviceType] || ICON_MAP.DEFAULT;
|
|
7082
|
+
}
|
|
7083
|
+
function formatPower(valueInWatts) {
|
|
7084
|
+
if (valueInWatts === null || valueInWatts === void 0 || isNaN(valueInWatts)) {
|
|
7085
|
+
return { num: "-", unit: "" };
|
|
7086
|
+
}
|
|
7087
|
+
const val = Number(valueInWatts);
|
|
7088
|
+
if (val >= 1e3) {
|
|
7089
|
+
const kw = Math.ceil(val / 1e3 * 100) / 100;
|
|
7090
|
+
return { num: kw.toFixed(2), unit: "kW" };
|
|
7091
|
+
} else {
|
|
7092
|
+
const w = Math.ceil(val);
|
|
7093
|
+
return { num: w.toString(), unit: "W" };
|
|
7094
|
+
}
|
|
7095
|
+
}
|
|
7096
|
+
function formatValueByDomain(value, domain) {
|
|
7097
|
+
if (domain === "water") {
|
|
7098
|
+
return formatWaterVolumeM3(value);
|
|
7099
|
+
}
|
|
7100
|
+
if (domain === "temperature") {
|
|
7101
|
+
return formatTemperature(value, 0);
|
|
7102
|
+
}
|
|
7103
|
+
return formatEnergy(value);
|
|
7104
|
+
}
|
|
7105
|
+
function formatRelativeTime2(timestamp) {
|
|
7106
|
+
if (!timestamp || isNaN(timestamp)) return "\u2014";
|
|
7107
|
+
const date = new Date(timestamp);
|
|
7108
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
7109
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
7110
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
7111
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
7112
|
+
const year = date.getFullYear();
|
|
7113
|
+
return `${hours}:${minutes} ${day}/${month}/${year}`;
|
|
7114
|
+
}
|
|
7115
|
+
function calculateConsumptionPercentage(target, consumption) {
|
|
7116
|
+
const numericTarget = Number(target);
|
|
7117
|
+
const numericConsumption = Number(consumption);
|
|
7118
|
+
if (isNaN(numericTarget) || isNaN(numericConsumption) || numericTarget <= 0) {
|
|
7119
|
+
return 0;
|
|
7120
|
+
}
|
|
7121
|
+
const percentage = numericConsumption / numericTarget * 100;
|
|
7122
|
+
return percentage;
|
|
7123
|
+
}
|
|
7124
|
+
function getStatusInfo(deviceStatus, i18n, domain) {
|
|
7125
|
+
switch (deviceStatus) {
|
|
7126
|
+
// --- Novos Status de Temperatura ---
|
|
7127
|
+
case "normal":
|
|
7128
|
+
return { chipClass: "chip--ok", label: "Normal" };
|
|
7129
|
+
case "cold":
|
|
7130
|
+
return { chipClass: "chip--standby", label: "Frio" };
|
|
7131
|
+
case "hot":
|
|
7132
|
+
return { chipClass: "chip--alert", label: "Quente" };
|
|
7133
|
+
// --- Status Existentes (aligned with getCardStateClass) ---
|
|
7134
|
+
case DeviceStatusType.POWER_ON:
|
|
7135
|
+
if (domain === "water") {
|
|
7136
|
+
return { chipClass: "chip--power-on", label: i18n.in_operation_water };
|
|
7137
|
+
}
|
|
7138
|
+
return { chipClass: "chip--power-on", label: i18n.in_operation };
|
|
7139
|
+
case DeviceStatusType.STANDBY:
|
|
7140
|
+
return { chipClass: "chip--standby", label: i18n.standby };
|
|
7141
|
+
case DeviceStatusType.WARNING:
|
|
7142
|
+
return { chipClass: "chip--warning", label: i18n.alert };
|
|
7143
|
+
case DeviceStatusType.MAINTENANCE:
|
|
7144
|
+
return { chipClass: "chip--maintenance", label: i18n.maintenance };
|
|
7145
|
+
case DeviceStatusType.FAILURE:
|
|
7146
|
+
return { chipClass: "chip--failure", label: i18n.failure };
|
|
7147
|
+
case DeviceStatusType.POWER_OFF:
|
|
7148
|
+
return { chipClass: "chip--power-off", label: i18n.power_off || i18n.failure };
|
|
7149
|
+
case DeviceStatusType.OFFLINE:
|
|
7150
|
+
return { chipClass: "chip--offline", label: i18n.offline };
|
|
7151
|
+
case DeviceStatusType.NO_INFO:
|
|
7152
|
+
return { chipClass: "chip--no-info", label: i18n.no_info || i18n.offline };
|
|
7153
|
+
case DeviceStatusType.NOT_INSTALLED:
|
|
7154
|
+
return { chipClass: "chip--not-installed", label: i18n.not_installed };
|
|
7155
|
+
default:
|
|
7156
|
+
return { chipClass: "chip--offline", label: i18n.offline };
|
|
7157
|
+
}
|
|
7158
|
+
}
|
|
7159
|
+
function getCardStateClass(deviceStatus) {
|
|
7160
|
+
switch (deviceStatus) {
|
|
7161
|
+
case DeviceStatusType.POWER_ON:
|
|
7162
|
+
return "is-power-on";
|
|
7163
|
+
// Blue border
|
|
7164
|
+
case DeviceStatusType.STANDBY:
|
|
7165
|
+
return "is-standby";
|
|
7166
|
+
// Green border
|
|
7167
|
+
case DeviceStatusType.WARNING:
|
|
7168
|
+
return "is-warning";
|
|
7169
|
+
// Yellow border
|
|
7170
|
+
case DeviceStatusType.MAINTENANCE:
|
|
7171
|
+
return "is-maintenance";
|
|
7172
|
+
// Yellow border
|
|
7173
|
+
case DeviceStatusType.FAILURE:
|
|
7174
|
+
return "is-failure";
|
|
7175
|
+
// Dark Red border
|
|
7176
|
+
case DeviceStatusType.POWER_OFF:
|
|
7177
|
+
return "is-power-off";
|
|
7178
|
+
// Light Red border
|
|
7179
|
+
case DeviceStatusType.OFFLINE:
|
|
7180
|
+
return "is-offline";
|
|
7181
|
+
// Dark Gray border
|
|
7182
|
+
case DeviceStatusType.NO_INFO:
|
|
7183
|
+
return "is-no-info";
|
|
7184
|
+
// Dark Orange border
|
|
7185
|
+
case DeviceStatusType.NOT_INSTALLED:
|
|
7186
|
+
return "is-not-installed";
|
|
7187
|
+
// Purple border
|
|
7188
|
+
default:
|
|
7189
|
+
return "";
|
|
7190
|
+
}
|
|
7191
|
+
}
|
|
7192
|
+
function getTempRangeClass(entityObject) {
|
|
7193
|
+
if (entityObject.domain !== "temperature") return "";
|
|
7194
|
+
const currentTemp = Number(entityObject.val ?? entityObject.currentTemperature ?? entityObject.temperature) || 0;
|
|
7195
|
+
const tempMin = entityObject.temperatureMin ?? entityObject.minTemperature;
|
|
7196
|
+
const tempMax = entityObject.temperatureMax ?? entityObject.maxTemperature;
|
|
7197
|
+
if (tempMin === void 0 || tempMax === void 0 || tempMin === null || tempMax === null) {
|
|
7198
|
+
return "";
|
|
7199
|
+
}
|
|
7200
|
+
if (currentTemp > tempMax) return "is-temp-hot";
|
|
7201
|
+
if (currentTemp < tempMin) return "is-temp-cold";
|
|
7202
|
+
return "is-temp-ok";
|
|
7203
|
+
}
|
|
6609
7204
|
function getStatusDotClass(deviceStatus) {
|
|
6610
7205
|
switch (deviceStatus) {
|
|
6611
7206
|
// --- Novos Status de Temperatura ---
|
|
@@ -7131,29 +7726,34 @@ function bindEvents(root, state, callbacks) {
|
|
|
7131
7726
|
MyIOSelectionStore2.on("selection:change", onSelectionChange);
|
|
7132
7727
|
root._selectionListener = onSelectionChange;
|
|
7133
7728
|
}
|
|
7134
|
-
|
|
7729
|
+
const valueElement = root.querySelector(".myio-ho-card__value");
|
|
7730
|
+
if (entityObject.domain === "temperature" && valueElement) {
|
|
7135
7731
|
const showTooltip = (e) => {
|
|
7136
7732
|
TempRangeTooltip.show(root, state.entityObject, e);
|
|
7137
7733
|
};
|
|
7138
7734
|
const hideTooltip = () => {
|
|
7139
7735
|
TempRangeTooltip.hide();
|
|
7140
7736
|
};
|
|
7141
|
-
|
|
7142
|
-
|
|
7737
|
+
valueElement.style.cursor = "help";
|
|
7738
|
+
valueElement.addEventListener("mouseenter", showTooltip);
|
|
7739
|
+
valueElement.addEventListener("mouseleave", hideTooltip);
|
|
7143
7740
|
root._tempTooltipShowFn = showTooltip;
|
|
7144
7741
|
root._tempTooltipHideFn = hideTooltip;
|
|
7742
|
+
root._tooltipElement = valueElement;
|
|
7145
7743
|
}
|
|
7146
|
-
if (entityObject.domain === "energy") {
|
|
7744
|
+
if (entityObject.domain === "energy" && valueElement) {
|
|
7147
7745
|
const showEnergyTooltip = (e) => {
|
|
7148
7746
|
EnergyRangeTooltip.show(root, state.entityObject, e);
|
|
7149
7747
|
};
|
|
7150
7748
|
const hideEnergyTooltip = () => {
|
|
7151
7749
|
EnergyRangeTooltip.hide();
|
|
7152
7750
|
};
|
|
7153
|
-
|
|
7154
|
-
|
|
7751
|
+
valueElement.style.cursor = "help";
|
|
7752
|
+
valueElement.addEventListener("mouseenter", showEnergyTooltip);
|
|
7753
|
+
valueElement.addEventListener("mouseleave", hideEnergyTooltip);
|
|
7155
7754
|
root._energyTooltipShowFn = showEnergyTooltip;
|
|
7156
7755
|
root._energyTooltipHideFn = hideEnergyTooltip;
|
|
7756
|
+
root._tooltipElement = valueElement;
|
|
7157
7757
|
}
|
|
7158
7758
|
root._cleanup = () => {
|
|
7159
7759
|
document.removeEventListener("click", closeMenu);
|
|
@@ -7161,14 +7761,14 @@ function bindEvents(root, state, callbacks) {
|
|
|
7161
7761
|
if (MyIOSelectionStore2 && root._selectionListener) {
|
|
7162
7762
|
MyIOSelectionStore2.off("selection:change", root._selectionListener);
|
|
7163
7763
|
}
|
|
7164
|
-
if (root._tempTooltipShowFn) {
|
|
7165
|
-
root.removeEventListener("mouseenter", root._tempTooltipShowFn);
|
|
7166
|
-
root.removeEventListener("mouseleave", root._tempTooltipHideFn);
|
|
7764
|
+
if (root._tempTooltipShowFn && root._tooltipElement) {
|
|
7765
|
+
root._tooltipElement.removeEventListener("mouseenter", root._tempTooltipShowFn);
|
|
7766
|
+
root._tooltipElement.removeEventListener("mouseleave", root._tempTooltipHideFn);
|
|
7167
7767
|
TempRangeTooltip.hide();
|
|
7168
7768
|
}
|
|
7169
|
-
if (root._energyTooltipShowFn) {
|
|
7170
|
-
root.removeEventListener("mouseenter", root._energyTooltipShowFn);
|
|
7171
|
-
root.removeEventListener("mouseleave", root._energyTooltipHideFn);
|
|
7769
|
+
if (root._energyTooltipShowFn && root._tooltipElement) {
|
|
7770
|
+
root._tooltipElement.removeEventListener("mouseenter", root._energyTooltipShowFn);
|
|
7771
|
+
root._tooltipElement.removeEventListener("mouseleave", root._energyTooltipHideFn);
|
|
7172
7772
|
EnergyRangeTooltip.hide();
|
|
7173
7773
|
}
|
|
7174
7774
|
};
|
|
@@ -7721,6 +8321,7 @@ function renderCardComponentV5({
|
|
|
7721
8321
|
};
|
|
7722
8322
|
const isTankDevice = deviceType === "TANK" || deviceType === "CAIXA_DAGUA";
|
|
7723
8323
|
const isTermostatoDevice = deviceType?.toUpperCase() === "TERMOSTATO";
|
|
8324
|
+
const isEnergyDeviceFlag = isEnergyDevice(deviceType);
|
|
7724
8325
|
const percentageForDisplay = isTankDevice ? (waterPercentage || 0) * 100 : perc;
|
|
7725
8326
|
const calculateTempStatus = () => {
|
|
7726
8327
|
if (temperatureStatus) return temperatureStatus;
|
|
@@ -7737,33 +8338,6 @@ function renderCardComponentV5({
|
|
|
7737
8338
|
tempStatus,
|
|
7738
8339
|
isOffline
|
|
7739
8340
|
});
|
|
7740
|
-
const getTemperatureTooltip = () => {
|
|
7741
|
-
if (!isTermostatoDevice) return "";
|
|
7742
|
-
const currentTemp = Number(val) || 0;
|
|
7743
|
-
const hasRange = temperatureMin !== void 0 && temperatureMax !== void 0 && temperatureMin !== null && temperatureMax !== null;
|
|
7744
|
-
if (isOffline) {
|
|
7745
|
-
return "Dispositivo offline";
|
|
7746
|
-
}
|
|
7747
|
-
if (!hasRange) {
|
|
7748
|
-
return `Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7749
|
-
Faixa n\xE3o configurada`;
|
|
7750
|
-
}
|
|
7751
|
-
const rangeText = `Faixa ideal: ${temperatureMin}\xB0C a ${temperatureMax}\xB0C`;
|
|
7752
|
-
if (tempStatus === "above") {
|
|
7753
|
-
return `ACIMA da faixa ideal
|
|
7754
|
-
Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7755
|
-
${rangeText}`;
|
|
7756
|
-
} else if (tempStatus === "below") {
|
|
7757
|
-
return `ABAIXO da faixa ideal
|
|
7758
|
-
Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7759
|
-
${rangeText}`;
|
|
7760
|
-
} else {
|
|
7761
|
-
return `DENTRO da faixa ideal
|
|
7762
|
-
Temperatura atual: ${currentTemp.toFixed(1)}\xB0C
|
|
7763
|
-
${rangeText}`;
|
|
7764
|
-
}
|
|
7765
|
-
};
|
|
7766
|
-
const temperatureTooltip = getTemperatureTooltip();
|
|
7767
8341
|
const cardHTML = `
|
|
7768
8342
|
<div class="device-card-centered clickable ${cardEntity.status === "offline" ? "offline" : ""}"
|
|
7769
8343
|
data-entity-id="${entityId}"
|
|
@@ -7789,7 +8363,7 @@ ${rangeText}`;
|
|
|
7789
8363
|
` : ""}
|
|
7790
8364
|
</div>
|
|
7791
8365
|
|
|
7792
|
-
<img class="device-image
|
|
8366
|
+
<img class="device-image ${isTermostatoDevice ? "temp-tooltip-trigger" : ""}${isEnergyDeviceFlag ? " energy-tooltip-trigger" : ""}" src="${deviceImageUrl}" alt="${deviceType}" style="${isTermostatoDevice || isEnergyDeviceFlag ? "cursor: help;" : ""}" />
|
|
7793
8367
|
|
|
7794
8368
|
|
|
7795
8369
|
${customerName && String(customerName).trim() !== "" ? `
|
|
@@ -8353,6 +8927,33 @@ ${rangeText}`;
|
|
|
8353
8927
|
}
|
|
8354
8928
|
});
|
|
8355
8929
|
}
|
|
8930
|
+
const tempTooltipTrigger = enhancedCardElement.querySelector(".temp-tooltip-trigger");
|
|
8931
|
+
let tempTooltipCleanup = null;
|
|
8932
|
+
if (tempTooltipTrigger && isTermostatoDevice) {
|
|
8933
|
+
const tooltipEntityData = {
|
|
8934
|
+
val,
|
|
8935
|
+
temperatureMin,
|
|
8936
|
+
temperatureMax,
|
|
8937
|
+
labelOrName: cardEntity.name,
|
|
8938
|
+
name: cardEntity.name
|
|
8939
|
+
};
|
|
8940
|
+
tempTooltipCleanup = TempRangeTooltip.attach(tempTooltipTrigger, tooltipEntityData);
|
|
8941
|
+
}
|
|
8942
|
+
const energyTooltipTrigger = enhancedCardElement.querySelector(".energy-tooltip-trigger");
|
|
8943
|
+
let energyTooltipCleanup = null;
|
|
8944
|
+
if (energyTooltipTrigger && isEnergyDeviceFlag) {
|
|
8945
|
+
const energyTooltipData = {
|
|
8946
|
+
labelOrName: cardEntity.name,
|
|
8947
|
+
name: cardEntity.name,
|
|
8948
|
+
instantaneousPower: entityObject.instantaneousPower ?? entityObject.consumption_power ?? val,
|
|
8949
|
+
powerRanges: entityObject.powerRanges || entityObject.ranges
|
|
8950
|
+
};
|
|
8951
|
+
energyTooltipCleanup = EnergyRangeTooltip.attach(energyTooltipTrigger, energyTooltipData);
|
|
8952
|
+
}
|
|
8953
|
+
container._cleanup = () => {
|
|
8954
|
+
if (tempTooltipCleanup) tempTooltipCleanup();
|
|
8955
|
+
if (energyTooltipCleanup) energyTooltipCleanup();
|
|
8956
|
+
};
|
|
8356
8957
|
const jQueryLikeObject = {
|
|
8357
8958
|
get: (index) => index === 0 ? container : void 0,
|
|
8358
8959
|
0: container,
|
|
@@ -11337,7 +11938,7 @@ var chartJsLoaded = false;
|
|
|
11337
11938
|
var zoomPluginLoaded = false;
|
|
11338
11939
|
var jsPdfLoaded = false;
|
|
11339
11940
|
var _jspdfPromise = null;
|
|
11340
|
-
var
|
|
11941
|
+
var cssInjected2 = false;
|
|
11341
11942
|
var STRINGS2 = {
|
|
11342
11943
|
"pt-BR": {
|
|
11343
11944
|
title: "Demanda",
|
|
@@ -11513,8 +12114,8 @@ function ensureRoom(doc, nextY, minRoom = 40) {
|
|
|
11513
12114
|
}
|
|
11514
12115
|
return nextY;
|
|
11515
12116
|
}
|
|
11516
|
-
function
|
|
11517
|
-
if (
|
|
12117
|
+
function injectCSS2(styles) {
|
|
12118
|
+
if (cssInjected2) return;
|
|
11518
12119
|
const css = `
|
|
11519
12120
|
.myio-demand-modal-overlay {
|
|
11520
12121
|
position: fixed;
|
|
@@ -11909,7 +12510,7 @@ function injectCSS(styles) {
|
|
|
11909
12510
|
const style = document.createElement("style");
|
|
11910
12511
|
style.textContent = css;
|
|
11911
12512
|
document.head.appendChild(style);
|
|
11912
|
-
|
|
12513
|
+
cssInjected2 = true;
|
|
11913
12514
|
}
|
|
11914
12515
|
function formatDate2(date, locale) {
|
|
11915
12516
|
return date.toLocaleDateString(locale, {
|
|
@@ -12091,7 +12692,7 @@ async function openDemandModal(params) {
|
|
|
12091
12692
|
const locale = params.locale || "pt-BR";
|
|
12092
12693
|
const strings = STRINGS2[locale] || STRINGS2["pt-BR"];
|
|
12093
12694
|
await loadExternalLibraries();
|
|
12094
|
-
|
|
12695
|
+
injectCSS2(styles);
|
|
12095
12696
|
const container = typeof params.container === "string" ? document.querySelector(params.container) : params.container || document.body;
|
|
12096
12697
|
if (!container) {
|
|
12097
12698
|
throw new Error("Container element not found");
|
|
@@ -21740,7 +22341,7 @@ async function createInputDateRangePickerInsideDIV(params) {
|
|
|
21740
22341
|
placeholder = "Clique para selecionar per\xEDodo",
|
|
21741
22342
|
pickerOptions = {},
|
|
21742
22343
|
classNames = {},
|
|
21743
|
-
injectStyles = true,
|
|
22344
|
+
injectStyles: injectStyles2 = true,
|
|
21744
22345
|
showHelper = true
|
|
21745
22346
|
} = params;
|
|
21746
22347
|
validateId(containerId, "containerId");
|
|
@@ -21749,7 +22350,7 @@ async function createInputDateRangePickerInsideDIV(params) {
|
|
|
21749
22350
|
if (!container) {
|
|
21750
22351
|
throw new Error(`[createInputDateRangePickerInsideDIV] Container '#${containerId}' not found`);
|
|
21751
22352
|
}
|
|
21752
|
-
if (
|
|
22353
|
+
if (injectStyles2) {
|
|
21753
22354
|
injectPremiumStyles();
|
|
21754
22355
|
}
|
|
21755
22356
|
let inputEl = document.getElementById(inputId);
|
|
@@ -21944,7 +22545,7 @@ function openGoalsPanel(params) {
|
|
|
21944
22545
|
modal.setAttribute("aria-labelledby", "goals-modal-title");
|
|
21945
22546
|
modal.innerHTML = generateModalHTML();
|
|
21946
22547
|
document.body.appendChild(modal);
|
|
21947
|
-
|
|
22548
|
+
injectStyles2();
|
|
21948
22549
|
attachEventListeners();
|
|
21949
22550
|
trapFocus(modal);
|
|
21950
22551
|
renderTabContent();
|
|
@@ -22697,7 +23298,7 @@ function openGoalsPanel(params) {
|
|
|
22697
23298
|
maximumFractionDigits: 2
|
|
22698
23299
|
}).format(value);
|
|
22699
23300
|
}
|
|
22700
|
-
function
|
|
23301
|
+
function injectStyles2() {
|
|
22701
23302
|
const styleId = "myio-goals-panel-styles";
|
|
22702
23303
|
if (document.getElementById(styleId)) return;
|
|
22703
23304
|
const style = document.createElement("style");
|
|
@@ -24954,7 +25555,7 @@ var LIGHT_THEME2 = {
|
|
|
24954
25555
|
function getColors(theme) {
|
|
24955
25556
|
return theme === "dark" ? DARK_THEME2 : LIGHT_THEME2;
|
|
24956
25557
|
}
|
|
24957
|
-
async function fetchCustomerAttributes(customerId, token) {
|
|
25558
|
+
async function fetchCustomerAttributes(customerId, token, onError) {
|
|
24958
25559
|
const url = `/api/plugins/telemetry/CUSTOMER/${customerId}/values/attributes/SERVER_SCOPE`;
|
|
24959
25560
|
const response = await fetch(url, {
|
|
24960
25561
|
method: "GET",
|
|
@@ -24967,6 +25568,10 @@ async function fetchCustomerAttributes(customerId, token) {
|
|
|
24967
25568
|
if (response.status === 404 || response.status === 400) {
|
|
24968
25569
|
return { minTemperature: null, maxTemperature: null };
|
|
24969
25570
|
}
|
|
25571
|
+
if (onError) {
|
|
25572
|
+
onError({ status: response.status, message: `Failed to fetch attributes: ${response.status}` });
|
|
25573
|
+
return { minTemperature: null, maxTemperature: null };
|
|
25574
|
+
}
|
|
24970
25575
|
throw new Error(`Failed to fetch attributes: ${response.status}`);
|
|
24971
25576
|
}
|
|
24972
25577
|
const attributes = await response.json();
|
|
@@ -24983,7 +25588,7 @@ async function fetchCustomerAttributes(customerId, token) {
|
|
|
24983
25588
|
}
|
|
24984
25589
|
return { minTemperature, maxTemperature };
|
|
24985
25590
|
}
|
|
24986
|
-
async function saveCustomerAttributes(customerId, token, minTemperature, maxTemperature) {
|
|
25591
|
+
async function saveCustomerAttributes(customerId, token, minTemperature, maxTemperature, onError) {
|
|
24987
25592
|
const url = `/api/plugins/telemetry/CUSTOMER/${customerId}/SERVER_SCOPE`;
|
|
24988
25593
|
const attributes = {
|
|
24989
25594
|
minTemperature,
|
|
@@ -24998,6 +25603,10 @@ async function saveCustomerAttributes(customerId, token, minTemperature, maxTemp
|
|
|
24998
25603
|
body: JSON.stringify(attributes)
|
|
24999
25604
|
});
|
|
25000
25605
|
if (!response.ok) {
|
|
25606
|
+
if (onError) {
|
|
25607
|
+
onError({ status: response.status, message: `Failed to save attributes: ${response.status}` });
|
|
25608
|
+
return;
|
|
25609
|
+
}
|
|
25001
25610
|
throw new Error(`Failed to save attributes: ${response.status}`);
|
|
25002
25611
|
}
|
|
25003
25612
|
}
|
|
@@ -25414,7 +26023,7 @@ function openTemperatureSettingsModal(params) {
|
|
|
25414
26023
|
state.successMessage = null;
|
|
25415
26024
|
renderModal3(container, state, modalId, destroy, handleSave);
|
|
25416
26025
|
try {
|
|
25417
|
-
await saveCustomerAttributes(state.customerId, state.token, min, max);
|
|
26026
|
+
await saveCustomerAttributes(state.customerId, state.token, min, max, params.onError);
|
|
25418
26027
|
state.minTemperature = min;
|
|
25419
26028
|
state.maxTemperature = max;
|
|
25420
26029
|
state.isSaving = false;
|
|
@@ -25431,7 +26040,7 @@ function openTemperatureSettingsModal(params) {
|
|
|
25431
26040
|
}
|
|
25432
26041
|
};
|
|
25433
26042
|
renderModal3(container, state, modalId, destroy, handleSave);
|
|
25434
|
-
fetchCustomerAttributes(state.customerId, state.token).then(({ minTemperature, maxTemperature }) => {
|
|
26043
|
+
fetchCustomerAttributes(state.customerId, state.token, params.onError).then(({ minTemperature, maxTemperature }) => {
|
|
25435
26044
|
state.minTemperature = minTemperature;
|
|
25436
26045
|
state.maxTemperature = maxTemperature;
|
|
25437
26046
|
state.isLoading = false;
|
|
@@ -27592,7 +28201,7 @@ function createConsumptionChartWidget(config) {
|
|
|
27592
28201
|
</div>
|
|
27593
28202
|
`;
|
|
27594
28203
|
}
|
|
27595
|
-
function
|
|
28204
|
+
function injectStyles2() {
|
|
27596
28205
|
if (styleElement) return;
|
|
27597
28206
|
styleElement = document.createElement("style");
|
|
27598
28207
|
styleElement.id = `${widgetId}-styles`;
|
|
@@ -28074,7 +28683,7 @@ function createConsumptionChartWidget(config) {
|
|
|
28074
28683
|
console.error(`[ConsumptionWidget] Container #${config.containerId} not found`);
|
|
28075
28684
|
return;
|
|
28076
28685
|
}
|
|
28077
|
-
|
|
28686
|
+
injectStyles2();
|
|
28078
28687
|
containerElement.innerHTML = renderHTML();
|
|
28079
28688
|
setupListeners();
|
|
28080
28689
|
setLoading(true);
|
|
@@ -29214,6 +29823,7 @@ function createDistributionChartWidget(config) {
|
|
|
29214
29823
|
EXPORT_DOMAIN_ICONS,
|
|
29215
29824
|
EXPORT_DOMAIN_LABELS,
|
|
29216
29825
|
EXPORT_DOMAIN_UNITS,
|
|
29826
|
+
EnergyRangeTooltip,
|
|
29217
29827
|
MyIOChartModal,
|
|
29218
29828
|
MyIODraggableCard,
|
|
29219
29829
|
MyIOSelectionStore,
|
|
@@ -29222,6 +29832,7 @@ function createDistributionChartWidget(config) {
|
|
|
29222
29832
|
POWER_LIMITS_DEVICE_TYPES,
|
|
29223
29833
|
POWER_LIMITS_STATUS_CONFIG,
|
|
29224
29834
|
POWER_LIMITS_TELEMETRY_TYPES,
|
|
29835
|
+
TempRangeTooltip,
|
|
29225
29836
|
addDetectionContext,
|
|
29226
29837
|
addNamespace,
|
|
29227
29838
|
aggregateByDay,
|