iobroker.lorawan 1.15.8 → 1.16.0

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,9 @@ 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.16.0 (2025-09-16)
27
+ * (BenAhrdt) possibility to insert foreign states to bridge by using enum.functions.bridge
28
+
26
29
  ### 1.15.8 (2025-09-16)
27
30
  * (BenAhrdt) remove await from some callings
28
31
 
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "lorawan",
4
- "version": "1.15.8",
4
+ "version": "1.16.0",
5
5
  "news": {
6
+ "1.16.0": {
7
+ "en": "possibility to insert foreign states to bridge by using enum.functions.bridge",
8
+ "de": "Möglichkeit, externe Zustände über enum.functions.bridge in die Bridge einzufügen.",
9
+ "ru": "Возможность вставки внешних состояний в мост путем использования enum.functions.bridge",
10
+ "pt": "possibilidade de inserir estados estrangeiros na ponte usando enum.functions.bridge",
11
+ "nl": "Mogelijkheid om externe toestanden in de brug in te voegen door gebruik te maken van enum.functions.bridge.",
12
+ "fr": "possibilité d'insérer des états étrangers dans le pont en utilisant enum.functions.bridge",
13
+ "it": "Possibilità di inserire stati esterni al bridge utilizzando enum.functions.bridge",
14
+ "es": "Posibilidad de insertar estados extranjeros en el puente utilizando enum.functions.bridge",
15
+ "pl": "możliwość wstawienia stanów zewnętrznych do mostka za pomocą enum.functions.bridge",
16
+ "uk": "Можливість додавання зовнішніх станів до моста за допомогою enum.functions.bridge",
17
+ "zh-cn": "通过使用enum.functions.bridge功能,可以将外部状态插入到桥接器中。"
18
+ },
6
19
  "1.15.8": {
7
20
  "en": "remove await from some callings",
8
21
  "de": "Entferne das „await“ aus einigen Aufrufen.",
@@ -80,19 +93,6 @@
80
93
  "pl": "nie tłumacz stanu \"selected\" w konfiguracji mostu",
81
94
  "uk": "не перекладайте обраний стан в конфігурації моста",
82
95
  "zh-cn": "不要将“selected state”翻译成桥接配置"
83
- },
84
- "1.15.2": {
85
- "en": "change wording of notifications\nimport diagnostic and config fpr entity_type\nchange extSernsorTemperature in ExtSernsorTemperature",
86
- "de": "Änderung der Benachrichtigungen\nDiagnose und konfiguriere entity_type\nÄndern von extSernsorTemperature in ExtSernsorTemperature",
87
- "ru": "изменить формулировку уведомлений\nИсправление диагностики и конфигурации для типа entity\nИзменено extSernsorTemperature на ExtSernsorTemperature",
88
- "pt": "alterar a redação das notificações\nimportação de diagnóstico e configuração para o tipo de entidade\nAlterar extSernsorTemperature para ExtSernsorTemperature",
89
- "nl": "wijziging van meldingen\nimport diagnose en configuratie voor entity_type\nVerander extSernsorTemperature in ExtSernsorTemperature",
90
- "fr": "modifier le libellé des notifications\nImporter le diagnostic et la configuration pour le type d'entité\nChanger extSernsorTemperature en ExtSernsorTemperature",
91
- "it": "modificare i testi delle notifiche\nimport diagnostiche e configurazioni per il tipo di entità\nModifica extSernsorTemperature in ExtSernsorTemperature",
92
- "es": "cambiar la redacción de las notificaciones\nimportar diagnóstico y configuración para el tipo de entidad\nCambiar extSensorTemperature a ExtSensorTemperature",
93
- "pl": "zmień sformułowanie powiadomień\nimport diagnostyka i konfiguracja dla entity_type\nzmień extSensorTemperature na ExtSensorTemperature",
94
- "uk": "змінити формулювання сповіщень\nімпорт діагнострики та конфігурації для типу entity\nЗміна extSensorTemperature на ExtSensorTemperature",
95
- "zh-cn": "更改通知内容\n为entity_type添加诊断和配置\n将\"extSensorTemperature\"更改为\"ExtSensorTemperature\""
96
96
  }
97
97
  },
98
98
  "titleLang": {
@@ -70,7 +70,7 @@ class bridgeClass {
70
70
  second: '2-digit',
71
71
  },
72
72
  };
73
-
73
+ this.ids = {};
74
74
  // Unitmapping zur Zuweisung der passenden Unit, wenn diese falsch geschrieben ist
75
75
  this.unitMap = {
76
76
  '°C': { device_class: 'temperature' },
@@ -207,7 +207,12 @@ class bridgeClass {
207
207
  await this.publishId(this.SubscribedTopics[topic].id, message, {});
208
208
  return;
209
209
  }
210
- await this.adapter.setState(this.SubscribedTopics[topic].id, message);
210
+ // Check for namespace and write own, oder foreign state
211
+ if (this.SubscribedTopics[topic].id.startsWith(this.adapter.namespace)) {
212
+ await this.adapter.setState(this.SubscribedTopics[topic].id, message);
213
+ } else {
214
+ await this.adapter.setForeignStateAsync(this.SubscribedTopics[topic].id, message);
215
+ }
211
216
  await this.adapter.setState('info.subscribedTopics', JSON.stringify(this.DiscoveredIds), true);
212
217
  } else {
213
218
  this.adapter.log.debug(`The received Topic ${topic} is not subscribed`);
@@ -226,8 +231,6 @@ class bridgeClass {
226
231
  const activeFunction = 'bridge.js - work';
227
232
  this.adapter.log.debug(`Function ${activeFunction} started.`);
228
233
  try {
229
- // First remove namespace from id
230
- id = this.adapter.removeNamespace(id);
231
234
  if (this.bridgeMqttClient.internalConnectionstate) {
232
235
  const countBefore = Object.keys(this.DiscoveredIds).length;
233
236
  await this.discovery(id, options);
@@ -293,7 +296,7 @@ class bridgeClass {
293
296
  const activeFunction = 'discoverDeviceNotifications';
294
297
  this.adapter.log.debug(`Function ${activeFunction} started.`);
295
298
  try {
296
- const notificationId = `${changeInfo.objectStartDirectory}${this.NotificationId}${this.GeneralId}`;
299
+ const notificationId = `${this.adapter.namespace}.${changeInfo.objectStartDirectory}${this.NotificationId}${this.GeneralId}`;
297
300
  if (!this.Notifications[notificationId]) {
298
301
  const deviceIdentifier = this.getDeviceIdentifier(changeInfo, this.adapter.config.DeviceIdentifiers);
299
302
  const normalizedDeviceIdentifier = this.normalizeString(deviceIdentifier);
@@ -319,7 +322,7 @@ class bridgeClass {
319
322
  // offline
320
323
  const offline = {
321
324
  topic: `${this.bridgeMqttClient.BridgePrefix}${normalizedDeviceIdentifier}/${this.Words.notification}_${this.Words.offline}${this.EndingState}`.toLowerCase(),
322
- notificationId: `${changeInfo.objectStartDirectory}${this.NotificationId}${this.OfflineId}`,
325
+ notificationId: `${this.adapter.namespace}.${changeInfo.objectStartDirectory}${this.NotificationId}${this.OfflineId}`,
323
326
  };
324
327
  discoveryobject = this.getNotificationDiscoveryObject(deviceIdentifier, this.Words.offline);
325
328
  this.Notifications[offline.notificationId] = {};
@@ -339,7 +342,7 @@ class bridgeClass {
339
342
  // online
340
343
  const online = {
341
344
  topic: `${this.bridgeMqttClient.BridgePrefix}${normalizedDeviceIdentifier}/${this.Words.notification}_${this.Words.online}${this.EndingState}`.toLowerCase(),
342
- notificationId: `${changeInfo.objectStartDirectory}${this.NotificationId}${this.OnlineId}`,
345
+ notificationId: `${this.adapter.namespace}.${changeInfo.objectStartDirectory}${this.NotificationId}${this.OnlineId}`,
343
346
  };
344
347
  discoveryobject = this.getNotificationDiscoveryObject(deviceIdentifier, this.Words.online);
345
348
  this.Notifications[online.notificationId] = {};
@@ -372,7 +375,7 @@ class bridgeClass {
372
375
  const activeFunction = 'discoverGeneralNotification';
373
376
  this.adapter.log.debug(`Function ${activeFunction} started.`);
374
377
  try {
375
- const notificationId = `${this.Words.notification}${this.GeneralId}`;
378
+ const notificationId = `${this.adapter.namespace}.${this.Words.notification}${this.GeneralId}`;
376
379
  if (!this.Notifications[notificationId]) {
377
380
  const discoveryobject = this.getNotificationDiscoveryObject(this.adapter.namespace, this.Words.general);
378
381
  this.Notifications[notificationId] = {};
@@ -638,12 +641,12 @@ class bridgeClass {
638
641
  this.adapter.log.debug(`Function ${activeFunction} started.`);
639
642
  try {
640
643
  const climateIds = { target: '', act: '', mode: '' };
641
- climateIds.target = `${config.TargetApplication}.devices.${config.TargetDevice}.${config.TargetFolder}.${config.TargetState}`;
642
- climateIds.act = `${config.ActApplication}.devices.${config.ActDevice}.${config.ActFolder}.${config.ActState}`;
644
+ climateIds.target = `${this.adapter.namespace}.${config.TargetApplication}.devices.${config.TargetDevice}.${config.TargetFolder}.${config.TargetState}`;
645
+ climateIds.act = `${this.adapter.namespace}.${config.ActApplication}.devices.${config.ActDevice}.${config.ActFolder}.${config.ActState}`;
643
646
  if (config.ModeApplication === 'NotPresent') {
644
- climateIds.mode = `${config.TargetApplication}.devices.${config.TargetDevice}.${config.TargetFolder}${this.EndingVirtualMode}`;
647
+ climateIds.mode = `${this.adapter.namespace}.${config.TargetApplication}.devices.${config.TargetDevice}.${config.TargetFolder}${this.EndingVirtualMode}`;
645
648
  } else {
646
- climateIds.mode = `${config.ModeApplication}.devices.${config.ModeDevice}.${config.ModeFolder}.${config.ModeState}`;
649
+ climateIds.mode = `${this.adapter.namespace}.${config.ModeApplication}.devices.${config.ModeDevice}.${config.ModeFolder}.${config.ModeState}`;
647
650
  }
648
651
  for (const id of Object.values(climateIds)) {
649
652
  if (!(await this.adapter.objectExists(id)) && !id.endsWith(this.EndingVirtualMode)) {
@@ -724,7 +727,7 @@ class bridgeClass {
724
727
  val = State.val;
725
728
  }
726
729
  }
727
- // safe old values (10 last values)
730
+ // safe old values (5 last values)
728
731
  if (this.PublishedIds[id].values) {
729
732
  if (!this.PublishedIds[id].oldValues) {
730
733
  this.PublishedIds[id].oldValues = [];
@@ -786,7 +789,7 @@ class bridgeClass {
786
789
  (changeInfo.applicationId === config.Application || config.Application === '*') &&
787
790
  (changeInfo.deviceEUI === config.Device || config.Device === '*') &&
788
791
  (id.includes(`.${config.Folder}.`) || config.Folder === '*') &&
789
- (id.endsWith(`.${config.Folder}.${config.State}`) || config.State === '*')
792
+ (id.endsWith(`.decoded.${config.State}`) || config.State === '*')
790
793
  ) {
791
794
  Bridgestate.discover = !config.exclude;
792
795
  Bridgestate.publish = config.publish;
@@ -852,7 +855,7 @@ class bridgeClass {
852
855
  (changeInfo.applicationId === config.Application || config.Application === '*') &&
853
856
  (changeInfo.deviceEUI === config.Device || config.Device === '*') &&
854
857
  (id.includes(`.${config.Folder}.`) || config.Folder === '*') &&
855
- (id.endsWith(`.${config.Folder}.${config.State}`) || config.State === '*')
858
+ (id.endsWith(`.control.${config.State}`) || config.State === '*')
856
859
  ) {
857
860
  Bridgestate.discover = !config.exclude;
858
861
  Bridgestate.publish = config.publish;
@@ -1390,6 +1393,7 @@ class bridgeClass {
1390
1393
  }
1391
1394
  await this.discoverClimate();
1392
1395
  await this.discoverGeneralNotification();
1396
+ await this.getForeignStatesForStandardEntities();
1393
1397
  } catch (error) {
1394
1398
  this.adapter.log.error(`error at ${activeFunction}: ${error}`);
1395
1399
  }
@@ -1441,5 +1445,153 @@ class bridgeClass {
1441
1445
  this.adapter.log.error(`error at ${activeFunction}: ${error}`);
1442
1446
  }
1443
1447
  }
1448
+
1449
+ /*****************************************************************
1450
+ * *********************** Foreign functions *********************
1451
+ * **************************************************************/
1452
+ /**
1453
+ * get Foreign states for Bridge
1454
+ */
1455
+ async getForeignStatesForStandardEntities() {
1456
+ const activeFunction = 'bridge.js - getForeignStatesForStandardEntities';
1457
+ this.adapter.log.debug(`Function ${activeFunction} started.`);
1458
+ try {
1459
+ const functions = await this.adapter.getEnums('functions');
1460
+ if (functions['enum.functions']['enum.functions.bridge']) {
1461
+ for (const member of functions['enum.functions']['enum.functions.bridge'].common.members) {
1462
+ const params = {
1463
+ startkey: member,
1464
+ endkey: `${member}.\u9999`,
1465
+ };
1466
+ const states = await this.adapter.getObjectViewAsync('system', 'state', params);
1467
+ for (const state of states.rows) {
1468
+ const common = state.value.common;
1469
+ await this.discoverForeignStandardEntity(state.id, { common: common });
1470
+ }
1471
+ }
1472
+ }
1473
+ } catch (error) {
1474
+ this.adapter.log.error(`error at ${activeFunction}: ${error}`);
1475
+ }
1476
+ }
1477
+
1478
+ /**
1479
+ * @param id id to discover foreign state
1480
+ * @param options options of foreign state
1481
+ */
1482
+ async discoverForeignStandardEntity(id, options) {
1483
+ const activeFunction = 'bridge.js - discoverForeignStandardEntity';
1484
+ this.adapter.log.debug(`Function ${activeFunction} started.`);
1485
+ try {
1486
+ const state = await this.adapter.getForeignStateAsync(id);
1487
+ const parentObject = await this.getParentObject(id);
1488
+ let partentId = '';
1489
+ let parentName = '';
1490
+ if (typeof parentObject === 'object') {
1491
+ partentId = parentObject._id;
1492
+ parentName = parentObject.common.name;
1493
+ } else {
1494
+ partentId = parentObject;
1495
+ parentName = partentId;
1496
+ }
1497
+ const deviceIdentifier = parentName;
1498
+ const statename = id.substring(partentId.length + 1, id.length);
1499
+ options.Bridgestate = {
1500
+ publish: options.common.read,
1501
+ subscribe: options.common.write,
1502
+ };
1503
+ const normalizedStateName = this.normalizeString(statename);
1504
+ const normalizedDeviceIdentifier = this.normalizeString(deviceIdentifier);
1505
+ const topic =
1506
+ `${this.bridgeMqttClient.BridgePrefix}${normalizedDeviceIdentifier}/${normalizedStateName}`.toLowerCase();
1507
+ const EntityType = await this.getEntityType(options);
1508
+ const AdditionalAttributes = await this.getStateAttributes(options.common, EntityType);
1509
+ const discoveryTopic =
1510
+ `${this.BridgeDiscoveryPrefix[this.adapter.config.BridgeType]}${EntityType}/${normalizedDeviceIdentifier}/${normalizedStateName}/config`.toLowerCase();
1511
+ const discoveryPayload = {
1512
+ name: statename,
1513
+ unique_id: `${normalizedDeviceIdentifier}_${normalizedStateName}`.toLowerCase(),
1514
+ device: { identifiers: [normalizedDeviceIdentifier.toLowerCase()], name: deviceIdentifier },
1515
+ };
1516
+ // Add Topics
1517
+ if (options.Bridgestate.publish) {
1518
+ discoveryPayload.state_topic = `${topic}${this.EndingState}`;
1519
+ }
1520
+ if (options.Bridgestate.subscribe) {
1521
+ discoveryPayload.command_topic = `${topic}${this.EndingSet}`;
1522
+ }
1523
+
1524
+ // Assign Attibute to Payload
1525
+ for (const Attribute in AdditionalAttributes) {
1526
+ discoveryPayload[Attribute] = AdditionalAttributes[Attribute];
1527
+ }
1528
+
1529
+ if (options.Bridgestate.publish) {
1530
+ if (!this.PublishedIds[id]) {
1531
+ this.PublishedIds[id] = { discovery: [] };
1532
+ }
1533
+ this.PublishedIds[id].discovery.push({
1534
+ topic: discoveryTopic,
1535
+ payload: structuredClone(discoveryPayload),
1536
+ });
1537
+ this.PublishedIds[id].state_topic = discoveryPayload.state_topic;
1538
+ }
1539
+ if (options.Bridgestate.subscribe) {
1540
+ if (!this.SubscribedTopics[discoveryPayload.command_topic]) {
1541
+ this.SubscribedTopics[discoveryPayload.command_topic] = { discovery: [] };
1542
+ }
1543
+ this.SubscribedTopics[discoveryPayload.command_topic].discovery.push({
1544
+ topic: discoveryTopic,
1545
+ payload: structuredClone(discoveryPayload),
1546
+ });
1547
+ this.SubscribedTopics[discoveryPayload.command_topic].id = id;
1548
+ }
1549
+ await this.publishDiscovery(id, {
1550
+ topic: discoveryTopic,
1551
+ payload: structuredClone(discoveryPayload),
1552
+ });
1553
+ // Delay for publish new entity
1554
+ setTimeout(async () => {
1555
+ await this.publishId(id, state.val, {});
1556
+ }, 1000);
1557
+ // Subscribe state for onStatechange mathode
1558
+ this.adapter.subscribeForeignStatesAsync(id);
1559
+ } catch (error) {
1560
+ this.adapter.log.error(`error at ${activeFunction}: ${error}`);
1561
+ }
1562
+ }
1563
+
1564
+ /**
1565
+ * @param id id to get parent Object
1566
+ */
1567
+ async getParentObject(id) {
1568
+ const activeFunction = 'bridge.js - getParentObject';
1569
+ this.adapter.log.debug(`Function ${activeFunction} started.`);
1570
+ try {
1571
+ const firstIdexOfDot = id.indexOf('.');
1572
+ const lastIdexOfDot = id.lastIndexOf('.');
1573
+ if (lastIdexOfDot > firstIdexOfDot + 3) {
1574
+ id = id.substring(0, lastIdexOfDot);
1575
+ const firstObj = await this.adapter.getForeignObjectAsync(id);
1576
+ if (!firstObj) {
1577
+ return undefined;
1578
+ }
1579
+ if (firstObj?.type === 'device') {
1580
+ return firstObj;
1581
+ }
1582
+ if (firstObj.type === 'channel') {
1583
+ const secondObj = await this.getParentObject(id);
1584
+ if (secondObj !== undefined) {
1585
+ return secondObj;
1586
+ }
1587
+ return firstObj;
1588
+ }
1589
+ return await this.getParentObject(id);
1590
+ }
1591
+ return id.substring(0, lastIdexOfDot);
1592
+ } catch (error) {
1593
+ this.adapter.log.error(`error at ${activeFunction}: ${error}`);
1594
+ }
1595
+ }
1444
1596
  }
1445
1597
  module.exports = bridgeClass;
package/main.js CHANGED
@@ -448,118 +448,151 @@ class Lorawan extends utils.Adapter {
448
448
  );
449
449
  }
450
450
  if (!state.ack) {
451
- // Check for downlink in id
452
- if (id.indexOf('.downlink.control.') !== -1) {
453
- // get information of the changing state
454
- const changeInfo = await this.getChangeInfo(id, { withBestMatch: true });
455
- const suffix = this.downlinkConfighandler?.getDownlinkTopicSuffix(changeInfo?.changedState);
456
- if (changeInfo?.changedState === 'push' || changeInfo?.changedState === 'replace') {
457
- const downlinkTopic = this.downlinkConfighandler?.getDownlinkTopic(changeInfo, suffix);
458
- try {
459
- if (JSON.parse(state.val)) {
460
- await this.sendDownlink(downlinkTopic, state.val, changeInfo);
461
- await this.bridge?.publishId(this.removeNamespace(id), state.val, {});
462
- await this.setState(id, state.val, true);
463
- }
464
- } catch (error) {
465
- this.log.warn(`Cant send invalid downlinks. Error: ${error}`);
466
- }
467
- } else if (changeInfo?.changedState === 'CustomSend') {
468
- if (state.val !== '') {
451
+ if (id.startsWith(this.namespace)) {
452
+ // Check for downlink in id
453
+ if (id.indexOf('.downlink.control.') !== -1) {
454
+ // get information of the changing state
455
+ const changeInfo = await this.getChangeInfo(id, { withBestMatch: true });
456
+ const suffix = this.downlinkConfighandler?.getDownlinkTopicSuffix(changeInfo?.changedState);
457
+ if (changeInfo?.changedState === 'push' || changeInfo?.changedState === 'replace') {
469
458
  const downlinkTopic = this.downlinkConfighandler?.getDownlinkTopic(changeInfo, suffix);
470
- const downlinkConfig =
471
- this.downlinkConfighandler?.activeDownlinkConfigs[
472
- changeInfo.bestMatchForDeviceType
473
- ];
474
- const Statevalues = state.val.split(',');
475
- const StateElements = {
476
- PayloadInHex: Statevalues[0].toUpperCase(),
477
- Port: Statevalues[1] ? parseInt(Statevalues[1]) : downlinkConfig.port,
478
- Confirmed: Statevalues[2]
479
- ? Statevalues[2] === 'true'
480
- ? true
481
- : false
482
- : downlinkConfig.confirmed,
483
- Priority: Statevalues[3] ? Statevalues[3] : downlinkConfig.priority,
484
- };
485
- // Query for righte type
486
- this.log.debug('The following values are detected at input of custom send state');
487
- for (const element of Object.values(StateElements)) {
488
- this.log.debug(typeof element);
489
- this.log.debug(element);
459
+ try {
460
+ if (JSON.parse(state.val)) {
461
+ await this.sendDownlink(downlinkTopic, state.val, changeInfo);
462
+ await this.bridge?.publishId(id, state.val, {});
463
+ await this.setState(id, state.val, true);
464
+ }
465
+ } catch (error) {
466
+ this.log.warn(`Cant send invalid downlinks. Error: ${error}`);
490
467
  }
491
- // Write into nextSend
492
- await this.writeNextSend(changeInfo, StateElements.PayloadInHex);
493
- if (
494
- !changeInfo?.bestMatchForDeviceType ||
495
- this.downlinkConfighandler?.activeDownlinkConfigs[changeInfo.bestMatchForDeviceType]
496
- .sendWithUplink === 'disabled'
497
- ) {
498
- const downlink = this.downlinkConfighandler?.getDownlink(
499
- {
500
- port: StateElements.Port,
501
- confirmed: StateElements.Confirmed,
502
- priority: StateElements.Priority,
503
- },
504
- StateElements.PayloadInHex,
468
+ } else if (changeInfo?.changedState === 'CustomSend') {
469
+ if (state.val !== '') {
470
+ const downlinkTopic = this.downlinkConfighandler?.getDownlinkTopic(
505
471
  changeInfo,
472
+ suffix,
506
473
  );
507
- if (downlink !== undefined) {
508
- await this.sendDownlink(downlinkTopic, JSON.stringify(downlink), changeInfo);
474
+ const downlinkConfig =
475
+ this.downlinkConfighandler?.activeDownlinkConfigs[
476
+ changeInfo.bestMatchForDeviceType
477
+ ];
478
+ const Statevalues = state.val.split(',');
479
+ const StateElements = {
480
+ PayloadInHex: Statevalues[0].toUpperCase(),
481
+ Port: Statevalues[1] ? parseInt(Statevalues[1]) : downlinkConfig.port,
482
+ Confirmed: Statevalues[2]
483
+ ? Statevalues[2] === 'true'
484
+ ? true
485
+ : false
486
+ : downlinkConfig.confirmed,
487
+ Priority: Statevalues[3] ? Statevalues[3] : downlinkConfig.priority,
488
+ };
489
+ // Query for righte type
490
+ this.log.debug('The following values are detected at input of custom send state');
491
+ for (const element of Object.values(StateElements)) {
492
+ this.log.debug(typeof element);
493
+ this.log.debug(element);
494
+ }
495
+ // Write into nextSend
496
+ await this.writeNextSend(changeInfo, StateElements.PayloadInHex);
497
+ if (
498
+ !changeInfo?.bestMatchForDeviceType ||
499
+ this.downlinkConfighandler?.activeDownlinkConfigs[
500
+ changeInfo.bestMatchForDeviceType
501
+ ].sendWithUplink === 'disabled'
502
+ ) {
503
+ const downlink = this.downlinkConfighandler?.getDownlink(
504
+ {
505
+ port: StateElements.Port,
506
+ confirmed: StateElements.Confirmed,
507
+ priority: StateElements.Priority,
508
+ },
509
+ StateElements.PayloadInHex,
510
+ changeInfo,
511
+ );
512
+ if (downlink !== undefined) {
513
+ await this.sendDownlink(
514
+ downlinkTopic,
515
+ JSON.stringify(downlink),
516
+ changeInfo,
517
+ );
518
+ }
509
519
  }
510
520
  }
511
- }
512
- await this.bridge?.publishId(this.removeNamespace(id), state.val, {});
513
- await this.setState(id, state.val, true);
514
- } else {
515
- const downlinkTopic = this.downlinkConfighandler?.getDownlinkTopic(changeInfo, suffix);
516
- const downlinkParameter = this.downlinkConfighandler?.getDownlinkParameter(changeInfo, {});
517
- if (downlinkParameter !== undefined) {
518
- const payloadInHex = this.downlinkConfighandler?.calculatePayloadInHex(
519
- downlinkParameter,
520
- state,
521
+ await this.bridge?.publishId(id, state.val, {});
522
+ await this.setState(id, state.val, true);
523
+ } else {
524
+ const downlinkTopic = this.downlinkConfighandler?.getDownlinkTopic(changeInfo, suffix);
525
+ const downlinkParameter = this.downlinkConfighandler?.getDownlinkParameter(
526
+ changeInfo,
527
+ {},
521
528
  );
522
- await this.writeNextSend(changeInfo, payloadInHex);
523
- if (
524
- !changeInfo?.bestMatchForDeviceType ||
525
- this.downlinkConfighandler?.activeDownlinkConfigs[changeInfo.bestMatchForDeviceType]
526
- .sendWithUplink === 'disabled'
527
- ) {
528
- const downlink = this.downlinkConfighandler?.getDownlink(
529
+ if (downlinkParameter !== undefined) {
530
+ const payloadInHex = this.downlinkConfighandler?.calculatePayloadInHex(
529
531
  downlinkParameter,
530
- payloadInHex,
531
- changeInfo,
532
+ state,
532
533
  );
533
- if (downlink !== undefined) {
534
- await this.sendDownlink(downlinkTopic, JSON.stringify(downlink), changeInfo);
534
+ await this.writeNextSend(changeInfo, payloadInHex);
535
+ if (
536
+ !changeInfo?.bestMatchForDeviceType ||
537
+ this.downlinkConfighandler?.activeDownlinkConfigs[
538
+ changeInfo.bestMatchForDeviceType
539
+ ].sendWithUplink === 'disabled'
540
+ ) {
541
+ const downlink = this.downlinkConfighandler?.getDownlink(
542
+ downlinkParameter,
543
+ payloadInHex,
544
+ changeInfo,
545
+ );
546
+ if (downlink !== undefined) {
547
+ await this.sendDownlink(
548
+ downlinkTopic,
549
+ JSON.stringify(downlink),
550
+ changeInfo,
551
+ );
552
+ }
535
553
  }
554
+ await this.bridge?.publishId(id, state.val, {});
555
+ await this.setState(id, state.val, true);
536
556
  }
537
- await this.bridge?.publishId(this.removeNamespace(id), state.val, {});
538
- await this.setState(id, state.val, true);
539
557
  }
540
- }
541
- } else if (id.indexOf('.configuration.') !== -1) {
542
- // State is from configuration path
543
- const changeInfo = await this.getChangeInfo(id, { withBestMatch: true });
544
- this.messagehandler?.fillWithDownlinkConfig(changeInfo?.objectStartDirectory, {});
558
+ } else if (id.indexOf('.configuration.') !== -1) {
559
+ // State is from configuration path
560
+ const changeInfo = await this.getChangeInfo(id, { withBestMatch: true });
561
+ this.messagehandler?.fillWithDownlinkConfig(changeInfo?.objectStartDirectory, {});
545
562
 
546
- // remove not configed states
547
- const adapterObjects = await this.getAdapterObjectsAsync();
548
- for (const adapterObject of Object.values(adapterObjects)) {
549
- if (
550
- adapterObject.type === 'state' &&
551
- adapterObject._id.indexOf(`${changeInfo?.objectStartDirectory}.downlink.control`) !== -1
552
- ) {
553
- const changeInfo = await this.getChangeInfo(adapterObject._id);
554
- const downlinkParameter = this.downlinkConfighandler?.getDownlinkParameter(changeInfo, {
555
- startupCheck: true,
556
- });
557
- if (!downlinkParameter) {
558
- await this.delObjectAsync(this.removeNamespace(adapterObject._id));
563
+ // remove not configed states
564
+ const adapterObjects = await this.getAdapterObjectsAsync();
565
+ for (const adapterObject of Object.values(adapterObjects)) {
566
+ if (
567
+ adapterObject.type === 'state' &&
568
+ adapterObject._id.indexOf(
569
+ `${changeInfo?.objectStartDirectory}.downlink.control`,
570
+ ) !== -1
571
+ ) {
572
+ const changeInfo = await this.getChangeInfo(adapterObject._id);
573
+ const downlinkParameter = this.downlinkConfighandler?.getDownlinkParameter(
574
+ changeInfo,
575
+ {
576
+ startupCheck: true,
577
+ },
578
+ );
579
+ if (!downlinkParameter) {
580
+ await this.delObjectAsync(this.removeNamespace(adapterObject._id));
581
+ }
559
582
  }
560
583
  }
584
+ await this.setState(id, state.val, true);
585
+ }
586
+ } else {
587
+ // Query for 0_userdata or alias => states also publish with ack = false
588
+ if (id.startsWith('0_userdata') || id.startsWith('alias')) {
589
+ await this.bridge?.publishId(id, state.val, {});
561
590
  }
562
- await this.setState(id, state.val, true);
591
+ }
592
+ } else {
593
+ // Query for Namespace => Just publish foreign States with ack = true
594
+ if (!id.startsWith(this.namespace)) {
595
+ await this.bridge?.publishId(id, state.val, {});
563
596
  }
564
597
  }
565
598
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lorawan",
3
- "version": "1.15.8",
3
+ "version": "1.16.0",
4
4
  "description": "converts the desired lora gateway data to a ioBroker structure",
5
5
  "author": {
6
6
  "name": "BenAhrdt",