myio-js-library 0.1.133 → 0.1.135
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 +772 -39
- package/dist/index.d.cts +28 -1
- package/dist/index.js +771 -39
- package/dist/myio-js-library.umd.js +771 -39
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
|
@@ -6973,6 +6973,632 @@ ${rangeText}`;
|
|
|
6973
6973
|
module.exports = { MyIOToast };
|
|
6974
6974
|
}
|
|
6975
6975
|
|
|
6976
|
+
// src/components/RealTimeTelemetryModal.ts
|
|
6977
|
+
var TELEMETRY_CONFIG = {
|
|
6978
|
+
voltage: { label: "Tens\xE3o", unit: "V", icon: "\u26A1", decimals: 1 },
|
|
6979
|
+
current: { label: "Corrente", unit: "A", icon: "\u{1F50C}", decimals: 2 },
|
|
6980
|
+
power: { label: "Pot\xEAncia", unit: "kW", icon: "\u2699\uFE0F", decimals: 2 },
|
|
6981
|
+
energy: { label: "Energia", unit: "kWh", icon: "\u{1F4CA}", decimals: 1 },
|
|
6982
|
+
temperature: { label: "Temperatura", unit: "\xB0C", icon: "\u{1F321}\uFE0F", decimals: 1 },
|
|
6983
|
+
activePower: { label: "Pot\xEAncia Ativa", unit: "kW", icon: "\u2699\uFE0F", decimals: 2 },
|
|
6984
|
+
reactivePower: { label: "Pot\xEAncia Reativa", unit: "kVAr", icon: "\u{1F504}", decimals: 2 },
|
|
6985
|
+
apparentPower: { label: "Pot\xEAncia Aparente", unit: "kVA", icon: "\u{1F4C8}", decimals: 2 },
|
|
6986
|
+
powerFactor: { label: "Fator de Pot\xEAncia", unit: "", icon: "\u{1F4D0}", decimals: 3 }
|
|
6987
|
+
};
|
|
6988
|
+
var STRINGS = {
|
|
6989
|
+
"pt-BR": {
|
|
6990
|
+
title: "Telemetrias em Tempo Real",
|
|
6991
|
+
close: "Fechar",
|
|
6992
|
+
pause: "Pausar",
|
|
6993
|
+
resume: "Retomar",
|
|
6994
|
+
export: "Exportar CSV",
|
|
6995
|
+
autoUpdate: "Atualiza\xE7\xE3o autom\xE1tica",
|
|
6996
|
+
lastUpdate: "\xDAltima atualiza\xE7\xE3o",
|
|
6997
|
+
noData: "Sem dados",
|
|
6998
|
+
loading: "Carregando...",
|
|
6999
|
+
error: "Erro ao carregar telemetrias",
|
|
7000
|
+
trend_up: "Aumentando",
|
|
7001
|
+
trend_down: "Diminuindo",
|
|
7002
|
+
trend_stable: "Est\xE1vel"
|
|
7003
|
+
},
|
|
7004
|
+
"en-US": {
|
|
7005
|
+
title: "Real-Time Telemetry",
|
|
7006
|
+
close: "Close",
|
|
7007
|
+
pause: "Pause",
|
|
7008
|
+
resume: "Resume",
|
|
7009
|
+
export: "Export CSV",
|
|
7010
|
+
autoUpdate: "Auto-update",
|
|
7011
|
+
lastUpdate: "Last update",
|
|
7012
|
+
noData: "No data",
|
|
7013
|
+
loading: "Loading...",
|
|
7014
|
+
error: "Error loading telemetry",
|
|
7015
|
+
trend_up: "Increasing",
|
|
7016
|
+
trend_down: "Decreasing",
|
|
7017
|
+
trend_stable: "Stable"
|
|
7018
|
+
}
|
|
7019
|
+
};
|
|
7020
|
+
async function openRealTimeTelemetryModal(params) {
|
|
7021
|
+
const {
|
|
7022
|
+
token,
|
|
7023
|
+
deviceId,
|
|
7024
|
+
deviceLabel = "Dispositivo",
|
|
7025
|
+
telemetryKeys = ["voltage", "current", "power", "energy"],
|
|
7026
|
+
refreshInterval = 8e3,
|
|
7027
|
+
historyPoints = 50,
|
|
7028
|
+
onClose,
|
|
7029
|
+
locale = "pt-BR"
|
|
7030
|
+
} = params;
|
|
7031
|
+
const strings = STRINGS[locale] || STRINGS["pt-BR"];
|
|
7032
|
+
let refreshIntervalId = null;
|
|
7033
|
+
let isPaused = false;
|
|
7034
|
+
let telemetryHistory = /* @__PURE__ */ new Map();
|
|
7035
|
+
let chart = null;
|
|
7036
|
+
const overlay = document.createElement("div");
|
|
7037
|
+
overlay.className = "myio-realtime-telemetry-overlay";
|
|
7038
|
+
overlay.innerHTML = `
|
|
7039
|
+
<style>
|
|
7040
|
+
.myio-realtime-telemetry-overlay {
|
|
7041
|
+
position: fixed;
|
|
7042
|
+
top: 0;
|
|
7043
|
+
left: 0;
|
|
7044
|
+
right: 0;
|
|
7045
|
+
bottom: 0;
|
|
7046
|
+
background: rgba(0, 0, 0, 0.5);
|
|
7047
|
+
display: flex;
|
|
7048
|
+
align-items: center;
|
|
7049
|
+
justify-content: center;
|
|
7050
|
+
z-index: 10000;
|
|
7051
|
+
padding: 20px;
|
|
7052
|
+
animation: fadeIn 0.2s ease;
|
|
7053
|
+
}
|
|
7054
|
+
|
|
7055
|
+
@keyframes fadeIn {
|
|
7056
|
+
from { opacity: 0; }
|
|
7057
|
+
to { opacity: 1; }
|
|
7058
|
+
}
|
|
7059
|
+
|
|
7060
|
+
.myio-realtime-telemetry-container {
|
|
7061
|
+
background: #ffffff;
|
|
7062
|
+
border-radius: 12px;
|
|
7063
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
|
7064
|
+
max-width: 1200px;
|
|
7065
|
+
width: 100%;
|
|
7066
|
+
max-height: 90vh;
|
|
7067
|
+
display: flex;
|
|
7068
|
+
flex-direction: column;
|
|
7069
|
+
overflow: hidden;
|
|
7070
|
+
animation: slideUp 0.3s ease;
|
|
7071
|
+
}
|
|
7072
|
+
|
|
7073
|
+
@keyframes slideUp {
|
|
7074
|
+
from { transform: translateY(20px); opacity: 0; }
|
|
7075
|
+
to { transform: translateY(0); opacity: 1; }
|
|
7076
|
+
}
|
|
7077
|
+
|
|
7078
|
+
.myio-realtime-telemetry-header {
|
|
7079
|
+
padding: 20px 24px;
|
|
7080
|
+
border-bottom: 1px solid #e0e0e0;
|
|
7081
|
+
display: flex;
|
|
7082
|
+
justify-content: space-between;
|
|
7083
|
+
align-items: center;
|
|
7084
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
7085
|
+
color: white;
|
|
7086
|
+
}
|
|
7087
|
+
|
|
7088
|
+
.myio-realtime-telemetry-title {
|
|
7089
|
+
font-size: 20px;
|
|
7090
|
+
font-weight: 600;
|
|
7091
|
+
margin: 0;
|
|
7092
|
+
display: flex;
|
|
7093
|
+
align-items: center;
|
|
7094
|
+
gap: 8px;
|
|
7095
|
+
}
|
|
7096
|
+
|
|
7097
|
+
.myio-realtime-telemetry-close {
|
|
7098
|
+
background: rgba(255, 255, 255, 0.2);
|
|
7099
|
+
border: none;
|
|
7100
|
+
color: white;
|
|
7101
|
+
font-size: 24px;
|
|
7102
|
+
width: 32px;
|
|
7103
|
+
height: 32px;
|
|
7104
|
+
border-radius: 6px;
|
|
7105
|
+
cursor: pointer;
|
|
7106
|
+
display: flex;
|
|
7107
|
+
align-items: center;
|
|
7108
|
+
justify-content: center;
|
|
7109
|
+
transition: all 0.2s ease;
|
|
7110
|
+
}
|
|
7111
|
+
|
|
7112
|
+
.myio-realtime-telemetry-close:hover {
|
|
7113
|
+
background: rgba(255, 255, 255, 0.3);
|
|
7114
|
+
transform: scale(1.1);
|
|
7115
|
+
}
|
|
7116
|
+
|
|
7117
|
+
.myio-realtime-telemetry-body {
|
|
7118
|
+
padding: 24px;
|
|
7119
|
+
overflow-y: auto;
|
|
7120
|
+
flex: 1;
|
|
7121
|
+
}
|
|
7122
|
+
|
|
7123
|
+
.myio-telemetry-cards-grid {
|
|
7124
|
+
display: grid;
|
|
7125
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
7126
|
+
gap: 16px;
|
|
7127
|
+
margin-bottom: 24px;
|
|
7128
|
+
}
|
|
7129
|
+
|
|
7130
|
+
.myio-telemetry-card {
|
|
7131
|
+
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
|
7132
|
+
border-radius: 12px;
|
|
7133
|
+
padding: 16px;
|
|
7134
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
7135
|
+
transition: all 0.3s ease;
|
|
7136
|
+
}
|
|
7137
|
+
|
|
7138
|
+
.myio-telemetry-card:hover {
|
|
7139
|
+
transform: translateY(-4px);
|
|
7140
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
|
7141
|
+
}
|
|
7142
|
+
|
|
7143
|
+
.myio-telemetry-card-header {
|
|
7144
|
+
display: flex;
|
|
7145
|
+
align-items: center;
|
|
7146
|
+
gap: 8px;
|
|
7147
|
+
margin-bottom: 12px;
|
|
7148
|
+
font-size: 14px;
|
|
7149
|
+
color: #555;
|
|
7150
|
+
font-weight: 500;
|
|
7151
|
+
}
|
|
7152
|
+
|
|
7153
|
+
.myio-telemetry-card-icon {
|
|
7154
|
+
font-size: 20px;
|
|
7155
|
+
}
|
|
7156
|
+
|
|
7157
|
+
.myio-telemetry-card-value {
|
|
7158
|
+
font-size: 28px;
|
|
7159
|
+
font-weight: 700;
|
|
7160
|
+
color: #2c3e50;
|
|
7161
|
+
margin-bottom: 4px;
|
|
7162
|
+
}
|
|
7163
|
+
|
|
7164
|
+
.myio-telemetry-card-trend {
|
|
7165
|
+
font-size: 12px;
|
|
7166
|
+
color: #777;
|
|
7167
|
+
display: flex;
|
|
7168
|
+
align-items: center;
|
|
7169
|
+
gap: 4px;
|
|
7170
|
+
}
|
|
7171
|
+
|
|
7172
|
+
.myio-telemetry-card-trend.up {
|
|
7173
|
+
color: #27ae60;
|
|
7174
|
+
}
|
|
7175
|
+
|
|
7176
|
+
.myio-telemetry-card-trend.down {
|
|
7177
|
+
color: #e74c3c;
|
|
7178
|
+
}
|
|
7179
|
+
|
|
7180
|
+
.myio-telemetry-chart-container {
|
|
7181
|
+
background: white;
|
|
7182
|
+
border-radius: 12px;
|
|
7183
|
+
padding: 20px;
|
|
7184
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
7185
|
+
margin-bottom: 20px;
|
|
7186
|
+
}
|
|
7187
|
+
|
|
7188
|
+
.myio-telemetry-chart-title {
|
|
7189
|
+
font-size: 16px;
|
|
7190
|
+
font-weight: 600;
|
|
7191
|
+
margin: 0 0 16px 0;
|
|
7192
|
+
color: #2c3e50;
|
|
7193
|
+
}
|
|
7194
|
+
|
|
7195
|
+
.myio-telemetry-chart {
|
|
7196
|
+
height: 200px;
|
|
7197
|
+
}
|
|
7198
|
+
|
|
7199
|
+
.myio-realtime-telemetry-footer {
|
|
7200
|
+
padding: 16px 24px;
|
|
7201
|
+
border-top: 1px solid #e0e0e0;
|
|
7202
|
+
display: flex;
|
|
7203
|
+
justify-content: space-between;
|
|
7204
|
+
align-items: center;
|
|
7205
|
+
background: #f8f9fa;
|
|
7206
|
+
}
|
|
7207
|
+
|
|
7208
|
+
.myio-telemetry-status {
|
|
7209
|
+
display: flex;
|
|
7210
|
+
align-items: center;
|
|
7211
|
+
gap: 12px;
|
|
7212
|
+
font-size: 14px;
|
|
7213
|
+
color: #555;
|
|
7214
|
+
}
|
|
7215
|
+
|
|
7216
|
+
.myio-telemetry-status-indicator {
|
|
7217
|
+
width: 8px;
|
|
7218
|
+
height: 8px;
|
|
7219
|
+
border-radius: 50%;
|
|
7220
|
+
background: #27ae60;
|
|
7221
|
+
animation: pulse 2s infinite;
|
|
7222
|
+
}
|
|
7223
|
+
|
|
7224
|
+
.myio-telemetry-status-indicator.paused {
|
|
7225
|
+
background: #e74c3c;
|
|
7226
|
+
animation: none;
|
|
7227
|
+
}
|
|
7228
|
+
|
|
7229
|
+
@keyframes pulse {
|
|
7230
|
+
0%, 100% { opacity: 1; }
|
|
7231
|
+
50% { opacity: 0.5; }
|
|
7232
|
+
}
|
|
7233
|
+
|
|
7234
|
+
.myio-telemetry-actions {
|
|
7235
|
+
display: flex;
|
|
7236
|
+
gap: 12px;
|
|
7237
|
+
}
|
|
7238
|
+
|
|
7239
|
+
.myio-telemetry-btn {
|
|
7240
|
+
padding: 8px 16px;
|
|
7241
|
+
border: none;
|
|
7242
|
+
border-radius: 6px;
|
|
7243
|
+
font-size: 14px;
|
|
7244
|
+
font-weight: 500;
|
|
7245
|
+
cursor: pointer;
|
|
7246
|
+
transition: all 0.2s ease;
|
|
7247
|
+
display: flex;
|
|
7248
|
+
align-items: center;
|
|
7249
|
+
gap: 6px;
|
|
7250
|
+
}
|
|
7251
|
+
|
|
7252
|
+
.myio-telemetry-btn-primary {
|
|
7253
|
+
background: #667eea;
|
|
7254
|
+
color: white;
|
|
7255
|
+
}
|
|
7256
|
+
|
|
7257
|
+
.myio-telemetry-btn-primary:hover {
|
|
7258
|
+
background: #5568d3;
|
|
7259
|
+
transform: translateY(-1px);
|
|
7260
|
+
}
|
|
7261
|
+
|
|
7262
|
+
.myio-telemetry-btn-secondary {
|
|
7263
|
+
background: #e0e0e0;
|
|
7264
|
+
color: #333;
|
|
7265
|
+
}
|
|
7266
|
+
|
|
7267
|
+
.myio-telemetry-btn-secondary:hover {
|
|
7268
|
+
background: #d0d0d0;
|
|
7269
|
+
transform: translateY(-1px);
|
|
7270
|
+
}
|
|
7271
|
+
|
|
7272
|
+
.myio-telemetry-loading {
|
|
7273
|
+
text-align: center;
|
|
7274
|
+
padding: 40px;
|
|
7275
|
+
color: #999;
|
|
7276
|
+
font-size: 16px;
|
|
7277
|
+
}
|
|
7278
|
+
|
|
7279
|
+
.myio-telemetry-error {
|
|
7280
|
+
text-align: center;
|
|
7281
|
+
padding: 40px;
|
|
7282
|
+
color: #e74c3c;
|
|
7283
|
+
font-size: 16px;
|
|
7284
|
+
}
|
|
7285
|
+
</style>
|
|
7286
|
+
|
|
7287
|
+
<div class="myio-realtime-telemetry-container">
|
|
7288
|
+
<div class="myio-realtime-telemetry-header">
|
|
7289
|
+
<h2 class="myio-realtime-telemetry-title">
|
|
7290
|
+
\u26A1 ${strings.title} - ${deviceLabel}
|
|
7291
|
+
</h2>
|
|
7292
|
+
<button class="myio-realtime-telemetry-close" id="close-btn" title="${strings.close}">
|
|
7293
|
+
\xD7
|
|
7294
|
+
</button>
|
|
7295
|
+
</div>
|
|
7296
|
+
|
|
7297
|
+
<div class="myio-realtime-telemetry-body">
|
|
7298
|
+
<div class="myio-telemetry-loading" id="loading-state">
|
|
7299
|
+
${strings.loading}
|
|
7300
|
+
</div>
|
|
7301
|
+
|
|
7302
|
+
<div id="telemetry-content" style="display: none;">
|
|
7303
|
+
<div class="myio-telemetry-cards-grid" id="telemetry-cards"></div>
|
|
7304
|
+
|
|
7305
|
+
<div class="myio-telemetry-chart-container" id="chart-container" style="display: none;">
|
|
7306
|
+
<h3 class="myio-telemetry-chart-title" id="chart-title">Pot\xEAncia (\xFAltimos 5 min)</h3>
|
|
7307
|
+
<canvas class="myio-telemetry-chart" id="telemetry-chart"></canvas>
|
|
7308
|
+
</div>
|
|
7309
|
+
</div>
|
|
7310
|
+
|
|
7311
|
+
<div class="myio-telemetry-error" id="error-state" style="display: none;">
|
|
7312
|
+
${strings.error}
|
|
7313
|
+
</div>
|
|
7314
|
+
</div>
|
|
7315
|
+
|
|
7316
|
+
<div class="myio-realtime-telemetry-footer">
|
|
7317
|
+
<div class="myio-telemetry-status">
|
|
7318
|
+
<span class="myio-telemetry-status-indicator" id="status-indicator"></span>
|
|
7319
|
+
<span id="status-text">${strings.autoUpdate}: ON</span>
|
|
7320
|
+
<span>\u2022</span>
|
|
7321
|
+
<span id="last-update-text">${strings.lastUpdate}: --:--:--</span>
|
|
7322
|
+
</div>
|
|
7323
|
+
|
|
7324
|
+
<div class="myio-telemetry-actions">
|
|
7325
|
+
<button class="myio-telemetry-btn myio-telemetry-btn-secondary" id="pause-btn">
|
|
7326
|
+
<span id="pause-btn-icon">\u23F8\uFE0F</span>
|
|
7327
|
+
<span id="pause-btn-text">${strings.pause}</span>
|
|
7328
|
+
</button>
|
|
7329
|
+
<button class="myio-telemetry-btn myio-telemetry-btn-primary" id="export-btn">
|
|
7330
|
+
\u2B07\uFE0F ${strings.export}
|
|
7331
|
+
</button>
|
|
7332
|
+
</div>
|
|
7333
|
+
</div>
|
|
7334
|
+
</div>
|
|
7335
|
+
`;
|
|
7336
|
+
document.body.appendChild(overlay);
|
|
7337
|
+
const closeBtn = document.getElementById("close-btn");
|
|
7338
|
+
const pauseBtn = document.getElementById("pause-btn");
|
|
7339
|
+
const pauseBtnIcon = document.getElementById("pause-btn-icon");
|
|
7340
|
+
const pauseBtnText = document.getElementById("pause-btn-text");
|
|
7341
|
+
const exportBtn = document.getElementById("export-btn");
|
|
7342
|
+
const loadingState = document.getElementById("loading-state");
|
|
7343
|
+
const telemetryContent = document.getElementById("telemetry-content");
|
|
7344
|
+
const errorState = document.getElementById("error-state");
|
|
7345
|
+
const telemetryCards = document.getElementById("telemetry-cards");
|
|
7346
|
+
const chartContainer = document.getElementById("chart-container");
|
|
7347
|
+
const chartCanvas = document.getElementById("telemetry-chart");
|
|
7348
|
+
const statusIndicator = document.getElementById("status-indicator");
|
|
7349
|
+
const statusText = document.getElementById("status-text");
|
|
7350
|
+
const lastUpdateText = document.getElementById("last-update-text");
|
|
7351
|
+
function closeModal() {
|
|
7352
|
+
if (refreshIntervalId) {
|
|
7353
|
+
clearInterval(refreshIntervalId);
|
|
7354
|
+
refreshIntervalId = null;
|
|
7355
|
+
}
|
|
7356
|
+
if (chart) {
|
|
7357
|
+
chart.destroy();
|
|
7358
|
+
chart = null;
|
|
7359
|
+
}
|
|
7360
|
+
overlay.remove();
|
|
7361
|
+
if (onClose) {
|
|
7362
|
+
onClose();
|
|
7363
|
+
}
|
|
7364
|
+
}
|
|
7365
|
+
async function fetchLatestTelemetry() {
|
|
7366
|
+
const keys = telemetryKeys.join(",");
|
|
7367
|
+
const url = `/api/plugins/telemetry/DEVICE/${deviceId}/values/timeseries?keys=${keys}&limit=1&agg=NONE`;
|
|
7368
|
+
const response = await fetch(url, {
|
|
7369
|
+
headers: {
|
|
7370
|
+
"X-Authorization": `Bearer ${token}`
|
|
7371
|
+
}
|
|
7372
|
+
});
|
|
7373
|
+
if (!response.ok) {
|
|
7374
|
+
throw new Error(`Failed to fetch telemetry: ${response.statusText}`);
|
|
7375
|
+
}
|
|
7376
|
+
return await response.json();
|
|
7377
|
+
}
|
|
7378
|
+
function processTelemetryData(data) {
|
|
7379
|
+
const values = [];
|
|
7380
|
+
for (const key of telemetryKeys) {
|
|
7381
|
+
const telemetryData = data[key];
|
|
7382
|
+
if (!telemetryData || telemetryData.length === 0) continue;
|
|
7383
|
+
const latest = telemetryData[0];
|
|
7384
|
+
const config = TELEMETRY_CONFIG[key] || { label: key, unit: "", icon: "\u{1F4CA}", decimals: 2 };
|
|
7385
|
+
const numValue = Number(latest.value) || 0;
|
|
7386
|
+
const formatted = numValue.toFixed(config.decimals);
|
|
7387
|
+
values.push({
|
|
7388
|
+
key,
|
|
7389
|
+
value: numValue,
|
|
7390
|
+
timestamp: latest.ts,
|
|
7391
|
+
formatted: `${formatted} ${config.unit}`,
|
|
7392
|
+
unit: config.unit,
|
|
7393
|
+
icon: config.icon,
|
|
7394
|
+
label: config.label,
|
|
7395
|
+
trend: "stable"
|
|
7396
|
+
// Will be calculated based on history
|
|
7397
|
+
});
|
|
7398
|
+
}
|
|
7399
|
+
return values;
|
|
7400
|
+
}
|
|
7401
|
+
function calculateTrend(key, currentValue) {
|
|
7402
|
+
const history = telemetryHistory.get(key);
|
|
7403
|
+
if (!history || history.length < 2) return "stable";
|
|
7404
|
+
const previousValue = history[history.length - 2].y;
|
|
7405
|
+
const diff = currentValue - previousValue;
|
|
7406
|
+
const threshold = previousValue * 0.02;
|
|
7407
|
+
if (diff > threshold) return "up";
|
|
7408
|
+
if (diff < -threshold) return "down";
|
|
7409
|
+
return "stable";
|
|
7410
|
+
}
|
|
7411
|
+
function updateTelemetryCards(values) {
|
|
7412
|
+
telemetryCards.innerHTML = values.map((tel) => {
|
|
7413
|
+
const trend = calculateTrend(tel.key, tel.value);
|
|
7414
|
+
const trendIcon = trend === "up" ? "\u2197" : trend === "down" ? "\u2198" : "\u2192";
|
|
7415
|
+
const trendClass = trend;
|
|
7416
|
+
const trendLabel = strings[`trend_${trend}`] || "";
|
|
7417
|
+
return `
|
|
7418
|
+
<div class="myio-telemetry-card">
|
|
7419
|
+
<div class="myio-telemetry-card-header">
|
|
7420
|
+
<span class="myio-telemetry-card-icon">${tel.icon}</span>
|
|
7421
|
+
<span>${tel.label}</span>
|
|
7422
|
+
</div>
|
|
7423
|
+
<div class="myio-telemetry-card-value">${tel.formatted}</div>
|
|
7424
|
+
<div class="myio-telemetry-card-trend ${trendClass}">
|
|
7425
|
+
${trendIcon} ${trendLabel}
|
|
7426
|
+
</div>
|
|
7427
|
+
</div>
|
|
7428
|
+
`;
|
|
7429
|
+
}).join("");
|
|
7430
|
+
}
|
|
7431
|
+
function updateHistory(values) {
|
|
7432
|
+
const now = Date.now();
|
|
7433
|
+
for (const tel of values) {
|
|
7434
|
+
if (!telemetryHistory.has(tel.key)) {
|
|
7435
|
+
telemetryHistory.set(tel.key, []);
|
|
7436
|
+
}
|
|
7437
|
+
const history = telemetryHistory.get(tel.key);
|
|
7438
|
+
history.push({ x: now, y: tel.value });
|
|
7439
|
+
if (history.length > historyPoints) {
|
|
7440
|
+
history.shift();
|
|
7441
|
+
}
|
|
7442
|
+
}
|
|
7443
|
+
if (telemetryHistory.has("power") && chart) {
|
|
7444
|
+
const powerHistory = telemetryHistory.get("power");
|
|
7445
|
+
chart.data.datasets[0].data = powerHistory;
|
|
7446
|
+
chart.update("none");
|
|
7447
|
+
}
|
|
7448
|
+
}
|
|
7449
|
+
function initializeChart() {
|
|
7450
|
+
const Chart = window.Chart;
|
|
7451
|
+
if (!Chart) {
|
|
7452
|
+
console.warn("[RealTimeTelemetry] Chart.js not loaded");
|
|
7453
|
+
return;
|
|
7454
|
+
}
|
|
7455
|
+
chartContainer.style.display = "block";
|
|
7456
|
+
chart = new Chart(chartCanvas, {
|
|
7457
|
+
type: "line",
|
|
7458
|
+
data: {
|
|
7459
|
+
datasets: [{
|
|
7460
|
+
label: "Pot\xEAncia",
|
|
7461
|
+
data: [],
|
|
7462
|
+
borderColor: "#667eea",
|
|
7463
|
+
backgroundColor: "rgba(102, 126, 234, 0.1)",
|
|
7464
|
+
borderWidth: 2,
|
|
7465
|
+
fill: true,
|
|
7466
|
+
tension: 0.4,
|
|
7467
|
+
pointRadius: 0
|
|
7468
|
+
}]
|
|
7469
|
+
},
|
|
7470
|
+
options: {
|
|
7471
|
+
responsive: true,
|
|
7472
|
+
maintainAspectRatio: false,
|
|
7473
|
+
plugins: {
|
|
7474
|
+
legend: { display: false },
|
|
7475
|
+
tooltip: {
|
|
7476
|
+
callbacks: {
|
|
7477
|
+
title: function(context) {
|
|
7478
|
+
const timestamp = context[0].parsed.x;
|
|
7479
|
+
const date = new Date(timestamp);
|
|
7480
|
+
return date.toLocaleTimeString(locale);
|
|
7481
|
+
},
|
|
7482
|
+
label: function(context) {
|
|
7483
|
+
return `${context.parsed.y.toFixed(2)} kW`;
|
|
7484
|
+
}
|
|
7485
|
+
}
|
|
7486
|
+
}
|
|
7487
|
+
},
|
|
7488
|
+
scales: {
|
|
7489
|
+
x: {
|
|
7490
|
+
type: "linear",
|
|
7491
|
+
ticks: {
|
|
7492
|
+
callback: function(value) {
|
|
7493
|
+
const date = new Date(value);
|
|
7494
|
+
return date.toLocaleTimeString(locale, { hour: "2-digit", minute: "2-digit" });
|
|
7495
|
+
}
|
|
7496
|
+
}
|
|
7497
|
+
},
|
|
7498
|
+
y: {
|
|
7499
|
+
beginAtZero: true,
|
|
7500
|
+
title: {
|
|
7501
|
+
display: true,
|
|
7502
|
+
text: "kW"
|
|
7503
|
+
}
|
|
7504
|
+
}
|
|
7505
|
+
}
|
|
7506
|
+
}
|
|
7507
|
+
});
|
|
7508
|
+
}
|
|
7509
|
+
async function refreshData() {
|
|
7510
|
+
try {
|
|
7511
|
+
const data = await fetchLatestTelemetry();
|
|
7512
|
+
const values = processTelemetryData(data);
|
|
7513
|
+
updateHistory(values);
|
|
7514
|
+
updateTelemetryCards(values);
|
|
7515
|
+
const now = /* @__PURE__ */ new Date();
|
|
7516
|
+
lastUpdateText.textContent = `${strings.lastUpdate}: ${now.toLocaleTimeString(locale)}`;
|
|
7517
|
+
if (loadingState.style.display !== "none") {
|
|
7518
|
+
loadingState.style.display = "none";
|
|
7519
|
+
telemetryContent.style.display = "block";
|
|
7520
|
+
if (telemetryKeys.includes("power")) {
|
|
7521
|
+
initializeChart();
|
|
7522
|
+
}
|
|
7523
|
+
}
|
|
7524
|
+
} catch (error) {
|
|
7525
|
+
console.error("[RealTimeTelemetry] Error fetching data:", error);
|
|
7526
|
+
errorState.style.display = "block";
|
|
7527
|
+
loadingState.style.display = "none";
|
|
7528
|
+
telemetryContent.style.display = "none";
|
|
7529
|
+
}
|
|
7530
|
+
}
|
|
7531
|
+
function togglePause() {
|
|
7532
|
+
isPaused = !isPaused;
|
|
7533
|
+
if (isPaused) {
|
|
7534
|
+
if (refreshIntervalId) {
|
|
7535
|
+
clearInterval(refreshIntervalId);
|
|
7536
|
+
refreshIntervalId = null;
|
|
7537
|
+
}
|
|
7538
|
+
pauseBtnIcon.textContent = "\u25B6\uFE0F";
|
|
7539
|
+
pauseBtnText.textContent = strings.resume;
|
|
7540
|
+
statusIndicator.classList.add("paused");
|
|
7541
|
+
statusText.textContent = `${strings.autoUpdate}: OFF`;
|
|
7542
|
+
} else {
|
|
7543
|
+
refreshIntervalId = window.setInterval(refreshData, refreshInterval);
|
|
7544
|
+
pauseBtnIcon.textContent = "\u23F8\uFE0F";
|
|
7545
|
+
pauseBtnText.textContent = strings.pause;
|
|
7546
|
+
statusIndicator.classList.remove("paused");
|
|
7547
|
+
statusText.textContent = `${strings.autoUpdate}: ON`;
|
|
7548
|
+
}
|
|
7549
|
+
}
|
|
7550
|
+
function exportToCSV2() {
|
|
7551
|
+
const rows = [];
|
|
7552
|
+
rows.push("Timestamp," + telemetryKeys.map((k) => TELEMETRY_CONFIG[k]?.label || k).join(","));
|
|
7553
|
+
let maxLength = 0;
|
|
7554
|
+
for (const key of telemetryKeys) {
|
|
7555
|
+
const history = telemetryHistory.get(key);
|
|
7556
|
+
if (history && history.length > maxLength) {
|
|
7557
|
+
maxLength = history.length;
|
|
7558
|
+
}
|
|
7559
|
+
}
|
|
7560
|
+
for (let i = 0; i < maxLength; i++) {
|
|
7561
|
+
const row = [];
|
|
7562
|
+
let timestamp = "";
|
|
7563
|
+
for (const key of telemetryKeys) {
|
|
7564
|
+
const history = telemetryHistory.get(key);
|
|
7565
|
+
if (history && history[i]) {
|
|
7566
|
+
if (!timestamp) {
|
|
7567
|
+
timestamp = new Date(history[i].x).toISOString();
|
|
7568
|
+
}
|
|
7569
|
+
row.push(history[i].y.toFixed(2));
|
|
7570
|
+
} else {
|
|
7571
|
+
row.push("");
|
|
7572
|
+
}
|
|
7573
|
+
}
|
|
7574
|
+
if (timestamp) {
|
|
7575
|
+
rows.push(timestamp + "," + row.join(","));
|
|
7576
|
+
}
|
|
7577
|
+
}
|
|
7578
|
+
const csv = rows.join("\n");
|
|
7579
|
+
const blob = new Blob([csv], { type: "text/csv" });
|
|
7580
|
+
const url = URL.createObjectURL(blob);
|
|
7581
|
+
const a = document.createElement("a");
|
|
7582
|
+
a.href = url;
|
|
7583
|
+
a.download = `telemetry_${deviceLabel}_${(/* @__PURE__ */ new Date()).toISOString()}.csv`;
|
|
7584
|
+
a.click();
|
|
7585
|
+
URL.revokeObjectURL(url);
|
|
7586
|
+
}
|
|
7587
|
+
closeBtn.addEventListener("click", closeModal);
|
|
7588
|
+
pauseBtn.addEventListener("click", togglePause);
|
|
7589
|
+
exportBtn.addEventListener("click", exportToCSV2);
|
|
7590
|
+
overlay.addEventListener("click", (e) => {
|
|
7591
|
+
if (e.target === overlay) {
|
|
7592
|
+
closeModal();
|
|
7593
|
+
}
|
|
7594
|
+
});
|
|
7595
|
+
await refreshData();
|
|
7596
|
+
refreshIntervalId = window.setInterval(refreshData, refreshInterval);
|
|
7597
|
+
return {
|
|
7598
|
+
destroy: closeModal
|
|
7599
|
+
};
|
|
7600
|
+
}
|
|
7601
|
+
|
|
6976
7602
|
// src/components/premium-modals/internal/styles/tokens.ts
|
|
6977
7603
|
var CSS_TOKENS = `
|
|
6978
7604
|
:root {
|
|
@@ -8411,7 +9037,7 @@ ${rangeText}`;
|
|
|
8411
9037
|
var jsPdfLoaded = false;
|
|
8412
9038
|
var _jspdfPromise = null;
|
|
8413
9039
|
var cssInjected = false;
|
|
8414
|
-
var
|
|
9040
|
+
var STRINGS2 = {
|
|
8415
9041
|
"pt-BR": {
|
|
8416
9042
|
title: "Demanda",
|
|
8417
9043
|
period: "Per\xEDodo",
|
|
@@ -8998,6 +9624,32 @@ ${rangeText}`;
|
|
|
8998
9624
|
year: "numeric"
|
|
8999
9625
|
});
|
|
9000
9626
|
}
|
|
9627
|
+
function interpolateTemperatureData(rawPoints) {
|
|
9628
|
+
if (rawPoints.length === 0) return [];
|
|
9629
|
+
const interpolated = [];
|
|
9630
|
+
const interval = 30 * 60 * 1e3;
|
|
9631
|
+
const sorted = [...rawPoints].sort((a, b) => a.x - b.x);
|
|
9632
|
+
const startTime = sorted[0].x;
|
|
9633
|
+
const endTime = sorted[sorted.length - 1].x;
|
|
9634
|
+
let lastKnownValue = sorted[0].y;
|
|
9635
|
+
let dataIndex = 0;
|
|
9636
|
+
for (let time = startTime; time <= endTime; time += interval) {
|
|
9637
|
+
const actualPoint = sorted.find((p, idx) => {
|
|
9638
|
+
if (idx >= dataIndex && Math.abs(p.x - time) < 5 * 60 * 1e3) {
|
|
9639
|
+
dataIndex = idx + 1;
|
|
9640
|
+
return true;
|
|
9641
|
+
}
|
|
9642
|
+
return false;
|
|
9643
|
+
});
|
|
9644
|
+
if (actualPoint) {
|
|
9645
|
+
lastKnownValue = actualPoint.y;
|
|
9646
|
+
interpolated.push({ x: time, y: lastKnownValue });
|
|
9647
|
+
} else {
|
|
9648
|
+
interpolated.push({ x: time, y: lastKnownValue });
|
|
9649
|
+
}
|
|
9650
|
+
}
|
|
9651
|
+
return interpolated;
|
|
9652
|
+
}
|
|
9001
9653
|
async function fetchTelemetryData(token, deviceId, startDate, endDate, queryParams) {
|
|
9002
9654
|
const startTs = new Date(startDate).getTime();
|
|
9003
9655
|
const endTs = new Date(endDate).getTime();
|
|
@@ -9136,7 +9788,7 @@ ${rangeText}`;
|
|
|
9136
9788
|
}
|
|
9137
9789
|
const styles = { ...DEFAULT_STYLES, ...params.styles };
|
|
9138
9790
|
const locale = params.locale || "pt-BR";
|
|
9139
|
-
const strings =
|
|
9791
|
+
const strings = STRINGS2[locale] || STRINGS2["pt-BR"];
|
|
9140
9792
|
await loadExternalLibraries();
|
|
9141
9793
|
injectCSS(styles);
|
|
9142
9794
|
const container = typeof params.container === "string" ? document.querySelector(params.container) : params.container || document.body;
|
|
@@ -9702,6 +10354,12 @@ ${rangeText}`;
|
|
|
9702
10354
|
params.timezoneOffset
|
|
9703
10355
|
// Pass timezone offset (default: -3)
|
|
9704
10356
|
);
|
|
10357
|
+
if (params.readingType === "temperature" && !chartData.isEmpty) {
|
|
10358
|
+
chartData.series = chartData.series.map((series) => ({
|
|
10359
|
+
...series,
|
|
10360
|
+
points: interpolateTemperatureData(series.points)
|
|
10361
|
+
}));
|
|
10362
|
+
}
|
|
9705
10363
|
if (chartData.isEmpty) {
|
|
9706
10364
|
errorEl.style.display = "flex";
|
|
9707
10365
|
errorText.textContent = strings.noData;
|
|
@@ -9733,11 +10391,21 @@ ${rangeText}`;
|
|
|
9733
10391
|
title: function(context) {
|
|
9734
10392
|
const timestamp = context[0].parsed.x;
|
|
9735
10393
|
const date = new Date(timestamp);
|
|
9736
|
-
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
|
|
9740
|
-
|
|
10394
|
+
if (params.readingType === "temperature") {
|
|
10395
|
+
return date.toLocaleString(locale, {
|
|
10396
|
+
day: "2-digit",
|
|
10397
|
+
month: "2-digit",
|
|
10398
|
+
year: "numeric",
|
|
10399
|
+
hour: "2-digit",
|
|
10400
|
+
minute: "2-digit"
|
|
10401
|
+
});
|
|
10402
|
+
} else {
|
|
10403
|
+
return date.toLocaleDateString(locale, {
|
|
10404
|
+
day: "2-digit",
|
|
10405
|
+
month: "2-digit",
|
|
10406
|
+
year: "numeric"
|
|
10407
|
+
});
|
|
10408
|
+
}
|
|
9741
10409
|
},
|
|
9742
10410
|
label: function(context) {
|
|
9743
10411
|
const seriesLabel = context.dataset.label || "";
|
|
@@ -9745,6 +10413,20 @@ ${rangeText}`;
|
|
|
9745
10413
|
return `${seriesLabel}: ${value.toFixed(2)} kW`;
|
|
9746
10414
|
}
|
|
9747
10415
|
};
|
|
10416
|
+
chart.options.scales.x.ticks.callback = function(value) {
|
|
10417
|
+
const date = new Date(value);
|
|
10418
|
+
if (params.readingType === "temperature") {
|
|
10419
|
+
return date.toLocaleTimeString(locale, {
|
|
10420
|
+
hour: "2-digit",
|
|
10421
|
+
minute: "2-digit"
|
|
10422
|
+
});
|
|
10423
|
+
} else {
|
|
10424
|
+
return date.toLocaleDateString(locale, {
|
|
10425
|
+
day: "2-digit",
|
|
10426
|
+
month: "2-digit"
|
|
10427
|
+
});
|
|
10428
|
+
}
|
|
10429
|
+
};
|
|
9748
10430
|
chart.update();
|
|
9749
10431
|
} else {
|
|
9750
10432
|
chart = new Chart(chartCanvas, {
|
|
@@ -9776,11 +10458,21 @@ ${rangeText}`;
|
|
|
9776
10458
|
title: function(context) {
|
|
9777
10459
|
const timestamp = context[0].parsed.x;
|
|
9778
10460
|
const date = new Date(timestamp);
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
10461
|
+
if (params.readingType === "temperature") {
|
|
10462
|
+
return date.toLocaleString(locale, {
|
|
10463
|
+
day: "2-digit",
|
|
10464
|
+
month: "2-digit",
|
|
10465
|
+
year: "numeric",
|
|
10466
|
+
hour: "2-digit",
|
|
10467
|
+
minute: "2-digit"
|
|
10468
|
+
});
|
|
10469
|
+
} else {
|
|
10470
|
+
return date.toLocaleDateString(locale, {
|
|
10471
|
+
day: "2-digit",
|
|
10472
|
+
month: "2-digit",
|
|
10473
|
+
year: "numeric"
|
|
10474
|
+
});
|
|
10475
|
+
}
|
|
9784
10476
|
},
|
|
9785
10477
|
label: function(context) {
|
|
9786
10478
|
const seriesLabel = context.dataset.label || "";
|
|
@@ -9814,10 +10506,17 @@ ${rangeText}`;
|
|
|
9814
10506
|
ticks: {
|
|
9815
10507
|
callback: function(value) {
|
|
9816
10508
|
const date = new Date(value);
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
10509
|
+
if (params.readingType === "temperature") {
|
|
10510
|
+
return date.toLocaleTimeString(locale, {
|
|
10511
|
+
hour: "2-digit",
|
|
10512
|
+
minute: "2-digit"
|
|
10513
|
+
});
|
|
10514
|
+
} else {
|
|
10515
|
+
return date.toLocaleDateString(locale, {
|
|
10516
|
+
day: "2-digit",
|
|
10517
|
+
month: "2-digit"
|
|
10518
|
+
});
|
|
10519
|
+
}
|
|
9821
10520
|
}
|
|
9822
10521
|
}
|
|
9823
10522
|
},
|
|
@@ -10082,6 +10781,16 @@ ${rangeText}`;
|
|
|
10082
10781
|
Exportar CSV
|
|
10083
10782
|
</button>
|
|
10084
10783
|
${this.config.params.readingType === "energy" && this.config.params.mode !== "comparison" ? `
|
|
10784
|
+
<button id="view-demand-btn" class="myio-btn myio-btn-secondary" style="
|
|
10785
|
+
background: linear-gradient(135deg, #1976D2 0%, #2196F3 100%);
|
|
10786
|
+
color: white;
|
|
10787
|
+
border: none;
|
|
10788
|
+
transition: all 0.3s ease;
|
|
10789
|
+
box-shadow: 0 2px 8px rgba(25, 118, 210, 0.3);
|
|
10790
|
+
">
|
|
10791
|
+
<span style="font-size: 16px; margin-right: 4px;">\u{1F4CA}</span>
|
|
10792
|
+
Pico de Demanda
|
|
10793
|
+
</button>
|
|
10085
10794
|
<button id="view-telemetry-btn" class="myio-btn myio-btn-secondary" style="
|
|
10086
10795
|
background: linear-gradient(135deg, #4A148C 0%, #6A1B9A 100%);
|
|
10087
10796
|
color: white;
|
|
@@ -10707,42 +11416,64 @@ ${rangeText}`;
|
|
|
10707
11416
|
if (loadBtn) {
|
|
10708
11417
|
loadBtn.addEventListener("click", () => this.loadData());
|
|
10709
11418
|
}
|
|
10710
|
-
const
|
|
10711
|
-
if (
|
|
10712
|
-
|
|
11419
|
+
const viewDemandBtn = document.getElementById("view-demand-btn");
|
|
11420
|
+
if (viewDemandBtn) {
|
|
11421
|
+
viewDemandBtn.addEventListener("click", async () => {
|
|
10713
11422
|
try {
|
|
10714
|
-
console.log("[EnergyModalView] Opening demand modal");
|
|
11423
|
+
console.log("[EnergyModalView] Opening demand modal (Pico de Demanda)");
|
|
10715
11424
|
const jwtToken = localStorage.getItem("jwt_token");
|
|
10716
11425
|
if (!jwtToken) {
|
|
10717
11426
|
throw new Error("Token de autentica\xE7\xE3o n\xE3o encontrado");
|
|
10718
11427
|
}
|
|
10719
|
-
let startDate
|
|
10720
|
-
let endDate
|
|
11428
|
+
let startDate;
|
|
11429
|
+
let endDate;
|
|
10721
11430
|
if (this.dateRangePicker) {
|
|
10722
|
-
const dates = this.dateRangePicker.
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
|
|
11431
|
+
const dates = this.dateRangePicker.getRange();
|
|
11432
|
+
startDate = dates.startISO;
|
|
11433
|
+
endDate = dates.endISO;
|
|
11434
|
+
} else {
|
|
11435
|
+
startDate = this.config.params.startDate instanceof Date ? this.config.params.startDate.toISOString() : this.config.params.startDate;
|
|
11436
|
+
endDate = this.config.params.endDate instanceof Date ? this.config.params.endDate.toISOString() : this.config.params.endDate;
|
|
10727
11437
|
}
|
|
10728
11438
|
await openDemandModal({
|
|
10729
11439
|
token: jwtToken,
|
|
10730
11440
|
deviceId: this.config.params.deviceId,
|
|
10731
|
-
startDate
|
|
10732
|
-
endDate
|
|
10733
|
-
label: this.config.params.
|
|
10734
|
-
|
|
10735
|
-
|
|
10736
|
-
|
|
10737
|
-
|
|
10738
|
-
|
|
10739
|
-
agg: "MAX",
|
|
10740
|
-
// default, can be changed inside modal
|
|
10741
|
-
limit: 1e4
|
|
10742
|
-
}
|
|
11441
|
+
startDate,
|
|
11442
|
+
endDate,
|
|
11443
|
+
label: this.config.params.deviceLabel || "Dispositivo",
|
|
11444
|
+
locale: "pt-BR",
|
|
11445
|
+
readingType: this.config.params.readingType || "energy",
|
|
11446
|
+
enableRealTimeMode: true,
|
|
11447
|
+
realTimeInterval: 8e3,
|
|
11448
|
+
realTimeAutoScroll: true
|
|
10743
11449
|
});
|
|
10744
11450
|
} catch (error) {
|
|
10745
11451
|
console.error("[EnergyModalView] Error opening demand modal:", error);
|
|
11452
|
+
this.showError("Erro ao abrir pico de demanda: " + error.message);
|
|
11453
|
+
}
|
|
11454
|
+
});
|
|
11455
|
+
}
|
|
11456
|
+
const viewTelemetryBtn = document.getElementById("view-telemetry-btn");
|
|
11457
|
+
if (viewTelemetryBtn) {
|
|
11458
|
+
viewTelemetryBtn.addEventListener("click", async () => {
|
|
11459
|
+
try {
|
|
11460
|
+
console.log("[EnergyModalView] Opening real-time telemetry modal");
|
|
11461
|
+
const jwtToken = localStorage.getItem("jwt_token");
|
|
11462
|
+
if (!jwtToken) {
|
|
11463
|
+
throw new Error("Token de autentica\xE7\xE3o n\xE3o encontrado");
|
|
11464
|
+
}
|
|
11465
|
+
await openRealTimeTelemetryModal({
|
|
11466
|
+
token: jwtToken,
|
|
11467
|
+
deviceId: this.config.params.deviceId,
|
|
11468
|
+
deviceLabel: this.config.params.deviceLabel || "Dispositivo",
|
|
11469
|
+
telemetryKeys: ["voltage", "current", "power", "energy"],
|
|
11470
|
+
refreshInterval: 8e3,
|
|
11471
|
+
// 8 seconds
|
|
11472
|
+
historyPoints: 50,
|
|
11473
|
+
locale: "pt-BR"
|
|
11474
|
+
});
|
|
11475
|
+
} catch (error) {
|
|
11476
|
+
console.error("[EnergyModalView] Error opening real-time telemetry modal:", error);
|
|
10746
11477
|
this.showError("Erro ao abrir telemetrias: " + error.message);
|
|
10747
11478
|
}
|
|
10748
11479
|
});
|
|
@@ -18694,6 +19425,7 @@ ${rangeText}`;
|
|
|
18694
19425
|
exports.openDashboardPopupWaterTank = openDashboardPopupWaterTank;
|
|
18695
19426
|
exports.openDemandModal = openDemandModal;
|
|
18696
19427
|
exports.openGoalsPanel = openGoalsPanel;
|
|
19428
|
+
exports.openRealTimeTelemetryModal = openRealTimeTelemetryModal;
|
|
18697
19429
|
exports.parseInputDateToDate = parseInputDateToDate;
|
|
18698
19430
|
exports.renderCardComponent = renderCardComponent;
|
|
18699
19431
|
exports.renderCardComponentEnhanced = renderCardComponent2;
|