myio-js-library 0.1.169 → 0.1.172
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 +857 -291
- package/dist/index.d.cts +8 -3
- package/dist/index.js +857 -291
- package/dist/myio-js-library.umd.js +856 -291
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
|
@@ -1324,7 +1324,8 @@
|
|
|
1324
1324
|
FAILURE: "failure",
|
|
1325
1325
|
MAINTENANCE: "maintenance",
|
|
1326
1326
|
NO_INFO: "no_info",
|
|
1327
|
-
NOT_INSTALLED: "not_installed"
|
|
1327
|
+
NOT_INSTALLED: "not_installed",
|
|
1328
|
+
OFFLINE: "offline"
|
|
1328
1329
|
};
|
|
1329
1330
|
var ConnectionStatusType = {
|
|
1330
1331
|
CONNECTED: "connected",
|
|
@@ -1333,39 +1334,42 @@
|
|
|
1333
1334
|
var deviceStatusIcons = {
|
|
1334
1335
|
[DeviceStatusType.POWER_ON]: "\u26A1",
|
|
1335
1336
|
[DeviceStatusType.STANDBY]: "\u{1F50C}",
|
|
1336
|
-
[DeviceStatusType.POWER_OFF]: "\
|
|
1337
|
+
[DeviceStatusType.POWER_OFF]: "\u26AB",
|
|
1337
1338
|
[DeviceStatusType.WARNING]: "\u26A0\uFE0F",
|
|
1338
1339
|
[DeviceStatusType.FAILURE]: "\u{1F6A8}",
|
|
1339
1340
|
[DeviceStatusType.MAINTENANCE]: "\u{1F6E0}\uFE0F",
|
|
1340
1341
|
[DeviceStatusType.NO_INFO]: "\u2753\uFE0F",
|
|
1341
|
-
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}"
|
|
1342
|
+
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}",
|
|
1343
|
+
[DeviceStatusType.OFFLINE]: "\u{1F534}"
|
|
1342
1344
|
};
|
|
1343
1345
|
var waterDeviceStatusIcons = {
|
|
1344
1346
|
[DeviceStatusType.POWER_ON]: "\u{1F4A7}",
|
|
1345
1347
|
[DeviceStatusType.STANDBY]: "\u{1F6B0}",
|
|
1346
|
-
[DeviceStatusType.POWER_OFF]: "\
|
|
1348
|
+
[DeviceStatusType.POWER_OFF]: "\u26AB",
|
|
1347
1349
|
[DeviceStatusType.WARNING]: "\u26A0\uFE0F",
|
|
1348
1350
|
[DeviceStatusType.FAILURE]: "\u{1F6A8}",
|
|
1349
1351
|
[DeviceStatusType.MAINTENANCE]: "\u{1F6E0}\uFE0F",
|
|
1350
1352
|
[DeviceStatusType.NO_INFO]: "\u2753\uFE0F",
|
|
1351
|
-
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}"
|
|
1353
|
+
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}",
|
|
1354
|
+
[DeviceStatusType.OFFLINE]: "\u{1F534}"
|
|
1352
1355
|
};
|
|
1353
1356
|
var temperatureDeviceStatusIcons = {
|
|
1354
1357
|
[DeviceStatusType.POWER_ON]: "\u{1F321}\uFE0F",
|
|
1355
1358
|
[DeviceStatusType.STANDBY]: "\u{1F321}\uFE0F",
|
|
1356
|
-
[DeviceStatusType.POWER_OFF]: "\
|
|
1359
|
+
[DeviceStatusType.POWER_OFF]: "\u26AB",
|
|
1357
1360
|
[DeviceStatusType.WARNING]: "\u26A0\uFE0F",
|
|
1358
1361
|
[DeviceStatusType.FAILURE]: "\u{1F6A8}",
|
|
1359
1362
|
[DeviceStatusType.MAINTENANCE]: "\u{1F6E0}\uFE0F",
|
|
1360
1363
|
[DeviceStatusType.NO_INFO]: "\u2753\uFE0F",
|
|
1361
|
-
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}"
|
|
1364
|
+
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}",
|
|
1365
|
+
[DeviceStatusType.OFFLINE]: "\u{1F534}"
|
|
1362
1366
|
};
|
|
1363
1367
|
var connectionStatusIcons = {
|
|
1364
1368
|
[ConnectionStatusType.CONNECTED]: "\u{1F7E2}",
|
|
1365
1369
|
[ConnectionStatusType.OFFLINE]: "\u{1F6AB}"
|
|
1366
1370
|
};
|
|
1367
1371
|
function mapDeviceToConnectionStatus(deviceStatus) {
|
|
1368
|
-
if (deviceStatus === DeviceStatusType.NO_INFO) {
|
|
1372
|
+
if (deviceStatus === DeviceStatusType.NO_INFO || deviceStatus === DeviceStatusType.OFFLINE) {
|
|
1369
1373
|
return ConnectionStatusType.OFFLINE;
|
|
1370
1374
|
}
|
|
1371
1375
|
return ConnectionStatusType.CONNECTED;
|
|
@@ -1389,15 +1393,16 @@
|
|
|
1389
1393
|
[DeviceStatusType.FAILURE]: "fail",
|
|
1390
1394
|
[DeviceStatusType.MAINTENANCE]: "alert",
|
|
1391
1395
|
[DeviceStatusType.NO_INFO]: "unknown",
|
|
1392
|
-
[DeviceStatusType.NOT_INSTALLED]: "not_installed"
|
|
1396
|
+
[DeviceStatusType.NOT_INSTALLED]: "not_installed",
|
|
1397
|
+
[DeviceStatusType.OFFLINE]: "offline"
|
|
1393
1398
|
};
|
|
1394
1399
|
return statusMap[deviceStatus] || "unknown";
|
|
1395
1400
|
}
|
|
1396
1401
|
function shouldFlashIcon(deviceStatus) {
|
|
1397
|
-
return deviceStatus === DeviceStatusType.POWER_OFF || deviceStatus === DeviceStatusType.WARNING || deviceStatus === DeviceStatusType.FAILURE || deviceStatus === DeviceStatusType.MAINTENANCE;
|
|
1402
|
+
return deviceStatus === DeviceStatusType.POWER_OFF || deviceStatus === DeviceStatusType.WARNING || deviceStatus === DeviceStatusType.FAILURE || deviceStatus === DeviceStatusType.MAINTENANCE || deviceStatus === DeviceStatusType.OFFLINE;
|
|
1398
1403
|
}
|
|
1399
1404
|
function isDeviceOffline(deviceStatus) {
|
|
1400
|
-
return deviceStatus === DeviceStatusType.NO_INFO;
|
|
1405
|
+
return deviceStatus === DeviceStatusType.NO_INFO || deviceStatus === DeviceStatusType.OFFLINE;
|
|
1401
1406
|
}
|
|
1402
1407
|
function getDeviceStatusIcon(deviceStatus, deviceType = null) {
|
|
1403
1408
|
const normalizedType = deviceType?.toUpperCase() || "";
|
|
@@ -3953,15 +3958,30 @@
|
|
|
3953
3958
|
--myio-chip-alert-fg: #b45309;
|
|
3954
3959
|
--myio-border-alert: rgba(245, 158, 11, 0.5);
|
|
3955
3960
|
|
|
3956
|
-
/* Status colors - Failure (red) */
|
|
3961
|
+
/* Status colors - Failure (dark red) */
|
|
3957
3962
|
--myio-chip-failure-bg: #fee2e2;
|
|
3958
3963
|
--myio-chip-failure-fg: #b91c1c;
|
|
3959
|
-
--myio-border-failure: rgba(
|
|
3964
|
+
--myio-border-failure: rgba(153, 27, 27, 0.6);
|
|
3965
|
+
|
|
3966
|
+
/* Status colors - Power Off (light red) */
|
|
3967
|
+
--myio-chip-power-off-bg: #fecaca;
|
|
3968
|
+
--myio-chip-power-off-fg: #dc2626;
|
|
3969
|
+
--myio-border-power-off: rgba(239, 68, 68, 0.5);
|
|
3970
|
+
|
|
3971
|
+
/* Status colors - Offline (dark gray) */
|
|
3972
|
+
--myio-chip-offline-bg: #e2e8f0;
|
|
3973
|
+
--myio-chip-offline-fg: #475569;
|
|
3974
|
+
--myio-border-offline: rgba(71, 85, 105, 0.6);
|
|
3975
|
+
|
|
3976
|
+
/* Status colors - No Info (dark orange) */
|
|
3977
|
+
--myio-chip-no-info-bg: #fed7aa;
|
|
3978
|
+
--myio-chip-no-info-fg: #c2410c;
|
|
3979
|
+
--myio-border-no-info: rgba(194, 65, 12, 0.5);
|
|
3960
3980
|
|
|
3961
|
-
/* Status colors -
|
|
3962
|
-
--myio-chip-
|
|
3963
|
-
--myio-chip-
|
|
3964
|
-
--myio-border-
|
|
3981
|
+
/* Status colors - Not Installed (purple) */
|
|
3982
|
+
--myio-chip-not-installed-bg: #e9d5ff;
|
|
3983
|
+
--myio-chip-not-installed-fg: #7c3aed;
|
|
3984
|
+
--myio-border-not-installed: rgba(124, 58, 237, 0.5);
|
|
3965
3985
|
|
|
3966
3986
|
--myio-text-1: #0f172a;
|
|
3967
3987
|
--myio-text-2: #4b5563;
|
|
@@ -4017,26 +4037,55 @@
|
|
|
4017
4037
|
}
|
|
4018
4038
|
|
|
4019
4039
|
/* Card border states based on device status */
|
|
4020
|
-
|
|
4040
|
+
|
|
4041
|
+
/* POWER_ON - Blue */
|
|
4042
|
+
.myio-ho-card.is-power-on {
|
|
4021
4043
|
border-color: var(--myio-border-ok);
|
|
4022
4044
|
box-shadow: 0 0 0 2px var(--myio-border-ok), var(--myio-card-shadow);
|
|
4023
4045
|
}
|
|
4024
4046
|
|
|
4047
|
+
/* STANDBY - Green */
|
|
4025
4048
|
.myio-ho-card.is-standby {
|
|
4026
4049
|
border-color: var(--myio-border-standby);
|
|
4027
4050
|
box-shadow: 0 0 0 2px var(--myio-border-standby), var(--myio-card-shadow);
|
|
4028
4051
|
}
|
|
4029
4052
|
|
|
4030
|
-
|
|
4053
|
+
/* WARNING - Yellow */
|
|
4054
|
+
.myio-ho-card.is-warning {
|
|
4031
4055
|
border-color: var(--myio-border-alert);
|
|
4032
4056
|
box-shadow: 0 0 0 2px var(--myio-border-alert), var(--myio-card-shadow);
|
|
4033
4057
|
}
|
|
4034
4058
|
|
|
4059
|
+
/* MAINTENANCE - Yellow */
|
|
4060
|
+
.myio-ho-card.is-maintenance {
|
|
4061
|
+
border-color: var(--myio-border-alert);
|
|
4062
|
+
box-shadow: 0 0 0 2px var(--myio-border-alert), var(--myio-card-shadow);
|
|
4063
|
+
}
|
|
4064
|
+
|
|
4065
|
+
/* FAILURE - Dark Red */
|
|
4035
4066
|
.myio-ho-card.is-failure {
|
|
4036
4067
|
border-color: var(--myio-border-failure);
|
|
4037
4068
|
box-shadow: 0 0 0 2px var(--myio-border-failure), var(--myio-card-shadow);
|
|
4038
4069
|
}
|
|
4039
4070
|
|
|
4071
|
+
/* POWER_OFF - Light Red */
|
|
4072
|
+
.myio-ho-card.is-power-off {
|
|
4073
|
+
border-color: var(--myio-border-power-off);
|
|
4074
|
+
box-shadow: 0 0 0 2px var(--myio-border-power-off), var(--myio-card-shadow);
|
|
4075
|
+
}
|
|
4076
|
+
|
|
4077
|
+
/* NO_INFO - Dark Orange */
|
|
4078
|
+
.myio-ho-card.is-no-info {
|
|
4079
|
+
border-color: var(--myio-border-no-info);
|
|
4080
|
+
box-shadow: 0 0 0 2px var(--myio-border-no-info), var(--myio-card-shadow);
|
|
4081
|
+
}
|
|
4082
|
+
|
|
4083
|
+
/* NOT_INSTALLED - Purple */
|
|
4084
|
+
.myio-ho-card.is-not-installed {
|
|
4085
|
+
border-color: var(--myio-border-not-installed);
|
|
4086
|
+
box-shadow: 0 0 0 2px var(--myio-border-not-installed), var(--myio-card-shadow);
|
|
4087
|
+
}
|
|
4088
|
+
|
|
4040
4089
|
/* Header section */
|
|
4041
4090
|
.myio-ho-card__header {
|
|
4042
4091
|
display: flex;
|
|
@@ -4054,7 +4103,9 @@
|
|
|
4054
4103
|
margin-top: 2px;
|
|
4055
4104
|
}
|
|
4056
4105
|
|
|
4057
|
-
|
|
4106
|
+
/* Icon colors based on status */
|
|
4107
|
+
.myio-ho-card.is-warning .myio-ho-card__icon,
|
|
4108
|
+
.myio-ho-card.is-maintenance .myio-ho-card__icon {
|
|
4058
4109
|
color: var(--myio-chip-alert-fg);
|
|
4059
4110
|
}
|
|
4060
4111
|
|
|
@@ -4062,14 +4113,28 @@
|
|
|
4062
4113
|
color: var(--myio-chip-failure-fg);
|
|
4063
4114
|
}
|
|
4064
4115
|
|
|
4116
|
+
.myio-ho-card.is-power-off .myio-ho-card__icon {
|
|
4117
|
+
color: var(--myio-chip-power-off-fg);
|
|
4118
|
+
}
|
|
4119
|
+
|
|
4120
|
+
.myio-ho-card.is-offline .myio-ho-card__icon {
|
|
4121
|
+
color: var(--myio-chip-offline-fg);
|
|
4122
|
+
}
|
|
4123
|
+
|
|
4124
|
+
.myio-ho-card.is-no-info .myio-ho-card__icon {
|
|
4125
|
+
color: var(--myio-chip-no-info-fg);
|
|
4126
|
+
}
|
|
4127
|
+
|
|
4128
|
+
.myio-ho-card.is-not-installed .myio-ho-card__icon {
|
|
4129
|
+
color: var(--myio-chip-not-installed-fg);
|
|
4130
|
+
}
|
|
4131
|
+
|
|
4065
4132
|
.myio-ho-card__title {
|
|
4066
4133
|
flex: 1;
|
|
4067
4134
|
min-width: 0;
|
|
4068
4135
|
}
|
|
4069
4136
|
|
|
4070
|
-
/*
|
|
4071
|
-
|
|
4072
|
-
/* Estado Offline - borda cinza */
|
|
4137
|
+
/* OFFLINE - Dark Gray */
|
|
4073
4138
|
.myio-ho-card.is-offline {
|
|
4074
4139
|
border-color: var(--myio-border-offline);
|
|
4075
4140
|
box-shadow: 0 0 0 2px var(--myio-border-offline), var(--myio-card-shadow);
|
|
@@ -4464,6 +4529,37 @@
|
|
|
4464
4529
|
color: var(--myio-chip-offline-fg);
|
|
4465
4530
|
}
|
|
4466
4531
|
|
|
4532
|
+
/* New chip classes aligned with getCardStateClass */
|
|
4533
|
+
.chip--power-on {
|
|
4534
|
+
background: var(--myio-chip-ok-bg);
|
|
4535
|
+
color: var(--myio-chip-ok-fg);
|
|
4536
|
+
}
|
|
4537
|
+
|
|
4538
|
+
.chip--warning {
|
|
4539
|
+
background: var(--myio-chip-alert-bg);
|
|
4540
|
+
color: var(--myio-chip-alert-fg);
|
|
4541
|
+
}
|
|
4542
|
+
|
|
4543
|
+
.chip--maintenance {
|
|
4544
|
+
background: var(--myio-chip-alert-bg);
|
|
4545
|
+
color: var(--myio-chip-alert-fg);
|
|
4546
|
+
}
|
|
4547
|
+
|
|
4548
|
+
.chip--power-off {
|
|
4549
|
+
background: var(--myio-chip-power-off-bg);
|
|
4550
|
+
color: var(--myio-chip-power-off-fg);
|
|
4551
|
+
}
|
|
4552
|
+
|
|
4553
|
+
.chip--no-info {
|
|
4554
|
+
background: var(--myio-chip-no-info-bg);
|
|
4555
|
+
color: var(--myio-chip-no-info-fg);
|
|
4556
|
+
}
|
|
4557
|
+
|
|
4558
|
+
.chip--not-installed {
|
|
4559
|
+
background: var(--myio-chip-not-installed-bg);
|
|
4560
|
+
color: var(--myio-chip-not-installed-fg);
|
|
4561
|
+
}
|
|
4562
|
+
|
|
4467
4563
|
/* Status indicator dot for power metric */
|
|
4468
4564
|
.status-dot {
|
|
4469
4565
|
width: 8px;
|
|
@@ -4497,6 +4593,31 @@
|
|
|
4497
4593
|
background: var(--myio-muted);
|
|
4498
4594
|
}
|
|
4499
4595
|
|
|
4596
|
+
/* New dot classes aligned with getCardStateClass */
|
|
4597
|
+
.status-dot.dot--power-on {
|
|
4598
|
+
background: var(--myio-chip-ok-fg);
|
|
4599
|
+
}
|
|
4600
|
+
|
|
4601
|
+
.status-dot.dot--warning {
|
|
4602
|
+
background: var(--myio-chip-alert-fg);
|
|
4603
|
+
}
|
|
4604
|
+
|
|
4605
|
+
.status-dot.dot--maintenance {
|
|
4606
|
+
background: var(--myio-chip-alert-fg);
|
|
4607
|
+
}
|
|
4608
|
+
|
|
4609
|
+
.status-dot.dot--power-off {
|
|
4610
|
+
background: var(--myio-chip-power-off-fg);
|
|
4611
|
+
}
|
|
4612
|
+
|
|
4613
|
+
.status-dot.dot--no-info {
|
|
4614
|
+
background: var(--myio-chip-no-info-fg);
|
|
4615
|
+
}
|
|
4616
|
+
|
|
4617
|
+
.status-dot.dot--not-installed {
|
|
4618
|
+
background: var(--myio-chip-not-installed-fg);
|
|
4619
|
+
}
|
|
4620
|
+
|
|
4500
4621
|
/* Primary metric */
|
|
4501
4622
|
.myio-ho-card__primary {
|
|
4502
4623
|
margin-bottom: 14px;
|
|
@@ -4679,6 +4800,215 @@
|
|
|
4679
4800
|
transition: none;
|
|
4680
4801
|
}
|
|
4681
4802
|
}
|
|
4803
|
+
|
|
4804
|
+
/* ============================================
|
|
4805
|
+
DEBUG TOOLTIP STYLES (Premium)
|
|
4806
|
+
============================================ */
|
|
4807
|
+
|
|
4808
|
+
.has-debug-tooltip {
|
|
4809
|
+
cursor: help !important;
|
|
4810
|
+
}
|
|
4811
|
+
|
|
4812
|
+
.has-debug-tooltip::after {
|
|
4813
|
+
content: '\u{1F41B}';
|
|
4814
|
+
position: absolute;
|
|
4815
|
+
top: -4px;
|
|
4816
|
+
right: -4px;
|
|
4817
|
+
font-size: 10px;
|
|
4818
|
+
z-index: 1;
|
|
4819
|
+
}
|
|
4820
|
+
|
|
4821
|
+
.debug-tooltip-container {
|
|
4822
|
+
position: absolute;
|
|
4823
|
+
bottom: calc(100% + 8px);
|
|
4824
|
+
left: 50%;
|
|
4825
|
+
transform: translateX(-50%);
|
|
4826
|
+
z-index: 10000;
|
|
4827
|
+
pointer-events: none;
|
|
4828
|
+
opacity: 0;
|
|
4829
|
+
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
4830
|
+
}
|
|
4831
|
+
|
|
4832
|
+
.has-debug-tooltip:hover .debug-tooltip-container {
|
|
4833
|
+
opacity: 1;
|
|
4834
|
+
pointer-events: auto;
|
|
4835
|
+
}
|
|
4836
|
+
|
|
4837
|
+
.debug-tooltip {
|
|
4838
|
+
background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
|
|
4839
|
+
border: 1px solid rgba(99, 102, 241, 0.3);
|
|
4840
|
+
border-radius: 12px;
|
|
4841
|
+
box-shadow:
|
|
4842
|
+
0 20px 40px rgba(0, 0, 0, 0.4),
|
|
4843
|
+
0 0 0 1px rgba(255, 255, 255, 0.05),
|
|
4844
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
4845
|
+
min-width: 340px;
|
|
4846
|
+
max-width: 420px;
|
|
4847
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
4848
|
+
font-size: 12px;
|
|
4849
|
+
color: #e2e8f0;
|
|
4850
|
+
overflow: hidden;
|
|
4851
|
+
}
|
|
4852
|
+
|
|
4853
|
+
.debug-tooltip__header {
|
|
4854
|
+
display: flex;
|
|
4855
|
+
align-items: center;
|
|
4856
|
+
gap: 8px;
|
|
4857
|
+
padding: 12px 16px;
|
|
4858
|
+
background: linear-gradient(90deg, rgba(99, 102, 241, 0.2) 0%, rgba(139, 92, 246, 0.1) 100%);
|
|
4859
|
+
border-bottom: 1px solid rgba(99, 102, 241, 0.2);
|
|
4860
|
+
}
|
|
4861
|
+
|
|
4862
|
+
.debug-tooltip__icon {
|
|
4863
|
+
font-size: 16px;
|
|
4864
|
+
}
|
|
4865
|
+
|
|
4866
|
+
.debug-tooltip__title {
|
|
4867
|
+
font-weight: 700;
|
|
4868
|
+
font-size: 13px;
|
|
4869
|
+
color: #f1f5f9;
|
|
4870
|
+
letter-spacing: 0.5px;
|
|
4871
|
+
text-transform: uppercase;
|
|
4872
|
+
}
|
|
4873
|
+
|
|
4874
|
+
.debug-tooltip__content {
|
|
4875
|
+
padding: 12px 16px;
|
|
4876
|
+
max-height: 400px;
|
|
4877
|
+
overflow-y: auto;
|
|
4878
|
+
}
|
|
4879
|
+
|
|
4880
|
+
.debug-tooltip__section {
|
|
4881
|
+
margin-bottom: 14px;
|
|
4882
|
+
padding-bottom: 12px;
|
|
4883
|
+
border-bottom: 1px solid rgba(148, 163, 184, 0.1);
|
|
4884
|
+
}
|
|
4885
|
+
|
|
4886
|
+
.debug-tooltip__section:last-child {
|
|
4887
|
+
margin-bottom: 0;
|
|
4888
|
+
padding-bottom: 0;
|
|
4889
|
+
border-bottom: none;
|
|
4890
|
+
}
|
|
4891
|
+
|
|
4892
|
+
.debug-tooltip__section-title {
|
|
4893
|
+
font-size: 11px;
|
|
4894
|
+
font-weight: 600;
|
|
4895
|
+
color: #94a3b8;
|
|
4896
|
+
text-transform: uppercase;
|
|
4897
|
+
letter-spacing: 0.8px;
|
|
4898
|
+
margin-bottom: 10px;
|
|
4899
|
+
display: flex;
|
|
4900
|
+
align-items: center;
|
|
4901
|
+
gap: 6px;
|
|
4902
|
+
}
|
|
4903
|
+
|
|
4904
|
+
.debug-tooltip__row {
|
|
4905
|
+
display: flex;
|
|
4906
|
+
justify-content: space-between;
|
|
4907
|
+
align-items: flex-start;
|
|
4908
|
+
padding: 4px 0;
|
|
4909
|
+
gap: 12px;
|
|
4910
|
+
}
|
|
4911
|
+
|
|
4912
|
+
.debug-tooltip__row--full {
|
|
4913
|
+
flex-direction: column;
|
|
4914
|
+
gap: 4px;
|
|
4915
|
+
}
|
|
4916
|
+
|
|
4917
|
+
.debug-tooltip__label {
|
|
4918
|
+
color: #94a3b8;
|
|
4919
|
+
font-size: 11px;
|
|
4920
|
+
flex-shrink: 0;
|
|
4921
|
+
}
|
|
4922
|
+
|
|
4923
|
+
.debug-tooltip__value {
|
|
4924
|
+
color: #f1f5f9;
|
|
4925
|
+
font-weight: 500;
|
|
4926
|
+
text-align: right;
|
|
4927
|
+
word-break: break-all;
|
|
4928
|
+
}
|
|
4929
|
+
|
|
4930
|
+
.debug-tooltip__row--full .debug-tooltip__value {
|
|
4931
|
+
text-align: left;
|
|
4932
|
+
background: rgba(0, 0, 0, 0.3);
|
|
4933
|
+
padding: 6px 10px;
|
|
4934
|
+
border-radius: 6px;
|
|
4935
|
+
font-size: 11px;
|
|
4936
|
+
width: 100%;
|
|
4937
|
+
box-sizing: border-box;
|
|
4938
|
+
}
|
|
4939
|
+
|
|
4940
|
+
.debug-tooltip__value--mono {
|
|
4941
|
+
font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
|
|
4942
|
+
font-size: 11px;
|
|
4943
|
+
background: rgba(0, 0, 0, 0.3);
|
|
4944
|
+
padding: 2px 6px;
|
|
4945
|
+
border-radius: 4px;
|
|
4946
|
+
}
|
|
4947
|
+
|
|
4948
|
+
.debug-tooltip__value--highlight {
|
|
4949
|
+
color: #a5b4fc;
|
|
4950
|
+
font-style: italic;
|
|
4951
|
+
}
|
|
4952
|
+
|
|
4953
|
+
.debug-tooltip__badge {
|
|
4954
|
+
display: inline-block;
|
|
4955
|
+
padding: 2px 8px;
|
|
4956
|
+
border-radius: 4px;
|
|
4957
|
+
font-size: 10px;
|
|
4958
|
+
font-weight: 600;
|
|
4959
|
+
text-transform: uppercase;
|
|
4960
|
+
letter-spacing: 0.5px;
|
|
4961
|
+
background: rgba(99, 102, 241, 0.3);
|
|
4962
|
+
color: #a5b4fc;
|
|
4963
|
+
}
|
|
4964
|
+
|
|
4965
|
+
.debug-tooltip__badge--energy {
|
|
4966
|
+
background: rgba(59, 130, 246, 0.3);
|
|
4967
|
+
color: #93c5fd;
|
|
4968
|
+
}
|
|
4969
|
+
|
|
4970
|
+
.debug-tooltip__badge--water {
|
|
4971
|
+
background: rgba(6, 182, 212, 0.3);
|
|
4972
|
+
color: #67e8f9;
|
|
4973
|
+
}
|
|
4974
|
+
|
|
4975
|
+
.debug-tooltip__badge--temperature {
|
|
4976
|
+
background: rgba(249, 115, 22, 0.3);
|
|
4977
|
+
color: #fdba74;
|
|
4978
|
+
}
|
|
4979
|
+
|
|
4980
|
+
/* Tooltip arrow */
|
|
4981
|
+
.debug-tooltip::after {
|
|
4982
|
+
content: '';
|
|
4983
|
+
position: absolute;
|
|
4984
|
+
bottom: -6px;
|
|
4985
|
+
left: 50%;
|
|
4986
|
+
transform: translateX(-50%) rotate(45deg);
|
|
4987
|
+
width: 12px;
|
|
4988
|
+
height: 12px;
|
|
4989
|
+
background: #0f172a;
|
|
4990
|
+
border-right: 1px solid rgba(99, 102, 241, 0.3);
|
|
4991
|
+
border-bottom: 1px solid rgba(99, 102, 241, 0.3);
|
|
4992
|
+
}
|
|
4993
|
+
|
|
4994
|
+
/* Scrollbar styling for tooltip content */
|
|
4995
|
+
.debug-tooltip__content::-webkit-scrollbar {
|
|
4996
|
+
width: 6px;
|
|
4997
|
+
}
|
|
4998
|
+
|
|
4999
|
+
.debug-tooltip__content::-webkit-scrollbar-track {
|
|
5000
|
+
background: rgba(0, 0, 0, 0.2);
|
|
5001
|
+
border-radius: 3px;
|
|
5002
|
+
}
|
|
5003
|
+
|
|
5004
|
+
.debug-tooltip__content::-webkit-scrollbar-thumb {
|
|
5005
|
+
background: rgba(99, 102, 241, 0.4);
|
|
5006
|
+
border-radius: 3px;
|
|
5007
|
+
}
|
|
5008
|
+
|
|
5009
|
+
.debug-tooltip__content::-webkit-scrollbar-thumb:hover {
|
|
5010
|
+
background: rgba(99, 102, 241, 0.6);
|
|
5011
|
+
}
|
|
4682
5012
|
`;
|
|
4683
5013
|
|
|
4684
5014
|
// src/thingsboard/main-dashboard-shopping/v-4.0.0/head-office/card-head-office.icons.ts
|
|
@@ -4819,7 +5149,245 @@
|
|
|
4819
5149
|
menu_settings: "Configura\xE7\xF5es"
|
|
4820
5150
|
};
|
|
4821
5151
|
|
|
5152
|
+
// src/components/temperature/utils.ts
|
|
5153
|
+
var DAY_PERIODS = [
|
|
5154
|
+
{ id: "madrugada", label: "Madrugada (00h-06h)", startHour: 0, endHour: 6 },
|
|
5155
|
+
{ id: "manha", label: "Manh\xE3 (06h-12h)", startHour: 6, endHour: 12 },
|
|
5156
|
+
{ id: "tarde", label: "Tarde (12h-18h)", startHour: 12, endHour: 18 },
|
|
5157
|
+
{ id: "noite", label: "Noite (18h-24h)", startHour: 18, endHour: 24 }
|
|
5158
|
+
];
|
|
5159
|
+
var DEFAULT_CLAMP_RANGE = { min: 15, max: 40 };
|
|
5160
|
+
function getTodaySoFar() {
|
|
5161
|
+
const now = /* @__PURE__ */ new Date();
|
|
5162
|
+
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0);
|
|
5163
|
+
return {
|
|
5164
|
+
startTs: startOfDay.getTime(),
|
|
5165
|
+
endTs: now.getTime()
|
|
5166
|
+
};
|
|
5167
|
+
}
|
|
5168
|
+
var CHART_COLORS = [
|
|
5169
|
+
"#1976d2",
|
|
5170
|
+
// Blue
|
|
5171
|
+
"#FF6B6B",
|
|
5172
|
+
// Red
|
|
5173
|
+
"#4CAF50",
|
|
5174
|
+
// Green
|
|
5175
|
+
"#FF9800",
|
|
5176
|
+
// Orange
|
|
5177
|
+
"#9C27B0",
|
|
5178
|
+
// Purple
|
|
5179
|
+
"#00BCD4",
|
|
5180
|
+
// Cyan
|
|
5181
|
+
"#E91E63",
|
|
5182
|
+
// Pink
|
|
5183
|
+
"#795548"
|
|
5184
|
+
// Brown
|
|
5185
|
+
];
|
|
5186
|
+
async function fetchTemperatureData(token, deviceId, startTs, endTs) {
|
|
5187
|
+
const url = `/api/plugins/telemetry/DEVICE/${deviceId}/values/timeseries?keys=temperature&startTs=${encodeURIComponent(startTs)}&endTs=${encodeURIComponent(endTs)}&limit=50000&agg=NONE`;
|
|
5188
|
+
const response = await fetch(url, {
|
|
5189
|
+
headers: {
|
|
5190
|
+
"X-Authorization": `Bearer ${token}`,
|
|
5191
|
+
"Content-Type": "application/json"
|
|
5192
|
+
}
|
|
5193
|
+
});
|
|
5194
|
+
if (!response.ok) {
|
|
5195
|
+
throw new Error(`Failed to fetch temperature data: ${response.status}`);
|
|
5196
|
+
}
|
|
5197
|
+
const data = await response.json();
|
|
5198
|
+
return data?.temperature || [];
|
|
5199
|
+
}
|
|
5200
|
+
function clampTemperature(value, range = DEFAULT_CLAMP_RANGE) {
|
|
5201
|
+
const num = Number(value || 0);
|
|
5202
|
+
if (num < range.min) return range.min;
|
|
5203
|
+
if (num > range.max) return range.max;
|
|
5204
|
+
return num;
|
|
5205
|
+
}
|
|
5206
|
+
function calculateStats(data, clampRange = DEFAULT_CLAMP_RANGE) {
|
|
5207
|
+
if (data.length === 0) {
|
|
5208
|
+
return { avg: 0, min: 0, max: 0, count: 0 };
|
|
5209
|
+
}
|
|
5210
|
+
const values = data.map((item) => clampTemperature(item.value, clampRange));
|
|
5211
|
+
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
5212
|
+
return {
|
|
5213
|
+
avg: sum / values.length,
|
|
5214
|
+
min: Math.min(...values),
|
|
5215
|
+
max: Math.max(...values),
|
|
5216
|
+
count: values.length
|
|
5217
|
+
};
|
|
5218
|
+
}
|
|
5219
|
+
function interpolateTemperature(data, options) {
|
|
5220
|
+
const { intervalMinutes, startTs, endTs, clampRange = DEFAULT_CLAMP_RANGE } = options;
|
|
5221
|
+
const intervalMs = intervalMinutes * 60 * 1e3;
|
|
5222
|
+
if (data.length === 0) {
|
|
5223
|
+
return [];
|
|
5224
|
+
}
|
|
5225
|
+
const sortedData = [...data].sort((a, b) => a.ts - b.ts);
|
|
5226
|
+
const result = [];
|
|
5227
|
+
let lastKnownValue = clampTemperature(sortedData[0].value, clampRange);
|
|
5228
|
+
let dataIndex = 0;
|
|
5229
|
+
for (let ts = startTs; ts <= endTs; ts += intervalMs) {
|
|
5230
|
+
while (dataIndex < sortedData.length - 1 && sortedData[dataIndex + 1].ts <= ts) {
|
|
5231
|
+
dataIndex++;
|
|
5232
|
+
}
|
|
5233
|
+
const currentData = sortedData[dataIndex];
|
|
5234
|
+
if (currentData && Math.abs(currentData.ts - ts) < intervalMs) {
|
|
5235
|
+
lastKnownValue = clampTemperature(currentData.value, clampRange);
|
|
5236
|
+
}
|
|
5237
|
+
result.push({
|
|
5238
|
+
ts,
|
|
5239
|
+
value: lastKnownValue
|
|
5240
|
+
});
|
|
5241
|
+
}
|
|
5242
|
+
return result;
|
|
5243
|
+
}
|
|
5244
|
+
function aggregateByDay(data, clampRange = DEFAULT_CLAMP_RANGE) {
|
|
5245
|
+
if (data.length === 0) {
|
|
5246
|
+
return [];
|
|
5247
|
+
}
|
|
5248
|
+
const dayMap = /* @__PURE__ */ new Map();
|
|
5249
|
+
data.forEach((item) => {
|
|
5250
|
+
const date = new Date(item.ts);
|
|
5251
|
+
const dateKey = date.toISOString().split("T")[0];
|
|
5252
|
+
if (!dayMap.has(dateKey)) {
|
|
5253
|
+
dayMap.set(dateKey, []);
|
|
5254
|
+
}
|
|
5255
|
+
dayMap.get(dateKey).push(item);
|
|
5256
|
+
});
|
|
5257
|
+
const result = [];
|
|
5258
|
+
dayMap.forEach((dayData, dateKey) => {
|
|
5259
|
+
const values = dayData.map((item) => clampTemperature(item.value, clampRange));
|
|
5260
|
+
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
5261
|
+
result.push({
|
|
5262
|
+
date: dateKey,
|
|
5263
|
+
dateTs: new Date(dateKey).getTime(),
|
|
5264
|
+
avg: sum / values.length,
|
|
5265
|
+
min: Math.min(...values),
|
|
5266
|
+
max: Math.max(...values),
|
|
5267
|
+
count: values.length
|
|
5268
|
+
});
|
|
5269
|
+
});
|
|
5270
|
+
return result.sort((a, b) => a.dateTs - b.dateTs);
|
|
5271
|
+
}
|
|
5272
|
+
function filterByDayPeriods(data, selectedPeriods) {
|
|
5273
|
+
if (selectedPeriods.length === 0 || selectedPeriods.length === DAY_PERIODS.length) {
|
|
5274
|
+
return data;
|
|
5275
|
+
}
|
|
5276
|
+
return data.filter((item) => {
|
|
5277
|
+
const date = new Date(item.ts);
|
|
5278
|
+
const hour = date.getHours();
|
|
5279
|
+
return selectedPeriods.some((periodId) => {
|
|
5280
|
+
const period = DAY_PERIODS.find((p) => p.id === periodId);
|
|
5281
|
+
if (!period) return false;
|
|
5282
|
+
return hour >= period.startHour && hour < period.endHour;
|
|
5283
|
+
});
|
|
5284
|
+
});
|
|
5285
|
+
}
|
|
5286
|
+
function getSelectedPeriodsLabel(selectedPeriods) {
|
|
5287
|
+
if (selectedPeriods.length === 0 || selectedPeriods.length === DAY_PERIODS.length) {
|
|
5288
|
+
return "Todos os per\xEDodos";
|
|
5289
|
+
}
|
|
5290
|
+
if (selectedPeriods.length === 1) {
|
|
5291
|
+
const period = DAY_PERIODS.find((p) => p.id === selectedPeriods[0]);
|
|
5292
|
+
return period?.label || "";
|
|
5293
|
+
}
|
|
5294
|
+
return `${selectedPeriods.length} per\xEDodos selecionados`;
|
|
5295
|
+
}
|
|
5296
|
+
function formatTemperature(value, decimals = 1) {
|
|
5297
|
+
if (value === null || value === void 0 || isNaN(value)) {
|
|
5298
|
+
return "\u2014";
|
|
5299
|
+
}
|
|
5300
|
+
return `${value.toFixed(decimals)}\xB0C`;
|
|
5301
|
+
}
|
|
5302
|
+
function exportTemperatureCSV(data, deviceLabel, stats, startDate, endDate) {
|
|
5303
|
+
if (data.length === 0) {
|
|
5304
|
+
console.warn("No data to export");
|
|
5305
|
+
return;
|
|
5306
|
+
}
|
|
5307
|
+
const BOM = "\uFEFF";
|
|
5308
|
+
let csvContent = BOM;
|
|
5309
|
+
csvContent += `Relat\xF3rio de Temperatura - ${deviceLabel}
|
|
5310
|
+
`;
|
|
5311
|
+
csvContent += `Per\xEDodo: ${startDate} at\xE9 ${endDate}
|
|
5312
|
+
`;
|
|
5313
|
+
csvContent += `M\xE9dia: ${formatTemperature(stats.avg)}
|
|
5314
|
+
`;
|
|
5315
|
+
csvContent += `M\xEDnima: ${formatTemperature(stats.min)}
|
|
5316
|
+
`;
|
|
5317
|
+
csvContent += `M\xE1xima: ${formatTemperature(stats.max)}
|
|
5318
|
+
`;
|
|
5319
|
+
csvContent += `Total de leituras: ${stats.count}
|
|
5320
|
+
`;
|
|
5321
|
+
csvContent += "\n";
|
|
5322
|
+
csvContent += "Data/Hora,Temperatura (\xB0C)\n";
|
|
5323
|
+
data.forEach((item) => {
|
|
5324
|
+
const date = new Date(item.ts).toLocaleString("pt-BR");
|
|
5325
|
+
const temp = Number(item.value).toFixed(2);
|
|
5326
|
+
csvContent += `"${date}",${temp}
|
|
5327
|
+
`;
|
|
5328
|
+
});
|
|
5329
|
+
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
5330
|
+
const url = URL.createObjectURL(blob);
|
|
5331
|
+
const link = document.createElement("a");
|
|
5332
|
+
link.href = url;
|
|
5333
|
+
link.download = `temperatura_${deviceLabel.replace(/\s+/g, "_")}_${startDate}_${endDate}.csv`;
|
|
5334
|
+
document.body.appendChild(link);
|
|
5335
|
+
link.click();
|
|
5336
|
+
document.body.removeChild(link);
|
|
5337
|
+
URL.revokeObjectURL(url);
|
|
5338
|
+
}
|
|
5339
|
+
var DARK_THEME = {
|
|
5340
|
+
background: "rgba(0, 0, 0, 0.85)",
|
|
5341
|
+
surface: "#1a1f28",
|
|
5342
|
+
text: "#ffffff",
|
|
5343
|
+
textMuted: "rgba(255, 255, 255, 0.7)",
|
|
5344
|
+
border: "rgba(255, 255, 255, 0.1)",
|
|
5345
|
+
primary: "#1976d2",
|
|
5346
|
+
success: "#4CAF50",
|
|
5347
|
+
warning: "#FF9800",
|
|
5348
|
+
danger: "#f44336",
|
|
5349
|
+
chartLine: "#1976d2",
|
|
5350
|
+
chartGrid: "rgba(255, 255, 255, 0.1)"
|
|
5351
|
+
};
|
|
5352
|
+
var LIGHT_THEME = {
|
|
5353
|
+
background: "rgba(0, 0, 0, 0.6)",
|
|
5354
|
+
surface: "#ffffff",
|
|
5355
|
+
text: "#333333",
|
|
5356
|
+
textMuted: "#666666",
|
|
5357
|
+
border: "#e0e0e0",
|
|
5358
|
+
primary: "#1976d2",
|
|
5359
|
+
success: "#4CAF50",
|
|
5360
|
+
warning: "#FF9800",
|
|
5361
|
+
danger: "#f44336",
|
|
5362
|
+
chartLine: "#1976d2",
|
|
5363
|
+
chartGrid: "#e0e0e0"
|
|
5364
|
+
};
|
|
5365
|
+
function getThemeColors(theme) {
|
|
5366
|
+
return theme === "dark" ? DARK_THEME : LIGHT_THEME;
|
|
5367
|
+
}
|
|
5368
|
+
|
|
5369
|
+
// src/utils/logHelper.js
|
|
5370
|
+
function createLogHelper(debugActive = false) {
|
|
5371
|
+
return {
|
|
5372
|
+
log: function(...args) {
|
|
5373
|
+
if (debugActive) {
|
|
5374
|
+
console.log(...args);
|
|
5375
|
+
}
|
|
5376
|
+
},
|
|
5377
|
+
warn: function(...args) {
|
|
5378
|
+
if (debugActive) {
|
|
5379
|
+
console.warn(...args);
|
|
5380
|
+
}
|
|
5381
|
+
},
|
|
5382
|
+
error: function(...args) {
|
|
5383
|
+
console.error(...args);
|
|
5384
|
+
}
|
|
5385
|
+
};
|
|
5386
|
+
}
|
|
5387
|
+
|
|
4822
5388
|
// src/thingsboard/main-dashboard-shopping/v-4.0.0/card/head-office/card-head-office.js
|
|
5389
|
+
var LABEL_CHAR_LIMIT = 18;
|
|
5390
|
+
var DEFAUL_DELAY_TIME_CONNECTION_IN_MINS = 1440;
|
|
4823
5391
|
var CSS_TAG = "head-office-card-v1";
|
|
4824
5392
|
function ensureCss() {
|
|
4825
5393
|
if (!document.querySelector(`style[data-myio-css="${CSS_TAG}"]`)) {
|
|
@@ -4833,11 +5401,17 @@
|
|
|
4833
5401
|
if (!params || !params.entityObject) {
|
|
4834
5402
|
throw new Error("renderCardCompenteHeadOffice: entityObject is required");
|
|
4835
5403
|
}
|
|
5404
|
+
const LogHelper2 = createLogHelper(params.debugActive ?? false);
|
|
4836
5405
|
const entityObject = params.entityObject;
|
|
4837
5406
|
if (!entityObject.entityId) {
|
|
4838
|
-
|
|
5407
|
+
LogHelper2.warn("[CardHeadOffice] entityId is missing, generating temporary ID");
|
|
4839
5408
|
entityObject.entityId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
4840
5409
|
}
|
|
5410
|
+
if (!params.delayTimeConnectionInMins) {
|
|
5411
|
+
LogHelper2.warn(
|
|
5412
|
+
`[CardHeadOffice] delayTimeConnectionInMins is missing, defaulting to ${DEFAUL_DELAY_TIME_CONNECTION_IN_MINS} mins`
|
|
5413
|
+
);
|
|
5414
|
+
}
|
|
4841
5415
|
return {
|
|
4842
5416
|
entityObject,
|
|
4843
5417
|
i18n: { ...DEFAULT_I18N, ...params.i18n || {} },
|
|
@@ -4845,7 +5419,12 @@
|
|
|
4845
5419
|
enableDragDrop: Boolean(params.enableDragDrop),
|
|
4846
5420
|
useNewComponents: Boolean(params.useNewComponents),
|
|
4847
5421
|
// RFC-0091: Configurable delay time for connection status check (default 15 minutes)
|
|
4848
|
-
delayTimeConnectionInMins: params.delayTimeConnectionInMins ??
|
|
5422
|
+
delayTimeConnectionInMins: params.delayTimeConnectionInMins ?? DEFAUL_DELAY_TIME_CONNECTION_IN_MINS,
|
|
5423
|
+
// Debug options
|
|
5424
|
+
debugActive: params.debugActive ?? false,
|
|
5425
|
+
activeTooltipDebug: params.activeTooltipDebug ?? false,
|
|
5426
|
+
// LogHelper instance for this card
|
|
5427
|
+
LogHelper: LogHelper2,
|
|
4849
5428
|
callbacks: {
|
|
4850
5429
|
handleActionDashboard: params.handleActionDashboard,
|
|
4851
5430
|
handleActionReport: params.handleActionReport,
|
|
@@ -4883,16 +5462,10 @@
|
|
|
4883
5462
|
return formatWaterVolumeM3(value);
|
|
4884
5463
|
}
|
|
4885
5464
|
if (domain === "temperature") {
|
|
4886
|
-
return formatTemperature(value);
|
|
5465
|
+
return formatTemperature(value, 0);
|
|
4887
5466
|
}
|
|
4888
5467
|
return formatEnergy(value);
|
|
4889
5468
|
}
|
|
4890
|
-
function formatTemperature(temp) {
|
|
4891
|
-
if (temp === null || temp === void 0 || isNaN(temp)) {
|
|
4892
|
-
return "\u2014";
|
|
4893
|
-
}
|
|
4894
|
-
return `${temp.toFixed(0)}\xB0C`;
|
|
4895
|
-
}
|
|
4896
5469
|
function calculateConsumptionPercentage(target, consumption) {
|
|
4897
5470
|
const numericTarget = Number(target);
|
|
4898
5471
|
const numericConsumption = Number(consumption);
|
|
@@ -4907,32 +5480,32 @@
|
|
|
4907
5480
|
// --- Novos Status de Temperatura ---
|
|
4908
5481
|
case "normal":
|
|
4909
5482
|
return { chipClass: "chip--ok", label: "Normal" };
|
|
4910
|
-
// Verde/Azul
|
|
4911
5483
|
case "cold":
|
|
4912
5484
|
return { chipClass: "chip--standby", label: "Frio" };
|
|
4913
|
-
// Azul claro/Ciano
|
|
4914
5485
|
case "hot":
|
|
4915
5486
|
return { chipClass: "chip--alert", label: "Quente" };
|
|
4916
|
-
//
|
|
4917
|
-
// --- Status Existentes ---
|
|
5487
|
+
// --- Status Existentes (aligned with getCardStateClass) ---
|
|
4918
5488
|
case DeviceStatusType.POWER_ON:
|
|
4919
5489
|
if (domain === "water") {
|
|
4920
|
-
return { chipClass: "chip--
|
|
5490
|
+
return { chipClass: "chip--power-on", label: i18n.in_operation_water };
|
|
4921
5491
|
}
|
|
4922
|
-
return { chipClass: "chip--
|
|
5492
|
+
return { chipClass: "chip--power-on", label: i18n.in_operation };
|
|
4923
5493
|
case DeviceStatusType.STANDBY:
|
|
4924
5494
|
return { chipClass: "chip--standby", label: i18n.standby };
|
|
4925
5495
|
case DeviceStatusType.WARNING:
|
|
4926
|
-
return { chipClass: "chip--
|
|
5496
|
+
return { chipClass: "chip--warning", label: i18n.alert };
|
|
5497
|
+
case DeviceStatusType.MAINTENANCE:
|
|
5498
|
+
return { chipClass: "chip--maintenance", label: i18n.maintenance };
|
|
4927
5499
|
case DeviceStatusType.FAILURE:
|
|
4928
|
-
case DeviceStatusType.POWER_OFF:
|
|
4929
5500
|
return { chipClass: "chip--failure", label: i18n.failure };
|
|
4930
|
-
case DeviceStatusType.
|
|
4931
|
-
return { chipClass: "chip--
|
|
4932
|
-
case DeviceStatusType.
|
|
4933
|
-
return { chipClass: "chip--offline", label: i18n.
|
|
4934
|
-
// Default (Cai aqui se não achar 'normal', 'hot' etc)
|
|
5501
|
+
case DeviceStatusType.POWER_OFF:
|
|
5502
|
+
return { chipClass: "chip--power-off", label: i18n.power_off || i18n.failure };
|
|
5503
|
+
case DeviceStatusType.OFFLINE:
|
|
5504
|
+
return { chipClass: "chip--offline", label: i18n.offline };
|
|
4935
5505
|
case DeviceStatusType.NO_INFO:
|
|
5506
|
+
return { chipClass: "chip--no-info", label: i18n.no_info || i18n.offline };
|
|
5507
|
+
case DeviceStatusType.NOT_INSTALLED:
|
|
5508
|
+
return { chipClass: "chip--not-installed", label: i18n.not_installed };
|
|
4936
5509
|
default:
|
|
4937
5510
|
return { chipClass: "chip--offline", label: i18n.offline };
|
|
4938
5511
|
}
|
|
@@ -4940,23 +5513,32 @@
|
|
|
4940
5513
|
function getCardStateClass(deviceStatus) {
|
|
4941
5514
|
switch (deviceStatus) {
|
|
4942
5515
|
case DeviceStatusType.POWER_ON:
|
|
4943
|
-
return "is-
|
|
5516
|
+
return "is-power-on";
|
|
4944
5517
|
// Blue border
|
|
4945
5518
|
case DeviceStatusType.STANDBY:
|
|
4946
5519
|
return "is-standby";
|
|
4947
5520
|
// Green border
|
|
4948
5521
|
case DeviceStatusType.WARNING:
|
|
5522
|
+
return "is-warning";
|
|
5523
|
+
// Yellow border
|
|
4949
5524
|
case DeviceStatusType.MAINTENANCE:
|
|
4950
|
-
return "is-
|
|
5525
|
+
return "is-maintenance";
|
|
4951
5526
|
// Yellow border
|
|
4952
5527
|
case DeviceStatusType.FAILURE:
|
|
4953
|
-
case DeviceStatusType.POWER_OFF:
|
|
4954
5528
|
return "is-failure";
|
|
4955
|
-
// Red border
|
|
5529
|
+
// Dark Red border
|
|
5530
|
+
case DeviceStatusType.POWER_OFF:
|
|
5531
|
+
return "is-power-off";
|
|
5532
|
+
// Light Red border
|
|
5533
|
+
case DeviceStatusType.OFFLINE:
|
|
5534
|
+
return "is-offline";
|
|
5535
|
+
// Dark Gray border
|
|
4956
5536
|
case DeviceStatusType.NO_INFO:
|
|
5537
|
+
return "is-no-info";
|
|
5538
|
+
// Dark Orange border
|
|
4957
5539
|
case DeviceStatusType.NOT_INSTALLED:
|
|
4958
|
-
return "is-
|
|
4959
|
-
//
|
|
5540
|
+
return "is-not-installed";
|
|
5541
|
+
// Purple border
|
|
4960
5542
|
default:
|
|
4961
5543
|
return "";
|
|
4962
5544
|
}
|
|
@@ -4970,17 +5552,25 @@
|
|
|
4970
5552
|
return "dot--standby";
|
|
4971
5553
|
case "hot":
|
|
4972
5554
|
return "dot--alert";
|
|
4973
|
-
// --- Status Existentes ---
|
|
5555
|
+
// --- Status Existentes (aligned with getCardStateClass) ---
|
|
4974
5556
|
case DeviceStatusType.POWER_ON:
|
|
4975
|
-
return "dot--
|
|
5557
|
+
return "dot--power-on";
|
|
4976
5558
|
case DeviceStatusType.STANDBY:
|
|
4977
5559
|
return "dot--standby";
|
|
4978
5560
|
case DeviceStatusType.WARNING:
|
|
5561
|
+
return "dot--warning";
|
|
4979
5562
|
case DeviceStatusType.MAINTENANCE:
|
|
4980
|
-
return "dot--
|
|
5563
|
+
return "dot--maintenance";
|
|
4981
5564
|
case DeviceStatusType.FAILURE:
|
|
4982
|
-
case DeviceStatusType.POWER_OFF:
|
|
4983
5565
|
return "dot--failure";
|
|
5566
|
+
case DeviceStatusType.POWER_OFF:
|
|
5567
|
+
return "dot--power-off";
|
|
5568
|
+
case DeviceStatusType.OFFLINE:
|
|
5569
|
+
return "dot--offline";
|
|
5570
|
+
case DeviceStatusType.NO_INFO:
|
|
5571
|
+
return "dot--no-info";
|
|
5572
|
+
case DeviceStatusType.NOT_INSTALLED:
|
|
5573
|
+
return "dot--not-installed";
|
|
4984
5574
|
default:
|
|
4985
5575
|
return "dot--offline";
|
|
4986
5576
|
}
|
|
@@ -5004,7 +5594,13 @@
|
|
|
5004
5594
|
titleSection.className = "myio-ho-card__title";
|
|
5005
5595
|
const nameEl = document.createElement("div");
|
|
5006
5596
|
nameEl.className = "myio-ho-card__name";
|
|
5007
|
-
|
|
5597
|
+
const fullName = entityObject.labelOrName || "Unknown Device";
|
|
5598
|
+
if (fullName.length > LABEL_CHAR_LIMIT) {
|
|
5599
|
+
nameEl.textContent = fullName.slice(0, LABEL_CHAR_LIMIT) + "\u2026";
|
|
5600
|
+
nameEl.title = fullName;
|
|
5601
|
+
} else {
|
|
5602
|
+
nameEl.textContent = fullName;
|
|
5603
|
+
}
|
|
5008
5604
|
titleSection.appendChild(nameEl);
|
|
5009
5605
|
if (entityObject.deviceIdentifier) {
|
|
5010
5606
|
const codeEl = document.createElement("div");
|
|
@@ -5133,29 +5729,207 @@
|
|
|
5133
5729
|
root.appendChild(footer);
|
|
5134
5730
|
return root;
|
|
5135
5731
|
}
|
|
5136
|
-
function
|
|
5732
|
+
function buildDebugTooltipInfo(entityObject, statusInfo, stateClass, statusDecisionSource, delayTimeConnectionInMins) {
|
|
5733
|
+
const formatTimestamp = (ts) => {
|
|
5734
|
+
if (!ts) return "N/A";
|
|
5735
|
+
const d = new Date(ts);
|
|
5736
|
+
return d.toLocaleString("pt-BR", {
|
|
5737
|
+
day: "2-digit",
|
|
5738
|
+
month: "2-digit",
|
|
5739
|
+
year: "numeric",
|
|
5740
|
+
hour: "2-digit",
|
|
5741
|
+
minute: "2-digit",
|
|
5742
|
+
second: "2-digit"
|
|
5743
|
+
});
|
|
5744
|
+
};
|
|
5745
|
+
return {
|
|
5746
|
+
// Entity identification
|
|
5747
|
+
entityId: entityObject.entityId || "N/A",
|
|
5748
|
+
name: entityObject.name || entityObject.nameEl || "N/A",
|
|
5749
|
+
domain: entityObject.domain || "energy",
|
|
5750
|
+
// Status decision chain
|
|
5751
|
+
originalDeviceStatus: entityObject._originalDeviceStatus || entityObject.deviceStatus,
|
|
5752
|
+
finalDeviceStatus: entityObject.deviceStatus,
|
|
5753
|
+
connectionStatus: entityObject.connectionStatus || "N/A",
|
|
5754
|
+
statusDecisionSource,
|
|
5755
|
+
// Visual output
|
|
5756
|
+
stateClass,
|
|
5757
|
+
chipClass: statusInfo.chipClass,
|
|
5758
|
+
chipLabel: statusInfo.label,
|
|
5759
|
+
// Connection timestamps
|
|
5760
|
+
lastConnectTime: formatTimestamp(entityObject.lastConnectTime),
|
|
5761
|
+
lastDisconnectTime: formatTimestamp(entityObject.lastDisconnectTime),
|
|
5762
|
+
delayTimeConnectionInMins,
|
|
5763
|
+
// Raw values
|
|
5764
|
+
val: entityObject.val,
|
|
5765
|
+
consumptionTargetValue: entityObject.consumptionTargetValue,
|
|
5766
|
+
deviceType: entityObject.deviceType || "N/A"
|
|
5767
|
+
};
|
|
5768
|
+
}
|
|
5769
|
+
function attachDebugTooltip(element, debugInfo) {
|
|
5770
|
+
const existingTooltip = element.querySelector(".debug-tooltip-container");
|
|
5771
|
+
if (existingTooltip) {
|
|
5772
|
+
existingTooltip.remove();
|
|
5773
|
+
}
|
|
5774
|
+
const tooltipContainer = document.createElement("div");
|
|
5775
|
+
tooltipContainer.className = "debug-tooltip-container";
|
|
5776
|
+
const tooltip = document.createElement("div");
|
|
5777
|
+
tooltip.className = "debug-tooltip";
|
|
5778
|
+
tooltip.innerHTML = `
|
|
5779
|
+
<div class="debug-tooltip__header">
|
|
5780
|
+
<span class="debug-tooltip__icon">\u{1F50D}</span>
|
|
5781
|
+
<span class="debug-tooltip__title">Debug Info</span>
|
|
5782
|
+
</div>
|
|
5783
|
+
<div class="debug-tooltip__content">
|
|
5784
|
+
<div class="debug-tooltip__section">
|
|
5785
|
+
<div class="debug-tooltip__section-title">\u{1F4CB} Identifica\xE7\xE3o</div>
|
|
5786
|
+
<div class="debug-tooltip__row">
|
|
5787
|
+
<span class="debug-tooltip__label">Entity ID:</span>
|
|
5788
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.entityId}</span>
|
|
5789
|
+
</div>
|
|
5790
|
+
<div class="debug-tooltip__row">
|
|
5791
|
+
<span class="debug-tooltip__label">Nome:</span>
|
|
5792
|
+
<span class="debug-tooltip__value">${debugInfo.name}</span>
|
|
5793
|
+
</div>
|
|
5794
|
+
<div class="debug-tooltip__row">
|
|
5795
|
+
<span class="debug-tooltip__label">Dom\xEDnio:</span>
|
|
5796
|
+
<span class="debug-tooltip__value debug-tooltip__badge debug-tooltip__badge--${debugInfo.domain}">${debugInfo.domain}</span>
|
|
5797
|
+
</div>
|
|
5798
|
+
</div>
|
|
5799
|
+
|
|
5800
|
+
<div class="debug-tooltip__section">
|
|
5801
|
+
<div class="debug-tooltip__section-title">\u26A1 Decis\xE3o de Status</div>
|
|
5802
|
+
<div class="debug-tooltip__row">
|
|
5803
|
+
<span class="debug-tooltip__label">connectionStatus:</span>
|
|
5804
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.connectionStatus}</span>
|
|
5805
|
+
</div>
|
|
5806
|
+
<div class="debug-tooltip__row">
|
|
5807
|
+
<span class="debug-tooltip__label">deviceStatus (final):</span>
|
|
5808
|
+
<span class="debug-tooltip__value debug-tooltip__badge">${debugInfo.finalDeviceStatus}</span>
|
|
5809
|
+
</div>
|
|
5810
|
+
<div class="debug-tooltip__row debug-tooltip__row--full">
|
|
5811
|
+
<span class="debug-tooltip__label">Fonte da decis\xE3o:</span>
|
|
5812
|
+
<span class="debug-tooltip__value debug-tooltip__value--highlight">${debugInfo.statusDecisionSource}</span>
|
|
5813
|
+
</div>
|
|
5814
|
+
</div>
|
|
5815
|
+
|
|
5816
|
+
<div class="debug-tooltip__section">
|
|
5817
|
+
<div class="debug-tooltip__section-title">\u{1F3A8} Output Visual</div>
|
|
5818
|
+
<div class="debug-tooltip__row">
|
|
5819
|
+
<span class="debug-tooltip__label">stateClass:</span>
|
|
5820
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.stateClass}</span>
|
|
5821
|
+
</div>
|
|
5822
|
+
<div class="debug-tooltip__row">
|
|
5823
|
+
<span class="debug-tooltip__label">chipClass:</span>
|
|
5824
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.chipClass}</span>
|
|
5825
|
+
</div>
|
|
5826
|
+
<div class="debug-tooltip__row">
|
|
5827
|
+
<span class="debug-tooltip__label">chipLabel:</span>
|
|
5828
|
+
<span class="debug-tooltip__value">${debugInfo.chipLabel}</span>
|
|
5829
|
+
</div>
|
|
5830
|
+
</div>
|
|
5831
|
+
|
|
5832
|
+
<div class="debug-tooltip__section">
|
|
5833
|
+
<div class="debug-tooltip__section-title">\u{1F550} Timestamps de Conex\xE3o</div>
|
|
5834
|
+
<div class="debug-tooltip__row">
|
|
5835
|
+
<span class="debug-tooltip__label">lastConnectTime:</span>
|
|
5836
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.lastConnectTime}</span>
|
|
5837
|
+
</div>
|
|
5838
|
+
<div class="debug-tooltip__row">
|
|
5839
|
+
<span class="debug-tooltip__label">lastDisconnectTime:</span>
|
|
5840
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.lastDisconnectTime}</span>
|
|
5841
|
+
</div>
|
|
5842
|
+
<div class="debug-tooltip__row">
|
|
5843
|
+
<span class="debug-tooltip__label">delayTime:</span>
|
|
5844
|
+
<span class="debug-tooltip__value">${debugInfo.delayTimeConnectionInMins} mins</span>
|
|
5845
|
+
</div>
|
|
5846
|
+
</div>
|
|
5847
|
+
|
|
5848
|
+
<div class="debug-tooltip__section">
|
|
5849
|
+
<div class="debug-tooltip__section-title">\u{1F4CA} Valores</div>
|
|
5850
|
+
<div class="debug-tooltip__row">
|
|
5851
|
+
<span class="debug-tooltip__label">val (consumo):</span>
|
|
5852
|
+
<span class="debug-tooltip__value">${debugInfo.val ?? "N/A"}</span>
|
|
5853
|
+
</div>
|
|
5854
|
+
<div class="debug-tooltip__row">
|
|
5855
|
+
<span class="debug-tooltip__label">target (meta):</span>
|
|
5856
|
+
<span class="debug-tooltip__value">${debugInfo.consumptionTargetValue ?? "N/A"}</span>
|
|
5857
|
+
</div>
|
|
5858
|
+
<div class="debug-tooltip__row">
|
|
5859
|
+
<span class="debug-tooltip__label">deviceType:</span>
|
|
5860
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.deviceType}</span>
|
|
5861
|
+
</div>
|
|
5862
|
+
</div>
|
|
5863
|
+
</div>
|
|
5864
|
+
`;
|
|
5865
|
+
tooltipContainer.appendChild(tooltip);
|
|
5866
|
+
element.style.position = "relative";
|
|
5867
|
+
element.style.cursor = "help";
|
|
5868
|
+
element.appendChild(tooltipContainer);
|
|
5869
|
+
element.classList.add("has-debug-tooltip");
|
|
5870
|
+
}
|
|
5871
|
+
function verifyOfflineStatus(entityObject, delayTimeInMins = 15, LogHelper2) {
|
|
5137
5872
|
const lastConnectionTime = new Date(entityObject.lastConnectTime || 0);
|
|
5138
5873
|
const lastDisconnectTime = new Date(entityObject.lastDisconnectTime || 0);
|
|
5139
5874
|
const now = /* @__PURE__ */ new Date();
|
|
5140
5875
|
const delayTimeInMs = delayTimeInMins * 60 * 1e3;
|
|
5141
5876
|
const timeSinceConnection = now.getTime() - lastConnectionTime.getTime();
|
|
5877
|
+
let isOffline = false;
|
|
5142
5878
|
if (lastDisconnectTime.getTime() > lastConnectionTime.getTime()) {
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5879
|
+
isOffline = true;
|
|
5880
|
+
LogHelper2.log(
|
|
5881
|
+
"[CardHeadOffice][ConnectionStatus Verify] Device is OFFLINE because lastDisconnectTime is more recent than lastConnectTime",
|
|
5882
|
+
entityObject.nameEl
|
|
5883
|
+
);
|
|
5884
|
+
} else if (timeSinceConnection > delayTimeInMs) {
|
|
5885
|
+
isOffline = true;
|
|
5886
|
+
LogHelper2.log(
|
|
5887
|
+
"[CardHeadOffice][ConnectionStatus Verify] Device is OFFLINE because lastConnectTime is older than configured delayTimeConnectionInMins:",
|
|
5888
|
+
delayTimeInMins,
|
|
5889
|
+
"for device",
|
|
5890
|
+
entityObject.nameEl
|
|
5891
|
+
);
|
|
5892
|
+
} else {
|
|
5893
|
+
isOffline = false;
|
|
5894
|
+
LogHelper2.log(
|
|
5895
|
+
"[CardHeadOffice][ConnectionStatus Verify] Device is ONLINE because lastConnectTime is within configured delayTimeConnectionInMins:",
|
|
5896
|
+
delayTimeInMins,
|
|
5897
|
+
"for device",
|
|
5898
|
+
entityObject.nameEl
|
|
5899
|
+
);
|
|
5147
5900
|
}
|
|
5148
|
-
return
|
|
5901
|
+
return isOffline;
|
|
5149
5902
|
}
|
|
5150
5903
|
function paint(root, state) {
|
|
5151
|
-
const { entityObject, i18n, delayTimeConnectionInMins, isSelected } = state;
|
|
5904
|
+
const { entityObject, i18n, delayTimeConnectionInMins, isSelected, LogHelper: LogHelper2, activeTooltipDebug } = state;
|
|
5905
|
+
let statusDecisionSource = "unknown";
|
|
5152
5906
|
if (entityObject.connectionStatus) {
|
|
5153
5907
|
if (entityObject.connectionStatus === "offline") {
|
|
5154
|
-
|
|
5908
|
+
LogHelper2.log(
|
|
5909
|
+
"[CardHeadOffice][ConnectionStatus Verify 01] Setting deviceStatus to OFFLINE based on connectionStatus"
|
|
5910
|
+
);
|
|
5911
|
+
entityObject.deviceStatus = DeviceStatusType.OFFLINE;
|
|
5912
|
+
statusDecisionSource = 'connectionStatus === "offline"';
|
|
5913
|
+
} else {
|
|
5914
|
+
LogHelper2.log(
|
|
5915
|
+
"[CardHeadOffice] Device is ONLINE or WAITING based on connectionStatus for device",
|
|
5916
|
+
entityObject.nameEl
|
|
5917
|
+
);
|
|
5918
|
+
statusDecisionSource = `connectionStatus === "${entityObject.connectionStatus}" (kept original deviceStatus)`;
|
|
5155
5919
|
}
|
|
5156
5920
|
} else {
|
|
5157
|
-
if (verifyOfflineStatus(entityObject, delayTimeConnectionInMins) === false) {
|
|
5158
|
-
|
|
5921
|
+
if (verifyOfflineStatus(entityObject, delayTimeConnectionInMins, LogHelper2) === false) {
|
|
5922
|
+
LogHelper2.log(
|
|
5923
|
+
"[CardHeadOffice][ConnectionStatus Verify 02] Setting deviceStatus to OFFLINE based on timestamp verification by verifyOfflineStatus METHOD with delayTimeConnectionInMins:",
|
|
5924
|
+
delayTimeConnectionInMins
|
|
5925
|
+
);
|
|
5926
|
+
entityObject.deviceStatus = DeviceStatusType.OFFLINE;
|
|
5927
|
+
statusDecisionSource = `verifyOfflineStatus() returned false (delay: ${delayTimeConnectionInMins} mins)`;
|
|
5928
|
+
} else {
|
|
5929
|
+
LogHelper2.log(
|
|
5930
|
+
`[CardHeadOffice][ConnectionStatus Verify 03] Device is ONLINE with deviceStatus = ${entityObject.deviceStatus} based on timestamp verification for device ${entityObject.nameEl}`
|
|
5931
|
+
);
|
|
5932
|
+
statusDecisionSource = `verifyOfflineStatus() returned true (delay: ${delayTimeConnectionInMins} mins)`;
|
|
5159
5933
|
}
|
|
5160
5934
|
}
|
|
5161
5935
|
const stateClass = getCardStateClass(entityObject.deviceStatus);
|
|
@@ -5164,6 +5938,10 @@
|
|
|
5164
5938
|
const chip = root.querySelector(".chip");
|
|
5165
5939
|
chip.className = `chip ${statusInfo.chipClass}`;
|
|
5166
5940
|
chip.innerHTML = statusInfo.label;
|
|
5941
|
+
if (activeTooltipDebug) {
|
|
5942
|
+
const debugInfo = buildDebugTooltipInfo(entityObject, statusInfo, stateClass, statusDecisionSource, delayTimeConnectionInMins);
|
|
5943
|
+
attachDebugTooltip(chip, debugInfo);
|
|
5944
|
+
}
|
|
5167
5945
|
const primaryValue = formatValueByDomain(entityObject.val, entityObject.domain);
|
|
5168
5946
|
const numSpan = root.querySelector(".myio-ho-card__value .num");
|
|
5169
5947
|
root.querySelector(".myio-ho-card__value .unit");
|
|
@@ -5376,6 +6154,7 @@
|
|
|
5376
6154
|
}
|
|
5377
6155
|
|
|
5378
6156
|
// src/thingsboard/main-dashboard-shopping/v-5.2.0/card/template-card-v5.js
|
|
6157
|
+
var LABEL_CHAR_LIMIT2 = 18;
|
|
5379
6158
|
function renderCardComponentV5({
|
|
5380
6159
|
entityObject,
|
|
5381
6160
|
handleActionDashboard,
|
|
@@ -5892,7 +6671,7 @@ ${rangeText}`;
|
|
|
5892
6671
|
|
|
5893
6672
|
<div class="device-title-row" style="flex-direction: column; min-height: 38px; text-align: center; width: 100%;">
|
|
5894
6673
|
<span class="device-title" title="${cardEntity.name}">
|
|
5895
|
-
${cardEntity.name.length >
|
|
6674
|
+
${cardEntity.name.length > LABEL_CHAR_LIMIT2 ? cardEntity.name.slice(0, LABEL_CHAR_LIMIT2) + "\u2026" : cardEntity.name}
|
|
5896
6675
|
</span>
|
|
5897
6676
|
${deviceIdentifier ? `
|
|
5898
6677
|
<span class="device-subtitle" title="${deviceIdentifier}">
|
|
@@ -20045,220 +20824,6 @@ ${rangeText}`;
|
|
|
20045
20824
|
}
|
|
20046
20825
|
}
|
|
20047
20826
|
|
|
20048
|
-
// src/components/temperature/utils.ts
|
|
20049
|
-
var DAY_PERIODS = [
|
|
20050
|
-
{ id: "madrugada", label: "Madrugada (00h-06h)", startHour: 0, endHour: 6 },
|
|
20051
|
-
{ id: "manha", label: "Manh\xE3 (06h-12h)", startHour: 6, endHour: 12 },
|
|
20052
|
-
{ id: "tarde", label: "Tarde (12h-18h)", startHour: 12, endHour: 18 },
|
|
20053
|
-
{ id: "noite", label: "Noite (18h-24h)", startHour: 18, endHour: 24 }
|
|
20054
|
-
];
|
|
20055
|
-
var DEFAULT_CLAMP_RANGE = { min: 15, max: 40 };
|
|
20056
|
-
function getTodaySoFar() {
|
|
20057
|
-
const now = /* @__PURE__ */ new Date();
|
|
20058
|
-
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0);
|
|
20059
|
-
return {
|
|
20060
|
-
startTs: startOfDay.getTime(),
|
|
20061
|
-
endTs: now.getTime()
|
|
20062
|
-
};
|
|
20063
|
-
}
|
|
20064
|
-
var CHART_COLORS = [
|
|
20065
|
-
"#1976d2",
|
|
20066
|
-
// Blue
|
|
20067
|
-
"#FF6B6B",
|
|
20068
|
-
// Red
|
|
20069
|
-
"#4CAF50",
|
|
20070
|
-
// Green
|
|
20071
|
-
"#FF9800",
|
|
20072
|
-
// Orange
|
|
20073
|
-
"#9C27B0",
|
|
20074
|
-
// Purple
|
|
20075
|
-
"#00BCD4",
|
|
20076
|
-
// Cyan
|
|
20077
|
-
"#E91E63",
|
|
20078
|
-
// Pink
|
|
20079
|
-
"#795548"
|
|
20080
|
-
// Brown
|
|
20081
|
-
];
|
|
20082
|
-
async function fetchTemperatureData(token, deviceId, startTs, endTs) {
|
|
20083
|
-
const url = `/api/plugins/telemetry/DEVICE/${deviceId}/values/timeseries?keys=temperature&startTs=${encodeURIComponent(startTs)}&endTs=${encodeURIComponent(endTs)}&limit=50000&agg=NONE`;
|
|
20084
|
-
const response = await fetch(url, {
|
|
20085
|
-
headers: {
|
|
20086
|
-
"X-Authorization": `Bearer ${token}`,
|
|
20087
|
-
"Content-Type": "application/json"
|
|
20088
|
-
}
|
|
20089
|
-
});
|
|
20090
|
-
if (!response.ok) {
|
|
20091
|
-
throw new Error(`Failed to fetch temperature data: ${response.status}`);
|
|
20092
|
-
}
|
|
20093
|
-
const data = await response.json();
|
|
20094
|
-
return data?.temperature || [];
|
|
20095
|
-
}
|
|
20096
|
-
function clampTemperature(value, range = DEFAULT_CLAMP_RANGE) {
|
|
20097
|
-
const num = Number(value || 0);
|
|
20098
|
-
if (num < range.min) return range.min;
|
|
20099
|
-
if (num > range.max) return range.max;
|
|
20100
|
-
return num;
|
|
20101
|
-
}
|
|
20102
|
-
function calculateStats(data, clampRange = DEFAULT_CLAMP_RANGE) {
|
|
20103
|
-
if (data.length === 0) {
|
|
20104
|
-
return { avg: 0, min: 0, max: 0, count: 0 };
|
|
20105
|
-
}
|
|
20106
|
-
const values = data.map((item) => clampTemperature(item.value, clampRange));
|
|
20107
|
-
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
20108
|
-
return {
|
|
20109
|
-
avg: sum / values.length,
|
|
20110
|
-
min: Math.min(...values),
|
|
20111
|
-
max: Math.max(...values),
|
|
20112
|
-
count: values.length
|
|
20113
|
-
};
|
|
20114
|
-
}
|
|
20115
|
-
function interpolateTemperature(data, options) {
|
|
20116
|
-
const { intervalMinutes, startTs, endTs, clampRange = DEFAULT_CLAMP_RANGE } = options;
|
|
20117
|
-
const intervalMs = intervalMinutes * 60 * 1e3;
|
|
20118
|
-
if (data.length === 0) {
|
|
20119
|
-
return [];
|
|
20120
|
-
}
|
|
20121
|
-
const sortedData = [...data].sort((a, b) => a.ts - b.ts);
|
|
20122
|
-
const result = [];
|
|
20123
|
-
let lastKnownValue = clampTemperature(sortedData[0].value, clampRange);
|
|
20124
|
-
let dataIndex = 0;
|
|
20125
|
-
for (let ts = startTs; ts <= endTs; ts += intervalMs) {
|
|
20126
|
-
while (dataIndex < sortedData.length - 1 && sortedData[dataIndex + 1].ts <= ts) {
|
|
20127
|
-
dataIndex++;
|
|
20128
|
-
}
|
|
20129
|
-
const currentData = sortedData[dataIndex];
|
|
20130
|
-
if (currentData && Math.abs(currentData.ts - ts) < intervalMs) {
|
|
20131
|
-
lastKnownValue = clampTemperature(currentData.value, clampRange);
|
|
20132
|
-
}
|
|
20133
|
-
result.push({
|
|
20134
|
-
ts,
|
|
20135
|
-
value: lastKnownValue
|
|
20136
|
-
});
|
|
20137
|
-
}
|
|
20138
|
-
return result;
|
|
20139
|
-
}
|
|
20140
|
-
function aggregateByDay(data, clampRange = DEFAULT_CLAMP_RANGE) {
|
|
20141
|
-
if (data.length === 0) {
|
|
20142
|
-
return [];
|
|
20143
|
-
}
|
|
20144
|
-
const dayMap = /* @__PURE__ */ new Map();
|
|
20145
|
-
data.forEach((item) => {
|
|
20146
|
-
const date = new Date(item.ts);
|
|
20147
|
-
const dateKey = date.toISOString().split("T")[0];
|
|
20148
|
-
if (!dayMap.has(dateKey)) {
|
|
20149
|
-
dayMap.set(dateKey, []);
|
|
20150
|
-
}
|
|
20151
|
-
dayMap.get(dateKey).push(item);
|
|
20152
|
-
});
|
|
20153
|
-
const result = [];
|
|
20154
|
-
dayMap.forEach((dayData, dateKey) => {
|
|
20155
|
-
const values = dayData.map((item) => clampTemperature(item.value, clampRange));
|
|
20156
|
-
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
20157
|
-
result.push({
|
|
20158
|
-
date: dateKey,
|
|
20159
|
-
dateTs: new Date(dateKey).getTime(),
|
|
20160
|
-
avg: sum / values.length,
|
|
20161
|
-
min: Math.min(...values),
|
|
20162
|
-
max: Math.max(...values),
|
|
20163
|
-
count: values.length
|
|
20164
|
-
});
|
|
20165
|
-
});
|
|
20166
|
-
return result.sort((a, b) => a.dateTs - b.dateTs);
|
|
20167
|
-
}
|
|
20168
|
-
function filterByDayPeriods(data, selectedPeriods) {
|
|
20169
|
-
if (selectedPeriods.length === 0 || selectedPeriods.length === DAY_PERIODS.length) {
|
|
20170
|
-
return data;
|
|
20171
|
-
}
|
|
20172
|
-
return data.filter((item) => {
|
|
20173
|
-
const date = new Date(item.ts);
|
|
20174
|
-
const hour = date.getHours();
|
|
20175
|
-
return selectedPeriods.some((periodId) => {
|
|
20176
|
-
const period = DAY_PERIODS.find((p) => p.id === periodId);
|
|
20177
|
-
if (!period) return false;
|
|
20178
|
-
return hour >= period.startHour && hour < period.endHour;
|
|
20179
|
-
});
|
|
20180
|
-
});
|
|
20181
|
-
}
|
|
20182
|
-
function getSelectedPeriodsLabel(selectedPeriods) {
|
|
20183
|
-
if (selectedPeriods.length === 0 || selectedPeriods.length === DAY_PERIODS.length) {
|
|
20184
|
-
return "Todos os per\xEDodos";
|
|
20185
|
-
}
|
|
20186
|
-
if (selectedPeriods.length === 1) {
|
|
20187
|
-
const period = DAY_PERIODS.find((p) => p.id === selectedPeriods[0]);
|
|
20188
|
-
return period?.label || "";
|
|
20189
|
-
}
|
|
20190
|
-
return `${selectedPeriods.length} per\xEDodos selecionados`;
|
|
20191
|
-
}
|
|
20192
|
-
function formatTemperature2(value, decimals = 1) {
|
|
20193
|
-
return `${value.toFixed(decimals)}\xB0C`;
|
|
20194
|
-
}
|
|
20195
|
-
function exportTemperatureCSV(data, deviceLabel, stats, startDate, endDate) {
|
|
20196
|
-
if (data.length === 0) {
|
|
20197
|
-
console.warn("No data to export");
|
|
20198
|
-
return;
|
|
20199
|
-
}
|
|
20200
|
-
const BOM = "\uFEFF";
|
|
20201
|
-
let csvContent = BOM;
|
|
20202
|
-
csvContent += `Relat\xF3rio de Temperatura - ${deviceLabel}
|
|
20203
|
-
`;
|
|
20204
|
-
csvContent += `Per\xEDodo: ${startDate} at\xE9 ${endDate}
|
|
20205
|
-
`;
|
|
20206
|
-
csvContent += `M\xE9dia: ${formatTemperature2(stats.avg)}
|
|
20207
|
-
`;
|
|
20208
|
-
csvContent += `M\xEDnima: ${formatTemperature2(stats.min)}
|
|
20209
|
-
`;
|
|
20210
|
-
csvContent += `M\xE1xima: ${formatTemperature2(stats.max)}
|
|
20211
|
-
`;
|
|
20212
|
-
csvContent += `Total de leituras: ${stats.count}
|
|
20213
|
-
`;
|
|
20214
|
-
csvContent += "\n";
|
|
20215
|
-
csvContent += "Data/Hora,Temperatura (\xB0C)\n";
|
|
20216
|
-
data.forEach((item) => {
|
|
20217
|
-
const date = new Date(item.ts).toLocaleString("pt-BR");
|
|
20218
|
-
const temp = Number(item.value).toFixed(2);
|
|
20219
|
-
csvContent += `"${date}",${temp}
|
|
20220
|
-
`;
|
|
20221
|
-
});
|
|
20222
|
-
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
20223
|
-
const url = URL.createObjectURL(blob);
|
|
20224
|
-
const link = document.createElement("a");
|
|
20225
|
-
link.href = url;
|
|
20226
|
-
link.download = `temperatura_${deviceLabel.replace(/\s+/g, "_")}_${startDate}_${endDate}.csv`;
|
|
20227
|
-
document.body.appendChild(link);
|
|
20228
|
-
link.click();
|
|
20229
|
-
document.body.removeChild(link);
|
|
20230
|
-
URL.revokeObjectURL(url);
|
|
20231
|
-
}
|
|
20232
|
-
var DARK_THEME = {
|
|
20233
|
-
background: "rgba(0, 0, 0, 0.85)",
|
|
20234
|
-
surface: "#1a1f28",
|
|
20235
|
-
text: "#ffffff",
|
|
20236
|
-
textMuted: "rgba(255, 255, 255, 0.7)",
|
|
20237
|
-
border: "rgba(255, 255, 255, 0.1)",
|
|
20238
|
-
primary: "#1976d2",
|
|
20239
|
-
success: "#4CAF50",
|
|
20240
|
-
warning: "#FF9800",
|
|
20241
|
-
danger: "#f44336",
|
|
20242
|
-
chartLine: "#1976d2",
|
|
20243
|
-
chartGrid: "rgba(255, 255, 255, 0.1)"
|
|
20244
|
-
};
|
|
20245
|
-
var LIGHT_THEME = {
|
|
20246
|
-
background: "rgba(0, 0, 0, 0.6)",
|
|
20247
|
-
surface: "#ffffff",
|
|
20248
|
-
text: "#333333",
|
|
20249
|
-
textMuted: "#666666",
|
|
20250
|
-
border: "#e0e0e0",
|
|
20251
|
-
primary: "#1976d2",
|
|
20252
|
-
success: "#4CAF50",
|
|
20253
|
-
warning: "#FF9800",
|
|
20254
|
-
danger: "#f44336",
|
|
20255
|
-
chartLine: "#1976d2",
|
|
20256
|
-
chartGrid: "#e0e0e0"
|
|
20257
|
-
};
|
|
20258
|
-
function getThemeColors(theme) {
|
|
20259
|
-
return theme === "dark" ? DARK_THEME : LIGHT_THEME;
|
|
20260
|
-
}
|
|
20261
|
-
|
|
20262
20827
|
// src/components/temperature/TemperatureModal.ts
|
|
20263
20828
|
async function openTemperatureModal(params) {
|
|
20264
20829
|
const modalId = `myio-temp-modal-${Date.now()}`;
|
|
@@ -20498,7 +21063,7 @@ ${rangeText}`;
|
|
|
20498
21063
|
">
|
|
20499
21064
|
<span style="color: ${colors.textMuted}; font-size: 12px; font-weight: 500;">Temperatura Atual</span>
|
|
20500
21065
|
<div style="font-weight: 700; font-size: 24px; color: ${statusColor}; margin-top: 4px;">
|
|
20501
|
-
${state.currentTemperature !== null ?
|
|
21066
|
+
${state.currentTemperature !== null ? formatTemperature(state.currentTemperature) : "N/A"}
|
|
20502
21067
|
</div>
|
|
20503
21068
|
<div style="font-size: 11px; color: ${statusColor}; margin-top: 2px;">${statusText}</div>
|
|
20504
21069
|
</div>
|
|
@@ -20509,7 +21074,7 @@ ${rangeText}`;
|
|
|
20509
21074
|
">
|
|
20510
21075
|
<span style="color: ${colors.textMuted}; font-size: 12px; font-weight: 500;">M\xE9dia do Per\xEDodo</span>
|
|
20511
21076
|
<div id="${modalId}-avg" style="font-weight: 600; font-size: 20px; color: ${colors.text}; margin-top: 4px;">
|
|
20512
|
-
${state.stats.count > 0 ?
|
|
21077
|
+
${state.stats.count > 0 ? formatTemperature(state.stats.avg) : "N/A"}
|
|
20513
21078
|
</div>
|
|
20514
21079
|
<div style="font-size: 11px; color: ${colors.textMuted}; margin-top: 2px;">${startDateStr} - ${endDateStr}</div>
|
|
20515
21080
|
</div>
|
|
@@ -20520,7 +21085,7 @@ ${rangeText}`;
|
|
|
20520
21085
|
">
|
|
20521
21086
|
<span style="color: ${colors.textMuted}; font-size: 12px; font-weight: 500;">Min / Max</span>
|
|
20522
21087
|
<div id="${modalId}-minmax" style="font-weight: 600; font-size: 20px; color: ${colors.text}; margin-top: 4px;">
|
|
20523
|
-
${state.stats.count > 0 ? `${
|
|
21088
|
+
${state.stats.count > 0 ? `${formatTemperature(state.stats.min)} / ${formatTemperature(state.stats.max)}` : "N/A"}
|
|
20524
21089
|
</div>
|
|
20525
21090
|
<div style="font-size: 11px; color: ${colors.textMuted}; margin-top: 2px;">${state.stats.count} leituras</div>
|
|
20526
21091
|
</div>
|
|
@@ -20836,7 +21401,7 @@ ${rangeText}`;
|
|
|
20836
21401
|
}
|
|
20837
21402
|
tooltip.innerHTML = `
|
|
20838
21403
|
<div style="font-weight: 600; margin-bottom: 6px; color: ${colors.primary};">
|
|
20839
|
-
${
|
|
21404
|
+
${formatTemperature(point.y)}
|
|
20840
21405
|
</div>
|
|
20841
21406
|
<div style="font-size: 11px; color: ${colors.textMuted};">
|
|
20842
21407
|
\u{1F4C5} ${dateStr}
|
|
@@ -21099,7 +21664,7 @@ ${rangeText}`;
|
|
|
21099
21664
|
<span style="width: 12px; height: 12px; border-radius: 50%; background: ${dd.color};"></span>
|
|
21100
21665
|
<span style="color: ${colors.text}; font-size: 13px;">${dd.device.label}</span>
|
|
21101
21666
|
<span style="color: ${colors.textMuted}; font-size: 11px; margin-left: auto;">
|
|
21102
|
-
${dd.stats.count > 0 ?
|
|
21667
|
+
${dd.stats.count > 0 ? formatTemperature(dd.stats.avg) : "N/A"}
|
|
21103
21668
|
</span>
|
|
21104
21669
|
</div>
|
|
21105
21670
|
`).join("");
|
|
@@ -21115,15 +21680,15 @@ ${rangeText}`;
|
|
|
21115
21680
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 4px; font-size: 11px;">
|
|
21116
21681
|
<span style="color: ${colors.textMuted};">M\xE9dia:</span>
|
|
21117
21682
|
<span style="color: ${colors.text}; font-weight: 500;">
|
|
21118
|
-
${dd.stats.count > 0 ?
|
|
21683
|
+
${dd.stats.count > 0 ? formatTemperature(dd.stats.avg) : "N/A"}
|
|
21119
21684
|
</span>
|
|
21120
21685
|
<span style="color: ${colors.textMuted};">Min:</span>
|
|
21121
21686
|
<span style="color: ${colors.text};">
|
|
21122
|
-
${dd.stats.count > 0 ?
|
|
21687
|
+
${dd.stats.count > 0 ? formatTemperature(dd.stats.min) : "N/A"}
|
|
21123
21688
|
</span>
|
|
21124
21689
|
<span style="color: ${colors.textMuted};">Max:</span>
|
|
21125
21690
|
<span style="color: ${colors.text};">
|
|
21126
|
-
${dd.stats.count > 0 ?
|
|
21691
|
+
${dd.stats.count > 0 ? formatTemperature(dd.stats.max) : "N/A"}
|
|
21127
21692
|
</span>
|
|
21128
21693
|
<span style="color: ${colors.textMuted};">Leituras:</span>
|
|
21129
21694
|
<span style="color: ${colors.text};">${dd.stats.count}</span>
|
|
@@ -21659,7 +22224,7 @@ ${rangeText}`;
|
|
|
21659
22224
|
<span style="font-weight: 600;">${point.deviceLabel}</span>
|
|
21660
22225
|
</div>
|
|
21661
22226
|
<div style="font-weight: 600; font-size: 16px; color: ${point.deviceColor}; margin-bottom: 4px;">
|
|
21662
|
-
${
|
|
22227
|
+
${formatTemperature(point.y)}
|
|
21663
22228
|
</div>
|
|
21664
22229
|
<div style="font-size: 11px; color: ${colors.textMuted};">
|
|
21665
22230
|
\u{1F4C5} ${dateStr}
|
|
@@ -26205,7 +26770,7 @@ ${rangeText}`;
|
|
|
26205
26770
|
exports.formatNumberReadable = formatNumberReadable;
|
|
26206
26771
|
exports.formatRelativeTime = formatRelativeTime;
|
|
26207
26772
|
exports.formatTankHeadFromCm = formatTankHeadFromCm;
|
|
26208
|
-
exports.formatTemperature =
|
|
26773
|
+
exports.formatTemperature = formatTemperature;
|
|
26209
26774
|
exports.formatWater = formatWater;
|
|
26210
26775
|
exports.formatWaterByGroup = formatWaterByGroup;
|
|
26211
26776
|
exports.formatWaterVolumeM3 = formatWaterVolumeM3;
|