iobroker.lorawan 1.18.5 → 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 +6 -0
- package/admin/i18n/de/translations.json +10 -0
- package/admin/i18n/en/translations.json +11 -1
- package/admin/i18n/es/translations.json +10 -0
- package/admin/i18n/fr/translations.json +10 -0
- package/admin/i18n/it/translations.json +10 -0
- package/admin/i18n/nl/translations.json +10 -0
- package/admin/i18n/pl/translations.json +10 -0
- package/admin/i18n/pt/translations.json +10 -0
- package/admin/i18n/ru/translations.json +10 -0
- package/admin/i18n/uk/translations.json +10 -0
- package/admin/i18n/zh-cn/translations.json +10 -0
- package/admin/jsonConfig.json +117 -1
- package/io-package.json +29 -28
- package/lib/modules/bridge.js +346 -9
- package/lib/modules/downlinkConfighandler.js +0 -1
- package/lib/modules/messagehandler.js +1 -2
- package/main.js +4 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,6 +23,12 @@ 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
|
+
|
|
29
|
+
### 1.18.6 (2025-11-21)
|
|
30
|
+
* (BenAhrdt) set role color to entity_category config
|
|
31
|
+
|
|
26
32
|
### 1.18.5 (2025-11-21)
|
|
27
33
|
* (BenAhrdt) add mixed to type text for color values
|
|
28
34
|
|
|
@@ -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设备返回在线",
|
package/admin/jsonConfig.json
CHANGED
|
@@ -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,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "lorawan",
|
|
4
|
-
"version": "1.18.
|
|
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
|
+
},
|
|
19
|
+
"1.18.6": {
|
|
20
|
+
"en": "set role color to entity_category config",
|
|
21
|
+
"de": "rollenfarbe auf entity_category config einstellen",
|
|
22
|
+
"ru": "установить цвет ролей в конфигурации entity_category",
|
|
23
|
+
"pt": "definir a cor do papel para a configuração entity_category",
|
|
24
|
+
"nl": "rolkleur instellen op entiteit_categorie configuratie",
|
|
25
|
+
"fr": "définir la couleur du rôle à la config entity_category",
|
|
26
|
+
"it": "impostare colore ruolo a enti_category config",
|
|
27
|
+
"es": "definir el papel color a entity_category config",
|
|
28
|
+
"pl": "ustaw kolor ról do konfiguracji podmiotu _ kategorii",
|
|
29
|
+
"uk": "встановити колір ролі на сутність_category config",
|
|
30
|
+
"zh-cn": "设置角色颜色到实体_ 类别配置"
|
|
31
|
+
},
|
|
6
32
|
"1.18.5": {
|
|
7
33
|
"en": "add mixed to type text for color values",
|
|
8
34
|
"de": "hinzufügen gemischt zu geben text für farbwerte",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "Dodaj typ mostu Smarthome\nBugfix subskrybowane tematy\nBugfix w przypadku obiektów zaczyna się od \". '",
|
|
68
94
|
"uk": "Додати Bridge Type Smarthome\nВиправлено помилку\nВиправлення помилок при об'єктиві починається з '. Р",
|
|
69
95
|
"zh-cn": "添加桥型 Smarthome\nBugfix 已订阅主题\n对象大小写上的错误fix 开始于 。 '"
|
|
70
|
-
},
|
|
71
|
-
"1.18.0": {
|
|
72
|
-
"en": "New NPM Auorisation",
|
|
73
|
-
"de": "Neue NPM-Versteigerung",
|
|
74
|
-
"ru": "Новый NPM Auorization",
|
|
75
|
-
"pt": "Nova Auorização do NPM",
|
|
76
|
-
"nl": "Nieuwe NPM-aanmelding",
|
|
77
|
-
"fr": "Nouvelle autorisation NPM",
|
|
78
|
-
"it": "Nuova Auorizzazione NPM",
|
|
79
|
-
"es": "Nuevo NPM Auorisation",
|
|
80
|
-
"pl": "Nowa auryzacja NPM",
|
|
81
|
-
"uk": "Нова Ауроляція NPM",
|
|
82
|
-
"zh-cn": "新国家预防机制"
|
|
83
|
-
},
|
|
84
|
-
"1.17.19": {
|
|
85
|
-
"en": "improve Bridge Handling",
|
|
86
|
-
"de": "verbesserung der Bridge Handling",
|
|
87
|
-
"ru": "улучшение Bridge Handling",
|
|
88
|
-
"pt": "melhorar o manuseio da ponte",
|
|
89
|
-
"nl": "verbeteren Bridge Handling",
|
|
90
|
-
"fr": "améliorer la manipulation des ponts",
|
|
91
|
-
"it": "migliorare la gestione del ponte",
|
|
92
|
-
"es": "mejorar el manejo del puente",
|
|
93
|
-
"pl": "poprawić obsługę mostów",
|
|
94
|
-
"uk": "поліпшити мост ручка",
|
|
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": [
|
package/lib/modules/bridge.js
CHANGED
|
@@ -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;
|
|
@@ -1100,7 +1223,7 @@ class bridgeClass {
|
|
|
1100
1223
|
const normalizedUnit = this.normalizeUnit(unit);
|
|
1101
1224
|
const normalizedUnitLower = normalizedUnit.toLowerCase();
|
|
1102
1225
|
|
|
1103
|
-
if (entityType === 'sensor' || entityType === 'number') {
|
|
1226
|
+
if (entityType === 'sensor' || entityType === 'number' || entityType === 'text') {
|
|
1104
1227
|
if (role.includes('temperature')) {
|
|
1105
1228
|
attributes.device_class = 'temperature';
|
|
1106
1229
|
attributes.unit_of_measurement = normalizedUnit || '°C';
|
|
@@ -1121,6 +1244,8 @@ class bridgeClass {
|
|
|
1121
1244
|
if (attributes.unit_of_measurement === 'V') {
|
|
1122
1245
|
attributes.suggested_display_precision = 2;
|
|
1123
1246
|
}
|
|
1247
|
+
} else if (role.includes('color')) {
|
|
1248
|
+
attributes.entity_category = 'config';
|
|
1124
1249
|
} else if (role.includes('level.timer')) {
|
|
1125
1250
|
attributes.entity_category = 'config';
|
|
1126
1251
|
attributes.unit_of_measurement = normalizedUnit || 'min';
|
|
@@ -1426,6 +1551,7 @@ class bridgeClass {
|
|
|
1426
1551
|
await this.getForeignStatesForStandardEntities();
|
|
1427
1552
|
await this.getForeignClimateConfig();
|
|
1428
1553
|
await this.getForeignHumidifierConfig();
|
|
1554
|
+
await this.getForeignLightConfig();
|
|
1429
1555
|
await this.checkDiscoveries();
|
|
1430
1556
|
} catch (error) {
|
|
1431
1557
|
this.adapter.log.error(`error at ${activeFunction}: ${error}`);
|
|
@@ -1637,6 +1763,7 @@ class bridgeClass {
|
|
|
1637
1763
|
DiscoveryTopic,
|
|
1638
1764
|
DiscoveryPayload,
|
|
1639
1765
|
config.climateIds.target,
|
|
1766
|
+
undefined,
|
|
1640
1767
|
);
|
|
1641
1768
|
|
|
1642
1769
|
// Mode
|
|
@@ -1649,6 +1776,7 @@ class bridgeClass {
|
|
|
1649
1776
|
DiscoveryTopic,
|
|
1650
1777
|
DiscoveryPayload,
|
|
1651
1778
|
config.climateIds.mode,
|
|
1779
|
+
undefined,
|
|
1652
1780
|
);
|
|
1653
1781
|
|
|
1654
1782
|
// Assign published Topics
|
|
@@ -1662,6 +1790,7 @@ class bridgeClass {
|
|
|
1662
1790
|
DiscoveryTopic,
|
|
1663
1791
|
DiscoveryPayload,
|
|
1664
1792
|
`${target.Topic}${this.EndingState}`,
|
|
1793
|
+
undefined,
|
|
1665
1794
|
);
|
|
1666
1795
|
|
|
1667
1796
|
// Act
|
|
@@ -1674,6 +1803,7 @@ class bridgeClass {
|
|
|
1674
1803
|
DiscoveryTopic,
|
|
1675
1804
|
DiscoveryPayload,
|
|
1676
1805
|
`${act.Topic}${this.EndingState}`,
|
|
1806
|
+
undefined,
|
|
1677
1807
|
);
|
|
1678
1808
|
|
|
1679
1809
|
// Mode
|
|
@@ -1686,6 +1816,7 @@ class bridgeClass {
|
|
|
1686
1816
|
DiscoveryTopic,
|
|
1687
1817
|
DiscoveryPayload,
|
|
1688
1818
|
`${mode.Topic}${this.EndingState}`,
|
|
1819
|
+
undefined,
|
|
1689
1820
|
);
|
|
1690
1821
|
|
|
1691
1822
|
// State to publish for Mode
|
|
@@ -1828,20 +1959,20 @@ class bridgeClass {
|
|
|
1828
1959
|
|
|
1829
1960
|
const humidifierUniqueString = await this.getUniqueString(
|
|
1830
1961
|
`${this.adapter.namespace}.${config.HumidifierName}`,
|
|
1831
|
-
|
|
1962
|
+
onOff.DeviceIdentifier,
|
|
1832
1963
|
);
|
|
1833
1964
|
const entityType = config.Humidifier ? this.HumidifierEntityType : this.DeHumidifierEntityType;
|
|
1834
1965
|
const DiscoveryTopic =
|
|
1835
1966
|
`${this.BridgeDiscoveryPrefix[this.adapter.config.BridgeType]}${this.HumidifierEntityType}/${humidifierUniqueString?.path}/config`.toLowerCase();
|
|
1836
|
-
const
|
|
1837
|
-
const Id = config.HumidifierIds.
|
|
1967
|
+
const indexLastDotOnOff = config.HumidifierIds.onOff.lastIndexOf('.');
|
|
1968
|
+
const Id = config.HumidifierIds.onOff.substring(0, indexLastDotOnOff) + this.EndingVirtualHumidifier;
|
|
1838
1969
|
|
|
1839
1970
|
const DiscoveryPayload = {
|
|
1840
1971
|
name: config.HumidifierName,
|
|
1841
1972
|
unique_id: `${humidifierUniqueString?.flat}`.toLowerCase(),
|
|
1842
1973
|
device: {
|
|
1843
|
-
identifiers: [this.normalizeString(
|
|
1844
|
-
name:
|
|
1974
|
+
identifiers: [this.normalizeString(onOff.DeviceIdentifier).toLowerCase()],
|
|
1975
|
+
name: onOff.DeviceIdentifier,
|
|
1845
1976
|
},
|
|
1846
1977
|
device_class: `${entityType}`,
|
|
1847
1978
|
state_topic: `${onOff.Topic}${this.EndingState}`,
|
|
@@ -1869,6 +2000,7 @@ class bridgeClass {
|
|
|
1869
2000
|
DiscoveryTopic,
|
|
1870
2001
|
DiscoveryPayload,
|
|
1871
2002
|
config.HumidifierIds.onOff,
|
|
2003
|
+
undefined,
|
|
1872
2004
|
);
|
|
1873
2005
|
|
|
1874
2006
|
// Target
|
|
@@ -1881,6 +2013,7 @@ class bridgeClass {
|
|
|
1881
2013
|
DiscoveryTopic,
|
|
1882
2014
|
DiscoveryPayload,
|
|
1883
2015
|
config.HumidifierIds.target,
|
|
2016
|
+
undefined,
|
|
1884
2017
|
);
|
|
1885
2018
|
|
|
1886
2019
|
// Assign published Topics
|
|
@@ -1894,6 +2027,7 @@ class bridgeClass {
|
|
|
1894
2027
|
DiscoveryTopic,
|
|
1895
2028
|
DiscoveryPayload,
|
|
1896
2029
|
`${onOff.Topic}${this.EndingState}`,
|
|
2030
|
+
undefined,
|
|
1897
2031
|
);
|
|
1898
2032
|
|
|
1899
2033
|
// Target
|
|
@@ -1906,6 +2040,7 @@ class bridgeClass {
|
|
|
1906
2040
|
DiscoveryTopic,
|
|
1907
2041
|
DiscoveryPayload,
|
|
1908
2042
|
`${target.Topic}${this.EndingState}`,
|
|
2043
|
+
undefined,
|
|
1909
2044
|
);
|
|
1910
2045
|
|
|
1911
2046
|
// Act
|
|
@@ -1918,6 +2053,7 @@ class bridgeClass {
|
|
|
1918
2053
|
DiscoveryTopic,
|
|
1919
2054
|
DiscoveryPayload,
|
|
1920
2055
|
`${act.Topic}${this.EndingState}`,
|
|
2056
|
+
undefined,
|
|
1921
2057
|
);
|
|
1922
2058
|
const informations = {
|
|
1923
2059
|
onOff: {
|
|
@@ -1956,7 +2092,7 @@ class bridgeClass {
|
|
|
1956
2092
|
}
|
|
1957
2093
|
|
|
1958
2094
|
/*********************************************************************
|
|
1959
|
-
* *************** generate Foreign
|
|
2095
|
+
* *************** generate Foreign Humidifier Ids **********************
|
|
1960
2096
|
* ******************************************************************/
|
|
1961
2097
|
|
|
1962
2098
|
/**
|
|
@@ -1994,6 +2130,205 @@ class bridgeClass {
|
|
|
1994
2130
|
}
|
|
1995
2131
|
}
|
|
1996
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
|
+
|
|
1997
2332
|
/**
|
|
1998
2333
|
* get Foreign states for Bridge
|
|
1999
2334
|
*/
|
|
@@ -2173,6 +2508,7 @@ class bridgeClass {
|
|
|
2173
2508
|
discoveryTopic,
|
|
2174
2509
|
discoveryPayload,
|
|
2175
2510
|
discoveryPayload.state_topic,
|
|
2511
|
+
undefined,
|
|
2176
2512
|
);
|
|
2177
2513
|
}
|
|
2178
2514
|
if (options.Bridgestate.subscribe) {
|
|
@@ -2185,6 +2521,7 @@ class bridgeClass {
|
|
|
2185
2521
|
discoveryTopic,
|
|
2186
2522
|
discoveryPayload,
|
|
2187
2523
|
id,
|
|
2524
|
+
undefined,
|
|
2188
2525
|
);
|
|
2189
2526
|
}
|
|
2190
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: '
|
|
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
|
-
|
|
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();
|