iobroker.lorawan 1.22.1 → 1.22.3
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 -0
- package/admin/jsonConfig.json +0 -1
- package/io-package.json +27 -27
- package/lib/modules/assignhandler.js +2 -2
- package/lib/modules/deviceManager/bridgeDevices.js +491 -31
- package/lib/modules/deviceManager/lorawanDevices.js +1 -1
- package/lib/modules/deviceManager/toIobDevices.js +1 -1
- 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.22.3 (2026-04-10)
|
|
28
|
+
* (BenAhrdt) add first Test for states of configed devices shown in device Manager cards
|
|
29
|
+
|
|
30
|
+
### 1.22.2 (2026-04-07)
|
|
31
|
+
* (BenAhrdt) remove readOnly flag from jsonEditor
|
|
32
|
+
|
|
27
33
|
### 1.22.1 (2026-04-02)
|
|
28
34
|
* (BenAhrdt) add more roles to toIob devices
|
|
29
35
|
|
package/admin/jsonConfig.json
CHANGED
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "lorawan",
|
|
4
|
-
"version": "1.22.
|
|
4
|
+
"version": "1.22.3",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.22.3": {
|
|
7
|
+
"en": "add first Test for states of configed devices shown in device Manager cards",
|
|
8
|
+
"de": "fügen Sie ersten Test für Zustände von konfiktiven Geräten in Device Manager-Karten",
|
|
9
|
+
"ru": "добавить первый Тест для состояний конфигурированных устройств, показанных в картах диспетчера устройств",
|
|
10
|
+
"pt": "adicionar primeiro Teste para estados de dispositivos configurados mostrados nas placas do Gerenciador de dispositivos",
|
|
11
|
+
"nl": "toe te voegen eerste Test voor toestanden van geconfigureerde apparaten weergegeven in apparaat Manager kaarten",
|
|
12
|
+
"fr": "ajouter le premier test pour les états des périphériques configurés affichés dans les cartes de gestionnaire de périphériques",
|
|
13
|
+
"it": "aggiungere il primo test per gli stati di dispositivi confidificati mostrati nelle schede Gestione dispositivi",
|
|
14
|
+
"es": "añadir el primer Test para estados de dispositivos conectados mostrados en tarjetas de administrador de dispositivos",
|
|
15
|
+
"pl": "dodaj pierwszy test dla stanu podłączonych urządzeń pokazany w kartach menedżera urządzeń",
|
|
16
|
+
"uk": "додати перший тест для станів настрочених пристроїв, відображених в картах диспетчера пристроїв",
|
|
17
|
+
"zh-cn": "添加第一个设备管理卡中显示的配置设备状态测试"
|
|
18
|
+
},
|
|
19
|
+
"1.22.2": {
|
|
20
|
+
"en": "remove readOnly flag from jsonEditor",
|
|
21
|
+
"de": "readOnly flag von jsonEditor entfernen",
|
|
22
|
+
"ru": "удалить только флаг jsonEditor",
|
|
23
|
+
"pt": "remove readOnly flag do jsonEditor",
|
|
24
|
+
"nl": "readOnly-vlag verwijderen uit jsonEditor",
|
|
25
|
+
"fr": "supprimer readOnly drapeau de jsonEditor",
|
|
26
|
+
"it": "rimuovere readOnly flag da jsonEditor",
|
|
27
|
+
"es": "eliminar readOnly flag de jsonEditor",
|
|
28
|
+
"pl": "usuń flagę readOnly z jsonEditor",
|
|
29
|
+
"uk": "remove readOnly прапорець з jsonEditor",
|
|
30
|
+
"zh-cn": "从json编辑器中删除只读的旗"
|
|
31
|
+
},
|
|
6
32
|
"1.22.1": {
|
|
7
33
|
"en": "add more roles to toIob devices",
|
|
8
34
|
"de": "weitere Rollen zu Iob-Geräten hinzufügen",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "sprawdź rodzime",
|
|
68
94
|
"uk": "перевірити рідний",
|
|
69
95
|
"zh-cn": "检查本地"
|
|
70
|
-
},
|
|
71
|
-
"1.21.28": {
|
|
72
|
-
"en": "add enum query to air quality",
|
|
73
|
-
"de": "enum quer zur luftqualität hinzufügen",
|
|
74
|
-
"ru": "добавить вопрос к качеству воздуха",
|
|
75
|
-
"pt": "adicionar consulta enum à qualidade do ar",
|
|
76
|
-
"nl": "enum query toevoegen aan luchtkwaliteit",
|
|
77
|
-
"fr": "ajouter une requête enum à la qualité de l'air",
|
|
78
|
-
"it": "aggiungere query enum alla qualità dell'aria",
|
|
79
|
-
"es": "añadir enum query a la calidad del aire",
|
|
80
|
-
"pl": "dodaj enum query do jakości powietrza",
|
|
81
|
-
"uk": "додати конвертер для якості повітря",
|
|
82
|
-
"zh-cn": "在空气质量中添加enum查询"
|
|
83
|
-
},
|
|
84
|
-
"1.21.27": {
|
|
85
|
-
"en": "bugfix airqulity",
|
|
86
|
-
"de": "bugfix luftmenge",
|
|
87
|
-
"ru": "багфикс airlity",
|
|
88
|
-
"pt": "errorfix airqulity",
|
|
89
|
-
"nl": "bugfix airqulity",
|
|
90
|
-
"fr": "bugfix airqulity",
|
|
91
|
-
"it": "bugfix airqulity",
|
|
92
|
-
"es": "bugfix airqulity",
|
|
93
|
-
"pl": "bugfix airquality",
|
|
94
|
-
"uk": "български, english, українська..",
|
|
95
|
-
"zh-cn": "错误修正空格"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
|
@@ -549,7 +549,7 @@ class assignhandlerClass {
|
|
|
549
549
|
},
|
|
550
550
|
},
|
|
551
551
|
},
|
|
552
|
-
TempC_DS: {
|
|
552
|
+
/*TempC_DS: { outcommented 02.04.2026
|
|
553
553
|
approvedFolders: {
|
|
554
554
|
'uplink.decoded': {
|
|
555
555
|
assignfunction: this.commonAssign,
|
|
@@ -559,7 +559,7 @@ class assignhandlerClass {
|
|
|
559
559
|
},
|
|
560
560
|
},
|
|
561
561
|
},
|
|
562
|
-
}
|
|
562
|
+
},*/
|
|
563
563
|
TempC_SHT: {
|
|
564
564
|
approvedFolders: {
|
|
565
565
|
'uplink.decoded': {
|
|
@@ -63,20 +63,478 @@ class bridgeDevicesClass {
|
|
|
63
63
|
items: {},
|
|
64
64
|
},
|
|
65
65
|
};
|
|
66
|
-
|
|
66
|
+
// Special Devices / Entities
|
|
67
|
+
const usedId = {};
|
|
68
|
+
if (deviceValue.entityType.climate) {
|
|
69
|
+
for (const discovery of deviceValue.discovery) {
|
|
70
|
+
if (discovery.topic.startsWith('homeassistant/climate/')) {
|
|
71
|
+
let card = {};
|
|
72
|
+
if (discovery.ids.target) {
|
|
73
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
74
|
+
`Start building Light On for Id: ${discovery.ids.target}`,
|
|
75
|
+
);
|
|
76
|
+
usedId[discovery.ids.target] = true;
|
|
77
|
+
card = { preLabel: '🌡 ', label: 'Solltemperatur' };
|
|
78
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.target].object.native?.card);
|
|
79
|
+
const preLabel = card.preLabel ?? '';
|
|
80
|
+
let label = '';
|
|
81
|
+
if (card.name) {
|
|
82
|
+
label = card.name;
|
|
83
|
+
} else if (card.label) {
|
|
84
|
+
label = card.label;
|
|
85
|
+
} else {
|
|
86
|
+
label = deviceValue.ids[discovery.ids.target].object._id.substring(
|
|
87
|
+
deviceValue.ids[discovery.ids.target].object._id.lastIndexOf('.') + 1,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
res.customInfo.schema.items[`${discovery.ids.target}`] = {
|
|
91
|
+
type: 'state',
|
|
92
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
93
|
+
oid: discovery.ids.target,
|
|
94
|
+
foreign: true,
|
|
95
|
+
// Render as an interactive switch control.
|
|
96
|
+
control: 'slider',
|
|
97
|
+
// Style the text based on the boolean value.
|
|
98
|
+
label: preLabel + label,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
if (discovery.ids.act) {
|
|
102
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
103
|
+
`Start building Light Brightness for Id: ${discovery.ids.act}`,
|
|
104
|
+
);
|
|
105
|
+
usedId[discovery.ids.act] = true;
|
|
106
|
+
card = { preLabel: '🌡 ', label: 'Isttemperatur' };
|
|
107
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.act].object.native?.card);
|
|
108
|
+
const preLabel = card.preLabel ?? '';
|
|
109
|
+
let label = '';
|
|
110
|
+
if (card.name) {
|
|
111
|
+
label = card.name;
|
|
112
|
+
} else if (card.label) {
|
|
113
|
+
label = card.label;
|
|
114
|
+
} else {
|
|
115
|
+
label = deviceValue.ids[discovery.ids.act].object._id.substring(
|
|
116
|
+
deviceValue.ids[discovery.ids.act].object._id.lastIndexOf('.') + 1,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
res.customInfo.schema.items[`${discovery.ids.act}`] = {
|
|
120
|
+
type: 'state',
|
|
121
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
122
|
+
oid: discovery.ids.act,
|
|
123
|
+
foreign: true,
|
|
124
|
+
// Render as an interactive switch control.
|
|
125
|
+
control: 'text',
|
|
126
|
+
// Style the text based on the boolean value.
|
|
127
|
+
label: preLabel + label,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
135
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
136
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
137
|
+
if (deviceValue.entityType.humidifier) {
|
|
138
|
+
for (const discovery of deviceValue.discovery) {
|
|
139
|
+
if (discovery.topic.startsWith('homeassistant/humidifier/')) {
|
|
140
|
+
let card = {};
|
|
141
|
+
if (discovery.ids.onOff) {
|
|
142
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
143
|
+
`Start building Light On for Id: ${discovery.ids.onOff}`,
|
|
144
|
+
);
|
|
145
|
+
usedId[discovery.ids.onOff] = true;
|
|
146
|
+
card = { preLabel: '⏻ ', label: 'Aus / An' };
|
|
147
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.onOff].object.native?.card);
|
|
148
|
+
const preLabel = card.preLabel ?? '';
|
|
149
|
+
let label = '';
|
|
150
|
+
if (card.name) {
|
|
151
|
+
label = card.name;
|
|
152
|
+
} else if (card.label) {
|
|
153
|
+
label = card.label;
|
|
154
|
+
} else {
|
|
155
|
+
label = deviceValue.ids[discovery.ids.onOff].object._id.substring(
|
|
156
|
+
deviceValue.ids[discovery.ids.onOff].object._id.lastIndexOf('.') + 1,
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
res.customInfo.schema.items[`${discovery.ids.onOff}`] = {
|
|
160
|
+
type: 'state',
|
|
161
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
162
|
+
oid: discovery.ids.onOff,
|
|
163
|
+
foreign: true,
|
|
164
|
+
// Render as an interactive switch control.
|
|
165
|
+
control: 'switch',
|
|
166
|
+
// Style the text based on the boolean value.
|
|
167
|
+
trueTextStyle: { color: 'green' },
|
|
168
|
+
falseTextStyle: { color: 'red' },
|
|
169
|
+
label: preLabel + label,
|
|
170
|
+
trueText: 'ON',
|
|
171
|
+
falseText: 'OFF',
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (discovery.ids.target) {
|
|
175
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
176
|
+
`Start building Light Brightness for Id: ${discovery.ids.target}`,
|
|
177
|
+
);
|
|
178
|
+
usedId[discovery.ids.target] = true;
|
|
179
|
+
card = { preLabel: '💧 ', label: 'Sollfeuchtigkeit' };
|
|
180
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.target].object.native?.card);
|
|
181
|
+
const preLabel = card.preLabel ?? '';
|
|
182
|
+
let label = '';
|
|
183
|
+
if (card.name) {
|
|
184
|
+
label = card.name;
|
|
185
|
+
} else if (card.label) {
|
|
186
|
+
label = card.label;
|
|
187
|
+
} else {
|
|
188
|
+
label = deviceValue.ids[discovery.ids.target].object._id.substring(
|
|
189
|
+
deviceValue.ids[discovery.ids.target].object._id.lastIndexOf('.') + 1,
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
res.customInfo.schema.items[`${discovery.ids.target}`] = {
|
|
193
|
+
type: 'state',
|
|
194
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
195
|
+
oid: discovery.ids.target,
|
|
196
|
+
foreign: true,
|
|
197
|
+
// Render as an interactive switch control.
|
|
198
|
+
control: 'slider',
|
|
199
|
+
// Style the text based on the boolean value.
|
|
200
|
+
label: preLabel + label,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
if (discovery.ids.act) {
|
|
204
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
205
|
+
`Start building Light Brightness for Id: ${discovery.ids.act}`,
|
|
206
|
+
);
|
|
207
|
+
usedId[discovery.ids.act] = true;
|
|
208
|
+
card = { preLabel: '💧 ', label: 'Istfeuchtigkeit' };
|
|
209
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.act].object.native?.card);
|
|
210
|
+
const preLabel = card.preLabel ?? '';
|
|
211
|
+
let label = '';
|
|
212
|
+
if (card.name) {
|
|
213
|
+
label = card.name;
|
|
214
|
+
} else if (card.label) {
|
|
215
|
+
label = card.label;
|
|
216
|
+
} else {
|
|
217
|
+
label = deviceValue.ids[discovery.ids.act].object._id.substring(
|
|
218
|
+
deviceValue.ids[discovery.ids.act].object._id.lastIndexOf('.') + 1,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
res.customInfo.schema.items[`${discovery.ids.act}`] = {
|
|
222
|
+
type: 'state',
|
|
223
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
224
|
+
oid: discovery.ids.act,
|
|
225
|
+
foreign: true,
|
|
226
|
+
// Render as an interactive switch control.
|
|
227
|
+
control: 'text',
|
|
228
|
+
// Style the text based on the boolean value.
|
|
229
|
+
label: preLabel + label,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
237
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
238
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
239
|
+
if (deviceValue.entityType.cover) {
|
|
240
|
+
for (const discovery of deviceValue.discovery) {
|
|
241
|
+
if (discovery.topic.startsWith('homeassistant/cover/')) {
|
|
242
|
+
this.adapter.log.warn(3);
|
|
243
|
+
let card = {};
|
|
244
|
+
if (discovery.ids.open) {
|
|
245
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
246
|
+
`Start building Light On for Id: ${discovery.ids.open}`,
|
|
247
|
+
);
|
|
248
|
+
usedId[discovery.ids.open] = true;
|
|
249
|
+
card = { preLabel: '⏻ ', label: 'Aus / An' };
|
|
250
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.open].object.native?.card);
|
|
251
|
+
const preLabel = card.preLabel ?? '';
|
|
252
|
+
let label = '';
|
|
253
|
+
if (card.name) {
|
|
254
|
+
label = card.name;
|
|
255
|
+
} else if (card.label) {
|
|
256
|
+
label = card.label;
|
|
257
|
+
} else {
|
|
258
|
+
label = deviceValue.ids[discovery.ids.open].object._id.substring(
|
|
259
|
+
deviceValue.ids[discovery.ids.open].object._id.lastIndexOf('.') + 1,
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
res.customInfo.schema.items[`${discovery.ids.open}`] = {
|
|
263
|
+
type: 'state',
|
|
264
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
265
|
+
oid: discovery.ids.open,
|
|
266
|
+
foreign: true,
|
|
267
|
+
// Render as an interactive switch control.
|
|
268
|
+
control: 'button',
|
|
269
|
+
// Style the text based on the boolean value.
|
|
270
|
+
label: preLabel + label,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
if (discovery.ids.close) {
|
|
274
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
275
|
+
`Start building Light On for Id: ${discovery.ids.close}`,
|
|
276
|
+
);
|
|
277
|
+
usedId[discovery.ids.close] = true;
|
|
278
|
+
card = { preLabel: '⏻ ', label: 'Aus / An' };
|
|
279
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.close].object.native?.card);
|
|
280
|
+
const preLabel = card.preLabel ?? '';
|
|
281
|
+
let label = '';
|
|
282
|
+
if (card.name) {
|
|
283
|
+
label = card.name;
|
|
284
|
+
} else if (card.label) {
|
|
285
|
+
label = card.label;
|
|
286
|
+
} else {
|
|
287
|
+
label = deviceValue.ids[discovery.ids.close].object._id.substring(
|
|
288
|
+
deviceValue.ids[discovery.ids.close].object._id.lastIndexOf('.') + 1,
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
res.customInfo.schema.items[`${discovery.ids.close}`] = {
|
|
292
|
+
type: 'state',
|
|
293
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
294
|
+
oid: discovery.ids.close,
|
|
295
|
+
foreign: true,
|
|
296
|
+
// Render as an interactive switch control.
|
|
297
|
+
control: 'button',
|
|
298
|
+
// Style the text based on the boolean value.
|
|
299
|
+
label: preLabel + label,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
if (discovery.ids.stop) {
|
|
303
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
304
|
+
`Start building Light On for Id: ${discovery.ids.stop}`,
|
|
305
|
+
);
|
|
306
|
+
usedId[discovery.ids.stop] = true;
|
|
307
|
+
card = { preLabel: '⏻ ', label: 'Aus / An' };
|
|
308
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.stop].object.native?.card);
|
|
309
|
+
const preLabel = card.preLabel ?? '';
|
|
310
|
+
let label = '';
|
|
311
|
+
if (card.name) {
|
|
312
|
+
label = card.name;
|
|
313
|
+
} else if (card.label) {
|
|
314
|
+
label = card.label;
|
|
315
|
+
} else {
|
|
316
|
+
label = deviceValue.ids[discovery.ids.stop].object._id.substring(
|
|
317
|
+
deviceValue.ids[discovery.ids.stop].object._id.lastIndexOf('.') + 1,
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
res.customInfo.schema.items[`${discovery.ids.stop}`] = {
|
|
321
|
+
type: 'state',
|
|
322
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
323
|
+
oid: discovery.ids.stop,
|
|
324
|
+
foreign: true,
|
|
325
|
+
// Render as an interactive switch control.
|
|
326
|
+
control: 'button',
|
|
327
|
+
// Style the text based on the boolean value.
|
|
328
|
+
label: preLabel + label,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
if (discovery.ids.openSignal) {
|
|
332
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
333
|
+
`Start building Light On for Id: ${discovery.ids.openSignal}`,
|
|
334
|
+
);
|
|
335
|
+
usedId[discovery.ids.openSignal] = true;
|
|
336
|
+
card = { preLabel: '', label: 'Oben (offen)' };
|
|
337
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.openSignal].object.native?.card);
|
|
338
|
+
const preLabel = card.preLabel ?? '';
|
|
339
|
+
let label = '';
|
|
340
|
+
if (card.name) {
|
|
341
|
+
label = card.name;
|
|
342
|
+
} else if (card.label) {
|
|
343
|
+
label = card.label;
|
|
344
|
+
} else {
|
|
345
|
+
label = deviceValue.ids[discovery.ids.openSignal].object._id.substring(
|
|
346
|
+
deviceValue.ids[discovery.ids.openSignal].object._id.lastIndexOf('.') + 1,
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
res.customInfo.schema.items[`${discovery.ids.openSignal}`] = {
|
|
350
|
+
type: 'state',
|
|
351
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
352
|
+
oid: discovery.ids.openSignal,
|
|
353
|
+
foreign: true,
|
|
354
|
+
// Render as an interactive switch control.
|
|
355
|
+
control: 'text',
|
|
356
|
+
// Style the text based on the boolean value.
|
|
357
|
+
label: preLabel + label,
|
|
358
|
+
trueText: 'nicht Offen',
|
|
359
|
+
falseText: 'Aufgefahren',
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
if (discovery.ids.closedSignal) {
|
|
363
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
364
|
+
`Start building Light On for Id: ${discovery.ids.closedSignal}`,
|
|
365
|
+
);
|
|
366
|
+
usedId[discovery.ids.closedSignal] = true;
|
|
367
|
+
card = { preLabel: '', label: 'Unten (geschlossen)' };
|
|
368
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.closedSignal].object.native?.card);
|
|
369
|
+
const preLabel = card.preLabel ?? '';
|
|
370
|
+
let label = '';
|
|
371
|
+
if (card.name) {
|
|
372
|
+
label = card.name;
|
|
373
|
+
} else if (card.label) {
|
|
374
|
+
label = card.label;
|
|
375
|
+
} else {
|
|
376
|
+
label = deviceValue.ids[discovery.ids.closedSignal].object._id.substring(
|
|
377
|
+
deviceValue.ids[discovery.ids.closedSignal].object._id.lastIndexOf('.') + 1,
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
res.customInfo.schema.items[`${discovery.ids.closedSignal}`] = {
|
|
381
|
+
type: 'state',
|
|
382
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
383
|
+
oid: discovery.ids.closedSignal,
|
|
384
|
+
foreign: true,
|
|
385
|
+
// Render as an interactive switch control.
|
|
386
|
+
control: 'text',
|
|
387
|
+
// Style the text based on the boolean value.
|
|
388
|
+
label: preLabel + label,
|
|
389
|
+
trueText: 'nicht geschlossen',
|
|
390
|
+
falseText: 'Zugefahren',
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
398
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
399
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
400
|
+
if (deviceValue.entityType.lock) {
|
|
401
|
+
for (const discovery of deviceValue.discovery) {
|
|
402
|
+
if (discovery.topic.startsWith('homeassistant/lock/')) {
|
|
403
|
+
let card = {};
|
|
404
|
+
if (discovery.ids.lock) {
|
|
405
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
406
|
+
`Start building Light On for Id: ${discovery.ids.open}`,
|
|
407
|
+
);
|
|
408
|
+
usedId[discovery.ids.open] = true;
|
|
409
|
+
card = { preLabel: '🔒 ', label: 'Abschließen' };
|
|
410
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.open].object.native?.card);
|
|
411
|
+
const preLabel = card.preLabel ?? '';
|
|
412
|
+
let label = '';
|
|
413
|
+
if (card.name) {
|
|
414
|
+
label = card.name;
|
|
415
|
+
} else if (card.label) {
|
|
416
|
+
label = card.label;
|
|
417
|
+
} else {
|
|
418
|
+
label = deviceValue.ids[discovery.ids.open].object._id.substring(
|
|
419
|
+
deviceValue.ids[discovery.ids.open].object._id.lastIndexOf('.') + 1,
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
res.customInfo.schema.items[`${discovery.ids.open}`] = {
|
|
423
|
+
type: 'state',
|
|
424
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
425
|
+
oid: discovery.ids.open,
|
|
426
|
+
foreign: true,
|
|
427
|
+
// Render as an interactive switch control.
|
|
428
|
+
control: 'button',
|
|
429
|
+
// Style the text based on the boolean value.
|
|
430
|
+
label: preLabel + label,
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
if (discovery.ids.unlock) {
|
|
434
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
435
|
+
`Start building Light On for Id: ${discovery.ids.close}`,
|
|
436
|
+
);
|
|
437
|
+
usedId[discovery.ids.close] = true;
|
|
438
|
+
card = { preLabel: '🔓 ', label: 'Aufschließen' };
|
|
439
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.close].object.native?.card);
|
|
440
|
+
const preLabel = card.preLabel ?? '';
|
|
441
|
+
let label = '';
|
|
442
|
+
if (card.name) {
|
|
443
|
+
label = card.name;
|
|
444
|
+
} else if (card.label) {
|
|
445
|
+
label = card.label;
|
|
446
|
+
} else {
|
|
447
|
+
label = deviceValue.ids[discovery.ids.close].object._id.substring(
|
|
448
|
+
deviceValue.ids[discovery.ids.close].object._id.lastIndexOf('.') + 1,
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
res.customInfo.schema.items[`${discovery.ids.close}`] = {
|
|
452
|
+
type: 'state',
|
|
453
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
454
|
+
oid: discovery.ids.close,
|
|
455
|
+
foreign: true,
|
|
456
|
+
// Render as an interactive switch control.
|
|
457
|
+
control: 'button',
|
|
458
|
+
// Style the text based on the boolean value.
|
|
459
|
+
label: preLabel + label,
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
if (discovery.ids.open) {
|
|
463
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
464
|
+
`Start building Light On for Id: ${discovery.ids.open}`,
|
|
465
|
+
);
|
|
466
|
+
usedId[discovery.ids.open] = true;
|
|
467
|
+
card = { preLabel: '', label: 'Öffnen' };
|
|
468
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.open].object.native?.card);
|
|
469
|
+
const preLabel = card.preLabel ?? '';
|
|
470
|
+
let label = '';
|
|
471
|
+
if (card.name) {
|
|
472
|
+
label = card.name;
|
|
473
|
+
} else if (card.label) {
|
|
474
|
+
label = card.label;
|
|
475
|
+
} else {
|
|
476
|
+
label = deviceValue.ids[discovery.ids.open].object._id.substring(
|
|
477
|
+
deviceValue.ids[discovery.ids.open].object._id.lastIndexOf('.') + 1,
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
res.customInfo.schema.items[`${discovery.ids.open}`] = {
|
|
481
|
+
type: 'state',
|
|
482
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
483
|
+
oid: discovery.ids.open,
|
|
484
|
+
foreign: true,
|
|
485
|
+
// Render as an interactive switch control.
|
|
486
|
+
control: 'button',
|
|
487
|
+
// Style the text based on the boolean value.
|
|
488
|
+
label: preLabel + label,
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
if (discovery.ids.state) {
|
|
492
|
+
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
493
|
+
`Start building Light On for Id: ${discovery.ids.state}`,
|
|
494
|
+
);
|
|
495
|
+
usedId[discovery.ids.state] = true;
|
|
496
|
+
card = { preLabel: '', label: 'Status' };
|
|
497
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.state].object.native?.card);
|
|
498
|
+
const preLabel = card.preLabel ?? '';
|
|
499
|
+
let label = '';
|
|
500
|
+
if (card.name) {
|
|
501
|
+
label = card.name;
|
|
502
|
+
} else if (card.label) {
|
|
503
|
+
label = card.label;
|
|
504
|
+
} else {
|
|
505
|
+
label = deviceValue.ids[discovery.ids.state].object._id.substring(
|
|
506
|
+
deviceValue.ids[discovery.ids.state].object._id.lastIndexOf('.') + 1,
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
res.customInfo.schema.items[`${discovery.ids.state}`] = {
|
|
510
|
+
type: 'state',
|
|
511
|
+
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
512
|
+
oid: discovery.ids.state,
|
|
513
|
+
foreign: true,
|
|
514
|
+
// Render as an interactive switch control.
|
|
515
|
+
control: 'text',
|
|
516
|
+
// Style the text based on the boolean value.
|
|
517
|
+
label: preLabel + label,
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
525
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
526
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
67
527
|
if (deviceValue.entityType.light) {
|
|
68
|
-
const ids = {};
|
|
69
528
|
for (const discovery of deviceValue.discovery) {
|
|
70
529
|
if (discovery.topic.startsWith('homeassistant/light/')) {
|
|
71
530
|
let card = {};
|
|
72
531
|
if (discovery.ids.onOff) {
|
|
73
|
-
ids.onOff = discovery.ids.onOff;
|
|
74
532
|
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
75
|
-
`Start building Light On for Id: ${ids.onOff}`,
|
|
533
|
+
`Start building Light On for Id: ${discovery.ids.onOff}`,
|
|
76
534
|
);
|
|
77
|
-
|
|
78
|
-
card = { preLabel: '⏻ ', label: '
|
|
79
|
-
card = lodash.merge(card, deviceValue.ids[ids.onOff].object.native?.card);
|
|
535
|
+
usedId[discovery.ids.onOff] = true;
|
|
536
|
+
card = { preLabel: '⏻ ', label: 'Aus / An' };
|
|
537
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.onOff].object.native?.card);
|
|
80
538
|
const preLabel = card.preLabel ?? '';
|
|
81
539
|
let label = '';
|
|
82
540
|
if (card.name) {
|
|
@@ -84,14 +542,14 @@ class bridgeDevicesClass {
|
|
|
84
542
|
} else if (card.label) {
|
|
85
543
|
label = card.label;
|
|
86
544
|
} else {
|
|
87
|
-
label = deviceValue.ids[ids.onOff].object._id.substring(
|
|
88
|
-
deviceValue.ids[ids.onOff].object._id.lastIndexOf('.') + 1,
|
|
545
|
+
label = deviceValue.ids[discovery.ids.onOff].object._id.substring(
|
|
546
|
+
deviceValue.ids[discovery.ids.onOff].object._id.lastIndexOf('.') + 1,
|
|
89
547
|
);
|
|
90
548
|
}
|
|
91
|
-
res.customInfo.schema.items.
|
|
549
|
+
res.customInfo.schema.items[`${discovery.ids.onOff}`] = {
|
|
92
550
|
type: 'state',
|
|
93
551
|
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
94
|
-
oid: ids.onOff,
|
|
552
|
+
oid: discovery.ids.onOff,
|
|
95
553
|
foreign: true,
|
|
96
554
|
// Render as an interactive switch control.
|
|
97
555
|
control: 'switch',
|
|
@@ -104,13 +562,12 @@ class bridgeDevicesClass {
|
|
|
104
562
|
};
|
|
105
563
|
}
|
|
106
564
|
if (discovery.ids.brightness) {
|
|
107
|
-
ids.brightness = discovery.ids.brightness;
|
|
108
565
|
this.adapter.log[this.adapter.logtypes.listDevices]?.(
|
|
109
|
-
`Start building Light Brightness for Id: ${ids.brightness}`,
|
|
566
|
+
`Start building Light Brightness for Id: ${discovery.ids.brightness}`,
|
|
110
567
|
);
|
|
111
|
-
|
|
568
|
+
usedId[discovery.ids.brightness] = true;
|
|
112
569
|
card = { preLabel: '🔆 ', label: 'Helligkeit' };
|
|
113
|
-
card = lodash.merge(card, deviceValue.ids[ids.brightness].object.native?.card);
|
|
570
|
+
card = lodash.merge(card, deviceValue.ids[discovery.ids.brightness].object.native?.card);
|
|
114
571
|
const preLabel = card.preLabel ?? '';
|
|
115
572
|
let label = '';
|
|
116
573
|
if (card.name) {
|
|
@@ -118,14 +575,14 @@ class bridgeDevicesClass {
|
|
|
118
575
|
} else if (card.label) {
|
|
119
576
|
label = card.label;
|
|
120
577
|
} else {
|
|
121
|
-
label = deviceValue.ids[ids.
|
|
122
|
-
deviceValue.ids[ids.
|
|
578
|
+
label = deviceValue.ids[discovery.ids.brightness].object._id.substring(
|
|
579
|
+
deviceValue.ids[discovery.ids.brightness].object._id.lastIndexOf('.') + 1,
|
|
123
580
|
);
|
|
124
581
|
}
|
|
125
|
-
res.customInfo.schema.items.
|
|
582
|
+
res.customInfo.schema.items[`${discovery.ids.brighness}`] = {
|
|
126
583
|
type: 'state',
|
|
127
584
|
// The full state ID including namespace (foreign = true means it's an absolute ID).
|
|
128
|
-
oid: ids.brightness,
|
|
585
|
+
oid: discovery.ids.brightness,
|
|
129
586
|
foreign: true,
|
|
130
587
|
// Render as an interactive switch control.
|
|
131
588
|
control: 'slider',
|
|
@@ -135,17 +592,14 @@ class bridgeDevicesClass {
|
|
|
135
592
|
label: preLabel + label,
|
|
136
593
|
};
|
|
137
594
|
}
|
|
138
|
-
|
|
139
|
-
ids.color = discovery.ids.color;
|
|
140
|
-
}
|
|
141
|
-
break;
|
|
595
|
+
continue;
|
|
142
596
|
}
|
|
143
597
|
}
|
|
144
598
|
}
|
|
145
599
|
// Check all entries in Informations.card
|
|
146
600
|
if (deviceValue.informations?.card) {
|
|
147
601
|
for (const [key, value] of Object.entries(deviceValue.informations?.card)) {
|
|
148
|
-
if (
|
|
602
|
+
if (usedId[value.object._id]) {
|
|
149
603
|
continue;
|
|
150
604
|
}
|
|
151
605
|
this.adapter.log[this.adapter.logtypes.listDevices]?.(`Start building for Id: ${value.object._id}`);
|
|
@@ -184,12 +638,18 @@ class bridgeDevicesClass {
|
|
|
184
638
|
delete res.customInfo;
|
|
185
639
|
} else {
|
|
186
640
|
const items = res.customInfo.schema.items;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
641
|
+
|
|
642
|
+
// 1. Keys trennen
|
|
643
|
+
const normalKeys = Object.keys(items).filter(key => !key.startsWith('_'));
|
|
644
|
+
const underscoreKeys = Object.keys(items)
|
|
645
|
+
.filter(key => key.startsWith('_'))
|
|
646
|
+
.sort((a, b) => a.localeCompare(b));
|
|
647
|
+
|
|
648
|
+
// 2. Zusammenführen (normale zuerst, dann sortierte "_"-Keys)
|
|
649
|
+
const sortedItems = [...normalKeys, ...underscoreKeys].reduce((acc, key) => {
|
|
650
|
+
acc[key] = items[key];
|
|
651
|
+
return acc;
|
|
652
|
+
}, {});
|
|
193
653
|
|
|
194
654
|
res.customInfo.schema.items = sortedItems;
|
|
195
655
|
}
|
|
@@ -388,7 +848,7 @@ class bridgeDevicesClass {
|
|
|
388
848
|
type: 'text',
|
|
389
849
|
readOnly: true,
|
|
390
850
|
minRows: 10,
|
|
391
|
-
maxRows:
|
|
851
|
+
maxRows: 30,
|
|
392
852
|
};
|
|
393
853
|
const sortedDiscovery = [...this.adapter.objectStore.bridge.devices[id].discovery].sort(
|
|
394
854
|
(a, b) => b.lastDiscover.ts - a.lastDiscover.ts,
|
|
@@ -418,7 +418,7 @@ class lorawanDevicesClass {
|
|
|
418
418
|
type: 'text',
|
|
419
419
|
readOnly: true,
|
|
420
420
|
minRows: 10,
|
|
421
|
-
maxRows:
|
|
421
|
+
maxRows: 30,
|
|
422
422
|
};
|
|
423
423
|
const sortedUplinkDecoded = this.sortObjectDeep(this.adapter.objectStore.lorawan.devices[id].uplink.decoded);
|
|
424
424
|
data.uplinkDecoded = JSON.stringify(this.extractStateValues(sortedUplinkDecoded), null, 2);
|