iobroker.smartfriends 1.1.0-alpha.1 → 1.2.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/LICENSE +2 -3
- package/README.md +6 -2
- package/io-package.json +27 -1
- package/lib/SchellenbergBridge.js +13 -12
- package/lib/devices/DeviceCapabilityRegistry.js +70 -0
- package/lib/devices/DeviceKindCapabilities.js +78 -0
- package/lib/devices/DeviceManager.js +1 -1
- package/lib/devices/SchellenbergDevice.js +133 -52
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2025 Black-Thunder <glwars@aol.de>
|
|
3
|
+
Copyright (c) 2025-2026 Black-Thunder <glwars@aol.de>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -20,8 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
-------------------------------------------------------------------------------
|
|
23
|
+
---
|
|
25
24
|
|
|
26
25
|
LoPablo/SchellenbergApi (https://github.com/LoPablo/SchellenbergApi)
|
|
27
26
|
|
package/README.md
CHANGED
|
@@ -33,7 +33,11 @@ The adapter establishes a direct connection to the gateway to control and query
|
|
|
33
33
|
Placeholder for the next version (at the beginning of the line):
|
|
34
34
|
### __WORK IN PROGRESS__
|
|
35
35
|
-->
|
|
36
|
-
### 1.
|
|
36
|
+
### 1.2.0-alpha.0 (2026-01-02)
|
|
37
|
+
|
|
38
|
+
- (Black-Thunder) Refactored device handling and added support for further device types
|
|
39
|
+
|
|
40
|
+
### 1.1.0 (2025-12-28)
|
|
37
41
|
|
|
38
42
|
- (Black-Thunder) Refactored device handling: dynamic states, removed type whitelist, grouped devices under master ID
|
|
39
43
|
- (Black-Thunder) Handle device value updates now correctly
|
|
@@ -55,7 +59,7 @@ Special thanks und credits to [LoPablo](https://github.com/LoPablo/SchellenbergA
|
|
|
55
59
|
|
|
56
60
|
MIT License
|
|
57
61
|
|
|
58
|
-
Copyright (c) 2025 Black-Thunder <glwars@aol.de>
|
|
62
|
+
Copyright (c) 2025-2026 Black-Thunder <glwars@aol.de>
|
|
59
63
|
|
|
60
64
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
61
65
|
of this software and associated documentation files (the "Software"), to deal
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "smartfriends",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.2.0-alpha.0",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.2.0-alpha.0": {
|
|
7
|
+
"en": "Refactored device handling and added support for further device types",
|
|
8
|
+
"de": "Refactored Device Handling und zusätzliche Unterstützung für weitere Gerätetypen",
|
|
9
|
+
"ru": "Рефакторированная обработка устройств и дополнительная поддержка для других типов устройств",
|
|
10
|
+
"pt": "Manipulação do dispositivo refatorizado e suporte adicional para outros tipos de dispositivo",
|
|
11
|
+
"nl": "Refactored device handling en toegevoegde ondersteuning voor andere apparaattypes",
|
|
12
|
+
"fr": "Manipulation de l'appareil refactoré et support supplémentaire pour d'autres types d'appareil",
|
|
13
|
+
"it": "Gestione del dispositivo e supporto aggiunto per ulteriori tipi di dispositivo",
|
|
14
|
+
"es": "Manejo de dispositivo refactorizado y soporte añadido para nuevos tipos de dispositivos",
|
|
15
|
+
"pl": "Zmieniona obsługa urządzenia i dodana obsługa dla innych typów urządzeń",
|
|
16
|
+
"uk": "Рефакторний пристрій обробки та додано підтримку для подальших типів пристроїв",
|
|
17
|
+
"zh-cn": "对设备类型进行重构处理并添加支持"
|
|
18
|
+
},
|
|
19
|
+
"1.1.0": {
|
|
20
|
+
"en": "Refactored device handling: dynamic states, removed type whitelist, grouped devices under master ID\nHandle device value updates now correctly",
|
|
21
|
+
"de": "Refactored Device Handling: dynamische Zustände, entfernte Typ Whitelist, gruppierte Geräte unter Master ID\nGerätewert-Updates jetzt korrekt ausschalten",
|
|
22
|
+
"ru": "Рефакторированная обработка устройств: динамические состояния, удаленный белый список типов, сгруппированные устройства под идентификатором Master ID\nОбновления стоимости устройства теперь правильно",
|
|
23
|
+
"pt": "Manipulação do dispositivo refatorado: estados dinâmicos, lista branca do tipo removido, dispositivos agrupados sob ID mestre\nGerenciar as atualizações de valor do dispositivo agora corretamente",
|
|
24
|
+
"nl": "Refactored device handling: dynamische toestanden, verwijderd type whitelist, gegroepeerde apparaten onder master ID\nHandle apparaat waarde updates nu correct",
|
|
25
|
+
"fr": "Manipulation de l'appareil refacturé : états dynamiques, liste blanche de type enlevé, dispositifs groupés sous Master ID\nGérer les mises à jour de la valeur du périphérique maintenant correctement",
|
|
26
|
+
"it": "Movimentazione del dispositivo refattore: stati dinamici, tipo rimosso whitelist, dispositivi raggruppati sotto master ID\nMantenere gli aggiornamenti del valore del dispositivo ora correttamente",
|
|
27
|
+
"es": "Manejo de dispositivo refactorizado: estados dinámicos, lista blanca de tipo eliminado, dispositivos agrupados bajo ID maestro\nActualizaciones de valor del dispositivo manual ahora correctamente",
|
|
28
|
+
"pl": "Przekształcona obsługa urządzenia: stany dynamiczne, usunięty biały typ, zgrupowane urządzenia pod master ID\nUchwyt aktualizacji wartości urządzenia teraz poprawnie",
|
|
29
|
+
"uk": "Рефакторний пристрій обробки: динамічні стани, видалений тип білий список, вбудовані пристрої під магістр ID\nОновлення значення ручного пристрою тепер правильно",
|
|
30
|
+
"zh-cn": "重构设备处理: 动态状态, 删除类型白名单, 主 ID 下分组设备\n现在正确处理设备值更新"
|
|
31
|
+
},
|
|
6
32
|
"1.1.0-alpha.1": {
|
|
7
33
|
"en": "Refactored device handling: dynamic states, removed type whitelist, grouped devices under master ID\nHandle device value updates now correctly",
|
|
8
34
|
"de": "Refactored Device Handling: dynamische Zustände, entfernte Typ Whitelist, gruppierte Geräte unter Master ID\nGerätewert-Updates jetzt korrekt ausschalten",
|
|
@@ -12,6 +12,7 @@ const SmartSocketFactory = require("./comunication/SmartSocketFactory");
|
|
|
12
12
|
const CommonDefines = require("./helpers/CommonDefines");
|
|
13
13
|
const DeviceManager = require("./devices/DeviceManager");
|
|
14
14
|
const { SchellenbergMasterDevice } = require("./devices/SchellenbergMasterDevice");
|
|
15
|
+
const { getDeviceCapabilities } = require("./devices/DeviceKindCapabilities");
|
|
15
16
|
|
|
16
17
|
class SchellenbergBridge {
|
|
17
18
|
constructor(adapter) {
|
|
@@ -170,25 +171,30 @@ class SchellenbergBridge {
|
|
|
170
171
|
|
|
171
172
|
// 2️⃣ MasterDevices anlegen
|
|
172
173
|
for (const [masterId, childDevices] of Object.entries(devicesByMaster)) {
|
|
173
|
-
const masterName = childDevices[0].masterDeviceName || childDevices[0].deviceName
|
|
174
|
+
const masterName = (childDevices[0].masterDeviceName || childDevices[0].deviceName).replace(
|
|
175
|
+
/\${|}/g,
|
|
176
|
+
"",
|
|
177
|
+
);
|
|
174
178
|
const masterDevice = new SchellenbergMasterDevice(this.adapter, masterId, masterName, []);
|
|
175
179
|
|
|
176
180
|
// 3️⃣ Child-Devices unter Master anlegen
|
|
177
181
|
for (const child of childDevices) {
|
|
178
|
-
// Nur Devices mit definierbaren
|
|
179
|
-
const
|
|
180
|
-
|
|
182
|
+
// Nur Devices mit definierbaren States
|
|
183
|
+
const capabilities = getDeviceCapabilities(child.definition);
|
|
184
|
+
this.adapter.log.debug(
|
|
185
|
+
`Device ${child.deviceID}: kind=${child.definition.deviceType.kind}, capabilities=${JSON.stringify(capabilities)}`,
|
|
186
|
+
);
|
|
181
187
|
|
|
182
|
-
if (!
|
|
188
|
+
if (!capabilities.shouldBeCreated) {
|
|
183
189
|
this.adapter.log.debug(
|
|
184
|
-
`Skipping device ${child.deviceName} (${child.deviceDesignation}) – no definable
|
|
190
|
+
`Skipping device ${child.deviceName} (${child.deviceDesignation}) – no definable states found`,
|
|
185
191
|
);
|
|
186
192
|
continue;
|
|
187
193
|
}
|
|
188
194
|
|
|
189
195
|
const schellenbergDevice = await this.deviceManager.createDevice({
|
|
190
196
|
id: child.deviceID,
|
|
191
|
-
name: child.deviceName,
|
|
197
|
+
name: child.deviceName.replace(/\${|}/g, ""),
|
|
192
198
|
deviceType: child.deviceTypClient ?? child.definition.deviceType?.kind ?? "unknown",
|
|
193
199
|
designation: child.deviceDesignation,
|
|
194
200
|
definition: child.definition,
|
|
@@ -258,11 +264,6 @@ class SchellenbergBridge {
|
|
|
258
264
|
`Message received: ${parsedResponse.responseMessage} (code: ${parsedResponse.responseCode})`,
|
|
259
265
|
);
|
|
260
266
|
|
|
261
|
-
if (parsedResponse.currentTimestamp) {
|
|
262
|
-
this.adapter.log.debug(`Updated timestamp to ${parsedResponse.currentTimestamp}`);
|
|
263
|
-
this.lastTimestamp = parsedResponse.currentTimestamp;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
267
|
this.handleResponseCode(parsedResponse);
|
|
267
268
|
}
|
|
268
269
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Declarative registry for device kinds that provide
|
|
5
|
+
* a level-like control (position, brightness, etc.)
|
|
6
|
+
*/
|
|
7
|
+
const LevelKinds = {
|
|
8
|
+
position: {
|
|
9
|
+
role: "level.blind",
|
|
10
|
+
desc: "Position of the device",
|
|
11
|
+
unit: "%",
|
|
12
|
+
defaultMin: 0,
|
|
13
|
+
defaultMax: 100,
|
|
14
|
+
defaultStep: 1,
|
|
15
|
+
},
|
|
16
|
+
brightness: {
|
|
17
|
+
role: "level.dimmer",
|
|
18
|
+
desc: "Brightness of the device",
|
|
19
|
+
unit: "%",
|
|
20
|
+
defaultMin: 0,
|
|
21
|
+
defaultMax: 100,
|
|
22
|
+
defaultStep: 1,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Declarative registry for device kinds that provide
|
|
28
|
+
* a sensor state information (temperature, rain, etc.)
|
|
29
|
+
*/
|
|
30
|
+
const SensorKinds = {
|
|
31
|
+
thermometer: {
|
|
32
|
+
role: "level.temperature",
|
|
33
|
+
desc: "Measured temperature",
|
|
34
|
+
unit: "°C",
|
|
35
|
+
defaultMin: -90,
|
|
36
|
+
defaultMax: 60,
|
|
37
|
+
defaultStep: 0.5,
|
|
38
|
+
},
|
|
39
|
+
volume: {
|
|
40
|
+
role: "value.rain",
|
|
41
|
+
desc: "Measured rain volume",
|
|
42
|
+
unit: "mm",
|
|
43
|
+
defaultMin: 0,
|
|
44
|
+
defaultMax: 350,
|
|
45
|
+
defaultStep: 1,
|
|
46
|
+
},
|
|
47
|
+
// generic sensor kind for different types of weather sensors (e.g. atmospheric pressure, wind speed, etc.)
|
|
48
|
+
weather: {
|
|
49
|
+
role: "value",
|
|
50
|
+
desc: "Measured value",
|
|
51
|
+
unit: "",
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Declarative registry for device kinds that provide
|
|
57
|
+
* an alarm information
|
|
58
|
+
*/
|
|
59
|
+
const AlarmKinds = {
|
|
60
|
+
failureStatus: {
|
|
61
|
+
role: "value",
|
|
62
|
+
desc: "Error code of the device",
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
module.exports = {
|
|
67
|
+
AlarmKinds,
|
|
68
|
+
LevelKinds,
|
|
69
|
+
SensorKinds,
|
|
70
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { LevelKinds, SensorKinds, AlarmKinds } = require("./DeviceCapabilityRegistry");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Resolves capabilities from a SmartFriends device definition
|
|
7
|
+
*/
|
|
8
|
+
function getDeviceCapabilities(definition) {
|
|
9
|
+
const deviceType = definition?.deviceType ?? {};
|
|
10
|
+
const kind = deviceType.kind ?? "unknown";
|
|
11
|
+
const deviceDesignation = definition?.deviceDesignation?.replace(/\${|}/g, "") ?? kind;
|
|
12
|
+
const model = deviceType.model ?? "unknown";
|
|
13
|
+
|
|
14
|
+
const switchingValues = Array.isArray(deviceType.switchingValues) ? deviceType.switchingValues : [];
|
|
15
|
+
|
|
16
|
+
const hasSwitchingValues = switchingValues.length > 0;
|
|
17
|
+
let configObj = {
|
|
18
|
+
kind,
|
|
19
|
+
name: deviceDesignation,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const levelConfig = LevelKinds[kind] ?? null;
|
|
23
|
+
const sensorConfig = (SensorKinds[kind] && model == "analog") ?? null; // only sensor type "analog" contains measurable values
|
|
24
|
+
const alarmConfig = AlarmKinds[kind] ?? null;
|
|
25
|
+
|
|
26
|
+
if (levelConfig) {
|
|
27
|
+
configObj = {
|
|
28
|
+
...configObj,
|
|
29
|
+
role: levelConfig.role,
|
|
30
|
+
desc: levelConfig.desc,
|
|
31
|
+
unit: levelConfig.unit,
|
|
32
|
+
min: deviceType.min ?? levelConfig.defaultMin,
|
|
33
|
+
max: deviceType.max ?? levelConfig.defaultMax,
|
|
34
|
+
step: deviceType.step ?? levelConfig.defaultStep,
|
|
35
|
+
};
|
|
36
|
+
} else if (sensorConfig) {
|
|
37
|
+
configObj = {
|
|
38
|
+
...configObj,
|
|
39
|
+
role: sensorConfig.role,
|
|
40
|
+
desc: sensorConfig.desc,
|
|
41
|
+
unit: sensorConfig.unit,
|
|
42
|
+
min: deviceType.min ?? sensorConfig.defaultMin,
|
|
43
|
+
max: deviceType.max ?? sensorConfig.defaultMax,
|
|
44
|
+
step: deviceType.step ?? sensorConfig.defaultStep,
|
|
45
|
+
};
|
|
46
|
+
} else if (alarmConfig) {
|
|
47
|
+
configObj = {
|
|
48
|
+
...configObj,
|
|
49
|
+
role: alarmConfig.role,
|
|
50
|
+
desc: alarmConfig.desc,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// map "textOptions" (if present) into configObj as enumerated states
|
|
54
|
+
if (deviceType.textOptions && Array.isArray(deviceType.textOptions) && deviceType.textOptions.length > 0) {
|
|
55
|
+
configObj.states = deviceType.textOptions.reduce((acc, opt) => {
|
|
56
|
+
acc[opt.value] = `${opt.state} (${opt.name.replace(/\${|}/g, "")})`;
|
|
57
|
+
return acc;
|
|
58
|
+
}, {});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
// state creation decision
|
|
64
|
+
shouldBeCreated: hasSwitchingValues || !!levelConfig || !!sensorConfig || !!alarmConfig,
|
|
65
|
+
hasWritableStates: hasSwitchingValues || !!levelConfig,
|
|
66
|
+
// metadata for builders
|
|
67
|
+
hasSwitchingValues,
|
|
68
|
+
hasLevel: !!levelConfig,
|
|
69
|
+
hasSensor: !!sensorConfig,
|
|
70
|
+
hasAlarm: !!alarmConfig,
|
|
71
|
+
// config object for state creation
|
|
72
|
+
configObj: configObj,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = {
|
|
77
|
+
getDeviceCapabilities,
|
|
78
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
const { getDeviceCapabilities } = require("./DeviceKindCapabilities");
|
|
3
4
|
const commonDefines = require("../helpers/CommonDefines");
|
|
4
5
|
|
|
5
6
|
class SchellenbergDevice {
|
|
@@ -16,6 +17,9 @@ class SchellenbergDevice {
|
|
|
16
17
|
|
|
17
18
|
// Creates all necessery states and channels and writes the values into the DB
|
|
18
19
|
async CreateAndSave(masterPrefix) {
|
|
20
|
+
// Dynamisch aus device.definition
|
|
21
|
+
const capabilities = getDeviceCapabilities(this.definition);
|
|
22
|
+
|
|
19
23
|
let devicePrefix = masterPrefix
|
|
20
24
|
? `${masterPrefix}.${this.id}`
|
|
21
25
|
: `${commonDefines.AdapterDatapointIDs.Devices}.${this.id}`;
|
|
@@ -83,65 +87,121 @@ class SchellenbergDevice {
|
|
|
83
87
|
},
|
|
84
88
|
native: {},
|
|
85
89
|
});
|
|
90
|
+
|
|
91
|
+
if (capabilities.hasSensor) {
|
|
92
|
+
await this.createSensorState(infoPrefix, capabilities.configObj);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (capabilities.hasAlarm) {
|
|
96
|
+
await this.createAlarmState(infoPrefix, capabilities.configObj);
|
|
97
|
+
}
|
|
86
98
|
//#endregion
|
|
87
99
|
|
|
88
100
|
//#region CONTROL
|
|
89
|
-
|
|
101
|
+
if (capabilities.hasWritableStates) {
|
|
102
|
+
let controlPrefix = `${devicePrefix}.${commonDefines.AdapterDatapointIDs.Control}`;
|
|
90
103
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
104
|
+
await this.adapter.setObjectNotExistsAsync(controlPrefix, {
|
|
105
|
+
type: "channel",
|
|
106
|
+
common: {
|
|
107
|
+
name: "Device control",
|
|
108
|
+
},
|
|
109
|
+
native: {},
|
|
110
|
+
});
|
|
98
111
|
|
|
99
|
-
|
|
112
|
+
controlPrefix += ".";
|
|
100
113
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
for (const stateDef of this.definition.deviceType.switchingValues) {
|
|
104
|
-
const stateId = stateDef.name
|
|
105
|
-
.replace(/\${|}/g, "") // ${On} → On
|
|
106
|
-
.replace(this.adapter.FORBIDDEN_CHARS, "")
|
|
107
|
-
.toLowerCase();
|
|
108
|
-
|
|
109
|
-
await this.adapter.setObjectNotExistsAsync(`${controlPrefix}${stateId}`, {
|
|
110
|
-
type: "state",
|
|
111
|
-
common: {
|
|
112
|
-
name: stateId,
|
|
113
|
-
type: "boolean",
|
|
114
|
-
role: "button",
|
|
115
|
-
read: false,
|
|
116
|
-
write: true,
|
|
117
|
-
def: false,
|
|
118
|
-
},
|
|
119
|
-
native: {
|
|
120
|
-
commandValue: stateDef.value,
|
|
121
|
-
},
|
|
122
|
-
});
|
|
114
|
+
if (capabilities.hasSwitchingValues) {
|
|
115
|
+
await this.createSwitchStates(controlPrefix);
|
|
123
116
|
}
|
|
124
|
-
|
|
125
|
-
|
|
117
|
+
|
|
118
|
+
if (capabilities.hasLevel) {
|
|
119
|
+
await this.createLevelState(controlPrefix, capabilities.configObj);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
|
|
124
|
+
this.adapter.log.debug(`Created and saved device ${this.id} (${this.name})`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async createSwitchStates(statePrefix) {
|
|
128
|
+
for (const stateDef of this.definition.deviceType.switchingValues) {
|
|
129
|
+
const stateId = stateDef.name
|
|
130
|
+
.replace(/\${|}/g, "") // ${On} → On
|
|
131
|
+
.replace(this.adapter.FORBIDDEN_CHARS, "")
|
|
132
|
+
.toLowerCase();
|
|
133
|
+
|
|
134
|
+
await this.adapter.setObjectNotExistsAsync(`${statePrefix}${stateId}`, {
|
|
126
135
|
type: "state",
|
|
127
136
|
common: {
|
|
128
|
-
name:
|
|
129
|
-
type: "
|
|
130
|
-
role: "
|
|
131
|
-
read:
|
|
137
|
+
name: stateId,
|
|
138
|
+
type: "boolean",
|
|
139
|
+
role: "button",
|
|
140
|
+
read: false,
|
|
132
141
|
write: true,
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def: 0,
|
|
142
|
+
def: false,
|
|
143
|
+
},
|
|
144
|
+
native: {
|
|
145
|
+
commandValue: stateDef.value,
|
|
138
146
|
},
|
|
139
|
-
native: {},
|
|
140
147
|
});
|
|
141
148
|
}
|
|
142
|
-
|
|
149
|
+
}
|
|
143
150
|
|
|
144
|
-
|
|
151
|
+
async createLevelState(statePrefix, levelConfigObj) {
|
|
152
|
+
await this.adapter.setObjectNotExistsAsync(`${statePrefix}${levelConfigObj.kind}`, {
|
|
153
|
+
type: "state",
|
|
154
|
+
common: {
|
|
155
|
+
name: levelConfigObj.kind,
|
|
156
|
+
desc: levelConfigObj.desc,
|
|
157
|
+
type: "number",
|
|
158
|
+
role: levelConfigObj.role,
|
|
159
|
+
read: true,
|
|
160
|
+
write: true,
|
|
161
|
+
min: levelConfigObj.min,
|
|
162
|
+
max: levelConfigObj.max,
|
|
163
|
+
step: levelConfigObj.step,
|
|
164
|
+
unit: levelConfigObj.unit,
|
|
165
|
+
def: 0,
|
|
166
|
+
},
|
|
167
|
+
native: {},
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async createSensorState(statePrefix, sensorConfigObj) {
|
|
172
|
+
await this.adapter.setObjectNotExistsAsync(`${statePrefix}${sensorConfigObj.kind}`, {
|
|
173
|
+
type: "state",
|
|
174
|
+
common: {
|
|
175
|
+
name: sensorConfigObj.kind,
|
|
176
|
+
desc: sensorConfigObj.desc,
|
|
177
|
+
type: "number",
|
|
178
|
+
role: sensorConfigObj.role,
|
|
179
|
+
read: true,
|
|
180
|
+
write: false,
|
|
181
|
+
min: sensorConfigObj.min,
|
|
182
|
+
max: sensorConfigObj.max,
|
|
183
|
+
step: sensorConfigObj.step,
|
|
184
|
+
unit: sensorConfigObj.unit,
|
|
185
|
+
def: 0,
|
|
186
|
+
},
|
|
187
|
+
native: {},
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async createAlarmState(statePrefix, alarmConfigObj) {
|
|
192
|
+
await this.adapter.setObjectNotExistsAsync(`${statePrefix}${alarmConfigObj.kind}`, {
|
|
193
|
+
type: "state",
|
|
194
|
+
common: {
|
|
195
|
+
name: alarmConfigObj.kind,
|
|
196
|
+
desc: alarmConfigObj.desc,
|
|
197
|
+
type: "number",
|
|
198
|
+
role: alarmConfigObj.role,
|
|
199
|
+
read: true,
|
|
200
|
+
write: false,
|
|
201
|
+
states: alarmConfigObj.states,
|
|
202
|
+
},
|
|
203
|
+
native: {},
|
|
204
|
+
});
|
|
145
205
|
}
|
|
146
206
|
|
|
147
207
|
// Only writes changed data into the DB
|
|
@@ -173,23 +233,44 @@ class SchellenbergDevice {
|
|
|
173
233
|
}
|
|
174
234
|
|
|
175
235
|
let controlPrefix = "";
|
|
236
|
+
let infoPrefix = "";
|
|
176
237
|
if (value.masterDeviceID != this.id) {
|
|
177
238
|
// Child-Device unter einem Master-Device
|
|
178
239
|
controlPrefix = `${commonDefines.AdapterDatapointIDs.Devices}.${value.masterDeviceID}.${this.id}.${commonDefines.AdapterDatapointIDs.Control}.`;
|
|
240
|
+
infoPrefix = `${commonDefines.AdapterDatapointIDs.Devices}.${value.masterDeviceID}.${this.id}.${commonDefines.AdapterDatapointIDs.Info}.`;
|
|
179
241
|
} else {
|
|
180
242
|
// Einzelnes Device
|
|
181
243
|
controlPrefix = `${commonDefines.AdapterDatapointIDs.Devices}.${this.id}.${commonDefines.AdapterDatapointIDs.Control}.`;
|
|
244
|
+
infoPrefix = `${commonDefines.AdapterDatapointIDs.Devices}.${this.id}.${commonDefines.AdapterDatapointIDs.Info}.`;
|
|
182
245
|
}
|
|
183
246
|
|
|
184
|
-
|
|
247
|
+
// Dynamisch aus device.definition
|
|
248
|
+
const capabilities = getDeviceCapabilities(this.definition);
|
|
249
|
+
|
|
250
|
+
if (capabilities.hasSwitchingValues) {
|
|
185
251
|
// SwitchingValues ignorieren, liefern keine Updates zurück
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const stateId = `${controlPrefix}${commonDefines.AdapterStateIDs.Position}`;
|
|
189
|
-
await this.adapter.setStateAsync(stateId, value.value, true);
|
|
190
|
-
this.adapter.log.debug(`Device ${this.id}: Updated position = ${value.value}`);
|
|
252
|
+
this.adapter.log.debug(`Device ${this.id}: switchingValue update ignored (value=${value.value})`);
|
|
253
|
+
return;
|
|
191
254
|
}
|
|
255
|
+
|
|
256
|
+
if (capabilities.hasLevel) {
|
|
257
|
+
await this.setDeviceStateValue(controlPrefix, capabilities.configObj, value);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (capabilities.hasSensor) {
|
|
261
|
+
await this.setDeviceStateValue(infoPrefix, capabilities.configObj, value);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (capabilities.hasAlarm) {
|
|
265
|
+
await this.setDeviceStateValue(infoPrefix, capabilities.configObj, value);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async setDeviceStateValue(statePrefix, configObj, value) {
|
|
270
|
+
const stateId = `${statePrefix}${configObj.kind}`;
|
|
271
|
+
await this.adapter.setStateAsync(stateId, value.value, true);
|
|
272
|
+
this.adapter.log.debug(`Device ${this.id}: Updated ${configObj.kind} = ${value.value}`);
|
|
192
273
|
}
|
|
193
274
|
}
|
|
194
275
|
|
|
195
|
-
exports
|
|
276
|
+
module.exports = SchellenbergDevice;
|