iobroker.sbfspot 4.0.6 → 4.1.0
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/.github/workflows/test-and-release.yml +6 -5
- package/LICENSE +1 -1
- package/README.md +11 -1
- package/io-package.json +41 -2
- package/lib/tools.js +2 -2
- package/main.js +79 -278
- package/package.json +17 -17
- package/sbfspot.njsproj +5 -2
- package/widgets/sbfspot/lib/js/flot/jquery.canvaswrapper.js +7 -8
- package/widgets/sbfspot/lib/js/flot/jquery.flot.axislabels.js +215 -0
- package/widgets/sbfspot/lib/js/flot/jquery.flot.drawSeries.js +3 -4
- package/widgets/sbfspot/lib/js/flot/jquery.flot.fillbetween.js +12 -12
- package/widgets/sbfspot/lib/js/flot/jquery.flot.hover.js +7 -8
- package/widgets/sbfspot/lib/js/flot/jquery.flot.js +49 -56
- package/widgets/sbfspot/lib/js/flot/jquery.flot.legend.js +2 -2
- package/widgets/sbfspot/lib/js/flot/jquery.flot.logaxis.js +3 -3
- package/widgets/sbfspot/lib/js/flot/jquery.flot.navigate.js +44 -8
- package/widgets/sbfspot/lib/js/flot/jquery.flot.resize.js +1 -1
- package/widgets/sbfspot/lib/js/flot/jquery.flot.selection.js +11 -1
- package/widgets/sbfspot/lib/js/flot/jquery.flot.stack.js +3 -3
- package/widgets/sbfspot/lib/js/flot/jquery.flot.time.js +110 -108
- package/widgets/sbfspot/lib/js/flot/jquery.flot.touchNavigate.js +1 -1
- package/widgets/sbfspot.html +215 -191
- package/lib/support_tools.js +0 -371
|
@@ -28,7 +28,7 @@ jobs:
|
|
|
28
28
|
node-version: [12.x]
|
|
29
29
|
|
|
30
30
|
steps:
|
|
31
|
-
- uses: actions/checkout@
|
|
31
|
+
- uses: actions/checkout@v2
|
|
32
32
|
- name: Use Node.js ${{ matrix.node-version }}
|
|
33
33
|
uses: actions/setup-node@v1
|
|
34
34
|
with:
|
|
@@ -51,14 +51,14 @@ jobs:
|
|
|
51
51
|
runs-on: ${{ matrix.os }}
|
|
52
52
|
strategy:
|
|
53
53
|
matrix:
|
|
54
|
-
node-version: [
|
|
54
|
+
node-version: [12.x, 14.x, 16.x]
|
|
55
55
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
56
56
|
exclude:
|
|
57
57
|
# Don't test Node.js 8 on Windows. npm is weird here
|
|
58
58
|
- os: windows-latest
|
|
59
59
|
node-version: 8.x
|
|
60
60
|
steps:
|
|
61
|
-
- uses: actions/checkout@
|
|
61
|
+
- uses: actions/checkout@v2
|
|
62
62
|
- name: Use Node.js ${{ matrix.node-version }}
|
|
63
63
|
uses: actions/setup-node@v1
|
|
64
64
|
with:
|
|
@@ -78,7 +78,7 @@ jobs:
|
|
|
78
78
|
if: startsWith(runner.OS, 'windows')
|
|
79
79
|
run: set DEBUG=testing:* & npm run test:integration
|
|
80
80
|
|
|
81
|
-
# TODO: To enable automatic npm releases, create a token on npmjs.org
|
|
81
|
+
# TODO: To enable automatic npm releases, create a token on npmjs.org
|
|
82
82
|
# Enter this token as a GitHub secret (with name NPM_TOKEN) in the repository options
|
|
83
83
|
# Then uncomment the following block:
|
|
84
84
|
|
|
@@ -90,6 +90,7 @@ jobs:
|
|
|
90
90
|
# if: |
|
|
91
91
|
# contains(github.event.head_commit.message, '[skip ci]') == false &&
|
|
92
92
|
# github.event_name == 'push' &&
|
|
93
|
+
# github.event.base_ref == 'refs/heads/master' &&
|
|
93
94
|
# startsWith(github.ref, 'refs/tags/v')
|
|
94
95
|
#
|
|
95
96
|
# runs-on: ubuntu-latest
|
|
@@ -98,7 +99,7 @@ jobs:
|
|
|
98
99
|
# node-version: [12.x]
|
|
99
100
|
#
|
|
100
101
|
# steps:
|
|
101
|
-
# - uses: actions/checkout@
|
|
102
|
+
# - uses: actions/checkout@v2
|
|
102
103
|
# - name: Use Node.js ${{ matrix.node-version }}
|
|
103
104
|
# uses: actions/setup-node@v1
|
|
104
105
|
# with:
|
package/LICENSE
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (C) <2017-
|
|
1
|
+
Copyright (C) <2017-2022> <info@rg-engineering.eu>
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
4
|
|
package/README.md
CHANGED
|
@@ -51,6 +51,16 @@ sometimes npm intall must be called more then one time to successfully install a
|
|
|
51
51
|
|
|
52
52
|
## Changelog
|
|
53
53
|
|
|
54
|
+
### 4.1.0 (2022-04-21)
|
|
55
|
+
* (René) add datapoint to show when data uploaded to sbfspot
|
|
56
|
+
|
|
57
|
+
### 4.0.8 (2021-07-11)
|
|
58
|
+
* (René) bug fix color of labels in widget
|
|
59
|
+
|
|
60
|
+
### 4.0.7 (2021-10-30)
|
|
61
|
+
* (René) see issue #62: avoid endless loop
|
|
62
|
+
* (René) update flot to 4.2.2
|
|
63
|
+
|
|
54
64
|
### 4.0.6 (2021-07-09)
|
|
55
65
|
* (René) bug fix data types
|
|
56
66
|
|
|
@@ -175,7 +185,7 @@ sometimes npm intall must be called more then one time to successfully install a
|
|
|
175
185
|
|
|
176
186
|
|
|
177
187
|
## License
|
|
178
|
-
Copyright (C) <2017-
|
|
188
|
+
Copyright (C) <2017-2022> <info@rg-engineering.eu>
|
|
179
189
|
|
|
180
190
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
181
191
|
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "sbfspot",
|
|
4
|
-
"version": "4.0
|
|
4
|
+
"version": "4.1.0",
|
|
5
5
|
"news": {
|
|
6
|
+
"4.1.0": {
|
|
7
|
+
"en": "add datapoint to show when data uploaded to sbfspot",
|
|
8
|
+
"de": "Datenpunkt hinzufügen, um anzuzeigen, wann Daten auf sbfspot hochgeladen wurden",
|
|
9
|
+
"ru": "добавить точку данных, чтобы показать, когда данные загружаются в sbfspot",
|
|
10
|
+
"pt": "adicionar ponto de dados para mostrar quando os dados são carregados no sbfspot",
|
|
11
|
+
"nl": "voeg datapunt toe om te laten zien wanneer gegevens zijn geüpload naar sbfspot",
|
|
12
|
+
"fr": "ajouter un point de données pour montrer quand les données sont téléchargées sur sbfspot",
|
|
13
|
+
"it": "aggiungi datapoint per mostrare quando i dati sono stati caricati su sbfspot",
|
|
14
|
+
"es": "agregue un punto de datos para mostrar cuándo se cargan los datos en sbfspot",
|
|
15
|
+
"pl": "dodaj punkt danych, aby pokazać, kiedy dane zostały przesłane do sbfspot",
|
|
16
|
+
"zh-cn": "添加数据点以显示何时将数据上传到 sbfspot"
|
|
17
|
+
},
|
|
18
|
+
"4.0.8": {
|
|
19
|
+
"en": "bug fix color of labels in widget",
|
|
20
|
+
"de": "Fehlerkorrektur Farbe der Labels im Widget",
|
|
21
|
+
"ru": "исправлена ошибка цвета меток в виджете",
|
|
22
|
+
"pt": "correção de bug de cor de rótulos no widget",
|
|
23
|
+
"nl": "bug fix kleur van labels in widget",
|
|
24
|
+
"fr": "correction de bogues couleur des étiquettes dans le widget",
|
|
25
|
+
"it": "bug fix colore delle etichette nel widget",
|
|
26
|
+
"es": "corrección de errores de color de las etiquetas en el widget",
|
|
27
|
+
"pl": "naprawa błędu koloru etykiet w widżecie",
|
|
28
|
+
"zh-cn": "错误修复小部件中标签的颜色"
|
|
29
|
+
},
|
|
30
|
+
"4.0.7": {
|
|
31
|
+
"en": "avoid endles loops",
|
|
32
|
+
"de": "Endlosschleifen vermeiden",
|
|
33
|
+
"ru": "избегать петель endles",
|
|
34
|
+
"pt": "evite loops de endles",
|
|
35
|
+
"nl": "vermijd eindeloze lussen",
|
|
36
|
+
"fr": "éviter les boucles sans fin",
|
|
37
|
+
"it": "evita i loop infiniti",
|
|
38
|
+
"es": "evitar bucles endles",
|
|
39
|
+
"pl": "unikaj niekończących się pętli",
|
|
40
|
+
"zh-cn": "避免无限循环"
|
|
41
|
+
},
|
|
6
42
|
"4.0.6": {
|
|
7
43
|
"en": "bug fix data types",
|
|
8
44
|
"de": "Bugfix-Datentypen",
|
|
@@ -130,7 +166,10 @@
|
|
|
130
166
|
}
|
|
131
167
|
],
|
|
132
168
|
"connectionType": "local",
|
|
133
|
-
"dataSource": "push"
|
|
169
|
+
"dataSource": "push",
|
|
170
|
+
"adminUI": {
|
|
171
|
+
"config": "materialize"
|
|
172
|
+
}
|
|
134
173
|
},
|
|
135
174
|
"native": {
|
|
136
175
|
"sbfspotIP": "localhost",
|
package/lib/tools.js
CHANGED
|
@@ -56,7 +56,7 @@ async function translateYandex(text, targetLang, apiKey) {
|
|
|
56
56
|
}
|
|
57
57
|
try {
|
|
58
58
|
const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(text)}&lang=en-${targetLang}`;
|
|
59
|
-
const response = await axios({url, timeout: 15000});
|
|
59
|
+
const response = await axios({ url, timeout: 15000 });
|
|
60
60
|
if (response.data && response.data.text && isArray(response.data.text)) {
|
|
61
61
|
return response.data.text[0];
|
|
62
62
|
}
|
|
@@ -75,7 +75,7 @@ async function translateYandex(text, targetLang, apiKey) {
|
|
|
75
75
|
async function translateGoogle(text, targetLang) {
|
|
76
76
|
try {
|
|
77
77
|
const url = `http://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}&ie=UTF-8&oe=UTF-8`;
|
|
78
|
-
const response = await axios({url, timeout: 15000});
|
|
78
|
+
const response = await axios({ url, timeout: 15000 });
|
|
79
79
|
if (isArray(response.data)) {
|
|
80
80
|
// we got a valid response
|
|
81
81
|
return response.data[0][0][0];
|
package/main.js
CHANGED
|
@@ -15,8 +15,12 @@ Copyright(C)[2016-2020][René Glaß]
|
|
|
15
15
|
"use strict";
|
|
16
16
|
|
|
17
17
|
const utils = require("@iobroker/adapter-core");
|
|
18
|
+
//const { json } = require("stream/consumers");
|
|
18
19
|
const SunCalc = require("suncalc2");
|
|
19
20
|
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
20
24
|
let adapter;
|
|
21
25
|
function startAdapter(options) {
|
|
22
26
|
options = options || {};
|
|
@@ -110,6 +114,7 @@ async function main() {
|
|
|
110
114
|
|
|
111
115
|
await GetInverter(i, rows);
|
|
112
116
|
|
|
117
|
+
await DB_CheckLastUploads(serial);
|
|
113
118
|
|
|
114
119
|
let rows1 = await DB_GetInvertersData(serial);
|
|
115
120
|
|
|
@@ -151,12 +156,8 @@ async function main() {
|
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
}
|
|
154
|
-
|
|
155
159
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
160
|
}
|
|
159
|
-
|
|
160
161
|
}
|
|
161
162
|
} else {
|
|
162
163
|
//
|
|
@@ -165,8 +166,6 @@ async function main() {
|
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
168
|
DB_Disconnect();
|
|
168
|
-
|
|
169
|
-
|
|
170
169
|
}
|
|
171
170
|
else {
|
|
172
171
|
adapter.log.info("nothing to do, because no daylight ... ");
|
|
@@ -185,18 +184,23 @@ async function main() {
|
|
|
185
184
|
}
|
|
186
185
|
|
|
187
186
|
async function GetSystemDateformat() {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
187
|
+
try {
|
|
188
|
+
const ret = await adapter.getForeignObjectAsync("system.config");
|
|
189
|
+
|
|
190
|
+
if (typeof ret != undefined && ret != null) {
|
|
191
|
+
//dateformat = ret.common.dateFormat;
|
|
192
|
+
longitude = ret.common.longitude;
|
|
193
|
+
latitude = ret.common.latitude;
|
|
194
|
+
adapter.log.debug("system: longitude " + longitude + " latitude " + latitude);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
adapter.log.error("system.config not available. longitude and latitude set to Berlin");
|
|
198
|
+
longitude = 52.520008;
|
|
199
|
+
latitude = 13.404954;
|
|
200
|
+
}
|
|
195
201
|
}
|
|
196
|
-
|
|
197
|
-
adapter.log.error("
|
|
198
|
-
longitude = 52.520008;
|
|
199
|
-
latitude = 13.404954;
|
|
202
|
+
catch (e) {
|
|
203
|
+
adapter.log.error("exception in GetSystemDateformat [" + e + "]");
|
|
200
204
|
}
|
|
201
205
|
}
|
|
202
206
|
|
|
@@ -324,6 +328,9 @@ async function AddInverterVariables(serial) {
|
|
|
324
328
|
await AddObject(serial.toString() + ".history.last12Months", "state", "SMA inverter history last 12 Months (JSON)", "string", "value", "", true, false);
|
|
325
329
|
await AddObject(serial.toString() + ".history.years", "state", "SMA inverter history years (JSON)", "string", "value", "", true, false);
|
|
326
330
|
|
|
331
|
+
await AddObject(serial.toString() + ".sbfspot.LastUpload", "state", "date/time of last upload to sbfspot", "string", "value", "", true, false);
|
|
332
|
+
await AddObject(serial.toString() + ".sbfspot.notUploaded", "state", "number of datapoints waiting for upload", "number", "value", "", true, false);
|
|
333
|
+
|
|
327
334
|
|
|
328
335
|
adapter.log.debug("AddInverterVariables done " );
|
|
329
336
|
}
|
|
@@ -467,49 +474,78 @@ async function DB_Connect() {
|
|
|
467
474
|
return ret;
|
|
468
475
|
}
|
|
469
476
|
|
|
477
|
+
async function DB_Query(query) {
|
|
478
|
+
|
|
479
|
+
adapter.log.debug(query);
|
|
480
|
+
let retRows;
|
|
470
481
|
|
|
482
|
+
if (adapter.config.databasetype == "mySQL" || adapter.config.databasetype == "MariaDB") {
|
|
471
483
|
|
|
484
|
+
const [rows, fields] = await mysql_connection.execute(query);
|
|
485
|
+
retRows = rows;
|
|
472
486
|
|
|
487
|
+
} else {
|
|
488
|
+
const stmt = sqlite_db.prepare(query);
|
|
473
489
|
|
|
474
|
-
|
|
490
|
+
const rows = stmt.all();
|
|
491
|
+
retRows = rows;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
adapter.log.debug(JSON.stringify(retRows));
|
|
495
|
+
|
|
496
|
+
return retRows;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
async function DB_CheckLastUploads(serial) {
|
|
475
500
|
|
|
476
|
-
let retRows;
|
|
477
501
|
try {
|
|
478
|
-
|
|
479
|
-
//numOfInverters = 0;
|
|
480
|
-
adapter.log.debug(query);
|
|
502
|
+
let query = "SELECT `TimeStamp` FROM `DayData` WHERE `PVoutput` is null ";
|
|
481
503
|
|
|
504
|
+
let rows = await DB_Query(query);
|
|
482
505
|
|
|
506
|
+
let notUploaded = rows.length;
|
|
483
507
|
|
|
484
|
-
|
|
508
|
+
await adapter.setStateAsync(serial + ".sbfspot.notUploaded", { ack: true, val: notUploaded });
|
|
485
509
|
|
|
486
|
-
|
|
510
|
+
query = "SELECT `TimeStamp` FROM `DayData` WHERE `PVoutput` = 1 ORDER BY TimeStamp DESC LIMIT 1 ";
|
|
487
511
|
|
|
488
|
-
|
|
512
|
+
rows = await DB_Query(query);
|
|
489
513
|
|
|
490
|
-
|
|
514
|
+
if (rows.length > 0) {
|
|
515
|
+
let updateTimestamp = rows[0].TimeStamp;
|
|
516
|
+
const oDate = new Date(updateTimestamp * 1000);
|
|
517
|
+
const oDateNow = new Date();
|
|
491
518
|
|
|
492
|
-
|
|
493
|
-
} else {
|
|
519
|
+
oDateNow.setDate(oDateNow.getDate() - 1);
|
|
494
520
|
|
|
495
|
-
const stmt = sqlite_db.prepare(query);
|
|
496
521
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
522
|
+
if (oDate < oDateNow) {
|
|
523
|
+
adapter.log.error("no upload to sbfspot since " + oDate.toLocaleString());
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
let lastUpload = oDate.toLocaleString();
|
|
500
527
|
|
|
501
|
-
|
|
528
|
+
await adapter.setStateAsync(serial + ".sbfspot.LastUpload", { ack: true, val: lastUpload });
|
|
502
529
|
}
|
|
530
|
+
}
|
|
531
|
+
catch (e) {
|
|
532
|
+
adapter.log.error("exception in DB_CheckLastUploads [" + e + "]");
|
|
533
|
+
}
|
|
534
|
+
}
|
|
503
535
|
|
|
504
|
-
|
|
505
536
|
|
|
506
537
|
|
|
538
|
+
async function DB_GetInverters() {
|
|
539
|
+
|
|
540
|
+
let retRows;
|
|
541
|
+
try {
|
|
542
|
+
const query = "SELECT * from Inverters";
|
|
543
|
+
retRows = await DB_Query(query);
|
|
507
544
|
}
|
|
508
545
|
catch (e) {
|
|
509
546
|
adapter.log.error("exception in DB_GetInverters [" + e + "]");
|
|
510
547
|
}
|
|
511
548
|
|
|
512
|
-
|
|
513
549
|
return retRows;
|
|
514
550
|
}
|
|
515
551
|
|
|
@@ -574,28 +610,7 @@ async function DB_GetInvertersData(serial) {
|
|
|
574
610
|
try {
|
|
575
611
|
//SELECT * from SpotData where Serial ='2000562095' ORDER BY TimeStamp DESC LIMIT 1
|
|
576
612
|
const query = "SELECT * from SpotData where Serial =" + serial + " ORDER BY TimeStamp DESC LIMIT 1";
|
|
577
|
-
|
|
578
|
-
if (adapter.config.databasetype == "mySQL" || adapter.config.databasetype == "MariaDB") {
|
|
579
|
-
//we only get one row = last one
|
|
580
|
-
|
|
581
|
-
const [rows, fields] = await mysql_connection.execute(query);
|
|
582
|
-
|
|
583
|
-
retRows = rows;
|
|
584
|
-
//await GetInverterData(0, rows, serial);
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
} else {
|
|
588
|
-
|
|
589
|
-
const stmt = sqlite_db.prepare(query);
|
|
590
|
-
|
|
591
|
-
const rows = stmt.all();
|
|
592
|
-
|
|
593
|
-
retRows = rows;
|
|
594
|
-
|
|
595
|
-
//await GetInverterData(0, rows, serial);
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
}
|
|
613
|
+
retRows = await DB_Query(query);
|
|
599
614
|
}
|
|
600
615
|
catch (e) {
|
|
601
616
|
adapter.log.error("exception in DB_GetInvertersData [" + e + "]");
|
|
@@ -701,25 +716,7 @@ async function DB_CalcHistory_LastMonth(serial) {
|
|
|
701
716
|
} else {
|
|
702
717
|
query = "SELECT strftime('%Y-%m-%d', datetime(TimeStamp, 'unixepoch')) as date, Max(`EToday`) as ertrag FROM `SpotData` WHERE `Serial` = '" + serial + "' AND TimeStamp>= " + datefrom.getTime() / 1000 + " AND TimeStamp<= " + dateto.getTime() / 1000 + " Group By strftime('%Y-%m-%d', datetime(TimeStamp, 'unixepoch'))";
|
|
703
718
|
}
|
|
704
|
-
|
|
705
|
-
if (adapter.config.databasetype == "mySQL" || adapter.config.databasetype == "MariaDB") {
|
|
706
|
-
|
|
707
|
-
const [rows, fields] = await mysql_connection.execute(query);
|
|
708
|
-
|
|
709
|
-
retRows = rows;
|
|
710
|
-
//await calcHistory_LastMonth(0, rows, serial);
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
} else {
|
|
714
|
-
|
|
715
|
-
const stmt = sqlite_db.prepare(query);
|
|
716
|
-
|
|
717
|
-
const rows = stmt.all();
|
|
718
|
-
retRows = rows;
|
|
719
|
-
//await CalcHistory_LastMonth(0, rows, serial);
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
}
|
|
719
|
+
retRows = await DB_Query(query);
|
|
723
720
|
}
|
|
724
721
|
catch (e) {
|
|
725
722
|
adapter.log.error("exception in DB_CalcHistory_LastMonth [" + e + "]");
|
|
@@ -784,26 +781,7 @@ async function DB_CalcHistory_Prepare(serial) {
|
|
|
784
781
|
} else {
|
|
785
782
|
query = "SELECT strftime('%Y-%m-%d', datetime(TimeStamp, 'unixepoch')) as date, ETotal FROM `SpotData` WHERE `Serial` = '" + serial + "' ORDER by `TimeStamp` ASC LIMIT 1";
|
|
786
783
|
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
if (adapter.config.databasetype == "mySQL" || adapter.config.databasetype == "MariaDB") {
|
|
790
|
-
|
|
791
|
-
const [rows, fields] = await mysql_connection.execute(query);
|
|
792
|
-
|
|
793
|
-
retRows = rows;
|
|
794
|
-
//await CalcHistory_Prepare(0, rows, serial);
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
} else {
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
const stmt = sqlite_db.prepare(query);
|
|
801
|
-
|
|
802
|
-
const rows = stmt.all();
|
|
803
|
-
retRows = rows;
|
|
804
|
-
//await CalcHistory_Prepare(0, rows, serial);
|
|
805
|
-
|
|
806
|
-
}
|
|
784
|
+
retRows = await DB_Query(query);
|
|
807
785
|
}
|
|
808
786
|
catch (e) {
|
|
809
787
|
adapter.log.error("exception in DB_CalcHistory_Prepare [" + e + "]");
|
|
@@ -860,25 +838,7 @@ async function DB_CalcHistory_Today(serial) {
|
|
|
860
838
|
} else {
|
|
861
839
|
query = "SELECT strftime('%H:%m', datetime(TimeStamp, 'unixepoch')) as time, Max(`EToday`) as ertrag FROM `SpotData` WHERE `Serial` = '" + serial + "' AND TimeStamp>= " + datefrom.getTime() / 1000 + " AND TimeStamp<= " + dateto.getTime() / 1000 + " Group By strftime('%H-%m', datetime(TimeStamp, 'unixepoch'))";
|
|
862
840
|
}
|
|
863
|
-
|
|
864
|
-
if (adapter.config.databasetype == "mySQL" || adapter.config.databasetype == "MariaDB") {
|
|
865
|
-
|
|
866
|
-
const [rows, fields] = await mysql_connection.execute(query);
|
|
867
|
-
retRows = rows;
|
|
868
|
-
|
|
869
|
-
//await CalcHistory_Today(0, rows, serial);
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
} else {
|
|
873
|
-
|
|
874
|
-
const stmt = sqlite_db.prepare(query);
|
|
875
|
-
|
|
876
|
-
const rows = stmt.all();
|
|
877
|
-
retRows = rows;
|
|
878
|
-
//await CalcHistory_Today(0, rows, serial);
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
}
|
|
841
|
+
retRows = await DB_Query(query);
|
|
882
842
|
}
|
|
883
843
|
catch (e) {
|
|
884
844
|
adapter.log.error("exception in DB_CalcHistory_Today [" + e + "]");
|
|
@@ -908,12 +868,11 @@ async function CalcHistory_Today(err, rows, serial) {
|
|
|
908
868
|
"time": data["time"],
|
|
909
869
|
"value": data["ertrag"]
|
|
910
870
|
});
|
|
911
|
-
|
|
871
|
+
|
|
912
872
|
}
|
|
913
873
|
|
|
914
874
|
await adapter.setStateAsync(serial + ".history.today", { ack: true, val: JSON.stringify(oLastDays) });
|
|
915
875
|
|
|
916
|
-
//await DB_CalcHistory_Years(serial);
|
|
917
876
|
} else {
|
|
918
877
|
adapter.log.error("Error while performing Query in CalcHistory_Today. " + err);
|
|
919
878
|
}
|
|
@@ -937,27 +896,7 @@ async function DB_CalcHistory_Years(serial) {
|
|
|
937
896
|
} else {
|
|
938
897
|
query = "SELECT strftime('%Y', datetime(TimeStamp, 'unixepoch')) as date, Max(`ETotal`) as ertrag, Min(`ETotal`) as startertrag FROM `SpotData` WHERE `Serial` = '" + serial + "' Group By strftime('%Y', datetime(TimeStamp, 'unixepoch'))";
|
|
939
898
|
}
|
|
940
|
-
|
|
941
|
-
if (adapter.config.databasetype == "mySQL" || adapter.config.databasetype == "MariaDB") {
|
|
942
|
-
|
|
943
|
-
const [rows, fields] = await mysql_connection.execute(query);
|
|
944
|
-
|
|
945
|
-
retRows = rows;
|
|
946
|
-
//await CalcHistory_Years(0, rows, serial);
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
} else {
|
|
950
|
-
|
|
951
|
-
const stmt = sqlite_db.prepare(query);
|
|
952
|
-
|
|
953
|
-
const rows = stmt.all();
|
|
954
|
-
retRows = rows;
|
|
955
|
-
|
|
956
|
-
//await CalcHistory_Years(0, rows, serial);
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
}
|
|
899
|
+
retRows = await DB_Query(query);
|
|
961
900
|
}
|
|
962
901
|
catch (e) {
|
|
963
902
|
adapter.log.error("exception in DB_CalcHistory_Years [" + e + "]");
|
|
@@ -1053,7 +992,6 @@ async function CalcHistory_Years(err, rows, serial) {
|
|
|
1053
992
|
adapter.log.debug(JSON.stringify(oLastYears));
|
|
1054
993
|
await adapter.setStateAsync(serial + ".history.years", { ack: true, val: JSON.stringify(oLastYears) });
|
|
1055
994
|
|
|
1056
|
-
//await DB_CalcHistory_Months(serial);
|
|
1057
995
|
} else {
|
|
1058
996
|
adapter.log.error("Error while performing Query in CalcHistory_Years. " + err);
|
|
1059
997
|
}
|
|
@@ -1086,24 +1024,7 @@ async function DB_CalcHistory_Months(serial) {
|
|
|
1086
1024
|
} else {
|
|
1087
1025
|
query = "SELECT strftime('%Y-%m', datetime(TimeStamp, 'unixepoch')) as date, Max(`ETotal`) as ertrag FROM `SpotData` WHERE `Serial` = '" + serial + "' AND TimeStamp>= " + datefrom.getTime() / 1000 + " AND TimeStamp<= " + dateto.getTime() / 1000 + " Group By strftime('%Y-%m', datetime(TimeStamp, 'unixepoch'))";
|
|
1088
1026
|
}
|
|
1089
|
-
|
|
1090
|
-
if (adapter.config.databasetype == "mySQL" || adapter.config.databasetype == "MariaDB") {
|
|
1091
|
-
|
|
1092
|
-
const [rows, fields] = await mysql_connection.execute(query);
|
|
1093
|
-
retRows = rows;
|
|
1094
|
-
//await CalcHistory_Months(0, rows, serial);
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
} else {
|
|
1098
|
-
|
|
1099
|
-
const stmt = sqlite_db.prepare(query);
|
|
1100
|
-
|
|
1101
|
-
const rows = stmt.all();
|
|
1102
|
-
retRows = rows;
|
|
1103
|
-
//await CalcHistory_Months(0, rows, serial);
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
}
|
|
1027
|
+
retRows = await DB_Query(query);
|
|
1107
1028
|
}
|
|
1108
1029
|
catch (e) {
|
|
1109
1030
|
adapter.log.error("exception in DB_CalcHistory_Months [" + e + "]");
|
|
@@ -1122,7 +1043,6 @@ async function CalcHistory_Months(err, rows, serial) {
|
|
|
1122
1043
|
adapter.log.debug("rows " + JSON.stringify(rows));
|
|
1123
1044
|
|
|
1124
1045
|
const oLastMonth = [];
|
|
1125
|
-
//var monthdata = {};
|
|
1126
1046
|
|
|
1127
1047
|
for (const i in rows) {
|
|
1128
1048
|
|
|
@@ -1132,12 +1052,11 @@ async function CalcHistory_Months(err, rows, serial) {
|
|
|
1132
1052
|
"month": data["date"],
|
|
1133
1053
|
"value": data["ertrag"]
|
|
1134
1054
|
});
|
|
1135
|
-
|
|
1055
|
+
|
|
1136
1056
|
}
|
|
1137
1057
|
|
|
1138
1058
|
await adapter.setStateAsync(serial + ".history.last12Months", { ack: true, val: JSON.stringify(oLastMonth) });
|
|
1139
1059
|
|
|
1140
|
-
//DB_Disconnect();
|
|
1141
1060
|
} else {
|
|
1142
1061
|
adapter.log.error("Error while performing Query in CalcHistory_Months. " + err);
|
|
1143
1062
|
}
|
|
@@ -1189,10 +1108,6 @@ async function DB_AddDummyData() {
|
|
|
1189
1108
|
|
|
1190
1109
|
function DB_Disconnect() {
|
|
1191
1110
|
|
|
1192
|
-
//numOfInverters--;
|
|
1193
|
-
// wait for all data paths... last data path will close connection
|
|
1194
|
-
|
|
1195
|
-
//if (numOfInverters == 0) {
|
|
1196
1111
|
adapter.log.debug("disconnect database");
|
|
1197
1112
|
if (adapter.config.databasetype == "mySQL" || adapter.config.databasetype == "MariaDB") {
|
|
1198
1113
|
if (typeof mysql_connection != undefined && mysql_connection != null) {
|
|
@@ -1205,124 +1120,10 @@ function DB_Disconnect() {
|
|
|
1205
1120
|
}
|
|
1206
1121
|
|
|
1207
1122
|
adapter.log.info("all done ... ");
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
//} else {
|
|
1211
|
-
// adapter.log.debug("need to wait for disconnect");
|
|
1212
|
-
//}
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
/**
|
|
1217
|
-
* @param {string} timeVal
|
|
1218
|
-
* @param {string} timeLimit
|
|
1219
|
-
*/
|
|
1220
|
-
/*
|
|
1221
|
-
function IsLater(timeVal, timeLimit) {
|
|
1222
|
-
|
|
1223
|
-
let ret = false;
|
|
1224
|
-
try {
|
|
1225
|
-
adapter.log.debug("check IsLater : " + timeVal + " " + timeLimit);
|
|
1226
|
-
|
|
1227
|
-
if (typeof timeVal === "string" && typeof timeLimit === "string") {
|
|
1228
|
-
const valIn = timeVal.split(":");
|
|
1229
|
-
const valLimits = timeLimit.split(":");
|
|
1230
|
-
|
|
1231
|
-
if (valIn.length > 1 && valLimits.length > 1) {
|
|
1232
|
-
|
|
1233
|
-
if (parseInt(valIn[0]) > parseInt(valLimits[0])
|
|
1234
|
-
|| (parseInt(valIn[0]) == parseInt(valLimits[0]) && parseInt(valIn[1]) > parseInt(valLimits[1]))) {
|
|
1235
|
-
ret = true;
|
|
1236
|
-
adapter.log.debug("yes, IsLater : " + timeVal + " " + timeLimit);
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
else {
|
|
1240
|
-
adapter.log.error("string does not contain : " + timeVal + " " + timeLimit);
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
else {
|
|
1244
|
-
adapter.log.error("not a string " + typeof timeVal + " " + typeof timeLimit);
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
catch (e) {
|
|
1248
|
-
adapter.log.error("exception in IsLater [" + e + "]");
|
|
1249
|
-
}
|
|
1250
|
-
return ret;
|
|
1251
|
-
}
|
|
1252
|
-
*/
|
|
1253
|
-
/**
|
|
1254
|
-
* @param {string } timeVal
|
|
1255
|
-
* @param {string } [timeLimit]
|
|
1256
|
-
*/
|
|
1257
|
-
/*
|
|
1258
|
-
function IsEarlier(timeVal, timeLimit) {
|
|
1259
|
-
|
|
1260
|
-
let ret = false;
|
|
1261
|
-
try {
|
|
1262
|
-
adapter.log.debug("check IsEarlier : " + timeVal + " " + timeLimit);
|
|
1263
|
-
|
|
1264
|
-
if (typeof timeVal === "string" && typeof timeLimit === "string") {
|
|
1265
|
-
const valIn = timeVal.split(":");
|
|
1266
|
-
const valLimits = timeLimit.split(":");
|
|
1267
|
-
|
|
1268
|
-
if (valIn.length > 1 && valLimits.length > 1) {
|
|
1269
|
-
|
|
1270
|
-
if (parseInt(valIn[0]) < parseInt(valLimits[0])
|
|
1271
|
-
|| (parseInt(valIn[0]) == parseInt(valLimits[0]) && parseInt(valIn[1]) < parseInt(valLimits[1]))) {
|
|
1272
|
-
ret = true;
|
|
1273
|
-
adapter.log.debug("yes, IsEarlier : " + timeVal + " " + timeLimit);
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
else {
|
|
1277
|
-
adapter.log.error("string does not contain : " + timeVal + " " + timeLimit);
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
|
-
else {
|
|
1281
|
-
adapter.log.error("not a string " + typeof timeVal + " " + typeof timeLimit);
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
catch (e) {
|
|
1285
|
-
adapter.log.error("exception in IsEarlier [" + e + "]");
|
|
1286
|
-
}
|
|
1287
|
-
return ret;
|
|
1288
1123
|
}
|
|
1289
|
-
*/
|
|
1290
|
-
/**
|
|
1291
|
-
* @param {string} timeVal
|
|
1292
|
-
* @param {string} timeLimit
|
|
1293
|
-
*/
|
|
1294
|
-
/*
|
|
1295
|
-
function IsEqual(timeVal, timeLimit) {
|
|
1296
|
-
|
|
1297
|
-
let ret = false;
|
|
1298
|
-
try {
|
|
1299
|
-
adapter.log.debug("check IsEqual : " + timeVal + " " + timeLimit);
|
|
1300
1124
|
|
|
1301
|
-
if (typeof timeVal === "string" && typeof timeLimit === "string") {
|
|
1302
|
-
const valIn = timeVal.split(":");
|
|
1303
|
-
const valLimits = timeLimit.split(":");
|
|
1304
1125
|
|
|
1305
|
-
if (valIn.length > 1 && valLimits.length > 1) {
|
|
1306
1126
|
|
|
1307
|
-
if (parseInt(valIn[0]) === parseInt(valLimits[0]) && parseInt(valIn[1]) === parseInt(valLimits[1])) {
|
|
1308
|
-
ret = true;
|
|
1309
|
-
adapter.log.debug("yes, IsEqual : " + timeVal + " " + timeLimit);
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
else {
|
|
1313
|
-
adapter.log.error("string does not contain : " + timeVal + " " + timeLimit);
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
else {
|
|
1317
|
-
adapter.log.error("not a string " + typeof timeVal + " " + typeof timeLimit);
|
|
1318
|
-
}
|
|
1319
|
-
}
|
|
1320
|
-
catch (e) {
|
|
1321
|
-
adapter.log.error("exception in IsEqual [" + e + "]");
|
|
1322
|
-
}
|
|
1323
|
-
return ret;
|
|
1324
|
-
}
|
|
1325
|
-
*/
|
|
1326
1127
|
|
|
1327
1128
|
// If started as allInOne/compact mode => return function to create instance
|
|
1328
1129
|
if (module && module.parent) {
|