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 +6 -106
- package/io-package.json +27 -27
- package/lib/modules/deviceManager/bridgeDevices.js +489 -30
- 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.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.
|
|
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
|
-
|
|
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
|
-
|
|
78
|
-
card = { preLabel: '⏻ ', label: '
|
|
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.
|
|
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
|
-
|
|
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.
|
|
122
|
-
deviceValue.ids[ids.
|
|
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.
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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
|
}
|