edilkamin 1.10.0 → 1.10.1
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/cjs/package.json +1 -1
- package/dist/cjs/src/cli.js +105 -0
- package/dist/cjs/src/index.d.ts +2 -1
- package/dist/cjs/src/index.js +4 -1
- package/dist/cjs/src/library.d.ts +10 -1
- package/dist/cjs/src/library.js +199 -0
- package/dist/cjs/src/library.test.js +223 -0
- package/dist/cjs/src/types.d.ts +127 -1
- package/dist/cjs/src/types.js +64 -0
- package/dist/esm/package.json +1 -1
- package/dist/esm/src/cli.js +105 -0
- package/dist/esm/src/index.d.ts +2 -1
- package/dist/esm/src/index.js +1 -0
- package/dist/esm/src/library.d.ts +10 -1
- package/dist/esm/src/library.js +199 -0
- package/dist/esm/src/library.test.js +223 -0
- package/dist/esm/src/types.d.ts +127 -1
- package/dist/esm/src/types.js +63 -1
- package/package.json +1 -1
- package/src/cli.ts +156 -0
- package/src/index.ts +10 -0
- package/src/library.test.ts +290 -0
- package/src/library.ts +258 -0
- package/src/types.ts +180 -0
package/src/library.test.ts
CHANGED
|
@@ -242,6 +242,17 @@ describe("library", () => {
|
|
|
242
242
|
"getLanguage",
|
|
243
243
|
"getPelletInReserve",
|
|
244
244
|
"getPelletAutonomyTime",
|
|
245
|
+
// Statistics getters
|
|
246
|
+
"getTotalCounters",
|
|
247
|
+
"getServiceCounters",
|
|
248
|
+
"getAlarmHistory",
|
|
249
|
+
"getRegenerationData",
|
|
250
|
+
"getServiceTime",
|
|
251
|
+
// Analytics functions
|
|
252
|
+
"getTotalOperatingHours",
|
|
253
|
+
"getPowerDistribution",
|
|
254
|
+
"getServiceStatus",
|
|
255
|
+
"getUsageAnalytics",
|
|
245
256
|
];
|
|
246
257
|
it("should create API methods with the correct baseURL", async () => {
|
|
247
258
|
const baseURL = "https://example.com/api/";
|
|
@@ -1017,6 +1028,285 @@ describe("library", () => {
|
|
|
1017
1028
|
});
|
|
1018
1029
|
});
|
|
1019
1030
|
|
|
1031
|
+
describe("statistics getters", () => {
|
|
1032
|
+
const mockDeviceInfoWithStats = {
|
|
1033
|
+
status: {
|
|
1034
|
+
commands: { power: true },
|
|
1035
|
+
temperatures: { board: 25, enviroment: 20 },
|
|
1036
|
+
flags: { is_pellet_in_reserve: false },
|
|
1037
|
+
pellet: { autonomy_time: 900 },
|
|
1038
|
+
counters: { service_time: 1108 },
|
|
1039
|
+
},
|
|
1040
|
+
nvm: {
|
|
1041
|
+
user_parameters: {
|
|
1042
|
+
language: 1,
|
|
1043
|
+
is_auto: false,
|
|
1044
|
+
is_fahrenheit: false,
|
|
1045
|
+
is_sound_active: false,
|
|
1046
|
+
enviroment_1_temperature: 19,
|
|
1047
|
+
enviroment_2_temperature: 20,
|
|
1048
|
+
enviroment_3_temperature: 20,
|
|
1049
|
+
manual_power: 1,
|
|
1050
|
+
fan_1_ventilation: 3,
|
|
1051
|
+
fan_2_ventilation: 0,
|
|
1052
|
+
fan_3_ventilation: 0,
|
|
1053
|
+
is_standby_active: false,
|
|
1054
|
+
standby_waiting_time: 60,
|
|
1055
|
+
},
|
|
1056
|
+
total_counters: {
|
|
1057
|
+
power_ons: 278,
|
|
1058
|
+
p1_working_time: 833,
|
|
1059
|
+
p2_working_time: 15,
|
|
1060
|
+
p3_working_time: 19,
|
|
1061
|
+
p4_working_time: 8,
|
|
1062
|
+
p5_working_time: 17,
|
|
1063
|
+
},
|
|
1064
|
+
service_counters: {
|
|
1065
|
+
p1_working_time: 100,
|
|
1066
|
+
p2_working_time: 10,
|
|
1067
|
+
p3_working_time: 5,
|
|
1068
|
+
p4_working_time: 2,
|
|
1069
|
+
p5_working_time: 1,
|
|
1070
|
+
},
|
|
1071
|
+
alarms_log: {
|
|
1072
|
+
number: 2,
|
|
1073
|
+
index: 2,
|
|
1074
|
+
alarms: [
|
|
1075
|
+
{ type: 3, timestamp: 1700000000 },
|
|
1076
|
+
{ type: 21, timestamp: 1700001000 },
|
|
1077
|
+
],
|
|
1078
|
+
},
|
|
1079
|
+
regeneration: {
|
|
1080
|
+
time: 0,
|
|
1081
|
+
last_intervention: 1577836800,
|
|
1082
|
+
daylight_time_flag: 0,
|
|
1083
|
+
blackout_counter: 43,
|
|
1084
|
+
airkare_working_hours_counter: 0,
|
|
1085
|
+
},
|
|
1086
|
+
},
|
|
1087
|
+
};
|
|
1088
|
+
|
|
1089
|
+
it("should get total counters", async () => {
|
|
1090
|
+
fetchStub.resolves(mockResponse(mockDeviceInfoWithStats));
|
|
1091
|
+
const api = configure(API_URL);
|
|
1092
|
+
const result = await api.getTotalCounters(
|
|
1093
|
+
expectedToken,
|
|
1094
|
+
"00:11:22:33:44:55",
|
|
1095
|
+
);
|
|
1096
|
+
assert.deepEqual(result, mockDeviceInfoWithStats.nvm.total_counters);
|
|
1097
|
+
});
|
|
1098
|
+
|
|
1099
|
+
it("should get service counters", async () => {
|
|
1100
|
+
fetchStub.resolves(mockResponse(mockDeviceInfoWithStats));
|
|
1101
|
+
const api = configure(API_URL);
|
|
1102
|
+
const result = await api.getServiceCounters(
|
|
1103
|
+
expectedToken,
|
|
1104
|
+
"00:11:22:33:44:55",
|
|
1105
|
+
);
|
|
1106
|
+
assert.deepEqual(result, mockDeviceInfoWithStats.nvm.service_counters);
|
|
1107
|
+
});
|
|
1108
|
+
|
|
1109
|
+
it("should get alarm history", async () => {
|
|
1110
|
+
fetchStub.resolves(mockResponse(mockDeviceInfoWithStats));
|
|
1111
|
+
const api = configure(API_URL);
|
|
1112
|
+
const result = await api.getAlarmHistory(
|
|
1113
|
+
expectedToken,
|
|
1114
|
+
"00:11:22:33:44:55",
|
|
1115
|
+
);
|
|
1116
|
+
assert.deepEqual(result, mockDeviceInfoWithStats.nvm.alarms_log);
|
|
1117
|
+
});
|
|
1118
|
+
|
|
1119
|
+
it("should get regeneration data", async () => {
|
|
1120
|
+
fetchStub.resolves(mockResponse(mockDeviceInfoWithStats));
|
|
1121
|
+
const api = configure(API_URL);
|
|
1122
|
+
const result = await api.getRegenerationData(
|
|
1123
|
+
expectedToken,
|
|
1124
|
+
"00:11:22:33:44:55",
|
|
1125
|
+
);
|
|
1126
|
+
assert.deepEqual(result, mockDeviceInfoWithStats.nvm.regeneration);
|
|
1127
|
+
});
|
|
1128
|
+
|
|
1129
|
+
it("should get service time", async () => {
|
|
1130
|
+
fetchStub.resolves(mockResponse(mockDeviceInfoWithStats));
|
|
1131
|
+
const api = configure(API_URL);
|
|
1132
|
+
const result = await api.getServiceTime(
|
|
1133
|
+
expectedToken,
|
|
1134
|
+
"00:11:22:33:44:55",
|
|
1135
|
+
);
|
|
1136
|
+
assert.equal(result, 1108);
|
|
1137
|
+
});
|
|
1138
|
+
});
|
|
1139
|
+
|
|
1140
|
+
describe("analytics functions", () => {
|
|
1141
|
+
const mockDeviceInfoWithStats = {
|
|
1142
|
+
status: {
|
|
1143
|
+
commands: { power: true },
|
|
1144
|
+
temperatures: { board: 25, enviroment: 20 },
|
|
1145
|
+
flags: { is_pellet_in_reserve: false },
|
|
1146
|
+
pellet: { autonomy_time: 900 },
|
|
1147
|
+
counters: { service_time: 1108 },
|
|
1148
|
+
},
|
|
1149
|
+
nvm: {
|
|
1150
|
+
user_parameters: {
|
|
1151
|
+
language: 1,
|
|
1152
|
+
is_auto: false,
|
|
1153
|
+
is_fahrenheit: false,
|
|
1154
|
+
is_sound_active: false,
|
|
1155
|
+
enviroment_1_temperature: 19,
|
|
1156
|
+
enviroment_2_temperature: 20,
|
|
1157
|
+
enviroment_3_temperature: 20,
|
|
1158
|
+
manual_power: 1,
|
|
1159
|
+
fan_1_ventilation: 3,
|
|
1160
|
+
fan_2_ventilation: 0,
|
|
1161
|
+
fan_3_ventilation: 0,
|
|
1162
|
+
is_standby_active: false,
|
|
1163
|
+
standby_waiting_time: 60,
|
|
1164
|
+
},
|
|
1165
|
+
total_counters: {
|
|
1166
|
+
power_ons: 278,
|
|
1167
|
+
p1_working_time: 833,
|
|
1168
|
+
p2_working_time: 15,
|
|
1169
|
+
p3_working_time: 19,
|
|
1170
|
+
p4_working_time: 8,
|
|
1171
|
+
p5_working_time: 17,
|
|
1172
|
+
},
|
|
1173
|
+
service_counters: {
|
|
1174
|
+
p1_working_time: 100,
|
|
1175
|
+
p2_working_time: 10,
|
|
1176
|
+
p3_working_time: 5,
|
|
1177
|
+
p4_working_time: 2,
|
|
1178
|
+
p5_working_time: 1,
|
|
1179
|
+
},
|
|
1180
|
+
alarms_log: {
|
|
1181
|
+
number: 2,
|
|
1182
|
+
index: 2,
|
|
1183
|
+
alarms: [
|
|
1184
|
+
{ type: 3, timestamp: 1700000000 },
|
|
1185
|
+
{ type: 21, timestamp: 1700001000 },
|
|
1186
|
+
],
|
|
1187
|
+
},
|
|
1188
|
+
regeneration: {
|
|
1189
|
+
time: 0,
|
|
1190
|
+
last_intervention: 1577836800,
|
|
1191
|
+
daylight_time_flag: 0,
|
|
1192
|
+
blackout_counter: 43,
|
|
1193
|
+
airkare_working_hours_counter: 0,
|
|
1194
|
+
},
|
|
1195
|
+
},
|
|
1196
|
+
};
|
|
1197
|
+
|
|
1198
|
+
it("should calculate total operating hours", async () => {
|
|
1199
|
+
fetchStub.resolves(mockResponse(mockDeviceInfoWithStats));
|
|
1200
|
+
const api = configure(API_URL);
|
|
1201
|
+
const result = await api.getTotalOperatingHours(
|
|
1202
|
+
expectedToken,
|
|
1203
|
+
"00:11:22:33:44:55",
|
|
1204
|
+
);
|
|
1205
|
+
// 833 + 15 + 19 + 8 + 17 = 892
|
|
1206
|
+
assert.equal(result, 892);
|
|
1207
|
+
});
|
|
1208
|
+
|
|
1209
|
+
it("should calculate power distribution percentages", async () => {
|
|
1210
|
+
fetchStub.resolves(mockResponse(mockDeviceInfoWithStats));
|
|
1211
|
+
const api = configure(API_URL);
|
|
1212
|
+
const result = await api.getPowerDistribution(
|
|
1213
|
+
expectedToken,
|
|
1214
|
+
"00:11:22:33:44:55",
|
|
1215
|
+
);
|
|
1216
|
+
// Total: 892 hours
|
|
1217
|
+
assert.ok(result.p1 > 90); // 833/892 = 93.4%
|
|
1218
|
+
assert.ok(result.p2 < 5); // 15/892 = 1.7%
|
|
1219
|
+
// Sum should be ~100%
|
|
1220
|
+
const sum = result.p1 + result.p2 + result.p3 + result.p4 + result.p5;
|
|
1221
|
+
assert.ok(Math.abs(sum - 100) < 0.1);
|
|
1222
|
+
});
|
|
1223
|
+
|
|
1224
|
+
it("should handle zero operating hours in power distribution", async () => {
|
|
1225
|
+
const zeroHoursInfo = {
|
|
1226
|
+
...mockDeviceInfoWithStats,
|
|
1227
|
+
nvm: {
|
|
1228
|
+
...mockDeviceInfoWithStats.nvm,
|
|
1229
|
+
total_counters: {
|
|
1230
|
+
power_ons: 0,
|
|
1231
|
+
p1_working_time: 0,
|
|
1232
|
+
p2_working_time: 0,
|
|
1233
|
+
p3_working_time: 0,
|
|
1234
|
+
p4_working_time: 0,
|
|
1235
|
+
p5_working_time: 0,
|
|
1236
|
+
},
|
|
1237
|
+
},
|
|
1238
|
+
};
|
|
1239
|
+
fetchStub.resolves(mockResponse(zeroHoursInfo));
|
|
1240
|
+
const api = configure(API_URL);
|
|
1241
|
+
const result = await api.getPowerDistribution(
|
|
1242
|
+
expectedToken,
|
|
1243
|
+
"00:11:22:33:44:55",
|
|
1244
|
+
);
|
|
1245
|
+
assert.deepEqual(result, { p1: 0, p2: 0, p3: 0, p4: 0, p5: 0 });
|
|
1246
|
+
});
|
|
1247
|
+
|
|
1248
|
+
it("should calculate service status", async () => {
|
|
1249
|
+
fetchStub.resolves(mockResponse(mockDeviceInfoWithStats));
|
|
1250
|
+
const api = configure(API_URL);
|
|
1251
|
+
const result = await api.getServiceStatus(
|
|
1252
|
+
expectedToken,
|
|
1253
|
+
"00:11:22:33:44:55",
|
|
1254
|
+
);
|
|
1255
|
+
assert.equal(result.totalServiceHours, 1108);
|
|
1256
|
+
// 100 + 10 + 5 + 2 + 1 = 118 hours since service
|
|
1257
|
+
assert.equal(result.hoursSinceService, 118);
|
|
1258
|
+
assert.equal(result.isServiceDue, false); // 118 < 2000
|
|
1259
|
+
});
|
|
1260
|
+
|
|
1261
|
+
it("should indicate service is due when threshold exceeded", async () => {
|
|
1262
|
+
fetchStub.resolves(mockResponse(mockDeviceInfoWithStats));
|
|
1263
|
+
const api = configure(API_URL);
|
|
1264
|
+
// Use threshold of 100 hours
|
|
1265
|
+
const result = await api.getServiceStatus(
|
|
1266
|
+
expectedToken,
|
|
1267
|
+
"00:11:22:33:44:55",
|
|
1268
|
+
100,
|
|
1269
|
+
);
|
|
1270
|
+
assert.equal(result.isServiceDue, true); // 118 >= 100
|
|
1271
|
+
});
|
|
1272
|
+
|
|
1273
|
+
it("should get comprehensive usage analytics", async () => {
|
|
1274
|
+
fetchStub.resolves(mockResponse(mockDeviceInfoWithStats));
|
|
1275
|
+
const api = configure(API_URL);
|
|
1276
|
+
const result = await api.getUsageAnalytics(
|
|
1277
|
+
expectedToken,
|
|
1278
|
+
"00:11:22:33:44:55",
|
|
1279
|
+
);
|
|
1280
|
+
|
|
1281
|
+
assert.equal(result.totalPowerOns, 278);
|
|
1282
|
+
assert.equal(result.totalOperatingHours, 892);
|
|
1283
|
+
assert.equal(result.blackoutCount, 43);
|
|
1284
|
+
assert.equal(result.alarmCount, 2);
|
|
1285
|
+
assert.ok(result.lastMaintenanceDate instanceof Date);
|
|
1286
|
+
assert.equal(result.serviceStatus.isServiceDue, false);
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1289
|
+
it("should handle null lastMaintenanceDate when timestamp is 0", async () => {
|
|
1290
|
+
const noMaintenanceInfo = {
|
|
1291
|
+
...mockDeviceInfoWithStats,
|
|
1292
|
+
nvm: {
|
|
1293
|
+
...mockDeviceInfoWithStats.nvm,
|
|
1294
|
+
regeneration: {
|
|
1295
|
+
...mockDeviceInfoWithStats.nvm.regeneration,
|
|
1296
|
+
last_intervention: 0,
|
|
1297
|
+
},
|
|
1298
|
+
},
|
|
1299
|
+
};
|
|
1300
|
+
fetchStub.resolves(mockResponse(noMaintenanceInfo));
|
|
1301
|
+
const api = configure(API_URL);
|
|
1302
|
+
const result = await api.getUsageAnalytics(
|
|
1303
|
+
expectedToken,
|
|
1304
|
+
"00:11:22:33:44:55",
|
|
1305
|
+
);
|
|
1306
|
+
assert.equal(result.lastMaintenanceDate, null);
|
|
1307
|
+
});
|
|
1308
|
+
});
|
|
1309
|
+
|
|
1020
1310
|
describe("Error Handling", () => {
|
|
1021
1311
|
const errorTests = [
|
|
1022
1312
|
{ status: 400, statusText: "Bad Request" },
|
package/src/library.ts
CHANGED
|
@@ -6,11 +6,18 @@ import { cognitoUserPoolsTokenProvider } from "aws-amplify/auth/cognito";
|
|
|
6
6
|
import { processResponse } from "./buffer-utils";
|
|
7
7
|
import { API_URL } from "./constants";
|
|
8
8
|
import {
|
|
9
|
+
AlarmsLogType,
|
|
9
10
|
DeviceAssociationBody,
|
|
10
11
|
DeviceAssociationResponse,
|
|
11
12
|
DeviceInfoRawType,
|
|
12
13
|
DeviceInfoType,
|
|
13
14
|
EditDeviceAssociationBody,
|
|
15
|
+
PowerDistributionType,
|
|
16
|
+
RegenerationDataType,
|
|
17
|
+
ServiceCountersType,
|
|
18
|
+
ServiceStatusType,
|
|
19
|
+
TotalCountersType,
|
|
20
|
+
UsageAnalyticsType,
|
|
14
21
|
} from "./types";
|
|
15
22
|
|
|
16
23
|
/**
|
|
@@ -624,6 +631,246 @@ const getPelletAutonomyTime =
|
|
|
624
631
|
return info.status.pellet.autonomy_time;
|
|
625
632
|
};
|
|
626
633
|
|
|
634
|
+
const getTotalCounters =
|
|
635
|
+
(baseURL: string) =>
|
|
636
|
+
/**
|
|
637
|
+
* Retrieves lifetime operating counters.
|
|
638
|
+
* Includes power-on count and runtime hours per power level.
|
|
639
|
+
* These counters are never reset.
|
|
640
|
+
*
|
|
641
|
+
* @param {string} jwtToken - The JWT token for authentication.
|
|
642
|
+
* @param {string} macAddress - The MAC address of the device.
|
|
643
|
+
* @returns {Promise<TotalCountersType>} - Lifetime operating statistics.
|
|
644
|
+
*/
|
|
645
|
+
async (jwtToken: string, macAddress: string): Promise<TotalCountersType> => {
|
|
646
|
+
const info = await deviceInfo(baseURL)(jwtToken, macAddress);
|
|
647
|
+
return info.nvm.total_counters;
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
const getServiceCounters =
|
|
651
|
+
(baseURL: string) =>
|
|
652
|
+
/**
|
|
653
|
+
* Retrieves service counters (runtime since last maintenance).
|
|
654
|
+
* These counters track hours per power level since last service reset.
|
|
655
|
+
*
|
|
656
|
+
* @param {string} jwtToken - The JWT token for authentication.
|
|
657
|
+
* @param {string} macAddress - The MAC address of the device.
|
|
658
|
+
* @returns {Promise<ServiceCountersType>} - Service tracking statistics.
|
|
659
|
+
*/
|
|
660
|
+
async (
|
|
661
|
+
jwtToken: string,
|
|
662
|
+
macAddress: string,
|
|
663
|
+
): Promise<ServiceCountersType> => {
|
|
664
|
+
const info = await deviceInfo(baseURL)(jwtToken, macAddress);
|
|
665
|
+
return info.nvm.service_counters;
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
const getAlarmHistory =
|
|
669
|
+
(baseURL: string) =>
|
|
670
|
+
/**
|
|
671
|
+
* Retrieves the alarm history log.
|
|
672
|
+
* Contains a circular buffer of recent alarms with timestamps.
|
|
673
|
+
*
|
|
674
|
+
* @param {string} jwtToken - The JWT token for authentication.
|
|
675
|
+
* @param {string} macAddress - The MAC address of the device.
|
|
676
|
+
* @returns {Promise<AlarmsLogType>} - Alarm history log.
|
|
677
|
+
*/
|
|
678
|
+
async (jwtToken: string, macAddress: string): Promise<AlarmsLogType> => {
|
|
679
|
+
const info = await deviceInfo(baseURL)(jwtToken, macAddress);
|
|
680
|
+
return info.nvm.alarms_log;
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
const getRegenerationData =
|
|
684
|
+
(baseURL: string) =>
|
|
685
|
+
/**
|
|
686
|
+
* Retrieves regeneration and maintenance data.
|
|
687
|
+
* Includes blackout counter and last intervention timestamp.
|
|
688
|
+
*
|
|
689
|
+
* @param {string} jwtToken - The JWT token for authentication.
|
|
690
|
+
* @param {string} macAddress - The MAC address of the device.
|
|
691
|
+
* @returns {Promise<RegenerationDataType>} - Maintenance tracking data.
|
|
692
|
+
*/
|
|
693
|
+
async (
|
|
694
|
+
jwtToken: string,
|
|
695
|
+
macAddress: string,
|
|
696
|
+
): Promise<RegenerationDataType> => {
|
|
697
|
+
const info = await deviceInfo(baseURL)(jwtToken, macAddress);
|
|
698
|
+
return info.nvm.regeneration;
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
const getServiceTime =
|
|
702
|
+
(baseURL: string) =>
|
|
703
|
+
/**
|
|
704
|
+
* Retrieves the total service time in hours.
|
|
705
|
+
*
|
|
706
|
+
* @param {string} jwtToken - The JWT token for authentication.
|
|
707
|
+
* @param {string} macAddress - The MAC address of the device.
|
|
708
|
+
* @returns {Promise<number>} - Total service hours.
|
|
709
|
+
*/
|
|
710
|
+
async (jwtToken: string, macAddress: string): Promise<number> => {
|
|
711
|
+
const info = await deviceInfo(baseURL)(jwtToken, macAddress);
|
|
712
|
+
return info.status.counters.service_time;
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Default service threshold in hours (from OEM parameters).
|
|
717
|
+
* Most devices use 2000 hours.
|
|
718
|
+
*/
|
|
719
|
+
const DEFAULT_SERVICE_THRESHOLD = 2000;
|
|
720
|
+
|
|
721
|
+
const getTotalOperatingHours =
|
|
722
|
+
(baseURL: string) =>
|
|
723
|
+
/**
|
|
724
|
+
* Calculates total operating hours across all power levels.
|
|
725
|
+
*
|
|
726
|
+
* @param {string} jwtToken - The JWT token for authentication.
|
|
727
|
+
* @param {string} macAddress - The MAC address of the device.
|
|
728
|
+
* @returns {Promise<number>} - Total operating hours.
|
|
729
|
+
*/
|
|
730
|
+
async (jwtToken: string, macAddress: string): Promise<number> => {
|
|
731
|
+
const counters = await getTotalCounters(baseURL)(jwtToken, macAddress);
|
|
732
|
+
return (
|
|
733
|
+
counters.p1_working_time +
|
|
734
|
+
counters.p2_working_time +
|
|
735
|
+
counters.p3_working_time +
|
|
736
|
+
counters.p4_working_time +
|
|
737
|
+
counters.p5_working_time
|
|
738
|
+
);
|
|
739
|
+
};
|
|
740
|
+
|
|
741
|
+
const getPowerDistribution =
|
|
742
|
+
(baseURL: string) =>
|
|
743
|
+
/**
|
|
744
|
+
* Calculates power level usage distribution as percentages.
|
|
745
|
+
*
|
|
746
|
+
* @param {string} jwtToken - The JWT token for authentication.
|
|
747
|
+
* @param {string} macAddress - The MAC address of the device.
|
|
748
|
+
* @returns {Promise<PowerDistributionType>} - Percentage time at each power level.
|
|
749
|
+
*/
|
|
750
|
+
async (
|
|
751
|
+
jwtToken: string,
|
|
752
|
+
macAddress: string,
|
|
753
|
+
): Promise<PowerDistributionType> => {
|
|
754
|
+
const counters = await getTotalCounters(baseURL)(jwtToken, macAddress);
|
|
755
|
+
const total =
|
|
756
|
+
counters.p1_working_time +
|
|
757
|
+
counters.p2_working_time +
|
|
758
|
+
counters.p3_working_time +
|
|
759
|
+
counters.p4_working_time +
|
|
760
|
+
counters.p5_working_time;
|
|
761
|
+
|
|
762
|
+
if (total === 0) {
|
|
763
|
+
return { p1: 0, p2: 0, p3: 0, p4: 0, p5: 0 };
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
return {
|
|
767
|
+
p1: (counters.p1_working_time / total) * 100,
|
|
768
|
+
p2: (counters.p2_working_time / total) * 100,
|
|
769
|
+
p3: (counters.p3_working_time / total) * 100,
|
|
770
|
+
p4: (counters.p4_working_time / total) * 100,
|
|
771
|
+
p5: (counters.p5_working_time / total) * 100,
|
|
772
|
+
};
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
const getServiceStatus =
|
|
776
|
+
(baseURL: string) =>
|
|
777
|
+
/**
|
|
778
|
+
* Calculates service status including whether maintenance is due.
|
|
779
|
+
*
|
|
780
|
+
* @param {string} jwtToken - The JWT token for authentication.
|
|
781
|
+
* @param {string} macAddress - The MAC address of the device.
|
|
782
|
+
* @param {number} [thresholdHours=2000] - Service threshold in hours.
|
|
783
|
+
* @returns {Promise<ServiceStatusType>} - Service status with computed fields.
|
|
784
|
+
*/
|
|
785
|
+
async (
|
|
786
|
+
jwtToken: string,
|
|
787
|
+
macAddress: string,
|
|
788
|
+
thresholdHours: number = DEFAULT_SERVICE_THRESHOLD,
|
|
789
|
+
): Promise<ServiceStatusType> => {
|
|
790
|
+
const info = await deviceInfo(baseURL)(jwtToken, macAddress);
|
|
791
|
+
const serviceCounters = info.nvm.service_counters;
|
|
792
|
+
const hoursSinceService =
|
|
793
|
+
serviceCounters.p1_working_time +
|
|
794
|
+
serviceCounters.p2_working_time +
|
|
795
|
+
serviceCounters.p3_working_time +
|
|
796
|
+
serviceCounters.p4_working_time +
|
|
797
|
+
serviceCounters.p5_working_time;
|
|
798
|
+
|
|
799
|
+
return {
|
|
800
|
+
totalServiceHours: info.status.counters.service_time,
|
|
801
|
+
hoursSinceService,
|
|
802
|
+
serviceThresholdHours: thresholdHours,
|
|
803
|
+
isServiceDue: hoursSinceService >= thresholdHours,
|
|
804
|
+
};
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
const getUsageAnalytics =
|
|
808
|
+
(baseURL: string) =>
|
|
809
|
+
/**
|
|
810
|
+
* Retrieves comprehensive usage analytics in a single call.
|
|
811
|
+
* Combines multiple statistics into a unified analytics object.
|
|
812
|
+
*
|
|
813
|
+
* @param {string} jwtToken - The JWT token for authentication.
|
|
814
|
+
* @param {string} macAddress - The MAC address of the device.
|
|
815
|
+
* @param {number} [serviceThreshold=2000] - Service threshold in hours.
|
|
816
|
+
* @returns {Promise<UsageAnalyticsType>} - Comprehensive usage analytics.
|
|
817
|
+
*/
|
|
818
|
+
async (
|
|
819
|
+
jwtToken: string,
|
|
820
|
+
macAddress: string,
|
|
821
|
+
serviceThreshold: number = DEFAULT_SERVICE_THRESHOLD,
|
|
822
|
+
): Promise<UsageAnalyticsType> => {
|
|
823
|
+
const info = await deviceInfo(baseURL)(jwtToken, macAddress);
|
|
824
|
+
|
|
825
|
+
const totalCounters = info.nvm.total_counters;
|
|
826
|
+
const serviceCounters = info.nvm.service_counters;
|
|
827
|
+
const regeneration = info.nvm.regeneration;
|
|
828
|
+
const alarmsLog = info.nvm.alarms_log;
|
|
829
|
+
|
|
830
|
+
const totalOperatingHours =
|
|
831
|
+
totalCounters.p1_working_time +
|
|
832
|
+
totalCounters.p2_working_time +
|
|
833
|
+
totalCounters.p3_working_time +
|
|
834
|
+
totalCounters.p4_working_time +
|
|
835
|
+
totalCounters.p5_working_time;
|
|
836
|
+
|
|
837
|
+
const hoursSinceService =
|
|
838
|
+
serviceCounters.p1_working_time +
|
|
839
|
+
serviceCounters.p2_working_time +
|
|
840
|
+
serviceCounters.p3_working_time +
|
|
841
|
+
serviceCounters.p4_working_time +
|
|
842
|
+
serviceCounters.p5_working_time;
|
|
843
|
+
|
|
844
|
+
const powerDistribution: PowerDistributionType =
|
|
845
|
+
totalOperatingHours === 0
|
|
846
|
+
? { p1: 0, p2: 0, p3: 0, p4: 0, p5: 0 }
|
|
847
|
+
: {
|
|
848
|
+
p1: (totalCounters.p1_working_time / totalOperatingHours) * 100,
|
|
849
|
+
p2: (totalCounters.p2_working_time / totalOperatingHours) * 100,
|
|
850
|
+
p3: (totalCounters.p3_working_time / totalOperatingHours) * 100,
|
|
851
|
+
p4: (totalCounters.p4_working_time / totalOperatingHours) * 100,
|
|
852
|
+
p5: (totalCounters.p5_working_time / totalOperatingHours) * 100,
|
|
853
|
+
};
|
|
854
|
+
|
|
855
|
+
return {
|
|
856
|
+
totalPowerOns: totalCounters.power_ons,
|
|
857
|
+
totalOperatingHours,
|
|
858
|
+
powerDistribution,
|
|
859
|
+
serviceStatus: {
|
|
860
|
+
totalServiceHours: info.status.counters.service_time,
|
|
861
|
+
hoursSinceService,
|
|
862
|
+
serviceThresholdHours: serviceThreshold,
|
|
863
|
+
isServiceDue: hoursSinceService >= serviceThreshold,
|
|
864
|
+
},
|
|
865
|
+
blackoutCount: regeneration.blackout_counter,
|
|
866
|
+
lastMaintenanceDate:
|
|
867
|
+
regeneration.last_intervention > 0
|
|
868
|
+
? new Date(regeneration.last_intervention * 1000)
|
|
869
|
+
: null,
|
|
870
|
+
alarmCount: alarmsLog.number,
|
|
871
|
+
};
|
|
872
|
+
};
|
|
873
|
+
|
|
627
874
|
const registerDevice =
|
|
628
875
|
(baseURL: string) =>
|
|
629
876
|
/**
|
|
@@ -748,6 +995,17 @@ const configure = (baseURL: string = API_URL) => ({
|
|
|
748
995
|
getLanguage: getLanguage(baseURL),
|
|
749
996
|
getPelletInReserve: getPelletInReserve(baseURL),
|
|
750
997
|
getPelletAutonomyTime: getPelletAutonomyTime(baseURL),
|
|
998
|
+
// Statistics getters
|
|
999
|
+
getTotalCounters: getTotalCounters(baseURL),
|
|
1000
|
+
getServiceCounters: getServiceCounters(baseURL),
|
|
1001
|
+
getAlarmHistory: getAlarmHistory(baseURL),
|
|
1002
|
+
getRegenerationData: getRegenerationData(baseURL),
|
|
1003
|
+
getServiceTime: getServiceTime(baseURL),
|
|
1004
|
+
// Analytics functions
|
|
1005
|
+
getTotalOperatingHours: getTotalOperatingHours(baseURL),
|
|
1006
|
+
getPowerDistribution: getPowerDistribution(baseURL),
|
|
1007
|
+
getServiceStatus: getServiceStatus(baseURL),
|
|
1008
|
+
getUsageAnalytics: getUsageAnalytics(baseURL),
|
|
751
1009
|
});
|
|
752
1010
|
|
|
753
1011
|
export {
|