myio-js-library 0.1.494 → 0.1.495
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 +87 -14
- package/dist/index.js +87 -14
- package/dist/myio-js-library.umd.js +86 -14
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1162,7 +1162,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
1162
1162
|
// package.json
|
|
1163
1163
|
var package_default = {
|
|
1164
1164
|
name: "myio-js-library",
|
|
1165
|
-
version: "0.1.
|
|
1165
|
+
version: "0.1.495",
|
|
1166
1166
|
description: "A clean, standalone JS SDK for MYIO projects",
|
|
1167
1167
|
license: "MIT",
|
|
1168
1168
|
repository: "github:gh-myio/myio-js-library",
|
|
@@ -23680,13 +23680,13 @@ function createDateRangePicker($2, input, opts) {
|
|
|
23680
23680
|
const now = moment();
|
|
23681
23681
|
ranges = {
|
|
23682
23682
|
"\xDAltima hora": [moment().subtract(1, "hours"), now.clone()],
|
|
23683
|
-
"\xDAltimas 6 horas": [moment().subtract(6, "hours"), now.clone()],
|
|
23684
23683
|
"\xDAltimas 12 horas": [moment().subtract(12, "hours"), now.clone()],
|
|
23685
23684
|
"\xDAltimas 24 horas": [moment().subtract(24, "hours"), now.clone()],
|
|
23686
23685
|
"Hoje": [moment().startOf("day"), now.clone()],
|
|
23687
23686
|
"Ontem": [moment().subtract(1, "day").startOf("day"), moment().subtract(1, "day").endOf("day")],
|
|
23688
23687
|
"\xDAltimos 7 dias": [moment().subtract(6, "days").startOf("day"), now.clone()],
|
|
23689
|
-
"Este m\xEAs": [moment().startOf("month"), now.clone()]
|
|
23688
|
+
"Este m\xEAs": [moment().startOf("month"), now.clone()],
|
|
23689
|
+
"M\xEAs Anterior": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")]
|
|
23690
23690
|
};
|
|
23691
23691
|
} else {
|
|
23692
23692
|
ranges = {
|
|
@@ -23932,11 +23932,14 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
23932
23932
|
const isMyioUser = !!userEmail?.toLowerCase().includes("@myio.com.br");
|
|
23933
23933
|
let checkDeviceIntervalMs = 3e4;
|
|
23934
23934
|
let checkDeviceWaitMs = 15e3;
|
|
23935
|
+
const SESSION_LIMIT_MS = 5 * 60 * 1e3;
|
|
23935
23936
|
let refreshIntervalId = null;
|
|
23936
23937
|
let countdownTimerId = null;
|
|
23937
23938
|
let nextTickAt = 0;
|
|
23938
23939
|
let isFirstTick = true;
|
|
23939
23940
|
let isPaused = false;
|
|
23941
|
+
let sessionCountdownTimerId = null;
|
|
23942
|
+
let sessionExpiresAt = 0;
|
|
23940
23943
|
let cardTooltipEl = null;
|
|
23941
23944
|
let cardTooltipKey = null;
|
|
23942
23945
|
let cardTooltipPinned = false;
|
|
@@ -24889,7 +24892,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
24889
24892
|
<div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:16px;">
|
|
24890
24893
|
<div class="myio-rtt-mode-tabs" id="rtt-mode-tabs">
|
|
24891
24894
|
<button class="myio-rtt-tab active" data-mode="realtime">Realtime</button>
|
|
24892
|
-
<button class="myio-rtt-tab" data-mode="period">Per\xEDodo</button>
|
|
24895
|
+
<button class="myio-rtt-tab" data-mode="period">Pro Per\xEDodo</button>
|
|
24893
24896
|
</div>
|
|
24894
24897
|
<div class="myio-rtt-period-input" id="rtt-period-row">
|
|
24895
24898
|
<div class="myio-rtt-period-controls">
|
|
@@ -24955,6 +24958,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
24955
24958
|
</div>
|
|
24956
24959
|
|
|
24957
24960
|
<div class="myio-telemetry-actions">
|
|
24961
|
+
<span id="rtt-session-countdown" style="display:none;font-size:12px;font-weight:600;color:#667eea;background:rgba(102,126,234,0.1);padding:2px 10px;border-radius:10px;white-space:nowrap;"></span>
|
|
24958
24962
|
<button class="myio-telemetry-btn myio-telemetry-btn-secondary" id="pause-btn">
|
|
24959
24963
|
<span id="pause-btn-icon">\u23F8\uFE0F</span>
|
|
24960
24964
|
<span id="pause-btn-text">${strings.pause}</span>
|
|
@@ -24979,6 +24983,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
24979
24983
|
const pauseBtn = overlay.querySelector("#pause-btn");
|
|
24980
24984
|
const pauseBtnIcon = overlay.querySelector("#pause-btn-icon");
|
|
24981
24985
|
const pauseBtnText = overlay.querySelector("#pause-btn-text");
|
|
24986
|
+
const sessionCountdownEl = overlay.querySelector("#rtt-session-countdown");
|
|
24982
24987
|
const exportBtn = overlay.querySelector("#export-btn");
|
|
24983
24988
|
const loadingState = overlay.querySelector("#loading-state");
|
|
24984
24989
|
const telemetryContent = overlay.querySelector("#telemetry-content");
|
|
@@ -25000,6 +25005,26 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25000
25005
|
const countdownText = overlay.querySelector("#rtt-countdown-text");
|
|
25001
25006
|
const centralBadge = overlay.querySelector("#rtt-central-badge");
|
|
25002
25007
|
const deviceBadge = overlay.querySelector("#rtt-device-badge");
|
|
25008
|
+
const chartTitleEl = overlay.querySelector("#chart-title");
|
|
25009
|
+
function updateChartTitle() {
|
|
25010
|
+
if (!chartTitleEl) return;
|
|
25011
|
+
if (currentMode === "period") {
|
|
25012
|
+
chartTitleEl.innerHTML = "Hist\xF3rico de Telemetria";
|
|
25013
|
+
return;
|
|
25014
|
+
}
|
|
25015
|
+
const deviceOk = lastTelemetryUpdateMs > 0 && Date.now() - lastTelemetryUpdateMs <= DEVICE_OK_DELTA_MS;
|
|
25016
|
+
let iconHtml = "";
|
|
25017
|
+
if (centralStatus === "unknown") {
|
|
25018
|
+
iconHtml = "";
|
|
25019
|
+
} else if (centralStatus === "ok" && deviceOk) {
|
|
25020
|
+
iconHtml = `<span title="Central online e dispositivo online" style="margin-left:8px;cursor:default;font-size:16px;vertical-align:middle;">\u2705</span>`;
|
|
25021
|
+
} else if (centralStatus === "ok" && !deviceOk) {
|
|
25022
|
+
iconHtml = `<span title="Central online e dispositivo offline / conex\xE3o fraca" style="margin-left:8px;cursor:default;font-size:16px;vertical-align:middle;">\u26A0\uFE0F</span>`;
|
|
25023
|
+
} else {
|
|
25024
|
+
iconHtml = `<span title="Central offline" style="margin-left:8px;cursor:default;font-size:16px;vertical-align:middle;">\u{1F534}</span>`;
|
|
25025
|
+
}
|
|
25026
|
+
chartTitleEl.innerHTML = `Telemetria em Tempo Real${iconHtml}`;
|
|
25027
|
+
}
|
|
25003
25028
|
function updateStatusBadges() {
|
|
25004
25029
|
if (!centralBadge || !deviceBadge) return;
|
|
25005
25030
|
if (centralStatus === "unknown") {
|
|
@@ -25024,7 +25049,9 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25024
25049
|
deviceBadge.textContent = "Device OFFLINE";
|
|
25025
25050
|
deviceBadge.style.cssText = "display:inline-block;font-size:11px;font-weight:700;padding:2px 8px;border-radius:10px;letter-spacing:0.3px;color:#fff;background:#e74c3c;";
|
|
25026
25051
|
}
|
|
25052
|
+
updateChartTitle();
|
|
25027
25053
|
}
|
|
25054
|
+
updateChartTitle();
|
|
25028
25055
|
function startCountdown(targetMs, label = "pr\xF3xima em") {
|
|
25029
25056
|
nextTickAt = Date.now() + targetMs;
|
|
25030
25057
|
if (countdownTimerId !== null) {
|
|
@@ -25045,6 +25072,36 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25045
25072
|
}
|
|
25046
25073
|
if (countdownText) countdownText.textContent = "";
|
|
25047
25074
|
}
|
|
25075
|
+
function startSession() {
|
|
25076
|
+
stopSession();
|
|
25077
|
+
sessionExpiresAt = Date.now() + SESSION_LIMIT_MS;
|
|
25078
|
+
sessionCountdownTimerId = window.setInterval(() => {
|
|
25079
|
+
const remaining = Math.max(0, Math.ceil((sessionExpiresAt - Date.now()) / 1e3));
|
|
25080
|
+
if (sessionCountdownEl) {
|
|
25081
|
+
if (remaining > 0) {
|
|
25082
|
+
const mins = Math.floor(remaining / 60);
|
|
25083
|
+
const secs = remaining % 60;
|
|
25084
|
+
sessionCountdownEl.textContent = `\u23F1 ${mins}:${secs.toString().padStart(2, "0")}`;
|
|
25085
|
+
sessionCountdownEl.style.display = "inline-block";
|
|
25086
|
+
}
|
|
25087
|
+
}
|
|
25088
|
+
if (remaining <= 0) {
|
|
25089
|
+
stopSession();
|
|
25090
|
+
if (!isPaused) {
|
|
25091
|
+
togglePause();
|
|
25092
|
+
clearCountdown();
|
|
25093
|
+
showRTTToast("Sess\xE3o de 5 min encerrada. Clique em Retomar para continuar.", "warn");
|
|
25094
|
+
}
|
|
25095
|
+
}
|
|
25096
|
+
}, 1e3);
|
|
25097
|
+
}
|
|
25098
|
+
function stopSession() {
|
|
25099
|
+
if (sessionCountdownTimerId !== null) {
|
|
25100
|
+
clearInterval(sessionCountdownTimerId);
|
|
25101
|
+
sessionCountdownTimerId = null;
|
|
25102
|
+
}
|
|
25103
|
+
if (sessionCountdownEl) sessionCountdownEl.style.display = "none";
|
|
25104
|
+
}
|
|
25048
25105
|
function showRTTToast(message, type = "info") {
|
|
25049
25106
|
const bg = { warn: "#e67e22", error: "#e74c3c", info: "#3498db" }[type];
|
|
25050
25107
|
overlay.querySelector(".myio-rtt-toast")?.remove();
|
|
@@ -25450,6 +25507,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25450
25507
|
refreshIntervalId = null;
|
|
25451
25508
|
}
|
|
25452
25509
|
clearCountdown();
|
|
25510
|
+
stopSession();
|
|
25453
25511
|
if (chart) {
|
|
25454
25512
|
chart.destroy();
|
|
25455
25513
|
chart = null;
|
|
@@ -25713,6 +25771,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25713
25771
|
const points = series.map((pt) => {
|
|
25714
25772
|
let y = pt.value ?? 0;
|
|
25715
25773
|
if (key === "total_current" || key === "current") y = y / 1e3;
|
|
25774
|
+
if (key === "fp_a" || key === "fp_b" || key === "fp_c" || key === "powerFactor") y = y / 255;
|
|
25716
25775
|
return { x: pt.ts, y };
|
|
25717
25776
|
});
|
|
25718
25777
|
telemetryHistory.set(key, points);
|
|
@@ -25749,6 +25808,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25749
25808
|
const points = series.map((pt) => {
|
|
25750
25809
|
let y = pt.value ?? 0;
|
|
25751
25810
|
if (key === "total_current" || key === "current") y = y / 1e3;
|
|
25811
|
+
if (key === "fp_a" || key === "fp_b" || key === "fp_c" || key === "powerFactor") y = y / 255;
|
|
25752
25812
|
return { x: pt.ts, y };
|
|
25753
25813
|
});
|
|
25754
25814
|
telemetryHistory.set(key, points);
|
|
@@ -25795,6 +25855,9 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25795
25855
|
if (key === "total_current" || key === "current" || key === "current_a" || key === "current_b" || key === "current_c") {
|
|
25796
25856
|
numValue = numValue / 1e3;
|
|
25797
25857
|
}
|
|
25858
|
+
if (key === "fp_a" || key === "fp_b" || key === "fp_c" || key === "powerFactor") {
|
|
25859
|
+
numValue = numValue / 255;
|
|
25860
|
+
}
|
|
25798
25861
|
const formattedNum = numValue.toFixed(config.decimals);
|
|
25799
25862
|
const displayUnit = config.unit === "fp" ? "" : config.unit;
|
|
25800
25863
|
const formatted = displayUnit ? `${formattedNum} ${displayUnit}` : formattedNum;
|
|
@@ -26164,12 +26227,14 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
26164
26227
|
clearTimeout(refreshIntervalId);
|
|
26165
26228
|
refreshIntervalId = null;
|
|
26166
26229
|
}
|
|
26230
|
+
stopSession();
|
|
26167
26231
|
pauseBtnIcon.textContent = "\u25B6\uFE0F";
|
|
26168
26232
|
pauseBtnText.textContent = strings.resume;
|
|
26169
26233
|
statusIndicator.classList.add("paused");
|
|
26170
26234
|
statusText.textContent = `${strings.autoUpdate}: OFF`;
|
|
26171
26235
|
} else {
|
|
26172
26236
|
scheduleCheckDeviceTick();
|
|
26237
|
+
startSession();
|
|
26173
26238
|
pauseBtnIcon.textContent = "\u23F8\uFE0F";
|
|
26174
26239
|
pauseBtnText.textContent = strings.pause;
|
|
26175
26240
|
statusIndicator.classList.remove("paused");
|
|
@@ -26245,6 +26310,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
26245
26310
|
async function switchMode(mode) {
|
|
26246
26311
|
if (mode === currentMode) return;
|
|
26247
26312
|
currentMode = mode;
|
|
26313
|
+
updateChartTitle();
|
|
26248
26314
|
modeTabs.forEach((btn) => {
|
|
26249
26315
|
btn.classList.toggle("active", btn.dataset["mode"] === mode);
|
|
26250
26316
|
});
|
|
@@ -26285,6 +26351,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
26285
26351
|
isFirstTick = true;
|
|
26286
26352
|
await refreshData();
|
|
26287
26353
|
scheduleCheckDeviceTick();
|
|
26354
|
+
startSession();
|
|
26288
26355
|
}
|
|
26289
26356
|
}
|
|
26290
26357
|
}
|
|
@@ -26391,6 +26458,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
26391
26458
|
await refreshData();
|
|
26392
26459
|
isFirstTick = false;
|
|
26393
26460
|
scheduleCheckDeviceTick();
|
|
26461
|
+
startSession();
|
|
26394
26462
|
return {
|
|
26395
26463
|
destroy: closeModal2
|
|
26396
26464
|
};
|
|
@@ -30396,7 +30464,7 @@ var EnergyModalView = class {
|
|
|
30396
30464
|
token: jwtToken,
|
|
30397
30465
|
deviceId: this.config.params.deviceId,
|
|
30398
30466
|
tbBaseUrl: this.config.params.tbBaseUrl || "",
|
|
30399
|
-
deviceLabel: this.config.params.deviceLabel || "Dispositivo",
|
|
30467
|
+
deviceLabel: this.config.context.device.label || this.config.params.deviceLabel || "Dispositivo",
|
|
30400
30468
|
deviceName: this.config.context.device.name,
|
|
30401
30469
|
customerName: this.config.params.customerName,
|
|
30402
30470
|
centralId: this.config.context.resolved.centralId,
|
|
@@ -30466,7 +30534,7 @@ var EnergyModalView = class {
|
|
|
30466
30534
|
presetEnd: this.config.params.endDate instanceof Date ? this.config.params.endDate.toISOString().split("T")[0] : this.config.params.endDate,
|
|
30467
30535
|
maxRangeDays: 90,
|
|
30468
30536
|
includeTime: true,
|
|
30469
|
-
timePrecision: "
|
|
30537
|
+
timePrecision: "minute",
|
|
30470
30538
|
parentEl: this.modal.element,
|
|
30471
30539
|
onApply: ({ startISO, endISO }) => {
|
|
30472
30540
|
this.hideError();
|
|
@@ -30866,7 +30934,7 @@ var EnergyModal = class {
|
|
|
30866
30934
|
* Normalizes and validates parameters
|
|
30867
30935
|
*/
|
|
30868
30936
|
normalizeParams(params) {
|
|
30869
|
-
if (!validateJwtToken(params.tbJwtToken)) {
|
|
30937
|
+
if (!validateJwtToken(params.tbJwtToken || "")) {
|
|
30870
30938
|
throw new Error("Invalid JWT token format");
|
|
30871
30939
|
}
|
|
30872
30940
|
return {
|
|
@@ -30898,10 +30966,10 @@ var EnergyModal = class {
|
|
|
30898
30966
|
attributes: {}
|
|
30899
30967
|
},
|
|
30900
30968
|
resolved: {
|
|
30901
|
-
ingestionId:
|
|
30902
|
-
centralId:
|
|
30903
|
-
slaveId:
|
|
30904
|
-
customerId:
|
|
30969
|
+
ingestionId: void 0,
|
|
30970
|
+
centralId: void 0,
|
|
30971
|
+
slaveId: void 0,
|
|
30972
|
+
customerId: void 0
|
|
30905
30973
|
}
|
|
30906
30974
|
};
|
|
30907
30975
|
}
|
|
@@ -31037,10 +31105,10 @@ var EnergyModal = class {
|
|
|
31037
31105
|
};
|
|
31038
31106
|
const mainTitle = domainTitles[readingType] ?? "\u26A1 Gr\xE1fico de Energia";
|
|
31039
31107
|
const label = this.context?.device.label || "";
|
|
31040
|
-
const
|
|
31108
|
+
const deviceName = this.context?.device.name || this.context?.device?.attributes?.identifier || "";
|
|
31041
31109
|
const customer = this.params.customerName || "";
|
|
31042
31110
|
const version2 = window.MyIOLibrary?.version;
|
|
31043
|
-
const deviceBadge = label ? `<span class="myio-modal-header-device-label">${label}${
|
|
31111
|
+
const deviceBadge = label ? `<span class="myio-modal-header-device-label">${label}${deviceName && deviceName !== label ? `<span class="myio-modal-header-device-name">(${deviceName})</span>` : ""}</span>` : "";
|
|
31044
31112
|
const customerBadge = customer ? `<span class="myio-modal-header-customer-badge">${customer}</span>` : "";
|
|
31045
31113
|
const versionBadge = version2 ? `<span class="myio-modal-header-version-badge">v${version2}</span>` : "";
|
|
31046
31114
|
return `${mainTitle}${deviceBadge}${customerBadge}${versionBadge}`;
|
|
@@ -31169,10 +31237,15 @@ var EnergyModal = class {
|
|
|
31169
31237
|
title: "Dispositivo n\xE3o encontrado",
|
|
31170
31238
|
detail: "Este dispositivo ainda n\xE3o possui dados de telemetria cadastrados. Verifique a integra\xE7\xE3o ou contate o suporte."
|
|
31171
31239
|
};
|
|
31240
|
+
if (msg.includes("token_expired") || msg.includes("token has expired") || msg.includes("authentication token") || msg.includes("token expirou"))
|
|
31241
|
+
return {
|
|
31242
|
+
title: "Sess\xE3o expirada",
|
|
31243
|
+
detail: "Seu token de acesso expirou. Recarregue a p\xE1gina para continuar."
|
|
31244
|
+
};
|
|
31172
31245
|
if (msg.includes("insufficient permissions") || msg.includes("401") || msg.includes("403") || msg.includes("unauthorized") || msg.includes("forbidden"))
|
|
31173
31246
|
return {
|
|
31174
31247
|
title: "Sem permiss\xE3o de acesso",
|
|
31175
|
-
detail: "
|
|
31248
|
+
detail: "Voc\xEA n\xE3o tem permiss\xE3o para visualizar estes dados. Tente reabrir o modal ou contate o suporte."
|
|
31176
31249
|
};
|
|
31177
31250
|
if (msg.includes("failed to fetch") || msg.includes("networkerror") || msg.includes("network error") || msg.includes("err_network"))
|
|
31178
31251
|
return {
|
package/dist/index.js
CHANGED
|
@@ -546,7 +546,7 @@ var init_template_card = __esm({
|
|
|
546
546
|
// package.json
|
|
547
547
|
var package_default = {
|
|
548
548
|
name: "myio-js-library",
|
|
549
|
-
version: "0.1.
|
|
549
|
+
version: "0.1.495",
|
|
550
550
|
description: "A clean, standalone JS SDK for MYIO projects",
|
|
551
551
|
license: "MIT",
|
|
552
552
|
repository: "github:gh-myio/myio-js-library",
|
|
@@ -23064,13 +23064,13 @@ function createDateRangePicker($2, input, opts) {
|
|
|
23064
23064
|
const now = moment();
|
|
23065
23065
|
ranges = {
|
|
23066
23066
|
"\xDAltima hora": [moment().subtract(1, "hours"), now.clone()],
|
|
23067
|
-
"\xDAltimas 6 horas": [moment().subtract(6, "hours"), now.clone()],
|
|
23068
23067
|
"\xDAltimas 12 horas": [moment().subtract(12, "hours"), now.clone()],
|
|
23069
23068
|
"\xDAltimas 24 horas": [moment().subtract(24, "hours"), now.clone()],
|
|
23070
23069
|
"Hoje": [moment().startOf("day"), now.clone()],
|
|
23071
23070
|
"Ontem": [moment().subtract(1, "day").startOf("day"), moment().subtract(1, "day").endOf("day")],
|
|
23072
23071
|
"\xDAltimos 7 dias": [moment().subtract(6, "days").startOf("day"), now.clone()],
|
|
23073
|
-
"Este m\xEAs": [moment().startOf("month"), now.clone()]
|
|
23072
|
+
"Este m\xEAs": [moment().startOf("month"), now.clone()],
|
|
23073
|
+
"M\xEAs Anterior": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")]
|
|
23074
23074
|
};
|
|
23075
23075
|
} else {
|
|
23076
23076
|
ranges = {
|
|
@@ -23316,11 +23316,14 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
23316
23316
|
const isMyioUser = !!userEmail?.toLowerCase().includes("@myio.com.br");
|
|
23317
23317
|
let checkDeviceIntervalMs = 3e4;
|
|
23318
23318
|
let checkDeviceWaitMs = 15e3;
|
|
23319
|
+
const SESSION_LIMIT_MS = 5 * 60 * 1e3;
|
|
23319
23320
|
let refreshIntervalId = null;
|
|
23320
23321
|
let countdownTimerId = null;
|
|
23321
23322
|
let nextTickAt = 0;
|
|
23322
23323
|
let isFirstTick = true;
|
|
23323
23324
|
let isPaused = false;
|
|
23325
|
+
let sessionCountdownTimerId = null;
|
|
23326
|
+
let sessionExpiresAt = 0;
|
|
23324
23327
|
let cardTooltipEl = null;
|
|
23325
23328
|
let cardTooltipKey = null;
|
|
23326
23329
|
let cardTooltipPinned = false;
|
|
@@ -24273,7 +24276,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
24273
24276
|
<div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:16px;">
|
|
24274
24277
|
<div class="myio-rtt-mode-tabs" id="rtt-mode-tabs">
|
|
24275
24278
|
<button class="myio-rtt-tab active" data-mode="realtime">Realtime</button>
|
|
24276
|
-
<button class="myio-rtt-tab" data-mode="period">Per\xEDodo</button>
|
|
24279
|
+
<button class="myio-rtt-tab" data-mode="period">Pro Per\xEDodo</button>
|
|
24277
24280
|
</div>
|
|
24278
24281
|
<div class="myio-rtt-period-input" id="rtt-period-row">
|
|
24279
24282
|
<div class="myio-rtt-period-controls">
|
|
@@ -24339,6 +24342,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
24339
24342
|
</div>
|
|
24340
24343
|
|
|
24341
24344
|
<div class="myio-telemetry-actions">
|
|
24345
|
+
<span id="rtt-session-countdown" style="display:none;font-size:12px;font-weight:600;color:#667eea;background:rgba(102,126,234,0.1);padding:2px 10px;border-radius:10px;white-space:nowrap;"></span>
|
|
24342
24346
|
<button class="myio-telemetry-btn myio-telemetry-btn-secondary" id="pause-btn">
|
|
24343
24347
|
<span id="pause-btn-icon">\u23F8\uFE0F</span>
|
|
24344
24348
|
<span id="pause-btn-text">${strings.pause}</span>
|
|
@@ -24363,6 +24367,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
24363
24367
|
const pauseBtn = overlay.querySelector("#pause-btn");
|
|
24364
24368
|
const pauseBtnIcon = overlay.querySelector("#pause-btn-icon");
|
|
24365
24369
|
const pauseBtnText = overlay.querySelector("#pause-btn-text");
|
|
24370
|
+
const sessionCountdownEl = overlay.querySelector("#rtt-session-countdown");
|
|
24366
24371
|
const exportBtn = overlay.querySelector("#export-btn");
|
|
24367
24372
|
const loadingState = overlay.querySelector("#loading-state");
|
|
24368
24373
|
const telemetryContent = overlay.querySelector("#telemetry-content");
|
|
@@ -24384,6 +24389,26 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
24384
24389
|
const countdownText = overlay.querySelector("#rtt-countdown-text");
|
|
24385
24390
|
const centralBadge = overlay.querySelector("#rtt-central-badge");
|
|
24386
24391
|
const deviceBadge = overlay.querySelector("#rtt-device-badge");
|
|
24392
|
+
const chartTitleEl = overlay.querySelector("#chart-title");
|
|
24393
|
+
function updateChartTitle() {
|
|
24394
|
+
if (!chartTitleEl) return;
|
|
24395
|
+
if (currentMode === "period") {
|
|
24396
|
+
chartTitleEl.innerHTML = "Hist\xF3rico de Telemetria";
|
|
24397
|
+
return;
|
|
24398
|
+
}
|
|
24399
|
+
const deviceOk = lastTelemetryUpdateMs > 0 && Date.now() - lastTelemetryUpdateMs <= DEVICE_OK_DELTA_MS;
|
|
24400
|
+
let iconHtml = "";
|
|
24401
|
+
if (centralStatus === "unknown") {
|
|
24402
|
+
iconHtml = "";
|
|
24403
|
+
} else if (centralStatus === "ok" && deviceOk) {
|
|
24404
|
+
iconHtml = `<span title="Central online e dispositivo online" style="margin-left:8px;cursor:default;font-size:16px;vertical-align:middle;">\u2705</span>`;
|
|
24405
|
+
} else if (centralStatus === "ok" && !deviceOk) {
|
|
24406
|
+
iconHtml = `<span title="Central online e dispositivo offline / conex\xE3o fraca" style="margin-left:8px;cursor:default;font-size:16px;vertical-align:middle;">\u26A0\uFE0F</span>`;
|
|
24407
|
+
} else {
|
|
24408
|
+
iconHtml = `<span title="Central offline" style="margin-left:8px;cursor:default;font-size:16px;vertical-align:middle;">\u{1F534}</span>`;
|
|
24409
|
+
}
|
|
24410
|
+
chartTitleEl.innerHTML = `Telemetria em Tempo Real${iconHtml}`;
|
|
24411
|
+
}
|
|
24387
24412
|
function updateStatusBadges() {
|
|
24388
24413
|
if (!centralBadge || !deviceBadge) return;
|
|
24389
24414
|
if (centralStatus === "unknown") {
|
|
@@ -24408,7 +24433,9 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
24408
24433
|
deviceBadge.textContent = "Device OFFLINE";
|
|
24409
24434
|
deviceBadge.style.cssText = "display:inline-block;font-size:11px;font-weight:700;padding:2px 8px;border-radius:10px;letter-spacing:0.3px;color:#fff;background:#e74c3c;";
|
|
24410
24435
|
}
|
|
24436
|
+
updateChartTitle();
|
|
24411
24437
|
}
|
|
24438
|
+
updateChartTitle();
|
|
24412
24439
|
function startCountdown(targetMs, label = "pr\xF3xima em") {
|
|
24413
24440
|
nextTickAt = Date.now() + targetMs;
|
|
24414
24441
|
if (countdownTimerId !== null) {
|
|
@@ -24429,6 +24456,36 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
24429
24456
|
}
|
|
24430
24457
|
if (countdownText) countdownText.textContent = "";
|
|
24431
24458
|
}
|
|
24459
|
+
function startSession() {
|
|
24460
|
+
stopSession();
|
|
24461
|
+
sessionExpiresAt = Date.now() + SESSION_LIMIT_MS;
|
|
24462
|
+
sessionCountdownTimerId = window.setInterval(() => {
|
|
24463
|
+
const remaining = Math.max(0, Math.ceil((sessionExpiresAt - Date.now()) / 1e3));
|
|
24464
|
+
if (sessionCountdownEl) {
|
|
24465
|
+
if (remaining > 0) {
|
|
24466
|
+
const mins = Math.floor(remaining / 60);
|
|
24467
|
+
const secs = remaining % 60;
|
|
24468
|
+
sessionCountdownEl.textContent = `\u23F1 ${mins}:${secs.toString().padStart(2, "0")}`;
|
|
24469
|
+
sessionCountdownEl.style.display = "inline-block";
|
|
24470
|
+
}
|
|
24471
|
+
}
|
|
24472
|
+
if (remaining <= 0) {
|
|
24473
|
+
stopSession();
|
|
24474
|
+
if (!isPaused) {
|
|
24475
|
+
togglePause();
|
|
24476
|
+
clearCountdown();
|
|
24477
|
+
showRTTToast("Sess\xE3o de 5 min encerrada. Clique em Retomar para continuar.", "warn");
|
|
24478
|
+
}
|
|
24479
|
+
}
|
|
24480
|
+
}, 1e3);
|
|
24481
|
+
}
|
|
24482
|
+
function stopSession() {
|
|
24483
|
+
if (sessionCountdownTimerId !== null) {
|
|
24484
|
+
clearInterval(sessionCountdownTimerId);
|
|
24485
|
+
sessionCountdownTimerId = null;
|
|
24486
|
+
}
|
|
24487
|
+
if (sessionCountdownEl) sessionCountdownEl.style.display = "none";
|
|
24488
|
+
}
|
|
24432
24489
|
function showRTTToast(message, type = "info") {
|
|
24433
24490
|
const bg = { warn: "#e67e22", error: "#e74c3c", info: "#3498db" }[type];
|
|
24434
24491
|
overlay.querySelector(".myio-rtt-toast")?.remove();
|
|
@@ -24834,6 +24891,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
24834
24891
|
refreshIntervalId = null;
|
|
24835
24892
|
}
|
|
24836
24893
|
clearCountdown();
|
|
24894
|
+
stopSession();
|
|
24837
24895
|
if (chart) {
|
|
24838
24896
|
chart.destroy();
|
|
24839
24897
|
chart = null;
|
|
@@ -25097,6 +25155,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25097
25155
|
const points = series.map((pt) => {
|
|
25098
25156
|
let y = pt.value ?? 0;
|
|
25099
25157
|
if (key === "total_current" || key === "current") y = y / 1e3;
|
|
25158
|
+
if (key === "fp_a" || key === "fp_b" || key === "fp_c" || key === "powerFactor") y = y / 255;
|
|
25100
25159
|
return { x: pt.ts, y };
|
|
25101
25160
|
});
|
|
25102
25161
|
telemetryHistory.set(key, points);
|
|
@@ -25133,6 +25192,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25133
25192
|
const points = series.map((pt) => {
|
|
25134
25193
|
let y = pt.value ?? 0;
|
|
25135
25194
|
if (key === "total_current" || key === "current") y = y / 1e3;
|
|
25195
|
+
if (key === "fp_a" || key === "fp_b" || key === "fp_c" || key === "powerFactor") y = y / 255;
|
|
25136
25196
|
return { x: pt.ts, y };
|
|
25137
25197
|
});
|
|
25138
25198
|
telemetryHistory.set(key, points);
|
|
@@ -25179,6 +25239,9 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25179
25239
|
if (key === "total_current" || key === "current" || key === "current_a" || key === "current_b" || key === "current_c") {
|
|
25180
25240
|
numValue = numValue / 1e3;
|
|
25181
25241
|
}
|
|
25242
|
+
if (key === "fp_a" || key === "fp_b" || key === "fp_c" || key === "powerFactor") {
|
|
25243
|
+
numValue = numValue / 255;
|
|
25244
|
+
}
|
|
25182
25245
|
const formattedNum = numValue.toFixed(config.decimals);
|
|
25183
25246
|
const displayUnit = config.unit === "fp" ? "" : config.unit;
|
|
25184
25247
|
const formatted = displayUnit ? `${formattedNum} ${displayUnit}` : formattedNum;
|
|
@@ -25548,12 +25611,14 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25548
25611
|
clearTimeout(refreshIntervalId);
|
|
25549
25612
|
refreshIntervalId = null;
|
|
25550
25613
|
}
|
|
25614
|
+
stopSession();
|
|
25551
25615
|
pauseBtnIcon.textContent = "\u25B6\uFE0F";
|
|
25552
25616
|
pauseBtnText.textContent = strings.resume;
|
|
25553
25617
|
statusIndicator.classList.add("paused");
|
|
25554
25618
|
statusText.textContent = `${strings.autoUpdate}: OFF`;
|
|
25555
25619
|
} else {
|
|
25556
25620
|
scheduleCheckDeviceTick();
|
|
25621
|
+
startSession();
|
|
25557
25622
|
pauseBtnIcon.textContent = "\u23F8\uFE0F";
|
|
25558
25623
|
pauseBtnText.textContent = strings.pause;
|
|
25559
25624
|
statusIndicator.classList.remove("paused");
|
|
@@ -25629,6 +25694,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25629
25694
|
async function switchMode(mode) {
|
|
25630
25695
|
if (mode === currentMode) return;
|
|
25631
25696
|
currentMode = mode;
|
|
25697
|
+
updateChartTitle();
|
|
25632
25698
|
modeTabs.forEach((btn) => {
|
|
25633
25699
|
btn.classList.toggle("active", btn.dataset["mode"] === mode);
|
|
25634
25700
|
});
|
|
@@ -25669,6 +25735,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25669
25735
|
isFirstTick = true;
|
|
25670
25736
|
await refreshData();
|
|
25671
25737
|
scheduleCheckDeviceTick();
|
|
25738
|
+
startSession();
|
|
25672
25739
|
}
|
|
25673
25740
|
}
|
|
25674
25741
|
}
|
|
@@ -25775,6 +25842,7 @@ async function openRealTimeTelemetryModal(params) {
|
|
|
25775
25842
|
await refreshData();
|
|
25776
25843
|
isFirstTick = false;
|
|
25777
25844
|
scheduleCheckDeviceTick();
|
|
25845
|
+
startSession();
|
|
25778
25846
|
return {
|
|
25779
25847
|
destroy: closeModal2
|
|
25780
25848
|
};
|
|
@@ -29780,7 +29848,7 @@ var EnergyModalView = class {
|
|
|
29780
29848
|
token: jwtToken,
|
|
29781
29849
|
deviceId: this.config.params.deviceId,
|
|
29782
29850
|
tbBaseUrl: this.config.params.tbBaseUrl || "",
|
|
29783
|
-
deviceLabel: this.config.params.deviceLabel || "Dispositivo",
|
|
29851
|
+
deviceLabel: this.config.context.device.label || this.config.params.deviceLabel || "Dispositivo",
|
|
29784
29852
|
deviceName: this.config.context.device.name,
|
|
29785
29853
|
customerName: this.config.params.customerName,
|
|
29786
29854
|
centralId: this.config.context.resolved.centralId,
|
|
@@ -29850,7 +29918,7 @@ var EnergyModalView = class {
|
|
|
29850
29918
|
presetEnd: this.config.params.endDate instanceof Date ? this.config.params.endDate.toISOString().split("T")[0] : this.config.params.endDate,
|
|
29851
29919
|
maxRangeDays: 90,
|
|
29852
29920
|
includeTime: true,
|
|
29853
|
-
timePrecision: "
|
|
29921
|
+
timePrecision: "minute",
|
|
29854
29922
|
parentEl: this.modal.element,
|
|
29855
29923
|
onApply: ({ startISO, endISO }) => {
|
|
29856
29924
|
this.hideError();
|
|
@@ -30250,7 +30318,7 @@ var EnergyModal = class {
|
|
|
30250
30318
|
* Normalizes and validates parameters
|
|
30251
30319
|
*/
|
|
30252
30320
|
normalizeParams(params) {
|
|
30253
|
-
if (!validateJwtToken(params.tbJwtToken)) {
|
|
30321
|
+
if (!validateJwtToken(params.tbJwtToken || "")) {
|
|
30254
30322
|
throw new Error("Invalid JWT token format");
|
|
30255
30323
|
}
|
|
30256
30324
|
return {
|
|
@@ -30282,10 +30350,10 @@ var EnergyModal = class {
|
|
|
30282
30350
|
attributes: {}
|
|
30283
30351
|
},
|
|
30284
30352
|
resolved: {
|
|
30285
|
-
ingestionId:
|
|
30286
|
-
centralId:
|
|
30287
|
-
slaveId:
|
|
30288
|
-
customerId:
|
|
30353
|
+
ingestionId: void 0,
|
|
30354
|
+
centralId: void 0,
|
|
30355
|
+
slaveId: void 0,
|
|
30356
|
+
customerId: void 0
|
|
30289
30357
|
}
|
|
30290
30358
|
};
|
|
30291
30359
|
}
|
|
@@ -30421,10 +30489,10 @@ var EnergyModal = class {
|
|
|
30421
30489
|
};
|
|
30422
30490
|
const mainTitle = domainTitles[readingType] ?? "\u26A1 Gr\xE1fico de Energia";
|
|
30423
30491
|
const label = this.context?.device.label || "";
|
|
30424
|
-
const
|
|
30492
|
+
const deviceName = this.context?.device.name || this.context?.device?.attributes?.identifier || "";
|
|
30425
30493
|
const customer = this.params.customerName || "";
|
|
30426
30494
|
const version2 = window.MyIOLibrary?.version;
|
|
30427
|
-
const deviceBadge = label ? `<span class="myio-modal-header-device-label">${label}${
|
|
30495
|
+
const deviceBadge = label ? `<span class="myio-modal-header-device-label">${label}${deviceName && deviceName !== label ? `<span class="myio-modal-header-device-name">(${deviceName})</span>` : ""}</span>` : "";
|
|
30428
30496
|
const customerBadge = customer ? `<span class="myio-modal-header-customer-badge">${customer}</span>` : "";
|
|
30429
30497
|
const versionBadge = version2 ? `<span class="myio-modal-header-version-badge">v${version2}</span>` : "";
|
|
30430
30498
|
return `${mainTitle}${deviceBadge}${customerBadge}${versionBadge}`;
|
|
@@ -30553,10 +30621,15 @@ var EnergyModal = class {
|
|
|
30553
30621
|
title: "Dispositivo n\xE3o encontrado",
|
|
30554
30622
|
detail: "Este dispositivo ainda n\xE3o possui dados de telemetria cadastrados. Verifique a integra\xE7\xE3o ou contate o suporte."
|
|
30555
30623
|
};
|
|
30624
|
+
if (msg.includes("token_expired") || msg.includes("token has expired") || msg.includes("authentication token") || msg.includes("token expirou"))
|
|
30625
|
+
return {
|
|
30626
|
+
title: "Sess\xE3o expirada",
|
|
30627
|
+
detail: "Seu token de acesso expirou. Recarregue a p\xE1gina para continuar."
|
|
30628
|
+
};
|
|
30556
30629
|
if (msg.includes("insufficient permissions") || msg.includes("401") || msg.includes("403") || msg.includes("unauthorized") || msg.includes("forbidden"))
|
|
30557
30630
|
return {
|
|
30558
30631
|
title: "Sem permiss\xE3o de acesso",
|
|
30559
|
-
detail: "
|
|
30632
|
+
detail: "Voc\xEA n\xE3o tem permiss\xE3o para visualizar estes dados. Tente reabrir o modal ou contate o suporte."
|
|
30560
30633
|
};
|
|
30561
30634
|
if (msg.includes("failed to fetch") || msg.includes("networkerror") || msg.includes("network error") || msg.includes("err_network"))
|
|
30562
30635
|
return {
|