iobroker.lorawan 1.22.2 → 1.22.4

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 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.4 (2026-04-10)
28
+ * (BenAhrdt) bugfix lock entity in dM card
29
+
30
+ ### 1.22.3 (2026-04-10)
31
+ * (BenAhrdt) add first Test for states of configed devices shown in device Manager cards
32
+
27
33
  ### 1.22.2 (2026-04-07)
28
34
  * (BenAhrdt) remove readOnly flag from jsonEditor
29
35
 
@@ -33,112 +39,6 @@ For now there is documentation in English here: https://wiki.hafenmeister.de
33
39
  ### 1.22.0 (2026-04-01)
34
40
  * (BenAhrdt) new Design in device Manager Cards
35
41
 
36
- ### 1.21.31 (2026-04-01)
37
- * (BenAhrdt) Display more Infos and colors in Cards
38
-
39
- ### 1.21.30 (2026-04-01)
40
- * (BenAhrdt) bugfix warn logging
41
-
42
- ### 1.21.29 (2026-04-01)
43
- * (BenAhrdt) check native
44
-
45
- ### 1.21.28 (2026-04-01)
46
- * (BenAhrdt) add enum query to air quality
47
-
48
- ### 1.21.27 (2026-04-01)
49
- * (BenAhrdt) bugfix airqulity
50
-
51
- ### 1.21.26 (2026-04-01)
52
- * (BenAhrdt) add airquilty for toIob devices
53
- * (BenAhrdt) add functionality off native card
54
-
55
- ### 1.21.25 (2026-04-01)
56
- * (BenAhrdt) add prelabel to some roles for card
57
-
58
- ### 1.21.24 (2026-04-01)
59
- * (BenAhrdt) Merge cardRoles at startup in default
60
- * (BenAhrdt) add some roles to cardRoles
61
- * (BenAhrdt) add some roles to toIob generation
62
-
63
- ### 1.21.23 (2026-03-31)
64
- * (BenAhrdt) add DeviceObject to every device in dM
65
- * (BenAhrdt) remove moin / max because used in default
66
-
67
- ### 1.21.22 (2026-03-31)
68
- * (BenAhrdt) bugfix in bridge objectStore
69
- * (BenAhrdt) add sensor.motion to cardRoles
70
-
71
- ### 1.21.21 (2026-03-30)
72
- * (BenAhrdt) change priority to name => lable => id (in card)
73
-
74
- ### 1.21.20 (2026-03-30)
75
- * (BenAhrdt) add more role definitions and logic to card roles
76
-
77
- ### 1.21.19 (2026-03-30)
78
- * (BenAhrdt) add value.power.active to cardRoles and possibility for Name (label? Name? ID)
79
-
80
- ### 1.21.18 (2026-03-30)
81
- * (BenAhrdt) bugfix display states for bridged devices in dM
82
-
83
- ### 1.21.17 (2026-03-30)
84
- * (BenAhrdt) change display of sensor.contact in dM card
85
-
86
- ### 1.21.16 (2026-03-30)
87
- * (BenAhrdt) implements cardRoles state to define displayed Roles in card
88
- * (BenAhrdt) First try of custom Info at dM
89
-
90
- ### 1.21.15 (2026-03-28)
91
- * (BenAhrdt) implement TTI tenant to download to TTI
92
-
93
- ### 1.21.14 (2026-03-27)
94
- * (BenAhrdt) change userdata and alias query for bridge
95
-
96
- ### 1.21.13 (2026-03-23)
97
- * (BenAhrdt) improve displaying devEUI in actual Values
98
-
99
- ### 1.21.12 (2026-03-19)
100
- * (BenAhrdt) bugfix display devices in case of bridge is not selected
101
-
102
- ### 1.21.11 (2026-03-15)
103
- * (BenAhrdt) improve nameing of actual values
104
- * (BenAhrdt) imlpement digits to actual values
105
-
106
- ### 1.21.10 (2026-03-12)
107
- * (BenAhrdt) change Testing and change standard value of lorawan origin to off
108
-
109
- ### 1.21.9 (2026-03-06)
110
- * (BenAhrdt) persistant Bride DeviceIds
111
-
112
- ### 1.21.8 (2026-03-04)
113
- * (BenAhrdt) update icons
114
-
115
- ### 1.21.7 (2026-03-04)
116
- * (BenAhrdt) update logic for icons and link building
117
-
118
- ### 1.21.6 (2026-03-04)
119
- * (BenAhrdt) change logic for TTN link and change base ip handling
120
- * (BenAhrdt) set more devices at default
121
-
122
- ### 1.21.5 (2026-03-04)
123
- * (BenAhrdt) implements link to Chirpstack / TTN
124
-
125
- ### 1.21.4 (2026-03-03)
126
- * (BenAhrdt) update the updateBridge function in objectStore
127
- * (BenAhrdt) improve LoraWAN and ToIob funkction (init / update)
128
-
129
- ### 1.21.3 (2026-03-02)
130
- * (BenAhrdt) add Link to ToIoB Devices
131
-
132
- ### 1.21.2 (2026-03-02)
133
- * (BenAhrdt) update icon for device link
134
-
135
- ### 1.21.1 (2026-03-02)
136
- * (BenAhrdt) bring possibility for editing base ip in devce Manager
137
-
138
- ### 1.21.0 (2026-03-02)
139
- * (BenAhrdt) update deviceManager (dm-utils) to 3.0.0
140
- * (BenAhrdt) add Links for Bridge devices
141
-
142
42
  ### Older entries
143
43
  [here](OLD_CHANGELOG.md)
144
44
 
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "lorawan",
4
- "version": "1.22.2",
4
+ "version": "1.22.4",
5
5
  "news": {
6
+ "1.22.4": {
7
+ "en": "bugfix lock entity in dM card",
8
+ "de": "bugfix Schloss Entität in dM Karte",
9
+ "ru": "bugfix lock entity в карте dM",
10
+ "pt": "entidade de bloqueio de bugfix no cartão dM",
11
+ "nl": "bugfix slot entiteit in dM-kaart",
12
+ "fr": "bugfix lock entity dans la carte dM",
13
+ "it": "entità di blocco bugfix nella scheda dM",
14
+ "es": "bugfix entidad de bloqueo en tarjeta dM",
15
+ "pl": "element blokujący bugfix w karcie dM",
16
+ "uk": "суб'єкт блокування помилок в картці dM",
17
+ "zh-cn": "dM 卡中的bugfix锁实体"
18
+ },
19
+ "1.22.3": {
20
+ "en": "add first Test for states of configed devices shown in device Manager cards",
21
+ "de": "fügen Sie ersten Test für Zustände von konfiktiven Geräten in Device Manager-Karten",
22
+ "ru": "добавить первый Тест для состояний конфигурированных устройств, показанных в картах диспетчера устройств",
23
+ "pt": "adicionar primeiro Teste para estados de dispositivos configurados mostrados nas placas do Gerenciador de dispositivos",
24
+ "nl": "toe te voegen eerste Test voor toestanden van geconfigureerde apparaten weergegeven in apparaat Manager kaarten",
25
+ "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",
26
+ "it": "aggiungere il primo test per gli stati di dispositivi confidificati mostrati nelle schede Gestione dispositivi",
27
+ "es": "añadir el primer Test para estados de dispositivos conectados mostrados en tarjetas de administrador de dispositivos",
28
+ "pl": "dodaj pierwszy test dla stanu podłączonych urządzeń pokazany w kartach menedżera urządzeń",
29
+ "uk": "додати перший тест для станів настрочених пристроїв, відображених в картах диспетчера пристроїв",
30
+ "zh-cn": "添加第一个设备管理卡中显示的配置设备状态测试"
31
+ },
6
32
  "1.22.2": {
7
33
  "en": "remove readOnly flag from jsonEditor",
8
34
  "de": "readOnly flag von jsonEditor entfernen",
@@ -67,32 +93,6 @@
67
93
  "pl": "bugfix ostrzega logowanie",
68
94
  "uk": "виправлення помилок",
69
95
  "zh-cn": "错误修正警告日志"
70
- },
71
- "1.21.29": {
72
- "en": "check native",
73
- "de": "check native",
74
- "ru": "проверить родной",
75
- "pt": "verificar nativo",
76
- "nl": "native controleren",
77
- "fr": "vérifier native",
78
- "it": "controllare nativo",
79
- "es": "cheque nativo",
80
- "pl": "sprawdź rodzime",
81
- "uk": "перевірити рідний",
82
- "zh-cn": "检查本地"
83
- },
84
- "1.21.28": {
85
- "en": "add enum query to air quality",
86
- "de": "enum quer zur luftqualität hinzufügen",
87
- "ru": "добавить вопрос к качеству воздуха",
88
- "pt": "adicionar consulta enum à qualidade do ar",
89
- "nl": "enum query toevoegen aan luchtkwaliteit",
90
- "fr": "ajouter une requête enum à la qualité de l'air",
91
- "it": "aggiungere query enum alla qualità dell'aria",
92
- "es": "añadir enum query a la calidad del aire",
93
- "pl": "dodaj enum query do jakości powietrza",
94
- "uk": "додати конвертер для якості повітря",
95
- "zh-cn": "在空气质量中添加enum查询"
96
96
  }
97
97
  },
98
98
  "titleLang": {
@@ -63,20 +63,477 @@ class bridgeDevicesClass {
63
63
  items: {},
64
64
  },
65
65
  };
66
- const usedLightId = {};
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
+ let card = {};
243
+ if (discovery.ids.open) {
244
+ this.adapter.log[this.adapter.logtypes.listDevices]?.(
245
+ `Start building Light On for Id: ${discovery.ids.open}`,
246
+ );
247
+ usedId[discovery.ids.open] = true;
248
+ card = { preLabel: '⏻ ', label: 'Aus / An' };
249
+ card = lodash.merge(card, deviceValue.ids[discovery.ids.open].object.native?.card);
250
+ const preLabel = card.preLabel ?? '';
251
+ let label = '';
252
+ if (card.name) {
253
+ label = card.name;
254
+ } else if (card.label) {
255
+ label = card.label;
256
+ } else {
257
+ label = deviceValue.ids[discovery.ids.open].object._id.substring(
258
+ deviceValue.ids[discovery.ids.open].object._id.lastIndexOf('.') + 1,
259
+ );
260
+ }
261
+ res.customInfo.schema.items[`${discovery.ids.open}`] = {
262
+ type: 'state',
263
+ // The full state ID including namespace (foreign = true means it's an absolute ID).
264
+ oid: discovery.ids.open,
265
+ foreign: true,
266
+ // Render as an interactive switch control.
267
+ control: 'button',
268
+ // Style the text based on the boolean value.
269
+ label: preLabel + label,
270
+ };
271
+ }
272
+ if (discovery.ids.close) {
273
+ this.adapter.log[this.adapter.logtypes.listDevices]?.(
274
+ `Start building Light On for Id: ${discovery.ids.close}`,
275
+ );
276
+ usedId[discovery.ids.close] = true;
277
+ card = { preLabel: '⏻ ', label: 'Aus / An' };
278
+ card = lodash.merge(card, deviceValue.ids[discovery.ids.close].object.native?.card);
279
+ const preLabel = card.preLabel ?? '';
280
+ let label = '';
281
+ if (card.name) {
282
+ label = card.name;
283
+ } else if (card.label) {
284
+ label = card.label;
285
+ } else {
286
+ label = deviceValue.ids[discovery.ids.close].object._id.substring(
287
+ deviceValue.ids[discovery.ids.close].object._id.lastIndexOf('.') + 1,
288
+ );
289
+ }
290
+ res.customInfo.schema.items[`${discovery.ids.close}`] = {
291
+ type: 'state',
292
+ // The full state ID including namespace (foreign = true means it's an absolute ID).
293
+ oid: discovery.ids.close,
294
+ foreign: true,
295
+ // Render as an interactive switch control.
296
+ control: 'button',
297
+ // Style the text based on the boolean value.
298
+ label: preLabel + label,
299
+ };
300
+ }
301
+ if (discovery.ids.stop) {
302
+ this.adapter.log[this.adapter.logtypes.listDevices]?.(
303
+ `Start building Light On for Id: ${discovery.ids.stop}`,
304
+ );
305
+ usedId[discovery.ids.stop] = true;
306
+ card = { preLabel: '⏻ ', label: 'Aus / An' };
307
+ card = lodash.merge(card, deviceValue.ids[discovery.ids.stop].object.native?.card);
308
+ const preLabel = card.preLabel ?? '';
309
+ let label = '';
310
+ if (card.name) {
311
+ label = card.name;
312
+ } else if (card.label) {
313
+ label = card.label;
314
+ } else {
315
+ label = deviceValue.ids[discovery.ids.stop].object._id.substring(
316
+ deviceValue.ids[discovery.ids.stop].object._id.lastIndexOf('.') + 1,
317
+ );
318
+ }
319
+ res.customInfo.schema.items[`${discovery.ids.stop}`] = {
320
+ type: 'state',
321
+ // The full state ID including namespace (foreign = true means it's an absolute ID).
322
+ oid: discovery.ids.stop,
323
+ foreign: true,
324
+ // Render as an interactive switch control.
325
+ control: 'button',
326
+ // Style the text based on the boolean value.
327
+ label: preLabel + label,
328
+ };
329
+ }
330
+ if (discovery.ids.openSignal) {
331
+ this.adapter.log[this.adapter.logtypes.listDevices]?.(
332
+ `Start building Light On for Id: ${discovery.ids.openSignal}`,
333
+ );
334
+ usedId[discovery.ids.openSignal] = true;
335
+ card = { preLabel: '', label: 'Oben (offen)' };
336
+ card = lodash.merge(card, deviceValue.ids[discovery.ids.openSignal].object.native?.card);
337
+ const preLabel = card.preLabel ?? '';
338
+ let label = '';
339
+ if (card.name) {
340
+ label = card.name;
341
+ } else if (card.label) {
342
+ label = card.label;
343
+ } else {
344
+ label = deviceValue.ids[discovery.ids.openSignal].object._id.substring(
345
+ deviceValue.ids[discovery.ids.openSignal].object._id.lastIndexOf('.') + 1,
346
+ );
347
+ }
348
+ res.customInfo.schema.items[`${discovery.ids.openSignal}`] = {
349
+ type: 'state',
350
+ // The full state ID including namespace (foreign = true means it's an absolute ID).
351
+ oid: discovery.ids.openSignal,
352
+ foreign: true,
353
+ // Render as an interactive switch control.
354
+ control: 'text',
355
+ // Style the text based on the boolean value.
356
+ label: preLabel + label,
357
+ trueText: 'nicht Offen',
358
+ falseText: 'Aufgefahren',
359
+ };
360
+ }
361
+ if (discovery.ids.closedSignal) {
362
+ this.adapter.log[this.adapter.logtypes.listDevices]?.(
363
+ `Start building Light On for Id: ${discovery.ids.closedSignal}`,
364
+ );
365
+ usedId[discovery.ids.closedSignal] = true;
366
+ card = { preLabel: '', label: 'Unten (geschlossen)' };
367
+ card = lodash.merge(card, deviceValue.ids[discovery.ids.closedSignal].object.native?.card);
368
+ const preLabel = card.preLabel ?? '';
369
+ let label = '';
370
+ if (card.name) {
371
+ label = card.name;
372
+ } else if (card.label) {
373
+ label = card.label;
374
+ } else {
375
+ label = deviceValue.ids[discovery.ids.closedSignal].object._id.substring(
376
+ deviceValue.ids[discovery.ids.closedSignal].object._id.lastIndexOf('.') + 1,
377
+ );
378
+ }
379
+ res.customInfo.schema.items[`${discovery.ids.closedSignal}`] = {
380
+ type: 'state',
381
+ // The full state ID including namespace (foreign = true means it's an absolute ID).
382
+ oid: discovery.ids.closedSignal,
383
+ foreign: true,
384
+ // Render as an interactive switch control.
385
+ control: 'text',
386
+ // Style the text based on the boolean value.
387
+ label: preLabel + label,
388
+ trueText: 'nicht geschlossen',
389
+ falseText: 'Zugefahren',
390
+ };
391
+ }
392
+ break;
393
+ }
394
+ }
395
+ }
396
+ //////////////////////////////////////////////////////////////////////////////////////////////////
397
+ //////////////////////////////////////////////////////////////////////////////////////////////////
398
+ //////////////////////////////////////////////////////////////////////////////////////////////////
399
+ if (deviceValue.entityType.lock) {
400
+ for (const discovery of deviceValue.discovery) {
401
+ if (discovery.topic.startsWith('homeassistant/lock/')) {
402
+ let card = {};
403
+ if (discovery.ids.lock) {
404
+ this.adapter.log[this.adapter.logtypes.listDevices]?.(
405
+ `Start building Light On for Id: ${discovery.ids.open}`,
406
+ );
407
+ usedId[discovery.ids.open] = true;
408
+ card = { preLabel: '🔒 ', label: 'Abschließen' };
409
+ card = lodash.merge(card, deviceValue.ids[discovery.ids.open].object.native?.card);
410
+ const preLabel = card.preLabel ?? '';
411
+ let label = '';
412
+ if (card.name) {
413
+ label = card.name;
414
+ } else if (card.label) {
415
+ label = card.label;
416
+ } else {
417
+ label = deviceValue.ids[discovery.ids.open].object._id.substring(
418
+ deviceValue.ids[discovery.ids.open].object._id.lastIndexOf('.') + 1,
419
+ );
420
+ }
421
+ res.customInfo.schema.items[`${discovery.ids.open}`] = {
422
+ type: 'state',
423
+ // The full state ID including namespace (foreign = true means it's an absolute ID).
424
+ oid: discovery.ids.open,
425
+ foreign: true,
426
+ // Render as an interactive switch control.
427
+ control: 'button',
428
+ // Style the text based on the boolean value.
429
+ label: preLabel + label,
430
+ };
431
+ }
432
+ if (discovery.ids.unlock) {
433
+ this.adapter.log[this.adapter.logtypes.listDevices]?.(
434
+ `Start building Light On for Id: ${discovery.ids.unlock}`,
435
+ );
436
+ usedId[discovery.ids.unlock] = true;
437
+ card = { preLabel: '🔓 ', label: 'Aufschließen' };
438
+ card = lodash.merge(card, deviceValue.ids[discovery.ids.unlock].object.native?.card);
439
+ const preLabel = card.preLabel ?? '';
440
+ let label = '';
441
+ if (card.name) {
442
+ label = card.name;
443
+ } else if (card.label) {
444
+ label = card.label;
445
+ } else {
446
+ label = deviceValue.ids[discovery.ids.unlock].object._id.substring(
447
+ deviceValue.ids[discovery.ids.unlock].object._id.lastIndexOf('.') + 1,
448
+ );
449
+ }
450
+ res.customInfo.schema.items[`${discovery.ids.unlock}`] = {
451
+ type: 'state',
452
+ // The full state ID including namespace (foreign = true means it's an absolute ID).
453
+ oid: discovery.ids.unlock,
454
+ foreign: true,
455
+ // Render as an interactive switch control.
456
+ control: 'button',
457
+ // Style the text based on the boolean value.
458
+ label: preLabel + label,
459
+ };
460
+ }
461
+ if (discovery.ids.open) {
462
+ this.adapter.log[this.adapter.logtypes.listDevices]?.(
463
+ `Start building Light On for Id: ${discovery.ids.open}`,
464
+ );
465
+ usedId[discovery.ids.open] = true;
466
+ card = { preLabel: '', label: 'Öffnen' };
467
+ card = lodash.merge(card, deviceValue.ids[discovery.ids.open].object.native?.card);
468
+ const preLabel = card.preLabel ?? '';
469
+ let label = '';
470
+ if (card.name) {
471
+ label = card.name;
472
+ } else if (card.label) {
473
+ label = card.label;
474
+ } else {
475
+ label = deviceValue.ids[discovery.ids.open].object._id.substring(
476
+ deviceValue.ids[discovery.ids.open].object._id.lastIndexOf('.') + 1,
477
+ );
478
+ }
479
+ res.customInfo.schema.items[`${discovery.ids.open}`] = {
480
+ type: 'state',
481
+ // The full state ID including namespace (foreign = true means it's an absolute ID).
482
+ oid: discovery.ids.open,
483
+ foreign: true,
484
+ // Render as an interactive switch control.
485
+ control: 'button',
486
+ // Style the text based on the boolean value.
487
+ label: preLabel + label,
488
+ };
489
+ }
490
+ if (discovery.ids.state) {
491
+ this.adapter.log[this.adapter.logtypes.listDevices]?.(
492
+ `Start building Light On for Id: ${discovery.ids.state}`,
493
+ );
494
+ usedId[discovery.ids.state] = true;
495
+ card = { preLabel: '', label: 'Status' };
496
+ card = lodash.merge(card, deviceValue.ids[discovery.ids.state].object.native?.card);
497
+ const preLabel = card.preLabel ?? '';
498
+ let label = '';
499
+ if (card.name) {
500
+ label = card.name;
501
+ } else if (card.label) {
502
+ label = card.label;
503
+ } else {
504
+ label = deviceValue.ids[discovery.ids.state].object._id.substring(
505
+ deviceValue.ids[discovery.ids.state].object._id.lastIndexOf('.') + 1,
506
+ );
507
+ }
508
+ res.customInfo.schema.items[`${discovery.ids.state}`] = {
509
+ type: 'state',
510
+ // The full state ID including namespace (foreign = true means it's an absolute ID).
511
+ oid: discovery.ids.state,
512
+ foreign: true,
513
+ // Render as an interactive switch control.
514
+ control: 'text',
515
+ // Style the text based on the boolean value.
516
+ label: preLabel + label,
517
+ };
518
+ }
519
+ break;
520
+ }
521
+ }
522
+ }
523
+ //////////////////////////////////////////////////////////////////////////////////////////////////
524
+ //////////////////////////////////////////////////////////////////////////////////////////////////
525
+ //////////////////////////////////////////////////////////////////////////////////////////////////
67
526
  if (deviceValue.entityType.light) {
68
- const ids = {};
69
527
  for (const discovery of deviceValue.discovery) {
70
528
  if (discovery.topic.startsWith('homeassistant/light/')) {
71
529
  let card = {};
72
530
  if (discovery.ids.onOff) {
73
- ids.onOff = discovery.ids.onOff;
74
531
  this.adapter.log[this.adapter.logtypes.listDevices]?.(
75
- `Start building Light On for Id: ${ids.onOff}`,
532
+ `Start building Light On for Id: ${discovery.ids.onOff}`,
76
533
  );
77
- usedLightId[ids.onOff] = true;
78
- card = { preLabel: '⏻ ', label: 'An / Aus' };
79
- card = lodash.merge(card, deviceValue.ids[ids.onOff].object.native?.card);
534
+ usedId[discovery.ids.onOff] = true;
535
+ card = { preLabel: '⏻ ', label: 'Aus / An' };
536
+ card = lodash.merge(card, deviceValue.ids[discovery.ids.onOff].object.native?.card);
80
537
  const preLabel = card.preLabel ?? '';
81
538
  let label = '';
82
539
  if (card.name) {
@@ -84,14 +541,14 @@ class bridgeDevicesClass {
84
541
  } else if (card.label) {
85
542
  label = card.label;
86
543
  } else {
87
- label = deviceValue.ids[ids.onOff].object._id.substring(
88
- deviceValue.ids[ids.onOff].object._id.lastIndexOf('.') + 1,
544
+ label = deviceValue.ids[discovery.ids.onOff].object._id.substring(
545
+ deviceValue.ids[discovery.ids.onOff].object._id.lastIndexOf('.') + 1,
89
546
  );
90
547
  }
91
- res.customInfo.schema.items._onOff = {
548
+ res.customInfo.schema.items[`${discovery.ids.onOff}`] = {
92
549
  type: 'state',
93
550
  // The full state ID including namespace (foreign = true means it's an absolute ID).
94
- oid: ids.onOff,
551
+ oid: discovery.ids.onOff,
95
552
  foreign: true,
96
553
  // Render as an interactive switch control.
97
554
  control: 'switch',
@@ -104,13 +561,12 @@ class bridgeDevicesClass {
104
561
  };
105
562
  }
106
563
  if (discovery.ids.brightness) {
107
- ids.brightness = discovery.ids.brightness;
108
564
  this.adapter.log[this.adapter.logtypes.listDevices]?.(
109
- `Start building Light Brightness for Id: ${ids.brightness}`,
565
+ `Start building Light Brightness for Id: ${discovery.ids.brightness}`,
110
566
  );
111
- usedLightId[ids.brightness] = true;
567
+ usedId[discovery.ids.brightness] = true;
112
568
  card = { preLabel: '🔆 ', label: 'Helligkeit' };
113
- card = lodash.merge(card, deviceValue.ids[ids.brightness].object.native?.card);
569
+ card = lodash.merge(card, deviceValue.ids[discovery.ids.brightness].object.native?.card);
114
570
  const preLabel = card.preLabel ?? '';
115
571
  let label = '';
116
572
  if (card.name) {
@@ -118,14 +574,14 @@ class bridgeDevicesClass {
118
574
  } else if (card.label) {
119
575
  label = card.label;
120
576
  } else {
121
- label = deviceValue.ids[ids.onOff].object._id.substring(
122
- deviceValue.ids[ids.onOff].object._id.lastIndexOf('.') + 1,
577
+ label = deviceValue.ids[discovery.ids.brightness].object._id.substring(
578
+ deviceValue.ids[discovery.ids.brightness].object._id.lastIndexOf('.') + 1,
123
579
  );
124
580
  }
125
- res.customInfo.schema.items._brightness = {
581
+ res.customInfo.schema.items[`${discovery.ids.brighness}`] = {
126
582
  type: 'state',
127
583
  // The full state ID including namespace (foreign = true means it's an absolute ID).
128
- oid: ids.brightness,
584
+ oid: discovery.ids.brightness,
129
585
  foreign: true,
130
586
  // Render as an interactive switch control.
131
587
  control: 'slider',
@@ -135,17 +591,14 @@ class bridgeDevicesClass {
135
591
  label: preLabel + label,
136
592
  };
137
593
  }
138
- if (discovery.ids.color) {
139
- ids.color = discovery.ids.color;
140
- }
141
- break;
594
+ continue;
142
595
  }
143
596
  }
144
597
  }
145
598
  // Check all entries in Informations.card
146
599
  if (deviceValue.informations?.card) {
147
600
  for (const [key, value] of Object.entries(deviceValue.informations?.card)) {
148
- if (usedLightId[value.object._id]) {
601
+ if (usedId[value.object._id]) {
149
602
  continue;
150
603
  }
151
604
  this.adapter.log[this.adapter.logtypes.listDevices]?.(`Start building for Id: ${value.object._id}`);
@@ -184,12 +637,18 @@ class bridgeDevicesClass {
184
637
  delete res.customInfo;
185
638
  } else {
186
639
  const items = res.customInfo.schema.items;
187
- const sortedItems = Object.keys(items)
188
- .sort((a, b) => a.localeCompare(b))
189
- .reduce((acc, key) => {
190
- acc[key] = items[key];
191
- return acc;
192
- }, {});
640
+
641
+ // 1. Keys trennen
642
+ const normalKeys = Object.keys(items).filter(key => !key.startsWith('_'));
643
+ const underscoreKeys = Object.keys(items)
644
+ .filter(key => key.startsWith('_'))
645
+ .sort((a, b) => a.localeCompare(b));
646
+
647
+ // 2. Zusammenführen (normale zuerst, dann sortierte "_"-Keys)
648
+ const sortedItems = [...normalKeys, ...underscoreKeys].reduce((acc, key) => {
649
+ acc[key] = items[key];
650
+ return acc;
651
+ }, {});
193
652
 
194
653
  res.customInfo.schema.items = sortedItems;
195
654
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lorawan",
3
- "version": "1.22.2",
3
+ "version": "1.22.4",
4
4
  "description": "converts the desired lora gateway data to a ioBroker structure",
5
5
  "author": {
6
6
  "name": "BenAhrdt",