iobroker.utility-monitor 1.5.1 → 1.6.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.
@@ -0,0 +1,650 @@
1
+ 'use strict';
2
+
3
+ const STATE_ROLES = require('./roles');
4
+
5
+ /**
6
+ * Creates the complete state structure for a utility type (gas, water, electricity)
7
+ *
8
+ * @param {object} adapter - The adapter instance
9
+ * @param {string} type - Utility type: 'gas', 'water', or 'electricity'
10
+ * @param {object} _config - Configuration for this utility
11
+ * @returns {Promise<void>}
12
+ */
13
+ async function createUtilityStateStructure(adapter, type, _config = {}) {
14
+ const labels = {
15
+ gas: { name: 'Gas', unit: 'kWh', volumeUnit: 'm³' },
16
+ water: { name: 'Wasser', unit: 'm³' },
17
+ electricity: { name: 'Strom', unit: 'kWh' },
18
+ pv: { name: 'PV', unit: 'kWh', consumption: 'Einspeisung', cost: 'Vergütung' },
19
+ };
20
+
21
+ const label = labels[type];
22
+ if (!label) {
23
+ adapter.log.error(`MISSING LABEL for type "${type}" in createUtilityStateStructure!`);
24
+ return;
25
+ }
26
+
27
+ // Create main channel
28
+ await adapter.setObjectNotExistsAsync(type, {
29
+ type: 'channel',
30
+ common: { name: `${label.name}-Überwachung` },
31
+ native: {},
32
+ });
33
+
34
+ // --- CONSUMPTION STATES ---
35
+ await adapter.setObjectNotExistsAsync(`${type}.consumption`, {
36
+ type: 'channel',
37
+ common: { name: label.consumption || 'Verbrauch' },
38
+ native: {},
39
+ });
40
+
41
+ if (type === 'gas') {
42
+ const volumeStates = [
43
+ { id: 'dailyVolume', name: 'Täglicher Verbrauch (m³)' },
44
+ { id: 'monthlyVolume', name: 'Monatlicher Verbrauch (m³)' },
45
+ { id: 'yearlyVolume', name: 'Jährlicher Verbrauch (m³)' },
46
+ ];
47
+ for (const state of volumeStates) {
48
+ await adapter.setObjectNotExistsAsync(`${type}.consumption.${state.id}`, {
49
+ type: 'state',
50
+ common: {
51
+ name: state.name,
52
+ type: 'number',
53
+ role: STATE_ROLES.consumption,
54
+ read: true,
55
+ write: false,
56
+ unit: 'm³',
57
+ def: 0,
58
+ },
59
+ native: {},
60
+ });
61
+ }
62
+ }
63
+
64
+ const mainPeriods = [
65
+ { id: 'daily', name: 'Tages' },
66
+ { id: 'monthly', name: 'Monats' },
67
+ { id: 'yearly', name: 'Jahres' },
68
+ { id: 'weekly', name: 'Wochen' },
69
+ ];
70
+
71
+ for (const period of mainPeriods) {
72
+ await adapter.setObjectNotExistsAsync(`${type}.consumption.${period.id}`, {
73
+ type: 'state',
74
+ common: {
75
+ name: `${period.name}-${(label.consumption || 'Verbrauch').toLowerCase()} (${label.unit})`,
76
+ type: 'number',
77
+ role: STATE_ROLES.consumption,
78
+ read: true,
79
+ write: false,
80
+ unit: label.unit,
81
+ def: 0,
82
+ },
83
+ native: {},
84
+ });
85
+ }
86
+
87
+ const configTypeMap = { electricity: 'strom', water: 'wasser', gas: 'gas', pv: 'pv' };
88
+ const configType = configTypeMap[type] || type;
89
+ const htNtEnabled = _config[`${configType}HtNtEnabled`];
90
+
91
+ if (htNtEnabled) {
92
+ const htNtStates = [
93
+ 'dailyHT',
94
+ 'dailyNT',
95
+ 'monthlyHT',
96
+ 'monthlyNT',
97
+ 'yearlyHT',
98
+ 'yearlyNT',
99
+ 'weeklyHT',
100
+ 'weeklyNT',
101
+ ];
102
+ const htNtLabels = {
103
+ dailyHT: 'Tagesverbrauch Haupttarif (HT)',
104
+ dailyNT: 'Tagesverbrauch Nebentarif (NT)',
105
+ monthlyHT: 'Monatsverbrauch Haupttarif (HT)',
106
+ monthlyNT: 'Monatsverbrauch Nebentarif (NT)',
107
+ yearlyHT: 'Jahresverbrauch Haupttarif (HT)',
108
+ yearlyNT: 'Jahresverbrauch Nebentarif (NT)',
109
+ weeklyHT: 'Wochenverbrauch Haupttarif (HT)',
110
+ weeklyNT: 'Wochenverbrauch Nebentarif (NT)',
111
+ };
112
+
113
+ for (const id of htNtStates) {
114
+ await adapter.setObjectNotExistsAsync(`${type}.consumption.${id}`, {
115
+ type: 'state',
116
+ common: {
117
+ name: `${htNtLabels[id]} (${label.unit})`,
118
+ type: 'number',
119
+ role: STATE_ROLES.consumption,
120
+ read: true,
121
+ write: false,
122
+ unit: label.unit,
123
+ def: 0,
124
+ },
125
+ native: {},
126
+ });
127
+ }
128
+ }
129
+
130
+ await adapter.setObjectNotExistsAsync(`${type}.consumption.lastUpdate`, {
131
+ type: 'state',
132
+ common: {
133
+ name: 'Letzte Aktualisierung',
134
+ type: 'number',
135
+ role: STATE_ROLES.timestamp,
136
+ read: true,
137
+ write: false,
138
+ },
139
+ native: {},
140
+ });
141
+
142
+ // --- COST STATES ---
143
+ await adapter.setObjectNotExistsAsync(`${type}.costs`, {
144
+ type: 'channel',
145
+ common: { name: label.cost || 'Kosten' },
146
+ native: {},
147
+ });
148
+
149
+ for (const period of mainPeriods) {
150
+ await adapter.setObjectNotExistsAsync(`${type}.costs.${period.id}`, {
151
+ type: 'state',
152
+ common: {
153
+ name: `${period.name}-${(label.cost || 'Kosten').toLowerCase()} (€)`,
154
+ type: 'number',
155
+ role: STATE_ROLES.cost,
156
+ read: true,
157
+ write: false,
158
+ unit: '€',
159
+ def: 0,
160
+ },
161
+ native: {},
162
+ });
163
+ }
164
+
165
+ if (htNtEnabled) {
166
+ const htNtCostStates = [
167
+ 'yearlyHT',
168
+ 'yearlyNT',
169
+ 'monthlyHT',
170
+ 'monthlyNT',
171
+ 'dailyHT',
172
+ 'dailyNT',
173
+ 'weeklyHT',
174
+ 'weeklyNT',
175
+ ];
176
+ const htNtCostLabels = {
177
+ yearlyHT: 'Jahreskosten Haupttarif (HT)',
178
+ yearlyNT: 'Jahreskosten Nebentarif (NT)',
179
+ monthlyHT: 'Monatskosten Haupttarif (HT)',
180
+ monthlyNT: 'Monatskosten Nebentarif (NT)',
181
+ dailyHT: 'Tageskosten Haupttarif (HT)',
182
+ dailyNT: 'Tageskosten Nebentarif (NT)',
183
+ weeklyHT: 'Wochenkosten Haupttarif (HT)',
184
+ weeklyNT: 'Wochenkosten Nebentarif (NT)',
185
+ };
186
+
187
+ for (const id of htNtCostStates) {
188
+ await adapter.setObjectNotExistsAsync(`${type}.costs.${id}`, {
189
+ type: 'state',
190
+ common: {
191
+ name: `${htNtCostLabels[id]} (€)`,
192
+ type: 'number',
193
+ role: STATE_ROLES.cost,
194
+ read: true,
195
+ write: false,
196
+ unit: '€',
197
+ def: 0,
198
+ },
199
+ native: {},
200
+ });
201
+ }
202
+ }
203
+
204
+ const costInfo = [
205
+ {
206
+ id: 'totalYearly',
207
+ name: `Gesamt-${(label.cost || 'Kosten').toLowerCase()} Jahr (Verbrauch + Grundgebühr) (€)`,
208
+ },
209
+ { id: 'annualFee', name: 'Jahresgebühr akkumuliert (€)' },
210
+ { id: 'basicCharge', name: 'Grundgebühr (€/Monat)' },
211
+ { id: 'paidTotal', name: 'Bezahlt gesamt (Abschlag × Monate) (€)' },
212
+ { id: 'balance', name: 'Saldo (Bezahlt - Verbraucht) (€)' },
213
+ ];
214
+
215
+ for (const item of costInfo) {
216
+ await adapter.setObjectNotExistsAsync(`${type}.costs.${item.id}`, {
217
+ type: 'state',
218
+ common: {
219
+ name: item.name,
220
+ type: 'number',
221
+ role: STATE_ROLES.cost,
222
+ read: true,
223
+ write: false,
224
+ unit: '€',
225
+ def: 0,
226
+ },
227
+ native: {},
228
+ });
229
+ }
230
+
231
+ // --- BILLING STATES ---
232
+ await adapter.setObjectNotExistsAsync(`${type}.billing`, {
233
+ type: 'channel',
234
+ common: { name: 'Abrechnungszeitraum' },
235
+ native: {},
236
+ });
237
+
238
+ const billingStates = [
239
+ {
240
+ id: 'endReading',
241
+ name: 'Endzählerstand (manuell eintragen)',
242
+ type: 'number',
243
+ role: STATE_ROLES.meterReading,
244
+ unit: label.volumeUnit || label.unit,
245
+ write: true,
246
+ },
247
+ {
248
+ id: 'closePeriod',
249
+ name: 'Zeitraum jetzt abschließen (Button)',
250
+ type: 'boolean',
251
+ role: 'button',
252
+ write: true,
253
+ def: false,
254
+ },
255
+ { id: 'periodEnd', name: 'Abrechnungszeitraum endet am', type: 'string', role: 'text', def: '' },
256
+ { id: 'daysRemaining', name: 'Tage bis Abrechnungsende', type: 'number', role: 'value', unit: 'Tage', def: 0 },
257
+ {
258
+ id: 'newInitialReading',
259
+ name: 'Neuer Startwert (für Config übernehmen!)',
260
+ type: 'number',
261
+ role: STATE_ROLES.meterReading,
262
+ unit: label.volumeUnit || label.unit,
263
+ def: 0,
264
+ },
265
+ {
266
+ id: 'notificationSent',
267
+ name: 'Benachrichtigung Zählerstand versendet',
268
+ type: 'boolean',
269
+ role: 'indicator',
270
+ def: false,
271
+ },
272
+ {
273
+ id: 'notificationChangeSent',
274
+ name: 'Benachrichtigung Vertragswechsel versendet',
275
+ type: 'boolean',
276
+ role: 'indicator',
277
+ def: false,
278
+ },
279
+ ];
280
+
281
+ for (const s of billingStates) {
282
+ await adapter.setObjectNotExistsAsync(`${type}.billing.${s.id}`, {
283
+ type: 'state',
284
+ common: {
285
+ name: s.name,
286
+ type: s.type,
287
+ role: s.role,
288
+ read: true,
289
+ write: s.write || false,
290
+ unit: s.unit || '',
291
+ def: s.def === undefined ? 0 : s.def,
292
+ },
293
+ native: {},
294
+ });
295
+ }
296
+
297
+ // --- ADJUSTMENT STATES ---
298
+ await adapter.setObjectNotExistsAsync(`${type}.adjustment`, {
299
+ type: 'channel',
300
+ common: { name: 'Manuelle Anpassung' },
301
+ native: {},
302
+ });
303
+
304
+ await adapter.setObjectNotExistsAsync(`${type}.adjustment.value`, {
305
+ type: 'state',
306
+ common: {
307
+ name: 'Korrekturwert (Differenz zum echten Zähler)',
308
+ type: 'number',
309
+ role: STATE_ROLES.value,
310
+ read: true,
311
+ write: true,
312
+ unit: label.volumeUnit || label.unit,
313
+ def: 0,
314
+ },
315
+ native: {},
316
+ });
317
+
318
+ await adapter.setObjectNotExistsAsync(`${type}.adjustment.note`, {
319
+ type: 'state',
320
+ common: { name: 'Notiz/Grund für Anpassung', type: 'string', role: 'text', read: true, write: true, def: '' },
321
+ native: {},
322
+ });
323
+
324
+ await adapter.setObjectNotExistsAsync(`${type}.adjustment.applied`, {
325
+ type: 'state',
326
+ common: {
327
+ name: 'Zeitstempel der letzten Anwendung',
328
+ type: 'number',
329
+ role: 'value.time',
330
+ read: true,
331
+ write: false,
332
+ def: 0,
333
+ },
334
+ native: {},
335
+ });
336
+
337
+ // --- INFO STATES ---
338
+ await adapter.setObjectNotExistsAsync(`${type}.info`, {
339
+ type: 'channel',
340
+ common: { name: 'Informationen' },
341
+ native: {},
342
+ });
343
+
344
+ if (type === 'gas') {
345
+ await adapter.setObjectNotExistsAsync(`${type}.info.meterReadingVolume`, {
346
+ type: 'state',
347
+ common: {
348
+ name: `Zählerstand Volumen (${label.volumeUnit})`,
349
+ type: 'number',
350
+ role: STATE_ROLES.meterReading,
351
+ read: true,
352
+ write: false,
353
+ unit: label.volumeUnit || label.unit,
354
+ def: 0,
355
+ },
356
+ native: {},
357
+ });
358
+ }
359
+
360
+ await adapter.setObjectNotExistsAsync(`${type}.info.meterReading`, {
361
+ type: 'state',
362
+ common: {
363
+ name: `Zählerstand (${label.unit})`,
364
+ type: 'number',
365
+ role: STATE_ROLES.meterReading,
366
+ read: true,
367
+ write: false,
368
+ unit: label.unit,
369
+ def: 0,
370
+ },
371
+ native: {},
372
+ });
373
+
374
+ await adapter.setObjectNotExistsAsync(`${type}.info.currentPrice`, {
375
+ type: 'state',
376
+ common: {
377
+ name: `Aktueller Preis (€/${label.unit})`,
378
+ type: 'number',
379
+ role: STATE_ROLES.price,
380
+ read: true,
381
+ write: false,
382
+ unit: `€/${label.unit}`,
383
+ def: 0,
384
+ },
385
+ native: {},
386
+ });
387
+
388
+ await adapter.setObjectNotExistsAsync(`${type}.info.lastSync`, {
389
+ type: 'state',
390
+ common: {
391
+ name: 'Letzte Synchronisation',
392
+ type: 'number',
393
+ role: STATE_ROLES.timestamp,
394
+ read: true,
395
+ write: false,
396
+ },
397
+ native: {},
398
+ });
399
+
400
+ await adapter.setObjectNotExistsAsync(`${type}.info.sensorActive`, {
401
+ type: 'state',
402
+ common: {
403
+ name: 'Sensor aktiv',
404
+ type: 'boolean',
405
+ role: STATE_ROLES.indicator,
406
+ read: true,
407
+ write: false,
408
+ def: false,
409
+ },
410
+ native: {},
411
+ });
412
+
413
+ await adapter.setObjectNotExistsAsync(`${type}.info.currentTariff`, {
414
+ type: 'state',
415
+ common: {
416
+ name: 'Aktueller Tarif (HT/NT)',
417
+ type: 'string',
418
+ role: 'text',
419
+ read: true,
420
+ write: false,
421
+ def: 'Standard',
422
+ },
423
+ native: {},
424
+ });
425
+
426
+ // --- STATISTICS STATES (NEW STRUCTURE) ---
427
+ await adapter.setObjectNotExistsAsync(`${type}.statistics`, {
428
+ type: 'channel',
429
+ common: { name: 'Statistiken' },
430
+ native: {},
431
+ });
432
+
433
+ // Consumption Statistics
434
+ await adapter.setObjectNotExistsAsync(`${type}.statistics.consumption`, {
435
+ type: 'channel',
436
+ common: { name: 'Verbrauch' },
437
+ native: {},
438
+ });
439
+
440
+ const statConsumption = [
441
+ { id: 'averageDaily', name: `Durchschnitt pro Tag (${label.unit})` },
442
+ { id: 'averageMonthly', name: `Durchschnitt pro Monat (${label.unit})` },
443
+ { id: 'lastDay', name: `Verbrauch gestern (${label.unit})` },
444
+ { id: 'lastWeek', name: `Verbrauch letzte Woche (${label.unit})` },
445
+ { id: 'lastMonth', name: `Verbrauch letzter Monat (${label.unit})` },
446
+ { id: 'lastYear', name: `Verbrauch letztes Jahr (${label.unit})` },
447
+ ];
448
+
449
+ for (const item of statConsumption) {
450
+ await adapter.setObjectNotExistsAsync(`${type}.statistics.consumption.${item.id}`, {
451
+ type: 'state',
452
+ common: {
453
+ name: item.name,
454
+ type: 'number',
455
+ role: STATE_ROLES.consumption,
456
+ read: true,
457
+ write: false,
458
+ unit: label.unit,
459
+ def: 0,
460
+ },
461
+ native: {},
462
+ });
463
+ }
464
+
465
+ if (htNtEnabled) {
466
+ const statHTNT = [
467
+ { id: 'lastDayHT', name: `Verbrauch gestern HT (${label.unit})` },
468
+ { id: 'lastDayNT', name: `Verbrauch gestern NT (${label.unit})` },
469
+ { id: 'lastWeekHT', name: `Verbrauch letzte Woche HT (${label.unit})` },
470
+ { id: 'lastWeekNT', name: `Verbrauch letzte Woche NT (${label.unit})` },
471
+ { id: 'lastMonthHT', name: `Verbrauch letzter Monat HT (${label.unit})` },
472
+ { id: 'lastMonthNT', name: `Verbrauch letzter Monat NT (${label.unit})` },
473
+ { id: 'lastYearHT', name: `Verbrauch letztes Jahr HT (${label.unit})` },
474
+ { id: 'lastYearNT', name: `Verbrauch letztes Jahr NT (${label.unit})` },
475
+ ];
476
+ for (const item of statHTNT) {
477
+ await adapter.setObjectNotExistsAsync(`${type}.statistics.consumption.${item.id}`, {
478
+ type: 'state',
479
+ common: {
480
+ name: item.name,
481
+ type: 'number',
482
+ role: STATE_ROLES.consumption,
483
+ read: true,
484
+ write: false,
485
+ unit: label.unit,
486
+ def: 0,
487
+ },
488
+ native: {},
489
+ });
490
+ }
491
+ }
492
+
493
+ if (type === 'gas') {
494
+ const statGasVolume = [
495
+ { id: 'lastDayVolume', name: `Verbrauch gestern (${label.volumeUnit})` },
496
+ { id: 'lastWeekVolume', name: `Verbrauch letzte Woche (${label.volumeUnit})` },
497
+ { id: 'lastMonthVolume', name: `Verbrauch letzter Monat (${label.volumeUnit})` },
498
+ { id: 'lastYearVolume', name: `Verbrauch letztes Jahr (${label.volumeUnit})` },
499
+ ];
500
+ for (const item of statGasVolume) {
501
+ await adapter.setObjectNotExistsAsync(`${type}.statistics.consumption.${item.id}`, {
502
+ type: 'state',
503
+ common: {
504
+ name: item.name,
505
+ type: 'number',
506
+ role: STATE_ROLES.consumption,
507
+ read: true,
508
+ write: false,
509
+ unit: label.volumeUnit || label.unit,
510
+ def: 0,
511
+ },
512
+ native: {},
513
+ });
514
+ }
515
+ }
516
+
517
+ // Cost Statistics
518
+ await adapter.setObjectNotExistsAsync(`${type}.statistics.cost`, {
519
+ type: 'channel',
520
+ common: { name: 'Kosten' },
521
+ native: {},
522
+ });
523
+
524
+ const statCosts = [
525
+ { id: 'averageDaily', name: 'Durchschnitt pro Tag (€)' },
526
+ { id: 'averageMonthly', name: 'Durchschnitt pro Monat (€)' },
527
+ { id: 'lastDay', name: 'Kosten gestern (€)' },
528
+ { id: 'lastWeek', name: 'Kosten letzte Woche (€)' },
529
+ { id: 'lastMonth', name: 'Kosten letzter Monat (€)' },
530
+ { id: 'lastYear', name: 'Kosten letztes Jahr (€)' },
531
+ ];
532
+
533
+ for (const item of statCosts) {
534
+ await adapter.setObjectNotExistsAsync(`${type}.statistics.cost.${item.id}`, {
535
+ type: 'state',
536
+ common: {
537
+ name: item.name,
538
+ type: 'number',
539
+ role: STATE_ROLES.cost,
540
+ read: true,
541
+ write: false,
542
+ unit: '€',
543
+ def: 0,
544
+ },
545
+ native: {},
546
+ });
547
+ }
548
+
549
+ if (htNtEnabled) {
550
+ const costHTNT = [
551
+ { id: 'lastDayHT', name: 'Kosten gestern HT (€)' },
552
+ { id: 'lastDayNT', name: 'Kosten gestern NT (€)' },
553
+ { id: 'lastWeekHT', name: 'Kosten letzte Woche HT (€)' },
554
+ { id: 'lastWeekNT', name: 'Kosten letzte Woche NT (€)' },
555
+ { id: 'lastMonthHT', name: 'Kosten letzter Monat HT (€)' },
556
+ { id: 'lastMonthNT', name: 'Kosten letzter Monat NT (€)' },
557
+ { id: 'lastYearHT', name: 'Kosten letztes Jahr HT (€)' },
558
+ { id: 'lastYearNT', name: 'Kosten letztes Jahr NT (€)' },
559
+ ];
560
+ for (const item of costHTNT) {
561
+ await adapter.setObjectNotExistsAsync(`${type}.statistics.cost.${item.id}`, {
562
+ type: 'state',
563
+ common: {
564
+ name: item.name,
565
+ type: 'number',
566
+ role: STATE_ROLES.cost,
567
+ read: true,
568
+ write: false,
569
+ unit: '€',
570
+ def: 0,
571
+ },
572
+ native: {},
573
+ });
574
+ }
575
+ }
576
+
577
+ // Timestamps Statistics
578
+ await adapter.setObjectNotExistsAsync(`${type}.statistics.timestamps`, {
579
+ type: 'channel',
580
+ common: { name: 'Zeitstempel' },
581
+ native: {},
582
+ });
583
+
584
+ const timestamps = [
585
+ { id: 'lastDayStart', name: 'Tageszähler zurückgesetzt am' },
586
+ { id: 'lastWeekStart', name: 'Wochenzähler zurückgesetzt am' },
587
+ { id: 'lastMonthStart', name: 'Monatszähler zurückgesetzt am' },
588
+ { id: 'lastYearStart', name: 'Jahreszähler zurückgesetzt am' },
589
+ ];
590
+
591
+ for (const ts of timestamps) {
592
+ await adapter.setObjectNotExistsAsync(`${type}.statistics.timestamps.${ts.id}`, {
593
+ type: 'state',
594
+ common: { name: ts.name, type: 'number', role: STATE_ROLES.timestamp, read: true, write: false },
595
+ native: {},
596
+ });
597
+ }
598
+
599
+ // --- CLEANUP OLD STATS ---
600
+ const oldStats = [
601
+ 'averageDaily',
602
+ 'averageMonthly',
603
+ 'lastDay',
604
+ 'lastDayHT',
605
+ 'lastDayNT',
606
+ 'lastDayVolume',
607
+ 'lastWeek',
608
+ 'lastWeekVolume',
609
+ 'lastMonth',
610
+ 'lastMonthVolume',
611
+ 'lastDayStart',
612
+ 'lastWeekStart',
613
+ 'lastMonthStart',
614
+ 'lastYearStart',
615
+ ];
616
+ for (const id of oldStats) {
617
+ try {
618
+ const obj = await adapter.getObjectAsync(`${type}.statistics.${id}`);
619
+ if (obj) {
620
+ await adapter.delObjectAsync(`${type}.statistics.${id}`);
621
+ adapter.log.debug(`Deleted old statistics object: ${type}.statistics.${id}`);
622
+ }
623
+ } catch {
624
+ // ignore
625
+ }
626
+ }
627
+
628
+ adapter.log.debug(`State structure created for ${type} (including new statistics)`);
629
+ }
630
+
631
+ /**
632
+ * Deletes all states for a utility type
633
+ *
634
+ * @param {object} adapter - The adapter instance
635
+ * @param {string} type - Utility type: 'gas', 'water', or 'electricity'
636
+ * @returns {Promise<void>}
637
+ */
638
+ async function deleteUtilityStateStructure(adapter, type) {
639
+ try {
640
+ await adapter.delObjectAsync(type, { recursive: true });
641
+ adapter.log.debug(`State structure deleted for ${type}`);
642
+ } catch (error) {
643
+ adapter.log.warn(`Could not delete state structure for ${type}: ${error.message}`);
644
+ }
645
+ }
646
+
647
+ module.exports = {
648
+ createUtilityStateStructure,
649
+ deleteUtilityStateStructure,
650
+ };