iobroker.poolcontrol 0.0.7
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 +22 -0
- package/README.md +129 -0
- package/admin/i18n/de/translations.json +5 -0
- package/admin/i18n/en/translations.json +5 -0
- package/admin/i18n/es/translations.json +5 -0
- package/admin/i18n/fr/translations.json +5 -0
- package/admin/i18n/it/translations.json +5 -0
- package/admin/i18n/nl/translations.json +5 -0
- package/admin/i18n/pl/translations.json +5 -0
- package/admin/i18n/pt/translations.json +5 -0
- package/admin/i18n/ru/translations.json +5 -0
- package/admin/i18n/uk/translations.json +5 -0
- package/admin/i18n/zh-cn/translations.json +5 -0
- package/admin/jsonConfig.json +901 -0
- package/admin/poolcontrol.png +0 -0
- package/io-package.json +176 -0
- package/lib/adapter-config.d.ts +19 -0
- package/lib/helpers/consumptionHelper.js +185 -0
- package/lib/helpers/frostHelper.js +94 -0
- package/lib/helpers/pumpHelper.js +224 -0
- package/lib/helpers/runtimeHelper.js +159 -0
- package/lib/helpers/solarHelper.js +138 -0
- package/lib/helpers/speechHelper.js +108 -0
- package/lib/helpers/temperatureHelper.js +227 -0
- package/lib/helpers/timeHelper.js +88 -0
- package/lib/stateDefinitions/consumptionStates.js +82 -0
- package/lib/stateDefinitions/generalStates.js +68 -0
- package/lib/stateDefinitions/pumpStates.js +184 -0
- package/lib/stateDefinitions/runtimeStates.js +113 -0
- package/lib/stateDefinitions/solarStates.js +150 -0
- package/lib/stateDefinitions/speechStates.js +104 -0
- package/lib/stateDefinitions/temperatureStates.js +182 -0
- package/lib/stateDefinitions/timeStates.js +102 -0
- package/main.js +145 -0
- package/package.json +60 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Legt alle States für Laufzeit- und Umwälzwerte an:
|
|
5
|
+
* - runtime.total
|
|
6
|
+
* - runtime.today
|
|
7
|
+
* - runtime.formatted
|
|
8
|
+
* - circulation.daily_total
|
|
9
|
+
* - circulation.daily_required
|
|
10
|
+
* - circulation.daily_remaining
|
|
11
|
+
*
|
|
12
|
+
* @param {import("iobroker").Adapter} adapter - ioBroker Adapter-Instanz
|
|
13
|
+
*/
|
|
14
|
+
async function createRuntimeStates(adapter) {
|
|
15
|
+
// --- Kanal runtime ---
|
|
16
|
+
await adapter.setObjectNotExistsAsync('runtime', {
|
|
17
|
+
type: 'channel',
|
|
18
|
+
common: { name: 'Pumpenlaufzeit' },
|
|
19
|
+
native: {},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
await adapter.setObjectNotExistsAsync('runtime.total', {
|
|
23
|
+
type: 'state',
|
|
24
|
+
common: {
|
|
25
|
+
name: 'Gesamtlaufzeit',
|
|
26
|
+
type: 'number',
|
|
27
|
+
role: 'value.time',
|
|
28
|
+
unit: 's',
|
|
29
|
+
read: true,
|
|
30
|
+
write: false,
|
|
31
|
+
},
|
|
32
|
+
native: {},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
await adapter.setObjectNotExistsAsync('runtime.today', {
|
|
36
|
+
type: 'state',
|
|
37
|
+
common: {
|
|
38
|
+
name: 'Tageslaufzeit',
|
|
39
|
+
type: 'number',
|
|
40
|
+
role: 'value.time',
|
|
41
|
+
unit: 's',
|
|
42
|
+
read: true,
|
|
43
|
+
write: false,
|
|
44
|
+
},
|
|
45
|
+
native: {},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
await adapter.setObjectNotExistsAsync('runtime.formatted', {
|
|
49
|
+
type: 'state',
|
|
50
|
+
common: {
|
|
51
|
+
name: 'Formatierte Laufzeit heute',
|
|
52
|
+
type: 'string',
|
|
53
|
+
role: 'text',
|
|
54
|
+
read: true,
|
|
55
|
+
write: false,
|
|
56
|
+
},
|
|
57
|
+
native: {},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// --- Kanal circulation ---
|
|
61
|
+
await adapter.setObjectNotExistsAsync('circulation', {
|
|
62
|
+
type: 'channel',
|
|
63
|
+
common: { name: 'Umwälzung' },
|
|
64
|
+
native: {},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
await adapter.setObjectNotExistsAsync('circulation.daily_total', {
|
|
68
|
+
type: 'state',
|
|
69
|
+
common: {
|
|
70
|
+
name: 'Tägliche Umwälzmenge',
|
|
71
|
+
type: 'number',
|
|
72
|
+
role: 'value.volume',
|
|
73
|
+
unit: 'l',
|
|
74
|
+
read: true,
|
|
75
|
+
write: false,
|
|
76
|
+
},
|
|
77
|
+
native: {},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
await adapter.setObjectNotExistsAsync('circulation.daily_required', {
|
|
81
|
+
type: 'state',
|
|
82
|
+
common: {
|
|
83
|
+
name: 'Erforderliche tägliche Umwälzmenge',
|
|
84
|
+
type: 'number',
|
|
85
|
+
role: 'value.volume',
|
|
86
|
+
unit: 'l',
|
|
87
|
+
read: true,
|
|
88
|
+
write: false,
|
|
89
|
+
},
|
|
90
|
+
native: {},
|
|
91
|
+
});
|
|
92
|
+
await adapter.setStateAsync('circulation.daily_required', {
|
|
93
|
+
val: 0,
|
|
94
|
+
ack: true,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
await adapter.setObjectNotExistsAsync('circulation.daily_remaining', {
|
|
98
|
+
type: 'state',
|
|
99
|
+
common: {
|
|
100
|
+
name: 'Verbleibende Umwälzmenge heute',
|
|
101
|
+
type: 'number',
|
|
102
|
+
role: 'value.volume',
|
|
103
|
+
unit: 'l',
|
|
104
|
+
read: true,
|
|
105
|
+
write: false,
|
|
106
|
+
},
|
|
107
|
+
native: {},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
module.exports = {
|
|
112
|
+
createRuntimeStates,
|
|
113
|
+
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Legt alle States für die Solarverwaltung an:
|
|
5
|
+
* - solar.solar_control_active
|
|
6
|
+
* - solar.hysteresis_active
|
|
7
|
+
* - solar.temp_on (Einschaltgrenze)
|
|
8
|
+
* - solar.temp_off (Ausschaltgrenze)
|
|
9
|
+
* - solar.collector_warning (Warnung aktiv)
|
|
10
|
+
* - solar.warn_active (Warnlogik aktivieren/deaktivieren)
|
|
11
|
+
* - solar.warn_temp (Warnschwelle °C)
|
|
12
|
+
* - solar.warn_speech (Sprachausgabe bei Warnung)
|
|
13
|
+
*
|
|
14
|
+
* @param {import("iobroker").Adapter} adapter - ioBroker Adapter-Instanz
|
|
15
|
+
*/
|
|
16
|
+
async function createSolarStates(adapter) {
|
|
17
|
+
// Solarsteuerung aktiv
|
|
18
|
+
await adapter.setObjectNotExistsAsync('solar.solar_control_active', {
|
|
19
|
+
type: 'state',
|
|
20
|
+
common: {
|
|
21
|
+
name: 'Solarsteuerung aktivieren',
|
|
22
|
+
type: 'boolean',
|
|
23
|
+
role: 'switch',
|
|
24
|
+
read: true,
|
|
25
|
+
write: true,
|
|
26
|
+
},
|
|
27
|
+
native: {},
|
|
28
|
+
});
|
|
29
|
+
await adapter.setStateAsync('solar.solar_control_active', {
|
|
30
|
+
val: adapter.config.solar_control_active,
|
|
31
|
+
ack: true,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Hysterese aktiv
|
|
35
|
+
await adapter.setObjectNotExistsAsync('solar.hysteresis_active', {
|
|
36
|
+
type: 'state',
|
|
37
|
+
common: {
|
|
38
|
+
name: 'Regelung mit Hysterese verwenden',
|
|
39
|
+
type: 'boolean',
|
|
40
|
+
role: 'switch',
|
|
41
|
+
read: true,
|
|
42
|
+
write: true,
|
|
43
|
+
},
|
|
44
|
+
native: {},
|
|
45
|
+
});
|
|
46
|
+
await adapter.setStateAsync('solar.hysteresis_active', {
|
|
47
|
+
val: adapter.config.solar_hysteresis_active,
|
|
48
|
+
ack: true,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Einschaltgrenze
|
|
52
|
+
await adapter.setObjectNotExistsAsync('solar.temp_on', {
|
|
53
|
+
type: 'state',
|
|
54
|
+
common: {
|
|
55
|
+
name: 'Kollektortemperatur Einschaltgrenze (°C)',
|
|
56
|
+
type: 'number',
|
|
57
|
+
role: 'value.temperature',
|
|
58
|
+
unit: '°C',
|
|
59
|
+
read: true,
|
|
60
|
+
write: true,
|
|
61
|
+
},
|
|
62
|
+
native: {},
|
|
63
|
+
});
|
|
64
|
+
await adapter.setStateAsync('solar.temp_on', {
|
|
65
|
+
val: adapter.config.solar_temp_on,
|
|
66
|
+
ack: true,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Ausschaltgrenze
|
|
70
|
+
await adapter.setObjectNotExistsAsync('solar.temp_off', {
|
|
71
|
+
type: 'state',
|
|
72
|
+
common: {
|
|
73
|
+
name: 'Kollektortemperatur Ausschaltgrenze (°C)',
|
|
74
|
+
type: 'number',
|
|
75
|
+
role: 'value.temperature',
|
|
76
|
+
unit: '°C',
|
|
77
|
+
read: true,
|
|
78
|
+
write: true,
|
|
79
|
+
},
|
|
80
|
+
native: {},
|
|
81
|
+
});
|
|
82
|
+
await adapter.setStateAsync('solar.temp_off', {
|
|
83
|
+
val: adapter.config.solar_temp_off,
|
|
84
|
+
ack: true,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Warnung Kollektortemperatur aktiv
|
|
88
|
+
await adapter.setObjectNotExistsAsync('solar.collector_warning', {
|
|
89
|
+
type: 'state',
|
|
90
|
+
common: {
|
|
91
|
+
name: 'Kollektortemperatur-Warnung aktiv',
|
|
92
|
+
type: 'boolean',
|
|
93
|
+
role: 'indicator.error',
|
|
94
|
+
read: true,
|
|
95
|
+
write: false,
|
|
96
|
+
},
|
|
97
|
+
native: {},
|
|
98
|
+
});
|
|
99
|
+
await adapter.setStateAsync('solar.collector_warning', {
|
|
100
|
+
val: false,
|
|
101
|
+
ack: true,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// NEU: Warnlogik aktivieren
|
|
105
|
+
await adapter.setObjectNotExistsAsync('solar.warn_active', {
|
|
106
|
+
type: 'state',
|
|
107
|
+
common: {
|
|
108
|
+
name: 'Warnung Kollektortemperatur aktivieren',
|
|
109
|
+
type: 'boolean',
|
|
110
|
+
role: 'switch',
|
|
111
|
+
read: true,
|
|
112
|
+
write: true,
|
|
113
|
+
},
|
|
114
|
+
native: {},
|
|
115
|
+
});
|
|
116
|
+
await adapter.setStateAsync('solar.warn_active', { val: false, ack: true });
|
|
117
|
+
|
|
118
|
+
// NEU: Warnschwelle (°C)
|
|
119
|
+
await adapter.setObjectNotExistsAsync('solar.warn_temp', {
|
|
120
|
+
type: 'state',
|
|
121
|
+
common: {
|
|
122
|
+
name: 'Warnschwelle Kollektortemperatur (°C)',
|
|
123
|
+
type: 'number',
|
|
124
|
+
role: 'value.temperature',
|
|
125
|
+
unit: '°C',
|
|
126
|
+
read: true,
|
|
127
|
+
write: true,
|
|
128
|
+
},
|
|
129
|
+
native: {},
|
|
130
|
+
});
|
|
131
|
+
await adapter.setStateAsync('solar.warn_temp', { val: 80, ack: true });
|
|
132
|
+
|
|
133
|
+
// NEU: Sprachausgabe bei Warnung
|
|
134
|
+
await adapter.setObjectNotExistsAsync('solar.warn_speech', {
|
|
135
|
+
type: 'state',
|
|
136
|
+
common: {
|
|
137
|
+
name: 'Sprachausgabe bei Warnung aktivieren',
|
|
138
|
+
type: 'boolean',
|
|
139
|
+
role: 'switch',
|
|
140
|
+
read: true,
|
|
141
|
+
write: true,
|
|
142
|
+
},
|
|
143
|
+
native: {},
|
|
144
|
+
});
|
|
145
|
+
await adapter.setStateAsync('solar.warn_speech', { val: true, ack: true });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
module.exports = {
|
|
149
|
+
createSolarStates,
|
|
150
|
+
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Legt alle States für Sprachausgaben an:
|
|
5
|
+
* - speech.active
|
|
6
|
+
* - speech.last_text
|
|
7
|
+
* - speech.start_text, speech.end_text
|
|
8
|
+
* - speech.texts.[sensor] (Temperaturtexte)
|
|
9
|
+
*
|
|
10
|
+
* @param {import("iobroker").Adapter} adapter - ioBroker Adapter-Instanz
|
|
11
|
+
*/
|
|
12
|
+
async function createSpeechStates(adapter) {
|
|
13
|
+
// Root-Kanal
|
|
14
|
+
await adapter.setObjectNotExistsAsync('speech', {
|
|
15
|
+
type: 'channel',
|
|
16
|
+
common: { name: 'Sprachausgaben' },
|
|
17
|
+
native: {},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Sprachausgaben global aktiv
|
|
21
|
+
await adapter.setObjectNotExistsAsync('speech.active', {
|
|
22
|
+
type: 'state',
|
|
23
|
+
common: {
|
|
24
|
+
name: 'Sprachausgaben aktiv',
|
|
25
|
+
type: 'boolean',
|
|
26
|
+
role: 'switch',
|
|
27
|
+
read: true,
|
|
28
|
+
write: true,
|
|
29
|
+
},
|
|
30
|
+
native: {},
|
|
31
|
+
});
|
|
32
|
+
await adapter.setStateAsync('speech.active', {
|
|
33
|
+
val: adapter.config.speech_active ?? false,
|
|
34
|
+
ack: true,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Letzter gesprochener Text
|
|
38
|
+
await adapter.setObjectNotExistsAsync('speech.last_text', {
|
|
39
|
+
type: 'state',
|
|
40
|
+
common: {
|
|
41
|
+
name: 'Zuletzt gesprochener Text',
|
|
42
|
+
type: 'string',
|
|
43
|
+
role: 'text',
|
|
44
|
+
read: true,
|
|
45
|
+
write: false,
|
|
46
|
+
},
|
|
47
|
+
native: {},
|
|
48
|
+
});
|
|
49
|
+
await adapter.setStateAsync('speech.last_text', { val: '', ack: true });
|
|
50
|
+
|
|
51
|
+
// Start-/Endtexte
|
|
52
|
+
await adapter.setObjectNotExistsAsync('speech.start_text', {
|
|
53
|
+
type: 'state',
|
|
54
|
+
common: {
|
|
55
|
+
name: 'Starttext',
|
|
56
|
+
type: 'string',
|
|
57
|
+
role: 'text',
|
|
58
|
+
read: true,
|
|
59
|
+
write: true,
|
|
60
|
+
},
|
|
61
|
+
native: {},
|
|
62
|
+
});
|
|
63
|
+
await adapter.setStateAsync('speech.start_text', {
|
|
64
|
+
val: 'Die Poolpumpe wurde gestartet.',
|
|
65
|
+
ack: true,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
await adapter.setObjectNotExistsAsync('speech.end_text', {
|
|
69
|
+
type: 'state',
|
|
70
|
+
common: {
|
|
71
|
+
name: 'Endtext',
|
|
72
|
+
type: 'string',
|
|
73
|
+
role: 'text',
|
|
74
|
+
read: true,
|
|
75
|
+
write: true,
|
|
76
|
+
},
|
|
77
|
+
native: {},
|
|
78
|
+
});
|
|
79
|
+
await adapter.setStateAsync('speech.end_text', {
|
|
80
|
+
val: 'Die Poolpumpe wurde gestoppt.',
|
|
81
|
+
ack: true,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Temperaturtexte (optional)
|
|
85
|
+
const sensors = ['surface', 'ground', 'flow', 'return', 'collector', 'outside'];
|
|
86
|
+
for (const key of sensors) {
|
|
87
|
+
await adapter.setObjectNotExistsAsync(`speech.texts.${key}`, {
|
|
88
|
+
type: 'state',
|
|
89
|
+
common: {
|
|
90
|
+
name: `Textausgabe Sensor ${key}`,
|
|
91
|
+
type: 'string',
|
|
92
|
+
role: 'text',
|
|
93
|
+
read: true,
|
|
94
|
+
write: true,
|
|
95
|
+
},
|
|
96
|
+
native: {},
|
|
97
|
+
});
|
|
98
|
+
await adapter.setStateAsync(`speech.texts.${key}`, { val: '', ack: true });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = {
|
|
103
|
+
createSpeechStates,
|
|
104
|
+
};
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Temperature States – vollständig gemäß jsonConfig (Temperaturverwaltung)
|
|
5
|
+
*
|
|
6
|
+
* Für jeden Sensor (surface, ground, flow, return, collector, outside):
|
|
7
|
+
* - temperature.<sensor>_temp_active (boolean, write: true) -> Ja/Nein (aus UI)
|
|
8
|
+
* - temperature.<sensor>_temp_sensor (string, write: false) -> Objekt-ID (aus UI)
|
|
9
|
+
* - temperature.<sensor>.current (number, °C)
|
|
10
|
+
* - temperature.<sensor>.min_today (number, °C)
|
|
11
|
+
* - temperature.<sensor>.max_today (number, °C)
|
|
12
|
+
* - temperature.<sensor>.delta_per_hour (number, °C/h)
|
|
13
|
+
*
|
|
14
|
+
* Zusätzlich:
|
|
15
|
+
* - temperature.delta.collector_outside
|
|
16
|
+
* - temperature.delta.surface_ground
|
|
17
|
+
* - temperature.delta.flow_return
|
|
18
|
+
*
|
|
19
|
+
* @param {import("iobroker").Adapter} adapter - ioBroker Adapter-Instanz
|
|
20
|
+
*/
|
|
21
|
+
async function createTemperatureStates(adapter) {
|
|
22
|
+
// Root-Kanal (robustheitshalber explizit anlegen)
|
|
23
|
+
await adapter.setObjectNotExistsAsync('temperature', {
|
|
24
|
+
type: 'channel',
|
|
25
|
+
common: { name: 'Temperaturverwaltung' },
|
|
26
|
+
native: {},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Kanal für Deltas
|
|
30
|
+
await adapter.setObjectNotExistsAsync('temperature.delta', {
|
|
31
|
+
type: 'channel',
|
|
32
|
+
common: { name: 'Temperatur-Differenzen' },
|
|
33
|
+
native: {},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Hilfsfunktion: Mirror-States (Active + Sensor-ID) + Messkanal anlegen
|
|
37
|
+
async function createSensorSet(sensorKey, label) {
|
|
38
|
+
// 1) Mirror-States der Instanz-Config
|
|
39
|
+
await adapter.setObjectNotExistsAsync(`temperature.${sensorKey}_temp_active`, {
|
|
40
|
+
type: 'state',
|
|
41
|
+
common: {
|
|
42
|
+
name: `Sensor ${label} verwenden`,
|
|
43
|
+
type: 'boolean',
|
|
44
|
+
role: 'switch',
|
|
45
|
+
read: true,
|
|
46
|
+
write: true, // Ja/Nein per State toggelbar
|
|
47
|
+
},
|
|
48
|
+
native: {},
|
|
49
|
+
});
|
|
50
|
+
await adapter.setStateAsync(`temperature.${sensorKey}_temp_active`, {
|
|
51
|
+
val: !!adapter.config[`${sensorKey}_temp_active`],
|
|
52
|
+
ack: true,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
await adapter.setObjectNotExistsAsync(`temperature.${sensorKey}_temp_sensor`, {
|
|
56
|
+
type: 'state',
|
|
57
|
+
common: {
|
|
58
|
+
name: `Objekt-ID Sensor ${label}`,
|
|
59
|
+
type: 'string',
|
|
60
|
+
role: 'text',
|
|
61
|
+
read: true,
|
|
62
|
+
write: false, // nur Spiegel der Config
|
|
63
|
+
},
|
|
64
|
+
native: {},
|
|
65
|
+
});
|
|
66
|
+
await adapter.setStateAsync(`temperature.${sensorKey}_temp_sensor`, {
|
|
67
|
+
val: adapter.config[`${sensorKey}_temp_sensor`] || '',
|
|
68
|
+
ack: true,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// 2) Messkanal + Werte-States
|
|
72
|
+
await adapter.setObjectNotExistsAsync(`temperature.${sensorKey}`, {
|
|
73
|
+
type: 'channel',
|
|
74
|
+
common: { name: `Sensor ${label}` },
|
|
75
|
+
native: {},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
await adapter.setObjectNotExistsAsync(`temperature.${sensorKey}.current`, {
|
|
79
|
+
type: 'state',
|
|
80
|
+
common: {
|
|
81
|
+
name: `Aktueller Wert Sensor ${label}`,
|
|
82
|
+
type: 'number',
|
|
83
|
+
role: 'value.temperature',
|
|
84
|
+
unit: '°C',
|
|
85
|
+
read: true,
|
|
86
|
+
write: false,
|
|
87
|
+
},
|
|
88
|
+
native: {},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
await adapter.setObjectNotExistsAsync(`temperature.${sensorKey}.min_today`, {
|
|
92
|
+
type: 'state',
|
|
93
|
+
common: {
|
|
94
|
+
name: `Tagesminimum Sensor ${label}`,
|
|
95
|
+
type: 'number',
|
|
96
|
+
role: 'value.temperature',
|
|
97
|
+
unit: '°C',
|
|
98
|
+
read: true,
|
|
99
|
+
write: false,
|
|
100
|
+
},
|
|
101
|
+
native: {},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
await adapter.setObjectNotExistsAsync(`temperature.${sensorKey}.max_today`, {
|
|
105
|
+
type: 'state',
|
|
106
|
+
common: {
|
|
107
|
+
name: `Tagesmaximum Sensor ${label}`,
|
|
108
|
+
type: 'number',
|
|
109
|
+
role: 'value.temperature',
|
|
110
|
+
unit: '°C',
|
|
111
|
+
read: true,
|
|
112
|
+
write: false,
|
|
113
|
+
},
|
|
114
|
+
native: {},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
await adapter.setObjectNotExistsAsync(`temperature.${sensorKey}.delta_per_hour`, {
|
|
118
|
+
type: 'state',
|
|
119
|
+
common: {
|
|
120
|
+
name: `Veränderung pro Stunde Sensor ${label}`,
|
|
121
|
+
type: 'number',
|
|
122
|
+
role: 'value.temperature',
|
|
123
|
+
unit: '°C/h',
|
|
124
|
+
read: true,
|
|
125
|
+
write: false,
|
|
126
|
+
},
|
|
127
|
+
native: {},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Reihenfolge wie in der Instanz-Config (jsonConfig)
|
|
132
|
+
await createSensorSet('surface', 'Oberfläche');
|
|
133
|
+
await createSensorSet('ground', 'Grund');
|
|
134
|
+
await createSensorSet('flow', 'Vorlauf');
|
|
135
|
+
await createSensorSet('return', 'Rücklauf');
|
|
136
|
+
await createSensorSet('collector', 'Kollektor');
|
|
137
|
+
await createSensorSet('outside', 'Außentemperatur');
|
|
138
|
+
|
|
139
|
+
// Deltas zwischen Sensoren
|
|
140
|
+
await adapter.setObjectNotExistsAsync('temperature.delta.collector_outside', {
|
|
141
|
+
type: 'state',
|
|
142
|
+
common: {
|
|
143
|
+
name: 'Differenz Kollektor - Luft',
|
|
144
|
+
type: 'number',
|
|
145
|
+
role: 'value.temperature',
|
|
146
|
+
unit: '°C',
|
|
147
|
+
read: true,
|
|
148
|
+
write: false,
|
|
149
|
+
},
|
|
150
|
+
native: {},
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
await adapter.setObjectNotExistsAsync('temperature.delta.surface_ground', {
|
|
154
|
+
type: 'state',
|
|
155
|
+
common: {
|
|
156
|
+
name: 'Differenz Oberfläche - Grund',
|
|
157
|
+
type: 'number',
|
|
158
|
+
role: 'value.temperature',
|
|
159
|
+
unit: '°C',
|
|
160
|
+
read: true,
|
|
161
|
+
write: false,
|
|
162
|
+
},
|
|
163
|
+
native: {},
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
await adapter.setObjectNotExistsAsync('temperature.delta.flow_return', {
|
|
167
|
+
type: 'state',
|
|
168
|
+
common: {
|
|
169
|
+
name: 'Differenz Vorlauf - Rücklauf',
|
|
170
|
+
type: 'number',
|
|
171
|
+
role: 'value.temperature',
|
|
172
|
+
unit: '°C',
|
|
173
|
+
read: true,
|
|
174
|
+
write: false,
|
|
175
|
+
},
|
|
176
|
+
native: {},
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
module.exports = {
|
|
181
|
+
createTemperatureStates,
|
|
182
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Legt alle States für die Zeitsteuerung an:
|
|
5
|
+
* - time1_active, time1_start, time1_end, time1_day_mon ... time1_day_sun
|
|
6
|
+
* - time2_active, time2_start, time2_end, time2_day_mon ... time2_day_sun
|
|
7
|
+
* - time3_active, time3_start, time3_end, time3_day_mon ... time3_day_sun
|
|
8
|
+
*
|
|
9
|
+
* @param {import("iobroker").Adapter} adapter - ioBroker Adapter-Instanz
|
|
10
|
+
*/
|
|
11
|
+
async function createTimeStates(adapter) {
|
|
12
|
+
async function createTimeWindow(prefix, label) {
|
|
13
|
+
// Aktiv
|
|
14
|
+
await adapter.setObjectNotExistsAsync(`timecontrol.${prefix}_active`, {
|
|
15
|
+
type: 'state',
|
|
16
|
+
common: {
|
|
17
|
+
name: `Zeitfenster ${label} aktiv`,
|
|
18
|
+
type: 'boolean',
|
|
19
|
+
role: 'switch',
|
|
20
|
+
read: true,
|
|
21
|
+
write: true,
|
|
22
|
+
},
|
|
23
|
+
native: {},
|
|
24
|
+
});
|
|
25
|
+
await adapter.setStateAsync(`timecontrol.${prefix}_active`, {
|
|
26
|
+
val: adapter.config[`${prefix}_active`],
|
|
27
|
+
ack: true,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Startzeit
|
|
31
|
+
await adapter.setObjectNotExistsAsync(`timecontrol.${prefix}_start`, {
|
|
32
|
+
type: 'state',
|
|
33
|
+
common: {
|
|
34
|
+
name: `Zeitfenster ${label} Start (HH:MM)`,
|
|
35
|
+
type: 'string',
|
|
36
|
+
role: 'value.time',
|
|
37
|
+
read: true,
|
|
38
|
+
write: true,
|
|
39
|
+
},
|
|
40
|
+
native: {},
|
|
41
|
+
});
|
|
42
|
+
await adapter.setStateAsync(`timecontrol.${prefix}_start`, {
|
|
43
|
+
val: adapter.config[`${prefix}_start`] || '00:00',
|
|
44
|
+
ack: true,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Endzeit
|
|
48
|
+
await adapter.setObjectNotExistsAsync(`timecontrol.${prefix}_end`, {
|
|
49
|
+
type: 'state',
|
|
50
|
+
common: {
|
|
51
|
+
name: `Zeitfenster ${label} Ende (HH:MM)`,
|
|
52
|
+
type: 'string',
|
|
53
|
+
role: 'value.time',
|
|
54
|
+
read: true,
|
|
55
|
+
write: true,
|
|
56
|
+
},
|
|
57
|
+
native: {},
|
|
58
|
+
});
|
|
59
|
+
await adapter.setStateAsync(`timecontrol.${prefix}_end`, {
|
|
60
|
+
val: adapter.config[`${prefix}_end`] || '00:00',
|
|
61
|
+
ack: true,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Wochentage
|
|
65
|
+
const days = [
|
|
66
|
+
['mon', 'Montag'],
|
|
67
|
+
['tue', 'Dienstag'],
|
|
68
|
+
['wed', 'Mittwoch'],
|
|
69
|
+
['thu', 'Donnerstag'],
|
|
70
|
+
['fri', 'Freitag'],
|
|
71
|
+
['sat', 'Samstag'],
|
|
72
|
+
['sun', 'Sonntag'],
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
for (const [key, labelDay] of days) {
|
|
76
|
+
await adapter.setObjectNotExistsAsync(`timecontrol.${prefix}_day_${key}`, {
|
|
77
|
+
type: 'state',
|
|
78
|
+
common: {
|
|
79
|
+
name: `Zeitfenster ${label} ${labelDay}`,
|
|
80
|
+
type: 'boolean',
|
|
81
|
+
role: 'switch',
|
|
82
|
+
read: true,
|
|
83
|
+
write: true,
|
|
84
|
+
},
|
|
85
|
+
native: {},
|
|
86
|
+
});
|
|
87
|
+
await adapter.setStateAsync(`timecontrol.${prefix}_day_${key}`, {
|
|
88
|
+
val: adapter.config[`${prefix}_day_${key}`],
|
|
89
|
+
ack: true,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Zeitfenster 1 bis 3 anlegen
|
|
95
|
+
await createTimeWindow('time1', '1');
|
|
96
|
+
await createTimeWindow('time2', '2');
|
|
97
|
+
await createTimeWindow('time3', '3');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
module.exports = {
|
|
101
|
+
createTimeStates,
|
|
102
|
+
};
|