iobroker.pv-notifications 1.0.92 → 1.0.98
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 +13 -0
- package/admin/jsonConfig.json +10 -0
- package/io-package.json +14 -1
- package/main.js +92 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -339,6 +339,19 @@ sadam6752@gmail.com
|
|
|
339
339
|
### **WORK IN PROGRESS**
|
|
340
340
|
-->
|
|
341
341
|
|
|
342
|
+
### 1.0.98 (2026-03-01)
|
|
343
|
+
|
|
344
|
+
* (FIX) Weekly/monthly stats now read directly from external states using getForeignStateAsync (not from internal states)
|
|
345
|
+
|
|
346
|
+
### 1.0.97 (2026-03-01)
|
|
347
|
+
|
|
348
|
+
* (FIX) Weekly/monthly statistics now read from internal states (statistics.currentTotalProduction, etc.) instead of external config
|
|
349
|
+
|
|
350
|
+
### 1.0.93 (2026-02-27)
|
|
351
|
+
|
|
352
|
+
* (FIX) size attributes (xs, xl) added for number fields in jsonConfig.json (E5507)
|
|
353
|
+
* (FIX) VSCode schema definitions updated for io-package.json and jsonConfig.json (W4040, W4042)
|
|
354
|
+
|
|
342
355
|
### 1.0.92 (2026-02-27)
|
|
343
356
|
|
|
344
357
|
* (ADD) VSCode settings added with JSON schema definitions (S4036)
|
package/admin/jsonConfig.json
CHANGED
|
@@ -184,9 +184,11 @@
|
|
|
184
184
|
"batteryCapacityWh": {
|
|
185
185
|
"type": "number",
|
|
186
186
|
"label": "label_batteryCapacityWh",
|
|
187
|
+
"xs": 12,
|
|
187
188
|
"sm": 6,
|
|
188
189
|
"md": 6,
|
|
189
190
|
"lg": 6,
|
|
191
|
+
"xl": 6,
|
|
190
192
|
"min": 1000,
|
|
191
193
|
"max": 100000,
|
|
192
194
|
"step": 100
|
|
@@ -194,36 +196,44 @@
|
|
|
194
196
|
"thresholdFull": {
|
|
195
197
|
"type": "number",
|
|
196
198
|
"label": "label_thresholdFull",
|
|
199
|
+
"xs": 12,
|
|
197
200
|
"sm": 3,
|
|
198
201
|
"md": 3,
|
|
199
202
|
"lg": 3,
|
|
203
|
+
"xl": 3,
|
|
200
204
|
"min": 0,
|
|
201
205
|
"max": 100
|
|
202
206
|
},
|
|
203
207
|
"thresholdEmpty": {
|
|
204
208
|
"type": "number",
|
|
205
209
|
"label": "label_thresholdEmpty",
|
|
210
|
+
"xs": 12,
|
|
206
211
|
"sm": 3,
|
|
207
212
|
"md": 3,
|
|
208
213
|
"lg": 3,
|
|
214
|
+
"xl": 3,
|
|
209
215
|
"min": 0,
|
|
210
216
|
"max": 100
|
|
211
217
|
},
|
|
212
218
|
"thresholdResetFull": {
|
|
213
219
|
"type": "number",
|
|
214
220
|
"label": "label_thresholdResetFull",
|
|
221
|
+
"xs": 12,
|
|
215
222
|
"sm": 3,
|
|
216
223
|
"md": 3,
|
|
217
224
|
"lg": 3,
|
|
225
|
+
"xl": 3,
|
|
218
226
|
"min": 0,
|
|
219
227
|
"max": 100
|
|
220
228
|
},
|
|
221
229
|
"thresholdResetEmpty": {
|
|
222
230
|
"type": "number",
|
|
223
231
|
"label": "label_thresholdResetEmpty",
|
|
232
|
+
"xs": 12,
|
|
224
233
|
"sm": 3,
|
|
225
234
|
"md": 3,
|
|
226
235
|
"lg": 3,
|
|
236
|
+
"xl": 3,
|
|
227
237
|
"min": 0,
|
|
228
238
|
"max": 100
|
|
229
239
|
},
|
package/io-package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "pv-notifications",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.98",
|
|
5
5
|
"titleLang": {
|
|
6
6
|
"en": "PV Notifications",
|
|
7
7
|
"de": "PV-Benachrichtigungen",
|
|
@@ -67,6 +67,19 @@
|
|
|
67
67
|
}
|
|
68
68
|
],
|
|
69
69
|
"news": {
|
|
70
|
+
"1.0.93": {
|
|
71
|
+
"en": "Repository checker fixes: size attributes added for number fields (batteryCapacityWh, thresholdFull/Empty/ResetFull/ResetEmpty), VSCode schema definitions updated",
|
|
72
|
+
"de": "Repository-Checker-Fixes: size-Attribute für number-Felder hinzugefügt (batteryCapacityWh, thresholdFull/Empty/ResetFull/ResetEmpty), VSCode-Schema-Definitionen aktualisiert",
|
|
73
|
+
"ru": "Исправления репозитория: добавлены атрибуты size для числовых полей (batteryCapacityWh, thresholdFull/Empty/ResetFull/ResetEmpty), обновлены определения схемы VSCode",
|
|
74
|
+
"pt": "Correções do repositório: atributos size adicionados para campos numéricos (batteryCapacityWh, thresholdFull/Empty/ResetFull/ResetEmpty), definições de esquema VSCode atualizadas",
|
|
75
|
+
"nl": "Repository checker fixes: size-attributen toegevoegd voor nummervelden (batteryCapacityWh, thresholdFull/Empty/ResetFull/ResetEmpty), VSCode-schema-definities bijgewerkt",
|
|
76
|
+
"fr": "Corrections du dépôt : attributs size ajoutés pour les champs numériques (batteryCapacityWh, thresholdFull/Empty/ResetFull/ResetEmpty), définitions de schéma VSCode mises à jour",
|
|
77
|
+
"it": "Correzioni del repository: aggiunti attributi size per i campi numerici (batteryCapacityWh, thresholdFull/Empty/ResetFull/ResetEmpty), aggiornate definizioni di schema VSCode",
|
|
78
|
+
"es": "Correcciones del repositorio: atributos size agregados para campos numéricos (batteryCapacityWh, thresholdFull/Empty/ResetFull/ResetEmpty), definiciones de esquema VSCode actualizadas",
|
|
79
|
+
"pl": "Poprawki repozytorium: dodano atrybuty size dla pól liczbowych (batteryCapacityWh, thresholdFull/Empty/ResetFull/ResetEmpty), zaktualizowano definicje schematu VSCode",
|
|
80
|
+
"uk": "Виправлення репозиторію: додано атрибути size для числових полів (batteryCapacityWh, thresholdFull/Empty/ResetFull/ResetEmpty), оновлено визначення схеми VSCode",
|
|
81
|
+
"zh-cn": "仓库修复:已为数字字段添加 size 属性(batteryCapacityWh, thresholdFull/Empty/ResetFull/ResetEmpty),已更新 VSCode 架构定义"
|
|
82
|
+
},
|
|
70
83
|
"1.0.92": {
|
|
71
84
|
"en": "VSCode settings added with JSON schema definitions for better development experience",
|
|
72
85
|
"de": "VSCode-Einstellungen mit JSON-Schema-Definitionen für bessere Entwicklungserfahrung hinzugefügt",
|
package/main.js
CHANGED
|
@@ -414,6 +414,38 @@ class PvNotifications extends utils.Adapter {
|
|
|
414
414
|
this.stats.lastStatsReset = today;
|
|
415
415
|
await this.saveStatistics();
|
|
416
416
|
}
|
|
417
|
+
|
|
418
|
+
// Load saved last week data from states
|
|
419
|
+
const lastWeekProduction = await this.getStateAsync('statistics.lastWeekProduction');
|
|
420
|
+
const lastWeekConsumption = await this.getStateAsync('statistics.lastWeekConsumption');
|
|
421
|
+
const lastWeekFeedIn = await this.getStateAsync('statistics.lastWeekFeedIn');
|
|
422
|
+
const lastWeekGridPower = await this.getStateAsync('statistics.lastWeekGridPower');
|
|
423
|
+
const lastWeekFullCycles = await this.getStateAsync('statistics.lastWeekFullCycles');
|
|
424
|
+
const lastWeekEmptyCycles = await this.getStateAsync('statistics.lastWeekEmptyCycles');
|
|
425
|
+
|
|
426
|
+
this.stats.lastWeekProduction = lastWeekProduction && lastWeekProduction.val !== null ? lastWeekProduction.val : 0;
|
|
427
|
+
this.stats.lastWeekConsumption = lastWeekConsumption && lastWeekConsumption.val !== null ? lastWeekConsumption.val : 0;
|
|
428
|
+
this.stats.lastWeekFeedIn = lastWeekFeedIn && lastWeekFeedIn.val !== null ? lastWeekFeedIn.val : 0;
|
|
429
|
+
this.stats.lastWeekGridPower = lastWeekGridPower && lastWeekGridPower.val !== null ? lastWeekGridPower.val : 0;
|
|
430
|
+
this.stats.lastWeekFullCycles = lastWeekFullCycles && lastWeekFullCycles.val !== null ? lastWeekFullCycles.val : 0;
|
|
431
|
+
this.stats.lastWeekEmptyCycles = lastWeekEmptyCycles && lastWeekEmptyCycles.val !== null ? lastWeekEmptyCycles.val : 0;
|
|
432
|
+
|
|
433
|
+
// Load saved last month data from states
|
|
434
|
+
const lastMonthProduction = await this.getStateAsync('statistics.lastMonthProduction');
|
|
435
|
+
const lastMonthConsumption = await this.getStateAsync('statistics.lastMonthConsumption');
|
|
436
|
+
const lastMonthFeedIn = await this.getStateAsync('statistics.lastMonthFeedIn');
|
|
437
|
+
const lastMonthGridPower = await this.getStateAsync('statistics.lastMonthGridPower');
|
|
438
|
+
const lastMonthFullCycles = await this.getStateAsync('statistics.lastMonthFullCycles');
|
|
439
|
+
const lastMonthEmptyCycles = await this.getStateAsync('statistics.lastMonthEmptyCycles');
|
|
440
|
+
|
|
441
|
+
this.stats.lastMonthProduction = lastMonthProduction && lastMonthProduction.val !== null ? lastMonthProduction.val : 0;
|
|
442
|
+
this.stats.lastMonthConsumption = lastMonthConsumption && lastMonthConsumption.val !== null ? lastMonthConsumption.val : 0;
|
|
443
|
+
this.stats.lastMonthFeedIn = lastMonthFeedIn && lastMonthFeedIn.val !== null ? lastMonthFeedIn.val : 0;
|
|
444
|
+
this.stats.lastMonthGridPower = lastMonthGridPower && lastMonthGridPower.val !== null ? lastMonthGridPower.val : 0;
|
|
445
|
+
this.stats.lastMonthFullCycles = lastMonthFullCycles && lastMonthFullCycles.val !== null ? lastMonthFullCycles.val : 0;
|
|
446
|
+
this.stats.lastMonthEmptyCycles = lastMonthEmptyCycles && lastMonthEmptyCycles.val !== null ? lastMonthEmptyCycles.val : 0;
|
|
447
|
+
|
|
448
|
+
this.log.info('Statistics loaded from states');
|
|
417
449
|
} catch (e) {
|
|
418
450
|
this.log.error(`Error loading statistics: ${e.message}`);
|
|
419
451
|
}
|
|
@@ -528,24 +560,29 @@ class PvNotifications extends utils.Adapter {
|
|
|
528
560
|
return;
|
|
529
561
|
}
|
|
530
562
|
|
|
531
|
-
// Update other data points (Production, Consumption, etc.)
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
563
|
+
// Update other data points (Production, Consumption, etc.) - only ack states
|
|
564
|
+
if (state.ack) {
|
|
565
|
+
if (id === this.config.totalProduction) {
|
|
566
|
+
await this.setStateAsync('statistics.currentTotalProduction', state.val, true);
|
|
567
|
+
this.log.debug(`Updated currentTotalProduction: ${state.val}`);
|
|
568
|
+
}
|
|
569
|
+
if (id === this.config.feedIn) {
|
|
570
|
+
await this.setStateAsync('statistics.currentFeedIn', state.val, true);
|
|
571
|
+
this.log.debug(`Updated currentFeedIn: ${state.val}`);
|
|
572
|
+
}
|
|
573
|
+
if (id === this.config.consumption) {
|
|
574
|
+
await this.setStateAsync('statistics.currentConsumption', state.val, true);
|
|
575
|
+
this.log.debug(`Updated currentConsumption: ${state.val}`);
|
|
576
|
+
}
|
|
577
|
+
if (id === this.config.gridPower) {
|
|
578
|
+
await this.setStateAsync('statistics.currentGridPower', state.val, true);
|
|
579
|
+
this.log.debug(`Updated currentGridPower: ${state.val}`);
|
|
580
|
+
}
|
|
581
|
+
if (id === this.config.powerProduction) {
|
|
582
|
+
await this.setStateAsync('statistics.currentPower', state.val, true);
|
|
583
|
+
this.log.debug(`Updated currentPower: ${state.val}`);
|
|
584
|
+
}
|
|
547
585
|
}
|
|
548
|
-
// }
|
|
549
586
|
}
|
|
550
587
|
}
|
|
551
588
|
|
|
@@ -1166,7 +1203,9 @@ ${statusText}`;
|
|
|
1166
1203
|
const now = new Date();
|
|
1167
1204
|
const hours = now.getHours();
|
|
1168
1205
|
const minutes = now.getMinutes();
|
|
1169
|
-
const
|
|
1206
|
+
const jsDay = now.getDay(); // JavaScript: 0=So, 1=Mo, ..., 6=Sa
|
|
1207
|
+
// Umwandeln in ioBroker-Format: 0=Mo, 1=Di, ..., 6=So
|
|
1208
|
+
const day = jsDay === 0 ? 6 : jsDay - 1;
|
|
1170
1209
|
const date = now.getDate();
|
|
1171
1210
|
|
|
1172
1211
|
// Alle 5 Minuten: Statistik prüfen (um :00, :05, :10, ...)
|
|
@@ -1229,16 +1268,25 @@ ${statusText}`;
|
|
|
1229
1268
|
/**
|
|
1230
1269
|
* Reset weekly statistics
|
|
1231
1270
|
*/
|
|
1232
|
-
resetWeeklyStats() {
|
|
1233
|
-
const
|
|
1271
|
+
async resetWeeklyStats() {
|
|
1272
|
+
const jsDay = new Date().getDay(); // JavaScript: 0=So, 1=Mo, ..., 6=Sa
|
|
1273
|
+
// Umwandeln in ioBroker-Format: 0=Mo, 1=Di, ..., 6=So
|
|
1274
|
+
const today = jsDay === 0 ? 6 : jsDay - 1;
|
|
1275
|
+
|
|
1234
1276
|
if (today === this.config.statsWeekDay && today !== this.stats.lastWeekReset) {
|
|
1235
1277
|
this.log.info('Resetting weekly statistics');
|
|
1236
1278
|
|
|
1237
|
-
// Aktuelle Daten
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1279
|
+
// Aktuelle Daten aus internen States lesen (aktualisiert in Echtzeit)
|
|
1280
|
+
// Fallback: Wenn interne States leer, direkt aus externen States lesen
|
|
1281
|
+
const totalProd = await this.getForeignStateAsync(this.config.totalProduction);
|
|
1282
|
+
const consumption = await this.getForeignStateAsync(this.config.consumption);
|
|
1283
|
+
const feedIn = await this.getForeignStateAsync(this.config.feedIn);
|
|
1284
|
+
const gridPower = await this.getForeignStateAsync(this.config.gridPower);
|
|
1285
|
+
|
|
1286
|
+
this.stats.lastWeekProduction = totalProd && totalProd.val !== null ? totalProd.val : 0;
|
|
1287
|
+
this.stats.lastWeekConsumption = consumption && consumption.val !== null ? consumption.val : 0;
|
|
1288
|
+
this.stats.lastWeekFeedIn = feedIn && feedIn.val !== null ? feedIn.val : 0;
|
|
1289
|
+
this.stats.lastWeekGridPower = gridPower && gridPower.val !== null ? gridPower.val : 0;
|
|
1242
1290
|
this.stats.lastWeekFullCycles = this.stats.weekFullCycles;
|
|
1243
1291
|
this.stats.lastWeekEmptyCycles = this.stats.weekEmptyCycles;
|
|
1244
1292
|
|
|
@@ -1248,14 +1296,15 @@ ${statusText}`;
|
|
|
1248
1296
|
this.stats.lastWeekReset = today;
|
|
1249
1297
|
|
|
1250
1298
|
this.saveStatistics();
|
|
1251
|
-
this.
|
|
1299
|
+
this.log.info(`Weekly stats saved: Production=${this.stats.lastWeekProduction} kWh`);
|
|
1300
|
+
// KEIN Senden hier - Senden erfolgt nur in startScheduledTasks() zur konfigurierten Zeit
|
|
1252
1301
|
}
|
|
1253
1302
|
}
|
|
1254
1303
|
|
|
1255
1304
|
/**
|
|
1256
1305
|
* Monatsstatistik zurücksetzen
|
|
1257
1306
|
*/
|
|
1258
|
-
resetMonthlyStats() {
|
|
1307
|
+
async resetMonthlyStats() {
|
|
1259
1308
|
if (!this.config.monthlyStatsEnabled) {
|
|
1260
1309
|
return;
|
|
1261
1310
|
}
|
|
@@ -1263,23 +1312,30 @@ ${statusText}`;
|
|
|
1263
1312
|
const today = new Date().getDate();
|
|
1264
1313
|
const now = new Date();
|
|
1265
1314
|
const hours = now.getHours();
|
|
1266
|
-
const
|
|
1267
|
-
|
|
1315
|
+
const minutes = now.getMinutes();
|
|
1316
|
+
const [statHours, statMinutes] = this.config.monthlyStatsTime.split(':').map(Number);
|
|
1268
1317
|
|
|
1269
|
-
// Daten am konfigurierten Tag
|
|
1270
|
-
if (today === this.config.monthlyStatsDay && this.stats.lastMonthReset !== today &&
|
|
1318
|
+
// Daten am konfigurierten Tag zur konfigurierten Zeit speichern (nicht vorher)
|
|
1319
|
+
if (today === this.config.monthlyStatsDay && this.stats.lastMonthReset !== today &&
|
|
1320
|
+
(hours > statHours || (hours === statHours && minutes >= statMinutes))) {
|
|
1271
1321
|
this.log.info('Resetting monthly statistics');
|
|
1272
1322
|
|
|
1273
|
-
// Aktuelle Daten
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1323
|
+
// Aktuelle Daten aus externen States lesen (direkter Zugriff)
|
|
1324
|
+
const totalProd = await this.getForeignStateAsync(this.config.monthlyProduction);
|
|
1325
|
+
const consumption = await this.getForeignStateAsync(this.config.monthlyConsumption);
|
|
1326
|
+
const feedIn = await this.getForeignStateAsync(this.config.monthlyFeedIn);
|
|
1327
|
+
const gridPower = await this.getForeignStateAsync(this.config.monthlyGridPower);
|
|
1328
|
+
|
|
1329
|
+
this.stats.lastMonthProduction = totalProd && totalProd.val !== null ? totalProd.val : 0;
|
|
1330
|
+
this.stats.lastMonthConsumption = consumption && consumption.val !== null ? consumption.val : 0;
|
|
1331
|
+
this.stats.lastMonthFeedIn = feedIn && feedIn.val !== null ? feedIn.val : 0;
|
|
1332
|
+
this.stats.lastMonthGridPower = gridPower && gridPower.val !== null ? gridPower.val : 0;
|
|
1278
1333
|
this.stats.lastMonthFullCycles = this.stats.fullCycles;
|
|
1279
1334
|
this.stats.lastMonthEmptyCycles = this.stats.emptyCycles;
|
|
1280
1335
|
|
|
1281
1336
|
this.stats.lastMonthReset = today;
|
|
1282
1337
|
this.saveStatistics();
|
|
1338
|
+
this.log.info(`Monthly stats saved: Production=${this.stats.lastMonthProduction} kWh`);
|
|
1283
1339
|
}
|
|
1284
1340
|
}
|
|
1285
1341
|
|