iobroker.lorawan 1.18.6 → 1.18.7

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.18.7 (2025-11-22)
27
+ * (BenAhrdt) Add light to possible special devices
28
+
26
29
  ### 1.18.6 (2025-11-21)
27
30
  * (BenAhrdt) set role color to entity_category config
28
31
 
@@ -48,6 +48,16 @@
48
48
  "HumidifierOnOffText": "Ein / Aus",
49
49
  "HumidifierTargetText": "Zielfeuchtigkeit",
50
50
  "HumidifierTooltip": "Luftbefeuchter / Luftentfeuchter",
51
+ "LightBrightness": "Helligkeit",
52
+ "LightBrightnessText": "Helligkeits-ID",
53
+ "LightBrightnessTooltip": "Aktivieren, um die Helligkeits-ID festzulegen",
54
+ "LightColor": "Farbe",
55
+ "LightColorText": "Farb-ID",
56
+ "LightColorTooltip": "Aktivieren, um die Farb-ID festzulegen",
57
+ "LightHeader": "Definieren Sie Zustände für eine Licht Entität",
58
+ "LightInformation": "Hier können Sie eine Reihe von Lichtdefinitionen definieren",
59
+ "LightNameText": "Entitätsname",
60
+ "LightOnOffText": "Ein/Aus",
51
61
  "LoRaWAN Network Service is connected": "Der Lorawan Netzwerkdienst ist verbunden",
52
62
  "LoRaWAN Network Service is disconnected": "Der Lorawan Netzwerkdienst ist getrennt",
53
63
  "LoRaWAN device is back online": "Folgendes Lorawan Gerät ist wieder online",
@@ -186,5 +186,15 @@
186
186
  "WithActTooltip": "activate for setting id for actual value",
187
187
  "HumidifierOnOffText": "On / Off",
188
188
  "HumidifierTargetText": "Target humidity",
189
- "HumidifierActText": "Actual humidity"
189
+ "HumidifierActText": "Actual humidity",
190
+ "LightHeader": "Define States for a Light Entity",
191
+ "LightInformation": "Here you can define an array of Light definitions",
192
+ "LightNameText": "Entityname",
193
+ "LightBrightness": "Brightness",
194
+ "LightBrightnessTooltip": "enable to set brightness id",
195
+ "LightColor": "Color",
196
+ "LightColorTooltip": "enable to set color id",
197
+ "LightOnOffText": "On / Off",
198
+ "LightBrightnessText": "Brightness id",
199
+ "LightColorText": "Color id"
190
200
  }
@@ -48,6 +48,16 @@
48
48
  "HumidifierOnOffText": "Encendido / apagado",
49
49
  "HumidifierTargetText": "Humedad objetivo",
50
50
  "HumidifierTooltip": "humidificador / deshumidificador",
51
+ "LightBrightness": "Brillo",
52
+ "LightBrightnessText": "Identificación de brillo",
53
+ "LightBrightnessTooltip": "habilitar para configurar la identificación del brillo",
54
+ "LightColor": "Color",
55
+ "LightColorText": "identificación del color",
56
+ "LightColorTooltip": "habilitar para establecer la identificación del color",
57
+ "LightHeader": "Definir estados para una entidad ligera",
58
+ "LightInformation": "Aquí puede definir una variedad de definiciones de Luz.",
59
+ "LightNameText": "nombre de entidad",
60
+ "LightOnOffText": "Encendido/Apagado",
51
61
  "LoRaWAN Network Service is connected": "El servicio de red de Lorawan está conectado",
52
62
  "LoRaWAN Network Service is disconnected": "El servicio de la red Lorawan está desconectado",
53
63
  "LoRaWAN device is back online": "El siguiente dispositivo Lorawan está en línea",
@@ -48,6 +48,16 @@
48
48
  "HumidifierOnOffText": "En marche / arrêt",
49
49
  "HumidifierTargetText": "Humidité cible",
50
50
  "HumidifierTooltip": "humidificateur / déshumidificateur",
51
+ "LightBrightness": "Luminosité",
52
+ "LightBrightnessText": "Identifiant de luminosité",
53
+ "LightBrightnessTooltip": "activer pour définir l'identifiant de luminosité",
54
+ "LightColor": "Couleur",
55
+ "LightColorText": "Identifiant de couleur",
56
+ "LightColorTooltip": "permettre de définir l'identifiant de couleur",
57
+ "LightHeader": "Définir les états d'une entité légère",
58
+ "LightInformation": "Ici, vous pouvez définir un tableau de définitions de lumière",
59
+ "LightNameText": "Nom de l'entité",
60
+ "LightOnOffText": "Marche/Arrêt",
51
61
  "LoRaWAN Network Service is connected": "Le service réseau Lorawan est connecté",
52
62
  "LoRaWAN Network Service is disconnected": "Le service réseau Lorawan est déconnecté",
53
63
  "LoRaWAN device is back online": "L'appareil Lorawan suivant est de retour en ligne",
@@ -48,6 +48,16 @@
48
48
  "HumidifierOnOffText": "ON / OFF",
49
49
  "HumidifierTargetText": "Umidità target",
50
50
  "HumidifierTooltip": "umidificatore / deumidificatore",
51
+ "LightBrightness": "Luminosità",
52
+ "LightBrightnessText": "ID luminosità",
53
+ "LightBrightnessTooltip": "abilitare per impostare l'ID luminosità",
54
+ "LightColor": "Colore",
55
+ "LightColorText": "Identificativo colore",
56
+ "LightColorTooltip": "abilitare per impostare l'ID colore",
57
+ "LightHeader": "Definire gli stati per un'entità luce",
58
+ "LightInformation": "Qui puoi definire una serie di definizioni di Luce",
59
+ "LightNameText": "Nome entità",
60
+ "LightOnOffText": "Acceso/Spento",
51
61
  "LoRaWAN Network Service is connected": "Il servizio di rete Lorawan è connesso",
52
62
  "LoRaWAN Network Service is disconnected": "Il servizio di rete Lorawan è disconnesso",
53
63
  "LoRaWAN device is back online": "Il seguente dispositivo Lorawan è tornato online",
@@ -48,6 +48,16 @@
48
48
  "HumidifierOnOffText": "Aan / uit",
49
49
  "HumidifierTargetText": "Richt de luchtvochtigheid",
50
50
  "HumidifierTooltip": "luchtbevochtiger / ontvochtiger",
51
+ "LightBrightness": "Helderheid",
52
+ "LightBrightnessText": "Helderheid ID",
53
+ "LightBrightnessTooltip": "inschakelen om helderheids-id in te stellen",
54
+ "LightColor": "Kleur",
55
+ "LightColorText": "Kleur-id",
56
+ "LightColorTooltip": "inschakelen om kleur-ID in te stellen",
57
+ "LightHeader": "Definieer toestanden voor een lichte entiteit",
58
+ "LightInformation": "Hier kunt u een reeks lichtdefinities definiëren",
59
+ "LightNameText": "Entiteitsnaam",
60
+ "LightOnOffText": "Aan / Uit",
51
61
  "LoRaWAN Network Service is connected": "Lorawan Network Service is verbonden",
52
62
  "LoRaWAN Network Service is disconnected": "Lorawan Network Service is losgekoppeld",
53
63
  "LoRaWAN device is back online": "Het volgende Lorawan -apparaat is weer online",
@@ -48,6 +48,16 @@
48
48
  "HumidifierOnOffText": "Włącz / wyłączony",
49
49
  "HumidifierTargetText": "Docelowa wilgotność",
50
50
  "HumidifierTooltip": "nawilżacz / dehumidifier",
51
+ "LightBrightness": "Jasność",
52
+ "LightBrightnessText": "Identyfikator jasności",
53
+ "LightBrightnessTooltip": "włącz ustawienie identyfikatora jasności",
54
+ "LightColor": "Kolor",
55
+ "LightColorText": "Identyfikator koloru",
56
+ "LightColorTooltip": "włącz ustawienie identyfikatora koloru",
57
+ "LightHeader": "Zdefiniuj Stany dla Bytu Lekkiego",
58
+ "LightInformation": "Tutaj możesz zdefiniować tablicę definicji Światła",
59
+ "LightNameText": "Nazwa jednostki",
60
+ "LightOnOffText": "Wł./Wył",
51
61
  "LoRaWAN Network Service is connected": "Lorawan Network Service jest podłączona",
52
62
  "LoRaWAN Network Service is disconnected": "Lorawan Network Service jest odłączona",
53
63
  "LoRaWAN device is back online": "Następujące urządzenie Lorawan powraca do Internetu",
@@ -48,6 +48,16 @@
48
48
  "HumidifierOnOffText": "ON / OFF",
49
49
  "HumidifierTargetText": "Umidade alvo",
50
50
  "HumidifierTooltip": "umidificador / desumidificador",
51
+ "LightBrightness": "Brilho",
52
+ "LightBrightnessText": "ID de brilho",
53
+ "LightBrightnessTooltip": "ativar para definir o ID de brilho",
54
+ "LightColor": "Cor",
55
+ "LightColorText": "ID da cor",
56
+ "LightColorTooltip": "ativar para definir o ID da cor",
57
+ "LightHeader": "Definir estados para uma entidade leve",
58
+ "LightInformation": "Aqui você pode definir uma série de definições de luz",
59
+ "LightNameText": "Nome da entidade",
60
+ "LightOnOffText": "Ligado/Desligado",
51
61
  "LoRaWAN Network Service is connected": "O serviço de rede de Lorawan está conectado",
52
62
  "LoRaWAN Network Service is disconnected": "O serviço de rede de Lorawan está desconectado",
53
63
  "LoRaWAN device is back online": "O seguinte dispositivo Lorawan está novamente online",
@@ -48,6 +48,16 @@
48
48
  "HumidifierOnOffText": "ВКЛ / OFF",
49
49
  "HumidifierTargetText": "Целевая влажность",
50
50
  "HumidifierTooltip": "Увлажнитель / осушитель",
51
+ "LightBrightness": "Яркость",
52
+ "LightBrightnessText": "Идентификатор яркости",
53
+ "LightBrightnessTooltip": "включить установку идентификатора яркости",
54
+ "LightColor": "Цвет",
55
+ "LightColorText": "Идентификатор цвета",
56
+ "LightColorTooltip": "включить установку идентификатора цвета",
57
+ "LightHeader": "Определите состояния для легкой сущности",
58
+ "LightInformation": "Здесь вы можете определить массив определений света.",
59
+ "LightNameText": "Имя объекта",
60
+ "LightOnOffText": "Вкл/Выкл",
51
61
  "LoRaWAN Network Service is connected": "СЕВЕТЫЙ СЕВЕТ ЛОРАВАН подключен",
52
62
  "LoRaWAN Network Service is disconnected": "Сетевая служба Lorawan отключена",
53
63
  "LoRaWAN device is back online": "Следующее устройство Lorawan возвращается в Интернет",
@@ -48,6 +48,16 @@
48
48
  "HumidifierOnOffText": "Увімкнення / вимкнення",
49
49
  "HumidifierTargetText": "Цільова вологість",
50
50
  "HumidifierTooltip": "зволожувач / осушувач",
51
+ "LightBrightness": "Яскравість",
52
+ "LightBrightnessText": "Ідентифікатор яскравості",
53
+ "LightBrightnessTooltip": "дозволити встановити ідентифікатор яскравості",
54
+ "LightColor": "Колір",
55
+ "LightColorText": "Ідентифікатор кольору",
56
+ "LightColorTooltip": "дозволити встановити ідентифікатор кольору",
57
+ "LightHeader": "Визначення станів для легкої сутності",
58
+ "LightInformation": "Тут ви можете визначити масив визначень Light",
59
+ "LightNameText": "Назва сутності",
60
+ "LightOnOffText": "Увімк. / Вимк",
51
61
  "LoRaWAN Network Service is connected": "Служба мережі Lorawan підключена",
52
62
  "LoRaWAN Network Service is disconnected": "Служба мережі Lorawan відключена",
53
63
  "LoRaWAN device is back online": "Наступний пристрій Lorawan повернувся в Інтернет",
@@ -48,6 +48,16 @@
48
48
  "HumidifierOnOffText": "打开 /关",
49
49
  "HumidifierTargetText": "目标湿度",
50
50
  "HumidifierTooltip": "加湿器 /除湿机",
51
+ "LightBrightness": "亮度",
52
+ "LightBrightnessText": "亮度 ID",
53
+ "LightBrightnessTooltip": "启用设置亮度ID",
54
+ "LightColor": "颜色",
55
+ "LightColorText": "颜色编号",
56
+ "LightColorTooltip": "启用设置颜色 ID",
57
+ "LightHeader": "定义光实体的状态",
58
+ "LightInformation": "在这里您可以定义一组灯光定义",
59
+ "LightNameText": "实体名称",
60
+ "LightOnOffText": "开/关",
51
61
  "LoRaWAN Network Service is connected": "Lorawan网络服务已连接",
52
62
  "LoRaWAN Network Service is disconnected": "Lorawan网络服务已断开连接",
53
63
  "LoRaWAN device is back online": "以下Lorawan设备返回在线",
@@ -1612,7 +1612,7 @@
1612
1612
  "md": 12,
1613
1613
  "lg": 12,
1614
1614
  "xl": 12
1615
- },
1615
+ },
1616
1616
  "_HumidifierForeignInformation":{
1617
1617
  "newLine":true,
1618
1618
  "type": "staticText",
@@ -1716,6 +1716,122 @@
1716
1716
  "xl": 4
1717
1717
  }
1718
1718
  ]
1719
+ },
1720
+ "_LightForeignHeader":{
1721
+ "newLine": true,
1722
+ "type": "header",
1723
+ "text": "LightHeader",
1724
+ "size": 3,
1725
+ "xs": 12,
1726
+ "sm": 12,
1727
+ "md": 12,
1728
+ "lg": 12,
1729
+ "xl": 12
1730
+ },
1731
+ "_LightForeignInformation":{
1732
+ "newLine":true,
1733
+ "type": "staticText",
1734
+ "label": "LightInformation",
1735
+ "xs": 12,
1736
+ "sm": 12,
1737
+ "md": 12,
1738
+ "lg": 12,
1739
+ "xl": 12
1740
+ },
1741
+ "LightForeignConfig":{
1742
+ "newLine": true,
1743
+ "type":"accordion",
1744
+ "titleAttr": "LightName",
1745
+ "clone": true,
1746
+ "xs": 12,
1747
+ "sm": 12,
1748
+ "md": 12,
1749
+ "lg": 12,
1750
+ "xl": 12,
1751
+ "items":[
1752
+ {
1753
+ "type": "text",
1754
+ "attr": "LightName",
1755
+ "label": "LightNameText",
1756
+ "validator": "if(data.LightName === ''){return false;}else{return true;}",
1757
+ "validatorNoSaveOnError": true,
1758
+ "default": "Light Name",
1759
+ "xs": 12,
1760
+ "sm": 4,
1761
+ "md": 4,
1762
+ "lg": 4,
1763
+ "xl": 4
1764
+ },
1765
+ {
1766
+ "type": "checkbox",
1767
+ "attr": "LightBrightness",
1768
+ "label": "LightBrightness",
1769
+ "tooltip": "LightBrightnessTooltip",
1770
+ "default": true,
1771
+ "xs": 12,
1772
+ "sm": 2,
1773
+ "md": 2,
1774
+ "lg": 2,
1775
+ "xl": 2
1776
+ },
1777
+ {
1778
+ "type": "checkbox",
1779
+ "attr": "LightColor",
1780
+ "label": "LightColor",
1781
+ "tooltip": "LightColorTooltip",
1782
+ "default": true,
1783
+ "xs": 12,
1784
+ "sm": 2,
1785
+ "md": 2,
1786
+ "lg": 2,
1787
+ "xl": 2
1788
+ },
1789
+ {
1790
+ "type": "staticText",
1791
+ "attr": "_staticTextTarget",
1792
+ "label": "",
1793
+ "xs": 12,
1794
+ "sm": 4,
1795
+ "md": 4,
1796
+ "lg": 4,
1797
+ "xl": 4
1798
+ },
1799
+ {
1800
+ "type": "objectId",
1801
+ "attr": "OnOffId",
1802
+ "label": "LightOnOffText",
1803
+ "customFilter": "{common: {type: ['boolean']}",
1804
+ "xs": 12,
1805
+ "sm": 4,
1806
+ "md": 4,
1807
+ "lg": 4,
1808
+ "xl": 4
1809
+ },
1810
+ {
1811
+ "type": "objectId",
1812
+ "attr": "BrightnessId",
1813
+ "label": "LightBrightnessText",
1814
+ "hidden": "data.LightBrightness === false",
1815
+ "customFilter": "{common: {type: ['number']}",
1816
+ "xs": 12,
1817
+ "sm": 4,
1818
+ "md": 4,
1819
+ "lg": 4,
1820
+ "xl": 4
1821
+ },
1822
+ {
1823
+ "type": "objectId",
1824
+ "attr": "ColorId",
1825
+ "label": "LightColorText",
1826
+ "hidden": "data.LightColor === false",
1827
+ "customFilter": "{common: {type: ['number']}",
1828
+ "xs": 12,
1829
+ "sm": 4,
1830
+ "md": 4,
1831
+ "lg": 4,
1832
+ "xl": 4
1833
+ }
1834
+ ]
1719
1835
  }
1720
1836
  }
1721
1837
  }
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "lorawan",
4
- "version": "1.18.6",
4
+ "version": "1.18.7",
5
5
  "news": {
6
+ "1.18.7": {
7
+ "en": "Add light to possible special devices",
8
+ "de": "Licht zu möglichen Spezialgeräten hinzufügen",
9
+ "ru": "Добавление света к возможным специальным устройствам",
10
+ "pt": "Adicionar luz a possíveis dispositivos especiais",
11
+ "nl": "Licht toevoegen aan mogelijke speciale apparaten",
12
+ "fr": "Ajouter de la lumière aux dispositifs spéciaux possibles",
13
+ "it": "Aggiungi luce a possibili dispositivi speciali",
14
+ "es": "Añadir luz a posibles dispositivos especiales",
15
+ "pl": "Dodaj światło do możliwych urządzeń specjalnych",
16
+ "uk": "Додати світло для можливих спеціальних пристроїв",
17
+ "zh-cn": "在可能的特殊设备中添加光"
18
+ },
6
19
  "1.18.6": {
7
20
  "en": "set role color to entity_category config",
8
21
  "de": "rollenfarbe auf entity_category config einstellen",
@@ -80,19 +93,6 @@
80
93
  "pl": "Dodaj typ mostu Smarthome\nBugfix subskrybowane tematy\nBugfix w przypadku obiektów zaczyna się od \". '",
81
94
  "uk": "Додати Bridge Type Smarthome\nВиправлено помилку\nВиправлення помилок при об'єктиві починається з '. Р",
82
95
  "zh-cn": "添加桥型 Smarthome\nBugfix 已订阅主题\n对象大小写上的错误fix 开始于 。 '"
83
- },
84
- "1.18.0": {
85
- "en": "New NPM Auorisation",
86
- "de": "Neue NPM-Versteigerung",
87
- "ru": "Новый NPM Auorization",
88
- "pt": "Nova Auorização do NPM",
89
- "nl": "Nieuwe NPM-aanmelding",
90
- "fr": "Nouvelle autorisation NPM",
91
- "it": "Nuova Auorizzazione NPM",
92
- "es": "Nuevo NPM Auorisation",
93
- "pl": "Nowa auryzacja NPM",
94
- "uk": "Нова Ауроляція NPM",
95
- "zh-cn": "新国家预防机制"
96
96
  }
97
97
  },
98
98
  "titleLang": {
@@ -454,7 +454,8 @@
454
454
  ],
455
455
  "ClimateConfig": [],
456
456
  "ClimateForeignConfig": [],
457
- "HumidifierForeignConfig": []
457
+ "HumidifierForeignConfig": [],
458
+ "LightForeignConfig": []
458
459
  },
459
460
  "objects": [],
460
461
  "instanceObjects": [
@@ -38,6 +38,7 @@ class bridgeClass {
38
38
  this.EndingState = '/state';
39
39
  this.EndingVirtualClimate = '.virtual_climate';
40
40
  this.EndingVirtualHumidifier = '.virtual_humiditier';
41
+ this.EndingVirtualLight = '.virtual_light';
41
42
  this.EndingVirtualMode = '.virtual_mode';
42
43
  this.NotificationId = '.notification';
43
44
  this.GeneralId = '.general';
@@ -46,6 +47,7 @@ class bridgeClass {
46
47
  this.EndingNotification = '.notification';
47
48
  this.ClimateEntityType = 'climate';
48
49
  this.HumidifierEntityType = 'humidifier';
50
+ this.LightEntityType = 'light';
49
51
  this.DeHumidifierEntityType = 'dehumidifier';
50
52
  this.NotificationEntityType = 'device_automation';
51
53
  this.MaxValueCount = 5;
@@ -215,6 +217,26 @@ class bridgeClass {
215
217
  await this.publishId(this.SubscribedTopics[topic].id, message, {});
216
218
  return;
217
219
  }
220
+ if (this.SubscribedTopics[topic].light) {
221
+ if (message.state) {
222
+ message.state = message.state === 'ON' ? true : false;
223
+ await this.adapter.setForeignStateAsync(
224
+ this.SubscribedTopics[topic].LightIds.onOff,
225
+ message.state,
226
+ );
227
+ }
228
+ if (message.brightness) {
229
+ await this.adapter.setForeignStateAsync(
230
+ this.SubscribedTopics[topic].LightIds.brightness,
231
+ message.brightness,
232
+ );
233
+ }
234
+ if (message.color) {
235
+ const color = this.rgbToHex(message.color);
236
+ await this.adapter.setForeignStateAsync(this.SubscribedTopics[topic].LightIds.color, color);
237
+ }
238
+ return;
239
+ }
218
240
  // Check for namespace and write own, oder foreign state
219
241
  if (this.SubscribedTopics[topic].id.startsWith(this.adapter.namespace)) {
220
242
  await this.adapter.setState(this.SubscribedTopics[topic].id, message);
@@ -230,6 +252,67 @@ class bridgeClass {
230
252
  }
231
253
  }
232
254
 
255
+ /**
256
+ * @param {string} hex value of the color
257
+ */
258
+ hexToRgb(hex) {
259
+ const activeFunction = 'bridge.js - hexToRgb';
260
+ this.adapter.log.debug(`Function ${activeFunction} started.`);
261
+ try {
262
+ hex = hex.replace('#', '').trim();
263
+
264
+ if (hex.length === 3) {
265
+ // Kurzform #FFF → #FFFFFF
266
+ hex = hex
267
+ .split('')
268
+ .map(c => c + c)
269
+ .join('');
270
+ }
271
+
272
+ return {
273
+ r: parseInt(hex.substring(0, 2), 16),
274
+ g: parseInt(hex.substring(2, 4), 16),
275
+ b: parseInt(hex.substring(4, 6), 16),
276
+ };
277
+ } catch (error) {
278
+ this.adapter.log.error(`error at ${activeFunction}: ${error}`);
279
+ return {
280
+ r: 255,
281
+ g: 255,
282
+ b: 255,
283
+ };
284
+ }
285
+ }
286
+
287
+ /**
288
+ * Converts an RGB color object to a HEX string.
289
+ *
290
+ * @param {object} colorObject - RGB color object
291
+ * @param {number} colorObject.r - Red component (0–255)
292
+ * @param {number} colorObject.g - Green component (0–255)
293
+ * @param {number} colorObject.b - Blue component (0–255)
294
+ * @returns {string} HEX color string (#RRGGBB)
295
+ */
296
+ rgbToHex(colorObject) {
297
+ const activeFunction = 'bridge.js - rgbToHex';
298
+ this.adapter.log.debug(`Function ${activeFunction} started.`);
299
+ try {
300
+ const { r, g, b } = colorObject;
301
+
302
+ /**
303
+ * @param {number} c - Blue component (0–255)
304
+ */
305
+ const toHex = c => {
306
+ const hex = c.toString(16);
307
+ return hex.length === 1 ? `0${hex}` : hex;
308
+ };
309
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
310
+ } catch (error) {
311
+ this.adapter.log.error(`error at ${activeFunction}: ${error}`);
312
+ return `#FFFFFF`;
313
+ }
314
+ }
315
+
233
316
  /**
234
317
  * @param id Id of actual element, handled in the bridge
235
318
  * @param Stateval Value of the used Id
@@ -301,6 +384,7 @@ class bridgeClass {
301
384
  discoveryobject?.topic,
302
385
  discoveryobject?.payload,
303
386
  discoveryobject?.payload.topic,
387
+ undefined,
304
388
  );
305
389
 
306
390
  await this.publishDiscovery(notificationId, {
@@ -445,6 +529,7 @@ class bridgeClass {
445
529
  DiscoveryTopic,
446
530
  DiscoveryPayload,
447
531
  config.climateIds.target,
532
+ undefined,
448
533
  );
449
534
 
450
535
  // Mode
@@ -460,6 +545,7 @@ class bridgeClass {
460
545
  DiscoveryTopic,
461
546
  DiscoveryPayload,
462
547
  config.climateIds.mode,
548
+ undefined,
463
549
  );
464
550
 
465
551
  // Assign published Topics
@@ -476,6 +562,7 @@ class bridgeClass {
476
562
  DiscoveryTopic,
477
563
  DiscoveryPayload,
478
564
  `${target.Topic}${this.EndingState}`,
565
+ undefined,
479
566
  );
480
567
 
481
568
  // Act
@@ -491,6 +578,7 @@ class bridgeClass {
491
578
  DiscoveryTopic,
492
579
  DiscoveryPayload,
493
580
  `${act.Topic}${this.EndingState}`,
581
+ undefined,
494
582
  );
495
583
 
496
584
  // Mode
@@ -506,6 +594,7 @@ class bridgeClass {
506
594
  DiscoveryTopic,
507
595
  DiscoveryPayload,
508
596
  `${mode.Topic}${this.EndingState}`,
597
+ undefined,
509
598
  );
510
599
 
511
600
  // State to publish for Mode
@@ -638,6 +727,24 @@ class bridgeClass {
638
727
  val = State.val;
639
728
  }
640
729
  }
730
+
731
+ if (this.PublishedIds[id].light) {
732
+ val = {};
733
+ val.state = (await this.adapter.getForeignStateAsync(this.PublishedIds[id].LightIds.onOff)).val;
734
+ val.state = val.state === true ? 'ON' : 'OFF';
735
+ if (this.PublishedIds[id].LightIds.brightness) {
736
+ val.brightness = (
737
+ await this.adapter.getForeignStateAsync(this.PublishedIds[id].LightIds.brightness)
738
+ ).val;
739
+ }
740
+ if (this.PublishedIds[id].LightIds.color) {
741
+ val.color_mode = 'rgb';
742
+ val.color = this.hexToRgb(
743
+ (await this.adapter.getForeignStateAsync(this.PublishedIds[id].LightIds.color)).val,
744
+ );
745
+ }
746
+ }
747
+
641
748
  // safe old values (5 last values)
642
749
  if (this.PublishedIds[id].values) {
643
750
  if (!this.PublishedIds[id].oldValues) {
@@ -735,6 +842,7 @@ class bridgeClass {
735
842
  DiscoveryObject?.topic,
736
843
  DiscoveryObject?.payload,
737
844
  DiscoveryObject?.payload.state_topic,
845
+ undefined,
738
846
  );
739
847
  }
740
848
  returnValue = await this.publishDiscovery(id, {
@@ -797,6 +905,7 @@ class bridgeClass {
797
905
  DiscoveryObject?.topic,
798
906
  DiscoveryObject?.payload,
799
907
  DiscoveryObject?.payload.state_topic,
908
+ undefined,
800
909
  );
801
910
  }
802
911
  if (Bridgestate.subscribe) {
@@ -812,6 +921,7 @@ class bridgeClass {
812
921
  DiscoveryObject?.topic,
813
922
  DiscoveryObject?.payload,
814
923
  id,
924
+ undefined,
815
925
  );
816
926
  }
817
927
  returnValue = await this.publishDiscovery(id, {
@@ -847,8 +957,9 @@ class bridgeClass {
847
957
  * @param topic dicoverytopic of the assign
848
958
  * @param payload payload of the assign
849
959
  * @param state_topic topic for the of the assigned state
960
+ * @param options additional options, that can be added
850
961
  */
851
- assignIdStructure(assignObject, indexId, informations, topic, payload, state_topic) {
962
+ assignIdStructure(assignObject, indexId, informations, topic, payload, state_topic, options) {
852
963
  if (!assignObject[indexId]) {
853
964
  assignObject[indexId] = { discovery: [] };
854
965
  }
@@ -858,6 +969,11 @@ class bridgeClass {
858
969
  });
859
970
  assignObject[indexId].state_topic = state_topic;
860
971
  assignObject[indexId].informations = structuredClone(informations);
972
+ if (options) {
973
+ for (const option in options) {
974
+ assignObject[indexId][option] = options[option];
975
+ }
976
+ }
861
977
  }
862
978
 
863
979
  /*********************************************************************
@@ -870,8 +986,9 @@ class bridgeClass {
870
986
  * @param topic dicoverytopic of the assign
871
987
  * @param payload payload of the assign
872
988
  * @param id id for the assign to the foreign state
989
+ * @param options additional options, that can be added
873
990
  */
874
- assignTopicStructure(assignObject, indexTopic, informations, topic, payload, id) {
991
+ assignTopicStructure(assignObject, indexTopic, informations, topic, payload, id, options) {
875
992
  if (!assignObject[indexTopic]) {
876
993
  assignObject[indexTopic] = { discovery: [] };
877
994
  }
@@ -881,6 +998,11 @@ class bridgeClass {
881
998
  });
882
999
  this.SubscribedTopics[indexTopic].id = id;
883
1000
  this.SubscribedTopics[indexTopic].informations = structuredClone(informations);
1001
+ if (options) {
1002
+ for (const option in options) {
1003
+ assignObject[indexTopic][option] = options[option];
1004
+ }
1005
+ }
884
1006
  }
885
1007
 
886
1008
  /*********************************************************************
@@ -1014,6 +1136,7 @@ class bridgeClass {
1014
1136
  *************************************************** */
1015
1137
 
1016
1138
  this.DiscoveredIds[id] = DiscoveryObject;
1139
+
1017
1140
  let payload = JSON.stringify(DiscoveryObject.payload);
1018
1141
  if (typeof DiscoveryObject.payload === 'string') {
1019
1142
  payload = DiscoveryObject.payload;
@@ -1428,6 +1551,7 @@ class bridgeClass {
1428
1551
  await this.getForeignStatesForStandardEntities();
1429
1552
  await this.getForeignClimateConfig();
1430
1553
  await this.getForeignHumidifierConfig();
1554
+ await this.getForeignLightConfig();
1431
1555
  await this.checkDiscoveries();
1432
1556
  } catch (error) {
1433
1557
  this.adapter.log.error(`error at ${activeFunction}: ${error}`);
@@ -1639,6 +1763,7 @@ class bridgeClass {
1639
1763
  DiscoveryTopic,
1640
1764
  DiscoveryPayload,
1641
1765
  config.climateIds.target,
1766
+ undefined,
1642
1767
  );
1643
1768
 
1644
1769
  // Mode
@@ -1651,6 +1776,7 @@ class bridgeClass {
1651
1776
  DiscoveryTopic,
1652
1777
  DiscoveryPayload,
1653
1778
  config.climateIds.mode,
1779
+ undefined,
1654
1780
  );
1655
1781
 
1656
1782
  // Assign published Topics
@@ -1664,6 +1790,7 @@ class bridgeClass {
1664
1790
  DiscoveryTopic,
1665
1791
  DiscoveryPayload,
1666
1792
  `${target.Topic}${this.EndingState}`,
1793
+ undefined,
1667
1794
  );
1668
1795
 
1669
1796
  // Act
@@ -1676,6 +1803,7 @@ class bridgeClass {
1676
1803
  DiscoveryTopic,
1677
1804
  DiscoveryPayload,
1678
1805
  `${act.Topic}${this.EndingState}`,
1806
+ undefined,
1679
1807
  );
1680
1808
 
1681
1809
  // Mode
@@ -1688,6 +1816,7 @@ class bridgeClass {
1688
1816
  DiscoveryTopic,
1689
1817
  DiscoveryPayload,
1690
1818
  `${mode.Topic}${this.EndingState}`,
1819
+ undefined,
1691
1820
  );
1692
1821
 
1693
1822
  // State to publish for Mode
@@ -1830,20 +1959,20 @@ class bridgeClass {
1830
1959
 
1831
1960
  const humidifierUniqueString = await this.getUniqueString(
1832
1961
  `${this.adapter.namespace}.${config.HumidifierName}`,
1833
- target.DeviceIdentifier,
1962
+ onOff.DeviceIdentifier,
1834
1963
  );
1835
1964
  const entityType = config.Humidifier ? this.HumidifierEntityType : this.DeHumidifierEntityType;
1836
1965
  const DiscoveryTopic =
1837
1966
  `${this.BridgeDiscoveryPrefix[this.adapter.config.BridgeType]}${this.HumidifierEntityType}/${humidifierUniqueString?.path}/config`.toLowerCase();
1838
- const indexLastDotTarget = config.HumidifierIds.target.lastIndexOf('.');
1839
- const Id = config.HumidifierIds.target.substring(0, indexLastDotTarget) + this.EndingVirtualHumidifier;
1967
+ const indexLastDotOnOff = config.HumidifierIds.onOff.lastIndexOf('.');
1968
+ const Id = config.HumidifierIds.onOff.substring(0, indexLastDotOnOff) + this.EndingVirtualHumidifier;
1840
1969
 
1841
1970
  const DiscoveryPayload = {
1842
1971
  name: config.HumidifierName,
1843
1972
  unique_id: `${humidifierUniqueString?.flat}`.toLowerCase(),
1844
1973
  device: {
1845
- identifiers: [this.normalizeString(target.DeviceIdentifier).toLowerCase()],
1846
- name: target.DeviceIdentifier,
1974
+ identifiers: [this.normalizeString(onOff.DeviceIdentifier).toLowerCase()],
1975
+ name: onOff.DeviceIdentifier,
1847
1976
  },
1848
1977
  device_class: `${entityType}`,
1849
1978
  state_topic: `${onOff.Topic}${this.EndingState}`,
@@ -1871,6 +2000,7 @@ class bridgeClass {
1871
2000
  DiscoveryTopic,
1872
2001
  DiscoveryPayload,
1873
2002
  config.HumidifierIds.onOff,
2003
+ undefined,
1874
2004
  );
1875
2005
 
1876
2006
  // Target
@@ -1883,6 +2013,7 @@ class bridgeClass {
1883
2013
  DiscoveryTopic,
1884
2014
  DiscoveryPayload,
1885
2015
  config.HumidifierIds.target,
2016
+ undefined,
1886
2017
  );
1887
2018
 
1888
2019
  // Assign published Topics
@@ -1896,6 +2027,7 @@ class bridgeClass {
1896
2027
  DiscoveryTopic,
1897
2028
  DiscoveryPayload,
1898
2029
  `${onOff.Topic}${this.EndingState}`,
2030
+ undefined,
1899
2031
  );
1900
2032
 
1901
2033
  // Target
@@ -1908,6 +2040,7 @@ class bridgeClass {
1908
2040
  DiscoveryTopic,
1909
2041
  DiscoveryPayload,
1910
2042
  `${target.Topic}${this.EndingState}`,
2043
+ undefined,
1911
2044
  );
1912
2045
 
1913
2046
  // Act
@@ -1920,6 +2053,7 @@ class bridgeClass {
1920
2053
  DiscoveryTopic,
1921
2054
  DiscoveryPayload,
1922
2055
  `${act.Topic}${this.EndingState}`,
2056
+ undefined,
1923
2057
  );
1924
2058
  const informations = {
1925
2059
  onOff: {
@@ -1958,7 +2092,7 @@ class bridgeClass {
1958
2092
  }
1959
2093
 
1960
2094
  /*********************************************************************
1961
- * *************** generate Foreign Climate Ids **********************
2095
+ * *************** generate Foreign Humidifier Ids **********************
1962
2096
  * ******************************************************************/
1963
2097
 
1964
2098
  /**
@@ -1996,6 +2130,205 @@ class bridgeClass {
1996
2130
  }
1997
2131
  }
1998
2132
 
2133
+ /**
2134
+ * get Foreign states for Bridge
2135
+ */
2136
+ async getForeignLightConfig() {
2137
+ const activeFunction = 'bridge.js - getForeignLightConfig';
2138
+ this.adapter.log.debug(`Function ${activeFunction} started.`);
2139
+ try {
2140
+ for (const config of this.adapter.config.LightForeignConfig) {
2141
+ await this.discoverForeignLight(config);
2142
+ }
2143
+ } catch (error) {
2144
+ this.adapter.log.error(`error at ${activeFunction}: ${error}`);
2145
+ }
2146
+ }
2147
+
2148
+ /**
2149
+ * get Foreign states for Bridge
2150
+ *
2151
+ * @param config config of the climate entity
2152
+ */
2153
+ async discoverForeignLight(config) {
2154
+ const activeFunction = 'bridge.js - discoverForeignLight';
2155
+ this.adapter.log.debug(`Function ${activeFunction} started.`);
2156
+ try {
2157
+ // Assign the Ids (use the codenameing of discoverClimate)
2158
+ if (!(await this.generateForeignLightIds(config))) {
2159
+ this.adapter.log.warn(
2160
+ `The Foreign Light config is not complete, or has error(s): ${config.ClimateName}`,
2161
+ );
2162
+ return;
2163
+ }
2164
+
2165
+ // On Off
2166
+ const onOff = {};
2167
+ onOff.DeviceIdentifier = (await this.getParentNameing(config.LightIds.onOff))?.parentName;
2168
+
2169
+ const lightUniqueString = await this.getUniqueString(
2170
+ `${this.adapter.namespace}.${config.LightName}`,
2171
+ onOff.DeviceIdentifier,
2172
+ );
2173
+
2174
+ const DiscoveryTopic =
2175
+ `${this.BridgeDiscoveryPrefix[this.adapter.config.BridgeType]}${this.LightEntityType}/${lightUniqueString?.path}/config`.toLowerCase();
2176
+ const indexLastDotOnOff = config.LightIds.onOff.lastIndexOf('.');
2177
+ const Id = config.LightIds.onOff.substring(0, indexLastDotOnOff) + this.EndingVirtualLight;
2178
+
2179
+ // Generate Light Topic
2180
+ const lightTopic = `${this.bridgeMqttClient.BridgePrefix}${lightUniqueString?.path}`.toLowerCase();
2181
+
2182
+ const DiscoveryPayload = {
2183
+ name: config.LightName,
2184
+ unique_id: `${lightUniqueString?.flat}`.toLowerCase(),
2185
+ schema: 'json',
2186
+ command_topic: `${lightTopic}${this.EndingSet}`,
2187
+ state_topic: `${lightTopic}${this.EndingState}`,
2188
+ payload_on: 'ON',
2189
+ payload_off: 'OFF',
2190
+ device: {
2191
+ identifiers: [this.normalizeString(onOff.DeviceIdentifier).toLowerCase()],
2192
+ name: onOff.DeviceIdentifier,
2193
+ },
2194
+ };
2195
+ if (config.LightBrightness) {
2196
+ DiscoveryPayload.brightness = true;
2197
+ DiscoveryPayload.brightness_scale = 255;
2198
+ }
2199
+ if (config.LightColor) {
2200
+ DiscoveryPayload.supported_color_modes = ['rgb'];
2201
+ }
2202
+
2203
+ // Assign Subscribed Topic
2204
+ this.assignTopicStructure(
2205
+ this.SubscribedTopics,
2206
+ `${lightTopic}${this.EndingSet}`,
2207
+ {
2208
+ usedDeviceId: onOff.DeviceIdentifier,
2209
+ },
2210
+ DiscoveryTopic,
2211
+ DiscoveryPayload,
2212
+ Id,
2213
+ { light: true, LightIds: config.LightIds },
2214
+ );
2215
+
2216
+ // Assign published Ids
2217
+ this.assignIdStructure(
2218
+ this.PublishedIds,
2219
+ config.LightIds.onOff,
2220
+ {
2221
+ usedDeviceId: onOff.DeviceIdentifier,
2222
+ },
2223
+ DiscoveryTopic,
2224
+ DiscoveryPayload,
2225
+ `${lightTopic}${this.EndingState}`,
2226
+ { light: true, LightIds: config.LightIds },
2227
+ );
2228
+
2229
+ if (config.LightBrightness) {
2230
+ this.assignIdStructure(
2231
+ this.PublishedIds,
2232
+ config.LightIds.brightness,
2233
+ {
2234
+ usedDeviceId: onOff.DeviceIdentifier,
2235
+ },
2236
+ DiscoveryTopic,
2237
+ DiscoveryPayload,
2238
+ `${lightTopic}${this.EndingState}`,
2239
+ { light: true, LightIds: config.LightIds },
2240
+ );
2241
+ }
2242
+
2243
+ if (config.LightColor) {
2244
+ this.assignIdStructure(
2245
+ this.PublishedIds,
2246
+ config.LightIds.color,
2247
+ {
2248
+ usedDeviceId: onOff.DeviceIdentifier,
2249
+ },
2250
+ DiscoveryTopic,
2251
+ DiscoveryPayload,
2252
+ `${lightTopic}${this.EndingState}`,
2253
+ { light: true, LightIds: config.LightIds },
2254
+ );
2255
+ }
2256
+
2257
+ const informations = {
2258
+ onOff: {
2259
+ usedDeviceId: onOff.DeviceIdentifier,
2260
+ },
2261
+ };
2262
+
2263
+ // Publishing the discover message
2264
+ await this.publishDiscovery(Id, {
2265
+ topic: DiscoveryTopic,
2266
+ payload: structuredClone(DiscoveryPayload),
2267
+ informations: informations,
2268
+ });
2269
+ // Delay for publish new entity
2270
+ setTimeout(async () => {
2271
+ await this.publishId(config.LightIds.onOff, undefined, {});
2272
+ if (config.LightBrightness) {
2273
+ await this.publishId(config.LightIds.brightness, undefined, {});
2274
+ }
2275
+ if (config.LightColors) {
2276
+ await this.publishId(config.LightIds.color, undefined, {});
2277
+ }
2278
+ // Subscribe state for onStatechange mathode
2279
+ await this.adapter.subscribeForeignStatesAsync(config.LightIds.onOff);
2280
+ if (config.LightBrightness) {
2281
+ await this.adapter.subscribeForeignStatesAsync(config.LightIds.brightness);
2282
+ }
2283
+ if (config.LightColor) {
2284
+ await this.adapter.subscribeForeignStatesAsync(config.LightIds.color);
2285
+ }
2286
+ }, 1000);
2287
+ } catch (error) {
2288
+ this.adapter.log.error(`error at ${activeFunction}: ${error}`);
2289
+ }
2290
+ }
2291
+
2292
+ /*********************************************************************
2293
+ * *************** generate Foreign Light Ids **********************
2294
+ * ******************************************************************/
2295
+
2296
+ /**
2297
+ * @param config Configuration of the climate entity, wich is to genereate
2298
+ */
2299
+ async generateForeignLightIds(config) {
2300
+ const activeFunction = 'generateForeignLightIds';
2301
+ this.adapter.log.debug(`Function ${activeFunction} started.`);
2302
+ try {
2303
+ const LightIds = { onOff: '' };
2304
+ LightIds.onOff = config.OnOffId;
2305
+ if (config.LightBrightness) {
2306
+ LightIds.brightness = config.BrightnessId;
2307
+ }
2308
+ if (config.LightColor) {
2309
+ LightIds.color = config.ColorId;
2310
+ }
2311
+ for (const id of Object.values(LightIds)) {
2312
+ if (!(await this.adapter.getForeignObjectAsync(id))) {
2313
+ this.adapter.log.debug(`Id: ${id} does not exsit.`);
2314
+ return false;
2315
+ }
2316
+ }
2317
+ if (config.LightName === '') {
2318
+ this.adapter.log.debug(`Light name is empty`);
2319
+ return false;
2320
+ }
2321
+ const indexOfSpace = config.LightName.indexOf(' -- ');
2322
+ if (indexOfSpace > 0) {
2323
+ config.LightName = config.LightName.substring(0, indexOfSpace);
2324
+ }
2325
+ config.LightIds = LightIds;
2326
+ return true;
2327
+ } catch (error) {
2328
+ this.adapter.log.error(`error at ${activeFunction}: ${error}`);
2329
+ }
2330
+ }
2331
+
1999
2332
  /**
2000
2333
  * get Foreign states for Bridge
2001
2334
  */
@@ -2175,6 +2508,7 @@ class bridgeClass {
2175
2508
  discoveryTopic,
2176
2509
  discoveryPayload,
2177
2510
  discoveryPayload.state_topic,
2511
+ undefined,
2178
2512
  );
2179
2513
  }
2180
2514
  if (options.Bridgestate.subscribe) {
@@ -2187,6 +2521,7 @@ class bridgeClass {
2187
2521
  discoveryTopic,
2188
2522
  discoveryPayload,
2189
2523
  id,
2524
+ undefined,
2190
2525
  );
2191
2526
  }
2192
2527
  await this.publishDiscovery(id, {
@@ -729,7 +729,6 @@ class downlinkConfighandlerClass {
729
729
  */
730
730
  getChirpstackDownlink(downlinkConfig, payloadInHex, changeInfo) {
731
731
  this.adapter.log.silly(`the downlink for chirpstack is requested`);
732
-
733
732
  const payloadInBase64 = Buffer.from(payloadInHex, 'hex').toString('base64');
734
733
  // retun the whole downlink
735
734
  return {
@@ -511,7 +511,6 @@ class messagehandlerClass {
511
511
  { common: common },
512
512
  );
513
513
  }
514
-
515
514
  // Query for base device and parameter push or replace
516
515
  if (downlinkDevice === this.adapter.downlinkConfighandler.internalDevices.baseDevice) {
517
516
  if (downlinkParameter.name === 'push' || downlinkParameter.name === 'replace') {
@@ -537,7 +536,6 @@ class messagehandlerClass {
537
536
  common: common,
538
537
  });
539
538
  }
540
-
541
539
  //check for right type of data (after a possible change)
542
540
  if (!options || !options.inMessage) {
543
541
  const state = await this.adapter.getStateAsync(stateId);
@@ -546,6 +544,7 @@ class messagehandlerClass {
546
544
  `the defaultvale for state ${stateId} will set to ${common.def}`,
547
545
  );
548
546
  await this.adapter.setStateAsync(stateId, common.def, true);
547
+ this.adapter.log.warn('aaaa');
549
548
  }
550
549
  }
551
550
  }
package/main.js CHANGED
@@ -42,7 +42,7 @@ class Lorawan extends utils.Adapter {
42
42
  this.language;
43
43
 
44
44
  this.secret = {
45
- hash: '42b2bbd1dd29a1148fa43609a71f6881162e484a0a5ada2ec6ce98d129606d8f',
45
+ hash: 'feda26376e3d3b38eae8efa48d055754eb0c388d6dbc7ced2ddb5f2f8166f417',
46
46
  salt: 'LoRaWANBeScJoFr',
47
47
  };
48
48
  }
@@ -75,7 +75,9 @@ class Lorawan extends utils.Adapter {
75
75
  this.messagehandler = new messagehandlerClass(this);
76
76
 
77
77
  // generate new configed downlinkstates on allready existing devices at adapter startup
78
- await this.messagehandler.generateDownlinksAndRemoveStatesAtStatup();
78
+ if (this.config.origin !== 'off') {
79
+ await this.messagehandler.generateDownlinksAndRemoveStatesAtStatup();
80
+ }
79
81
 
80
82
  // generate deviceinfo of all devices in info folder
81
83
  await this.messagehandler.generateDeviceinfosAtStartup();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.lorawan",
3
- "version": "1.18.6",
3
+ "version": "1.18.7",
4
4
  "description": "converts the desired lora gateway data to a ioBroker structure",
5
5
  "author": {
6
6
  "name": "BenAhrdt",