iobroker.utility-monitor 1.4.2
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/LICENSE +21 -0
- package/README.md +384 -0
- package/admin/i18n/de.json +5 -0
- package/admin/i18n/en.json +5 -0
- package/admin/i18n/es.json +5 -0
- package/admin/i18n/fr.json +5 -0
- package/admin/i18n/it.json +5 -0
- package/admin/i18n/nl.json +5 -0
- package/admin/i18n/pl.json +5 -0
- package/admin/i18n/pt.json +5 -0
- package/admin/i18n/ru.json +5 -0
- package/admin/i18n/uk.json +5 -0
- package/admin/i18n/zh-cn.json +5 -0
- package/admin/jsonConfig.json +1542 -0
- package/admin/utility-monitor.png +0 -0
- package/io-package.json +188 -0
- package/lib/adapter-config.d.ts +19 -0
- package/lib/billingManager.js +806 -0
- package/lib/calculator.js +254 -0
- package/lib/configParser.js +92 -0
- package/lib/consumptionManager.js +407 -0
- package/lib/messagingHandler.js +339 -0
- package/lib/multiMeterManager.js +749 -0
- package/lib/stateManager.js +1556 -0
- package/main.js +297 -0
- package/package.json +80 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const calculator = require('./calculator');
|
|
4
|
+
const stateManager = require('./stateManager');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ConsumptionManager handles all sensor-related logic,
|
|
8
|
+
* including initialization, unit conversion, and sensor updates.
|
|
9
|
+
*/
|
|
10
|
+
class ConsumptionManager {
|
|
11
|
+
/**
|
|
12
|
+
* @param {object} adapter - ioBroker adapter instance
|
|
13
|
+
*/
|
|
14
|
+
constructor(adapter) {
|
|
15
|
+
this.adapter = adapter;
|
|
16
|
+
this.lastSensorValues = {};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Maps internal utility type to config/state name
|
|
21
|
+
*
|
|
22
|
+
* @param {string} type - gas, water, or electricity
|
|
23
|
+
* @returns {string} - gas, wasser, or strom
|
|
24
|
+
*/
|
|
25
|
+
getConfigType(type) {
|
|
26
|
+
const mapping = {
|
|
27
|
+
electricity: 'strom',
|
|
28
|
+
water: 'wasser',
|
|
29
|
+
gas: 'gas',
|
|
30
|
+
};
|
|
31
|
+
return mapping[type] || type;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Initializes a utility type (gas, water, or electricity)
|
|
36
|
+
*
|
|
37
|
+
* @param {string} type - Utility type
|
|
38
|
+
* @param {boolean} isActive - Whether this utility is active
|
|
39
|
+
*/
|
|
40
|
+
async initializeUtility(type, isActive) {
|
|
41
|
+
if (!isActive) {
|
|
42
|
+
this.adapter.log.debug(`${type} monitoring is disabled`);
|
|
43
|
+
// Clean up states if utility was disabled
|
|
44
|
+
await stateManager.deleteUtilityStateStructure(this.adapter, type);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
this.adapter.log.info(`Initializing ${type} monitoring...`);
|
|
49
|
+
|
|
50
|
+
// Create state structure
|
|
51
|
+
await stateManager.createUtilityStateStructure(this.adapter, type, this.adapter.config);
|
|
52
|
+
|
|
53
|
+
const configType = this.getConfigType(type);
|
|
54
|
+
const sensorDPKey = `${configType}SensorDP`;
|
|
55
|
+
const sensorDP = this.adapter.config[sensorDPKey];
|
|
56
|
+
|
|
57
|
+
if (!sensorDP) {
|
|
58
|
+
this.adapter.log.warn(`${type} is active but no sensor datapoint configured!`);
|
|
59
|
+
await this.adapter.setStateAsync(`${type}.info.sensorActive`, false, true);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this.adapter.log.debug(`Using sensor datapoint for ${type}: ${sensorDP}`);
|
|
64
|
+
|
|
65
|
+
// Log configured contract start for user verification
|
|
66
|
+
const contractStartKey = `${configType}ContractStart`;
|
|
67
|
+
const contractStartDateStr = this.adapter.config[contractStartKey];
|
|
68
|
+
if (contractStartDateStr) {
|
|
69
|
+
this.adapter.log.info(`${type}: Managed with contract start: ${contractStartDateStr}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Subscribe to sensor datapoint
|
|
73
|
+
this.adapter.subscribeForeignStates(sensorDP);
|
|
74
|
+
await this.adapter.setStateAsync(`${type}.info.sensorActive`, true, true);
|
|
75
|
+
this.adapter.log.debug(`Subscribed to ${type} sensor: ${sensorDP}`);
|
|
76
|
+
|
|
77
|
+
// Initialize all meters (main + additional) via MultiMeterManager
|
|
78
|
+
if (this.adapter.multiMeterManager) {
|
|
79
|
+
await this.adapter.multiMeterManager.initializeType(type);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Restore last sensor value from persistent state to prevent delta loss
|
|
83
|
+
const lastReading = await this.adapter.getStateAsync(`${type}.info.meterReading`);
|
|
84
|
+
if (lastReading && typeof lastReading.val === 'number') {
|
|
85
|
+
this.lastSensorValues[sensorDP] = lastReading.val;
|
|
86
|
+
this.adapter.log.debug(`${type}: Restored last sensor value: ${lastReading.val}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Initialize with current sensor value
|
|
90
|
+
try {
|
|
91
|
+
const sensorState = await this.adapter.getForeignStateAsync(sensorDP);
|
|
92
|
+
if (sensorState && sensorState.val !== null && typeof sensorState.val === 'number') {
|
|
93
|
+
await this.handleSensorUpdate(type, sensorDP, sensorState.val);
|
|
94
|
+
}
|
|
95
|
+
} catch (error) {
|
|
96
|
+
this.adapter.log.warn(`Could not read initial value from ${sensorDP}: ${error.message}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Initialize period start timestamps if not set
|
|
100
|
+
const now = Date.now();
|
|
101
|
+
const dayStart = await this.adapter.getStateAsync(`${type}.statistics.lastDayStart`);
|
|
102
|
+
if (!dayStart || !dayStart.val) {
|
|
103
|
+
await this.adapter.setStateAsync(`${type}.statistics.lastDayStart`, now, true);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const monthStart = await this.adapter.getStateAsync(`${type}.statistics.lastMonthStart`);
|
|
107
|
+
if (!monthStart || !monthStart.val) {
|
|
108
|
+
await this.adapter.setStateAsync(`${type}.statistics.lastMonthStart`, now, true);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const yearStart = await this.adapter.getStateAsync(`${type}.statistics.lastYearStart`);
|
|
112
|
+
if (!yearStart || !yearStart.val) {
|
|
113
|
+
// Determine year start based on contract date or January 1st
|
|
114
|
+
const contractStartKey = `${configType}ContractStart`;
|
|
115
|
+
const contractStartDateStr = this.adapter.config[contractStartKey];
|
|
116
|
+
|
|
117
|
+
let yearStartDate;
|
|
118
|
+
if (contractStartDateStr) {
|
|
119
|
+
const contractStart = calculator.parseGermanDate(contractStartDateStr);
|
|
120
|
+
if (contractStart && !isNaN(contractStart.getTime())) {
|
|
121
|
+
// Calculate last anniversary
|
|
122
|
+
const nowDate = new Date(now);
|
|
123
|
+
const currentYear = nowDate.getFullYear();
|
|
124
|
+
yearStartDate = new Date(currentYear, contractStart.getMonth(), contractStart.getDate(), 12, 0, 0);
|
|
125
|
+
|
|
126
|
+
// If anniversary is in the future this year, take last year
|
|
127
|
+
if (yearStartDate > nowDate) {
|
|
128
|
+
yearStartDate.setFullYear(currentYear - 1);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!yearStartDate) {
|
|
134
|
+
// Fallback: January 1st of current year
|
|
135
|
+
const nowDate = new Date(now);
|
|
136
|
+
yearStartDate = new Date(nowDate.getFullYear(), 0, 1, 12, 0, 0);
|
|
137
|
+
this.adapter.log.info(
|
|
138
|
+
`${type}: No contract start found. Setting initial year start to January 1st: ${yearStartDate.toLocaleDateString('de-DE')}`,
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
await this.adapter.setStateAsync(`${type}.statistics.lastYearStart`, yearStartDate.getTime(), true);
|
|
143
|
+
}
|
|
144
|
+
// Update current price
|
|
145
|
+
await this.updateCurrentPrice(type);
|
|
146
|
+
|
|
147
|
+
// Initial cost calculation (wichtig! Sonst bleiben Kosten bei 0)
|
|
148
|
+
if (typeof this.adapter.updateCosts === 'function') {
|
|
149
|
+
await this.adapter.updateCosts(type);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Initialize yearly consumption from initial reading if set
|
|
153
|
+
const initialReadingKey = `${configType}InitialReading`;
|
|
154
|
+
const initialReading = this.adapter.config[initialReadingKey] || 0;
|
|
155
|
+
|
|
156
|
+
if (initialReading > 0) {
|
|
157
|
+
const sensorState = await this.adapter.getForeignStateAsync(sensorDP);
|
|
158
|
+
if (sensorState && typeof sensorState.val === 'number') {
|
|
159
|
+
let currentRaw = sensorState.val;
|
|
160
|
+
|
|
161
|
+
// Apply offset if configured (in original unit)
|
|
162
|
+
const offsetKey = `${configType}Offset`;
|
|
163
|
+
const offset = this.adapter.config[offsetKey] || 0;
|
|
164
|
+
if (offset !== 0) {
|
|
165
|
+
currentRaw = currentRaw - offset;
|
|
166
|
+
this.adapter.log.debug(`Applied offset for ${type}: -${offset}, new value: ${currentRaw}`);
|
|
167
|
+
}
|
|
168
|
+
let yearlyConsumption = Math.max(0, currentRaw - initialReading);
|
|
169
|
+
|
|
170
|
+
// For gas: convert m³ to kWh AFTER calculating the difference
|
|
171
|
+
if (type === 'gas') {
|
|
172
|
+
const brennwert = this.adapter.config.gasBrennwert || 11.5;
|
|
173
|
+
const zZahl = this.adapter.config.gasZahl || 0.95;
|
|
174
|
+
const yearlyVolume = yearlyConsumption;
|
|
175
|
+
yearlyConsumption = calculator.convertGasM3ToKWh(yearlyConsumption, brennwert, zZahl);
|
|
176
|
+
await this.adapter.setStateAsync(`${type}.consumption.yearlyVolume`, yearlyVolume, true);
|
|
177
|
+
this.adapter.log.info(
|
|
178
|
+
`Init yearly ${type}: ${yearlyConsumption.toFixed(2)} kWh = ${(currentRaw - initialReading).toFixed(2)} m³ (current: ${currentRaw.toFixed(2)} m³, initial: ${initialReading} m³)`,
|
|
179
|
+
);
|
|
180
|
+
} else {
|
|
181
|
+
this.adapter.log.info(
|
|
182
|
+
`Init yearly ${type}: ${yearlyConsumption.toFixed(2)} (current: ${currentRaw.toFixed(2)}, initial: ${initialReading})`,
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
await this.adapter.setStateAsync(`${type}.consumption.yearly`, yearlyConsumption, true);
|
|
187
|
+
if (typeof this.adapter.updateCosts === 'function') {
|
|
188
|
+
await this.adapter.updateCosts(type);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Update billing countdown
|
|
194
|
+
if (typeof this.adapter.updateBillingCountdown === 'function') {
|
|
195
|
+
await this.adapter.updateBillingCountdown(type);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
this.adapter.log.debug(`Initial cost calculation completed for ${type}`);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Handles sensor value updates
|
|
203
|
+
*
|
|
204
|
+
* @param {string} type - Utility type
|
|
205
|
+
* @param {string} sensorDP - Sensor datapoint ID
|
|
206
|
+
* @param {number} value - New sensor value
|
|
207
|
+
*/
|
|
208
|
+
async handleSensorUpdate(type, sensorDP, value) {
|
|
209
|
+
if (typeof value !== 'number' || value < 0) {
|
|
210
|
+
this.adapter.log.warn(`Invalid sensor value for ${type}: ${value}`);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
this.adapter.log.debug(`Sensor update for ${type}: ${value}`);
|
|
215
|
+
|
|
216
|
+
const now = Date.now();
|
|
217
|
+
let consumption = value;
|
|
218
|
+
let consumptionM3 = null;
|
|
219
|
+
|
|
220
|
+
const configType = this.getConfigType(type);
|
|
221
|
+
|
|
222
|
+
// Apply offset FIRST
|
|
223
|
+
const offsetKey = `${configType}Offset`;
|
|
224
|
+
const offset = this.adapter.config[offsetKey] || 0;
|
|
225
|
+
if (offset !== 0) {
|
|
226
|
+
consumption = consumption - offset;
|
|
227
|
+
this.adapter.log.debug(`Applied offset for ${type}: -${offset}, new value: ${consumption}`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// For gas, convert m³ to kWh
|
|
231
|
+
if (type === 'gas') {
|
|
232
|
+
const brennwert = this.adapter.config.gasBrennwert || 11.5;
|
|
233
|
+
const zZahl = this.adapter.config.gasZahl || 0.95;
|
|
234
|
+
consumptionM3 = consumption;
|
|
235
|
+
await this.adapter.setStateAsync(`${type}.info.meterReadingVolume`, consumption, true);
|
|
236
|
+
consumption = calculator.convertGasM3ToKWh(consumption, brennwert, zZahl);
|
|
237
|
+
consumption = calculator.roundToDecimals(consumption, 2);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Update meter reading
|
|
241
|
+
await this.adapter.setStateAsync(`${type}.info.meterReading`, consumption, true);
|
|
242
|
+
|
|
243
|
+
// Calculate deltas
|
|
244
|
+
const lastValue = this.lastSensorValues[sensorDP];
|
|
245
|
+
this.lastSensorValues[sensorDP] = consumption;
|
|
246
|
+
|
|
247
|
+
if (lastValue === undefined || consumption <= lastValue) {
|
|
248
|
+
if (lastValue !== undefined && consumption < lastValue) {
|
|
249
|
+
this.adapter.log.warn(
|
|
250
|
+
`${type}: Sensor value decreased (${lastValue} -> ${consumption}). Assuming meter reset or replacement.`,
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
if (typeof this.adapter.updateCosts === 'function') {
|
|
254
|
+
await this.adapter.updateCosts(type);
|
|
255
|
+
}
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const delta = consumption - lastValue;
|
|
260
|
+
this.adapter.log.debug(`${type} delta: ${delta}`);
|
|
261
|
+
|
|
262
|
+
// Track volume for gas
|
|
263
|
+
if (type === 'gas') {
|
|
264
|
+
const brennwert = this.adapter.config.gasBrennwert || 11.5;
|
|
265
|
+
const zZahl = this.adapter.config.gasZahl || 0.95;
|
|
266
|
+
const deltaVolume = delta / (brennwert * zZahl);
|
|
267
|
+
|
|
268
|
+
const dailyVolume = await this.adapter.getStateAsync(`${type}.consumption.dailyVolume`);
|
|
269
|
+
const monthlyVolume = await this.adapter.getStateAsync(`${type}.consumption.monthlyVolume`);
|
|
270
|
+
const yearlyVolume = await this.adapter.getStateAsync(`${type}.consumption.yearlyVolume`);
|
|
271
|
+
|
|
272
|
+
await this.adapter.setStateAsync(
|
|
273
|
+
`${type}.consumption.dailyVolume`,
|
|
274
|
+
calculator.roundToDecimals((dailyVolume?.val || 0) + deltaVolume, 2),
|
|
275
|
+
true,
|
|
276
|
+
);
|
|
277
|
+
await this.adapter.setStateAsync(
|
|
278
|
+
`${type}.consumption.monthlyVolume`,
|
|
279
|
+
calculator.roundToDecimals((monthlyVolume?.val || 0) + deltaVolume, 2),
|
|
280
|
+
true,
|
|
281
|
+
);
|
|
282
|
+
await this.adapter.setStateAsync(
|
|
283
|
+
`${type}.consumption.yearlyVolume`,
|
|
284
|
+
calculator.roundToDecimals((yearlyVolume?.val || 0) + deltaVolume, 3),
|
|
285
|
+
true,
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Update consumption values
|
|
290
|
+
const dailyState = await this.adapter.getStateAsync(`${type}.consumption.daily`);
|
|
291
|
+
await this.adapter.setStateAsync(
|
|
292
|
+
`${type}.consumption.daily`,
|
|
293
|
+
calculator.roundToDecimals((dailyState?.val || 0) + delta, 2),
|
|
294
|
+
true,
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
const monthlyState = await this.adapter.getStateAsync(`${type}.consumption.monthly`);
|
|
298
|
+
await this.adapter.setStateAsync(
|
|
299
|
+
`${type}.consumption.monthly`,
|
|
300
|
+
calculator.roundToDecimals((monthlyState?.val || 0) + delta, 2),
|
|
301
|
+
true,
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
// HT/NT tracking
|
|
305
|
+
const htNtEnabledKey = `${configType}HtNtEnabled`;
|
|
306
|
+
if (this.adapter.config[htNtEnabledKey]) {
|
|
307
|
+
const isHT = calculator.isHTTime(this.adapter.config, configType);
|
|
308
|
+
const suffix = isHT ? 'HT' : 'NT';
|
|
309
|
+
|
|
310
|
+
const dHTNT = await this.adapter.getStateAsync(`${type}.consumption.daily${suffix}`);
|
|
311
|
+
await this.adapter.setStateAsync(
|
|
312
|
+
`${type}.consumption.daily${suffix}`,
|
|
313
|
+
calculator.roundToDecimals((dHTNT?.val || 0) + delta, 2),
|
|
314
|
+
true,
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
const mHTNT = await this.adapter.getStateAsync(`${type}.consumption.monthly${suffix}`);
|
|
318
|
+
await this.adapter.setStateAsync(
|
|
319
|
+
`${type}.consumption.monthly${suffix}`,
|
|
320
|
+
calculator.roundToDecimals((mHTNT?.val || 0) + delta, 2),
|
|
321
|
+
true,
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
const yHTNT = await this.adapter.getStateAsync(`${type}.consumption.yearly${suffix}`);
|
|
325
|
+
await this.adapter.setStateAsync(
|
|
326
|
+
`${type}.consumption.yearly${suffix}`,
|
|
327
|
+
calculator.roundToDecimals((yHTNT?.val || 0) + delta, 2),
|
|
328
|
+
true,
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Yearly consumption
|
|
333
|
+
const initialReadingKey = `${configType}InitialReading`;
|
|
334
|
+
const initialReading = this.adapter.config[initialReadingKey] || 0;
|
|
335
|
+
|
|
336
|
+
if (initialReading > 0) {
|
|
337
|
+
let yearlyAmount;
|
|
338
|
+
if (type === 'gas') {
|
|
339
|
+
const yearlyM3 = Math.max(0, (consumptionM3 || 0) - initialReading);
|
|
340
|
+
await this.adapter.setStateAsync(
|
|
341
|
+
`${type}.consumption.yearlyVolume`,
|
|
342
|
+
calculator.roundToDecimals(yearlyM3, 2),
|
|
343
|
+
true,
|
|
344
|
+
);
|
|
345
|
+
const brennwert = this.adapter.config.gasBrennwert || 11.5;
|
|
346
|
+
const zZahl = this.adapter.config.gasZahl || 0.95;
|
|
347
|
+
yearlyAmount = calculator.convertGasM3ToKWh(yearlyM3, brennwert, zZahl);
|
|
348
|
+
} else {
|
|
349
|
+
yearlyAmount = Math.max(0, consumption - initialReading);
|
|
350
|
+
}
|
|
351
|
+
await this.adapter.setStateAsync(
|
|
352
|
+
`${type}.consumption.yearly`,
|
|
353
|
+
calculator.roundToDecimals(yearlyAmount, 2),
|
|
354
|
+
true,
|
|
355
|
+
);
|
|
356
|
+
} else {
|
|
357
|
+
const yState = await this.adapter.getStateAsync(`${type}.consumption.yearly`);
|
|
358
|
+
await this.adapter.setStateAsync(
|
|
359
|
+
`${type}.consumption.yearly`,
|
|
360
|
+
calculator.roundToDecimals((yState?.val || 0) + delta, 2),
|
|
361
|
+
true,
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (typeof this.adapter.updateCosts === 'function') {
|
|
366
|
+
await this.adapter.updateCosts(type);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
await this.adapter.setStateAsync(`${type}.consumption.lastUpdate`, now, true);
|
|
370
|
+
await this.adapter.setStateAsync(`${type}.info.lastSync`, now, true);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Updates the current price display
|
|
375
|
+
*
|
|
376
|
+
* @param {string} type - Utility type
|
|
377
|
+
*/
|
|
378
|
+
async updateCurrentPrice(type) {
|
|
379
|
+
const configType = this.getConfigType(type);
|
|
380
|
+
|
|
381
|
+
// Check for HT/NT
|
|
382
|
+
const htNtEnabledKey = `${configType}HtNtEnabled`;
|
|
383
|
+
const htNtEnabled = this.adapter.config[htNtEnabledKey] || false;
|
|
384
|
+
|
|
385
|
+
let tariffName = 'Standard';
|
|
386
|
+
let activePrice = 0;
|
|
387
|
+
|
|
388
|
+
if (htNtEnabled) {
|
|
389
|
+
const isHT = calculator.isHTTime(this.adapter.config, configType);
|
|
390
|
+
if (isHT) {
|
|
391
|
+
activePrice = this.adapter.config[`${configType}HtPrice`] || 0;
|
|
392
|
+
tariffName = 'Haupttarif (HT)';
|
|
393
|
+
} else {
|
|
394
|
+
activePrice = this.adapter.config[`${configType}NtPrice`] || 0;
|
|
395
|
+
tariffName = 'Nebentarif (NT)';
|
|
396
|
+
}
|
|
397
|
+
} else {
|
|
398
|
+
const priceKey = `${configType}Preis`;
|
|
399
|
+
activePrice = this.adapter.config[priceKey] || 0;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
await this.adapter.setStateAsync(`${type}.info.currentPrice`, calculator.roundToDecimals(activePrice, 4), true);
|
|
403
|
+
await this.adapter.setStateAsync(`${type}.info.currentTariff`, tariffName, true);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
module.exports = ConsumptionManager;
|