iobroker.lorawan 1.13.4 → 1.13.6

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
@@ -23,6 +23,15 @@ For now there is documentation in English here: https://wiki.hafenmeister.de
23
23
  Placeholder for the next version (at the beginning of the line):
24
24
  ### **WORK IN PROGRESS**
25
25
  -->
26
+ ### 1.13.6 (2025-09-06)
27
+ * (BenAhrdt) Bugfix handling in fillDownlink
28
+
29
+ ### 1.13.5 (2025-09-06)
30
+ * (BenAhrdt) Show discovery topic(s) & messag(es) ind array
31
+ * (BenAhrdt) Add Tab to see Discovered, Published and Subscribed Ids.
32
+ * (BenAhrdt) Add Posibility to discover climate Entity
33
+ * (BenAhrdt) Retaining Discovery
34
+
26
35
  ### 1.13.4 (2025-09-04)
27
36
  * (BenAhrdt) Bugfixing crc in Vicki Profile => ChildLock
28
37
 
@@ -117,7 +117,7 @@
117
117
  "_NoLoRaWAN": "Der State ist nicht in der richtigen Lorawan - Instanz",
118
118
  "publishTooltip": "Veröffentlichen Sie den State zur der Bridge",
119
119
  "subscribeTooltip": "Abonnieren Sie den State von der Bridge",
120
- "BridgeStateHeader": "Definieren Sie ZustäStates für das HA Discovery",
120
+ "BridgeStateHeader": "Definieren Sie Zustände für das HA Discovery",
121
121
  "BridgeStateInformation": "Hier können Sie ein Array von States definieren, die ein Topic für Discovery festlegen. (Wildcards sind auch möglich)",
122
122
  "Application": "Anwendung",
123
123
  "Device": "Gerät",
@@ -126,7 +126,15 @@
126
126
  "BridgeType": "Bridge Typ",
127
127
  "BridgeTypeTooltip": "Wählen Sie den Typ des Fremdsystems aus",
128
128
  "BridgeTypeOff": "aus",
129
- "BridgeTypeHA": "Voldemort",
129
+ "BridgeTypeHA": "Home Assistant",
130
130
  "RefreshDiscoveryCronJob": "Discovery Zyklus",
131
- "RefreshDiscoveryCronJobTooltip": "Stellen Sie den Cronjob für das Discovery ein"
131
+ "RefreshDiscoveryCronJobTooltip": "Stellen Sie den Cronjob für das Discovery ein",
132
+ "ClimateHeader": "Definieren Sie Zustände für eine Klima ENtität",
133
+ "ClimateInformation": "Hier können Sie ein Array von Klimaentitäten definieren",
134
+ "ClimateTargetTemperatureText": "Solltemperatur",
135
+ "ClimateActTemperatureText": "Isttemperatur",
136
+ "ClimateActModeText": "Mode",
137
+ "_DiscoveredIds": "Discoverd Ids",
138
+ "_PublishedIds": "Published Ids",
139
+ "_SubscribedTopics": "Subscribed Topics"
132
140
  }
@@ -128,5 +128,13 @@
128
128
  "BridgeTypeOff": "off",
129
129
  "BridgeTypeHA": "Home Assistant",
130
130
  "RefreshDiscoveryCronJob": "Discover Cycle",
131
- "RefreshDiscoveryCronJobTooltip": "insert the cronjob for refreshing the discovery"
131
+ "RefreshDiscoveryCronJobTooltip": "insert the cronjob for refreshing the discovery",
132
+ "ClimateHeader": "Define States for Climate Entity",
133
+ "ClimateInformation": "Here you can define an array of Climate definitions",
134
+ "ClimateTargetTemperatureText": "Target Temperature",
135
+ "ClimateActTemperatureText": "Target Temperature",
136
+ "ClimateActModeText": "Target Temperature",
137
+ "_DiscoveredIds": "Discoverd Ids",
138
+ "_PublishedIds": "Published Ids",
139
+ "_SubscribedTopics": "Subscribed Topics"
132
140
  }
@@ -1112,7 +1112,7 @@
1112
1112
  "attr": "subscribe",
1113
1113
  "label": "subscribe",
1114
1114
  "hidden": "data.Folder !== 'downlink.control'",
1115
- "default": false,
1115
+ "default": true,
1116
1116
  "width": "5%"
1117
1117
  },
1118
1118
  {
@@ -1123,6 +1123,273 @@
1123
1123
  "width": "5%"
1124
1124
  }
1125
1125
  ]
1126
+ },
1127
+ "_ClimateHeader":{
1128
+ "newLine": true,
1129
+ "hidden": "data.BridgeType === 'off'",
1130
+ "type": "header",
1131
+ "text": "ClimateHeader",
1132
+ "size": 3,
1133
+ "xs": 12,
1134
+ "sm": 12,
1135
+ "md": 12,
1136
+ "lg": 12,
1137
+ "xl": 12
1138
+ },
1139
+ "_ClimateInformation":{
1140
+ "newLine":true,
1141
+ "hidden": "data.BridgeType === 'off'",
1142
+ "type": "staticText",
1143
+ "label": "ClimateInformation",
1144
+ "xs": 12,
1145
+ "sm": 12,
1146
+ "md": 12,
1147
+ "lg": 12,
1148
+ "xl": 12
1149
+ },
1150
+ "ClimateConfig":{
1151
+ "newLine": true,
1152
+ "hidden": "data.BridgeType === 'off'",
1153
+ "type":"accordion",
1154
+ "titleAttr": "ClimateName",
1155
+ "clone": true,
1156
+ "xs": 12,
1157
+ "sm": 12,
1158
+ "md": 12,
1159
+ "lg": 12,
1160
+ "xl": 12,
1161
+ "items":[
1162
+ {
1163
+ "type": "text",
1164
+ "attr": "ClimateName",
1165
+ "label": "ClimateNameText",
1166
+ "xs": 12,
1167
+ "sm": 4,
1168
+ "md": 4,
1169
+ "lg": 4,
1170
+ "xl": 4
1171
+ },
1172
+ {
1173
+ "newLine": true,
1174
+ "type": "staticText",
1175
+ "attr": "_statciTextTarget",
1176
+ "label": "ClimateTargetTemperatureText",
1177
+ "xs": 12,
1178
+ "sm": 12,
1179
+ "md": 12,
1180
+ "lg": 12,
1181
+ "xl": 12
1182
+ },
1183
+ {
1184
+ "newLine": true,
1185
+ "type": "selectSendTo",
1186
+ "attr": "TargetApplication",
1187
+ "label": "Application",
1188
+ "default": "No Application selected",
1189
+ "jsonData": "{}",
1190
+ "command": "getApplicationsForClimateConfig",
1191
+ "xs": 12,
1192
+ "sm": 3,
1193
+ "md": 3,
1194
+ "lg": 3,
1195
+ "xl": 3
1196
+ },
1197
+ {
1198
+ "type": "selectSendTo",
1199
+ "attr": "TargetDevice",
1200
+ "label": "Device",
1201
+ "default": "No Device selected",
1202
+ "jsonData": "{\"application\":\"${data.TargetApplication}\"}",
1203
+ "command": "getDevicesForClimateConfig",
1204
+ "alsoDependsOn":[
1205
+ "TargetApplication"
1206
+ ],
1207
+ "xs": 12,
1208
+ "sm": 3,
1209
+ "md": 3,
1210
+ "lg": 3,
1211
+ "xl": 3
1212
+ },
1213
+ {
1214
+ "type": "select",
1215
+ "attr": "TargetFolder",
1216
+ "label": "Folder",
1217
+ "default": "downlink.control",
1218
+ "options": [
1219
+ {"label":"downlink.control","value":"downlink.control"}
1220
+ ],
1221
+ "xs": 12,
1222
+ "sm": 2,
1223
+ "md": 2,
1224
+ "lg": 2,
1225
+ "xl": 2
1226
+ },
1227
+ {
1228
+ "type": "selectSendTo",
1229
+ "attr": "TargetState",
1230
+ "label": "State",
1231
+ "default": "No State selected",
1232
+ "jsonData": "{\"application\":\"${data.TargetApplication}\",\"device\":\"${data.TargetDevice}\",\"folder\":\"${data.TargetFolder}\"}",
1233
+ "command": "getStatesForClimateConfig",
1234
+ "alsoDependsOn":[
1235
+ "TargetApplication",
1236
+ "TargetDevice",
1237
+ "TargetFolder"
1238
+ ],
1239
+ "xs": 12,
1240
+ "sm": 4,
1241
+ "md": 4,
1242
+ "lg": 4,
1243
+ "xl": 4
1244
+ },
1245
+ {
1246
+ "type": "staticText",
1247
+ "attr": "_statciTextAct",
1248
+ "label": "ClimateActTemperatureText",
1249
+ "xs": 12,
1250
+ "sm": 12,
1251
+ "md": 12,
1252
+ "lg": 12,
1253
+ "xl": 12
1254
+ },
1255
+ {
1256
+ "newLine": true,
1257
+ "type": "selectSendTo",
1258
+ "attr": "ActApplication",
1259
+ "label": "Application",
1260
+ "default": "No Application selected",
1261
+ "jsonData": "{}",
1262
+ "command": "getApplicationsForClimateConfig",
1263
+ "xs": 12,
1264
+ "sm": 3,
1265
+ "md": 3,
1266
+ "lg": 3,
1267
+ "xl": 3
1268
+ },
1269
+ {
1270
+ "type": "selectSendTo",
1271
+ "attr": "ActDevice",
1272
+ "label": "Device",
1273
+ "default": "No Device selected",
1274
+ "jsonData": "{\"application\":\"${data.ActApplication}\"}",
1275
+ "command": "getDevicesForClimateConfig",
1276
+ "alsoDependsOn":[
1277
+ "ActApplication"
1278
+ ],
1279
+ "xs": 12,
1280
+ "sm": 3,
1281
+ "md": 3,
1282
+ "lg": 3,
1283
+ "xl": 3
1284
+ },
1285
+ {
1286
+ "type": "select",
1287
+ "attr": "ActFolder",
1288
+ "label": "Folder",
1289
+ "default": "uplink.decoded",
1290
+ "options": [
1291
+ {"label":"uplink.decoded","value":"uplink.decoded"}
1292
+ ],
1293
+ "xs": 12,
1294
+ "sm": 2,
1295
+ "md": 2,
1296
+ "lg": 2,
1297
+ "xl": 2
1298
+ },
1299
+ {
1300
+ "type": "selectSendTo",
1301
+ "attr": "ActState",
1302
+ "label": "State",
1303
+ "default": "No State selected",
1304
+ "jsonData": "{\"application\":\"${data.ActApplication}\",\"device\":\"${data.ActDevice}\",\"folder\":\"${data.ActFolder}\"}",
1305
+ "command": "getStatesForClimateConfig",
1306
+ "alsoDependsOn":[
1307
+ "ActApplication",
1308
+ "ActDevice",
1309
+ "ActFolder"
1310
+ ],
1311
+ "xs": 12,
1312
+ "sm": 4,
1313
+ "md": 4,
1314
+ "lg": 4,
1315
+ "xl": 4
1316
+ },
1317
+ {
1318
+ "type": "staticText",
1319
+ "attr": "_statciTextMode",
1320
+ "label": "ClimateModeTemperatureText",
1321
+ "xs": 12,
1322
+ "sm": 12,
1323
+ "md": 12,
1324
+ "lg": 12,
1325
+ "xl": 12
1326
+ },
1327
+ {
1328
+ "newLine": true,
1329
+ "type": "selectSendTo",
1330
+ "attr": "ModeApplication",
1331
+ "label": "Application",
1332
+ "default": "NotPresent",
1333
+ "jsonData": "{}",
1334
+ "command": "getApplicationsForClimateModeConfig",
1335
+ "xs": 12,
1336
+ "sm": 3,
1337
+ "md": 3,
1338
+ "lg": 3,
1339
+ "xl": 3
1340
+ },
1341
+ {
1342
+ "type": "selectSendTo",
1343
+ "attr": "ModeDevice",
1344
+ "label": "Device",
1345
+ "default": "*",
1346
+ "jsonData": "{\"application\":\"${data.ModeApplication}\"}",
1347
+ "command": "getDevicesForClimateConfig",
1348
+ "hidden": "data.ModeApplication === 'NotPresent'",
1349
+ "alsoDependsOn":[
1350
+ "ModeApplication"
1351
+ ],
1352
+ "xs": 12,
1353
+ "sm": 3,
1354
+ "md": 3,
1355
+ "lg": 3,
1356
+ "xl": 3
1357
+ },
1358
+ {
1359
+ "type": "select",
1360
+ "attr": "ModeFolder",
1361
+ "label": "Folder",
1362
+ "default": "uplink.decoded",
1363
+ "options": [
1364
+ {"label":"uplink.decoded","value":"uplink.decoded"}
1365
+ ],
1366
+ "hidden": "data.ModeApplication === 'NotPresent'",
1367
+ "xs": 12,
1368
+ "sm": 2,
1369
+ "md": 2,
1370
+ "lg": 2,
1371
+ "xl": 2
1372
+ },
1373
+ {
1374
+ "type": "selectSendTo",
1375
+ "attr": "ModeState",
1376
+ "label": "State",
1377
+ "default": "No State selected",
1378
+ "jsonData": "{\"application\":\"${data.ModeApplication}\",\"device\":\"${data.ActDevice}\",\"folder\":\"${data.ActFolder}\"}",
1379
+ "command": "getStatesForClimateConfig",
1380
+ "alsoDependsOn":[
1381
+ "ModeApplication",
1382
+ "ModeDevice",
1383
+ "ModeFolder"
1384
+ ],
1385
+ "hidden": "data.ModeApplication === 'NotPresent'",
1386
+ "xs": 12,
1387
+ "sm": 4,
1388
+ "md": 4,
1389
+ "lg": 4,
1390
+ "xl": 4
1391
+ }
1392
+ ]
1126
1393
  }
1127
1394
  }
1128
1395
  }
@@ -0,0 +1,69 @@
1
+ {
2
+ "i18n": true,
3
+ "type": "tabs",
4
+ "tabsStyle": {
5
+ "width": "calc(100% - 100px)"
6
+ },
7
+ "items":{
8
+ "_DiscoveredIds":{
9
+ "type": "panel",
10
+ "label": "_DiscoveredIds",
11
+ "items": {
12
+ "_DiscoveredIds":{
13
+ "type": "text",
14
+ "label": "_DiscoveredIds",
15
+ "defaultSendTo": "getDiscoveredIds",
16
+ "minRows": 10,
17
+ "readOnly": true,
18
+ "trim": false,
19
+ "noClearButton": true,
20
+ "xs": 12,
21
+ "sm": 12,
22
+ "md": 12,
23
+ "lg": 12,
24
+ "xl": 12
25
+ }
26
+ }
27
+ },
28
+ "_PublishedIds":{
29
+ "type": "panel",
30
+ "label": "_PublishedIds",
31
+ "items": {
32
+ "_PublishedIds":{
33
+ "type": "text",
34
+ "label": "_PublishedIds",
35
+ "defaultSendTo": "getPublishedIds",
36
+ "minRows": 10,
37
+ "readOnly": true,
38
+ "trim": false,
39
+ "noClearButton": true,
40
+ "xs": 12,
41
+ "sm": 12,
42
+ "md": 12,
43
+ "lg": 12,
44
+ "xl": 12
45
+ }
46
+ }
47
+ },
48
+ "_SubscribedTopics":{
49
+ "type": "panel",
50
+ "label": "_SubscribedTopics",
51
+ "items": {
52
+ "_SubscribedTopics":{
53
+ "type": "text",
54
+ "label": "_SubscribedTopics",
55
+ "defaultSendTo": "getSubscribedTopics",
56
+ "minRows": 10,
57
+ "readOnly": true,
58
+ "trim": false,
59
+ "noClearButton": true,
60
+ "xs": 12,
61
+ "sm": 12,
62
+ "md": 12,
63
+ "lg": 12,
64
+ "xl": 12
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "lorawan",
4
- "version": "1.13.4",
4
+ "version": "1.13.6",
5
5
  "news": {
6
+ "1.13.6": {
7
+ "en": "Bugfix handling in fillDownlink",
8
+ "de": "Bugfix Handhabung in fillDownlink",
9
+ "ru": "Обработка Bugfix в fillDownlink",
10
+ "pt": "Tratamento de erros em fillDownlink",
11
+ "nl": "Bugfix-verwerking in fillDownlink",
12
+ "fr": "Gestion du bugfix dans fillDownlink",
13
+ "it": "Gestione bugfix in fillDownlink",
14
+ "es": "Manejo de bugfix en rellenoDownlink",
15
+ "pl": "Obsługa Bugfix w FuelDownlink",
16
+ "uk": "Обробка помилок в накладціДоне посилання",
17
+ "zh-cn": "在 fillDownlink 中处理错误"
18
+ },
19
+ "1.13.5": {
20
+ "en": "Show discovery topic(s) & messag(es) ind array\nAdd Tab to see Discovered, Published and Subscribed Ids.\nAdd Posibility to discover climate Entity\nRetaining Discovery",
21
+ "de": "Zeige Entdeckungsthemen & Messag(en) ind array\nFügen Sie Tab hinzu, um entdeckte, veröffentlichte und abgemeldete Ids zu sehen.\nMöglichkeit, das Klima zu entdecken\nRetaining Discovery",
22
+ "ru": "Показать тему(ы) обнаружения и мессенджер(ы) ind array\nДобавьте вкладку, чтобы увидеть обнаруженные, опубликованные и подписанные идентификаторы.\nДобавить возможность открыть климатическую организацию\nСохранение Discovery",
23
+ "pt": "Mostrar o( s) tópico( s) de descoberta & messag( es) ind array\nAdicionar aba para ver IDs descobertos, publicados e assinados.\nAdicionar Possibilidade de descobrir o clima Entidade\nManter a Descoberta",
24
+ "nl": "Ontdekkingsonderwerp(s) & messag(es) ind-array tonen\nTabblad toevoegen om Ontdekt, Gepubliceerd en Geabonneerd Ids te zien.\nMogelijkheid toevoegen om klimaat te ontdekken Entity\nOntdekking behouden",
25
+ "fr": "Afficher le(s) sujet(s) de découverte et le(s) tableau(s) ind\nAjouter un onglet pour voir les idées découvertes, publiées et enregistrées.\nAjouter la possibilité de découvrir le climat Entité\nConserver la découverte",
26
+ "it": "Mostra argomento(i) & messag(es) ind array\nAggiungi scheda per vedere Scoperto, Pubblicato e Abbonato Ids.\nAggiungi Posibilità per scoprire il clima\nRecuperare Discovery",
27
+ "es": "Mostrar el tema de descubrimiento(s) & messag(es) end array\nAñadir Tab para ver Ids descubiertos, publicados y suscritos.\nAñadir Posibilidad de descubrir la Entidad climática\nRetaining Discovery",
28
+ "pl": "Pokaż temat (y) & messag (y) ind array\nDodaj kartę, aby zobaczyć odkryte, opublikowane i subskrybowane identyfikatory.\nDodaj możliwość odkrywania podmiotu klimatu\nZachowanie Odkrycia",
29
+ "uk": "Показати тему відкриття (s) & mesag(es) ind array\nДодати вкладку, щоб побачити Discovered, Опубліковано та підписувати Ids.\nДодати можливість відкрити клімат\nПідтримка Discovery",
30
+ "zh-cn": "显示发现主题 & messag( es) ind 数组\n添加 Tab 以查看发现、 发布和订阅的 Ids .\n添加发现气候实体的可能性\n保留发现"
31
+ },
6
32
  "1.13.4": {
7
33
  "en": "Bugfixing crc in Vicki Profile => ChildLock",
8
34
  "de": "Bugfixing crc in Vicki Profil => ChildLock",
@@ -67,32 +93,6 @@
67
93
  "pl": "Zbuduj pięść wersja własnego klienta Bridge MQTT",
68
94
  "uk": "Створення fist версії власного Bridge MQTT Клієнт",
69
95
  "zh-cn": "构建自有桥 MQTT 客户端的拳头版本"
70
- },
71
- "1.12.1": {
72
- "en": "remove Bug with folder / state handling",
73
- "de": "entfernen Bug mit Ordner / State Handling",
74
- "ru": "удалять Баг с папкой / обработка состояния",
75
- "pt": "remover Erro com manipulação de pasta / estado",
76
- "nl": "verwijderen Bug met map / status behandeling",
77
- "fr": "supprimer Bogue avec gestion de dossier / état",
78
- "it": "rimuovere Bug con cartella / gestione dello stato",
79
- "es": "retirar Error con carpeta / manejo del estado",
80
- "pl": "usunąć Błąd z obsługą folderu / stanu",
81
- "uk": "видалення Помилки з папкою / державною обробкою",
82
- "zh-cn": "删除 有文件夹/ 状态处理的错误"
83
- },
84
- "1.12.0": {
85
- "en": "Custom Table for Config HA Bridge",
86
- "de": "Benutzerdefinierte Tisch für Config HA Bridge",
87
- "ru": "Настольный стол для моста Config HA",
88
- "pt": "Mesa personalizada para configuração HA Bridge",
89
- "nl": "Aangepaste tabel voor Config HA Bridge",
90
- "fr": "Table personnalisée pour Config HA Bridge",
91
- "it": "Tabella personalizzata per Config HA Bridge",
92
- "es": "Tabla personalizada para el puente Config HA",
93
- "pl": "Niestandardowa tabela dla Config HA Bridge",
94
- "uk": "Спеціальна таблиця для Config HA Bridge",
95
- "zh-cn": "配置 HA 桥的自定义表格"
96
96
  }
97
97
  },
98
98
  "titleLang": {
@@ -146,7 +146,16 @@
146
146
  "dataSource": "push",
147
147
  "blockly": true,
148
148
  "adminUI": {
149
- "config": "json"
149
+ "config": "json",
150
+ "tab": "json"
151
+ },
152
+ "adminTab": {
153
+ "link": "jsonTab.json",
154
+ "singleton": false,
155
+ "name": {
156
+ "en": "LoRaWAN",
157
+ "de": "LoRaWAN"
158
+ }
150
159
  },
151
160
  "dependencies": [
152
161
  {
@@ -376,7 +385,8 @@
376
385
  "subscribe": false,
377
386
  "exclude": false
378
387
  }
379
- ]
388
+ ],
389
+ "ClimateConfig": []
380
390
  },
381
391
  "objects": [],
382
392
  "instanceObjects": [
@@ -1,6 +1,8 @@
1
1
  const bridgeMqttClientClass = require('./bridgeMqttclient');
2
2
  const schedule = require('node-schedule');
3
-
3
+ /*
4
+ Also er published irgendwie nicht den Mode => und es kommt virtual_Mode nicht subcribed....
5
+ */
4
6
  /**
5
7
  * this class handles the bridge to foreign system
6
8
  */
@@ -10,7 +12,7 @@ class bridgeClass {
10
12
  */
11
13
  constructor(adapter) {
12
14
  this.adapter = adapter;
13
-
15
+ this.InitDone = false; // Activates work
14
16
  /*********************************************************************
15
17
  * ************** Definition Assigns (externel Module) ***************
16
18
  * ******************************************************************/
@@ -21,12 +23,16 @@ class bridgeClass {
21
23
  this.CheckedIds = {};
22
24
  this.DiscoveredIds = {};
23
25
  this.SubscribedTopics = {};
24
- this.PulishedIds = {};
26
+ this.PublishedIds = {};
27
+ this.VitualIds = {};
25
28
  this.BridgeDiscoveryPrefix = {
26
29
  HA: 'homeassistant/',
27
30
  };
28
31
  this.MinTime = 100; // ms between publish and subscribe same value
29
32
  this.DiscoveryCronjob = {};
33
+ this.EndingVirtualClimate = '.virtual_climate';
34
+ this.EndingVirtualMode = '.virtual_mode';
35
+ this.ClimateEntityType = 'climate';
30
36
  }
31
37
 
32
38
  /*********************************************************************
@@ -42,13 +48,21 @@ class bridgeClass {
42
48
  this.adapter.log.debug(`Function ${activeFunction} started.`);
43
49
  try {
44
50
  if (this.SubscribedTopics[topic]) {
45
- this.SubscribedTopics[topic].val = message;
46
- this.SubscribedTopics[topic].ts = Date.now();
47
51
  if (
48
- !this.PulishedIds[this.SubscribedTopics[topic].id] ||
49
- this.PulishedIds[this.SubscribedTopics[topic].id].val !== message ||
50
- Date.now() - this.PulishedIds[this.SubscribedTopics[topic].id].ts > this.MinTime
52
+ !this.PublishedIds[this.SubscribedTopics[topic].id] ||
53
+ this.PublishedIds[this.SubscribedTopics[topic].id].val !== message ||
54
+ Date.now() - this.PublishedIds[this.SubscribedTopics[topic].id].ts >= this.MinTime
51
55
  ) {
56
+ this.SubscribedTopics[topic].val = message;
57
+ this.SubscribedTopics[topic].ts = Date.now();
58
+ if (this.SubscribedTopics[topic].id.endsWith(this.EndingVirtualMode)) {
59
+ this.adapter.log.debug(
60
+ `The value ${message} is assigned to virtual id: ${this.SubscribedTopics[topic].id}`,
61
+ );
62
+ this.VitualIds[this.SubscribedTopics[topic].id] = message;
63
+ this.adapter.log.warn(`aaa${JSON.stringify(this.VitualIds)}`);
64
+ return;
65
+ }
52
66
  await this.adapter.setState(this.SubscribedTopics[topic].id, message);
53
67
  }
54
68
  } else {
@@ -68,9 +82,13 @@ class bridgeClass {
68
82
  const activeFunction = 'bridge.js - work';
69
83
  this.adapter.log.debug(`Function ${activeFunction} started.`);
70
84
  try {
85
+ // First remove namespace from id
86
+ id = this.adapter.removeNamespace(id);
71
87
  if (this.bridgeMqttClient.internalConnectionstate) {
72
88
  await this.discovery(id, options);
73
89
  await this.publishId(id, Stateval);
90
+ } else {
91
+ this.adapter.log.debug(`work called with id ${id}, but Bridge is not connected yet.`);
74
92
  }
75
93
  } catch (error) {
76
94
  this.adapter.log.error(`error at ${activeFunction}: ${error}`);
@@ -90,7 +108,11 @@ class bridgeClass {
90
108
  this.adapter.log.debug(`Function ${activeFunction} started.`);
91
109
  try {
92
110
  if (!this.CheckedIds[id] || (options && options.forceDiscovery)) {
111
+ this.CheckedIds[id] = {};
112
+ this.adapter.log.debug(`discover the id ${id}`);
93
113
  await this.buildDiscovery(id, options);
114
+ } else {
115
+ this.adapter.log.debug(`${id} allready checked for discovery`);
94
116
  }
95
117
  } catch (error) {
96
118
  this.adapter.log.error(`error at ${activeFunction}: ${error}`);
@@ -98,7 +120,205 @@ class bridgeClass {
98
120
  }
99
121
 
100
122
  /*********************************************************************
101
- * ********************* Publish zur Bridge **************=***********
123
+ * ********************** Discover Climate ***************************
124
+ * ******************************************************************/
125
+
126
+ /**
127
+ * Discover Configed Climate Entities
128
+ */
129
+ async discoverClimate() {
130
+ const activeFunction = 'discoverClimate';
131
+ this.adapter.log.debug(`Function ${activeFunction} started.`);
132
+ try {
133
+ if (this.adapter.config.ClimateConfig) {
134
+ for (const config of this.adapter.config.ClimateConfig) {
135
+ if (!(await this.generateClimateIds(config))) {
136
+ continue;
137
+ }
138
+ // All Ids ok
139
+ // Target
140
+ const target = {};
141
+ target.changeInfo = await this.adapter.getChangeInfo(config.climateIds.target);
142
+ target.DeviceIdentifier = this.getDeviceIdentifier(
143
+ target.changeInfo,
144
+ this.adapter.config.DeviceIdentifiers,
145
+ );
146
+ target.ReplacedDeviceIdentifier = await this.replaceGermanSpecific(target.DeviceIdentifier);
147
+ target.ReplacedWithoutSpace = await this.replaceSpace(target.ReplacedDeviceIdentifier);
148
+ target.ReplaceWithoutSlash = await this.replaceSlash(target.ReplacedWithoutSpace);
149
+ target.Topic = `${this.bridgeMqttClient.BridgePrefix}${target.ReplacedDeviceIdentifier}/${target.changeInfo.changedState}`;
150
+
151
+ //Min und Max holen
152
+ const targetObject = await this.adapter.getObjectAsync(config.climateIds.target);
153
+ if (targetObject.common.min) {
154
+ target.min = targetObject.common.min;
155
+ }
156
+ if (targetObject.common.max) {
157
+ target.max = targetObject.common.max;
158
+ }
159
+
160
+ // Act
161
+ const act = {};
162
+ act.changeInfo = await this.adapter.getChangeInfo(config.climateIds.act);
163
+ act.DeviceIdentifier = this.getDeviceIdentifier(
164
+ act.changeInfo,
165
+ this.adapter.config.DeviceIdentifiers,
166
+ );
167
+ act.ReplacedDeviceIdentifier = await this.replaceGermanSpecific(act.DeviceIdentifier);
168
+ act.ReplacedWithoutSpace = await this.replaceSpace(act.ReplacedDeviceIdentifier);
169
+ act.ReplaceWithoutSlash = await this.replaceSlash(act.ReplacedWithoutSpace);
170
+ act.Topic = `${this.bridgeMqttClient.BridgePrefix}${act.ReplacedDeviceIdentifier}/${act.changeInfo.changedState}`;
171
+
172
+ // Mode
173
+ const mode = {};
174
+ mode.changeInfo = await this.adapter.getChangeInfo(config.climateIds.mode);
175
+ mode.DeviceIdentifier = this.getDeviceIdentifier(
176
+ mode.changeInfo,
177
+ this.adapter.config.DeviceIdentifiers,
178
+ );
179
+ mode.ReplacedDeviceIdentifier = await this.replaceGermanSpecific(mode.DeviceIdentifier);
180
+ mode.ReplacedWithoutSpace = await this.replaceSpace(mode.ReplacedDeviceIdentifier);
181
+ mode.ReplaceWithoutSlash = await this.replaceSlash(mode.ReplacedWithoutSpace);
182
+ mode.Topic = `${this.bridgeMqttClient.BridgePrefix}${mode.ReplacedDeviceIdentifier}/${mode.changeInfo.changedState}`;
183
+
184
+ const indexLastSlashTarget = target.Topic.lastIndexOf('/');
185
+ const Topic = target.Topic.substring(0, indexLastSlashTarget) + this.EndingVirtualClimate;
186
+ const DiscoveryTopic = `${this.BridgeDiscoveryPrefix[this.adapter.config.BridgeType]}${this.ClimateEntityType}/${target.ReplaceWithoutSlash}/${config.ClimateName}/config`;
187
+ const indexLastDotTarget = config.climateIds.target.lastIndexOf('.');
188
+ const Id = config.climateIds.target.substring(0, indexLastDotTarget) + this.EndingVirtualClimate;
189
+ const DiscoveryPayload = {
190
+ name: config.ClimateName,
191
+ unique_id: `${target.ReplaceWithoutSlash}_${config.ClimateName}`.toLowerCase(),
192
+ device: {
193
+ identifiers: [target.ReplaceWithoutSlash.toLowerCase()],
194
+ name: target.DeviceIdentifier,
195
+ },
196
+ mode_state_topic: mode.Topic,
197
+ mode_command_topic: mode.Topic,
198
+ temperature_state_topic: target.Topic,
199
+ temperature_command_topic: target.Topic,
200
+ current_temperature_topic: act.Topic,
201
+ min_temp: target.min ? target.min : 0,
202
+ max_temp: target.max ? target.max : 40,
203
+ modes: ['auto', 'heat', 'off'],
204
+ precision: 0.5,
205
+ temp_step: 0.5,
206
+ };
207
+
208
+ // Assign Subscribed Topics
209
+ this.SubscribedTopics[target.Topic] = {};
210
+ this.SubscribedTopics[target.Topic].id = config.climateIds.target;
211
+ this.SubscribedTopics[target.Topic].val = await this.adapter.getState(config.climateIds.target).val;
212
+ this.SubscribedTopics[target.Topic].ts = Date.now() - this.MinTime;
213
+
214
+ this.SubscribedTopics[mode.Topic] = {};
215
+ this.SubscribedTopics[mode.Topic].id = config.climateIds.mode;
216
+ if (config.climateIds.mode.endsWith(this.EndingVirtualMode)) {
217
+ this.SubscribedTopics[mode.Topic].val = 'auto';
218
+ this.VitualIds[config.climateIds.mode] = this.SubscribedTopics[mode.Topic].val;
219
+ } else {
220
+ this.SubscribedTopics[mode.Topic].val = await this.adapter.getState(config.climateIds.mode).val;
221
+ }
222
+ this.SubscribedTopics[mode.Topic].ts = Date.now() - this.MinTime;
223
+
224
+ const DiscoveryObject = {
225
+ Topic: Topic,
226
+ topic: DiscoveryTopic,
227
+ payload: structuredClone(DiscoveryPayload),
228
+ };
229
+
230
+ // Assign published Topics
231
+ // Target
232
+ if (!this.PublishedIds[config.climateIds.target]) {
233
+ this.PublishedIds[config.climateIds.target] = { discovery: [] };
234
+ }
235
+ this.PublishedIds[config.climateIds.target].Topic = target.Topic;
236
+ this.PublishedIds[config.climateIds.target].discovery.push({
237
+ topic: DiscoveryTopic,
238
+ payload: structuredClone(DiscoveryPayload),
239
+ });
240
+ this.PublishedIds[config.climateIds.target].val = 0;
241
+ this.PublishedIds[config.climateIds.target].ts = Date.now();
242
+
243
+ // Act
244
+ if (!this.PublishedIds[config.climateIds.act]) {
245
+ this.PublishedIds[config.climateIds.act] = { discovery: [] };
246
+ }
247
+ this.PublishedIds[config.climateIds.act].Topic = act.Topic;
248
+ this.PublishedIds[config.climateIds.act].discovery.push({
249
+ topic: DiscoveryTopic,
250
+ payload: structuredClone(DiscoveryPayload),
251
+ });
252
+ this.PublishedIds[config.climateIds.act].val = 0;
253
+ this.PublishedIds[config.climateIds.act].ts = Date.now();
254
+
255
+ // Mode
256
+ if (!this.PublishedIds[config.climateIds.mode]) {
257
+ this.PublishedIds[config.climateIds.mode] = { discovery: [] };
258
+ }
259
+ this.PublishedIds[config.climateIds.mode].Topic = mode.Topic;
260
+ this.PublishedIds[config.climateIds.mode].discovery.push({
261
+ topic: DiscoveryTopic,
262
+ payload: structuredClone(DiscoveryPayload),
263
+ });
264
+ this.PublishedIds[config.climateIds.mode].val = 0;
265
+ this.PublishedIds[config.climateIds.mode].ts = Date.now();
266
+
267
+ // Publishing the discover message
268
+ await this.publishDiscovery(Id, {
269
+ topic: DiscoveryObject?.topic,
270
+ payload: structuredClone(DiscoveryObject.payload),
271
+ });
272
+ await this.publishId(config.climateIds.target, this.SubscribedTopics[target.Topic].val);
273
+ await this.publishId(config.climateIds.act, await this.adapter.getState(config.climateIds.act).val);
274
+ await this.publishId(config.climateIds.mode, this.SubscribedTopics[mode.Topic].val);
275
+ }
276
+ }
277
+ } catch (error) {
278
+ this.adapter.log.error(`error at ${activeFunction}: ${error}`);
279
+ }
280
+ }
281
+
282
+ /*********************************************************************
283
+ * ****************** generate Climate Ids ***************************
284
+ * ******************************************************************/
285
+
286
+ /**
287
+ * @param config Configuration of the climate entity, wich is to genereate
288
+ */
289
+ async generateClimateIds(config) {
290
+ const activeFunction = 'generateClimateIds';
291
+ this.adapter.log.debug(`Function ${activeFunction} started.`);
292
+ try {
293
+ const climateIds = { target: '', act: '', mode: '' };
294
+ climateIds.target = `${config.TargetApplication}.devices.${config.TargetDevice}.${config.TargetFolder}.${config.TargetState}`;
295
+ climateIds.act = `${config.ActApplication}.devices.${config.ActDevice}.${config.ActFolder}.${config.ActState}`;
296
+ if (config.ModeApplication === 'NotPresent') {
297
+ climateIds.mode = `${climateIds.target}${this.EndingVirtualMode}`;
298
+ } else {
299
+ climateIds.mode = `${config.ModeApplication}.devices.${config.ModeDevice}.${config.ModeFolder}.${config.ModeState}`;
300
+ }
301
+ for (const id of Object.values(climateIds)) {
302
+ if (!(await this.adapter.objectExists(id)) && !id.endsWith(this.EndingVirtualMode)) {
303
+ return false;
304
+ }
305
+ }
306
+ if (config.ClimateName === '') {
307
+ return false;
308
+ }
309
+ const indexOfSpace = config.ClimateName.indexOf(' ');
310
+ if (indexOfSpace > 0) {
311
+ config.ClimateName = config.ClimateName.substring(0, indexOfSpace);
312
+ }
313
+ config.climateIds = climateIds;
314
+ return true;
315
+ } catch (error) {
316
+ this.adapter.log.error(`error at ${activeFunction}: ${error}`);
317
+ }
318
+ }
319
+
320
+ /*********************************************************************
321
+ * ********************* Publish zur Bridge **************************
102
322
  * ******************************************************************/
103
323
 
104
324
  /**
@@ -106,10 +326,10 @@ class bridgeClass {
106
326
  * @param val Value of the used Id
107
327
  */
108
328
  async publishId(id, val) {
109
- const activeFunction = 'bridge.js - publish';
329
+ const activeFunction = 'bridge.js - publishId';
110
330
  this.adapter.log.debug(`Function ${activeFunction} started.`);
111
331
  try {
112
- if (this.PulishedIds[id]) {
332
+ if (this.PublishedIds[id]) {
113
333
  if (val === undefined) {
114
334
  const State = await this.adapter.getState(id);
115
335
  if (State) {
@@ -117,16 +337,21 @@ class bridgeClass {
117
337
  }
118
338
  }
119
339
  if (
120
- !this.SubscribedTopics[this.PulishedIds[id].Topic] ||
121
- this.SubscribedTopics[this.PulishedIds[id].Topic].val !== val ||
122
- Date.now() - this.SubscribedTopics[this.PulishedIds[id].Topic].ts > this.MinTime
340
+ !this.SubscribedTopics[this.PublishedIds[id].Topic] ||
341
+ this.SubscribedTopics[this.PublishedIds[id].Topic].val !== val ||
342
+ Date.now() - this.SubscribedTopics[this.PublishedIds[id].Topic].ts >= this.MinTime
123
343
  ) {
124
- this.PulishedIds[id].ts = Date.now();
125
- this.PulishedIds[id].val = val;
126
- await this.bridgeMqttClient.publish(this.PulishedIds[id].Topic, JSON.stringify(val), {
344
+ this.PublishedIds[id].ts = Date.now();
345
+ this.PublishedIds[id].val = val;
346
+ if (typeof val !== 'string') {
347
+ val = JSON.stringify(val);
348
+ }
349
+ await this.bridgeMqttClient.publish(this.PublishedIds[id].Topic, val, {
127
350
  retain: true,
128
351
  });
129
352
  }
353
+ } else {
354
+ this.adapter.log.debug(`Id not for publish used.`);
130
355
  }
131
356
  } catch (error) {
132
357
  this.adapter.log.error(`error at ${activeFunction}: ${error}`);
@@ -138,7 +363,7 @@ class bridgeClass {
138
363
  * @param options Options for using spezial fuctions
139
364
  */
140
365
  async buildDiscovery(id, options) {
141
- const activeFunction = 'bridge.js - publbuildDiscoveryish';
366
+ const activeFunction = 'bridge.js - buildDiscovery';
142
367
  this.adapter.log.debug(`Function ${activeFunction} started.`);
143
368
  try {
144
369
  // Query for decoded Folder
@@ -172,17 +397,27 @@ class bridgeClass {
172
397
  options.Bridgestate = Bridgestate;
173
398
  const DiscoveryObject = await this.getDiscoveryObject(changeInfo, options);
174
399
  if (Bridgestate.publish) {
175
- this.PulishedIds[id] = DiscoveryObject;
176
- this.PulishedIds[id].val = 0;
177
- this.PulishedIds[id].ts = Date.now();
400
+ if (!this.PublishedIds[id]) {
401
+ this.PublishedIds[id] = { discovery: [] };
402
+ }
403
+ this.PublishedIds[id].Topic = DiscoveryObject?.Topic;
404
+ this.PublishedIds[id].discovery.push({
405
+ topic: DiscoveryObject?.topic,
406
+ payload: structuredClone(DiscoveryObject?.payload),
407
+ });
408
+ this.PublishedIds[id].val = 0;
409
+ this.PublishedIds[id].ts = Date.now();
178
410
  }
179
411
  if (Bridgestate.subscribe) {
180
412
  this.SubscribedTopics[DiscoveryObject?.Topic] = {};
181
413
  this.SubscribedTopics[DiscoveryObject?.Topic].id = id;
182
414
  this.SubscribedTopics[DiscoveryObject?.Topic].val = 0;
183
- this.SubscribedTopics[DiscoveryObject?.Topic].ts = Date.now();
415
+ this.SubscribedTopics[DiscoveryObject?.Topic].ts = Date.now() - this.MinTime;
184
416
  }
185
- await this.publishDiscovery(id, DiscoveryObject);
417
+ await this.publishDiscovery(id, {
418
+ topic: DiscoveryObject?.topic,
419
+ payload: structuredClone(DiscoveryObject?.payload),
420
+ });
186
421
  }
187
422
  }
188
423
 
@@ -220,19 +455,30 @@ class bridgeClass {
220
455
  options.Bridgestate = Bridgestate;
221
456
  const DiscoveryObject = await this.getDiscoveryObject(changeInfo, options);
222
457
  if (Bridgestate.publish) {
223
- this.PulishedIds[id] = DiscoveryObject;
458
+ if (!this.PublishedIds[id]) {
459
+ this.PublishedIds[id] = { discovery: [] };
460
+ }
461
+ this.PublishedIds[id].Topic = DiscoveryObject?.Topic;
462
+ this.PublishedIds[id].discovery.push({
463
+ topic: DiscoveryObject?.topic,
464
+ payload: structuredClone(DiscoveryObject?.payload),
465
+ });
466
+ this.PublishedIds[id].val = 0;
467
+ this.PublishedIds[id].ts = Date.now();
224
468
  }
225
469
  if (Bridgestate.subscribe) {
226
470
  this.SubscribedTopics[DiscoveryObject?.Topic] = {};
227
471
  this.SubscribedTopics[DiscoveryObject?.Topic].id = id;
228
472
  this.SubscribedTopics[DiscoveryObject?.Topic].val = 0;
229
- this.SubscribedTopics[DiscoveryObject?.Topic].ts = Date.now();
473
+ this.SubscribedTopics[DiscoveryObject?.Topic].ts = Date.now() - this.MinTime;
230
474
  }
231
- await this.publishDiscovery(id, DiscoveryObject);
475
+ await this.publishDiscovery(id, {
476
+ topic: DiscoveryObject?.topic,
477
+ payload: structuredClone(DiscoveryObject?.payload),
478
+ });
232
479
  }
233
480
  }
234
481
  }
235
- this.CheckedIds[id] = {};
236
482
  } catch (error) {
237
483
  this.adapter.log.error(`error at ${activeFunction}: ${error}`);
238
484
  }
@@ -277,7 +523,7 @@ class bridgeClass {
277
523
  for (const Attribute in AdditionalAttributes) {
278
524
  DiscoveryPayload[Attribute] = AdditionalAttributes[Attribute];
279
525
  }
280
- return { Topic: Topic, DiscoveryTopic: DiscoveryTopic, DiscoveryPayload: DiscoveryPayload };
526
+ return { Topic: Topic, topic: DiscoveryTopic, payload: DiscoveryPayload };
281
527
  } catch (error) {
282
528
  this.adapter.log.error(`error at ${activeFunction}: ${error}`);
283
529
  }
@@ -296,11 +542,9 @@ class bridgeClass {
296
542
  this.adapter.log.debug(`Function ${activeFunction} started.`);
297
543
  try {
298
544
  this.DiscoveredIds[id] = DiscoveryObject;
299
- await this.bridgeMqttClient.publish(
300
- DiscoveryObject.DiscoveryTopic,
301
- JSON.stringify(DiscoveryObject.DiscoveryPayload),
302
- {},
303
- );
545
+ await this.bridgeMqttClient.publish(DiscoveryObject.topic, JSON.stringify(DiscoveryObject.payload), {
546
+ retain: true,
547
+ });
304
548
  await this.adapter.setState('info.discoveredIds', JSON.stringify(this.DiscoveredIds), true);
305
549
  } catch (error) {
306
550
  this.adapter.log.error(`error at ${activeFunction}: ${error}`);
@@ -619,6 +863,7 @@ class bridgeClass {
619
863
  }
620
864
  }
621
865
  }
866
+ await this.discoverClimate();
622
867
  } catch (error) {
623
868
  this.adapter.log.error(`error at ${activeFunction}: ${error}`);
624
869
  }
@@ -480,7 +480,7 @@ class directorieshandlerClass {
480
480
  });
481
481
  // Add Bridged Funktion (MQTT auto discovery)
482
482
  // Add for new state
483
- await this.adapter.bridge.work(objectId, stateVal, { common: common });
483
+ await this.adapter.bridge?.work(objectId, stateVal, { common: common });
484
484
  if (typeof stateVal === 'object') {
485
485
  stateVal = JSON.stringify(stateVal);
486
486
  }
@@ -136,7 +136,9 @@ class messagehandlerClass {
136
136
  const adapterObjectsAtStart = await this.adapter.getAdapterObjectsAsync();
137
137
  for (const adapterObject of Object.values(adapterObjectsAtStart)) {
138
138
  if (adapterObject.type === 'device') {
139
- await this.fillWithDownlinkConfig(this.adapter.removeNamespace(adapterObject._id), {});
139
+ await this.fillWithDownlinkConfig(this.adapter.removeNamespace(adapterObject._id), {
140
+ startup: true,
141
+ });
140
142
  //await this.addDirectoriesToPresentDirectory(`${stateId}`); Not used yet (Maybe for thefuture with more folders)
141
143
  }
142
144
  }
@@ -524,6 +526,11 @@ class messagehandlerClass {
524
526
  if (downlinkDevice !== this.adapter.downlinkConfighandler.internalDevices.baseDevice) {
525
527
  foundLength[downlinkParameter.name] = downlinkDevice.length;
526
528
  }
529
+ // Add Bridged Funktion (MQTT auto discovery) only in Message
530
+ if (!options?.startup) {
531
+ await this.adapter.bridge?.work(stateId, undefined, { common: common });
532
+ }
533
+
527
534
  //check for right type of data (after a possible change)
528
535
  if (!options || !options.inMessage) {
529
536
  const state = await this.adapter.getStateAsync(stateId);
package/main.js CHANGED
@@ -931,10 +931,21 @@ class Lorawan extends utils.Adapter {
931
931
  }
932
932
 
933
933
  // send application to config
934
- } else if (obj.command === 'getApplicationsForConfig') {
934
+ } else if (
935
+ obj.command === 'getApplicationsForConfig' ||
936
+ obj.command === 'getApplicationsForClimateConfig' ||
937
+ obj.command === 'getApplicationsForClimateModeConfig'
938
+ ) {
935
939
  try {
936
- let myCount = 1;
937
- const applications = [{ label: '* (Wildcard)', value: '*' }];
940
+ let myCount = 0;
941
+ const applications = [];
942
+ if (obj.command === 'getApplicationsForConfig') {
943
+ applications[myCount] = { label: '* (Wildcard)', value: '*' };
944
+ myCount++;
945
+ } else if (obj.command === 'getApplicationsForClimateModeConfig') {
946
+ applications[myCount] = { label: '* Not Present (Virtual)', value: 'NotPresent' };
947
+ myCount++;
948
+ }
938
949
  const currentApplications = {};
939
950
  const adapterObjects = await this.getAdapterObjectsAsync();
940
951
  for (const adapterObject of Object.values(adapterObjects)) {
@@ -955,10 +966,14 @@ class Lorawan extends utils.Adapter {
955
966
  } catch (error) {
956
967
  this.log.error(error);
957
968
  }
958
- } else if (obj.command === 'getDevicesForConfig') {
969
+ } else if (obj.command === 'getDevicesForConfig' || obj.command === 'getDevicesForClimateConfig') {
959
970
  try {
960
- let myCount = 1;
961
- const devices = [{ label: '* (Wildcard)', value: '*' }];
971
+ let myCount = 0;
972
+ const devices = [];
973
+ if (obj.command === 'getDevicesForConfig') {
974
+ devices[myCount] = { label: '* (Wildcard)', value: '*' };
975
+ myCount++;
976
+ }
962
977
  const adapterObjects = await this.getAdapterObjectsAsync();
963
978
  for (const adapterObject of Object.values(adapterObjects)) {
964
979
  if (
@@ -991,10 +1006,14 @@ class Lorawan extends utils.Adapter {
991
1006
  } catch (error) {
992
1007
  this.log.error(error);
993
1008
  }
994
- } else if (obj.command === 'getStatesForConfig') {
1009
+ } else if (obj.command === 'getStatesForConfig' || obj.command === 'getStatesForClimateConfig') {
995
1010
  try {
996
- let myCount = 1;
997
- const states = [{ label: '* (Wildcard)', value: '*' }];
1011
+ let myCount = 0;
1012
+ const states = [];
1013
+ if (obj.command === 'getDevicesForConfig') {
1014
+ states[myCount] = { label: '* (Wildcard)', value: '*' };
1015
+ myCount++;
1016
+ }
998
1017
  const currentStates = {};
999
1018
  const adapterObjects = await this.getAdapterObjectsAsync();
1000
1019
  for (const adapterObject of Object.values(adapterObjects)) {
@@ -1035,6 +1054,39 @@ class Lorawan extends utils.Adapter {
1035
1054
  } catch (error) {
1036
1055
  this.log.error(error);
1037
1056
  }
1057
+ } else if (obj.command === 'getDiscoveredIds') {
1058
+ try {
1059
+ this.sendTo(
1060
+ obj.from,
1061
+ obj.command,
1062
+ JSON.stringify(this.bridge?.DiscoveredIds, null, 2),
1063
+ obj.callback,
1064
+ );
1065
+ } catch (error) {
1066
+ this.log.error(error);
1067
+ }
1068
+ } else if (obj.command === 'getPublishedIds') {
1069
+ try {
1070
+ this.sendTo(
1071
+ obj.from,
1072
+ obj.command,
1073
+ JSON.stringify(this.bridge?.PublishedIds, null, 2),
1074
+ obj.callback,
1075
+ );
1076
+ } catch (error) {
1077
+ this.log.error(error);
1078
+ }
1079
+ } else if (obj.command === 'getSubscribedTopics') {
1080
+ try {
1081
+ this.sendTo(
1082
+ obj.from,
1083
+ obj.command,
1084
+ JSON.stringify(this.bridge?.SubscribedTopics, null, 2),
1085
+ obj.callback,
1086
+ );
1087
+ } catch (error) {
1088
+ this.log.error(error);
1089
+ }
1038
1090
  } else {
1039
1091
  const result = { error: true, message: 'No message matched', received: obj.message };
1040
1092
  if (obj.callback) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lorawan",
3
- "version": "1.13.4",
3
+ "version": "1.13.6",
4
4
  "description": "converts the desired lora gateway data to a ioBroker structure",
5
5
  "author": {
6
6
  "name": "BenAhrdt",