iobroker.poolcontrol 0.3.1 → 0.4.0-alpha.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/README.md +24 -18
- package/io-package.json +14 -14
- package/lib/helpers/consumptionHelper.js +27 -32
- package/lib/helpers/frostHelper.js +3 -8
- package/lib/helpers/pumpHelper.js +29 -12
- package/lib/helpers/pumpHelper3.js +51 -16
- package/lib/helpers/runtimeHelper.js +73 -32
- package/lib/helpers/statisticsHelper.js +448 -0
- package/lib/stateDefinitions/controlStates.js +0 -61
- package/lib/stateDefinitions/pumpStates3.js +22 -0
- package/lib/stateDefinitions/runtimeStates.js +20 -5
- package/lib/stateDefinitions/statisticsStates.js +138 -0
- package/main.js +9 -4
- package/package.json +5 -3
- package/lib/stateDefinitions/hardwareStates.js +0 -184
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* statisticsStates.js
|
|
5
|
+
* -------------------
|
|
6
|
+
* Erstellt alle States für die Tagesstatistik der Temperatursensoren.
|
|
7
|
+
* Struktur: analytics.statistics.temperature.today.*
|
|
8
|
+
*
|
|
9
|
+
* - Sechs Sensorbereiche (outside, ground, surface, flow, return, collector)
|
|
10
|
+
* - Je Sensor: Min/Max/Avg + Zeitstempel + JSON/HTML-Ausgabe
|
|
11
|
+
* - Zusätzlich: Gesamt-Ausgabe (summary_all_json / summary_all_html)
|
|
12
|
+
*
|
|
13
|
+
* Alle States sind persistiert, schreibgeschützt und überinstallationssicher.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {ioBroker.Adapter} adapter - Instanz des ioBroker-Adapters
|
|
18
|
+
*/
|
|
19
|
+
async function createStatisticsStates(adapter) {
|
|
20
|
+
adapter.log.debug('statisticsStates: Initialisierung der Tagesstatistik (Temperatur) gestartet.');
|
|
21
|
+
|
|
22
|
+
// Oberstruktur
|
|
23
|
+
await adapter.setObjectNotExistsAsync('analytics', {
|
|
24
|
+
type: 'channel',
|
|
25
|
+
common: { name: 'Analysen & Auswertungen (Statistik, Historie, Berichte)' },
|
|
26
|
+
native: {},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
await adapter.setObjectNotExistsAsync('analytics.statistics', {
|
|
30
|
+
type: 'channel',
|
|
31
|
+
common: { name: 'Statistische Auswertungen' },
|
|
32
|
+
native: {},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
await adapter.setObjectNotExistsAsync('analytics.statistics.temperature', {
|
|
36
|
+
type: 'channel',
|
|
37
|
+
common: { name: 'Temperaturstatistik' },
|
|
38
|
+
native: {},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
await adapter.setObjectNotExistsAsync('analytics.statistics.temperature.today', {
|
|
42
|
+
type: 'channel',
|
|
43
|
+
common: { name: 'Tagesstatistik (Temperaturen)' },
|
|
44
|
+
native: {},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Definierte Sensoren
|
|
48
|
+
const sensors = [
|
|
49
|
+
{ id: 'outside', name: 'Außentemperatur' },
|
|
50
|
+
{ id: 'ground', name: 'Bodentemperatur' },
|
|
51
|
+
{ id: 'surface', name: 'Pooloberfläche' },
|
|
52
|
+
{ id: 'flow', name: 'Vorlauf' },
|
|
53
|
+
{ id: 'return', name: 'Rücklauf' },
|
|
54
|
+
{ id: 'collector', name: 'Kollektor (Solar)' },
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
for (const sensor of sensors) {
|
|
58
|
+
const basePath = `analytics.statistics.temperature.today.${sensor.id}`;
|
|
59
|
+
|
|
60
|
+
await adapter.setObjectNotExistsAsync(basePath, {
|
|
61
|
+
type: 'channel',
|
|
62
|
+
common: { name: `${sensor.name} (Tagesstatistik)` },
|
|
63
|
+
native: {},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const stateDefs = [
|
|
67
|
+
{ id: 'temp_min', name: 'Niedrigste Temperatur', type: 'number', role: 'value.temperature', unit: '°C' },
|
|
68
|
+
{ id: 'temp_max', name: 'Höchste Temperatur', type: 'number', role: 'value.temperature', unit: '°C' },
|
|
69
|
+
{ id: 'temp_min_time', name: 'Zeitpunkt Minimum', type: 'string', role: 'value.time' },
|
|
70
|
+
{ id: 'temp_max_time', name: 'Zeitpunkt Maximum', type: 'string', role: 'value.time' },
|
|
71
|
+
{ id: 'temp_avg', name: 'Durchschnittstemperatur', type: 'number', role: 'value.temperature', unit: '°C' },
|
|
72
|
+
{ id: 'data_points_count', name: 'Anzahl Messwerte', type: 'number', role: 'value' },
|
|
73
|
+
{ id: 'last_update', name: 'Letzte Aktualisierung', type: 'string', role: 'value.time' },
|
|
74
|
+
{ id: 'summary_json', name: 'Tageszusammenfassung (JSON)', type: 'string', role: 'json' },
|
|
75
|
+
{ id: 'summary_html', name: 'Tageszusammenfassung (HTML)', type: 'string', role: 'html' },
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
for (const def of stateDefs) {
|
|
79
|
+
await adapter.setObjectNotExistsAsync(`${basePath}.${def.id}`, {
|
|
80
|
+
type: 'state',
|
|
81
|
+
common: {
|
|
82
|
+
name: def.name,
|
|
83
|
+
type: def.type,
|
|
84
|
+
role: def.role,
|
|
85
|
+
unit: def.unit || undefined,
|
|
86
|
+
read: true,
|
|
87
|
+
write: false,
|
|
88
|
+
def: def.type === 'number' ? null : '',
|
|
89
|
+
persist: true,
|
|
90
|
+
},
|
|
91
|
+
native: {},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Gesamt-Ausgabe (Outputs)
|
|
97
|
+
const outputBase = 'analytics.statistics.temperature.today.outputs';
|
|
98
|
+
await adapter.setObjectNotExistsAsync(outputBase, {
|
|
99
|
+
type: 'channel',
|
|
100
|
+
common: { name: 'Gesamtausgaben (alle Sensoren)' },
|
|
101
|
+
native: {},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const outputs = [
|
|
105
|
+
{
|
|
106
|
+
id: 'summary_all_json',
|
|
107
|
+
name: 'Gesamtzusammenfassung aller Sensoren (JSON)',
|
|
108
|
+
role: 'json',
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: 'summary_all_html',
|
|
112
|
+
name: 'Gesamtzusammenfassung aller Sensoren (HTML)',
|
|
113
|
+
role: 'html',
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
for (const out of outputs) {
|
|
118
|
+
await adapter.setObjectNotExistsAsync(`${outputBase}.${out.id}`, {
|
|
119
|
+
type: 'state',
|
|
120
|
+
common: {
|
|
121
|
+
name: out.name,
|
|
122
|
+
type: 'string',
|
|
123
|
+
role: out.role,
|
|
124
|
+
read: true,
|
|
125
|
+
write: false,
|
|
126
|
+
def: '',
|
|
127
|
+
persist: true,
|
|
128
|
+
},
|
|
129
|
+
native: {},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
adapter.log.debug('statisticsStates: Tagesstatistik (Temperatur) erfolgreich angelegt.');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
module.exports = {
|
|
137
|
+
createStatisticsStates,
|
|
138
|
+
};
|
package/main.js
CHANGED
|
@@ -8,6 +8,7 @@ const utils = require('@iobroker/adapter-core');
|
|
|
8
8
|
const temperatureHelper = require('./lib/helpers/temperatureHelper');
|
|
9
9
|
const timeHelper = require('./lib/helpers/timeHelper');
|
|
10
10
|
const runtimeHelper = require('./lib/helpers/runtimeHelper');
|
|
11
|
+
const statisticsHelper = require('./lib/helpers/statisticsHelper');
|
|
11
12
|
const pumpHelper = require('./lib/helpers/pumpHelper');
|
|
12
13
|
const pumpHelper2 = require('./lib/helpers/pumpHelper2');
|
|
13
14
|
const pumpHelper3 = require('./lib/helpers/pumpHelper3');
|
|
@@ -29,12 +30,12 @@ const { createSolarStates } = require('./lib/stateDefinitions/solarStates');
|
|
|
29
30
|
const { createGeneralStates } = require('./lib/stateDefinitions/generalStates');
|
|
30
31
|
const { createTimeStates } = require('./lib/stateDefinitions/timeStates');
|
|
31
32
|
const { createRuntimeStates } = require('./lib/stateDefinitions/runtimeStates');
|
|
33
|
+
const { createStatisticsStates } = require('./lib/stateDefinitions/statisticsStates');
|
|
32
34
|
const { createSpeechStates } = require('./lib/stateDefinitions/speechStates');
|
|
33
35
|
const { createConsumptionStates } = require('./lib/stateDefinitions/consumptionStates');
|
|
34
36
|
const { createStatusStates } = require('./lib/stateDefinitions/statusStates');
|
|
35
37
|
const { createControlStates } = require('./lib/stateDefinitions/controlStates');
|
|
36
38
|
const { createDebugLogStates } = require('./lib/stateDefinitions/debugLogStates');
|
|
37
|
-
const { createHardwareStates } = require('./lib/stateDefinitions/hardwareStates');
|
|
38
39
|
|
|
39
40
|
class Poolcontrol extends utils.Adapter {
|
|
40
41
|
constructor(options) {
|
|
@@ -70,6 +71,9 @@ class Poolcontrol extends utils.Adapter {
|
|
|
70
71
|
// --- Laufzeitsteuerung ---
|
|
71
72
|
await createRuntimeStates(this);
|
|
72
73
|
|
|
74
|
+
// Statistik-States (Temperaturen)
|
|
75
|
+
await createStatisticsStates(this);
|
|
76
|
+
|
|
73
77
|
// --- Sprachausgaben ---
|
|
74
78
|
await createSpeechStates(this);
|
|
75
79
|
|
|
@@ -91,9 +95,6 @@ class Poolcontrol extends utils.Adapter {
|
|
|
91
95
|
// --- DebugLog States ---
|
|
92
96
|
await createDebugLogStates(this);
|
|
93
97
|
|
|
94
|
-
// --- Hardware States ---
|
|
95
|
-
await createHardwareStates(this);
|
|
96
|
-
|
|
97
98
|
// --- Migration Helper zuletzt starten ---
|
|
98
99
|
await migrationHelper.init(this);
|
|
99
100
|
|
|
@@ -101,6 +102,7 @@ class Poolcontrol extends utils.Adapter {
|
|
|
101
102
|
temperatureHelper.init(this);
|
|
102
103
|
timeHelper.init(this);
|
|
103
104
|
runtimeHelper.init(this);
|
|
105
|
+
statisticsHelper.init(this);
|
|
104
106
|
pumpHelper.init(this);
|
|
105
107
|
pumpHelper2.init(this);
|
|
106
108
|
pumpHelper3.init(this);
|
|
@@ -126,6 +128,9 @@ class Poolcontrol extends utils.Adapter {
|
|
|
126
128
|
if (runtimeHelper.cleanup) {
|
|
127
129
|
runtimeHelper.cleanup();
|
|
128
130
|
}
|
|
131
|
+
if (statisticsHelper.cleanup) {
|
|
132
|
+
statisticsHelper.cleanup();
|
|
133
|
+
}
|
|
129
134
|
if (pumpHelper.cleanup) {
|
|
130
135
|
pumpHelper.cleanup();
|
|
131
136
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.poolcontrol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-alpha.0",
|
|
4
4
|
"description": "Steuerung & Automatisierung für den Pool (Pumpe, Heizung, Ventile, Sensoren).",
|
|
5
5
|
"author": "DasBo1975 <dasbo1975@outlook.de>",
|
|
6
6
|
"homepage": "https://github.com/DasBo1975/ioBroker.poolcontrol",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"@iobroker/testing": "^5.1.1",
|
|
31
31
|
"eslint": "^9.36.0",
|
|
32
32
|
"prettier": "^3.6.2",
|
|
33
|
-
"proxyquire": "^2.1.3"
|
|
33
|
+
"proxyquire": "^2.1.3",
|
|
34
|
+
"release-it": "^19.0.5"
|
|
34
35
|
},
|
|
35
36
|
"main": "main.js",
|
|
36
37
|
"files": [
|
|
@@ -48,7 +49,8 @@
|
|
|
48
49
|
"test:integration": "mocha test/integration.cjs --exit",
|
|
49
50
|
"test": "npm run test:js && npm run test:package",
|
|
50
51
|
"lint": "eslint .",
|
|
51
|
-
"translate": "translate-adapter"
|
|
52
|
+
"translate": "translate-adapter",
|
|
53
|
+
"release": "release-it"
|
|
52
54
|
},
|
|
53
55
|
"bugs": {
|
|
54
56
|
"url": "https://github.com/DasBo1975/ioBroker.poolcontrol/issues"
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* hardwareStates.js – Bereich für externe Boxen (TempBox, TasterBox usw.)
|
|
5
|
-
* Überarbeitete Version: Checkboxen & settings_enabled entfernt
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Erstellt die Objektstruktur für alle Hardware-Boxen (z. B. TempBox, TasterBox).
|
|
10
|
-
* Diese Version enthält keine Instanz-Checkboxen oder settings_enabled States mehr.
|
|
11
|
-
*
|
|
12
|
-
* @param {object} adapter - ioBroker Adapterinstanz
|
|
13
|
-
*/
|
|
14
|
-
async function createHardwareStates(adapter) {
|
|
15
|
-
try {
|
|
16
|
-
// ------------------------------------------------------
|
|
17
|
-
// Oberordner: Hardware
|
|
18
|
-
// ------------------------------------------------------
|
|
19
|
-
await adapter.setObjectNotExistsAsync('hardware', {
|
|
20
|
-
type: 'channel',
|
|
21
|
-
common: { name: 'Hardware-Boxen (Sensoren & externe Geräte)' },
|
|
22
|
-
native: {},
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
// ======================================================
|
|
26
|
-
// TEMPERATUR-BOX (ESP32)
|
|
27
|
-
// ======================================================
|
|
28
|
-
await adapter.setObjectNotExistsAsync('hardware.tempbox', {
|
|
29
|
-
type: 'channel',
|
|
30
|
-
common: { name: 'Temperatur-Box (ESP32)' },
|
|
31
|
-
native: {},
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// Statusmeldung: Erkennung/Verbindung
|
|
35
|
-
await adapter.setObjectNotExistsAsync('hardware.tempbox.status_detected', {
|
|
36
|
-
type: 'state',
|
|
37
|
-
common: {
|
|
38
|
-
name: 'Box-Status',
|
|
39
|
-
desc: 'Status der automatischen Erkennung der Temperatur-Box (z. B. verbunden/nicht gefunden)',
|
|
40
|
-
type: 'string',
|
|
41
|
-
role: 'text',
|
|
42
|
-
read: true,
|
|
43
|
-
write: false,
|
|
44
|
-
def: 'nicht gefunden',
|
|
45
|
-
},
|
|
46
|
-
native: {},
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
// LED-Status
|
|
50
|
-
await adapter.setObjectNotExistsAsync('hardware.tempbox.status_led', {
|
|
51
|
-
type: 'state',
|
|
52
|
-
common: {
|
|
53
|
-
name: 'LED-Status (TempBox)',
|
|
54
|
-
desc: 'Status der blauen LED auf der Temperatur-Box',
|
|
55
|
-
type: 'string',
|
|
56
|
-
role: 'text',
|
|
57
|
-
read: true,
|
|
58
|
-
write: false,
|
|
59
|
-
def: 'unbekannt',
|
|
60
|
-
},
|
|
61
|
-
native: {},
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// Firmware-Version
|
|
65
|
-
await adapter.setObjectNotExistsAsync('hardware.tempbox.fw_version', {
|
|
66
|
-
type: 'state',
|
|
67
|
-
common: {
|
|
68
|
-
name: 'Box-Firmware-Version',
|
|
69
|
-
desc: 'Firmware-Version der Temperatur-Box (ESP32)',
|
|
70
|
-
type: 'string',
|
|
71
|
-
role: 'text',
|
|
72
|
-
read: true,
|
|
73
|
-
write: false,
|
|
74
|
-
def: '',
|
|
75
|
-
},
|
|
76
|
-
native: {},
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// Box-ID
|
|
80
|
-
await adapter.setObjectNotExistsAsync('hardware.tempbox.box_id', {
|
|
81
|
-
type: 'state',
|
|
82
|
-
common: {
|
|
83
|
-
name: 'Box-ID (TempBox)',
|
|
84
|
-
desc: 'Eindeutige Kennung der Temperatur-Box (z. B. PC-TB-01)',
|
|
85
|
-
type: 'string',
|
|
86
|
-
role: 'text',
|
|
87
|
-
read: true,
|
|
88
|
-
write: false,
|
|
89
|
-
def: '',
|
|
90
|
-
},
|
|
91
|
-
native: {},
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// Sensorsystem-Status
|
|
95
|
-
await adapter.setObjectNotExistsAsync('hardware.tempbox.status_sensors', {
|
|
96
|
-
type: 'state',
|
|
97
|
-
common: {
|
|
98
|
-
name: 'Sensorsystem-Status',
|
|
99
|
-
desc: 'Meldung zum Zustand der Temperatursensoren in der TempBox',
|
|
100
|
-
type: 'string',
|
|
101
|
-
role: 'text',
|
|
102
|
-
read: true,
|
|
103
|
-
write: false,
|
|
104
|
-
def: 'keine Daten',
|
|
105
|
-
},
|
|
106
|
-
native: {},
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// ------------------------------------------------------
|
|
110
|
-
// TASTER-BOX (ESP32)
|
|
111
|
-
// ------------------------------------------------------
|
|
112
|
-
await adapter.setObjectNotExistsAsync('hardware.tasterbox', {
|
|
113
|
-
type: 'channel',
|
|
114
|
-
common: { name: 'Taster-Box (ESP32)' },
|
|
115
|
-
native: {},
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
// Statusmeldung
|
|
119
|
-
await adapter.setObjectNotExistsAsync('hardware.tasterbox.status_detected', {
|
|
120
|
-
type: 'state',
|
|
121
|
-
common: {
|
|
122
|
-
name: 'Box-Status',
|
|
123
|
-
desc: 'Status der automatischen Erkennung der Taster-Box (z. B. verbunden/nicht gefunden)',
|
|
124
|
-
type: 'string',
|
|
125
|
-
role: 'text',
|
|
126
|
-
read: true,
|
|
127
|
-
write: false,
|
|
128
|
-
def: 'nicht gefunden',
|
|
129
|
-
},
|
|
130
|
-
native: {},
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// Firmware-Version
|
|
134
|
-
await adapter.setObjectNotExistsAsync('hardware.tasterbox.fw_version', {
|
|
135
|
-
type: 'state',
|
|
136
|
-
common: {
|
|
137
|
-
name: 'Box-Firmware-Version',
|
|
138
|
-
desc: 'Firmware-Version der Taster-Box (ESP32)',
|
|
139
|
-
type: 'string',
|
|
140
|
-
role: 'text',
|
|
141
|
-
read: true,
|
|
142
|
-
write: false,
|
|
143
|
-
def: '',
|
|
144
|
-
},
|
|
145
|
-
native: {},
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
// Box-ID
|
|
149
|
-
await adapter.setObjectNotExistsAsync('hardware.tasterbox.box_id', {
|
|
150
|
-
type: 'state',
|
|
151
|
-
common: {
|
|
152
|
-
name: 'Box-ID (TasterBox)',
|
|
153
|
-
desc: 'Eindeutige Kennung der Taster-Box (z. B. PC-TB-02)',
|
|
154
|
-
type: 'string',
|
|
155
|
-
role: 'text',
|
|
156
|
-
read: true,
|
|
157
|
-
write: false,
|
|
158
|
-
def: '',
|
|
159
|
-
},
|
|
160
|
-
native: {},
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
// Status der Taster
|
|
164
|
-
await adapter.setObjectNotExistsAsync('hardware.tasterbox.status_buttons', {
|
|
165
|
-
type: 'state',
|
|
166
|
-
common: {
|
|
167
|
-
name: 'Status der Taster',
|
|
168
|
-
desc: 'Textmeldung zum Zustand der Taster (z. B. gedrückt, losgelassen, keine Verbindung)',
|
|
169
|
-
type: 'string',
|
|
170
|
-
role: 'text',
|
|
171
|
-
read: true,
|
|
172
|
-
write: false,
|
|
173
|
-
def: 'unbekannt',
|
|
174
|
-
},
|
|
175
|
-
native: {},
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
adapter.log.debug('[hardwareStates] Hardware-State-Struktur erfolgreich angelegt (bereinigt ohne Checkboxen).');
|
|
179
|
-
} catch (err) {
|
|
180
|
-
adapter.log.error(`[hardwareStates] Fehler beim Anlegen der Hardware-States: ${err.message}`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
module.exports = { createHardwareStates };
|