iobroker.lorawan 1.20.49 → 1.20.51
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 +6 -121
- package/io-package.json +27 -27
- package/lib/modules/bridgeDeviceHandler.js +369 -35
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,6 +24,12 @@ For now there is documentation in English here: https://wiki.hafenmeister.de
|
|
|
24
24
|
Placeholder for the next version (at the beginning of the line):
|
|
25
25
|
### **WORK IN PROGRESS**
|
|
26
26
|
-->
|
|
27
|
+
### 1.20.51 (2026-02-14)
|
|
28
|
+
* (BenAhrdt) including of more entites in ToIob functionality (light, climate, hummidifier, lock, cover)
|
|
29
|
+
|
|
30
|
+
### 1.20.50 (2026-02-10)
|
|
31
|
+
* (BenAhrdt) implements light to ToIoB function
|
|
32
|
+
|
|
27
33
|
### 1.20.49 (2026-02-08)
|
|
28
34
|
* (BenAhrdt) improve handling of remove Function fpr Bridge
|
|
29
35
|
|
|
@@ -55,127 +61,6 @@ For now there is documentation in English here: https://wiki.hafenmeister.de
|
|
|
55
61
|
### 1.20.40 (2026-02-02)
|
|
56
62
|
* (BenAhrdt) update Form Width in Device Details
|
|
57
63
|
|
|
58
|
-
### 1.20.39 (2026-02-01)
|
|
59
|
-
* (BenAhrdt) update DeviceProfile
|
|
60
|
-
|
|
61
|
-
### 1.20.38 (2026-02-01)
|
|
62
|
-
* (BenAhrdt) add min / max to form
|
|
63
|
-
|
|
64
|
-
### 1.20.37 (2026-02-01)
|
|
65
|
-
* (BenAhrdt) show Values (at bridge device) and Downlinks (at lorawan device) in Device Details flexible
|
|
66
|
-
|
|
67
|
-
### 1.20.36 (2026-01-31)
|
|
68
|
-
* (BenAhrdt) add more details to lorawan and bridged devices
|
|
69
|
-
* (BenAhrdt) change some logging
|
|
70
|
-
|
|
71
|
-
### 1.20.35 (2026-01-31)
|
|
72
|
-
* (BenAhrdt) display actual device values for foreign devices
|
|
73
|
-
|
|
74
|
-
### 1.20.34 (2026-01-30)
|
|
75
|
-
* (BenAhrdt) starup bridge device with battery value
|
|
76
|
-
|
|
77
|
-
### 1.20.33 (2026-01-30)
|
|
78
|
-
* (BenAhrdt) first step of role detectiopn in bridged devices
|
|
79
|
-
|
|
80
|
-
### 1.20.32 (2026-01-30)
|
|
81
|
-
* (BenAhrdt) change icon for default
|
|
82
|
-
|
|
83
|
-
### 1.20.31 (2026-01-30)
|
|
84
|
-
* (BenAhrdt) Add colors to DeviceInfo and Details to Bridge Devices
|
|
85
|
-
|
|
86
|
-
### 1.20.30 (2026-01-30)
|
|
87
|
-
* (BenAhrdt) Devices sorted alphabetically for Device Manager
|
|
88
|
-
|
|
89
|
-
### 1.20.29 (2026-01-30)
|
|
90
|
-
* (BenAhrdt) bugfix entity type
|
|
91
|
-
|
|
92
|
-
### 1.20.28 (2026-01-30)
|
|
93
|
-
* (BenAhrdt) showing experimental foreign devices
|
|
94
|
-
|
|
95
|
-
### 1.20.27 (2026-01-29)
|
|
96
|
-
* (BenAhrdt) bugfix rolehandling
|
|
97
|
-
|
|
98
|
-
### 1.20.26 (2026-01-29)
|
|
99
|
-
* (BenAhrdt) bring objectstore and deviceManager functions in new structure for future devices
|
|
100
|
-
|
|
101
|
-
### 1.20.25 (2026-01-28)
|
|
102
|
-
* (BenAhrdt) improve number of role detection
|
|
103
|
-
|
|
104
|
-
### 1.20.24 (2026-01-28)
|
|
105
|
-
* (BenAhrdt) change info Form to Detail button
|
|
106
|
-
|
|
107
|
-
### 1.20.23 (2026-01-28)
|
|
108
|
-
* (BenAhrdt) change role display and icons
|
|
109
|
-
|
|
110
|
-
### 1.20.22 (2026-01-27)
|
|
111
|
-
* (BenAhrdt) change preasure quere to pressure
|
|
112
|
-
|
|
113
|
-
### 1.20.21 (2026-01-27)
|
|
114
|
-
* (BenAhrdt) set Details to informations and add icons for weateher station / humidity
|
|
115
|
-
|
|
116
|
-
### 1.20.20 (2026-01-27)
|
|
117
|
-
* (BenAhrdt) icon assign changed
|
|
118
|
-
|
|
119
|
-
### 1.20.19 (2026-01-27)
|
|
120
|
-
* (BenAhrdt) bugfix incon set
|
|
121
|
-
|
|
122
|
-
### 1.20.18 (2026-01-27)
|
|
123
|
-
* (BenAhrdt) bugfix nameing incomingTopic
|
|
124
|
-
|
|
125
|
-
### 1.20.17 (2026-01-27)
|
|
126
|
-
* (BenAhrdt) implement Device details
|
|
127
|
-
|
|
128
|
-
### 1.20.16 (2026-01-27)
|
|
129
|
-
* (BenAhrdt) add informations to device Manager
|
|
130
|
-
|
|
131
|
-
### 1.20.15 (2026-01-26)
|
|
132
|
-
* (BenAhrdt) sort output for informations
|
|
133
|
-
|
|
134
|
-
### 1.20.14 (2026-01-26)
|
|
135
|
-
* (BenAhrdt) insert node
|
|
136
|
-
|
|
137
|
-
### 1.20.13 (2026-01-26)
|
|
138
|
-
* (BenAhrdt) remove nod from crypto
|
|
139
|
-
|
|
140
|
-
### 1.20.12 (2026-01-26)
|
|
141
|
-
* (BenAhrdt) check for update
|
|
142
|
-
|
|
143
|
-
### 1.20.11 (2026-01-26)
|
|
144
|
-
* (BenAhrdt) improve device Manager icons and Buttons
|
|
145
|
-
|
|
146
|
-
### 1.20.10 (2026-01-26)
|
|
147
|
-
* (BenAhrdt) return to root getCnageInfo
|
|
148
|
-
|
|
149
|
-
### 1.20.9 (2026-01-26)
|
|
150
|
-
* (BenAhrdt) experimental for form
|
|
151
|
-
|
|
152
|
-
### 1.20.8 (2026-01-26)
|
|
153
|
-
* (BenAhrdt) changes in objectStore
|
|
154
|
-
|
|
155
|
-
### 1.20.7 (2026-01-25)
|
|
156
|
-
* (BenAhrdt) bugfix correct writing of indicators
|
|
157
|
-
|
|
158
|
-
### 1.20.6 (2026-01-25)
|
|
159
|
-
* (BenAhrdt) updateing assignhandler und modifying indicators and informations
|
|
160
|
-
|
|
161
|
-
### 1.20.5 (2026-01-25)
|
|
162
|
-
* (BenAhrdt) bugfixing updating object Store with not alowed id
|
|
163
|
-
|
|
164
|
-
### 1.20.4 (2026-01-25)
|
|
165
|
-
* (BenAhrdt) experimental to debug in live system
|
|
166
|
-
|
|
167
|
-
### 1.20.3 (2026-01-25)
|
|
168
|
-
* (BenAhrdt) bugfix device Manager
|
|
169
|
-
|
|
170
|
-
### 1.20.2 (2026-01-25)
|
|
171
|
-
* (BenAhrdt) bugfix device Manager and objectStore device checks
|
|
172
|
-
|
|
173
|
-
### 1.20.1 (2026-01-25)
|
|
174
|
-
* (BenAhrdt) bugfix device Manager
|
|
175
|
-
|
|
176
|
-
### 1.20.0 (2026-01-25)
|
|
177
|
-
* (BenAhrdt) add first Steps of device Manager
|
|
178
|
-
|
|
179
64
|
### Older entries
|
|
180
65
|
[here](OLD_CHANGELOG.md)
|
|
181
66
|
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "lorawan",
|
|
4
|
-
"version": "1.20.
|
|
4
|
+
"version": "1.20.51",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.20.51": {
|
|
7
|
+
"en": "including of more entites in ToIob functionality (light, climate, hummidifier, lock, cover)",
|
|
8
|
+
"de": "mit mehr Entites in ToIob Funktionalität (Licht, Klima, Demütiger, Schloss, Cover)",
|
|
9
|
+
"ru": "включение большего количества элементов в функциональность ToIob (свет, климат, увлажнитель, замок, крышка)",
|
|
10
|
+
"pt": "incluindo de mais entites na funcionalidade ToIob (luz, clima, hummidificador, bloqueio, tampa)",
|
|
11
|
+
"nl": "met inbegrip van meer entites in Toiob functionaliteit (licht, klimaat, bevochtiger, slot, afdekking)",
|
|
12
|
+
"fr": "incluant plus d'entites dans la fonctionnalité TOIob (lumière, climat, hummidificateur, serrure, couvercle)",
|
|
13
|
+
"it": "incluso di più diritti nella funzionalità ToIob (luce, clima, hummidifier, lock, cover)",
|
|
14
|
+
"es": "incluyendo más entites en la funcionalidad ToIob (light, clima, hummidifier, lock, cover)",
|
|
15
|
+
"pl": "w tym więcej entytów w funkcjonalności Tołob (światło, klimat, hummidyfikator, zamek, okładka)",
|
|
16
|
+
"uk": "в тому числі більш схильні до функції ToIob (світло, клімат, зволожувач, замок, кришка)",
|
|
17
|
+
"zh-cn": "包括ToIob功能中的更多实体(光、气候、放大器、锁、覆盖)"
|
|
18
|
+
},
|
|
19
|
+
"1.20.50": {
|
|
20
|
+
"en": "implements light to ToIoB function",
|
|
21
|
+
"de": "implementiert Licht zur ToIoB-Funktion",
|
|
22
|
+
"ru": "функция Light to ToIoB",
|
|
23
|
+
"pt": "implementa luz para a função ToIoB",
|
|
24
|
+
"nl": "implementeert licht naar ToIoB functie",
|
|
25
|
+
"fr": "implémente la lumière à la fonction ToIoB",
|
|
26
|
+
"it": "implementa la luce alla funzione ToIoB",
|
|
27
|
+
"es": "implementa luz a la función ToIoB",
|
|
28
|
+
"pl": "implementuje światło do funkcji ToIoB",
|
|
29
|
+
"uk": "реалізує світло для функції ToIoB",
|
|
30
|
+
"zh-cn": "执行光线到 ToIOB 函数"
|
|
31
|
+
},
|
|
6
32
|
"1.20.49": {
|
|
7
33
|
"en": "improve handling of remove Function fpr Bridge",
|
|
8
34
|
"de": "verbesserung der Handhabung von Entfernen Function fpr Bridge",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "pierwsze możliwości ustawienia wartości w urządzeniach Tolob",
|
|
68
94
|
"uk": "перші можливості встановити значення в пристроях ToIob",
|
|
69
95
|
"zh-cn": "在 ToIob 设备中设置值的最初可能性"
|
|
70
|
-
},
|
|
71
|
-
"1.20.44": {
|
|
72
|
-
"en": "add possibility to see devices wiche are sendet ToIob",
|
|
73
|
-
"de": "hinzufügen der Möglichkeit, Geräte zu sehen wiche sind sendet ToIob",
|
|
74
|
-
"ru": "добавить возможность видеть устройства Wiche с помощью sendet ToIob",
|
|
75
|
-
"pt": "adicionar possibilidade de ver dispositivos wiche são sentet ToIob",
|
|
76
|
-
"nl": "voeg mogelijkheid toe om apparaten wiche te zien zijn sendet ToIob",
|
|
77
|
-
"fr": "ajouter la possibilité de voir les appareils wiche sont sendet toIob",
|
|
78
|
-
"it": "aggiungere la possibilità di vedere i dispositivi wiche sono mittente ToIob",
|
|
79
|
-
"es": "añadir la posibilidad de ver los dispositivos wiche son sendet ToIob",
|
|
80
|
-
"pl": "dodać możliwość zobaczyć urządzenia wiche są sendet Tolob",
|
|
81
|
-
"uk": "додати можливість побачити пристрої Wiche відправник ToIob",
|
|
82
|
-
"zh-cn": "添加可看到设备 wiche 是 sendet ToIob"
|
|
83
|
-
},
|
|
84
|
-
"1.20.43": {
|
|
85
|
-
"en": "add value.power.active and value.power.reactive ...",
|
|
86
|
-
"de": "add value.power.active und value.power.reactive ...",
|
|
87
|
-
"ru": "добавить value.power.active и value.power.reactive.",
|
|
88
|
-
"pt": "adicionar valor.power.active e valor.power.reative ...",
|
|
89
|
-
"nl": "toegevoegde waarde.power.active en waarde.power.reactive ...",
|
|
90
|
-
"fr": "ajouter value.power.active et value.power.réactive ...",
|
|
91
|
-
"it": "aggiungere valore.power.active e value.power.reactive ...",
|
|
92
|
-
"es": "añadir valor.power.active y valor.power.reactive ...",
|
|
93
|
-
"pl": "dodaj value.power.active i value.power.reaktywne...",
|
|
94
|
-
"uk": "add value.power.active and value.power.reactive ...",
|
|
95
|
-
"zh-cn": "增加值 能量 活性 能量 反应..."
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
|
@@ -47,7 +47,7 @@ class bridgeDeviceHandlerClass {
|
|
|
47
47
|
const activeFunction = 'bridgeDeviceHandler.js - generateDeviceStructure';
|
|
48
48
|
this.adapter.log.silly(`Function ${activeFunction} started.`);
|
|
49
49
|
try {
|
|
50
|
-
const version = '1.
|
|
50
|
+
const version = '1.1.1';
|
|
51
51
|
if (!message.version || message.version !== version) {
|
|
52
52
|
this.adapter.log.warn(`You need to use version ${version} of the Home Assistant automation.`);
|
|
53
53
|
return;
|
|
@@ -137,25 +137,42 @@ class bridgeDeviceHandlerClass {
|
|
|
137
137
|
unique_id = unique_id.substring(channel.length + 1, unique_id.length);
|
|
138
138
|
}
|
|
139
139
|
unique_id.replace('.', '_');
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
140
|
+
for (const state of entityInfo.state) {
|
|
141
|
+
await this.adapter.extendObject(state.id, {
|
|
142
|
+
type: 'state',
|
|
143
|
+
common: {
|
|
144
|
+
name: state.name,
|
|
145
|
+
type: state.type,
|
|
146
|
+
role: state.role,
|
|
147
|
+
read: state.read,
|
|
148
|
+
write: state.write,
|
|
149
|
+
unit: state.unit,
|
|
150
|
+
min: state.min,
|
|
151
|
+
max: state.max,
|
|
152
|
+
step: state.step,
|
|
153
|
+
states: state.states ? state.states : undefined,
|
|
154
|
+
},
|
|
155
|
+
native: { entity: entity, entityInfo: entityInfo, state: state },
|
|
156
|
+
});
|
|
157
|
+
let stateValue = state.val;
|
|
158
|
+
if (state.type === 'boolean') {
|
|
159
|
+
stateValue = state.val === 'on';
|
|
160
|
+
} else if (state.type === 'number') {
|
|
161
|
+
if (state.states && typeof state.val === 'string') {
|
|
162
|
+
stateValue = state.val;
|
|
163
|
+
} else {
|
|
164
|
+
stateValue = Number(state.val);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (
|
|
168
|
+
this.adapter.objectExists(state.id) &&
|
|
169
|
+
stateValue != null &&
|
|
170
|
+
stateValue !== 0 &&
|
|
171
|
+
stateValue != '#000000'
|
|
172
|
+
) {
|
|
173
|
+
await this.adapter.setState(state.id, stateValue, true);
|
|
174
|
+
}
|
|
157
175
|
}
|
|
158
|
-
await this.adapter.setState(entityInfo.state.id, state, true);
|
|
159
176
|
}
|
|
160
177
|
}
|
|
161
178
|
// Periodic discovery
|
|
@@ -170,7 +187,11 @@ class bridgeDeviceHandlerClass {
|
|
|
170
187
|
for (const entityId of Object.keys(entities)) {
|
|
171
188
|
if (!Object.keys(message.entities).includes(entityId)) {
|
|
172
189
|
const entityInfo = this.generateStructure(entities[entityId]);
|
|
173
|
-
|
|
190
|
+
if (entityInfo?.state) {
|
|
191
|
+
for (const state of entityInfo.state) {
|
|
192
|
+
await this.adapter.delObjectAsync(state.id);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
174
195
|
if (!checkDevices[entityInfo?.device.id]) {
|
|
175
196
|
checkDevices[entityInfo?.device.id] = {};
|
|
176
197
|
}
|
|
@@ -278,17 +299,241 @@ class bridgeDeviceHandlerClass {
|
|
|
278
299
|
if (clearStatename.startsWith(`${device.name} `)) {
|
|
279
300
|
clearStatename = clearStatename.substring(device.name.length + 1, clearStatename.length);
|
|
280
301
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
302
|
+
let state = [];
|
|
303
|
+
/************************************************************************************************
|
|
304
|
+
* **********************************************************************************************
|
|
305
|
+
* *********************************************************************************************/
|
|
306
|
+
if (entity.domain === 'light') {
|
|
307
|
+
state.push({
|
|
308
|
+
id: `${channel.id}.on`,
|
|
309
|
+
name: clearStatename || stateId,
|
|
310
|
+
type: 'boolean',
|
|
311
|
+
role: this.detectRole(entity, type),
|
|
312
|
+
read: true,
|
|
313
|
+
write: true,
|
|
314
|
+
val: entity.state,
|
|
315
|
+
});
|
|
316
|
+
if (entity.attributes.brightness !== undefined) {
|
|
317
|
+
state.push({
|
|
318
|
+
id: `${channel.id}.brightness`,
|
|
319
|
+
name: clearStatename || stateId,
|
|
320
|
+
type: 'number',
|
|
321
|
+
role: this.detectRole(entity, type),
|
|
322
|
+
read: true,
|
|
323
|
+
write: true,
|
|
324
|
+
val: entity.attributes.brightness,
|
|
325
|
+
isAttribute: true,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
if (
|
|
329
|
+
entity.attributes.rgb_color !== undefined &&
|
|
330
|
+
entity.capabilities.supported_color_modes.includes('rgb')
|
|
331
|
+
) {
|
|
332
|
+
const colorObject = {
|
|
333
|
+
r: 0,
|
|
334
|
+
g: 0,
|
|
335
|
+
b: 0,
|
|
336
|
+
};
|
|
337
|
+
if (entity.attributes.rgb_color) {
|
|
338
|
+
colorObject.r = entity.attributes.rgb_color[0];
|
|
339
|
+
colorObject.g = entity.attributes.rgb_color[1];
|
|
340
|
+
colorObject.b = entity.attributes.rgb_color[2];
|
|
341
|
+
}
|
|
342
|
+
state.push({
|
|
343
|
+
id: `${channel.id}.color`,
|
|
344
|
+
name: clearStatename || stateId,
|
|
345
|
+
type: 'string',
|
|
346
|
+
role: this.detectRole(entity, type),
|
|
347
|
+
read: true,
|
|
348
|
+
write: true,
|
|
349
|
+
val: this.adapter.bridge?.rgbToHex(colorObject),
|
|
350
|
+
isAttribute: true,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
if (
|
|
354
|
+
entity.attributes.color_temp_kelvin !== undefined &&
|
|
355
|
+
entity.capabilities.supported_color_modes.includes('color_temp')
|
|
356
|
+
) {
|
|
357
|
+
state.push({
|
|
358
|
+
id: `${channel.id}.colorTempKelvin`,
|
|
359
|
+
name: clearStatename || stateId,
|
|
360
|
+
type: 'number',
|
|
361
|
+
role: this.detectRole(entity, type),
|
|
362
|
+
read: true,
|
|
363
|
+
write: true,
|
|
364
|
+
val: entity.attributes.color_temp_kelvin,
|
|
365
|
+
min: entity.attributes.min_color_temp_kelvin,
|
|
366
|
+
max: entity.attributes.max_color_temp_kelvin,
|
|
367
|
+
isAttribute: true,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
if (entity.attributes.effect !== undefined) {
|
|
371
|
+
const states = entity.capabilities.effects.states;
|
|
372
|
+
const currentEffect = entity.attributes.effect;
|
|
373
|
+
state.push({
|
|
374
|
+
id: `${channel.id}.effect`,
|
|
375
|
+
name: clearStatename || stateId,
|
|
376
|
+
type: 'number',
|
|
377
|
+
role: this.detectRole(entity, type),
|
|
378
|
+
read: true,
|
|
379
|
+
write: true,
|
|
380
|
+
states: entity.capabilities.effects.states ? entity.capabilities.effects.states : undefined,
|
|
381
|
+
val: this.getKeyOfState(currentEffect, states),
|
|
382
|
+
isAttribute: true,
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
/************************************************************************************************
|
|
386
|
+
* **********************************************************************************************
|
|
387
|
+
* *********************************************************************************************/
|
|
388
|
+
} else if (entity.domain === 'cover') {
|
|
389
|
+
state.push({
|
|
390
|
+
id: `${channel.id}.command`,
|
|
391
|
+
name: clearStatename || stateId,
|
|
392
|
+
type: 'number',
|
|
393
|
+
role: this.detectRole(entity, type),
|
|
394
|
+
read: true,
|
|
395
|
+
write: true,
|
|
396
|
+
states: entity.capabilities.commands.states ? entity.capabilities.commands.states : undefined,
|
|
397
|
+
val: entity.capabilities.commands.states
|
|
398
|
+
? this.getKeyOfState(entity.state, entity.capabilities.commands.states)
|
|
399
|
+
: entity.state,
|
|
400
|
+
isAttribute: true,
|
|
401
|
+
});
|
|
402
|
+
if (entity.attributes.current_position !== undefined) {
|
|
403
|
+
state.push({
|
|
404
|
+
id: `${channel.id}.currentPosition`,
|
|
405
|
+
name: clearStatename || stateId,
|
|
406
|
+
type: 'number',
|
|
407
|
+
role: this.detectRole(entity, type),
|
|
408
|
+
read: true,
|
|
409
|
+
write: false,
|
|
410
|
+
val: entity.attributes.current_position,
|
|
411
|
+
isAttribute: true,
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
/************************************************************************************************
|
|
415
|
+
* **********************************************************************************************
|
|
416
|
+
* *********************************************************************************************/
|
|
417
|
+
} else if (entity.domain === 'climate') {
|
|
418
|
+
const modes = {};
|
|
419
|
+
for (const value of entity.attributes.hvac_modes) {
|
|
420
|
+
modes[value] = value;
|
|
421
|
+
}
|
|
422
|
+
state.push({
|
|
423
|
+
id: `${channel.id}.mode`,
|
|
424
|
+
name: clearStatename || stateId,
|
|
425
|
+
type: 'string',
|
|
426
|
+
role: this.detectRole(entity, type),
|
|
427
|
+
read: true,
|
|
428
|
+
write: true,
|
|
429
|
+
states: modes,
|
|
430
|
+
val: entity.state,
|
|
431
|
+
isAttribute: true,
|
|
432
|
+
});
|
|
433
|
+
if (entity.attributes.current_temperature !== undefined) {
|
|
434
|
+
state.push({
|
|
435
|
+
id: `${channel.id}.currentTemperature`,
|
|
436
|
+
name: clearStatename || stateId,
|
|
437
|
+
type: 'number',
|
|
438
|
+
role: this.detectRole(entity, type),
|
|
439
|
+
unit: entity.unit_of_measurement || undefined,
|
|
440
|
+
read: true,
|
|
441
|
+
write: false,
|
|
442
|
+
val: entity.attributes.current_temperature,
|
|
443
|
+
isAttribute: true,
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
if (entity.attributes.temperature !== undefined) {
|
|
447
|
+
state.push({
|
|
448
|
+
id: `${channel.id}.temperature`,
|
|
449
|
+
name: clearStatename || stateId,
|
|
450
|
+
type: 'number',
|
|
451
|
+
role: this.detectRole(entity, type),
|
|
452
|
+
unit: entity.unit_of_measurement || undefined,
|
|
453
|
+
read: true,
|
|
454
|
+
write: true,
|
|
455
|
+
min: entity.attributes.min_temp ? entity.attributes.min_temp : undefined,
|
|
456
|
+
max: entity.attributes.max_temp ? entity.attributes.max_temp : undefined,
|
|
457
|
+
step: entity.attributes.target_temp_step ? entity.attributes.target_temp_step : undefined,
|
|
458
|
+
val: entity.attributes.temperature,
|
|
459
|
+
isAttribute: true,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
/************************************************************************************************
|
|
463
|
+
* **********************************************************************************************
|
|
464
|
+
* *********************************************************************************************/
|
|
465
|
+
} else if (entity.domain === 'humidifier') {
|
|
466
|
+
state.push({
|
|
467
|
+
id: `${channel.id}.on`,
|
|
468
|
+
name: clearStatename || stateId,
|
|
469
|
+
type: 'boolean',
|
|
470
|
+
role: this.detectRole(entity, type),
|
|
471
|
+
read: true,
|
|
472
|
+
write: true,
|
|
473
|
+
val: entity.state,
|
|
474
|
+
});
|
|
475
|
+
if (entity.attributes.current_humidity !== undefined) {
|
|
476
|
+
state.push({
|
|
477
|
+
id: `${channel.id}.currentHumidity`,
|
|
478
|
+
name: clearStatename || stateId,
|
|
479
|
+
type: 'number',
|
|
480
|
+
role: this.detectRole(entity, type),
|
|
481
|
+
unit: entity.unit_of_measurement || undefined,
|
|
482
|
+
read: true,
|
|
483
|
+
write: false,
|
|
484
|
+
val: entity.attributes.current_humidity,
|
|
485
|
+
isAttribute: true,
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
if (entity.attributes.humidity !== undefined) {
|
|
489
|
+
state.push({
|
|
490
|
+
id: `${channel.id}.humidity`,
|
|
491
|
+
name: clearStatename || stateId,
|
|
492
|
+
type: 'number',
|
|
493
|
+
role: this.detectRole(entity, type),
|
|
494
|
+
unit: entity.unit_of_measurement || undefined,
|
|
495
|
+
read: true,
|
|
496
|
+
write: true,
|
|
497
|
+
min: entity.attributes.min_humidity ? entity.attributes.min_humidity : undefined,
|
|
498
|
+
max: entity.attributes.max_humidity ? entity.attributes.max_humidity : undefined,
|
|
499
|
+
val: entity.attributes.humidity,
|
|
500
|
+
isAttribute: true,
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
/************************************************************************************************
|
|
504
|
+
* **********************************************************************************************
|
|
505
|
+
* *********************************************************************************************/
|
|
506
|
+
} else if (entity.domain === 'lock') {
|
|
507
|
+
const commands = {
|
|
508
|
+
lock: 'lock',
|
|
509
|
+
unlock: 'unlock',
|
|
510
|
+
};
|
|
511
|
+
if ((entity.attributes.supported_features & 1) !== 0) {
|
|
512
|
+
commands.open = 'open';
|
|
513
|
+
}
|
|
514
|
+
state.push({
|
|
515
|
+
id: `${channel.id}.command`,
|
|
516
|
+
name: clearStatename || stateId,
|
|
517
|
+
type: 'string',
|
|
518
|
+
role: this.detectRole(entity, type),
|
|
519
|
+
read: true,
|
|
520
|
+
write: true,
|
|
521
|
+
states: commands,
|
|
522
|
+
val: entity.state,
|
|
523
|
+
isAttribute: true,
|
|
524
|
+
});
|
|
525
|
+
} else {
|
|
526
|
+
state.push({
|
|
527
|
+
id: `${channel.id}.${stateId}`,
|
|
528
|
+
name: clearStatename || stateId,
|
|
529
|
+
type: type,
|
|
530
|
+
role: this.detectRole(entity, type),
|
|
531
|
+
unit: entity.unit_of_measurement || undefined,
|
|
532
|
+
read: entity.domain !== 'button',
|
|
533
|
+
write: this.isWritable(entity.domain),
|
|
534
|
+
assign: assign ? assign : undefined,
|
|
535
|
+
val: entity.state,
|
|
536
|
+
});
|
|
292
537
|
}
|
|
293
538
|
|
|
294
539
|
const meta = {
|
|
@@ -308,6 +553,23 @@ class bridgeDeviceHandlerClass {
|
|
|
308
553
|
}
|
|
309
554
|
}
|
|
310
555
|
|
|
556
|
+
/**
|
|
557
|
+
*
|
|
558
|
+
* @param state Current state
|
|
559
|
+
* @param states States with possible entries
|
|
560
|
+
*/
|
|
561
|
+
getKeyOfState(state, states) {
|
|
562
|
+
let commandNumber = null;
|
|
563
|
+
|
|
564
|
+
for (const [key, value] of Object.entries(states)) {
|
|
565
|
+
if (value === state) {
|
|
566
|
+
commandNumber = Number(key);
|
|
567
|
+
return commandNumber;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return state;
|
|
571
|
+
}
|
|
572
|
+
|
|
311
573
|
/**
|
|
312
574
|
* @param entity entity wich contains the deired informations
|
|
313
575
|
*/
|
|
@@ -460,12 +722,84 @@ class bridgeDeviceHandlerClass {
|
|
|
460
722
|
try {
|
|
461
723
|
const idObject = await this.adapter.getObjectAsync(id);
|
|
462
724
|
const sendInfo = {};
|
|
463
|
-
if (idObject.native.
|
|
464
|
-
sendInfo
|
|
725
|
+
if (idObject.native.state.isAttribute) {
|
|
726
|
+
sendInfo.entity_id = idObject.native.entity.entity_id;
|
|
727
|
+
if (idObject.native.entity.domain === 'light') {
|
|
728
|
+
// Brightness
|
|
729
|
+
if (id.endsWith('brightness')) {
|
|
730
|
+
sendInfo.attribute = 'brightness';
|
|
731
|
+
sendInfo.value = state.val;
|
|
732
|
+
|
|
733
|
+
// color
|
|
734
|
+
} else if (id.endsWith('color')) {
|
|
735
|
+
sendInfo.attribute = 'rgb_color';
|
|
736
|
+
const colorObject = this.adapter.bridge?.hexToRgb(state.val);
|
|
737
|
+
sendInfo.value = [colorObject.r, colorObject.g, colorObject.b];
|
|
738
|
+
|
|
739
|
+
// colorTemp
|
|
740
|
+
} else if (id.endsWith('colorTempKelvin')) {
|
|
741
|
+
sendInfo.attribute = 'color_temp_kelvin';
|
|
742
|
+
sendInfo.value = state.val;
|
|
743
|
+
|
|
744
|
+
// effect
|
|
745
|
+
} else if (id.endsWith('effect')) {
|
|
746
|
+
sendInfo.attribute = 'effect';
|
|
747
|
+
const effects = idObject.native.entity.capabilities.effects.states;
|
|
748
|
+
sendInfo.value = effects[state.val];
|
|
749
|
+
}
|
|
750
|
+
/***************************************************************************************
|
|
751
|
+
* *************************************************************************************
|
|
752
|
+
* ************************************************************************************/
|
|
753
|
+
} else if (idObject.native.entity.domain === 'cover') {
|
|
754
|
+
// command
|
|
755
|
+
if (id.endsWith('command')) {
|
|
756
|
+
sendInfo.attribute = 'command';
|
|
757
|
+
const commands = idObject.native.entity.capabilities.commands.states;
|
|
758
|
+
sendInfo.value = commands[state.val];
|
|
759
|
+
}
|
|
760
|
+
/***************************************************************************************
|
|
761
|
+
* *************************************************************************************
|
|
762
|
+
* ************************************************************************************/
|
|
763
|
+
} else if (idObject.native.entity.domain === 'climate') {
|
|
764
|
+
// mode
|
|
765
|
+
if (id.endsWith('mode')) {
|
|
766
|
+
sendInfo.attribute = 'mode';
|
|
767
|
+
sendInfo.value = state.val;
|
|
768
|
+
|
|
769
|
+
// color
|
|
770
|
+
} else if (id.endsWith('temperature')) {
|
|
771
|
+
sendInfo.attribute = 'temperature';
|
|
772
|
+
sendInfo.value = state.val;
|
|
773
|
+
}
|
|
774
|
+
/***************************************************************************************
|
|
775
|
+
* *************************************************************************************
|
|
776
|
+
* ************************************************************************************/
|
|
777
|
+
} else if (idObject.native.entity.domain === 'humidifier') {
|
|
778
|
+
// humidity
|
|
779
|
+
if (id.endsWith('humidity')) {
|
|
780
|
+
sendInfo.attribute = 'humidity';
|
|
781
|
+
sendInfo.value = state.val;
|
|
782
|
+
}
|
|
783
|
+
/***************************************************************************************
|
|
784
|
+
* *************************************************************************************
|
|
785
|
+
* ************************************************************************************/
|
|
786
|
+
} else if (idObject.native.entity.domain === 'lock') {
|
|
787
|
+
// humidity
|
|
788
|
+
if (id.endsWith('command')) {
|
|
789
|
+
sendInfo.attribute = 'command';
|
|
790
|
+
sendInfo.value = state.val;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
465
793
|
} else {
|
|
466
|
-
|
|
794
|
+
if (idObject.native.entityInfo.state.assign) {
|
|
795
|
+
sendInfo[idObject.native.entity.entity_id] = idObject.native.entityInfo.state.assign[state.val];
|
|
796
|
+
} else {
|
|
797
|
+
sendInfo[idObject.native.entity.entity_id] = state.val;
|
|
798
|
+
}
|
|
467
799
|
}
|
|
468
|
-
await this.adapter.bridge.publishId(`${this.adapter.namespace}.bridge.dataFromIob`, sendInfo, {
|
|
800
|
+
await this.adapter.bridge.publishId(`${this.adapter.namespace}.bridge.dataFromIob`, sendInfo, {
|
|
801
|
+
retain: false,
|
|
802
|
+
});
|
|
469
803
|
await this.adapter.setState(`${this.adapter.namespace}.bridge.dataFromIob`, JSON.stringify(sendInfo), true);
|
|
470
804
|
} catch (error) {
|
|
471
805
|
this.adapter.log.error(`error at ${activeFunction}: ${error}`);
|