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
package/dist/index.js
CHANGED
|
@@ -1318,7 +1318,8 @@ var DeviceStatusType = {
|
|
|
1318
1318
|
FAILURE: "failure",
|
|
1319
1319
|
MAINTENANCE: "maintenance",
|
|
1320
1320
|
NO_INFO: "no_info",
|
|
1321
|
-
NOT_INSTALLED: "not_installed"
|
|
1321
|
+
NOT_INSTALLED: "not_installed",
|
|
1322
|
+
OFFLINE: "offline"
|
|
1322
1323
|
};
|
|
1323
1324
|
var ConnectionStatusType = {
|
|
1324
1325
|
CONNECTED: "connected",
|
|
@@ -1327,39 +1328,42 @@ var ConnectionStatusType = {
|
|
|
1327
1328
|
var deviceStatusIcons = {
|
|
1328
1329
|
[DeviceStatusType.POWER_ON]: "\u26A1",
|
|
1329
1330
|
[DeviceStatusType.STANDBY]: "\u{1F50C}",
|
|
1330
|
-
[DeviceStatusType.POWER_OFF]: "\
|
|
1331
|
+
[DeviceStatusType.POWER_OFF]: "\u26AB",
|
|
1331
1332
|
[DeviceStatusType.WARNING]: "\u26A0\uFE0F",
|
|
1332
1333
|
[DeviceStatusType.FAILURE]: "\u{1F6A8}",
|
|
1333
1334
|
[DeviceStatusType.MAINTENANCE]: "\u{1F6E0}\uFE0F",
|
|
1334
1335
|
[DeviceStatusType.NO_INFO]: "\u2753\uFE0F",
|
|
1335
|
-
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}"
|
|
1336
|
+
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}",
|
|
1337
|
+
[DeviceStatusType.OFFLINE]: "\u{1F534}"
|
|
1336
1338
|
};
|
|
1337
1339
|
var waterDeviceStatusIcons = {
|
|
1338
1340
|
[DeviceStatusType.POWER_ON]: "\u{1F4A7}",
|
|
1339
1341
|
[DeviceStatusType.STANDBY]: "\u{1F6B0}",
|
|
1340
|
-
[DeviceStatusType.POWER_OFF]: "\
|
|
1342
|
+
[DeviceStatusType.POWER_OFF]: "\u26AB",
|
|
1341
1343
|
[DeviceStatusType.WARNING]: "\u26A0\uFE0F",
|
|
1342
1344
|
[DeviceStatusType.FAILURE]: "\u{1F6A8}",
|
|
1343
1345
|
[DeviceStatusType.MAINTENANCE]: "\u{1F6E0}\uFE0F",
|
|
1344
1346
|
[DeviceStatusType.NO_INFO]: "\u2753\uFE0F",
|
|
1345
|
-
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}"
|
|
1347
|
+
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}",
|
|
1348
|
+
[DeviceStatusType.OFFLINE]: "\u{1F534}"
|
|
1346
1349
|
};
|
|
1347
1350
|
var temperatureDeviceStatusIcons = {
|
|
1348
1351
|
[DeviceStatusType.POWER_ON]: "\u{1F321}\uFE0F",
|
|
1349
1352
|
[DeviceStatusType.STANDBY]: "\u{1F321}\uFE0F",
|
|
1350
|
-
[DeviceStatusType.POWER_OFF]: "\
|
|
1353
|
+
[DeviceStatusType.POWER_OFF]: "\u26AB",
|
|
1351
1354
|
[DeviceStatusType.WARNING]: "\u26A0\uFE0F",
|
|
1352
1355
|
[DeviceStatusType.FAILURE]: "\u{1F6A8}",
|
|
1353
1356
|
[DeviceStatusType.MAINTENANCE]: "\u{1F6E0}\uFE0F",
|
|
1354
1357
|
[DeviceStatusType.NO_INFO]: "\u2753\uFE0F",
|
|
1355
|
-
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}"
|
|
1358
|
+
[DeviceStatusType.NOT_INSTALLED]: "\u{1F4E6}",
|
|
1359
|
+
[DeviceStatusType.OFFLINE]: "\u{1F534}"
|
|
1356
1360
|
};
|
|
1357
1361
|
var connectionStatusIcons = {
|
|
1358
1362
|
[ConnectionStatusType.CONNECTED]: "\u{1F7E2}",
|
|
1359
1363
|
[ConnectionStatusType.OFFLINE]: "\u{1F6AB}"
|
|
1360
1364
|
};
|
|
1361
1365
|
function mapDeviceToConnectionStatus(deviceStatus) {
|
|
1362
|
-
if (deviceStatus === DeviceStatusType.NO_INFO) {
|
|
1366
|
+
if (deviceStatus === DeviceStatusType.NO_INFO || deviceStatus === DeviceStatusType.OFFLINE) {
|
|
1363
1367
|
return ConnectionStatusType.OFFLINE;
|
|
1364
1368
|
}
|
|
1365
1369
|
return ConnectionStatusType.CONNECTED;
|
|
@@ -1383,15 +1387,16 @@ function mapDeviceStatusToCardStatus(deviceStatus) {
|
|
|
1383
1387
|
[DeviceStatusType.FAILURE]: "fail",
|
|
1384
1388
|
[DeviceStatusType.MAINTENANCE]: "alert",
|
|
1385
1389
|
[DeviceStatusType.NO_INFO]: "unknown",
|
|
1386
|
-
[DeviceStatusType.NOT_INSTALLED]: "not_installed"
|
|
1390
|
+
[DeviceStatusType.NOT_INSTALLED]: "not_installed",
|
|
1391
|
+
[DeviceStatusType.OFFLINE]: "offline"
|
|
1387
1392
|
};
|
|
1388
1393
|
return statusMap[deviceStatus] || "unknown";
|
|
1389
1394
|
}
|
|
1390
1395
|
function shouldFlashIcon(deviceStatus) {
|
|
1391
|
-
return deviceStatus === DeviceStatusType.POWER_OFF || deviceStatus === DeviceStatusType.WARNING || deviceStatus === DeviceStatusType.FAILURE || deviceStatus === DeviceStatusType.MAINTENANCE;
|
|
1396
|
+
return deviceStatus === DeviceStatusType.POWER_OFF || deviceStatus === DeviceStatusType.WARNING || deviceStatus === DeviceStatusType.FAILURE || deviceStatus === DeviceStatusType.MAINTENANCE || deviceStatus === DeviceStatusType.OFFLINE;
|
|
1392
1397
|
}
|
|
1393
1398
|
function isDeviceOffline(deviceStatus) {
|
|
1394
|
-
return deviceStatus === DeviceStatusType.NO_INFO;
|
|
1399
|
+
return deviceStatus === DeviceStatusType.NO_INFO || deviceStatus === DeviceStatusType.OFFLINE;
|
|
1395
1400
|
}
|
|
1396
1401
|
function getDeviceStatusIcon(deviceStatus, deviceType = null) {
|
|
1397
1402
|
const normalizedType = deviceType?.toUpperCase() || "";
|
|
@@ -3947,15 +3952,30 @@ var CSS_STRING = `
|
|
|
3947
3952
|
--myio-chip-alert-fg: #b45309;
|
|
3948
3953
|
--myio-border-alert: rgba(245, 158, 11, 0.5);
|
|
3949
3954
|
|
|
3950
|
-
/* Status colors - Failure (red) */
|
|
3955
|
+
/* Status colors - Failure (dark red) */
|
|
3951
3956
|
--myio-chip-failure-bg: #fee2e2;
|
|
3952
3957
|
--myio-chip-failure-fg: #b91c1c;
|
|
3953
|
-
--myio-border-failure: rgba(
|
|
3958
|
+
--myio-border-failure: rgba(153, 27, 27, 0.6);
|
|
3959
|
+
|
|
3960
|
+
/* Status colors - Power Off (light red) */
|
|
3961
|
+
--myio-chip-power-off-bg: #fecaca;
|
|
3962
|
+
--myio-chip-power-off-fg: #dc2626;
|
|
3963
|
+
--myio-border-power-off: rgba(239, 68, 68, 0.5);
|
|
3964
|
+
|
|
3965
|
+
/* Status colors - Offline (dark gray) */
|
|
3966
|
+
--myio-chip-offline-bg: #e2e8f0;
|
|
3967
|
+
--myio-chip-offline-fg: #475569;
|
|
3968
|
+
--myio-border-offline: rgba(71, 85, 105, 0.6);
|
|
3969
|
+
|
|
3970
|
+
/* Status colors - No Info (dark orange) */
|
|
3971
|
+
--myio-chip-no-info-bg: #fed7aa;
|
|
3972
|
+
--myio-chip-no-info-fg: #c2410c;
|
|
3973
|
+
--myio-border-no-info: rgba(194, 65, 12, 0.5);
|
|
3954
3974
|
|
|
3955
|
-
/* Status colors -
|
|
3956
|
-
--myio-chip-
|
|
3957
|
-
--myio-chip-
|
|
3958
|
-
--myio-border-
|
|
3975
|
+
/* Status colors - Not Installed (purple) */
|
|
3976
|
+
--myio-chip-not-installed-bg: #e9d5ff;
|
|
3977
|
+
--myio-chip-not-installed-fg: #7c3aed;
|
|
3978
|
+
--myio-border-not-installed: rgba(124, 58, 237, 0.5);
|
|
3959
3979
|
|
|
3960
3980
|
--myio-text-1: #0f172a;
|
|
3961
3981
|
--myio-text-2: #4b5563;
|
|
@@ -4011,26 +4031,55 @@ var CSS_STRING = `
|
|
|
4011
4031
|
}
|
|
4012
4032
|
|
|
4013
4033
|
/* Card border states based on device status */
|
|
4014
|
-
|
|
4034
|
+
|
|
4035
|
+
/* POWER_ON - Blue */
|
|
4036
|
+
.myio-ho-card.is-power-on {
|
|
4015
4037
|
border-color: var(--myio-border-ok);
|
|
4016
4038
|
box-shadow: 0 0 0 2px var(--myio-border-ok), var(--myio-card-shadow);
|
|
4017
4039
|
}
|
|
4018
4040
|
|
|
4041
|
+
/* STANDBY - Green */
|
|
4019
4042
|
.myio-ho-card.is-standby {
|
|
4020
4043
|
border-color: var(--myio-border-standby);
|
|
4021
4044
|
box-shadow: 0 0 0 2px var(--myio-border-standby), var(--myio-card-shadow);
|
|
4022
4045
|
}
|
|
4023
4046
|
|
|
4024
|
-
|
|
4047
|
+
/* WARNING - Yellow */
|
|
4048
|
+
.myio-ho-card.is-warning {
|
|
4025
4049
|
border-color: var(--myio-border-alert);
|
|
4026
4050
|
box-shadow: 0 0 0 2px var(--myio-border-alert), var(--myio-card-shadow);
|
|
4027
4051
|
}
|
|
4028
4052
|
|
|
4053
|
+
/* MAINTENANCE - Yellow */
|
|
4054
|
+
.myio-ho-card.is-maintenance {
|
|
4055
|
+
border-color: var(--myio-border-alert);
|
|
4056
|
+
box-shadow: 0 0 0 2px var(--myio-border-alert), var(--myio-card-shadow);
|
|
4057
|
+
}
|
|
4058
|
+
|
|
4059
|
+
/* FAILURE - Dark Red */
|
|
4029
4060
|
.myio-ho-card.is-failure {
|
|
4030
4061
|
border-color: var(--myio-border-failure);
|
|
4031
4062
|
box-shadow: 0 0 0 2px var(--myio-border-failure), var(--myio-card-shadow);
|
|
4032
4063
|
}
|
|
4033
4064
|
|
|
4065
|
+
/* POWER_OFF - Light Red */
|
|
4066
|
+
.myio-ho-card.is-power-off {
|
|
4067
|
+
border-color: var(--myio-border-power-off);
|
|
4068
|
+
box-shadow: 0 0 0 2px var(--myio-border-power-off), var(--myio-card-shadow);
|
|
4069
|
+
}
|
|
4070
|
+
|
|
4071
|
+
/* NO_INFO - Dark Orange */
|
|
4072
|
+
.myio-ho-card.is-no-info {
|
|
4073
|
+
border-color: var(--myio-border-no-info);
|
|
4074
|
+
box-shadow: 0 0 0 2px var(--myio-border-no-info), var(--myio-card-shadow);
|
|
4075
|
+
}
|
|
4076
|
+
|
|
4077
|
+
/* NOT_INSTALLED - Purple */
|
|
4078
|
+
.myio-ho-card.is-not-installed {
|
|
4079
|
+
border-color: var(--myio-border-not-installed);
|
|
4080
|
+
box-shadow: 0 0 0 2px var(--myio-border-not-installed), var(--myio-card-shadow);
|
|
4081
|
+
}
|
|
4082
|
+
|
|
4034
4083
|
/* Header section */
|
|
4035
4084
|
.myio-ho-card__header {
|
|
4036
4085
|
display: flex;
|
|
@@ -4048,7 +4097,9 @@ var CSS_STRING = `
|
|
|
4048
4097
|
margin-top: 2px;
|
|
4049
4098
|
}
|
|
4050
4099
|
|
|
4051
|
-
|
|
4100
|
+
/* Icon colors based on status */
|
|
4101
|
+
.myio-ho-card.is-warning .myio-ho-card__icon,
|
|
4102
|
+
.myio-ho-card.is-maintenance .myio-ho-card__icon {
|
|
4052
4103
|
color: var(--myio-chip-alert-fg);
|
|
4053
4104
|
}
|
|
4054
4105
|
|
|
@@ -4056,14 +4107,28 @@ var CSS_STRING = `
|
|
|
4056
4107
|
color: var(--myio-chip-failure-fg);
|
|
4057
4108
|
}
|
|
4058
4109
|
|
|
4110
|
+
.myio-ho-card.is-power-off .myio-ho-card__icon {
|
|
4111
|
+
color: var(--myio-chip-power-off-fg);
|
|
4112
|
+
}
|
|
4113
|
+
|
|
4114
|
+
.myio-ho-card.is-offline .myio-ho-card__icon {
|
|
4115
|
+
color: var(--myio-chip-offline-fg);
|
|
4116
|
+
}
|
|
4117
|
+
|
|
4118
|
+
.myio-ho-card.is-no-info .myio-ho-card__icon {
|
|
4119
|
+
color: var(--myio-chip-no-info-fg);
|
|
4120
|
+
}
|
|
4121
|
+
|
|
4122
|
+
.myio-ho-card.is-not-installed .myio-ho-card__icon {
|
|
4123
|
+
color: var(--myio-chip-not-installed-fg);
|
|
4124
|
+
}
|
|
4125
|
+
|
|
4059
4126
|
.myio-ho-card__title {
|
|
4060
4127
|
flex: 1;
|
|
4061
4128
|
min-width: 0;
|
|
4062
4129
|
}
|
|
4063
4130
|
|
|
4064
|
-
/*
|
|
4065
|
-
|
|
4066
|
-
/* Estado Offline - borda cinza */
|
|
4131
|
+
/* OFFLINE - Dark Gray */
|
|
4067
4132
|
.myio-ho-card.is-offline {
|
|
4068
4133
|
border-color: var(--myio-border-offline);
|
|
4069
4134
|
box-shadow: 0 0 0 2px var(--myio-border-offline), var(--myio-card-shadow);
|
|
@@ -4458,6 +4523,37 @@ var CSS_STRING = `
|
|
|
4458
4523
|
color: var(--myio-chip-offline-fg);
|
|
4459
4524
|
}
|
|
4460
4525
|
|
|
4526
|
+
/* New chip classes aligned with getCardStateClass */
|
|
4527
|
+
.chip--power-on {
|
|
4528
|
+
background: var(--myio-chip-ok-bg);
|
|
4529
|
+
color: var(--myio-chip-ok-fg);
|
|
4530
|
+
}
|
|
4531
|
+
|
|
4532
|
+
.chip--warning {
|
|
4533
|
+
background: var(--myio-chip-alert-bg);
|
|
4534
|
+
color: var(--myio-chip-alert-fg);
|
|
4535
|
+
}
|
|
4536
|
+
|
|
4537
|
+
.chip--maintenance {
|
|
4538
|
+
background: var(--myio-chip-alert-bg);
|
|
4539
|
+
color: var(--myio-chip-alert-fg);
|
|
4540
|
+
}
|
|
4541
|
+
|
|
4542
|
+
.chip--power-off {
|
|
4543
|
+
background: var(--myio-chip-power-off-bg);
|
|
4544
|
+
color: var(--myio-chip-power-off-fg);
|
|
4545
|
+
}
|
|
4546
|
+
|
|
4547
|
+
.chip--no-info {
|
|
4548
|
+
background: var(--myio-chip-no-info-bg);
|
|
4549
|
+
color: var(--myio-chip-no-info-fg);
|
|
4550
|
+
}
|
|
4551
|
+
|
|
4552
|
+
.chip--not-installed {
|
|
4553
|
+
background: var(--myio-chip-not-installed-bg);
|
|
4554
|
+
color: var(--myio-chip-not-installed-fg);
|
|
4555
|
+
}
|
|
4556
|
+
|
|
4461
4557
|
/* Status indicator dot for power metric */
|
|
4462
4558
|
.status-dot {
|
|
4463
4559
|
width: 8px;
|
|
@@ -4491,6 +4587,31 @@ var CSS_STRING = `
|
|
|
4491
4587
|
background: var(--myio-muted);
|
|
4492
4588
|
}
|
|
4493
4589
|
|
|
4590
|
+
/* New dot classes aligned with getCardStateClass */
|
|
4591
|
+
.status-dot.dot--power-on {
|
|
4592
|
+
background: var(--myio-chip-ok-fg);
|
|
4593
|
+
}
|
|
4594
|
+
|
|
4595
|
+
.status-dot.dot--warning {
|
|
4596
|
+
background: var(--myio-chip-alert-fg);
|
|
4597
|
+
}
|
|
4598
|
+
|
|
4599
|
+
.status-dot.dot--maintenance {
|
|
4600
|
+
background: var(--myio-chip-alert-fg);
|
|
4601
|
+
}
|
|
4602
|
+
|
|
4603
|
+
.status-dot.dot--power-off {
|
|
4604
|
+
background: var(--myio-chip-power-off-fg);
|
|
4605
|
+
}
|
|
4606
|
+
|
|
4607
|
+
.status-dot.dot--no-info {
|
|
4608
|
+
background: var(--myio-chip-no-info-fg);
|
|
4609
|
+
}
|
|
4610
|
+
|
|
4611
|
+
.status-dot.dot--not-installed {
|
|
4612
|
+
background: var(--myio-chip-not-installed-fg);
|
|
4613
|
+
}
|
|
4614
|
+
|
|
4494
4615
|
/* Primary metric */
|
|
4495
4616
|
.myio-ho-card__primary {
|
|
4496
4617
|
margin-bottom: 14px;
|
|
@@ -4673,6 +4794,215 @@ var CSS_STRING = `
|
|
|
4673
4794
|
transition: none;
|
|
4674
4795
|
}
|
|
4675
4796
|
}
|
|
4797
|
+
|
|
4798
|
+
/* ============================================
|
|
4799
|
+
DEBUG TOOLTIP STYLES (Premium)
|
|
4800
|
+
============================================ */
|
|
4801
|
+
|
|
4802
|
+
.has-debug-tooltip {
|
|
4803
|
+
cursor: help !important;
|
|
4804
|
+
}
|
|
4805
|
+
|
|
4806
|
+
.has-debug-tooltip::after {
|
|
4807
|
+
content: '\u{1F41B}';
|
|
4808
|
+
position: absolute;
|
|
4809
|
+
top: -4px;
|
|
4810
|
+
right: -4px;
|
|
4811
|
+
font-size: 10px;
|
|
4812
|
+
z-index: 1;
|
|
4813
|
+
}
|
|
4814
|
+
|
|
4815
|
+
.debug-tooltip-container {
|
|
4816
|
+
position: absolute;
|
|
4817
|
+
bottom: calc(100% + 8px);
|
|
4818
|
+
left: 50%;
|
|
4819
|
+
transform: translateX(-50%);
|
|
4820
|
+
z-index: 10000;
|
|
4821
|
+
pointer-events: none;
|
|
4822
|
+
opacity: 0;
|
|
4823
|
+
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
4824
|
+
}
|
|
4825
|
+
|
|
4826
|
+
.has-debug-tooltip:hover .debug-tooltip-container {
|
|
4827
|
+
opacity: 1;
|
|
4828
|
+
pointer-events: auto;
|
|
4829
|
+
}
|
|
4830
|
+
|
|
4831
|
+
.debug-tooltip {
|
|
4832
|
+
background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
|
|
4833
|
+
border: 1px solid rgba(99, 102, 241, 0.3);
|
|
4834
|
+
border-radius: 12px;
|
|
4835
|
+
box-shadow:
|
|
4836
|
+
0 20px 40px rgba(0, 0, 0, 0.4),
|
|
4837
|
+
0 0 0 1px rgba(255, 255, 255, 0.05),
|
|
4838
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
4839
|
+
min-width: 340px;
|
|
4840
|
+
max-width: 420px;
|
|
4841
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
4842
|
+
font-size: 12px;
|
|
4843
|
+
color: #e2e8f0;
|
|
4844
|
+
overflow: hidden;
|
|
4845
|
+
}
|
|
4846
|
+
|
|
4847
|
+
.debug-tooltip__header {
|
|
4848
|
+
display: flex;
|
|
4849
|
+
align-items: center;
|
|
4850
|
+
gap: 8px;
|
|
4851
|
+
padding: 12px 16px;
|
|
4852
|
+
background: linear-gradient(90deg, rgba(99, 102, 241, 0.2) 0%, rgba(139, 92, 246, 0.1) 100%);
|
|
4853
|
+
border-bottom: 1px solid rgba(99, 102, 241, 0.2);
|
|
4854
|
+
}
|
|
4855
|
+
|
|
4856
|
+
.debug-tooltip__icon {
|
|
4857
|
+
font-size: 16px;
|
|
4858
|
+
}
|
|
4859
|
+
|
|
4860
|
+
.debug-tooltip__title {
|
|
4861
|
+
font-weight: 700;
|
|
4862
|
+
font-size: 13px;
|
|
4863
|
+
color: #f1f5f9;
|
|
4864
|
+
letter-spacing: 0.5px;
|
|
4865
|
+
text-transform: uppercase;
|
|
4866
|
+
}
|
|
4867
|
+
|
|
4868
|
+
.debug-tooltip__content {
|
|
4869
|
+
padding: 12px 16px;
|
|
4870
|
+
max-height: 400px;
|
|
4871
|
+
overflow-y: auto;
|
|
4872
|
+
}
|
|
4873
|
+
|
|
4874
|
+
.debug-tooltip__section {
|
|
4875
|
+
margin-bottom: 14px;
|
|
4876
|
+
padding-bottom: 12px;
|
|
4877
|
+
border-bottom: 1px solid rgba(148, 163, 184, 0.1);
|
|
4878
|
+
}
|
|
4879
|
+
|
|
4880
|
+
.debug-tooltip__section:last-child {
|
|
4881
|
+
margin-bottom: 0;
|
|
4882
|
+
padding-bottom: 0;
|
|
4883
|
+
border-bottom: none;
|
|
4884
|
+
}
|
|
4885
|
+
|
|
4886
|
+
.debug-tooltip__section-title {
|
|
4887
|
+
font-size: 11px;
|
|
4888
|
+
font-weight: 600;
|
|
4889
|
+
color: #94a3b8;
|
|
4890
|
+
text-transform: uppercase;
|
|
4891
|
+
letter-spacing: 0.8px;
|
|
4892
|
+
margin-bottom: 10px;
|
|
4893
|
+
display: flex;
|
|
4894
|
+
align-items: center;
|
|
4895
|
+
gap: 6px;
|
|
4896
|
+
}
|
|
4897
|
+
|
|
4898
|
+
.debug-tooltip__row {
|
|
4899
|
+
display: flex;
|
|
4900
|
+
justify-content: space-between;
|
|
4901
|
+
align-items: flex-start;
|
|
4902
|
+
padding: 4px 0;
|
|
4903
|
+
gap: 12px;
|
|
4904
|
+
}
|
|
4905
|
+
|
|
4906
|
+
.debug-tooltip__row--full {
|
|
4907
|
+
flex-direction: column;
|
|
4908
|
+
gap: 4px;
|
|
4909
|
+
}
|
|
4910
|
+
|
|
4911
|
+
.debug-tooltip__label {
|
|
4912
|
+
color: #94a3b8;
|
|
4913
|
+
font-size: 11px;
|
|
4914
|
+
flex-shrink: 0;
|
|
4915
|
+
}
|
|
4916
|
+
|
|
4917
|
+
.debug-tooltip__value {
|
|
4918
|
+
color: #f1f5f9;
|
|
4919
|
+
font-weight: 500;
|
|
4920
|
+
text-align: right;
|
|
4921
|
+
word-break: break-all;
|
|
4922
|
+
}
|
|
4923
|
+
|
|
4924
|
+
.debug-tooltip__row--full .debug-tooltip__value {
|
|
4925
|
+
text-align: left;
|
|
4926
|
+
background: rgba(0, 0, 0, 0.3);
|
|
4927
|
+
padding: 6px 10px;
|
|
4928
|
+
border-radius: 6px;
|
|
4929
|
+
font-size: 11px;
|
|
4930
|
+
width: 100%;
|
|
4931
|
+
box-sizing: border-box;
|
|
4932
|
+
}
|
|
4933
|
+
|
|
4934
|
+
.debug-tooltip__value--mono {
|
|
4935
|
+
font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
|
|
4936
|
+
font-size: 11px;
|
|
4937
|
+
background: rgba(0, 0, 0, 0.3);
|
|
4938
|
+
padding: 2px 6px;
|
|
4939
|
+
border-radius: 4px;
|
|
4940
|
+
}
|
|
4941
|
+
|
|
4942
|
+
.debug-tooltip__value--highlight {
|
|
4943
|
+
color: #a5b4fc;
|
|
4944
|
+
font-style: italic;
|
|
4945
|
+
}
|
|
4946
|
+
|
|
4947
|
+
.debug-tooltip__badge {
|
|
4948
|
+
display: inline-block;
|
|
4949
|
+
padding: 2px 8px;
|
|
4950
|
+
border-radius: 4px;
|
|
4951
|
+
font-size: 10px;
|
|
4952
|
+
font-weight: 600;
|
|
4953
|
+
text-transform: uppercase;
|
|
4954
|
+
letter-spacing: 0.5px;
|
|
4955
|
+
background: rgba(99, 102, 241, 0.3);
|
|
4956
|
+
color: #a5b4fc;
|
|
4957
|
+
}
|
|
4958
|
+
|
|
4959
|
+
.debug-tooltip__badge--energy {
|
|
4960
|
+
background: rgba(59, 130, 246, 0.3);
|
|
4961
|
+
color: #93c5fd;
|
|
4962
|
+
}
|
|
4963
|
+
|
|
4964
|
+
.debug-tooltip__badge--water {
|
|
4965
|
+
background: rgba(6, 182, 212, 0.3);
|
|
4966
|
+
color: #67e8f9;
|
|
4967
|
+
}
|
|
4968
|
+
|
|
4969
|
+
.debug-tooltip__badge--temperature {
|
|
4970
|
+
background: rgba(249, 115, 22, 0.3);
|
|
4971
|
+
color: #fdba74;
|
|
4972
|
+
}
|
|
4973
|
+
|
|
4974
|
+
/* Tooltip arrow */
|
|
4975
|
+
.debug-tooltip::after {
|
|
4976
|
+
content: '';
|
|
4977
|
+
position: absolute;
|
|
4978
|
+
bottom: -6px;
|
|
4979
|
+
left: 50%;
|
|
4980
|
+
transform: translateX(-50%) rotate(45deg);
|
|
4981
|
+
width: 12px;
|
|
4982
|
+
height: 12px;
|
|
4983
|
+
background: #0f172a;
|
|
4984
|
+
border-right: 1px solid rgba(99, 102, 241, 0.3);
|
|
4985
|
+
border-bottom: 1px solid rgba(99, 102, 241, 0.3);
|
|
4986
|
+
}
|
|
4987
|
+
|
|
4988
|
+
/* Scrollbar styling for tooltip content */
|
|
4989
|
+
.debug-tooltip__content::-webkit-scrollbar {
|
|
4990
|
+
width: 6px;
|
|
4991
|
+
}
|
|
4992
|
+
|
|
4993
|
+
.debug-tooltip__content::-webkit-scrollbar-track {
|
|
4994
|
+
background: rgba(0, 0, 0, 0.2);
|
|
4995
|
+
border-radius: 3px;
|
|
4996
|
+
}
|
|
4997
|
+
|
|
4998
|
+
.debug-tooltip__content::-webkit-scrollbar-thumb {
|
|
4999
|
+
background: rgba(99, 102, 241, 0.4);
|
|
5000
|
+
border-radius: 3px;
|
|
5001
|
+
}
|
|
5002
|
+
|
|
5003
|
+
.debug-tooltip__content::-webkit-scrollbar-thumb:hover {
|
|
5004
|
+
background: rgba(99, 102, 241, 0.6);
|
|
5005
|
+
}
|
|
4676
5006
|
`;
|
|
4677
5007
|
|
|
4678
5008
|
// src/thingsboard/main-dashboard-shopping/v-4.0.0/head-office/card-head-office.icons.ts
|
|
@@ -4827,7 +5157,246 @@ var DEFAULT_I18N = {
|
|
|
4827
5157
|
menu_settings: "Configura\xE7\xF5es"
|
|
4828
5158
|
};
|
|
4829
5159
|
|
|
5160
|
+
// src/components/temperature/utils.ts
|
|
5161
|
+
var DAY_PERIODS = [
|
|
5162
|
+
{ id: "madrugada", label: "Madrugada (00h-06h)", startHour: 0, endHour: 6 },
|
|
5163
|
+
{ id: "manha", label: "Manh\xE3 (06h-12h)", startHour: 6, endHour: 12 },
|
|
5164
|
+
{ id: "tarde", label: "Tarde (12h-18h)", startHour: 12, endHour: 18 },
|
|
5165
|
+
{ id: "noite", label: "Noite (18h-24h)", startHour: 18, endHour: 24 }
|
|
5166
|
+
];
|
|
5167
|
+
var DEFAULT_CLAMP_RANGE = { min: 15, max: 40 };
|
|
5168
|
+
function getTodaySoFar() {
|
|
5169
|
+
const now = /* @__PURE__ */ new Date();
|
|
5170
|
+
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0);
|
|
5171
|
+
return {
|
|
5172
|
+
startTs: startOfDay.getTime(),
|
|
5173
|
+
endTs: now.getTime()
|
|
5174
|
+
};
|
|
5175
|
+
}
|
|
5176
|
+
var CHART_COLORS = [
|
|
5177
|
+
"#1976d2",
|
|
5178
|
+
// Blue
|
|
5179
|
+
"#FF6B6B",
|
|
5180
|
+
// Red
|
|
5181
|
+
"#4CAF50",
|
|
5182
|
+
// Green
|
|
5183
|
+
"#FF9800",
|
|
5184
|
+
// Orange
|
|
5185
|
+
"#9C27B0",
|
|
5186
|
+
// Purple
|
|
5187
|
+
"#00BCD4",
|
|
5188
|
+
// Cyan
|
|
5189
|
+
"#E91E63",
|
|
5190
|
+
// Pink
|
|
5191
|
+
"#795548"
|
|
5192
|
+
// Brown
|
|
5193
|
+
];
|
|
5194
|
+
async function fetchTemperatureData(token, deviceId, startTs, endTs) {
|
|
5195
|
+
const url = `/api/plugins/telemetry/DEVICE/${deviceId}/values/timeseries?keys=temperature&startTs=${encodeURIComponent(startTs)}&endTs=${encodeURIComponent(endTs)}&limit=50000&agg=NONE`;
|
|
5196
|
+
const response = await fetch(url, {
|
|
5197
|
+
headers: {
|
|
5198
|
+
"X-Authorization": `Bearer ${token}`,
|
|
5199
|
+
"Content-Type": "application/json"
|
|
5200
|
+
}
|
|
5201
|
+
});
|
|
5202
|
+
if (!response.ok) {
|
|
5203
|
+
throw new Error(`Failed to fetch temperature data: ${response.status}`);
|
|
5204
|
+
}
|
|
5205
|
+
const data = await response.json();
|
|
5206
|
+
return data?.temperature || [];
|
|
5207
|
+
}
|
|
5208
|
+
function clampTemperature(value, range = DEFAULT_CLAMP_RANGE) {
|
|
5209
|
+
const num = Number(value || 0);
|
|
5210
|
+
if (num < range.min) return range.min;
|
|
5211
|
+
if (num > range.max) return range.max;
|
|
5212
|
+
return num;
|
|
5213
|
+
}
|
|
5214
|
+
function calculateStats(data, clampRange = DEFAULT_CLAMP_RANGE) {
|
|
5215
|
+
if (data.length === 0) {
|
|
5216
|
+
return { avg: 0, min: 0, max: 0, count: 0 };
|
|
5217
|
+
}
|
|
5218
|
+
const values = data.map((item) => clampTemperature(item.value, clampRange));
|
|
5219
|
+
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
5220
|
+
return {
|
|
5221
|
+
avg: sum / values.length,
|
|
5222
|
+
min: Math.min(...values),
|
|
5223
|
+
max: Math.max(...values),
|
|
5224
|
+
count: values.length
|
|
5225
|
+
};
|
|
5226
|
+
}
|
|
5227
|
+
function interpolateTemperature(data, options) {
|
|
5228
|
+
const { intervalMinutes, startTs, endTs, clampRange = DEFAULT_CLAMP_RANGE } = options;
|
|
5229
|
+
const intervalMs = intervalMinutes * 60 * 1e3;
|
|
5230
|
+
if (data.length === 0) {
|
|
5231
|
+
return [];
|
|
5232
|
+
}
|
|
5233
|
+
const sortedData = [...data].sort((a, b) => a.ts - b.ts);
|
|
5234
|
+
const result = [];
|
|
5235
|
+
let lastKnownValue = clampTemperature(sortedData[0].value, clampRange);
|
|
5236
|
+
let dataIndex = 0;
|
|
5237
|
+
for (let ts = startTs; ts <= endTs; ts += intervalMs) {
|
|
5238
|
+
while (dataIndex < sortedData.length - 1 && sortedData[dataIndex + 1].ts <= ts) {
|
|
5239
|
+
dataIndex++;
|
|
5240
|
+
}
|
|
5241
|
+
const currentData = sortedData[dataIndex];
|
|
5242
|
+
if (currentData && Math.abs(currentData.ts - ts) < intervalMs) {
|
|
5243
|
+
lastKnownValue = clampTemperature(currentData.value, clampRange);
|
|
5244
|
+
}
|
|
5245
|
+
result.push({
|
|
5246
|
+
ts,
|
|
5247
|
+
value: lastKnownValue
|
|
5248
|
+
});
|
|
5249
|
+
}
|
|
5250
|
+
return result;
|
|
5251
|
+
}
|
|
5252
|
+
function aggregateByDay(data, clampRange = DEFAULT_CLAMP_RANGE) {
|
|
5253
|
+
if (data.length === 0) {
|
|
5254
|
+
return [];
|
|
5255
|
+
}
|
|
5256
|
+
const dayMap = /* @__PURE__ */ new Map();
|
|
5257
|
+
data.forEach((item) => {
|
|
5258
|
+
const date = new Date(item.ts);
|
|
5259
|
+
const dateKey = date.toISOString().split("T")[0];
|
|
5260
|
+
if (!dayMap.has(dateKey)) {
|
|
5261
|
+
dayMap.set(dateKey, []);
|
|
5262
|
+
}
|
|
5263
|
+
dayMap.get(dateKey).push(item);
|
|
5264
|
+
});
|
|
5265
|
+
const result = [];
|
|
5266
|
+
dayMap.forEach((dayData, dateKey) => {
|
|
5267
|
+
const values = dayData.map((item) => clampTemperature(item.value, clampRange));
|
|
5268
|
+
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
5269
|
+
result.push({
|
|
5270
|
+
date: dateKey,
|
|
5271
|
+
dateTs: new Date(dateKey).getTime(),
|
|
5272
|
+
avg: sum / values.length,
|
|
5273
|
+
min: Math.min(...values),
|
|
5274
|
+
max: Math.max(...values),
|
|
5275
|
+
count: values.length
|
|
5276
|
+
});
|
|
5277
|
+
});
|
|
5278
|
+
return result.sort((a, b) => a.dateTs - b.dateTs);
|
|
5279
|
+
}
|
|
5280
|
+
function filterByDayPeriods(data, selectedPeriods) {
|
|
5281
|
+
if (selectedPeriods.length === 0 || selectedPeriods.length === DAY_PERIODS.length) {
|
|
5282
|
+
return data;
|
|
5283
|
+
}
|
|
5284
|
+
return data.filter((item) => {
|
|
5285
|
+
const date = new Date(item.ts);
|
|
5286
|
+
const hour = date.getHours();
|
|
5287
|
+
return selectedPeriods.some((periodId) => {
|
|
5288
|
+
const period = DAY_PERIODS.find((p) => p.id === periodId);
|
|
5289
|
+
if (!period) return false;
|
|
5290
|
+
return hour >= period.startHour && hour < period.endHour;
|
|
5291
|
+
});
|
|
5292
|
+
});
|
|
5293
|
+
}
|
|
5294
|
+
function getSelectedPeriodsLabel(selectedPeriods) {
|
|
5295
|
+
if (selectedPeriods.length === 0 || selectedPeriods.length === DAY_PERIODS.length) {
|
|
5296
|
+
return "Todos os per\xEDodos";
|
|
5297
|
+
}
|
|
5298
|
+
if (selectedPeriods.length === 1) {
|
|
5299
|
+
const period = DAY_PERIODS.find((p) => p.id === selectedPeriods[0]);
|
|
5300
|
+
return period?.label || "";
|
|
5301
|
+
}
|
|
5302
|
+
return `${selectedPeriods.length} per\xEDodos selecionados`;
|
|
5303
|
+
}
|
|
5304
|
+
function formatTemperature(value, decimals = 1) {
|
|
5305
|
+
if (value === null || value === void 0 || isNaN(value)) {
|
|
5306
|
+
return "\u2014";
|
|
5307
|
+
}
|
|
5308
|
+
return `${value.toFixed(decimals)}\xB0C`;
|
|
5309
|
+
}
|
|
5310
|
+
function exportTemperatureCSV(data, deviceLabel, stats, startDate, endDate) {
|
|
5311
|
+
if (data.length === 0) {
|
|
5312
|
+
console.warn("No data to export");
|
|
5313
|
+
return;
|
|
5314
|
+
}
|
|
5315
|
+
const BOM = "\uFEFF";
|
|
5316
|
+
let csvContent = BOM;
|
|
5317
|
+
csvContent += `Relat\xF3rio de Temperatura - ${deviceLabel}
|
|
5318
|
+
`;
|
|
5319
|
+
csvContent += `Per\xEDodo: ${startDate} at\xE9 ${endDate}
|
|
5320
|
+
`;
|
|
5321
|
+
csvContent += `M\xE9dia: ${formatTemperature(stats.avg)}
|
|
5322
|
+
`;
|
|
5323
|
+
csvContent += `M\xEDnima: ${formatTemperature(stats.min)}
|
|
5324
|
+
`;
|
|
5325
|
+
csvContent += `M\xE1xima: ${formatTemperature(stats.max)}
|
|
5326
|
+
`;
|
|
5327
|
+
csvContent += `Total de leituras: ${stats.count}
|
|
5328
|
+
`;
|
|
5329
|
+
csvContent += "\n";
|
|
5330
|
+
csvContent += "Data/Hora,Temperatura (\xB0C)\n";
|
|
5331
|
+
data.forEach((item) => {
|
|
5332
|
+
const date = new Date(item.ts).toLocaleString("pt-BR");
|
|
5333
|
+
const temp = Number(item.value).toFixed(2);
|
|
5334
|
+
csvContent += `"${date}",${temp}
|
|
5335
|
+
`;
|
|
5336
|
+
});
|
|
5337
|
+
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
5338
|
+
const url = URL.createObjectURL(blob);
|
|
5339
|
+
const link = document.createElement("a");
|
|
5340
|
+
link.href = url;
|
|
5341
|
+
link.download = `temperatura_${deviceLabel.replace(/\s+/g, "_")}_${startDate}_${endDate}.csv`;
|
|
5342
|
+
document.body.appendChild(link);
|
|
5343
|
+
link.click();
|
|
5344
|
+
document.body.removeChild(link);
|
|
5345
|
+
URL.revokeObjectURL(url);
|
|
5346
|
+
}
|
|
5347
|
+
var DARK_THEME = {
|
|
5348
|
+
background: "rgba(0, 0, 0, 0.85)",
|
|
5349
|
+
surface: "#1a1f28",
|
|
5350
|
+
text: "#ffffff",
|
|
5351
|
+
textMuted: "rgba(255, 255, 255, 0.7)",
|
|
5352
|
+
border: "rgba(255, 255, 255, 0.1)",
|
|
5353
|
+
primary: "#1976d2",
|
|
5354
|
+
success: "#4CAF50",
|
|
5355
|
+
warning: "#FF9800",
|
|
5356
|
+
danger: "#f44336",
|
|
5357
|
+
chartLine: "#1976d2",
|
|
5358
|
+
chartGrid: "rgba(255, 255, 255, 0.1)"
|
|
5359
|
+
};
|
|
5360
|
+
var LIGHT_THEME = {
|
|
5361
|
+
background: "rgba(0, 0, 0, 0.6)",
|
|
5362
|
+
surface: "#ffffff",
|
|
5363
|
+
text: "#333333",
|
|
5364
|
+
textMuted: "#666666",
|
|
5365
|
+
border: "#e0e0e0",
|
|
5366
|
+
primary: "#1976d2",
|
|
5367
|
+
success: "#4CAF50",
|
|
5368
|
+
warning: "#FF9800",
|
|
5369
|
+
danger: "#f44336",
|
|
5370
|
+
chartLine: "#1976d2",
|
|
5371
|
+
chartGrid: "#e0e0e0"
|
|
5372
|
+
};
|
|
5373
|
+
function getThemeColors(theme) {
|
|
5374
|
+
return theme === "dark" ? DARK_THEME : LIGHT_THEME;
|
|
5375
|
+
}
|
|
5376
|
+
|
|
5377
|
+
// src/utils/logHelper.js
|
|
5378
|
+
function createLogHelper(debugActive = false) {
|
|
5379
|
+
return {
|
|
5380
|
+
log: function(...args) {
|
|
5381
|
+
if (debugActive) {
|
|
5382
|
+
console.log(...args);
|
|
5383
|
+
}
|
|
5384
|
+
},
|
|
5385
|
+
warn: function(...args) {
|
|
5386
|
+
if (debugActive) {
|
|
5387
|
+
console.warn(...args);
|
|
5388
|
+
}
|
|
5389
|
+
},
|
|
5390
|
+
error: function(...args) {
|
|
5391
|
+
console.error(...args);
|
|
5392
|
+
}
|
|
5393
|
+
};
|
|
5394
|
+
}
|
|
5395
|
+
var LogHelper = createLogHelper(false);
|
|
5396
|
+
|
|
4830
5397
|
// src/thingsboard/main-dashboard-shopping/v-4.0.0/card/head-office/card-head-office.js
|
|
5398
|
+
var LABEL_CHAR_LIMIT = 18;
|
|
5399
|
+
var DEFAUL_DELAY_TIME_CONNECTION_IN_MINS = 1440;
|
|
4831
5400
|
var CSS_TAG = "head-office-card-v1";
|
|
4832
5401
|
function ensureCss() {
|
|
4833
5402
|
if (!document.querySelector(`style[data-myio-css="${CSS_TAG}"]`)) {
|
|
@@ -4841,11 +5410,17 @@ function normalizeParams(params) {
|
|
|
4841
5410
|
if (!params || !params.entityObject) {
|
|
4842
5411
|
throw new Error("renderCardCompenteHeadOffice: entityObject is required");
|
|
4843
5412
|
}
|
|
5413
|
+
const LogHelper2 = createLogHelper(params.debugActive ?? false);
|
|
4844
5414
|
const entityObject = params.entityObject;
|
|
4845
5415
|
if (!entityObject.entityId) {
|
|
4846
|
-
|
|
5416
|
+
LogHelper2.warn("[CardHeadOffice] entityId is missing, generating temporary ID");
|
|
4847
5417
|
entityObject.entityId = `temp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
4848
5418
|
}
|
|
5419
|
+
if (!params.delayTimeConnectionInMins) {
|
|
5420
|
+
LogHelper2.warn(
|
|
5421
|
+
`[CardHeadOffice] delayTimeConnectionInMins is missing, defaulting to ${DEFAUL_DELAY_TIME_CONNECTION_IN_MINS} mins`
|
|
5422
|
+
);
|
|
5423
|
+
}
|
|
4849
5424
|
return {
|
|
4850
5425
|
entityObject,
|
|
4851
5426
|
i18n: { ...DEFAULT_I18N, ...params.i18n || {} },
|
|
@@ -4853,7 +5428,12 @@ function normalizeParams(params) {
|
|
|
4853
5428
|
enableDragDrop: Boolean(params.enableDragDrop),
|
|
4854
5429
|
useNewComponents: Boolean(params.useNewComponents),
|
|
4855
5430
|
// RFC-0091: Configurable delay time for connection status check (default 15 minutes)
|
|
4856
|
-
delayTimeConnectionInMins: params.delayTimeConnectionInMins ??
|
|
5431
|
+
delayTimeConnectionInMins: params.delayTimeConnectionInMins ?? DEFAUL_DELAY_TIME_CONNECTION_IN_MINS,
|
|
5432
|
+
// Debug options
|
|
5433
|
+
debugActive: params.debugActive ?? false,
|
|
5434
|
+
activeTooltipDebug: params.activeTooltipDebug ?? false,
|
|
5435
|
+
// LogHelper instance for this card
|
|
5436
|
+
LogHelper: LogHelper2,
|
|
4857
5437
|
callbacks: {
|
|
4858
5438
|
handleActionDashboard: params.handleActionDashboard,
|
|
4859
5439
|
handleActionReport: params.handleActionReport,
|
|
@@ -4891,16 +5471,10 @@ function formatValueByDomain(value, domain) {
|
|
|
4891
5471
|
return formatWaterVolumeM3(value);
|
|
4892
5472
|
}
|
|
4893
5473
|
if (domain === "temperature") {
|
|
4894
|
-
return formatTemperature(value);
|
|
5474
|
+
return formatTemperature(value, 0);
|
|
4895
5475
|
}
|
|
4896
5476
|
return formatEnergy(value);
|
|
4897
5477
|
}
|
|
4898
|
-
function formatTemperature(temp) {
|
|
4899
|
-
if (temp === null || temp === void 0 || isNaN(temp)) {
|
|
4900
|
-
return "\u2014";
|
|
4901
|
-
}
|
|
4902
|
-
return `${temp.toFixed(0)}\xB0C`;
|
|
4903
|
-
}
|
|
4904
5478
|
function calculateConsumptionPercentage(target, consumption) {
|
|
4905
5479
|
const numericTarget = Number(target);
|
|
4906
5480
|
const numericConsumption = Number(consumption);
|
|
@@ -4915,32 +5489,32 @@ function getStatusInfo(deviceStatus, i18n, domain) {
|
|
|
4915
5489
|
// --- Novos Status de Temperatura ---
|
|
4916
5490
|
case "normal":
|
|
4917
5491
|
return { chipClass: "chip--ok", label: "Normal" };
|
|
4918
|
-
// Verde/Azul
|
|
4919
5492
|
case "cold":
|
|
4920
5493
|
return { chipClass: "chip--standby", label: "Frio" };
|
|
4921
|
-
// Azul claro/Ciano
|
|
4922
5494
|
case "hot":
|
|
4923
5495
|
return { chipClass: "chip--alert", label: "Quente" };
|
|
4924
|
-
//
|
|
4925
|
-
// --- Status Existentes ---
|
|
5496
|
+
// --- Status Existentes (aligned with getCardStateClass) ---
|
|
4926
5497
|
case DeviceStatusType.POWER_ON:
|
|
4927
5498
|
if (domain === "water") {
|
|
4928
|
-
return { chipClass: "chip--
|
|
5499
|
+
return { chipClass: "chip--power-on", label: i18n.in_operation_water };
|
|
4929
5500
|
}
|
|
4930
|
-
return { chipClass: "chip--
|
|
5501
|
+
return { chipClass: "chip--power-on", label: i18n.in_operation };
|
|
4931
5502
|
case DeviceStatusType.STANDBY:
|
|
4932
5503
|
return { chipClass: "chip--standby", label: i18n.standby };
|
|
4933
5504
|
case DeviceStatusType.WARNING:
|
|
4934
|
-
return { chipClass: "chip--
|
|
5505
|
+
return { chipClass: "chip--warning", label: i18n.alert };
|
|
5506
|
+
case DeviceStatusType.MAINTENANCE:
|
|
5507
|
+
return { chipClass: "chip--maintenance", label: i18n.maintenance };
|
|
4935
5508
|
case DeviceStatusType.FAILURE:
|
|
4936
|
-
case DeviceStatusType.POWER_OFF:
|
|
4937
5509
|
return { chipClass: "chip--failure", label: i18n.failure };
|
|
4938
|
-
case DeviceStatusType.
|
|
4939
|
-
return { chipClass: "chip--
|
|
4940
|
-
case DeviceStatusType.
|
|
4941
|
-
return { chipClass: "chip--offline", label: i18n.
|
|
4942
|
-
// Default (Cai aqui se não achar 'normal', 'hot' etc)
|
|
5510
|
+
case DeviceStatusType.POWER_OFF:
|
|
5511
|
+
return { chipClass: "chip--power-off", label: i18n.power_off || i18n.failure };
|
|
5512
|
+
case DeviceStatusType.OFFLINE:
|
|
5513
|
+
return { chipClass: "chip--offline", label: i18n.offline };
|
|
4943
5514
|
case DeviceStatusType.NO_INFO:
|
|
5515
|
+
return { chipClass: "chip--no-info", label: i18n.no_info || i18n.offline };
|
|
5516
|
+
case DeviceStatusType.NOT_INSTALLED:
|
|
5517
|
+
return { chipClass: "chip--not-installed", label: i18n.not_installed };
|
|
4944
5518
|
default:
|
|
4945
5519
|
return { chipClass: "chip--offline", label: i18n.offline };
|
|
4946
5520
|
}
|
|
@@ -4948,23 +5522,32 @@ function getStatusInfo(deviceStatus, i18n, domain) {
|
|
|
4948
5522
|
function getCardStateClass(deviceStatus) {
|
|
4949
5523
|
switch (deviceStatus) {
|
|
4950
5524
|
case DeviceStatusType.POWER_ON:
|
|
4951
|
-
return "is-
|
|
5525
|
+
return "is-power-on";
|
|
4952
5526
|
// Blue border
|
|
4953
5527
|
case DeviceStatusType.STANDBY:
|
|
4954
5528
|
return "is-standby";
|
|
4955
5529
|
// Green border
|
|
4956
5530
|
case DeviceStatusType.WARNING:
|
|
5531
|
+
return "is-warning";
|
|
5532
|
+
// Yellow border
|
|
4957
5533
|
case DeviceStatusType.MAINTENANCE:
|
|
4958
|
-
return "is-
|
|
5534
|
+
return "is-maintenance";
|
|
4959
5535
|
// Yellow border
|
|
4960
5536
|
case DeviceStatusType.FAILURE:
|
|
4961
|
-
case DeviceStatusType.POWER_OFF:
|
|
4962
5537
|
return "is-failure";
|
|
4963
|
-
// Red border
|
|
5538
|
+
// Dark Red border
|
|
5539
|
+
case DeviceStatusType.POWER_OFF:
|
|
5540
|
+
return "is-power-off";
|
|
5541
|
+
// Light Red border
|
|
5542
|
+
case DeviceStatusType.OFFLINE:
|
|
5543
|
+
return "is-offline";
|
|
5544
|
+
// Dark Gray border
|
|
4964
5545
|
case DeviceStatusType.NO_INFO:
|
|
5546
|
+
return "is-no-info";
|
|
5547
|
+
// Dark Orange border
|
|
4965
5548
|
case DeviceStatusType.NOT_INSTALLED:
|
|
4966
|
-
return "is-
|
|
4967
|
-
//
|
|
5549
|
+
return "is-not-installed";
|
|
5550
|
+
// Purple border
|
|
4968
5551
|
default:
|
|
4969
5552
|
return "";
|
|
4970
5553
|
}
|
|
@@ -4978,17 +5561,25 @@ function getStatusDotClass(deviceStatus) {
|
|
|
4978
5561
|
return "dot--standby";
|
|
4979
5562
|
case "hot":
|
|
4980
5563
|
return "dot--alert";
|
|
4981
|
-
// --- Status Existentes ---
|
|
5564
|
+
// --- Status Existentes (aligned with getCardStateClass) ---
|
|
4982
5565
|
case DeviceStatusType.POWER_ON:
|
|
4983
|
-
return "dot--
|
|
5566
|
+
return "dot--power-on";
|
|
4984
5567
|
case DeviceStatusType.STANDBY:
|
|
4985
5568
|
return "dot--standby";
|
|
4986
5569
|
case DeviceStatusType.WARNING:
|
|
5570
|
+
return "dot--warning";
|
|
4987
5571
|
case DeviceStatusType.MAINTENANCE:
|
|
4988
|
-
return "dot--
|
|
5572
|
+
return "dot--maintenance";
|
|
4989
5573
|
case DeviceStatusType.FAILURE:
|
|
4990
|
-
case DeviceStatusType.POWER_OFF:
|
|
4991
5574
|
return "dot--failure";
|
|
5575
|
+
case DeviceStatusType.POWER_OFF:
|
|
5576
|
+
return "dot--power-off";
|
|
5577
|
+
case DeviceStatusType.OFFLINE:
|
|
5578
|
+
return "dot--offline";
|
|
5579
|
+
case DeviceStatusType.NO_INFO:
|
|
5580
|
+
return "dot--no-info";
|
|
5581
|
+
case DeviceStatusType.NOT_INSTALLED:
|
|
5582
|
+
return "dot--not-installed";
|
|
4992
5583
|
default:
|
|
4993
5584
|
return "dot--offline";
|
|
4994
5585
|
}
|
|
@@ -5012,7 +5603,13 @@ function buildDOM(state) {
|
|
|
5012
5603
|
titleSection.className = "myio-ho-card__title";
|
|
5013
5604
|
const nameEl = document.createElement("div");
|
|
5014
5605
|
nameEl.className = "myio-ho-card__name";
|
|
5015
|
-
|
|
5606
|
+
const fullName = entityObject.labelOrName || "Unknown Device";
|
|
5607
|
+
if (fullName.length > LABEL_CHAR_LIMIT) {
|
|
5608
|
+
nameEl.textContent = fullName.slice(0, LABEL_CHAR_LIMIT) + "\u2026";
|
|
5609
|
+
nameEl.title = fullName;
|
|
5610
|
+
} else {
|
|
5611
|
+
nameEl.textContent = fullName;
|
|
5612
|
+
}
|
|
5016
5613
|
titleSection.appendChild(nameEl);
|
|
5017
5614
|
if (entityObject.deviceIdentifier) {
|
|
5018
5615
|
const codeEl = document.createElement("div");
|
|
@@ -5141,29 +5738,207 @@ function buildDOM(state) {
|
|
|
5141
5738
|
root.appendChild(footer);
|
|
5142
5739
|
return root;
|
|
5143
5740
|
}
|
|
5144
|
-
function
|
|
5741
|
+
function buildDebugTooltipInfo(entityObject, statusInfo, stateClass, statusDecisionSource, delayTimeConnectionInMins) {
|
|
5742
|
+
const formatTimestamp = (ts) => {
|
|
5743
|
+
if (!ts) return "N/A";
|
|
5744
|
+
const d = new Date(ts);
|
|
5745
|
+
return d.toLocaleString("pt-BR", {
|
|
5746
|
+
day: "2-digit",
|
|
5747
|
+
month: "2-digit",
|
|
5748
|
+
year: "numeric",
|
|
5749
|
+
hour: "2-digit",
|
|
5750
|
+
minute: "2-digit",
|
|
5751
|
+
second: "2-digit"
|
|
5752
|
+
});
|
|
5753
|
+
};
|
|
5754
|
+
return {
|
|
5755
|
+
// Entity identification
|
|
5756
|
+
entityId: entityObject.entityId || "N/A",
|
|
5757
|
+
name: entityObject.name || entityObject.nameEl || "N/A",
|
|
5758
|
+
domain: entityObject.domain || "energy",
|
|
5759
|
+
// Status decision chain
|
|
5760
|
+
originalDeviceStatus: entityObject._originalDeviceStatus || entityObject.deviceStatus,
|
|
5761
|
+
finalDeviceStatus: entityObject.deviceStatus,
|
|
5762
|
+
connectionStatus: entityObject.connectionStatus || "N/A",
|
|
5763
|
+
statusDecisionSource,
|
|
5764
|
+
// Visual output
|
|
5765
|
+
stateClass,
|
|
5766
|
+
chipClass: statusInfo.chipClass,
|
|
5767
|
+
chipLabel: statusInfo.label,
|
|
5768
|
+
// Connection timestamps
|
|
5769
|
+
lastConnectTime: formatTimestamp(entityObject.lastConnectTime),
|
|
5770
|
+
lastDisconnectTime: formatTimestamp(entityObject.lastDisconnectTime),
|
|
5771
|
+
delayTimeConnectionInMins,
|
|
5772
|
+
// Raw values
|
|
5773
|
+
val: entityObject.val,
|
|
5774
|
+
consumptionTargetValue: entityObject.consumptionTargetValue,
|
|
5775
|
+
deviceType: entityObject.deviceType || "N/A"
|
|
5776
|
+
};
|
|
5777
|
+
}
|
|
5778
|
+
function attachDebugTooltip(element, debugInfo) {
|
|
5779
|
+
const existingTooltip = element.querySelector(".debug-tooltip-container");
|
|
5780
|
+
if (existingTooltip) {
|
|
5781
|
+
existingTooltip.remove();
|
|
5782
|
+
}
|
|
5783
|
+
const tooltipContainer = document.createElement("div");
|
|
5784
|
+
tooltipContainer.className = "debug-tooltip-container";
|
|
5785
|
+
const tooltip = document.createElement("div");
|
|
5786
|
+
tooltip.className = "debug-tooltip";
|
|
5787
|
+
tooltip.innerHTML = `
|
|
5788
|
+
<div class="debug-tooltip__header">
|
|
5789
|
+
<span class="debug-tooltip__icon">\u{1F50D}</span>
|
|
5790
|
+
<span class="debug-tooltip__title">Debug Info</span>
|
|
5791
|
+
</div>
|
|
5792
|
+
<div class="debug-tooltip__content">
|
|
5793
|
+
<div class="debug-tooltip__section">
|
|
5794
|
+
<div class="debug-tooltip__section-title">\u{1F4CB} Identifica\xE7\xE3o</div>
|
|
5795
|
+
<div class="debug-tooltip__row">
|
|
5796
|
+
<span class="debug-tooltip__label">Entity ID:</span>
|
|
5797
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.entityId}</span>
|
|
5798
|
+
</div>
|
|
5799
|
+
<div class="debug-tooltip__row">
|
|
5800
|
+
<span class="debug-tooltip__label">Nome:</span>
|
|
5801
|
+
<span class="debug-tooltip__value">${debugInfo.name}</span>
|
|
5802
|
+
</div>
|
|
5803
|
+
<div class="debug-tooltip__row">
|
|
5804
|
+
<span class="debug-tooltip__label">Dom\xEDnio:</span>
|
|
5805
|
+
<span class="debug-tooltip__value debug-tooltip__badge debug-tooltip__badge--${debugInfo.domain}">${debugInfo.domain}</span>
|
|
5806
|
+
</div>
|
|
5807
|
+
</div>
|
|
5808
|
+
|
|
5809
|
+
<div class="debug-tooltip__section">
|
|
5810
|
+
<div class="debug-tooltip__section-title">\u26A1 Decis\xE3o de Status</div>
|
|
5811
|
+
<div class="debug-tooltip__row">
|
|
5812
|
+
<span class="debug-tooltip__label">connectionStatus:</span>
|
|
5813
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.connectionStatus}</span>
|
|
5814
|
+
</div>
|
|
5815
|
+
<div class="debug-tooltip__row">
|
|
5816
|
+
<span class="debug-tooltip__label">deviceStatus (final):</span>
|
|
5817
|
+
<span class="debug-tooltip__value debug-tooltip__badge">${debugInfo.finalDeviceStatus}</span>
|
|
5818
|
+
</div>
|
|
5819
|
+
<div class="debug-tooltip__row debug-tooltip__row--full">
|
|
5820
|
+
<span class="debug-tooltip__label">Fonte da decis\xE3o:</span>
|
|
5821
|
+
<span class="debug-tooltip__value debug-tooltip__value--highlight">${debugInfo.statusDecisionSource}</span>
|
|
5822
|
+
</div>
|
|
5823
|
+
</div>
|
|
5824
|
+
|
|
5825
|
+
<div class="debug-tooltip__section">
|
|
5826
|
+
<div class="debug-tooltip__section-title">\u{1F3A8} Output Visual</div>
|
|
5827
|
+
<div class="debug-tooltip__row">
|
|
5828
|
+
<span class="debug-tooltip__label">stateClass:</span>
|
|
5829
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.stateClass}</span>
|
|
5830
|
+
</div>
|
|
5831
|
+
<div class="debug-tooltip__row">
|
|
5832
|
+
<span class="debug-tooltip__label">chipClass:</span>
|
|
5833
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.chipClass}</span>
|
|
5834
|
+
</div>
|
|
5835
|
+
<div class="debug-tooltip__row">
|
|
5836
|
+
<span class="debug-tooltip__label">chipLabel:</span>
|
|
5837
|
+
<span class="debug-tooltip__value">${debugInfo.chipLabel}</span>
|
|
5838
|
+
</div>
|
|
5839
|
+
</div>
|
|
5840
|
+
|
|
5841
|
+
<div class="debug-tooltip__section">
|
|
5842
|
+
<div class="debug-tooltip__section-title">\u{1F550} Timestamps de Conex\xE3o</div>
|
|
5843
|
+
<div class="debug-tooltip__row">
|
|
5844
|
+
<span class="debug-tooltip__label">lastConnectTime:</span>
|
|
5845
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.lastConnectTime}</span>
|
|
5846
|
+
</div>
|
|
5847
|
+
<div class="debug-tooltip__row">
|
|
5848
|
+
<span class="debug-tooltip__label">lastDisconnectTime:</span>
|
|
5849
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.lastDisconnectTime}</span>
|
|
5850
|
+
</div>
|
|
5851
|
+
<div class="debug-tooltip__row">
|
|
5852
|
+
<span class="debug-tooltip__label">delayTime:</span>
|
|
5853
|
+
<span class="debug-tooltip__value">${debugInfo.delayTimeConnectionInMins} mins</span>
|
|
5854
|
+
</div>
|
|
5855
|
+
</div>
|
|
5856
|
+
|
|
5857
|
+
<div class="debug-tooltip__section">
|
|
5858
|
+
<div class="debug-tooltip__section-title">\u{1F4CA} Valores</div>
|
|
5859
|
+
<div class="debug-tooltip__row">
|
|
5860
|
+
<span class="debug-tooltip__label">val (consumo):</span>
|
|
5861
|
+
<span class="debug-tooltip__value">${debugInfo.val ?? "N/A"}</span>
|
|
5862
|
+
</div>
|
|
5863
|
+
<div class="debug-tooltip__row">
|
|
5864
|
+
<span class="debug-tooltip__label">target (meta):</span>
|
|
5865
|
+
<span class="debug-tooltip__value">${debugInfo.consumptionTargetValue ?? "N/A"}</span>
|
|
5866
|
+
</div>
|
|
5867
|
+
<div class="debug-tooltip__row">
|
|
5868
|
+
<span class="debug-tooltip__label">deviceType:</span>
|
|
5869
|
+
<span class="debug-tooltip__value debug-tooltip__value--mono">${debugInfo.deviceType}</span>
|
|
5870
|
+
</div>
|
|
5871
|
+
</div>
|
|
5872
|
+
</div>
|
|
5873
|
+
`;
|
|
5874
|
+
tooltipContainer.appendChild(tooltip);
|
|
5875
|
+
element.style.position = "relative";
|
|
5876
|
+
element.style.cursor = "help";
|
|
5877
|
+
element.appendChild(tooltipContainer);
|
|
5878
|
+
element.classList.add("has-debug-tooltip");
|
|
5879
|
+
}
|
|
5880
|
+
function verifyOfflineStatus(entityObject, delayTimeInMins = 15, LogHelper2) {
|
|
5145
5881
|
const lastConnectionTime = new Date(entityObject.lastConnectTime || 0);
|
|
5146
5882
|
const lastDisconnectTime = new Date(entityObject.lastDisconnectTime || 0);
|
|
5147
5883
|
const now = /* @__PURE__ */ new Date();
|
|
5148
5884
|
const delayTimeInMs = delayTimeInMins * 60 * 1e3;
|
|
5149
5885
|
const timeSinceConnection = now.getTime() - lastConnectionTime.getTime();
|
|
5886
|
+
let isOffline = false;
|
|
5150
5887
|
if (lastDisconnectTime.getTime() > lastConnectionTime.getTime()) {
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5888
|
+
isOffline = true;
|
|
5889
|
+
LogHelper2.log(
|
|
5890
|
+
"[CardHeadOffice][ConnectionStatus Verify] Device is OFFLINE because lastDisconnectTime is more recent than lastConnectTime",
|
|
5891
|
+
entityObject.nameEl
|
|
5892
|
+
);
|
|
5893
|
+
} else if (timeSinceConnection > delayTimeInMs) {
|
|
5894
|
+
isOffline = true;
|
|
5895
|
+
LogHelper2.log(
|
|
5896
|
+
"[CardHeadOffice][ConnectionStatus Verify] Device is OFFLINE because lastConnectTime is older than configured delayTimeConnectionInMins:",
|
|
5897
|
+
delayTimeInMins,
|
|
5898
|
+
"for device",
|
|
5899
|
+
entityObject.nameEl
|
|
5900
|
+
);
|
|
5901
|
+
} else {
|
|
5902
|
+
isOffline = false;
|
|
5903
|
+
LogHelper2.log(
|
|
5904
|
+
"[CardHeadOffice][ConnectionStatus Verify] Device is ONLINE because lastConnectTime is within configured delayTimeConnectionInMins:",
|
|
5905
|
+
delayTimeInMins,
|
|
5906
|
+
"for device",
|
|
5907
|
+
entityObject.nameEl
|
|
5908
|
+
);
|
|
5155
5909
|
}
|
|
5156
|
-
return
|
|
5910
|
+
return isOffline;
|
|
5157
5911
|
}
|
|
5158
5912
|
function paint(root, state) {
|
|
5159
|
-
const { entityObject, i18n, delayTimeConnectionInMins, isSelected } = state;
|
|
5913
|
+
const { entityObject, i18n, delayTimeConnectionInMins, isSelected, LogHelper: LogHelper2, activeTooltipDebug } = state;
|
|
5914
|
+
let statusDecisionSource = "unknown";
|
|
5160
5915
|
if (entityObject.connectionStatus) {
|
|
5161
5916
|
if (entityObject.connectionStatus === "offline") {
|
|
5162
|
-
|
|
5917
|
+
LogHelper2.log(
|
|
5918
|
+
"[CardHeadOffice][ConnectionStatus Verify 01] Setting deviceStatus to OFFLINE based on connectionStatus"
|
|
5919
|
+
);
|
|
5920
|
+
entityObject.deviceStatus = DeviceStatusType.OFFLINE;
|
|
5921
|
+
statusDecisionSource = 'connectionStatus === "offline"';
|
|
5922
|
+
} else {
|
|
5923
|
+
LogHelper2.log(
|
|
5924
|
+
"[CardHeadOffice] Device is ONLINE or WAITING based on connectionStatus for device",
|
|
5925
|
+
entityObject.nameEl
|
|
5926
|
+
);
|
|
5927
|
+
statusDecisionSource = `connectionStatus === "${entityObject.connectionStatus}" (kept original deviceStatus)`;
|
|
5163
5928
|
}
|
|
5164
5929
|
} else {
|
|
5165
|
-
if (verifyOfflineStatus(entityObject, delayTimeConnectionInMins) === false) {
|
|
5166
|
-
|
|
5930
|
+
if (verifyOfflineStatus(entityObject, delayTimeConnectionInMins, LogHelper2) === false) {
|
|
5931
|
+
LogHelper2.log(
|
|
5932
|
+
"[CardHeadOffice][ConnectionStatus Verify 02] Setting deviceStatus to OFFLINE based on timestamp verification by verifyOfflineStatus METHOD with delayTimeConnectionInMins:",
|
|
5933
|
+
delayTimeConnectionInMins
|
|
5934
|
+
);
|
|
5935
|
+
entityObject.deviceStatus = DeviceStatusType.OFFLINE;
|
|
5936
|
+
statusDecisionSource = `verifyOfflineStatus() returned false (delay: ${delayTimeConnectionInMins} mins)`;
|
|
5937
|
+
} else {
|
|
5938
|
+
LogHelper2.log(
|
|
5939
|
+
`[CardHeadOffice][ConnectionStatus Verify 03] Device is ONLINE with deviceStatus = ${entityObject.deviceStatus} based on timestamp verification for device ${entityObject.nameEl}`
|
|
5940
|
+
);
|
|
5941
|
+
statusDecisionSource = `verifyOfflineStatus() returned true (delay: ${delayTimeConnectionInMins} mins)`;
|
|
5167
5942
|
}
|
|
5168
5943
|
}
|
|
5169
5944
|
const stateClass = getCardStateClass(entityObject.deviceStatus);
|
|
@@ -5172,6 +5947,10 @@ function paint(root, state) {
|
|
|
5172
5947
|
const chip = root.querySelector(".chip");
|
|
5173
5948
|
chip.className = `chip ${statusInfo.chipClass}`;
|
|
5174
5949
|
chip.innerHTML = statusInfo.label;
|
|
5950
|
+
if (activeTooltipDebug) {
|
|
5951
|
+
const debugInfo = buildDebugTooltipInfo(entityObject, statusInfo, stateClass, statusDecisionSource, delayTimeConnectionInMins);
|
|
5952
|
+
attachDebugTooltip(chip, debugInfo);
|
|
5953
|
+
}
|
|
5175
5954
|
const primaryValue = formatValueByDomain(entityObject.val, entityObject.domain);
|
|
5176
5955
|
const numSpan = root.querySelector(".myio-ho-card__value .num");
|
|
5177
5956
|
const unitSpan = root.querySelector(".myio-ho-card__value .unit");
|
|
@@ -5384,6 +6163,7 @@ function renderCardComponentHeadOffice(containerEl, params) {
|
|
|
5384
6163
|
}
|
|
5385
6164
|
|
|
5386
6165
|
// src/thingsboard/main-dashboard-shopping/v-5.2.0/card/template-card-v5.js
|
|
6166
|
+
var LABEL_CHAR_LIMIT2 = 18;
|
|
5387
6167
|
function renderCardComponentV5({
|
|
5388
6168
|
entityObject,
|
|
5389
6169
|
handleActionDashboard,
|
|
@@ -5900,7 +6680,7 @@ ${rangeText}`;
|
|
|
5900
6680
|
|
|
5901
6681
|
<div class="device-title-row" style="flex-direction: column; min-height: 38px; text-align: center; width: 100%;">
|
|
5902
6682
|
<span class="device-title" title="${cardEntity.name}">
|
|
5903
|
-
${cardEntity.name.length >
|
|
6683
|
+
${cardEntity.name.length > LABEL_CHAR_LIMIT2 ? cardEntity.name.slice(0, LABEL_CHAR_LIMIT2) + "\u2026" : cardEntity.name}
|
|
5904
6684
|
</span>
|
|
5905
6685
|
${deviceIdentifier ? `
|
|
5906
6686
|
<span class="device-subtitle" title="${deviceIdentifier}">
|
|
@@ -20227,220 +21007,6 @@ function openGoalsPanel(params) {
|
|
|
20227
21007
|
}
|
|
20228
21008
|
}
|
|
20229
21009
|
|
|
20230
|
-
// src/components/temperature/utils.ts
|
|
20231
|
-
var DAY_PERIODS = [
|
|
20232
|
-
{ id: "madrugada", label: "Madrugada (00h-06h)", startHour: 0, endHour: 6 },
|
|
20233
|
-
{ id: "manha", label: "Manh\xE3 (06h-12h)", startHour: 6, endHour: 12 },
|
|
20234
|
-
{ id: "tarde", label: "Tarde (12h-18h)", startHour: 12, endHour: 18 },
|
|
20235
|
-
{ id: "noite", label: "Noite (18h-24h)", startHour: 18, endHour: 24 }
|
|
20236
|
-
];
|
|
20237
|
-
var DEFAULT_CLAMP_RANGE = { min: 15, max: 40 };
|
|
20238
|
-
function getTodaySoFar() {
|
|
20239
|
-
const now = /* @__PURE__ */ new Date();
|
|
20240
|
-
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0);
|
|
20241
|
-
return {
|
|
20242
|
-
startTs: startOfDay.getTime(),
|
|
20243
|
-
endTs: now.getTime()
|
|
20244
|
-
};
|
|
20245
|
-
}
|
|
20246
|
-
var CHART_COLORS = [
|
|
20247
|
-
"#1976d2",
|
|
20248
|
-
// Blue
|
|
20249
|
-
"#FF6B6B",
|
|
20250
|
-
// Red
|
|
20251
|
-
"#4CAF50",
|
|
20252
|
-
// Green
|
|
20253
|
-
"#FF9800",
|
|
20254
|
-
// Orange
|
|
20255
|
-
"#9C27B0",
|
|
20256
|
-
// Purple
|
|
20257
|
-
"#00BCD4",
|
|
20258
|
-
// Cyan
|
|
20259
|
-
"#E91E63",
|
|
20260
|
-
// Pink
|
|
20261
|
-
"#795548"
|
|
20262
|
-
// Brown
|
|
20263
|
-
];
|
|
20264
|
-
async function fetchTemperatureData(token, deviceId, startTs, endTs) {
|
|
20265
|
-
const url = `/api/plugins/telemetry/DEVICE/${deviceId}/values/timeseries?keys=temperature&startTs=${encodeURIComponent(startTs)}&endTs=${encodeURIComponent(endTs)}&limit=50000&agg=NONE`;
|
|
20266
|
-
const response = await fetch(url, {
|
|
20267
|
-
headers: {
|
|
20268
|
-
"X-Authorization": `Bearer ${token}`,
|
|
20269
|
-
"Content-Type": "application/json"
|
|
20270
|
-
}
|
|
20271
|
-
});
|
|
20272
|
-
if (!response.ok) {
|
|
20273
|
-
throw new Error(`Failed to fetch temperature data: ${response.status}`);
|
|
20274
|
-
}
|
|
20275
|
-
const data = await response.json();
|
|
20276
|
-
return data?.temperature || [];
|
|
20277
|
-
}
|
|
20278
|
-
function clampTemperature(value, range = DEFAULT_CLAMP_RANGE) {
|
|
20279
|
-
const num = Number(value || 0);
|
|
20280
|
-
if (num < range.min) return range.min;
|
|
20281
|
-
if (num > range.max) return range.max;
|
|
20282
|
-
return num;
|
|
20283
|
-
}
|
|
20284
|
-
function calculateStats(data, clampRange = DEFAULT_CLAMP_RANGE) {
|
|
20285
|
-
if (data.length === 0) {
|
|
20286
|
-
return { avg: 0, min: 0, max: 0, count: 0 };
|
|
20287
|
-
}
|
|
20288
|
-
const values = data.map((item) => clampTemperature(item.value, clampRange));
|
|
20289
|
-
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
20290
|
-
return {
|
|
20291
|
-
avg: sum / values.length,
|
|
20292
|
-
min: Math.min(...values),
|
|
20293
|
-
max: Math.max(...values),
|
|
20294
|
-
count: values.length
|
|
20295
|
-
};
|
|
20296
|
-
}
|
|
20297
|
-
function interpolateTemperature(data, options) {
|
|
20298
|
-
const { intervalMinutes, startTs, endTs, clampRange = DEFAULT_CLAMP_RANGE } = options;
|
|
20299
|
-
const intervalMs = intervalMinutes * 60 * 1e3;
|
|
20300
|
-
if (data.length === 0) {
|
|
20301
|
-
return [];
|
|
20302
|
-
}
|
|
20303
|
-
const sortedData = [...data].sort((a, b) => a.ts - b.ts);
|
|
20304
|
-
const result = [];
|
|
20305
|
-
let lastKnownValue = clampTemperature(sortedData[0].value, clampRange);
|
|
20306
|
-
let dataIndex = 0;
|
|
20307
|
-
for (let ts = startTs; ts <= endTs; ts += intervalMs) {
|
|
20308
|
-
while (dataIndex < sortedData.length - 1 && sortedData[dataIndex + 1].ts <= ts) {
|
|
20309
|
-
dataIndex++;
|
|
20310
|
-
}
|
|
20311
|
-
const currentData = sortedData[dataIndex];
|
|
20312
|
-
if (currentData && Math.abs(currentData.ts - ts) < intervalMs) {
|
|
20313
|
-
lastKnownValue = clampTemperature(currentData.value, clampRange);
|
|
20314
|
-
}
|
|
20315
|
-
result.push({
|
|
20316
|
-
ts,
|
|
20317
|
-
value: lastKnownValue
|
|
20318
|
-
});
|
|
20319
|
-
}
|
|
20320
|
-
return result;
|
|
20321
|
-
}
|
|
20322
|
-
function aggregateByDay(data, clampRange = DEFAULT_CLAMP_RANGE) {
|
|
20323
|
-
if (data.length === 0) {
|
|
20324
|
-
return [];
|
|
20325
|
-
}
|
|
20326
|
-
const dayMap = /* @__PURE__ */ new Map();
|
|
20327
|
-
data.forEach((item) => {
|
|
20328
|
-
const date = new Date(item.ts);
|
|
20329
|
-
const dateKey = date.toISOString().split("T")[0];
|
|
20330
|
-
if (!dayMap.has(dateKey)) {
|
|
20331
|
-
dayMap.set(dateKey, []);
|
|
20332
|
-
}
|
|
20333
|
-
dayMap.get(dateKey).push(item);
|
|
20334
|
-
});
|
|
20335
|
-
const result = [];
|
|
20336
|
-
dayMap.forEach((dayData, dateKey) => {
|
|
20337
|
-
const values = dayData.map((item) => clampTemperature(item.value, clampRange));
|
|
20338
|
-
const sum = values.reduce((acc, v) => acc + v, 0);
|
|
20339
|
-
result.push({
|
|
20340
|
-
date: dateKey,
|
|
20341
|
-
dateTs: new Date(dateKey).getTime(),
|
|
20342
|
-
avg: sum / values.length,
|
|
20343
|
-
min: Math.min(...values),
|
|
20344
|
-
max: Math.max(...values),
|
|
20345
|
-
count: values.length
|
|
20346
|
-
});
|
|
20347
|
-
});
|
|
20348
|
-
return result.sort((a, b) => a.dateTs - b.dateTs);
|
|
20349
|
-
}
|
|
20350
|
-
function filterByDayPeriods(data, selectedPeriods) {
|
|
20351
|
-
if (selectedPeriods.length === 0 || selectedPeriods.length === DAY_PERIODS.length) {
|
|
20352
|
-
return data;
|
|
20353
|
-
}
|
|
20354
|
-
return data.filter((item) => {
|
|
20355
|
-
const date = new Date(item.ts);
|
|
20356
|
-
const hour = date.getHours();
|
|
20357
|
-
return selectedPeriods.some((periodId) => {
|
|
20358
|
-
const period = DAY_PERIODS.find((p) => p.id === periodId);
|
|
20359
|
-
if (!period) return false;
|
|
20360
|
-
return hour >= period.startHour && hour < period.endHour;
|
|
20361
|
-
});
|
|
20362
|
-
});
|
|
20363
|
-
}
|
|
20364
|
-
function getSelectedPeriodsLabel(selectedPeriods) {
|
|
20365
|
-
if (selectedPeriods.length === 0 || selectedPeriods.length === DAY_PERIODS.length) {
|
|
20366
|
-
return "Todos os per\xEDodos";
|
|
20367
|
-
}
|
|
20368
|
-
if (selectedPeriods.length === 1) {
|
|
20369
|
-
const period = DAY_PERIODS.find((p) => p.id === selectedPeriods[0]);
|
|
20370
|
-
return period?.label || "";
|
|
20371
|
-
}
|
|
20372
|
-
return `${selectedPeriods.length} per\xEDodos selecionados`;
|
|
20373
|
-
}
|
|
20374
|
-
function formatTemperature2(value, decimals = 1) {
|
|
20375
|
-
return `${value.toFixed(decimals)}\xB0C`;
|
|
20376
|
-
}
|
|
20377
|
-
function exportTemperatureCSV(data, deviceLabel, stats, startDate, endDate) {
|
|
20378
|
-
if (data.length === 0) {
|
|
20379
|
-
console.warn("No data to export");
|
|
20380
|
-
return;
|
|
20381
|
-
}
|
|
20382
|
-
const BOM = "\uFEFF";
|
|
20383
|
-
let csvContent = BOM;
|
|
20384
|
-
csvContent += `Relat\xF3rio de Temperatura - ${deviceLabel}
|
|
20385
|
-
`;
|
|
20386
|
-
csvContent += `Per\xEDodo: ${startDate} at\xE9 ${endDate}
|
|
20387
|
-
`;
|
|
20388
|
-
csvContent += `M\xE9dia: ${formatTemperature2(stats.avg)}
|
|
20389
|
-
`;
|
|
20390
|
-
csvContent += `M\xEDnima: ${formatTemperature2(stats.min)}
|
|
20391
|
-
`;
|
|
20392
|
-
csvContent += `M\xE1xima: ${formatTemperature2(stats.max)}
|
|
20393
|
-
`;
|
|
20394
|
-
csvContent += `Total de leituras: ${stats.count}
|
|
20395
|
-
`;
|
|
20396
|
-
csvContent += "\n";
|
|
20397
|
-
csvContent += "Data/Hora,Temperatura (\xB0C)\n";
|
|
20398
|
-
data.forEach((item) => {
|
|
20399
|
-
const date = new Date(item.ts).toLocaleString("pt-BR");
|
|
20400
|
-
const temp = Number(item.value).toFixed(2);
|
|
20401
|
-
csvContent += `"${date}",${temp}
|
|
20402
|
-
`;
|
|
20403
|
-
});
|
|
20404
|
-
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
20405
|
-
const url = URL.createObjectURL(blob);
|
|
20406
|
-
const link = document.createElement("a");
|
|
20407
|
-
link.href = url;
|
|
20408
|
-
link.download = `temperatura_${deviceLabel.replace(/\s+/g, "_")}_${startDate}_${endDate}.csv`;
|
|
20409
|
-
document.body.appendChild(link);
|
|
20410
|
-
link.click();
|
|
20411
|
-
document.body.removeChild(link);
|
|
20412
|
-
URL.revokeObjectURL(url);
|
|
20413
|
-
}
|
|
20414
|
-
var DARK_THEME = {
|
|
20415
|
-
background: "rgba(0, 0, 0, 0.85)",
|
|
20416
|
-
surface: "#1a1f28",
|
|
20417
|
-
text: "#ffffff",
|
|
20418
|
-
textMuted: "rgba(255, 255, 255, 0.7)",
|
|
20419
|
-
border: "rgba(255, 255, 255, 0.1)",
|
|
20420
|
-
primary: "#1976d2",
|
|
20421
|
-
success: "#4CAF50",
|
|
20422
|
-
warning: "#FF9800",
|
|
20423
|
-
danger: "#f44336",
|
|
20424
|
-
chartLine: "#1976d2",
|
|
20425
|
-
chartGrid: "rgba(255, 255, 255, 0.1)"
|
|
20426
|
-
};
|
|
20427
|
-
var LIGHT_THEME = {
|
|
20428
|
-
background: "rgba(0, 0, 0, 0.6)",
|
|
20429
|
-
surface: "#ffffff",
|
|
20430
|
-
text: "#333333",
|
|
20431
|
-
textMuted: "#666666",
|
|
20432
|
-
border: "#e0e0e0",
|
|
20433
|
-
primary: "#1976d2",
|
|
20434
|
-
success: "#4CAF50",
|
|
20435
|
-
warning: "#FF9800",
|
|
20436
|
-
danger: "#f44336",
|
|
20437
|
-
chartLine: "#1976d2",
|
|
20438
|
-
chartGrid: "#e0e0e0"
|
|
20439
|
-
};
|
|
20440
|
-
function getThemeColors(theme) {
|
|
20441
|
-
return theme === "dark" ? DARK_THEME : LIGHT_THEME;
|
|
20442
|
-
}
|
|
20443
|
-
|
|
20444
21010
|
// src/components/temperature/TemperatureModal.ts
|
|
20445
21011
|
async function openTemperatureModal(params) {
|
|
20446
21012
|
const modalId = `myio-temp-modal-${Date.now()}`;
|
|
@@ -20680,7 +21246,7 @@ function renderModal(container, state, modalId, error) {
|
|
|
20680
21246
|
">
|
|
20681
21247
|
<span style="color: ${colors.textMuted}; font-size: 12px; font-weight: 500;">Temperatura Atual</span>
|
|
20682
21248
|
<div style="font-weight: 700; font-size: 24px; color: ${statusColor}; margin-top: 4px;">
|
|
20683
|
-
${state.currentTemperature !== null ?
|
|
21249
|
+
${state.currentTemperature !== null ? formatTemperature(state.currentTemperature) : "N/A"}
|
|
20684
21250
|
</div>
|
|
20685
21251
|
<div style="font-size: 11px; color: ${statusColor}; margin-top: 2px;">${statusText}</div>
|
|
20686
21252
|
</div>
|
|
@@ -20691,7 +21257,7 @@ function renderModal(container, state, modalId, error) {
|
|
|
20691
21257
|
">
|
|
20692
21258
|
<span style="color: ${colors.textMuted}; font-size: 12px; font-weight: 500;">M\xE9dia do Per\xEDodo</span>
|
|
20693
21259
|
<div id="${modalId}-avg" style="font-weight: 600; font-size: 20px; color: ${colors.text}; margin-top: 4px;">
|
|
20694
|
-
${state.stats.count > 0 ?
|
|
21260
|
+
${state.stats.count > 0 ? formatTemperature(state.stats.avg) : "N/A"}
|
|
20695
21261
|
</div>
|
|
20696
21262
|
<div style="font-size: 11px; color: ${colors.textMuted}; margin-top: 2px;">${startDateStr} - ${endDateStr}</div>
|
|
20697
21263
|
</div>
|
|
@@ -20702,7 +21268,7 @@ function renderModal(container, state, modalId, error) {
|
|
|
20702
21268
|
">
|
|
20703
21269
|
<span style="color: ${colors.textMuted}; font-size: 12px; font-weight: 500;">Min / Max</span>
|
|
20704
21270
|
<div id="${modalId}-minmax" style="font-weight: 600; font-size: 20px; color: ${colors.text}; margin-top: 4px;">
|
|
20705
|
-
${state.stats.count > 0 ? `${
|
|
21271
|
+
${state.stats.count > 0 ? `${formatTemperature(state.stats.min)} / ${formatTemperature(state.stats.max)}` : "N/A"}
|
|
20706
21272
|
</div>
|
|
20707
21273
|
<div style="font-size: 11px; color: ${colors.textMuted}; margin-top: 2px;">${state.stats.count} leituras</div>
|
|
20708
21274
|
</div>
|
|
@@ -21018,7 +21584,7 @@ function setupChartTooltip(canvas, container, chartData, state, colors) {
|
|
|
21018
21584
|
}
|
|
21019
21585
|
tooltip.innerHTML = `
|
|
21020
21586
|
<div style="font-weight: 600; margin-bottom: 6px; color: ${colors.primary};">
|
|
21021
|
-
${
|
|
21587
|
+
${formatTemperature(point.y)}
|
|
21022
21588
|
</div>
|
|
21023
21589
|
<div style="font-size: 11px; color: ${colors.textMuted};">
|
|
21024
21590
|
\u{1F4C5} ${dateStr}
|
|
@@ -21281,7 +21847,7 @@ function renderModal2(container, state, modalId) {
|
|
|
21281
21847
|
<span style="width: 12px; height: 12px; border-radius: 50%; background: ${dd.color};"></span>
|
|
21282
21848
|
<span style="color: ${colors.text}; font-size: 13px;">${dd.device.label}</span>
|
|
21283
21849
|
<span style="color: ${colors.textMuted}; font-size: 11px; margin-left: auto;">
|
|
21284
|
-
${dd.stats.count > 0 ?
|
|
21850
|
+
${dd.stats.count > 0 ? formatTemperature(dd.stats.avg) : "N/A"}
|
|
21285
21851
|
</span>
|
|
21286
21852
|
</div>
|
|
21287
21853
|
`).join("");
|
|
@@ -21297,15 +21863,15 @@ function renderModal2(container, state, modalId) {
|
|
|
21297
21863
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 4px; font-size: 11px;">
|
|
21298
21864
|
<span style="color: ${colors.textMuted};">M\xE9dia:</span>
|
|
21299
21865
|
<span style="color: ${colors.text}; font-weight: 500;">
|
|
21300
|
-
${dd.stats.count > 0 ?
|
|
21866
|
+
${dd.stats.count > 0 ? formatTemperature(dd.stats.avg) : "N/A"}
|
|
21301
21867
|
</span>
|
|
21302
21868
|
<span style="color: ${colors.textMuted};">Min:</span>
|
|
21303
21869
|
<span style="color: ${colors.text};">
|
|
21304
|
-
${dd.stats.count > 0 ?
|
|
21870
|
+
${dd.stats.count > 0 ? formatTemperature(dd.stats.min) : "N/A"}
|
|
21305
21871
|
</span>
|
|
21306
21872
|
<span style="color: ${colors.textMuted};">Max:</span>
|
|
21307
21873
|
<span style="color: ${colors.text};">
|
|
21308
|
-
${dd.stats.count > 0 ?
|
|
21874
|
+
${dd.stats.count > 0 ? formatTemperature(dd.stats.max) : "N/A"}
|
|
21309
21875
|
</span>
|
|
21310
21876
|
<span style="color: ${colors.textMuted};">Leituras:</span>
|
|
21311
21877
|
<span style="color: ${colors.text};">${dd.stats.count}</span>
|
|
@@ -21841,7 +22407,7 @@ function setupComparisonChartTooltip(canvas, container, chartData, state, colors
|
|
|
21841
22407
|
<span style="font-weight: 600;">${point.deviceLabel}</span>
|
|
21842
22408
|
</div>
|
|
21843
22409
|
<div style="font-weight: 600; font-size: 16px; color: ${point.deviceColor}; margin-bottom: 4px;">
|
|
21844
|
-
${
|
|
22410
|
+
${formatTemperature(point.y)}
|
|
21845
22411
|
</div>
|
|
21846
22412
|
<div style="font-size: 11px; color: ${colors.textMuted};">
|
|
21847
22413
|
\u{1F4C5} ${dateStr}
|
|
@@ -26393,7 +26959,7 @@ export {
|
|
|
26393
26959
|
formatNumberReadable,
|
|
26394
26960
|
formatRelativeTime,
|
|
26395
26961
|
formatTankHeadFromCm,
|
|
26396
|
-
|
|
26962
|
+
formatTemperature,
|
|
26397
26963
|
formatWater,
|
|
26398
26964
|
formatWaterByGroup,
|
|
26399
26965
|
formatWaterVolumeM3,
|