iobroker.utility-monitor 1.4.6 → 1.5.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/README.md +110 -62
- package/admin/custom/.vite/manifest.json +90 -0
- package/admin/custom/@mf-types/Components.d.ts +2 -0
- package/admin/custom/@mf-types/compiled-types/Components/CSVImporter.d.ts +11 -0
- package/admin/custom/@mf-types/compiled-types/Components.d.ts +2 -0
- package/admin/custom/@mf-types.d.ts +3 -0
- package/admin/custom/@mf-types.zip +0 -0
- package/admin/custom/CSVImporter_v15_11.js +4415 -0
- package/admin/custom/assets/Components-i0AZ59nl.js +18887 -0
- package/admin/custom/assets/UtilityMonitor__loadShare__react__loadShare__-Da99Mak4.js +42 -0
- package/admin/custom/assets/UtilityMonitor__mf_v__runtimeInit__mf_v__-BmC4OGk6.js +16 -0
- package/admin/custom/assets/_commonjsHelpers-Dj2_voLF.js +30 -0
- package/admin/custom/assets/hostInit-DEXfeB0W.js +10 -0
- package/admin/custom/assets/index-B3WVNJTz.js +401 -0
- package/admin/custom/assets/index-VBwl8x_k.js +64 -0
- package/admin/custom/assets/preload-helper-BelkbqnE.js +61 -0
- package/admin/custom/assets/virtualExposes-CqCLUNLT.js +19 -0
- package/admin/custom/index.html +12 -0
- package/admin/custom/mf-manifest.json +1 -0
- package/admin/jsonConfig.json +90 -31
- package/io-package.json +15 -31
- package/lib/billingManager.js +382 -137
- package/lib/calculator.js +41 -146
- package/lib/consumptionManager.js +9 -252
- package/lib/importManager.js +300 -0
- package/lib/messagingHandler.js +4 -2
- package/lib/meter/MeterRegistry.js +110 -0
- package/lib/multiMeterManager.js +580 -173
- package/lib/stateManager.js +502 -31
- package/lib/utils/billingHelper.js +69 -0
- package/lib/utils/consumptionHelper.js +47 -0
- package/lib/utils/helpers.js +234 -0
- package/lib/utils/stateCache.js +147 -0
- package/lib/utils/typeMapper.js +19 -0
- package/main.js +67 -8
- package/package.json +10 -4
package/lib/stateManager.js
CHANGED
|
@@ -1,28 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* State Manager module for nebenkosten-monitor
|
|
3
2
|
* Manages the creation and structure of all adapter states
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
|
-
/**
|
|
7
|
-
* Safe wrapper for setObjectNotExistsAsync with error handling
|
|
8
|
-
*
|
|
9
|
-
* @param {object} adapter - Adapter instance
|
|
10
|
-
* @param {string} id - State ID
|
|
11
|
-
* @param {object} obj - State object
|
|
12
|
-
* @returns {Promise<void>}
|
|
13
|
-
*/
|
|
14
|
-
async function safeSetObjectNotExists(adapter, id, obj) {
|
|
15
|
-
try {
|
|
16
|
-
await adapter.setObjectNotExistsAsync(id, obj);
|
|
17
|
-
} catch (error) {
|
|
18
|
-
adapter.log.warn(`Failed to create state ${id}: ${error.message}`);
|
|
19
|
-
// Re-throw critical errors
|
|
20
|
-
if (error.message && error.message.includes('EACCES')) {
|
|
21
|
-
throw error;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
5
|
/**
|
|
27
6
|
* State role definitions for different state types
|
|
28
7
|
*/
|
|
@@ -162,6 +141,20 @@ async function createUtilityStateStructure(adapter, type, _config = {}) {
|
|
|
162
141
|
native: {},
|
|
163
142
|
});
|
|
164
143
|
|
|
144
|
+
await adapter.setObjectNotExistsAsync(`${type}.consumption.weekly`, {
|
|
145
|
+
type: 'state',
|
|
146
|
+
common: {
|
|
147
|
+
name: `Wochen-${(label.consumption || 'Verbrauch').toLowerCase()} (${label.unit})`,
|
|
148
|
+
type: 'number',
|
|
149
|
+
role: STATE_ROLES.consumption,
|
|
150
|
+
read: true,
|
|
151
|
+
write: false,
|
|
152
|
+
unit: label.unit,
|
|
153
|
+
def: 0,
|
|
154
|
+
},
|
|
155
|
+
native: {},
|
|
156
|
+
});
|
|
157
|
+
|
|
165
158
|
// Map internal type to config type (electricity -> strom, water -> wasser, gas -> gas)
|
|
166
159
|
const configTypeMap = {
|
|
167
160
|
electricity: 'strom',
|
|
@@ -200,6 +193,28 @@ async function createUtilityStateStructure(adapter, type, _config = {}) {
|
|
|
200
193
|
native: {},
|
|
201
194
|
});
|
|
202
195
|
}
|
|
196
|
+
|
|
197
|
+
const htNtWeeklyStates = ['weeklyHT', 'weeklyNT'];
|
|
198
|
+
const htNtWeeklyLabels = {
|
|
199
|
+
weeklyHT: 'Wochenverbrauch Haupttarif (HT)',
|
|
200
|
+
weeklyNT: 'Wochenverbrauch Nebentarif (NT)',
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
for (const state of htNtWeeklyStates) {
|
|
204
|
+
await adapter.setObjectNotExistsAsync(`${type}.consumption.${state}`, {
|
|
205
|
+
type: 'state',
|
|
206
|
+
common: {
|
|
207
|
+
name: `${htNtWeeklyLabels[state]} (${label.unit})`,
|
|
208
|
+
type: 'number',
|
|
209
|
+
role: STATE_ROLES.consumption,
|
|
210
|
+
read: true,
|
|
211
|
+
write: false,
|
|
212
|
+
unit: label.unit,
|
|
213
|
+
def: 0,
|
|
214
|
+
},
|
|
215
|
+
native: {},
|
|
216
|
+
});
|
|
217
|
+
}
|
|
203
218
|
}
|
|
204
219
|
|
|
205
220
|
await adapter.setObjectNotExistsAsync(`${type}.consumption.lastUpdate`, {
|
|
@@ -265,6 +280,20 @@ async function createUtilityStateStructure(adapter, type, _config = {}) {
|
|
|
265
280
|
native: {},
|
|
266
281
|
});
|
|
267
282
|
|
|
283
|
+
await adapter.setObjectNotExistsAsync(`${type}.costs.weekly`, {
|
|
284
|
+
type: 'state',
|
|
285
|
+
common: {
|
|
286
|
+
name: `Wochen-${(label.cost || 'Kosten').toLowerCase()} (€)`,
|
|
287
|
+
type: 'number',
|
|
288
|
+
role: STATE_ROLES.cost,
|
|
289
|
+
read: true,
|
|
290
|
+
write: false,
|
|
291
|
+
unit: '€',
|
|
292
|
+
def: 0,
|
|
293
|
+
},
|
|
294
|
+
native: {},
|
|
295
|
+
});
|
|
296
|
+
|
|
268
297
|
// HT/NT states - only create if HT/NT tariff is enabled
|
|
269
298
|
// Note: htNtEnabledKey already calculated above for consumption section
|
|
270
299
|
if (_config[htNtEnabledKey]) {
|
|
@@ -351,6 +380,34 @@ async function createUtilityStateStructure(adapter, type, _config = {}) {
|
|
|
351
380
|
},
|
|
352
381
|
native: {},
|
|
353
382
|
});
|
|
383
|
+
|
|
384
|
+
await adapter.setObjectNotExistsAsync(`${type}.costs.weeklyHT`, {
|
|
385
|
+
type: 'state',
|
|
386
|
+
common: {
|
|
387
|
+
name: 'Wochenkosten Haupttarif (HT) (€)',
|
|
388
|
+
type: 'number',
|
|
389
|
+
role: STATE_ROLES.cost,
|
|
390
|
+
read: true,
|
|
391
|
+
write: false,
|
|
392
|
+
unit: '€',
|
|
393
|
+
def: 0,
|
|
394
|
+
},
|
|
395
|
+
native: {},
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
await adapter.setObjectNotExistsAsync(`${type}.costs.weeklyNT`, {
|
|
399
|
+
type: 'state',
|
|
400
|
+
common: {
|
|
401
|
+
name: 'Wochenkosten Nebentarif (NT) (€)',
|
|
402
|
+
type: 'number',
|
|
403
|
+
role: STATE_ROLES.cost,
|
|
404
|
+
read: true,
|
|
405
|
+
write: false,
|
|
406
|
+
unit: '€',
|
|
407
|
+
def: 0,
|
|
408
|
+
},
|
|
409
|
+
native: {},
|
|
410
|
+
});
|
|
354
411
|
}
|
|
355
412
|
|
|
356
413
|
await adapter.setObjectNotExistsAsync(`${type}.costs.totalYearly`, {
|
|
@@ -765,6 +822,68 @@ async function createUtilityStateStructure(adapter, type, _config = {}) {
|
|
|
765
822
|
});
|
|
766
823
|
}
|
|
767
824
|
|
|
825
|
+
// Last week consumption
|
|
826
|
+
await adapter.setObjectNotExistsAsync(`${type}.statistics.lastWeek`, {
|
|
827
|
+
type: 'state',
|
|
828
|
+
common: {
|
|
829
|
+
name: `Verbrauch letzte Woche (${label.unit})`,
|
|
830
|
+
type: 'number',
|
|
831
|
+
role: STATE_ROLES.consumption,
|
|
832
|
+
read: true,
|
|
833
|
+
write: false,
|
|
834
|
+
unit: label.unit,
|
|
835
|
+
def: 0,
|
|
836
|
+
},
|
|
837
|
+
native: {},
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
if (type === 'gas') {
|
|
841
|
+
await adapter.setObjectNotExistsAsync(`${type}.statistics.lastWeekVolume`, {
|
|
842
|
+
type: 'state',
|
|
843
|
+
common: {
|
|
844
|
+
name: `Verbrauch letzte Woche (${label.volumeUnit})`,
|
|
845
|
+
type: 'number',
|
|
846
|
+
role: STATE_ROLES.consumption,
|
|
847
|
+
read: true,
|
|
848
|
+
write: false,
|
|
849
|
+
unit: label.volumeUnit,
|
|
850
|
+
def: 0,
|
|
851
|
+
},
|
|
852
|
+
native: {},
|
|
853
|
+
});
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
// Last month consumption
|
|
857
|
+
await adapter.setObjectNotExistsAsync(`${type}.statistics.lastMonth`, {
|
|
858
|
+
type: 'state',
|
|
859
|
+
common: {
|
|
860
|
+
name: `Verbrauch letzter Monat (${label.unit})`,
|
|
861
|
+
type: 'number',
|
|
862
|
+
role: STATE_ROLES.consumption,
|
|
863
|
+
read: true,
|
|
864
|
+
write: false,
|
|
865
|
+
unit: label.unit,
|
|
866
|
+
def: 0,
|
|
867
|
+
},
|
|
868
|
+
native: {},
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
if (type === 'gas') {
|
|
872
|
+
await adapter.setObjectNotExistsAsync(`${type}.statistics.lastMonthVolume`, {
|
|
873
|
+
type: 'state',
|
|
874
|
+
common: {
|
|
875
|
+
name: `Verbrauch letzter Monat (${label.volumeUnit})`,
|
|
876
|
+
type: 'number',
|
|
877
|
+
role: STATE_ROLES.consumption,
|
|
878
|
+
read: true,
|
|
879
|
+
write: false,
|
|
880
|
+
unit: label.volumeUnit,
|
|
881
|
+
def: 0,
|
|
882
|
+
},
|
|
883
|
+
native: {},
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
|
|
768
887
|
await adapter.setObjectNotExistsAsync(`${type}.statistics.lastDayStart`, {
|
|
769
888
|
type: 'state',
|
|
770
889
|
common: {
|
|
@@ -777,6 +896,18 @@ async function createUtilityStateStructure(adapter, type, _config = {}) {
|
|
|
777
896
|
native: {},
|
|
778
897
|
});
|
|
779
898
|
|
|
899
|
+
await adapter.setObjectNotExistsAsync(`${type}.statistics.lastWeekStart`, {
|
|
900
|
+
type: 'state',
|
|
901
|
+
common: {
|
|
902
|
+
name: 'Wochenzähler zurückgesetzt am',
|
|
903
|
+
type: 'number',
|
|
904
|
+
role: STATE_ROLES.timestamp,
|
|
905
|
+
read: true,
|
|
906
|
+
write: false,
|
|
907
|
+
},
|
|
908
|
+
native: {},
|
|
909
|
+
});
|
|
910
|
+
|
|
780
911
|
await adapter.setObjectNotExistsAsync(`${type}.statistics.lastMonthStart`, {
|
|
781
912
|
type: 'state',
|
|
782
913
|
common: {
|
|
@@ -896,6 +1027,20 @@ async function createMeterStructure(adapter, type, meterName, _config = {}) {
|
|
|
896
1027
|
},
|
|
897
1028
|
native: {},
|
|
898
1029
|
});
|
|
1030
|
+
|
|
1031
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.consumption.weeklyVolume`, {
|
|
1032
|
+
type: 'state',
|
|
1033
|
+
common: {
|
|
1034
|
+
name: 'Wöchentlicher Verbrauch (m³)',
|
|
1035
|
+
type: 'number',
|
|
1036
|
+
role: STATE_ROLES.consumption,
|
|
1037
|
+
read: true,
|
|
1038
|
+
write: false,
|
|
1039
|
+
unit: 'm³',
|
|
1040
|
+
def: 0,
|
|
1041
|
+
},
|
|
1042
|
+
native: {},
|
|
1043
|
+
});
|
|
899
1044
|
}
|
|
900
1045
|
|
|
901
1046
|
await adapter.setObjectNotExistsAsync(`${basePath}.consumption.daily`, {
|
|
@@ -940,6 +1085,65 @@ async function createMeterStructure(adapter, type, meterName, _config = {}) {
|
|
|
940
1085
|
native: {},
|
|
941
1086
|
});
|
|
942
1087
|
|
|
1088
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.consumption.weekly`, {
|
|
1089
|
+
type: 'state',
|
|
1090
|
+
common: {
|
|
1091
|
+
name: `Wochenverbrauch (${label.unit})`,
|
|
1092
|
+
type: 'number',
|
|
1093
|
+
role: STATE_ROLES.consumption,
|
|
1094
|
+
read: true,
|
|
1095
|
+
write: false,
|
|
1096
|
+
unit: label.unit,
|
|
1097
|
+
def: 0,
|
|
1098
|
+
},
|
|
1099
|
+
native: {},
|
|
1100
|
+
});
|
|
1101
|
+
|
|
1102
|
+
if (_config.htNtEnabled) {
|
|
1103
|
+
const htNtStates = [
|
|
1104
|
+
'dailyHT',
|
|
1105
|
+
'dailyNT',
|
|
1106
|
+
'monthlyHT',
|
|
1107
|
+
'monthlyNT',
|
|
1108
|
+
'yearlyHT',
|
|
1109
|
+
'yearlyNT',
|
|
1110
|
+
'weeklyHT',
|
|
1111
|
+
'weeklyNT',
|
|
1112
|
+
];
|
|
1113
|
+
const htNtLabels = {
|
|
1114
|
+
dailyHT: 'Tagesverbrauch Haupttarif (HT)',
|
|
1115
|
+
dailyNT: 'Tagesverbrauch Nebentarif (NT)',
|
|
1116
|
+
monthlyHT: 'Monatsverbrauch Haupttarif (HT)',
|
|
1117
|
+
monthlyNT: 'Monatsverbrauch Nebentarif (NT)',
|
|
1118
|
+
yearlyHT: 'Jahresverbrauch Haupttarif (HT)',
|
|
1119
|
+
yearlyNT: 'Jahresverbrauch Nebentarif (NT)',
|
|
1120
|
+
weeklyHT: 'Wochenverbrauch Haupttarif (HT)',
|
|
1121
|
+
weeklyNT: 'Wochenverbrauch Nebentarif (NT)',
|
|
1122
|
+
weeklyVolumeHT: 'Wochenverbrauch Haupttarif (m³)',
|
|
1123
|
+
weeklyVolumeNT: 'Wochenverbrauch Nebentarif (m³)',
|
|
1124
|
+
};
|
|
1125
|
+
|
|
1126
|
+
if (type === 'gas') {
|
|
1127
|
+
htNtStates.push('weeklyVolumeHT', 'weeklyVolumeNT');
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
for (const state of htNtStates) {
|
|
1131
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.consumption.${state}`, {
|
|
1132
|
+
type: 'state',
|
|
1133
|
+
common: {
|
|
1134
|
+
name: `${htNtLabels[state]} (${label.unit})`,
|
|
1135
|
+
type: 'number',
|
|
1136
|
+
role: STATE_ROLES.consumption,
|
|
1137
|
+
read: true,
|
|
1138
|
+
write: false,
|
|
1139
|
+
unit: label.unit,
|
|
1140
|
+
def: 0,
|
|
1141
|
+
},
|
|
1142
|
+
native: {},
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
|
|
943
1147
|
await adapter.setObjectNotExistsAsync(`${basePath}.consumption.lastUpdate`, {
|
|
944
1148
|
type: 'state',
|
|
945
1149
|
common: {
|
|
@@ -1003,6 +1207,59 @@ async function createMeterStructure(adapter, type, meterName, _config = {}) {
|
|
|
1003
1207
|
native: {},
|
|
1004
1208
|
});
|
|
1005
1209
|
|
|
1210
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.costs.weekly`, {
|
|
1211
|
+
type: 'state',
|
|
1212
|
+
common: {
|
|
1213
|
+
name: 'Wochenkosten (€)',
|
|
1214
|
+
type: 'number',
|
|
1215
|
+
role: STATE_ROLES.cost,
|
|
1216
|
+
read: true,
|
|
1217
|
+
write: false,
|
|
1218
|
+
unit: '€',
|
|
1219
|
+
def: 0,
|
|
1220
|
+
},
|
|
1221
|
+
native: {},
|
|
1222
|
+
});
|
|
1223
|
+
|
|
1224
|
+
if (_config.htNtEnabled) {
|
|
1225
|
+
const htNtCostStates = [
|
|
1226
|
+
'dailyHT',
|
|
1227
|
+
'dailyNT',
|
|
1228
|
+
'monthlyHT',
|
|
1229
|
+
'monthlyNT',
|
|
1230
|
+
'yearlyHT',
|
|
1231
|
+
'yearlyNT',
|
|
1232
|
+
'weeklyHT',
|
|
1233
|
+
'weeklyNT',
|
|
1234
|
+
];
|
|
1235
|
+
const htNtCostLabels = {
|
|
1236
|
+
dailyHT: 'Tageskosten Haupttarif (HT)',
|
|
1237
|
+
dailyNT: 'Tageskosten Nebentarif (NT)',
|
|
1238
|
+
monthlyHT: 'Monatskosten Haupttarif (HT)',
|
|
1239
|
+
monthlyNT: 'Monatskosten Nebentarif (NT)',
|
|
1240
|
+
yearlyHT: 'Jahreskosten Haupttarif (HT)',
|
|
1241
|
+
yearlyNT: 'Jahreskosten Nebentarif (NT)',
|
|
1242
|
+
weeklyHT: 'Wochenkosten Haupttarif (HT)',
|
|
1243
|
+
weeklyNT: 'Wochenkosten Nebentarif (NT)',
|
|
1244
|
+
};
|
|
1245
|
+
|
|
1246
|
+
for (const state of htNtCostStates) {
|
|
1247
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.costs.${state}`, {
|
|
1248
|
+
type: 'state',
|
|
1249
|
+
common: {
|
|
1250
|
+
name: `${htNtCostLabels[state]} (€)`,
|
|
1251
|
+
type: 'number',
|
|
1252
|
+
role: STATE_ROLES.cost,
|
|
1253
|
+
read: true,
|
|
1254
|
+
write: false,
|
|
1255
|
+
unit: '€',
|
|
1256
|
+
def: 0,
|
|
1257
|
+
},
|
|
1258
|
+
native: {},
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1006
1263
|
await adapter.setObjectNotExistsAsync(`${basePath}.costs.totalYearly`, {
|
|
1007
1264
|
type: 'state',
|
|
1008
1265
|
common: {
|
|
@@ -1279,27 +1536,27 @@ async function createMeterStructure(adapter, type, meterName, _config = {}) {
|
|
|
1279
1536
|
native: {},
|
|
1280
1537
|
});
|
|
1281
1538
|
|
|
1282
|
-
await adapter.setObjectNotExistsAsync(`${basePath}.info.
|
|
1539
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.info.sensorActive`, {
|
|
1283
1540
|
type: 'state',
|
|
1284
1541
|
common: {
|
|
1285
|
-
name: '
|
|
1286
|
-
type: '
|
|
1287
|
-
role:
|
|
1542
|
+
name: 'Sensor aktiv',
|
|
1543
|
+
type: 'boolean',
|
|
1544
|
+
role: 'indicator.reachable',
|
|
1288
1545
|
read: true,
|
|
1289
1546
|
write: false,
|
|
1547
|
+
def: false,
|
|
1290
1548
|
},
|
|
1291
1549
|
native: {},
|
|
1292
1550
|
});
|
|
1293
1551
|
|
|
1294
|
-
await adapter.setObjectNotExistsAsync(`${basePath}.info.
|
|
1552
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.info.lastSync`, {
|
|
1295
1553
|
type: 'state',
|
|
1296
1554
|
common: {
|
|
1297
|
-
name: '
|
|
1298
|
-
type: '
|
|
1299
|
-
role: STATE_ROLES.
|
|
1555
|
+
name: 'Letzte Synchronisation',
|
|
1556
|
+
type: 'number',
|
|
1557
|
+
role: STATE_ROLES.timestamp,
|
|
1300
1558
|
read: true,
|
|
1301
1559
|
write: false,
|
|
1302
|
-
def: false,
|
|
1303
1560
|
},
|
|
1304
1561
|
native: {},
|
|
1305
1562
|
});
|
|
@@ -1384,6 +1641,68 @@ async function createMeterStructure(adapter, type, meterName, _config = {}) {
|
|
|
1384
1641
|
});
|
|
1385
1642
|
}
|
|
1386
1643
|
|
|
1644
|
+
// Last week consumption
|
|
1645
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.statistics.lastWeek`, {
|
|
1646
|
+
type: 'state',
|
|
1647
|
+
common: {
|
|
1648
|
+
name: `Verbrauch letzte Woche (${label.unit})`,
|
|
1649
|
+
type: 'number',
|
|
1650
|
+
role: STATE_ROLES.consumption,
|
|
1651
|
+
read: true,
|
|
1652
|
+
write: false,
|
|
1653
|
+
unit: label.unit,
|
|
1654
|
+
def: 0,
|
|
1655
|
+
},
|
|
1656
|
+
native: {},
|
|
1657
|
+
});
|
|
1658
|
+
|
|
1659
|
+
if (type === 'gas') {
|
|
1660
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.statistics.lastWeekVolume`, {
|
|
1661
|
+
type: 'state',
|
|
1662
|
+
common: {
|
|
1663
|
+
name: `Verbrauch letzte Woche (${label.volumeUnit})`,
|
|
1664
|
+
type: 'number',
|
|
1665
|
+
role: STATE_ROLES.consumption,
|
|
1666
|
+
read: true,
|
|
1667
|
+
write: false,
|
|
1668
|
+
unit: label.volumeUnit,
|
|
1669
|
+
def: 0,
|
|
1670
|
+
},
|
|
1671
|
+
native: {},
|
|
1672
|
+
});
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
// Last month consumption
|
|
1676
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.statistics.lastMonth`, {
|
|
1677
|
+
type: 'state',
|
|
1678
|
+
common: {
|
|
1679
|
+
name: `Verbrauch letzter Monat (${label.unit})`,
|
|
1680
|
+
type: 'number',
|
|
1681
|
+
role: STATE_ROLES.consumption,
|
|
1682
|
+
read: true,
|
|
1683
|
+
write: false,
|
|
1684
|
+
unit: label.unit,
|
|
1685
|
+
def: 0,
|
|
1686
|
+
},
|
|
1687
|
+
native: {},
|
|
1688
|
+
});
|
|
1689
|
+
|
|
1690
|
+
if (type === 'gas') {
|
|
1691
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.statistics.lastMonthVolume`, {
|
|
1692
|
+
type: 'state',
|
|
1693
|
+
common: {
|
|
1694
|
+
name: `Verbrauch letzter Monat (${label.volumeUnit})`,
|
|
1695
|
+
type: 'number',
|
|
1696
|
+
role: STATE_ROLES.consumption,
|
|
1697
|
+
read: true,
|
|
1698
|
+
write: false,
|
|
1699
|
+
unit: label.volumeUnit,
|
|
1700
|
+
def: 0,
|
|
1701
|
+
},
|
|
1702
|
+
native: {},
|
|
1703
|
+
});
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1387
1706
|
await adapter.setObjectNotExistsAsync(`${basePath}.statistics.lastDayStart`, {
|
|
1388
1707
|
type: 'state',
|
|
1389
1708
|
common: {
|
|
@@ -1420,6 +1739,18 @@ async function createMeterStructure(adapter, type, meterName, _config = {}) {
|
|
|
1420
1739
|
native: {},
|
|
1421
1740
|
});
|
|
1422
1741
|
|
|
1742
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.statistics.lastWeekStart`, {
|
|
1743
|
+
type: 'state',
|
|
1744
|
+
common: {
|
|
1745
|
+
name: 'Wochenzähler zurückgesetzt am',
|
|
1746
|
+
type: 'number',
|
|
1747
|
+
role: STATE_ROLES.timestamp,
|
|
1748
|
+
read: true,
|
|
1749
|
+
write: false,
|
|
1750
|
+
},
|
|
1751
|
+
native: {},
|
|
1752
|
+
});
|
|
1753
|
+
|
|
1423
1754
|
adapter.log.debug(`Meter state structure created for ${type}.${meterName}`);
|
|
1424
1755
|
}
|
|
1425
1756
|
|
|
@@ -1524,6 +1855,61 @@ async function createTotalsStructure(adapter, type) {
|
|
|
1524
1855
|
native: {},
|
|
1525
1856
|
});
|
|
1526
1857
|
|
|
1858
|
+
if (type === 'gas') {
|
|
1859
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.consumption.weeklyVolume`, {
|
|
1860
|
+
type: 'state',
|
|
1861
|
+
common: {
|
|
1862
|
+
name: 'Wochenverbrauch Gesamt (m³)',
|
|
1863
|
+
type: 'number',
|
|
1864
|
+
role: STATE_ROLES.consumption,
|
|
1865
|
+
read: true,
|
|
1866
|
+
write: false,
|
|
1867
|
+
unit: 'm³',
|
|
1868
|
+
def: 0,
|
|
1869
|
+
},
|
|
1870
|
+
native: {},
|
|
1871
|
+
});
|
|
1872
|
+
|
|
1873
|
+
// Also add HT/NT volume totals if gas has HT/NT enabled
|
|
1874
|
+
if (adapter.config.gasHtNtEnabled) {
|
|
1875
|
+
const hntVolumeStates = ['weeklyVolumeHT', 'weeklyVolumeNT'];
|
|
1876
|
+
const hntVolumeLabels = {
|
|
1877
|
+
weeklyVolumeHT: 'Wochenverbrauch Gesamt Haupttarif (HT) (m³)',
|
|
1878
|
+
weeklyVolumeNT: 'Wochenverbrauch Gesamt Nebentarif (NT) (m³)',
|
|
1879
|
+
};
|
|
1880
|
+
|
|
1881
|
+
for (const state of hntVolumeStates) {
|
|
1882
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.consumption.${state}`, {
|
|
1883
|
+
type: 'state',
|
|
1884
|
+
common: {
|
|
1885
|
+
name: hntVolumeLabels[state],
|
|
1886
|
+
type: 'number',
|
|
1887
|
+
role: STATE_ROLES.consumption,
|
|
1888
|
+
read: true,
|
|
1889
|
+
write: false,
|
|
1890
|
+
unit: 'm³',
|
|
1891
|
+
def: 0,
|
|
1892
|
+
},
|
|
1893
|
+
native: {},
|
|
1894
|
+
});
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.consumption.weekly`, {
|
|
1900
|
+
type: 'state',
|
|
1901
|
+
common: {
|
|
1902
|
+
name: `Wochenverbrauch Gesamt (${label.unit})`,
|
|
1903
|
+
type: 'number',
|
|
1904
|
+
role: STATE_ROLES.consumption,
|
|
1905
|
+
read: true,
|
|
1906
|
+
write: false,
|
|
1907
|
+
unit: label.unit,
|
|
1908
|
+
def: 0,
|
|
1909
|
+
},
|
|
1910
|
+
native: {},
|
|
1911
|
+
});
|
|
1912
|
+
|
|
1527
1913
|
// COST STATES (totals)
|
|
1528
1914
|
await adapter.setObjectNotExistsAsync(`${basePath}.costs`, {
|
|
1529
1915
|
type: 'channel',
|
|
@@ -1561,6 +1947,20 @@ async function createTotalsStructure(adapter, type) {
|
|
|
1561
1947
|
native: {},
|
|
1562
1948
|
});
|
|
1563
1949
|
|
|
1950
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.costs.weekly`, {
|
|
1951
|
+
type: 'state',
|
|
1952
|
+
common: {
|
|
1953
|
+
name: 'Wochenkosten Gesamt (€)',
|
|
1954
|
+
type: 'number',
|
|
1955
|
+
role: STATE_ROLES.cost,
|
|
1956
|
+
read: true,
|
|
1957
|
+
write: false,
|
|
1958
|
+
unit: '€',
|
|
1959
|
+
def: 0,
|
|
1960
|
+
},
|
|
1961
|
+
native: {},
|
|
1962
|
+
});
|
|
1963
|
+
|
|
1564
1964
|
await adapter.setObjectNotExistsAsync(`${basePath}.costs.totalYearly`, {
|
|
1565
1965
|
type: 'state',
|
|
1566
1966
|
common: {
|
|
@@ -1578,11 +1978,82 @@ async function createTotalsStructure(adapter, type) {
|
|
|
1578
1978
|
adapter.log.debug(`Totals state structure created for ${type}`);
|
|
1579
1979
|
}
|
|
1580
1980
|
|
|
1981
|
+
/**
|
|
1982
|
+
* Creates history structure for a specific year
|
|
1983
|
+
*
|
|
1984
|
+
* @param {object} adapter - The adapter instance
|
|
1985
|
+
* @param {string} type - 'gas', 'water', 'electricity', 'pv'
|
|
1986
|
+
* @param {string} meterName - Meter name
|
|
1987
|
+
* @param {number|string} year - Year (YYYY)
|
|
1988
|
+
* @returns {Promise<void>}
|
|
1989
|
+
*/
|
|
1990
|
+
async function createHistoryStructure(adapter, type, meterName, year) {
|
|
1991
|
+
const basePath = `${type}.${meterName}.history.${year}`;
|
|
1992
|
+
|
|
1993
|
+
await adapter.setObjectNotExistsAsync(`${type}.${meterName}.history`, {
|
|
1994
|
+
type: 'channel',
|
|
1995
|
+
common: { name: 'Historie' },
|
|
1996
|
+
native: {},
|
|
1997
|
+
});
|
|
1998
|
+
|
|
1999
|
+
await adapter.setObjectNotExistsAsync(basePath, {
|
|
2000
|
+
type: 'channel',
|
|
2001
|
+
common: { name: `Jahr ${year}` },
|
|
2002
|
+
native: { year },
|
|
2003
|
+
});
|
|
2004
|
+
|
|
2005
|
+
const unit = type === 'water' ? 'm³' : 'kWh';
|
|
2006
|
+
|
|
2007
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.consumption`, {
|
|
2008
|
+
type: 'state',
|
|
2009
|
+
common: {
|
|
2010
|
+
name: `Jahresverbrauch ${year} (${unit})`,
|
|
2011
|
+
type: 'number',
|
|
2012
|
+
role: STATE_ROLES.consumption,
|
|
2013
|
+
read: true,
|
|
2014
|
+
write: false,
|
|
2015
|
+
unit: unit,
|
|
2016
|
+
def: 0,
|
|
2017
|
+
},
|
|
2018
|
+
native: {},
|
|
2019
|
+
});
|
|
2020
|
+
|
|
2021
|
+
if (type === 'gas') {
|
|
2022
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.volume`, {
|
|
2023
|
+
type: 'state',
|
|
2024
|
+
common: {
|
|
2025
|
+
name: `Jahresverbrauch ${year} (m³)`,
|
|
2026
|
+
type: 'number',
|
|
2027
|
+
role: STATE_ROLES.consumption,
|
|
2028
|
+
read: true,
|
|
2029
|
+
write: false,
|
|
2030
|
+
unit: 'm³',
|
|
2031
|
+
def: 0,
|
|
2032
|
+
},
|
|
2033
|
+
native: {},
|
|
2034
|
+
});
|
|
2035
|
+
}
|
|
2036
|
+
|
|
2037
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.costs`, {
|
|
2038
|
+
type: 'state',
|
|
2039
|
+
common: {
|
|
2040
|
+
name: `Jahreskosten ${year} (€)`,
|
|
2041
|
+
type: 'number',
|
|
2042
|
+
role: STATE_ROLES.cost,
|
|
2043
|
+
read: true,
|
|
2044
|
+
write: false,
|
|
2045
|
+
unit: '€',
|
|
2046
|
+
def: 0,
|
|
2047
|
+
},
|
|
2048
|
+
native: {},
|
|
2049
|
+
});
|
|
2050
|
+
}
|
|
2051
|
+
|
|
1581
2052
|
module.exports = {
|
|
1582
2053
|
createUtilityStateStructure,
|
|
1583
2054
|
createMeterStructure,
|
|
1584
2055
|
createTotalsStructure,
|
|
2056
|
+
createHistoryStructure,
|
|
1585
2057
|
deleteUtilityStateStructure,
|
|
1586
|
-
safeSetObjectNotExists,
|
|
1587
2058
|
STATE_ROLES,
|
|
1588
2059
|
};
|