myio-js-library 0.1.177 → 0.1.180
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 +960 -5
- package/dist/index.d.cts +2 -1
- package/dist/index.js +960 -5
- package/dist/myio-js-library.umd.js +953 -5
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
|
@@ -572,7 +572,7 @@
|
|
|
572
572
|
});
|
|
573
573
|
|
|
574
574
|
// src/format/energy.ts
|
|
575
|
-
function formatEnergy(value, unit) {
|
|
575
|
+
function formatEnergy(value, unit, decimals = 3) {
|
|
576
576
|
if (value === null || value === void 0 || isNaN(value)) {
|
|
577
577
|
return "-";
|
|
578
578
|
}
|
|
@@ -590,8 +590,8 @@
|
|
|
590
590
|
}
|
|
591
591
|
}
|
|
592
592
|
const formattedValue = adjustedValue.toLocaleString("pt-BR", {
|
|
593
|
-
minimumFractionDigits:
|
|
594
|
-
maximumFractionDigits:
|
|
593
|
+
minimumFractionDigits: decimals,
|
|
594
|
+
maximumFractionDigits: decimals
|
|
595
595
|
});
|
|
596
596
|
return `${formattedValue} ${adjustedUnit}`;
|
|
597
597
|
}
|
|
@@ -3983,6 +3983,14 @@
|
|
|
3983
3983
|
--myio-chip-not-installed-fg: #7c3aed;
|
|
3984
3984
|
--myio-border-not-installed: rgba(124, 58, 237, 0.5);
|
|
3985
3985
|
|
|
3986
|
+
/* Temperature range colors - solid backgrounds for better visibility */
|
|
3987
|
+
--myio-temp-cold-bg: #dbeafe; /* Blue 100 - below ideal range */
|
|
3988
|
+
--myio-temp-cold-border: rgba(59, 130, 246, 0.6);
|
|
3989
|
+
--myio-temp-ok-bg: #dcfce7; /* Green 100 - within ideal range */
|
|
3990
|
+
--myio-temp-ok-border: rgba(34, 197, 94, 0.6);
|
|
3991
|
+
--myio-temp-hot-bg: #fee2e2; /* Red 100 - above ideal range */
|
|
3992
|
+
--myio-temp-hot-border: rgba(239, 68, 68, 0.6);
|
|
3993
|
+
|
|
3986
3994
|
--myio-text-1: #0f172a;
|
|
3987
3995
|
--myio-text-2: #4b5563;
|
|
3988
3996
|
--myio-muted: #94a3b8;
|
|
@@ -4086,6 +4094,25 @@
|
|
|
4086
4094
|
box-shadow: 0 0 0 2px var(--myio-border-not-installed), var(--myio-card-shadow);
|
|
4087
4095
|
}
|
|
4088
4096
|
|
|
4097
|
+
/* Temperature range backgrounds (domain=temperature only) */
|
|
4098
|
+
.myio-ho-card.is-temp-cold {
|
|
4099
|
+
background: var(--myio-temp-cold-bg);
|
|
4100
|
+
border-color: var(--myio-temp-cold-border);
|
|
4101
|
+
box-shadow: 0 0 0 2px var(--myio-temp-cold-border), var(--myio-card-shadow);
|
|
4102
|
+
}
|
|
4103
|
+
|
|
4104
|
+
.myio-ho-card.is-temp-ok {
|
|
4105
|
+
background: var(--myio-temp-ok-bg);
|
|
4106
|
+
border-color: var(--myio-temp-ok-border);
|
|
4107
|
+
box-shadow: 0 0 0 2px var(--myio-temp-ok-border), var(--myio-card-shadow);
|
|
4108
|
+
}
|
|
4109
|
+
|
|
4110
|
+
.myio-ho-card.is-temp-hot {
|
|
4111
|
+
background: var(--myio-temp-hot-bg);
|
|
4112
|
+
border-color: var(--myio-temp-hot-border);
|
|
4113
|
+
box-shadow: 0 0 0 2px var(--myio-temp-hot-border), var(--myio-card-shadow);
|
|
4114
|
+
}
|
|
4115
|
+
|
|
4089
4116
|
/* Header section */
|
|
4090
4117
|
.myio-ho-card__header {
|
|
4091
4118
|
display: flex;
|
|
@@ -5009,6 +5036,504 @@
|
|
|
5009
5036
|
.debug-tooltip__content::-webkit-scrollbar-thumb:hover {
|
|
5010
5037
|
background: rgba(99, 102, 241, 0.6);
|
|
5011
5038
|
}
|
|
5039
|
+
|
|
5040
|
+
/* ============================================
|
|
5041
|
+
Temperature Range Tooltip (for domain=temperature)
|
|
5042
|
+
Shows temperature ruler with current position and deviation
|
|
5043
|
+
============================================ */
|
|
5044
|
+
.temp-range-tooltip {
|
|
5045
|
+
position: fixed;
|
|
5046
|
+
z-index: 99999;
|
|
5047
|
+
pointer-events: none;
|
|
5048
|
+
opacity: 0;
|
|
5049
|
+
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
5050
|
+
transform: translateY(5px);
|
|
5051
|
+
}
|
|
5052
|
+
|
|
5053
|
+
.temp-range-tooltip.visible {
|
|
5054
|
+
opacity: 1;
|
|
5055
|
+
pointer-events: auto;
|
|
5056
|
+
transform: translateY(0);
|
|
5057
|
+
}
|
|
5058
|
+
|
|
5059
|
+
.temp-range-tooltip__content {
|
|
5060
|
+
background: #ffffff;
|
|
5061
|
+
border: 1px solid #e2e8f0;
|
|
5062
|
+
border-radius: 12px;
|
|
5063
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15), 0 2px 10px rgba(0, 0, 0, 0.08);
|
|
5064
|
+
min-width: 280px;
|
|
5065
|
+
max-width: 320px;
|
|
5066
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
5067
|
+
font-size: 12px;
|
|
5068
|
+
color: #1e293b;
|
|
5069
|
+
overflow: hidden;
|
|
5070
|
+
}
|
|
5071
|
+
|
|
5072
|
+
.temp-range-tooltip__header {
|
|
5073
|
+
display: flex;
|
|
5074
|
+
align-items: center;
|
|
5075
|
+
gap: 8px;
|
|
5076
|
+
padding: 12px 16px;
|
|
5077
|
+
background: linear-gradient(90deg, #fff7ed 0%, #fed7aa 100%);
|
|
5078
|
+
border-bottom: 1px solid #fdba74;
|
|
5079
|
+
}
|
|
5080
|
+
|
|
5081
|
+
.temp-range-tooltip__icon {
|
|
5082
|
+
font-size: 18px;
|
|
5083
|
+
}
|
|
5084
|
+
|
|
5085
|
+
.temp-range-tooltip__title {
|
|
5086
|
+
font-weight: 700;
|
|
5087
|
+
font-size: 13px;
|
|
5088
|
+
color: #c2410c;
|
|
5089
|
+
}
|
|
5090
|
+
|
|
5091
|
+
.temp-range-tooltip__body {
|
|
5092
|
+
padding: 16px;
|
|
5093
|
+
}
|
|
5094
|
+
|
|
5095
|
+
/* Temperature value display */
|
|
5096
|
+
.temp-range-tooltip__value-row {
|
|
5097
|
+
display: flex;
|
|
5098
|
+
justify-content: space-between;
|
|
5099
|
+
align-items: center;
|
|
5100
|
+
margin-bottom: 16px;
|
|
5101
|
+
}
|
|
5102
|
+
|
|
5103
|
+
.temp-range-tooltip__current {
|
|
5104
|
+
font-size: 28px;
|
|
5105
|
+
font-weight: 700;
|
|
5106
|
+
color: #1e293b;
|
|
5107
|
+
}
|
|
5108
|
+
|
|
5109
|
+
.temp-range-tooltip__current sup {
|
|
5110
|
+
font-size: 14px;
|
|
5111
|
+
color: #64748b;
|
|
5112
|
+
}
|
|
5113
|
+
|
|
5114
|
+
.temp-range-tooltip__deviation {
|
|
5115
|
+
text-align: right;
|
|
5116
|
+
}
|
|
5117
|
+
|
|
5118
|
+
.temp-range-tooltip__deviation-value {
|
|
5119
|
+
font-size: 16px;
|
|
5120
|
+
font-weight: 700;
|
|
5121
|
+
}
|
|
5122
|
+
|
|
5123
|
+
.temp-range-tooltip__deviation-value.cold {
|
|
5124
|
+
color: #2563eb;
|
|
5125
|
+
}
|
|
5126
|
+
|
|
5127
|
+
.temp-range-tooltip__deviation-value.ok {
|
|
5128
|
+
color: #16a34a;
|
|
5129
|
+
}
|
|
5130
|
+
|
|
5131
|
+
.temp-range-tooltip__deviation-value.hot {
|
|
5132
|
+
color: #dc2626;
|
|
5133
|
+
}
|
|
5134
|
+
|
|
5135
|
+
.temp-range-tooltip__deviation-label {
|
|
5136
|
+
font-size: 10px;
|
|
5137
|
+
color: #64748b;
|
|
5138
|
+
text-transform: uppercase;
|
|
5139
|
+
letter-spacing: 0.5px;
|
|
5140
|
+
}
|
|
5141
|
+
|
|
5142
|
+
/* Temperature ruler/gauge */
|
|
5143
|
+
.temp-range-tooltip__ruler {
|
|
5144
|
+
position: relative;
|
|
5145
|
+
height: 32px;
|
|
5146
|
+
margin: 12px 0;
|
|
5147
|
+
border-radius: 8px;
|
|
5148
|
+
overflow: visible;
|
|
5149
|
+
}
|
|
5150
|
+
|
|
5151
|
+
.temp-range-tooltip__ruler-track {
|
|
5152
|
+
position: absolute;
|
|
5153
|
+
top: 12px;
|
|
5154
|
+
left: 0;
|
|
5155
|
+
right: 0;
|
|
5156
|
+
height: 8px;
|
|
5157
|
+
background: linear-gradient(90deg, #dbeafe 0%, #dcfce7 50%, #fee2e2 100%);
|
|
5158
|
+
border-radius: 4px;
|
|
5159
|
+
border: 1px solid #e2e8f0;
|
|
5160
|
+
}
|
|
5161
|
+
|
|
5162
|
+
.temp-range-tooltip__ruler-range {
|
|
5163
|
+
position: absolute;
|
|
5164
|
+
top: 12px;
|
|
5165
|
+
height: 8px;
|
|
5166
|
+
background: #22c55e;
|
|
5167
|
+
border-radius: 4px;
|
|
5168
|
+
opacity: 0.6;
|
|
5169
|
+
}
|
|
5170
|
+
|
|
5171
|
+
.temp-range-tooltip__ruler-marker {
|
|
5172
|
+
position: absolute;
|
|
5173
|
+
top: 4px;
|
|
5174
|
+
width: 4px;
|
|
5175
|
+
height: 24px;
|
|
5176
|
+
background: #1e293b;
|
|
5177
|
+
border-radius: 2px;
|
|
5178
|
+
transform: translateX(-50%);
|
|
5179
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
5180
|
+
}
|
|
5181
|
+
|
|
5182
|
+
.temp-range-tooltip__ruler-marker::after {
|
|
5183
|
+
content: '';
|
|
5184
|
+
position: absolute;
|
|
5185
|
+
top: -4px;
|
|
5186
|
+
left: 50%;
|
|
5187
|
+
transform: translateX(-50%);
|
|
5188
|
+
width: 12px;
|
|
5189
|
+
height: 12px;
|
|
5190
|
+
background: #1e293b;
|
|
5191
|
+
border-radius: 50%;
|
|
5192
|
+
border: 2px solid #fff;
|
|
5193
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
5194
|
+
}
|
|
5195
|
+
|
|
5196
|
+
.temp-range-tooltip__ruler-labels {
|
|
5197
|
+
display: flex;
|
|
5198
|
+
justify-content: space-between;
|
|
5199
|
+
margin-top: 8px;
|
|
5200
|
+
font-size: 10px;
|
|
5201
|
+
color: #64748b;
|
|
5202
|
+
}
|
|
5203
|
+
|
|
5204
|
+
.temp-range-tooltip__ruler-min,
|
|
5205
|
+
.temp-range-tooltip__ruler-max {
|
|
5206
|
+
font-weight: 600;
|
|
5207
|
+
}
|
|
5208
|
+
|
|
5209
|
+
/* Range info */
|
|
5210
|
+
.temp-range-tooltip__range-info {
|
|
5211
|
+
display: flex;
|
|
5212
|
+
justify-content: space-between;
|
|
5213
|
+
padding: 10px 12px;
|
|
5214
|
+
background: #f8fafc;
|
|
5215
|
+
border-radius: 8px;
|
|
5216
|
+
margin-top: 12px;
|
|
5217
|
+
}
|
|
5218
|
+
|
|
5219
|
+
.temp-range-tooltip__range-item {
|
|
5220
|
+
text-align: center;
|
|
5221
|
+
}
|
|
5222
|
+
|
|
5223
|
+
.temp-range-tooltip__range-label {
|
|
5224
|
+
font-size: 10px;
|
|
5225
|
+
color: #64748b;
|
|
5226
|
+
text-transform: uppercase;
|
|
5227
|
+
letter-spacing: 0.3px;
|
|
5228
|
+
margin-bottom: 2px;
|
|
5229
|
+
}
|
|
5230
|
+
|
|
5231
|
+
.temp-range-tooltip__range-value {
|
|
5232
|
+
font-size: 14px;
|
|
5233
|
+
font-weight: 600;
|
|
5234
|
+
color: #334155;
|
|
5235
|
+
}
|
|
5236
|
+
|
|
5237
|
+
/* Status badge */
|
|
5238
|
+
.temp-range-tooltip__status {
|
|
5239
|
+
display: flex;
|
|
5240
|
+
align-items: center;
|
|
5241
|
+
justify-content: center;
|
|
5242
|
+
gap: 6px;
|
|
5243
|
+
margin-top: 12px;
|
|
5244
|
+
padding: 8px 12px;
|
|
5245
|
+
border-radius: 6px;
|
|
5246
|
+
font-size: 11px;
|
|
5247
|
+
font-weight: 600;
|
|
5248
|
+
}
|
|
5249
|
+
|
|
5250
|
+
.temp-range-tooltip__status.cold {
|
|
5251
|
+
background: #dbeafe;
|
|
5252
|
+
color: #1d4ed8;
|
|
5253
|
+
border: 1px solid #93c5fd;
|
|
5254
|
+
}
|
|
5255
|
+
|
|
5256
|
+
.temp-range-tooltip__status.ok {
|
|
5257
|
+
background: #dcfce7;
|
|
5258
|
+
color: #15803d;
|
|
5259
|
+
border: 1px solid #86efac;
|
|
5260
|
+
}
|
|
5261
|
+
|
|
5262
|
+
.temp-range-tooltip__status.hot {
|
|
5263
|
+
background: #fee2e2;
|
|
5264
|
+
color: #b91c1c;
|
|
5265
|
+
border: 1px solid #fca5a5;
|
|
5266
|
+
}
|
|
5267
|
+
|
|
5268
|
+
.temp-range-tooltip__status.unknown {
|
|
5269
|
+
background: #f3f4f6;
|
|
5270
|
+
color: #6b7280;
|
|
5271
|
+
border: 1px solid #d1d5db;
|
|
5272
|
+
}
|
|
5273
|
+
|
|
5274
|
+
/* ============================================
|
|
5275
|
+
Energy Range Tooltip (for domain=energy)
|
|
5276
|
+
Shows power ruler with current position and status ranges
|
|
5277
|
+
============================================ */
|
|
5278
|
+
.energy-range-tooltip {
|
|
5279
|
+
position: fixed;
|
|
5280
|
+
z-index: 99999;
|
|
5281
|
+
pointer-events: none;
|
|
5282
|
+
opacity: 0;
|
|
5283
|
+
transition: opacity 0.2s ease, transform 0.2s ease;
|
|
5284
|
+
transform: translateY(5px);
|
|
5285
|
+
}
|
|
5286
|
+
|
|
5287
|
+
.energy-range-tooltip.visible {
|
|
5288
|
+
opacity: 1;
|
|
5289
|
+
pointer-events: auto;
|
|
5290
|
+
transform: translateY(0);
|
|
5291
|
+
}
|
|
5292
|
+
|
|
5293
|
+
.energy-range-tooltip__content {
|
|
5294
|
+
background: #ffffff;
|
|
5295
|
+
border: 1px solid #e2e8f0;
|
|
5296
|
+
border-radius: 12px;
|
|
5297
|
+
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15), 0 2px 10px rgba(0, 0, 0, 0.08);
|
|
5298
|
+
min-width: 300px;
|
|
5299
|
+
max-width: 360px;
|
|
5300
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
5301
|
+
font-size: 12px;
|
|
5302
|
+
color: #1e293b;
|
|
5303
|
+
overflow: hidden;
|
|
5304
|
+
}
|
|
5305
|
+
|
|
5306
|
+
.energy-range-tooltip__header {
|
|
5307
|
+
display: flex;
|
|
5308
|
+
align-items: center;
|
|
5309
|
+
gap: 8px;
|
|
5310
|
+
padding: 12px 16px;
|
|
5311
|
+
background: linear-gradient(90deg, #ecfdf5 0%, #d1fae5 100%);
|
|
5312
|
+
border-bottom: 1px solid #6ee7b7;
|
|
5313
|
+
}
|
|
5314
|
+
|
|
5315
|
+
.energy-range-tooltip__icon {
|
|
5316
|
+
font-size: 18px;
|
|
5317
|
+
}
|
|
5318
|
+
|
|
5319
|
+
.energy-range-tooltip__title {
|
|
5320
|
+
font-weight: 700;
|
|
5321
|
+
font-size: 13px;
|
|
5322
|
+
color: #047857;
|
|
5323
|
+
}
|
|
5324
|
+
|
|
5325
|
+
.energy-range-tooltip__body {
|
|
5326
|
+
padding: 16px;
|
|
5327
|
+
}
|
|
5328
|
+
|
|
5329
|
+
/* Power value display */
|
|
5330
|
+
.energy-range-tooltip__value-row {
|
|
5331
|
+
display: flex;
|
|
5332
|
+
justify-content: space-between;
|
|
5333
|
+
align-items: center;
|
|
5334
|
+
margin-bottom: 16px;
|
|
5335
|
+
}
|
|
5336
|
+
|
|
5337
|
+
.energy-range-tooltip__current {
|
|
5338
|
+
font-size: 28px;
|
|
5339
|
+
font-weight: 700;
|
|
5340
|
+
color: #1e293b;
|
|
5341
|
+
}
|
|
5342
|
+
|
|
5343
|
+
.energy-range-tooltip__current sup {
|
|
5344
|
+
font-size: 14px;
|
|
5345
|
+
color: #64748b;
|
|
5346
|
+
}
|
|
5347
|
+
|
|
5348
|
+
.energy-range-tooltip__status-badge {
|
|
5349
|
+
text-align: right;
|
|
5350
|
+
}
|
|
5351
|
+
|
|
5352
|
+
.energy-range-tooltip__status-value {
|
|
5353
|
+
font-size: 14px;
|
|
5354
|
+
font-weight: 700;
|
|
5355
|
+
padding: 4px 10px;
|
|
5356
|
+
border-radius: 6px;
|
|
5357
|
+
}
|
|
5358
|
+
|
|
5359
|
+
.energy-range-tooltip__status-value.standby {
|
|
5360
|
+
background: #dbeafe;
|
|
5361
|
+
color: #1d4ed8;
|
|
5362
|
+
}
|
|
5363
|
+
|
|
5364
|
+
.energy-range-tooltip__status-value.normal {
|
|
5365
|
+
background: #dcfce7;
|
|
5366
|
+
color: #15803d;
|
|
5367
|
+
}
|
|
5368
|
+
|
|
5369
|
+
.energy-range-tooltip__status-value.alert {
|
|
5370
|
+
background: #fef3c7;
|
|
5371
|
+
color: #b45309;
|
|
5372
|
+
}
|
|
5373
|
+
|
|
5374
|
+
.energy-range-tooltip__status-value.failure {
|
|
5375
|
+
background: #fee2e2;
|
|
5376
|
+
color: #b91c1c;
|
|
5377
|
+
}
|
|
5378
|
+
|
|
5379
|
+
.energy-range-tooltip__status-value.offline {
|
|
5380
|
+
background: #f3f4f6;
|
|
5381
|
+
color: #6b7280;
|
|
5382
|
+
}
|
|
5383
|
+
|
|
5384
|
+
/* Power ruler/gauge */
|
|
5385
|
+
.energy-range-tooltip__ruler {
|
|
5386
|
+
position: relative;
|
|
5387
|
+
height: 40px;
|
|
5388
|
+
margin: 12px 0;
|
|
5389
|
+
border-radius: 8px;
|
|
5390
|
+
overflow: visible;
|
|
5391
|
+
}
|
|
5392
|
+
|
|
5393
|
+
.energy-range-tooltip__ruler-track {
|
|
5394
|
+
position: absolute;
|
|
5395
|
+
top: 16px;
|
|
5396
|
+
left: 0;
|
|
5397
|
+
right: 0;
|
|
5398
|
+
height: 8px;
|
|
5399
|
+
display: flex;
|
|
5400
|
+
border-radius: 4px;
|
|
5401
|
+
overflow: hidden;
|
|
5402
|
+
border: 1px solid #e2e8f0;
|
|
5403
|
+
}
|
|
5404
|
+
|
|
5405
|
+
.energy-range-tooltip__ruler-segment {
|
|
5406
|
+
height: 100%;
|
|
5407
|
+
}
|
|
5408
|
+
|
|
5409
|
+
.energy-range-tooltip__ruler-segment.standby {
|
|
5410
|
+
background: #dbeafe;
|
|
5411
|
+
}
|
|
5412
|
+
|
|
5413
|
+
.energy-range-tooltip__ruler-segment.normal {
|
|
5414
|
+
background: #dcfce7;
|
|
5415
|
+
}
|
|
5416
|
+
|
|
5417
|
+
.energy-range-tooltip__ruler-segment.alert {
|
|
5418
|
+
background: #fef3c7;
|
|
5419
|
+
}
|
|
5420
|
+
|
|
5421
|
+
.energy-range-tooltip__ruler-segment.failure {
|
|
5422
|
+
background: #fee2e2;
|
|
5423
|
+
}
|
|
5424
|
+
|
|
5425
|
+
.energy-range-tooltip__ruler-marker {
|
|
5426
|
+
position: absolute;
|
|
5427
|
+
top: 8px;
|
|
5428
|
+
width: 4px;
|
|
5429
|
+
height: 24px;
|
|
5430
|
+
background: #1e293b;
|
|
5431
|
+
border-radius: 2px;
|
|
5432
|
+
transform: translateX(-50%);
|
|
5433
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
5434
|
+
}
|
|
5435
|
+
|
|
5436
|
+
.energy-range-tooltip__ruler-marker::after {
|
|
5437
|
+
content: '';
|
|
5438
|
+
position: absolute;
|
|
5439
|
+
top: -4px;
|
|
5440
|
+
left: 50%;
|
|
5441
|
+
transform: translateX(-50%);
|
|
5442
|
+
width: 12px;
|
|
5443
|
+
height: 12px;
|
|
5444
|
+
background: #1e293b;
|
|
5445
|
+
border-radius: 50%;
|
|
5446
|
+
border: 2px solid #fff;
|
|
5447
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
5448
|
+
}
|
|
5449
|
+
|
|
5450
|
+
/* Range info grid */
|
|
5451
|
+
.energy-range-tooltip__ranges {
|
|
5452
|
+
display: grid;
|
|
5453
|
+
grid-template-columns: repeat(4, 1fr);
|
|
5454
|
+
gap: 8px;
|
|
5455
|
+
margin-top: 16px;
|
|
5456
|
+
}
|
|
5457
|
+
|
|
5458
|
+
.energy-range-tooltip__range-item {
|
|
5459
|
+
text-align: center;
|
|
5460
|
+
padding: 8px 4px;
|
|
5461
|
+
border-radius: 6px;
|
|
5462
|
+
background: #f8fafc;
|
|
5463
|
+
}
|
|
5464
|
+
|
|
5465
|
+
.energy-range-tooltip__range-item.standby {
|
|
5466
|
+
border-left: 3px solid #3b82f6;
|
|
5467
|
+
}
|
|
5468
|
+
|
|
5469
|
+
.energy-range-tooltip__range-item.normal {
|
|
5470
|
+
border-left: 3px solid #22c55e;
|
|
5471
|
+
}
|
|
5472
|
+
|
|
5473
|
+
.energy-range-tooltip__range-item.alert {
|
|
5474
|
+
border-left: 3px solid #f59e0b;
|
|
5475
|
+
}
|
|
5476
|
+
|
|
5477
|
+
.energy-range-tooltip__range-item.failure {
|
|
5478
|
+
border-left: 3px solid #ef4444;
|
|
5479
|
+
}
|
|
5480
|
+
|
|
5481
|
+
.energy-range-tooltip__range-label {
|
|
5482
|
+
font-size: 9px;
|
|
5483
|
+
color: #64748b;
|
|
5484
|
+
text-transform: uppercase;
|
|
5485
|
+
letter-spacing: 0.3px;
|
|
5486
|
+
margin-bottom: 2px;
|
|
5487
|
+
}
|
|
5488
|
+
|
|
5489
|
+
.energy-range-tooltip__range-value {
|
|
5490
|
+
font-size: 11px;
|
|
5491
|
+
font-weight: 600;
|
|
5492
|
+
color: #334155;
|
|
5493
|
+
}
|
|
5494
|
+
|
|
5495
|
+
/* Status info */
|
|
5496
|
+
.energy-range-tooltip__status-info {
|
|
5497
|
+
display: flex;
|
|
5498
|
+
align-items: center;
|
|
5499
|
+
justify-content: center;
|
|
5500
|
+
gap: 6px;
|
|
5501
|
+
margin-top: 12px;
|
|
5502
|
+
padding: 8px 12px;
|
|
5503
|
+
border-radius: 6px;
|
|
5504
|
+
font-size: 11px;
|
|
5505
|
+
font-weight: 600;
|
|
5506
|
+
}
|
|
5507
|
+
|
|
5508
|
+
.energy-range-tooltip__status-info.standby {
|
|
5509
|
+
background: #dbeafe;
|
|
5510
|
+
color: #1d4ed8;
|
|
5511
|
+
border: 1px solid #93c5fd;
|
|
5512
|
+
}
|
|
5513
|
+
|
|
5514
|
+
.energy-range-tooltip__status-info.normal {
|
|
5515
|
+
background: #dcfce7;
|
|
5516
|
+
color: #15803d;
|
|
5517
|
+
border: 1px solid #86efac;
|
|
5518
|
+
}
|
|
5519
|
+
|
|
5520
|
+
.energy-range-tooltip__status-info.alert {
|
|
5521
|
+
background: #fef3c7;
|
|
5522
|
+
color: #b45309;
|
|
5523
|
+
border: 1px solid #fcd34d;
|
|
5524
|
+
}
|
|
5525
|
+
|
|
5526
|
+
.energy-range-tooltip__status-info.failure {
|
|
5527
|
+
background: #fee2e2;
|
|
5528
|
+
color: #b91c1c;
|
|
5529
|
+
border: 1px solid #fca5a5;
|
|
5530
|
+
}
|
|
5531
|
+
|
|
5532
|
+
.energy-range-tooltip__status-info.offline {
|
|
5533
|
+
background: #f3f4f6;
|
|
5534
|
+
color: #6b7280;
|
|
5535
|
+
border: 1px solid #d1d5db;
|
|
5536
|
+
}
|
|
5012
5537
|
`;
|
|
5013
5538
|
|
|
5014
5539
|
// src/thingsboard/main-dashboard-shopping/v-4.0.0/head-office/card-head-office.icons.ts
|
|
@@ -5466,6 +5991,16 @@
|
|
|
5466
5991
|
}
|
|
5467
5992
|
return formatEnergy(value);
|
|
5468
5993
|
}
|
|
5994
|
+
function formatRelativeTime2(timestamp) {
|
|
5995
|
+
if (!timestamp || isNaN(timestamp)) return "\u2014";
|
|
5996
|
+
const date = new Date(timestamp);
|
|
5997
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
5998
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
5999
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
6000
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
6001
|
+
const year = date.getFullYear();
|
|
6002
|
+
return `${hours}:${minutes} ${day}/${month}/${year}`;
|
|
6003
|
+
}
|
|
5469
6004
|
function calculateConsumptionPercentage(target, consumption) {
|
|
5470
6005
|
const numericTarget = Number(target);
|
|
5471
6006
|
const numericConsumption = Number(consumption);
|
|
@@ -5543,6 +6078,373 @@
|
|
|
5543
6078
|
return "";
|
|
5544
6079
|
}
|
|
5545
6080
|
}
|
|
6081
|
+
function getTempRangeClass(entityObject) {
|
|
6082
|
+
if (entityObject.domain !== "temperature") return "";
|
|
6083
|
+
const currentTemp = Number(entityObject.val ?? entityObject.currentTemperature ?? entityObject.temperature) || 0;
|
|
6084
|
+
const tempMin = entityObject.temperatureMin ?? entityObject.minTemperature;
|
|
6085
|
+
const tempMax = entityObject.temperatureMax ?? entityObject.maxTemperature;
|
|
6086
|
+
if (tempMin === void 0 || tempMax === void 0 || tempMin === null || tempMax === null) {
|
|
6087
|
+
return "";
|
|
6088
|
+
}
|
|
6089
|
+
if (currentTemp > tempMax) return "is-temp-hot";
|
|
6090
|
+
if (currentTemp < tempMin) return "is-temp-cold";
|
|
6091
|
+
return "is-temp-ok";
|
|
6092
|
+
}
|
|
6093
|
+
var TempRangeTooltip = {
|
|
6094
|
+
containerId: "myio-temp-range-tooltip",
|
|
6095
|
+
/**
|
|
6096
|
+
* Create or get the tooltip container
|
|
6097
|
+
*/
|
|
6098
|
+
getContainer() {
|
|
6099
|
+
let container = document.getElementById(this.containerId);
|
|
6100
|
+
if (!container) {
|
|
6101
|
+
container = document.createElement("div");
|
|
6102
|
+
container.id = this.containerId;
|
|
6103
|
+
container.className = "temp-range-tooltip";
|
|
6104
|
+
document.body.appendChild(container);
|
|
6105
|
+
}
|
|
6106
|
+
return container;
|
|
6107
|
+
},
|
|
6108
|
+
/**
|
|
6109
|
+
* Calculate temperature status and deviation
|
|
6110
|
+
*/
|
|
6111
|
+
calculateStatus(currentTemp, tempMin, tempMax) {
|
|
6112
|
+
if (tempMin == null || tempMax == null) {
|
|
6113
|
+
return { status: "unknown", deviation: null, deviationPercent: null };
|
|
6114
|
+
}
|
|
6115
|
+
const rangeSize = tempMax - tempMin;
|
|
6116
|
+
const midPoint = (tempMin + tempMax) / 2;
|
|
6117
|
+
if (currentTemp < tempMin) {
|
|
6118
|
+
const deviation = tempMin - currentTemp;
|
|
6119
|
+
const deviationPercent = rangeSize > 0 ? deviation / rangeSize * 100 : 0;
|
|
6120
|
+
return { status: "cold", deviation: -deviation, deviationPercent: -deviationPercent };
|
|
6121
|
+
} else if (currentTemp > tempMax) {
|
|
6122
|
+
const deviation = currentTemp - tempMax;
|
|
6123
|
+
const deviationPercent = rangeSize > 0 ? deviation / rangeSize * 100 : 0;
|
|
6124
|
+
return { status: "hot", deviation, deviationPercent };
|
|
6125
|
+
} else {
|
|
6126
|
+
const deviationFromMid = currentTemp - midPoint;
|
|
6127
|
+
return { status: "ok", deviation: deviationFromMid, deviationPercent: 0 };
|
|
6128
|
+
}
|
|
6129
|
+
},
|
|
6130
|
+
/**
|
|
6131
|
+
* Calculate marker position on ruler (0-100%)
|
|
6132
|
+
*/
|
|
6133
|
+
calculateMarkerPosition(currentTemp, tempMin, tempMax) {
|
|
6134
|
+
if (tempMin == null || tempMax == null) return 50;
|
|
6135
|
+
const rangeSize = tempMax - tempMin;
|
|
6136
|
+
const extension = rangeSize * 0.3;
|
|
6137
|
+
const visibleMin = tempMin - extension;
|
|
6138
|
+
const visibleMax = tempMax + extension;
|
|
6139
|
+
const visibleRange = visibleMax - visibleMin;
|
|
6140
|
+
const clampedTemp = Math.max(visibleMin, Math.min(visibleMax, currentTemp));
|
|
6141
|
+
const position = (clampedTemp - visibleMin) / visibleRange * 100;
|
|
6142
|
+
return Math.max(2, Math.min(98, position));
|
|
6143
|
+
},
|
|
6144
|
+
/**
|
|
6145
|
+
* Show tooltip for a temperature card
|
|
6146
|
+
* @param {HTMLElement} triggerElement - The card element
|
|
6147
|
+
* @param {Object} entityObject - Entity data
|
|
6148
|
+
* @param {MouseEvent} event - Mouse event for cursor position
|
|
6149
|
+
*/
|
|
6150
|
+
show(triggerElement, entityObject, event) {
|
|
6151
|
+
const container = this.getContainer();
|
|
6152
|
+
const currentTemp = Number(entityObject.val ?? entityObject.currentTemperature ?? entityObject.temperature) || 0;
|
|
6153
|
+
const tempMin = entityObject.temperatureMin ?? entityObject.minTemperature;
|
|
6154
|
+
const tempMax = entityObject.temperatureMax ?? entityObject.maxTemperature;
|
|
6155
|
+
const hasRange = tempMin != null && tempMax != null;
|
|
6156
|
+
const { status, deviation, deviationPercent } = this.calculateStatus(currentTemp, tempMin, tempMax);
|
|
6157
|
+
const markerPos = this.calculateMarkerPosition(currentTemp, tempMin, tempMax);
|
|
6158
|
+
let rangeLeft = 0, rangeWidth = 100;
|
|
6159
|
+
if (hasRange) {
|
|
6160
|
+
const rangeSize = tempMax - tempMin;
|
|
6161
|
+
const extension = rangeSize * 0.3;
|
|
6162
|
+
const visibleMin = tempMin - extension;
|
|
6163
|
+
const visibleMax = tempMax + extension;
|
|
6164
|
+
const visibleRange = visibleMax - visibleMin;
|
|
6165
|
+
rangeLeft = (tempMin - visibleMin) / visibleRange * 100;
|
|
6166
|
+
rangeWidth = rangeSize / visibleRange * 100;
|
|
6167
|
+
}
|
|
6168
|
+
let deviationClass = status;
|
|
6169
|
+
if (status === "cold") {
|
|
6170
|
+
`${Math.abs(deviation).toFixed(1)}\xB0C abaixo`;
|
|
6171
|
+
} else if (status === "hot") {
|
|
6172
|
+
`+${deviation.toFixed(1)}\xB0C acima`;
|
|
6173
|
+
} else ;
|
|
6174
|
+
const statusLabels = {
|
|
6175
|
+
cold: "\u2744\uFE0F Abaixo da Faixa Ideal",
|
|
6176
|
+
ok: "\u2714\uFE0F Dentro da Faixa Ideal",
|
|
6177
|
+
hot: "\u{1F525} Acima da Faixa Ideal",
|
|
6178
|
+
unknown: "\u2753 Faixa N\xE3o Configurada"
|
|
6179
|
+
};
|
|
6180
|
+
container.innerHTML = `
|
|
6181
|
+
<div class="temp-range-tooltip__content">
|
|
6182
|
+
<div class="temp-range-tooltip__header">
|
|
6183
|
+
<span class="temp-range-tooltip__icon">\u{1F321}\uFE0F</span>
|
|
6184
|
+
<span class="temp-range-tooltip__title">${entityObject.labelOrName || entityObject.name || "Sensor"}</span>
|
|
6185
|
+
</div>
|
|
6186
|
+
<div class="temp-range-tooltip__body">
|
|
6187
|
+
<div class="temp-range-tooltip__value-row">
|
|
6188
|
+
<div class="temp-range-tooltip__current">
|
|
6189
|
+
${currentTemp.toFixed(1)}<sup>\xB0C</sup>
|
|
6190
|
+
</div>
|
|
6191
|
+
<div class="temp-range-tooltip__deviation">
|
|
6192
|
+
<div class="temp-range-tooltip__deviation-value ${deviationClass}">
|
|
6193
|
+
${status === "ok" ? "\u2713" : status === "cold" ? "\u2193" : status === "hot" ? "\u2191" : "?"} ${Math.abs(deviationPercent || 0).toFixed(0)}%
|
|
6194
|
+
</div>
|
|
6195
|
+
<div class="temp-range-tooltip__deviation-label">Desvio</div>
|
|
6196
|
+
</div>
|
|
6197
|
+
</div>
|
|
6198
|
+
|
|
6199
|
+
${hasRange ? `
|
|
6200
|
+
<div class="temp-range-tooltip__ruler">
|
|
6201
|
+
<div class="temp-range-tooltip__ruler-track"></div>
|
|
6202
|
+
<div class="temp-range-tooltip__ruler-range" style="left: ${rangeLeft}%; width: ${rangeWidth}%;"></div>
|
|
6203
|
+
<div class="temp-range-tooltip__ruler-marker" style="left: ${markerPos}%;"></div>
|
|
6204
|
+
</div>
|
|
6205
|
+
<div class="temp-range-tooltip__ruler-labels">
|
|
6206
|
+
<span class="temp-range-tooltip__ruler-min">${tempMin}\xB0C</span>
|
|
6207
|
+
<span style="color: #22c55e; font-weight: 600;">Faixa Ideal</span>
|
|
6208
|
+
<span class="temp-range-tooltip__ruler-max">${tempMax}\xB0C</span>
|
|
6209
|
+
</div>
|
|
6210
|
+
` : ""}
|
|
6211
|
+
|
|
6212
|
+
<div class="temp-range-tooltip__range-info">
|
|
6213
|
+
<div class="temp-range-tooltip__range-item">
|
|
6214
|
+
<div class="temp-range-tooltip__range-label">M\xEDnimo</div>
|
|
6215
|
+
<div class="temp-range-tooltip__range-value">${hasRange ? tempMin + "\xB0C" : "--"}</div>
|
|
6216
|
+
</div>
|
|
6217
|
+
<div class="temp-range-tooltip__range-item">
|
|
6218
|
+
<div class="temp-range-tooltip__range-label">Atual</div>
|
|
6219
|
+
<div class="temp-range-tooltip__range-value" style="color: ${status === "ok" ? "#16a34a" : status === "cold" ? "#2563eb" : "#dc2626"}">${currentTemp.toFixed(1)}\xB0C</div>
|
|
6220
|
+
</div>
|
|
6221
|
+
<div class="temp-range-tooltip__range-item">
|
|
6222
|
+
<div class="temp-range-tooltip__range-label">M\xE1ximo</div>
|
|
6223
|
+
<div class="temp-range-tooltip__range-value">${hasRange ? tempMax + "\xB0C" : "--"}</div>
|
|
6224
|
+
</div>
|
|
6225
|
+
</div>
|
|
6226
|
+
|
|
6227
|
+
<div class="temp-range-tooltip__status ${status}">
|
|
6228
|
+
${statusLabels[status]}
|
|
6229
|
+
</div>
|
|
6230
|
+
</div>
|
|
6231
|
+
</div>
|
|
6232
|
+
`;
|
|
6233
|
+
let left, top;
|
|
6234
|
+
if (event && event.clientX && event.clientY) {
|
|
6235
|
+
left = event.clientX + 15;
|
|
6236
|
+
top = event.clientY + 15;
|
|
6237
|
+
} else {
|
|
6238
|
+
const rect = triggerElement.getBoundingClientRect();
|
|
6239
|
+
left = rect.left + rect.width / 2 - 150;
|
|
6240
|
+
top = rect.bottom + 8;
|
|
6241
|
+
}
|
|
6242
|
+
const tooltipWidth = 300;
|
|
6243
|
+
const tooltipHeight = 350;
|
|
6244
|
+
if (left + tooltipWidth > window.innerWidth - 10) {
|
|
6245
|
+
left = (event?.clientX || left) - tooltipWidth - 15;
|
|
6246
|
+
}
|
|
6247
|
+
if (left < 10) left = 10;
|
|
6248
|
+
if (top + tooltipHeight > window.innerHeight - 10) {
|
|
6249
|
+
top = (event?.clientY || top) - tooltipHeight - 15;
|
|
6250
|
+
}
|
|
6251
|
+
if (top < 10) top = 10;
|
|
6252
|
+
container.style.left = left + "px";
|
|
6253
|
+
container.style.top = top + "px";
|
|
6254
|
+
container.classList.add("visible");
|
|
6255
|
+
},
|
|
6256
|
+
/**
|
|
6257
|
+
* Hide tooltip
|
|
6258
|
+
*/
|
|
6259
|
+
hide() {
|
|
6260
|
+
const container = document.getElementById(this.containerId);
|
|
6261
|
+
if (container) {
|
|
6262
|
+
container.classList.remove("visible");
|
|
6263
|
+
}
|
|
6264
|
+
}
|
|
6265
|
+
};
|
|
6266
|
+
var EnergyRangeTooltip = {
|
|
6267
|
+
containerId: "myio-energy-range-tooltip",
|
|
6268
|
+
/**
|
|
6269
|
+
* Create or get the tooltip container
|
|
6270
|
+
*/
|
|
6271
|
+
getContainer() {
|
|
6272
|
+
let container = document.getElementById(this.containerId);
|
|
6273
|
+
if (!container) {
|
|
6274
|
+
container = document.createElement("div");
|
|
6275
|
+
container.id = this.containerId;
|
|
6276
|
+
container.className = "energy-range-tooltip";
|
|
6277
|
+
document.body.appendChild(container);
|
|
6278
|
+
}
|
|
6279
|
+
return container;
|
|
6280
|
+
},
|
|
6281
|
+
/**
|
|
6282
|
+
* Determine status based on power value and ranges
|
|
6283
|
+
*/
|
|
6284
|
+
calculateStatus(powerValue, ranges) {
|
|
6285
|
+
if (!ranges || powerValue == null) {
|
|
6286
|
+
return { status: "offline", label: "Sem dados" };
|
|
6287
|
+
}
|
|
6288
|
+
const power = Number(powerValue) || 0;
|
|
6289
|
+
const { standbyRange, normalRange, alertRange, failureRange } = ranges;
|
|
6290
|
+
if (standbyRange && power >= standbyRange.down && power <= standbyRange.up) {
|
|
6291
|
+
return { status: "standby", label: "Standby" };
|
|
6292
|
+
}
|
|
6293
|
+
if (normalRange && power >= normalRange.down && power <= normalRange.up) {
|
|
6294
|
+
return { status: "normal", label: "Normal" };
|
|
6295
|
+
}
|
|
6296
|
+
if (alertRange && power >= alertRange.down && power <= alertRange.up) {
|
|
6297
|
+
return { status: "alert", label: "Alerta" };
|
|
6298
|
+
}
|
|
6299
|
+
if (failureRange && power >= failureRange.down && power <= failureRange.up) {
|
|
6300
|
+
return { status: "failure", label: "Falha" };
|
|
6301
|
+
}
|
|
6302
|
+
return { status: "offline", label: "Fora da faixa" };
|
|
6303
|
+
},
|
|
6304
|
+
/**
|
|
6305
|
+
* Calculate marker position on ruler (0-100%)
|
|
6306
|
+
*/
|
|
6307
|
+
calculateMarkerPosition(powerValue, ranges) {
|
|
6308
|
+
if (!ranges) return 50;
|
|
6309
|
+
const power = Number(powerValue) || 0;
|
|
6310
|
+
const maxRange = ranges.failureRange?.up || ranges.alertRange?.up || 1e3;
|
|
6311
|
+
const displayMax = Math.min(maxRange, (ranges.alertRange?.up || maxRange) * 1.2);
|
|
6312
|
+
const position = power / displayMax * 100;
|
|
6313
|
+
return Math.max(2, Math.min(98, position));
|
|
6314
|
+
},
|
|
6315
|
+
/**
|
|
6316
|
+
* Calculate segment widths for the ruler
|
|
6317
|
+
*/
|
|
6318
|
+
calculateSegmentWidths(ranges) {
|
|
6319
|
+
if (!ranges) return { standby: 25, normal: 25, alert: 25, failure: 25 };
|
|
6320
|
+
const maxValue = ranges.failureRange?.up || 1e4;
|
|
6321
|
+
const total = Math.min(maxValue, (ranges.alertRange?.up || maxValue) * 1.2);
|
|
6322
|
+
return {
|
|
6323
|
+
standby: (ranges.standbyRange?.up || 0) / total * 100,
|
|
6324
|
+
normal: ((ranges.normalRange?.up || 0) - (ranges.normalRange?.down || 0)) / total * 100,
|
|
6325
|
+
alert: ((ranges.alertRange?.up || 0) - (ranges.alertRange?.down || 0)) / total * 100,
|
|
6326
|
+
failure: Math.max(5, 100 - (ranges.alertRange?.up || 0) / total * 100)
|
|
6327
|
+
};
|
|
6328
|
+
},
|
|
6329
|
+
/**
|
|
6330
|
+
* Format power value for display
|
|
6331
|
+
*/
|
|
6332
|
+
formatPower(value) {
|
|
6333
|
+
if (value == null || isNaN(value)) return "-";
|
|
6334
|
+
const num = Number(value);
|
|
6335
|
+
if (num >= 1e3) {
|
|
6336
|
+
return `${(num / 1e3).toFixed(2)} kW`;
|
|
6337
|
+
}
|
|
6338
|
+
return `${Math.round(num)} W`;
|
|
6339
|
+
},
|
|
6340
|
+
/**
|
|
6341
|
+
* Show tooltip for an energy card
|
|
6342
|
+
*/
|
|
6343
|
+
show(triggerElement, entityObject, event) {
|
|
6344
|
+
const container = this.getContainer();
|
|
6345
|
+
const powerValue = entityObject.instantaneousPower ?? entityObject.consumption_power ?? 0;
|
|
6346
|
+
const ranges = entityObject.powerRanges || entityObject.ranges;
|
|
6347
|
+
const hasRanges = ranges && ranges.normalRange;
|
|
6348
|
+
const { status, label } = this.calculateStatus(powerValue, ranges);
|
|
6349
|
+
const markerPos = this.calculateMarkerPosition(powerValue, ranges);
|
|
6350
|
+
const segmentWidths = this.calculateSegmentWidths(ranges);
|
|
6351
|
+
const statusLabels = {
|
|
6352
|
+
standby: "\u{1F535} Standby",
|
|
6353
|
+
normal: "\u2705 Opera\xE7\xE3o Normal",
|
|
6354
|
+
alert: "\u26A0\uFE0F Alerta",
|
|
6355
|
+
failure: "\u{1F534} Falha",
|
|
6356
|
+
offline: "\u26AB Offline / Sem dados"
|
|
6357
|
+
};
|
|
6358
|
+
container.innerHTML = `
|
|
6359
|
+
<div class="energy-range-tooltip__content">
|
|
6360
|
+
<div class="energy-range-tooltip__header">
|
|
6361
|
+
<span class="energy-range-tooltip__icon">\u26A1</span>
|
|
6362
|
+
<span class="energy-range-tooltip__title">${entityObject.labelOrName || entityObject.name || "Equipamento"}</span>
|
|
6363
|
+
</div>
|
|
6364
|
+
<div class="energy-range-tooltip__body">
|
|
6365
|
+
<div class="energy-range-tooltip__value-row">
|
|
6366
|
+
<div class="energy-range-tooltip__current">
|
|
6367
|
+
${this.formatPower(powerValue)}
|
|
6368
|
+
</div>
|
|
6369
|
+
<div class="energy-range-tooltip__status-badge">
|
|
6370
|
+
<span class="energy-range-tooltip__status-value ${status}">${label}</span>
|
|
6371
|
+
</div>
|
|
6372
|
+
</div>
|
|
6373
|
+
|
|
6374
|
+
${hasRanges ? `
|
|
6375
|
+
<div class="energy-range-tooltip__ruler">
|
|
6376
|
+
<div class="energy-range-tooltip__ruler-track">
|
|
6377
|
+
<div class="energy-range-tooltip__ruler-segment standby" style="width: ${segmentWidths.standby}%"></div>
|
|
6378
|
+
<div class="energy-range-tooltip__ruler-segment normal" style="width: ${segmentWidths.normal}%"></div>
|
|
6379
|
+
<div class="energy-range-tooltip__ruler-segment alert" style="width: ${segmentWidths.alert}%"></div>
|
|
6380
|
+
<div class="energy-range-tooltip__ruler-segment failure" style="width: ${segmentWidths.failure}%"></div>
|
|
6381
|
+
</div>
|
|
6382
|
+
<div class="energy-range-tooltip__ruler-marker" style="left: ${markerPos}%;"></div>
|
|
6383
|
+
</div>
|
|
6384
|
+
|
|
6385
|
+
<div class="energy-range-tooltip__ranges">
|
|
6386
|
+
<div class="energy-range-tooltip__range-item standby">
|
|
6387
|
+
<div class="energy-range-tooltip__range-label">Standby</div>
|
|
6388
|
+
<div class="energy-range-tooltip__range-value">${ranges.standbyRange?.down || 0}-${ranges.standbyRange?.up || 0}W</div>
|
|
6389
|
+
</div>
|
|
6390
|
+
<div class="energy-range-tooltip__range-item normal">
|
|
6391
|
+
<div class="energy-range-tooltip__range-label">Normal</div>
|
|
6392
|
+
<div class="energy-range-tooltip__range-value">${ranges.normalRange?.down || 0}-${ranges.normalRange?.up || 0}W</div>
|
|
6393
|
+
</div>
|
|
6394
|
+
<div class="energy-range-tooltip__range-item alert">
|
|
6395
|
+
<div class="energy-range-tooltip__range-label">Alerta</div>
|
|
6396
|
+
<div class="energy-range-tooltip__range-value">${ranges.alertRange?.down || 0}-${ranges.alertRange?.up || 0}W</div>
|
|
6397
|
+
</div>
|
|
6398
|
+
<div class="energy-range-tooltip__range-item failure">
|
|
6399
|
+
<div class="energy-range-tooltip__range-label">Falha</div>
|
|
6400
|
+
<div class="energy-range-tooltip__range-value">>${ranges.failureRange?.down || 0}W</div>
|
|
6401
|
+
</div>
|
|
6402
|
+
</div>
|
|
6403
|
+
` : `
|
|
6404
|
+
<div style="text-align: center; padding: 16px; color: #64748b; font-size: 12px;">
|
|
6405
|
+
Ranges de pot\xEAncia n\xE3o configurados
|
|
6406
|
+
</div>
|
|
6407
|
+
`}
|
|
6408
|
+
|
|
6409
|
+
<div class="energy-range-tooltip__status-info ${status}">
|
|
6410
|
+
${statusLabels[status] || statusLabels.offline}
|
|
6411
|
+
</div>
|
|
6412
|
+
</div>
|
|
6413
|
+
</div>
|
|
6414
|
+
`;
|
|
6415
|
+
let left, top;
|
|
6416
|
+
if (event && event.clientX && event.clientY) {
|
|
6417
|
+
left = event.clientX + 15;
|
|
6418
|
+
top = event.clientY + 15;
|
|
6419
|
+
} else {
|
|
6420
|
+
const rect = triggerElement.getBoundingClientRect();
|
|
6421
|
+
left = rect.left + rect.width / 2 - 150;
|
|
6422
|
+
top = rect.bottom + 8;
|
|
6423
|
+
}
|
|
6424
|
+
const tooltipWidth = 320;
|
|
6425
|
+
const tooltipHeight = 380;
|
|
6426
|
+
if (left + tooltipWidth > window.innerWidth - 10) {
|
|
6427
|
+
left = (event?.clientX || left) - tooltipWidth - 15;
|
|
6428
|
+
}
|
|
6429
|
+
if (left < 10) left = 10;
|
|
6430
|
+
if (top + tooltipHeight > window.innerHeight - 10) {
|
|
6431
|
+
top = (event?.clientY || top) - tooltipHeight - 15;
|
|
6432
|
+
}
|
|
6433
|
+
if (top < 10) top = 10;
|
|
6434
|
+
container.style.left = left + "px";
|
|
6435
|
+
container.style.top = top + "px";
|
|
6436
|
+
container.classList.add("visible");
|
|
6437
|
+
},
|
|
6438
|
+
/**
|
|
6439
|
+
* Hide tooltip
|
|
6440
|
+
*/
|
|
6441
|
+
hide() {
|
|
6442
|
+
const container = document.getElementById(this.containerId);
|
|
6443
|
+
if (container) {
|
|
6444
|
+
container.classList.remove("visible");
|
|
6445
|
+
}
|
|
6446
|
+
}
|
|
6447
|
+
};
|
|
5546
6448
|
function getStatusDotClass(deviceStatus) {
|
|
5547
6449
|
switch (deviceStatus) {
|
|
5548
6450
|
// --- Novos Status de Temperatura ---
|
|
@@ -5718,6 +6620,8 @@
|
|
|
5718
6620
|
powerLabel.className = "label";
|
|
5719
6621
|
if (entityObject.domain === "water") {
|
|
5720
6622
|
powerLabel.textContent = "Leitura";
|
|
6623
|
+
} else if (entityObject.domain === "temperature") {
|
|
6624
|
+
powerLabel.textContent = "\xDAlt. Telemetria";
|
|
5721
6625
|
} else {
|
|
5722
6626
|
powerLabel.textContent = i18n.instantaneous_power || "Pot\xEAncia";
|
|
5723
6627
|
}
|
|
@@ -5933,11 +6837,16 @@
|
|
|
5933
6837
|
}
|
|
5934
6838
|
}
|
|
5935
6839
|
const stateClass = getCardStateClass(entityObject.deviceStatus);
|
|
5936
|
-
|
|
6840
|
+
const tempRangeClass = getTempRangeClass(entityObject);
|
|
6841
|
+
root.className = `myio-ho-card ${stateClass} ${tempRangeClass}`.trim();
|
|
5937
6842
|
const statusInfo = getStatusInfo(entityObject.deviceStatus, i18n, entityObject.domain);
|
|
5938
6843
|
const chip = root.querySelector(".chip");
|
|
5939
6844
|
chip.className = `chip ${statusInfo.chipClass}`;
|
|
5940
6845
|
chip.innerHTML = statusInfo.label;
|
|
6846
|
+
const iconContainer = root.querySelector(".myio-ho-card__icon");
|
|
6847
|
+
if (iconContainer) {
|
|
6848
|
+
iconContainer.innerHTML = getIconSvg(entityObject.deviceType, entityObject.domain);
|
|
6849
|
+
}
|
|
5941
6850
|
if (activeTooltipDebug) {
|
|
5942
6851
|
const debugInfo = buildDebugTooltipInfo(entityObject, statusInfo, stateClass, statusDecisionSource, delayTimeConnectionInMins);
|
|
5943
6852
|
attachDebugTooltip(chip, debugInfo);
|
|
@@ -5971,14 +6880,19 @@
|
|
|
5971
6880
|
effContainer.style.display = "none";
|
|
5972
6881
|
}
|
|
5973
6882
|
const opTimeVal = root.querySelector(".myio-ho-card__footer .metric:nth-child(1) .val");
|
|
6883
|
+
const opTimeLabel = root.querySelector(".myio-ho-card__footer .metric:nth-child(1) .label");
|
|
5974
6884
|
if (opTimeVal) {
|
|
5975
|
-
|
|
6885
|
+
if (opTimeLabel) opTimeLabel.textContent = i18n.operation_time;
|
|
6886
|
+
const isOffline = entityObject.deviceStatus === DeviceStatusType.OFFLINE || entityObject.deviceStatus === "offline" || entityObject.deviceStatus === DeviceStatusType.NO_INFO;
|
|
6887
|
+
opTimeVal.textContent = isOffline ? "-" : entityObject.operationHours ?? "-";
|
|
5976
6888
|
}
|
|
5977
6889
|
const powerVal = root.querySelector(".myio-ho-card__footer .metric:nth-child(2) .val");
|
|
5978
6890
|
if (powerVal) {
|
|
5979
6891
|
if (entityObject.domain === "water") {
|
|
5980
6892
|
const pulses = entityObject.pulses ?? 0;
|
|
5981
6893
|
powerVal.textContent = `${pulses} L`;
|
|
6894
|
+
} else if (entityObject.domain === "temperature") {
|
|
6895
|
+
powerVal.textContent = entityObject.lastActivityTime ? formatRelativeTime2(entityObject.lastActivityTime) : "-";
|
|
5982
6896
|
} else {
|
|
5983
6897
|
const instantPower = entityObject.instantaneousPower ?? entityObject.consumption_power ?? null;
|
|
5984
6898
|
const powerFormatted = formatPower(instantPower);
|
|
@@ -6056,12 +6970,46 @@
|
|
|
6056
6970
|
MyIOSelectionStore2.on("selection:change", onSelectionChange);
|
|
6057
6971
|
root._selectionListener = onSelectionChange;
|
|
6058
6972
|
}
|
|
6973
|
+
if (entityObject.domain === "temperature") {
|
|
6974
|
+
const showTooltip = (e) => {
|
|
6975
|
+
TempRangeTooltip.show(root, state.entityObject, e);
|
|
6976
|
+
};
|
|
6977
|
+
const hideTooltip = () => {
|
|
6978
|
+
TempRangeTooltip.hide();
|
|
6979
|
+
};
|
|
6980
|
+
root.addEventListener("mouseenter", showTooltip);
|
|
6981
|
+
root.addEventListener("mouseleave", hideTooltip);
|
|
6982
|
+
root._tempTooltipShowFn = showTooltip;
|
|
6983
|
+
root._tempTooltipHideFn = hideTooltip;
|
|
6984
|
+
}
|
|
6985
|
+
if (entityObject.domain === "energy") {
|
|
6986
|
+
const showEnergyTooltip = (e) => {
|
|
6987
|
+
EnergyRangeTooltip.show(root, state.entityObject, e);
|
|
6988
|
+
};
|
|
6989
|
+
const hideEnergyTooltip = () => {
|
|
6990
|
+
EnergyRangeTooltip.hide();
|
|
6991
|
+
};
|
|
6992
|
+
root.addEventListener("mouseenter", showEnergyTooltip);
|
|
6993
|
+
root.addEventListener("mouseleave", hideEnergyTooltip);
|
|
6994
|
+
root._energyTooltipShowFn = showEnergyTooltip;
|
|
6995
|
+
root._energyTooltipHideFn = hideEnergyTooltip;
|
|
6996
|
+
}
|
|
6059
6997
|
root._cleanup = () => {
|
|
6060
6998
|
document.removeEventListener("click", closeMenu);
|
|
6061
6999
|
document.removeEventListener("keydown", closeMenu);
|
|
6062
7000
|
if (MyIOSelectionStore2 && root._selectionListener) {
|
|
6063
7001
|
MyIOSelectionStore2.off("selection:change", root._selectionListener);
|
|
6064
7002
|
}
|
|
7003
|
+
if (root._tempTooltipShowFn) {
|
|
7004
|
+
root.removeEventListener("mouseenter", root._tempTooltipShowFn);
|
|
7005
|
+
root.removeEventListener("mouseleave", root._tempTooltipHideFn);
|
|
7006
|
+
TempRangeTooltip.hide();
|
|
7007
|
+
}
|
|
7008
|
+
if (root._energyTooltipShowFn) {
|
|
7009
|
+
root.removeEventListener("mouseenter", root._energyTooltipShowFn);
|
|
7010
|
+
root.removeEventListener("mouseleave", root._energyTooltipHideFn);
|
|
7011
|
+
EnergyRangeTooltip.hide();
|
|
7012
|
+
}
|
|
6065
7013
|
};
|
|
6066
7014
|
const checkbox = root.querySelector('.myio-ho-card__select input[type="checkbox"]');
|
|
6067
7015
|
if (checkbox && callbacks.handleSelect) {
|