myio-js-library 0.1.143 → 0.1.145
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 +142 -48
- package/dist/index.d.cts +1 -0
- package/dist/index.js +142 -48
- package/dist/myio-js-library.umd.js +142 -48
- package/dist/myio-js-library.umd.min.js +1 -1
- package/package.json +1 -1
|
@@ -4701,6 +4701,12 @@
|
|
|
4701
4701
|
function getIconSvg(deviceType) {
|
|
4702
4702
|
return ICON_MAP[deviceType] || ICON_MAP.DEFAULT;
|
|
4703
4703
|
}
|
|
4704
|
+
function formatValueByDomain(value, domain) {
|
|
4705
|
+
if (domain === "water") {
|
|
4706
|
+
return formatWaterVolumeM3(value);
|
|
4707
|
+
}
|
|
4708
|
+
return formatEnergy(value);
|
|
4709
|
+
}
|
|
4704
4710
|
function formatUpdateDate(timeVal) {
|
|
4705
4711
|
let telemetryTimeFormatted = "N/A";
|
|
4706
4712
|
let timeSinceLastTelemetry = "";
|
|
@@ -4949,7 +4955,7 @@
|
|
|
4949
4955
|
const chip = root.querySelector(".chip");
|
|
4950
4956
|
chip.className = `chip ${statusInfo.chipClass}`;
|
|
4951
4957
|
chip.textContent = statusInfo.label;
|
|
4952
|
-
const primaryValue =
|
|
4958
|
+
const primaryValue = formatValueByDomain(entityObject.val, entityObject.domain);
|
|
4953
4959
|
const numSpan = root.querySelector(".myio-ho-card__value .num");
|
|
4954
4960
|
root.querySelector(".myio-ho-card__value .unit");
|
|
4955
4961
|
numSpan.textContent = primaryValue;
|
|
@@ -15113,7 +15119,13 @@ ${rangeText}`;
|
|
|
15113
15119
|
render(initialData) {
|
|
15114
15120
|
this.originalActiveElement = document.activeElement;
|
|
15115
15121
|
document.body.appendChild(this.container);
|
|
15116
|
-
|
|
15122
|
+
let formData = { ...initialData };
|
|
15123
|
+
if (initialData.deviceMapInstaneousPower && typeof initialData.deviceMapInstaneousPower === "object") {
|
|
15124
|
+
console.log("[SettingsModalView] Configura\xE7\xE3o salva encontrada (Device Scope). Processando...");
|
|
15125
|
+
const flatLimits = this.parseDeviceSavedLimits(initialData.deviceMapInstaneousPower);
|
|
15126
|
+
formData = { ...formData, ...flatLimits };
|
|
15127
|
+
}
|
|
15128
|
+
this.populateForm(formData);
|
|
15117
15129
|
this.attachEventListeners();
|
|
15118
15130
|
this.setupAccessibility();
|
|
15119
15131
|
this.setupFocusTrap();
|
|
@@ -16682,6 +16694,42 @@ ${rangeText}`;
|
|
|
16682
16694
|
}
|
|
16683
16695
|
}
|
|
16684
16696
|
}
|
|
16697
|
+
/**
|
|
16698
|
+
* Helper: Traduz o JSON RFC-0086 (deviceMapInstaneousPower)
|
|
16699
|
+
* para os campos planos do formulário (ex: standbyLimitUpConsumption)
|
|
16700
|
+
*/
|
|
16701
|
+
parseDeviceSavedLimits(deviceJson) {
|
|
16702
|
+
const extracted = {};
|
|
16703
|
+
try {
|
|
16704
|
+
if (!deviceJson || !deviceJson.limitsByInstantaneoustPowerType) return extracted;
|
|
16705
|
+
const consumptionGroup = deviceJson.limitsByInstantaneoustPowerType.find(
|
|
16706
|
+
(g) => g.telemetryType === "consumption"
|
|
16707
|
+
);
|
|
16708
|
+
const deviceItem = consumptionGroup?.itemsByDeviceType?.[0];
|
|
16709
|
+
if (!deviceItem?.limitsByDeviceStatus) return extracted;
|
|
16710
|
+
const mapPrefix = {
|
|
16711
|
+
"standBy": "standby",
|
|
16712
|
+
"normal": "normal",
|
|
16713
|
+
"alert": "alert",
|
|
16714
|
+
"failure": "failure"
|
|
16715
|
+
};
|
|
16716
|
+
deviceItem.limitsByDeviceStatus.forEach((status) => {
|
|
16717
|
+
const prefix = mapPrefix[status.deviceStatusName];
|
|
16718
|
+
if (prefix && status.limitsValues) {
|
|
16719
|
+
const { baseValue, topValue } = status.limitsValues;
|
|
16720
|
+
if (baseValue !== null && baseValue !== void 0) {
|
|
16721
|
+
extracted[`${prefix}LimitDownConsumption`] = baseValue;
|
|
16722
|
+
}
|
|
16723
|
+
if (topValue !== null && topValue !== void 0) {
|
|
16724
|
+
extracted[`${prefix}LimitUpConsumption`] = topValue;
|
|
16725
|
+
}
|
|
16726
|
+
}
|
|
16727
|
+
});
|
|
16728
|
+
} catch (e) {
|
|
16729
|
+
console.warn("[SettingsModalView] Erro ao processar deviceMapInstaneousPower:", e);
|
|
16730
|
+
}
|
|
16731
|
+
return extracted;
|
|
16732
|
+
}
|
|
16685
16733
|
attachEventListeners() {
|
|
16686
16734
|
this.form.addEventListener("submit", (event) => {
|
|
16687
16735
|
event.preventDefault();
|
|
@@ -16953,11 +17001,25 @@ ${rangeText}`;
|
|
|
16953
17001
|
}
|
|
16954
17002
|
async saveServerScopeAttributes(deviceId, attributes) {
|
|
16955
17003
|
try {
|
|
16956
|
-
const
|
|
16957
|
-
const
|
|
16958
|
-
|
|
16959
|
-
|
|
16960
|
-
|
|
17004
|
+
const payload = { ...attributes };
|
|
17005
|
+
const effectiveDeviceType = this.getEffectiveDeviceType();
|
|
17006
|
+
const deviceJson = this.buildDevicePowerJson(payload, effectiveDeviceType);
|
|
17007
|
+
if (deviceJson) {
|
|
17008
|
+
payload.deviceMapInstaneousPower = deviceJson;
|
|
17009
|
+
}
|
|
17010
|
+
const flatKeysToRemove = [
|
|
17011
|
+
"telemetryType",
|
|
17012
|
+
"standbyLimitDownConsumption",
|
|
17013
|
+
"standbyLimitUpConsumption",
|
|
17014
|
+
"normalLimitDownConsumption",
|
|
17015
|
+
"normalLimitUpConsumption",
|
|
17016
|
+
"alertLimitDownConsumption",
|
|
17017
|
+
"alertLimitUpConsumption",
|
|
17018
|
+
"failureLimitDownConsumption",
|
|
17019
|
+
"failureLimitUpConsumption"
|
|
17020
|
+
];
|
|
17021
|
+
flatKeysToRemove.forEach((key) => delete payload[key]);
|
|
17022
|
+
console.log("[SettingsPersister] Saving Server Scope Attributes:", payload);
|
|
16961
17023
|
const res = await fetch(
|
|
16962
17024
|
`${this.tbBaseUrl}/api/plugins/telemetry/DEVICE/${deviceId}/attributes/SERVER_SCOPE`,
|
|
16963
17025
|
{
|
|
@@ -16974,13 +17036,70 @@ ${rangeText}`;
|
|
|
16974
17036
|
}
|
|
16975
17037
|
return {
|
|
16976
17038
|
ok: true,
|
|
16977
|
-
updatedKeys:
|
|
17039
|
+
updatedKeys: Object.keys(payload)
|
|
16978
17040
|
};
|
|
16979
17041
|
} catch (error) {
|
|
16980
17042
|
console.error("[SettingsPersister] Attributes save failed:", error);
|
|
16981
17043
|
return { ok: false, error: this.mapError(error) };
|
|
16982
17044
|
}
|
|
16983
17045
|
}
|
|
17046
|
+
/**
|
|
17047
|
+
* Constrói o JSON Reduzido (apenas o deviceType atual) para salvar no Device.
|
|
17048
|
+
* Retorna null se nenhum campo de potência estiver presente.
|
|
17049
|
+
*/
|
|
17050
|
+
buildDevicePowerJson(formData, deviceType) {
|
|
17051
|
+
const statuses = ["standby", "normal", "alert", "failure"];
|
|
17052
|
+
const hasPowerData = statuses.some(
|
|
17053
|
+
(status) => formData[`${status}LimitDownConsumption`] !== void 0 && formData[`${status}LimitDownConsumption`] !== "" || formData[`${status}LimitUpConsumption`] !== void 0 && formData[`${status}LimitUpConsumption`] !== ""
|
|
17054
|
+
);
|
|
17055
|
+
if (!hasPowerData) return null;
|
|
17056
|
+
const statusMap = {
|
|
17057
|
+
"standby": "standBy",
|
|
17058
|
+
"normal": "normal",
|
|
17059
|
+
"alert": "alert",
|
|
17060
|
+
"failure": "failure"
|
|
17061
|
+
};
|
|
17062
|
+
const limitsList = [];
|
|
17063
|
+
statuses.forEach((statusKey) => {
|
|
17064
|
+
const down = formData[`${statusKey}LimitDownConsumption`];
|
|
17065
|
+
const up = formData[`${statusKey}LimitUpConsumption`];
|
|
17066
|
+
if (down !== void 0 && down !== "" || up !== void 0 && up !== "") {
|
|
17067
|
+
limitsList.push({
|
|
17068
|
+
deviceStatusName: statusMap[statusKey],
|
|
17069
|
+
limitsValues: {
|
|
17070
|
+
// Converte para Number ou null
|
|
17071
|
+
baseValue: down !== "" && down !== void 0 ? Number(down) : null,
|
|
17072
|
+
topValue: up !== "" && up !== void 0 ? Number(up) : null
|
|
17073
|
+
}
|
|
17074
|
+
});
|
|
17075
|
+
}
|
|
17076
|
+
});
|
|
17077
|
+
if (limitsList.length === 0) return null;
|
|
17078
|
+
return {
|
|
17079
|
+
version: "1.0.0",
|
|
17080
|
+
limitsByInstantaneoustPowerType: [
|
|
17081
|
+
{
|
|
17082
|
+
telemetryType: "consumption",
|
|
17083
|
+
itemsByDeviceType: [
|
|
17084
|
+
{
|
|
17085
|
+
deviceType,
|
|
17086
|
+
// Gera um nome descritivo interno
|
|
17087
|
+
name: `deviceMapInstaneousPower${this.formatDeviceTypeName(deviceType)}`,
|
|
17088
|
+
description: "Override manual configurado via Dashboard",
|
|
17089
|
+
limitsByDeviceStatus: limitsList
|
|
17090
|
+
}
|
|
17091
|
+
]
|
|
17092
|
+
}
|
|
17093
|
+
]
|
|
17094
|
+
};
|
|
17095
|
+
}
|
|
17096
|
+
/**
|
|
17097
|
+
* Helper para formatar o nome do tipo (PascalCase) para uso no campo "name" do JSON
|
|
17098
|
+
*/
|
|
17099
|
+
formatDeviceTypeName(deviceType) {
|
|
17100
|
+
if (!deviceType) return "";
|
|
17101
|
+
return deviceType.charAt(0).toUpperCase() + deviceType.slice(1).toLowerCase();
|
|
17102
|
+
}
|
|
16984
17103
|
/**
|
|
16985
17104
|
* RFC-0086: Build mapInstantaneousPower JSON structure from form data
|
|
16986
17105
|
* IMPORTANT: When saving to a DEVICE, only include entries for the specific deviceType
|
|
@@ -17037,25 +17156,6 @@ ${rangeText}`;
|
|
|
17037
17156
|
console.log(`[SettingsPersister] RFC-0086: Built mapInstantaneousPower for deviceType=${effectiveDeviceType}:`, result);
|
|
17038
17157
|
return result;
|
|
17039
17158
|
}
|
|
17040
|
-
/**
|
|
17041
|
-
* Format device type name for display (e.g., ELEVADOR -> Elevador)
|
|
17042
|
-
*/
|
|
17043
|
-
formatDeviceTypeName(deviceType) {
|
|
17044
|
-
const map = {
|
|
17045
|
-
"ELEVADOR": "Elevator",
|
|
17046
|
-
"ESCADA_ROLANTE": "Escalator",
|
|
17047
|
-
"MOTOR": "Motor",
|
|
17048
|
-
"BOMBA": "Pump",
|
|
17049
|
-
"3F_MEDIDOR": "3FMedidor",
|
|
17050
|
-
"CHILLER": "Chiller",
|
|
17051
|
-
"FANCOIL": "Fancoil",
|
|
17052
|
-
"AR_CONDICIONADO": "AirConditioner",
|
|
17053
|
-
"HVAC": "HVAC",
|
|
17054
|
-
"HIDROMETRO": "Hidrometro",
|
|
17055
|
-
"TERMOSTATO": "Termostato"
|
|
17056
|
-
};
|
|
17057
|
-
return map[deviceType] || deviceType;
|
|
17058
|
-
}
|
|
17059
17159
|
sanitizeLabel(label) {
|
|
17060
17160
|
return label.trim().slice(0, 255).replace(/[\x00-\x1F\x7F]/g, "");
|
|
17061
17161
|
}
|
|
@@ -17192,18 +17292,16 @@ ${rangeText}`;
|
|
|
17192
17292
|
}
|
|
17193
17293
|
const attributesArray = await response.json();
|
|
17194
17294
|
const attributes = {};
|
|
17195
|
-
const settingsNamespace = "myio.settings.energy.";
|
|
17196
17295
|
for (const attr of attributesArray) {
|
|
17197
17296
|
if (attr.key && attr.value !== void 0 && attr.value !== null && attr.value !== "") {
|
|
17198
|
-
if (attr.key
|
|
17199
|
-
const key = attr.key.replace(settingsNamespace, "");
|
|
17200
|
-
if (key !== "__version") {
|
|
17201
|
-
attributes[key] = attr.value;
|
|
17202
|
-
}
|
|
17203
|
-
} else if (attr.key === "floor") {
|
|
17297
|
+
if (attr.key === "floor") {
|
|
17204
17298
|
attributes.floor = attr.value;
|
|
17205
17299
|
} else if (attr.key === "identifier") {
|
|
17206
17300
|
attributes.identifier = attr.value;
|
|
17301
|
+
} else if (attr.key === "mapInstantaneousPower") {
|
|
17302
|
+
attributes.mapInstantaneousPower = attr.value;
|
|
17303
|
+
} else if (attr.key === "deviceMapInstaneousPower") {
|
|
17304
|
+
attributes.deviceMapInstaneousPower = attr.value;
|
|
17207
17305
|
}
|
|
17208
17306
|
}
|
|
17209
17307
|
}
|
|
@@ -17225,23 +17323,12 @@ ${rangeText}`;
|
|
|
17225
17323
|
}
|
|
17226
17324
|
return merged;
|
|
17227
17325
|
}
|
|
17228
|
-
/**
|
|
17229
|
-
* Utility method to validate and sanitize fetched data
|
|
17230
|
-
*/
|
|
17231
17326
|
static sanitizeFetchedData(data) {
|
|
17232
17327
|
const sanitized = {};
|
|
17233
17328
|
const stringFields = [
|
|
17234
17329
|
"label",
|
|
17235
17330
|
"floor",
|
|
17236
|
-
"identifier"
|
|
17237
|
-
"alertLimitDownConsumption",
|
|
17238
|
-
"alertLimitUpConsumption",
|
|
17239
|
-
"failureLimitDownConsumption",
|
|
17240
|
-
"failureLimitUpConsumption",
|
|
17241
|
-
"normalLimitDownConsumption",
|
|
17242
|
-
"normalLimitUpConsumption",
|
|
17243
|
-
"standbyLimitDownConsumption",
|
|
17244
|
-
"standbyLimitUpConsumption"
|
|
17331
|
+
"identifier"
|
|
17245
17332
|
];
|
|
17246
17333
|
for (const field of stringFields) {
|
|
17247
17334
|
if (data[field] && typeof data[field] === "string") {
|
|
@@ -17257,6 +17344,12 @@ ${rangeText}`;
|
|
|
17257
17344
|
}
|
|
17258
17345
|
}
|
|
17259
17346
|
}
|
|
17347
|
+
const objectFields = ["mapInstantaneousPower", "deviceMapInstaneousPower"];
|
|
17348
|
+
for (const field of objectFields) {
|
|
17349
|
+
if (data[field] && typeof data[field] === "object") {
|
|
17350
|
+
sanitized[field] = data[field];
|
|
17351
|
+
}
|
|
17352
|
+
}
|
|
17260
17353
|
return sanitized;
|
|
17261
17354
|
}
|
|
17262
17355
|
};
|
|
@@ -17306,8 +17399,9 @@ ${rangeText}`;
|
|
|
17306
17399
|
// Pass connection info for display
|
|
17307
17400
|
onSave: this.handleSave.bind(this),
|
|
17308
17401
|
onClose: this.handleClose.bind(this),
|
|
17309
|
-
mapInstantaneousPower: params.mapInstantaneousPower
|
|
17310
|
-
// RFC-0077: Pass instantaneous power map for Power Limits feature
|
|
17402
|
+
mapInstantaneousPower: params.mapInstantaneousPower,
|
|
17403
|
+
// RFC-0077: Pass instantaneous power map for Power Limits feature,
|
|
17404
|
+
deviceMapInstaneousPower: params.deviceMapInstaneousPower
|
|
17311
17405
|
});
|
|
17312
17406
|
}
|
|
17313
17407
|
async show() {
|