New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

iobroker.shelly

Package Overview
Dependencies
Maintainers
21
Versions
107
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

iobroker.shelly - npm Package Compare versions

Comparing version 5.1.3 to 5.2.0

lib/devices/gen2/shellyplus2pm.js

26

io-package.json
{
"common": {
"name": "shelly",
"version": "5.1.3",
"version": "5.2.0",
"news": {
"5.2.0": {
"en": "Added Shelly Pro 1\nAdded Shelly Pro 1 PM\nAdded Shelly Pro 2\nAdded Shelly Pro 2 PM\nAdded Shelly Plus 2 PM\nAllow to change device and channel names of generation 2 devices\nAdded auto on/off timers for generation 2 devices\nAdded input mode, events and initial state for generation 2 devices\nAdded support of covers / shutters for generation 2 devices\nReplaced node-fetch with axios (also for digest auth)",
"de": "Shelly Pro 1 hinzugefügt\nShelly Pro 13 Uhr hinzugefügt\nShelly Pro 2 hinzugefügt\nShelly Pro 14 Uhr hinzugefügt\nShelly Plus 14 Uhr hinzugefügt\nErmöglicht das Ändern von Geräte- und Kanalnamen von Geräten der Generation 2\nAuto-On/Off-Timer für Geräte der Generation 2 hinzugefügt\nEingabemodus, Ereignisse und Anfangszustand für Geräte der Generation 2 hinzugefügt\nUnterstützung von Abdeckungen/Verschlüssen für Geräte der Generation 2 hinzugefügt\nNode-Fetch durch Axios ersetzt (auch für Digest-Authentifizierung)",
"ru": "Добавлен Шелли Про 1\nДобавлен Шелли Про 13:00\nДобавлен Шелли Про 2\nДобавлен Шелли Про 14:00\nДобавлен Шелли Плюс 14:00\nРазрешить изменять имена устройств и каналов устройств поколения 2\nДобавлены таймеры автоматического включения/выключения для устройств 2-го поколения.\nДобавлен режим ввода, события и начальное состояние для устройств поколения 2.\nДобавлена поддержка крышек/жалюзи для устройств поколения 2\nNode-fetch заменен на axios (также для дайджест-аутентификации)",
"pt": "Adicionado Shelly Pro 1\nAdicionado Shelly Pro 13:00\nAdicionado Shelly Pro 2\nAdicionado Shelly Pro 14:00\nAdicionado Shelly Plus 14:00\nPermitir alterar nomes de dispositivos e canais de dispositivos de geração 2\nAdicionados temporizadores automáticos de ligar/desligar para dispositivos de geração 2\nAdicionado modo de entrada, eventos e estado inicial para dispositivos de geração 2\nAdicionado suporte de tampas / persianas para dispositivos de geração 2\nSubstituição de busca de nó por axios (também para autenticação de resumo)",
"nl": "Shelly Pro 1 toegevoegd\nShelly Pro om 13:00 uur toegevoegd\nShelly Pro 2 toegevoegd\nShelly Pro 14.00 uur toegevoegd\nShelly Plus 14.00 uur toegevoegd\nToestaan om apparaat- en kanaalnamen van generatie 2-apparaten te wijzigen\nAutomatische aan/uit-timers toegevoegd voor apparaten van generatie 2\nInvoermodus, gebeurtenissen en beginstatus toegevoegd voor apparaten van generatie 2\nOndersteuning toegevoegd voor covers / shutters voor generatie 2 apparaten\nNode-fetch vervangen door axios (ook voor digest auth)",
"fr": "Ajout de Shelly Pro 1\nAjout de Shelly Pro 1 PM\nAjout de Shelly Pro 2\nAjout de Shelly Pro 2 PM\nAjout de Shelly Plus 2 PM\nAutoriser la modification des noms d'appareils et de canaux des appareils de génération 2\nAjout de minuteries marche/arrêt automatiques pour les appareils de génération 2\nAjout du mode d'entrée, des événements et de l'état initial pour les appareils de génération 2\nAjout de la prise en charge des couvertures/obturateurs pour les appareils de génération 2\nNode-fetch remplacé par axios (également pour Digest Auth)",
"it": "Aggiunto Shelly Pro 1\nAggiunto Shelly Pro 13:00\nAggiunto Shelly Pro 2\nAggiunto Shelly Pro 14:00\nAggiunto Shelly Plus 14:00\nConsenti di cambiare i nomi dei dispositivi e dei canali dei dispositivi di generazione 2\nAggiunti timer di accensione/spegnimento automatici per i dispositivi di seconda generazione\nAggiunta modalità di input, eventi e stato iniziale per i dispositivi di seconda generazione\nAggiunto supporto per coperture/persiane per dispositivi di generazione 2\nSostituito node-fetch con axios (anche per digest auth)",
"es": "Añadido Shelly Pro 1\nSe agregó Shelly Pro a la 1 p. m.\nAñadido Shelly Pro 2\nSe agregó Shelly Pro a las 2 p. m.\nSe agregó Shelly Plus a las 2 p. m.\nPermitir cambiar los nombres de los dispositivos y canales de los dispositivos de generación 2\nTemporizadores de encendido/apagado automático agregados para dispositivos de generación 2\nModo de entrada agregado, eventos y estado inicial para dispositivos de generación 2\nSe agregó soporte de cubiertas / persianas para dispositivos de generación 2\nSe reemplazó la búsqueda de nodos con axios (también para autenticación de resumen)",
"pl": "Dodano Shelly Pro 1\nDodano Shelly Pro o 13:00\nDodano Shelly Pro 2\nDodano Shelly Pro 14:00\nDodano Shelly Plus 14:00\nZezwalaj na zmianę nazw urządzeń i kanałów urządzeń generacji 2\nDodano zegary automatycznego włączania/wyłączania dla urządzeń generacji 2\nDodano tryb wejścia, zdarzenia i stan początkowy dla urządzeń generacji 2\nDodano obsługę osłon / rolet dla urządzeń generacji 2\nZamieniono pobieranie węzła na axios (również dla auth skrótu)",
"zh-cn": "添加了 Shelly Pro 1\n添加了 Shelly Pro 下午 1 点\n添加了 Shelly Pro 2\n添加了 Shelly Pro 2 PM\n添加了 Shelly Plus 2 PM\n允许更改第 2 代设备的设备和通道名称\n为第 2 代设备添加了自动开/关计时器\n为第 2 代设备添加了输入模式、事件和初始状态\n增加了对第 2 代设备的盖板/百叶窗的支持\n将 node-fetch 替换为 axios(也用于摘要身份验证)"
},
"5.1.3": {

@@ -77,14 +89,2 @@ "en": "Changed common.states strings to objects\nJust perform firmware update if an available update was detected\nExtended logging for CoAP",

"zh-cn": "修复在线检查以保持在线状态"
},
"4.1.1": {
"en": "Try to prevent State changes after adapter is stopped",
"de": "Versuchen Sie, Statusänderungen nach dem Stoppen des Adapters zu verhindern",
"ru": "Попытайтесь предотвратить изменение состояния после остановки адаптера",
"pt": "Tente evitar mudanças de estado após o adaptador ser interrompido",
"nl": "Probeer statusveranderingen te voorkomen nadat de adapter is gestopt",
"fr": "Essayez d'empêcher les changements d'état après l'arrêt de l'adaptateur",
"it": "Prova a prevenire le modifiche allo stato dopo l'arresto dell'adattatore",
"es": "Intente evitar cambios de estado después de que se detenga el adaptador",
"pl": "Spróbuj zapobiec zmianom stanu po zatrzymaniu adaptera",
"zh-cn": "尝试在适配器停止后防止状态更改"
}

@@ -91,0 +91,0 @@ },

@@ -47,2 +47,7 @@ /* jshint -W097 */

const shellyplus1pm = require(__dirname + '/devices/gen2/shellyplus1pm').shellyplus1pm;
const shellyplus2pm = require(__dirname + '/devices/gen2/shellyplus2pm').shellyplus2pm;
const shellypro1 = require(__dirname + '/devices/gen2/shellypro1').shellypro1;
const shellypro1pm = require(__dirname + '/devices/gen2/shellypro1pm').shellypro1pm;
const shellypro2 = require(__dirname + '/devices/gen2/shellypro2').shellypro2;
const shellypro2pm = require(__dirname + '/devices/gen2/shellypro2pm').shellypro2pm;
const shellypro4pm = require(__dirname + '/devices/gen2/shellypro4pm').shellypro4pm;

@@ -83,2 +88,7 @@

'shellyplus1pm': shellyplus1pm,
'shellyplus2pm': shellyplus2pm,
'shellypro1': shellypro1,
'shellypro1pm': shellypro1pm,
'shellypro2': shellypro2,
'shellypro2pm': shellypro2pm,
'shellypro4pm': shellypro4pm

@@ -120,2 +130,7 @@ };

'shellyplus1pm': ['shellyplus1pm'],
'shellyplus2pm': ['shellyplus2pm'],
'shellypro1': ['shellypro1'],
'shellypro1pm': ['shellypro1pm'],
'shellypro2': ['shellypro2'],
'shellypro2pm': ['shellypro2pm'],
'shellypro4pm': ['shellypro4pm']

@@ -157,2 +172,7 @@ };

'shellyplus1pm': 2,
'shellyplus2pm': 2,
'shellypro1': 2,
'shellypro1pm': 2,
'shellypro2': 2,
'shellypro2pm': 2,
'shellypro4pm': 2

@@ -159,0 +179,0 @@ };

@@ -34,4 +34,6 @@ /* jshint -W097 */

coap: {
coap_init_value: false
},
mqtt: {
mqtt_init_value: false
},

@@ -49,11 +51,7 @@ common: {

http_publish: '/status',
http_publish_funct: async (value, self) => {
return value ? JSON.parse(value).update.has_update : undefined;
}
http_publish_funct: (value, self) => { return value ? JSON.parse(value).update.has_update : undefined; }
},
mqtt: {
mqtt_publish: 'shellies/announce',
mqtt_publish_funct: async (value, self) => {
return value ? JSON.parse(value).new_fw : false;
}
mqtt_publish_funct: (value, self) => { return value ? JSON.parse(value).new_fw : false; }
},

@@ -86,7 +84,7 @@ common: {

http_publish: '/status',
http_publish_funct: async (value) => { return value ? shellyHelper.uptimeString(JSON.parse(value).uptime) : undefined; }
http_publish_funct: (value) => { return value ? shellyHelper.uptimeString(JSON.parse(value).uptime) : undefined; }
},
mqtt: {
http_publish: '/status',
http_publish_funct: async (value) => { return value ? shellyHelper.uptimeString(JSON.parse(value).uptime) : undefined; }
http_publish_funct: (value) => { return value ? shellyHelper.uptimeString(JSON.parse(value).uptime) : undefined; }
},

@@ -108,3 +106,3 @@ common: {

mqtt_publish: 'shellies/announce',
mqtt_publish_funct: async (value) => { return value ? JSON.parse(value).fw_ver : undefined; }
mqtt_publish_funct: (value) => { return value ? JSON.parse(value).fw_ver : undefined; }
},

@@ -245,3 +243,3 @@ common: {

http_publish: '/rpc/Shelly.GetDeviceInfo',
http_publish_funct: async (value) => { return value ? JSON.parse(value).gen : undefined; }
http_publish_funct: (value) => { return value ? JSON.parse(value).gen : undefined; }
},

@@ -258,2 +256,3 @@ common: {

mqtt: {
mqtt_init_value: false
},

@@ -276,6 +275,7 @@ common: {

Object.prototype.hasOwnProperty.call(valueObj.sys, 'available_updates') &&
Object.prototype.hasOwnProperty.call(valueObj.sys.available_updates, 'stable') &&
Object.prototype.hasOwnProperty.call(valueObj.sys.available_updates.stable, 'version')
Object.prototype.hasOwnProperty.call(valueObj.sys.available_updates, 'stable') &&
Object.prototype.hasOwnProperty.call(valueObj.sys.available_updates.stable, 'version')
) {
return true;
// TODO: Thats not a good check, if a beta version is installed - compare with current version!
//return true;
}

@@ -309,3 +309,3 @@ }

http_publish: '/rpc/Shelly.GetStatus',
http_publish_funct: async (value) => { return value ? shellyHelper.uptimeString(JSON.parse(value).sys.uptime) : undefined; }
http_publish_funct: (value) => { return value ? shellyHelper.uptimeString(JSON.parse(value).sys.uptime) : undefined; }
},

@@ -323,3 +323,3 @@ common: {

http_publish: '/rpc/Shelly.GetDeviceInfo',
http_publish_funct: async (value) => { return value ? JSON.parse(value).ver : undefined; }
http_publish_funct: (value) => { return value ? JSON.parse(value).ver : undefined; }
},

@@ -400,3 +400,3 @@ common: {

http_publish: '/rpc/Shelly.GetStatus',
http_publish_funct: async (value) => { return value ? JSON.parse(value).wifi.rssi : undefined; }
http_publish_funct: (value) => { return value ? JSON.parse(value).wifi.rssi : undefined; }
},

@@ -414,3 +414,4 @@ common: {

mqtt: {
http_cmd: '/rpc/Shelly.Reboot',
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Shelly.Reboot'}); }
},

@@ -440,3 +441,5 @@ common: {

http_publish: '/rpc/Shelly.GetDeviceInfo',
http_publish_funct: async (value) => { return value ? JSON.parse(value).id : undefined; }
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setDeviceName(self, JSON.parse(value).name) : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Sys.SetConfig', params: {config: {device: {name: value}}}}); }
},

@@ -450,2 +453,77 @@ common: {

}
},
'Sys.eco': {
mqtt: {
http_publish: '/rpc/Sys.GetConfig',
http_publish_funct: (value) => { return value ? JSON.parse(value).device.eco_mode : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Sys.SetConfig', params: {config: {device: {eco_mode: value}}}}); }
},
common: {
'name': 'Eco Mode',
'type': 'boolean',
'role': 'state',
'read': true,
'write': true
}
},
'Sys.sntp': {
mqtt: {
http_publish: '/rpc/Sys.GetConfig',
http_publish_funct: (value) => { return value ? JSON.parse(value).sntp.server : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Sys.SetConfig', params: {config: {sntp: {server: value}}}}); }
},
common: {
'name': 'SNTP Server',
'type': 'string',
'role': 'url',
'read': true,
'write': true
}
},
'Sys.timezone': {
mqtt: {
http_publish: '/rpc/Sys.GetConfig',
http_publish_funct: (value) => { return value ? JSON.parse(value).location.tz : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Sys.SetConfig', params: {config: {location: {tz: value}}}}); }
},
common: {
'name': 'Timezone',
'type': 'string',
'role': 'text',
'read': true,
'write': true
}
},
'Sys.lat': {
mqtt: {
http_publish: '/rpc/Sys.GetConfig',
http_publish_funct: (value) => { return value ? JSON.parse(value).location.lat : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Sys.SetConfig', params: {config: {location: {lat: value}}}}); }
},
common: {
'name': 'Latitude',
'type': 'number',
'role': 'value.gps.latitude',
'read': true,
'write': true
}
},
'Sys.lon': {
mqtt: {
http_publish: '/rpc/Sys.GetConfig',
http_publish_funct: (value) => { return value ? JSON.parse(value).location.lon : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Sys.SetConfig', params: {config: {location: {lon: value}}}}); }
},
common: {
'name': 'Longitude',
'type': 'number',
'role': 'value.gps.longitude',
'read': true,
'write': true
}
}

@@ -452,0 +530,0 @@ };

@@ -38,3 +38,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -48,3 +48,3 @@ 'write': true,

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -55,3 +55,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -216,3 +216,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -219,0 +219,0 @@ 'role': 'level.timer',

@@ -27,3 +27,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -37,3 +37,3 @@ 'write': true,

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -44,3 +44,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -276,3 +276,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -279,0 +279,0 @@ 'role': 'level.timer',

@@ -38,3 +38,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -48,3 +48,3 @@ 'write': true,

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -55,3 +55,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -216,3 +216,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -219,0 +219,0 @@ 'role': 'level.timer',

@@ -78,3 +78,3 @@

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -102,3 +102,3 @@ 'role': 'level.timer',

common: {
'name': 'Modus',
'name': 'Mode',
'type': 'string',

@@ -105,0 +105,0 @@ 'role': 'state',

@@ -31,3 +31,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -42,3 +42,3 @@ 'write': true,

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -49,3 +49,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -100,3 +100,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -236,3 +236,3 @@ 'role': 'level.timer',

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -247,3 +247,3 @@ 'write': true,

http_publish: '/settings/relay/1',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/1',

@@ -254,3 +254,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/1',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/1',

@@ -305,3 +305,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -442,3 +442,3 @@ 'role': 'level.timer',

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -453,3 +453,3 @@ 'write': true,

http_publish: '/settings/relay/2',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay2.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay2', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/2',

@@ -460,3 +460,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/2',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay2.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay2', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/2',

@@ -511,3 +511,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -648,3 +648,3 @@ 'role': 'level.timer',

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -659,3 +659,3 @@ 'write': true,

http_publish: '/settings/relay/3',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay3.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay3', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/3',

@@ -666,3 +666,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/3',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay3.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay3', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/3',

@@ -717,3 +717,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -720,0 +720,0 @@ 'role': 'level.timer',

@@ -38,3 +38,3 @@

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -82,3 +82,3 @@ 'write': true,

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -106,3 +106,3 @@ 'role': 'level.timer',

common: {
'name': 'Modus',
'name': 'Mode',
'type': 'string',

@@ -109,0 +109,0 @@ 'role': 'state',

@@ -36,3 +36,3 @@

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -80,3 +80,3 @@ 'write': true,

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -83,0 +83,0 @@ 'role': 'level.timer',

@@ -38,3 +38,3 @@

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -82,3 +82,3 @@ 'write': true,

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -106,3 +106,3 @@ 'role': 'level.timer',

common: {
'name': 'Modus',
'name': 'Mode',
'type': 'string',

@@ -109,0 +109,0 @@ 'role': 'state',

@@ -36,3 +36,3 @@

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -46,3 +46,3 @@ 'write': true,

http_publish: '/settings/light/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'lights.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'lights', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/light/0',

@@ -53,3 +53,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/light/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'lights.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'lights', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/light/0',

@@ -99,3 +99,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Modus',
'name': 'Mode',
'type': 'string',

@@ -148,3 +148,3 @@ 'role': 'state',

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -151,0 +151,0 @@ 'role': 'level.timer',

@@ -33,3 +33,3 @@

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -43,3 +43,3 @@ 'write': true,

http_publish: '/settings/light/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'lights.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'lights', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/light/0',

@@ -50,3 +50,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/light/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'lights.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'lights', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/light/0',

@@ -95,3 +95,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Modus',
'name': 'Mode',
'type': 'string',

@@ -144,3 +144,3 @@ 'role': 'state',

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -147,0 +147,0 @@ 'role': 'level.timer',

@@ -34,3 +34,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -44,3 +44,3 @@ 'write': true,

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -50,3 +50,3 @@ http_cmd_funct: (value) => { return { name: value }; } },

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -100,3 +100,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -103,0 +103,0 @@ 'role': 'level.timer',

@@ -35,3 +35,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -45,3 +45,3 @@ 'write': true,

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -52,3 +52,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -102,3 +102,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -105,0 +105,0 @@ 'role': 'level.timer',

@@ -34,3 +34,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -44,3 +44,3 @@ 'write': true,

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -51,3 +51,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -101,3 +101,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -104,0 +104,0 @@ 'role': 'level.timer',

@@ -35,3 +35,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -45,3 +45,3 @@ 'write': true,

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -52,3 +52,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -102,3 +102,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -105,0 +105,0 @@ 'role': 'level.timer',

@@ -37,3 +37,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -81,3 +81,3 @@ 'write': true,

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -836,3 +836,3 @@ 'role': 'level.timer',

common: {
'name': 'Modus',
'name': 'Mode',
'type': 'string',

@@ -839,0 +839,0 @@ 'role': 'state',

@@ -35,3 +35,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -79,3 +79,3 @@ 'write': true,

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -102,3 +102,3 @@ 'role': 'level.timer',

common: {
'name': 'Modus',
'name': 'Mode',
'type': 'string',

@@ -105,0 +105,0 @@ 'role': 'state',

@@ -37,3 +37,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -47,3 +47,3 @@ 'write': true,

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -54,3 +54,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -104,3 +104,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -353,3 +353,3 @@ 'role': 'level.timer',

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -363,3 +363,3 @@ 'write': true,

http_publish: '/settings/relay/1',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/1',

@@ -370,3 +370,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/1',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/1',

@@ -420,3 +420,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -909,3 +909,3 @@ 'role': 'level.timer',

common: {
'name': 'Modus',
'name': 'Mode',
'type': 'string',

@@ -912,0 +912,0 @@ 'role': 'state',

@@ -36,3 +36,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -46,3 +46,3 @@ 'write': true,

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -53,3 +53,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -103,3 +103,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -404,3 +404,3 @@ 'role': 'level.timer',

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -414,3 +414,3 @@ 'write': true,

http_publish: '/settings/relay/1',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/1',

@@ -421,3 +421,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/1',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/1',

@@ -471,3 +471,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -1011,3 +1011,3 @@ 'role': 'level.timer',

common: {
'name': 'Modus',
'name': 'Mode',
'type': 'string',

@@ -1014,0 +1014,0 @@ 'role': 'state',

@@ -34,3 +34,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -44,3 +44,3 @@ 'write': true,

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -51,3 +51,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/0',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay0', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/0',

@@ -212,3 +212,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -311,3 +311,3 @@ 'role': 'level.timer',

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -321,3 +321,3 @@ 'write': true,

http_publish: '/settings/relay/1',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/1',

@@ -328,3 +328,3 @@ http_cmd_funct: (value) => { return { name: value }; }

http_publish: '/settings/relay/1',
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1.ChannelName', JSON.parse(value).name) : undefined; },
http_publish_funct: async (value, self) => { return value ? await shellyHelper.setChannelName(self, 'Relay1', JSON.parse(value).name) : undefined; },
http_cmd: '/settings/relay/1',

@@ -494,3 +494,3 @@ http_cmd_funct: (value) => { return { name: value }; }

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -497,0 +497,0 @@ 'role': 'level.timer',

@@ -34,3 +34,3 @@ /* jshint -W097 */

'type': 'boolean',
'role': 'switch',
'role': 'switch.power',
'read': true,

@@ -78,3 +78,3 @@ 'write': true,

common: {
'name': 'Auto Timer Off',
'name': 'Auto Timer On',
'type': 'number',

@@ -81,0 +81,0 @@ 'role': 'level.timer',

@@ -12,70 +12,6 @@ /* jshint -W097 */

* Shelly Plus 1 / shellyplus1
*
* https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPlus1
*/
const shellyplus1 = {
'Relay0.Switch': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'output')
) {
return valueObj.params['switch:0'].output;
}
return undefined;
},
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({'id': 1, 'src': 'iobroker', 'method': 'Switch.Set', 'params': {'id': 0, 'on': value}}); },
},
common: {
'name': 'Switch',
'type': 'boolean',
'role': 'switch',
'read': true,
'write': true,
'def': false
}
},
'Relay0.source': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'source')
) {
return valueObj.params['switch:0'].source;
}
return undefined;
}
},
common: {
'name': 'source of last command',
'type': 'string',
'role': 'state',
'read': true,
'write': false
}
},
'Relay0.Input': {
mqtt: {
mqtt_publish: '<mqttprefix>/status/input:0',
mqtt_publish_funct: (value) => { return JSON.parse(value).state; }
},
common: {
'name': 'Input / Detach',
'type': 'boolean',
'role': 'state',
'read': true,
'write': false
}
},
'temperatureC': {

@@ -88,6 +24,6 @@ mqtt: {

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'temperature')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'temperature')
) {

@@ -115,6 +51,6 @@ return valueObj.params['switch:0'].temperature.tC;

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'temperature')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'temperature')
) {

@@ -137,4 +73,8 @@ return valueObj.params['switch:0'].temperature.tF;

shellyHelper.addSwitchToGen2Device(shellyplus1, 0);
shellyHelper.addInputToGen2Device(shellyplus1, 0);
module.exports = {
shellyplus1: shellyplus1
};

@@ -12,70 +12,6 @@ /* jshint -W097 */

* Shelly Plus 1 PM / shellyplus1pm
*
* https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPlus1PM
*/
const shellyplus1pm = {
'Relay0.Switch': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'output')
) {
return valueObj.params['switch:0'].output;
}
return undefined;
},
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({'id': 1, 'src': 'iobroker', 'method': 'Switch.Set', 'params': {'id': 0, 'on': value}}); },
},
common: {
'name': 'Switch',
'type': 'boolean',
'role': 'switch',
'read': true,
'write': true,
'def': false
}
},
'Relay0.source': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'source')
) {
return valueObj.params['switch:0'].source;
}
return undefined;
}
},
common: {
'name': 'source of last command',
'type': 'string',
'role': 'state',
'read': true,
'write': false
}
},
'Relay0.Input': {
mqtt: {
mqtt_publish: '<mqttprefix>/status/input:0',
mqtt_publish_funct: (value) => { return JSON.parse(value).state; }
},
common: {
'name': 'Input / Detach',
'type': 'boolean',
'role': 'state',
'read': true,
'write': false
}
},
'Relay0.Power': {

@@ -88,6 +24,6 @@ mqtt: {

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'apower')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'apower')
) {

@@ -116,6 +52,6 @@ return valueObj.params['switch:0'].apower;

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'aenergy')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'aenergy')
) {

@@ -144,6 +80,6 @@ return valueObj.params['switch:0'].aenergy.total;

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'temperature')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'temperature')
) {

@@ -171,6 +107,6 @@ return valueObj.params['switch:0'].temperature.tC;

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'temperature')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'temperature')
) {

@@ -193,4 +129,8 @@ return valueObj.params['switch:0'].temperature.tF;

shellyHelper.addSwitchToGen2Device(shellyplus1pm, 0);
shellyHelper.addInputToGen2Device(shellyplus1pm, 0);
module.exports = {
shellyplus1pm: shellyplus1pm
};

@@ -12,70 +12,6 @@ /* jshint -W097 */

* Shelly Pro 4 PM / shellypro4pm
*
* https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPro4PM
*/
const shellypro4pm = {
'Relay0.Switch': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'output')
) {
return valueObj.params['switch:0'].output;
}
return undefined;
},
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({'id': 1, 'src': 'iobroker', 'method': 'Switch.Set', 'params': {'id': 0, 'on': value}}); },
},
common: {
'name': 'Switch',
'type': 'boolean',
'role': 'switch',
'read': true,
'write': true,
'def': false
}
},
'Relay0.source': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'source')
) {
return valueObj.params['switch:0'].source;
}
return undefined;
}
},
common: {
'name': 'source of last command',
'type': 'string',
'role': 'state',
'read': true,
'write': false
}
},
'Relay0.Input': {
mqtt: {
mqtt_publish: '<mqttprefix>/status/input:0',
mqtt_publish_funct: (value) => { return JSON.parse(value).state; }
},
common: {
'name': 'Input / Detach',
'type': 'boolean',
'role': 'state',
'read': true,
'write': false
}
},
'Relay0.Power': {

@@ -88,6 +24,6 @@ mqtt: {

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'apower')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'apower')
) {

@@ -116,6 +52,6 @@ return valueObj.params['switch:0'].apower;

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'aenergy')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:0') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:0'], 'aenergy')
) {

@@ -137,73 +73,2 @@ return valueObj.params['switch:0'].aenergy.total;

},
'Relay1.Switch': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:1') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:1'], 'output')
) {
return valueObj.params['switch:1'].output;
}
return undefined;
},
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({'id': 2, 'src': 'iobroker', 'method': 'Switch.Set', 'params': {'id': 1, 'on': value}}); },
},
common: {
'name': 'Switch',
'type': 'boolean',
'role': 'switch',
'read': true,
'write': true,
'def': false
}
},
'Relay1.source': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:1') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:1'], 'source')
) {
return valueObj.params['switch:1'].source;
}
return undefined;
}
},
common: {
'name': 'source of last command',
'type': 'string',
'role': 'state',
'read': true,
'write': false
}
},
'Relay1.Input': {
mqtt: {
mqtt_publish: '<mqttprefix>/status/input:1',
mqtt_publish_funct: (value) => { return JSON.parse(value).state; },
},
common: {
'name': 'Input / Detach',
'type': 'boolean',
'role': 'state',
'read': true,
'write': false,
'states': {
0: 'Input',
1: 'Detach'
}
//'def': false
}
},
'Relay1.Power': {

@@ -216,6 +81,6 @@ mqtt: {

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:1') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:1'], 'apower')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:1') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:1'], 'apower')
) {

@@ -244,6 +109,6 @@ return valueObj.params['switch:1'].apower;

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:1') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:1'], 'aenergy')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:1') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:1'], 'aenergy')
) {

@@ -265,73 +130,2 @@ return valueObj.params['switch:1'].aenergy.total;

},
'Relay2.Switch': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:2') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:2'], 'output')
) {
return valueObj.params['switch:2'].output;
}
return undefined;
},
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({'id': 3, 'src': 'iobroker', 'method': 'Switch.Set', 'params': {'id': 2, 'on': value}}); },
},
common: {
'name': 'Switch',
'type': 'boolean',
'role': 'switch',
'read': true,
'write': true,
'def': false
}
},
'Relay2.source': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:2') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:2'], 'source')
) {
return valueObj.params['switch:2'].source;
}
return undefined;
}
},
common: {
'name': 'source of last command',
'type': 'string',
'role': 'state',
'read': true,
'write': false
}
},
'Relay2.Input': {
mqtt: {
mqtt_publish: '<mqttprefix>/status/input:2',
mqtt_publish_funct: (value) => { return JSON.parse(value).state; },
},
common: {
'name': 'Input / Detach',
'type': 'boolean',
'role': 'state',
'read': true,
'write': false,
'states': {
0: 'Input',
1: 'Detach'
}
//'def': false
}
},
'Relay2.Power': {

@@ -344,6 +138,6 @@ mqtt: {

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:2') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:2'], 'apower')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:2') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:2'], 'apower')
) {

@@ -372,6 +166,6 @@ return valueObj.params['switch:2'].apower;

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:2') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:2'], 'aenergy')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:2') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:2'], 'aenergy')
) {

@@ -393,73 +187,2 @@ return valueObj.params['switch:2'].aenergy.total;

},
'Relay3.Switch': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:3') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:3'], 'output')
) {
return valueObj.params['switch:3'].output;
}
return undefined;
},
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({'id': 4, 'src': 'iobroker', 'method': 'Switch.Set', 'params': {'id': 3, 'on': value}}); },
},
common: {
'name': 'Switch',
'type': 'boolean',
'role': 'switch',
'read': true,
'write': true,
'def': false
}
},
'Relay3.source': {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:3') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:3'], 'source')
) {
return valueObj.params['switch:3'].source;
}
return undefined;
}
},
common: {
'name': 'source of last command',
'type': 'string',
'role': 'state',
'read': true,
'write': false
}
},
'Relay3.Input': {
mqtt: {
mqtt_publish: '<mqttprefix>/status/input:3',
mqtt_publish_funct: (value) => { return JSON.parse(value).state; },
},
common: {
'name': 'Input / Detach',
'type': 'boolean',
'role': 'state',
'read': true,
'write': false,
'states': {
0: 'Input',
1: 'Detach'
}
//'def': false
}
},
'Relay3.Power': {

@@ -472,6 +195,6 @@ mqtt: {

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:3') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:3'], 'apower')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:3') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:3'], 'apower')
) {

@@ -500,6 +223,6 @@ return valueObj.params['switch:3'].apower;

Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:3') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:3'], 'aenergy')
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'switch:3') &&
Object.prototype.hasOwnProperty.call(valueObj.params['switch:3'], 'aenergy')
) {

@@ -523,4 +246,14 @@ return valueObj.params['switch:3'].aenergy.total;

shellyHelper.addSwitchToGen2Device(shellypro4pm, 0);
shellyHelper.addSwitchToGen2Device(shellypro4pm, 1);
shellyHelper.addSwitchToGen2Device(shellypro4pm, 2);
shellyHelper.addSwitchToGen2Device(shellypro4pm, 3);
shellyHelper.addInputToGen2Device(shellypro4pm, 0);
shellyHelper.addInputToGen2Device(shellypro4pm, 1);
shellyHelper.addInputToGen2Device(shellypro4pm, 2);
shellyHelper.addInputToGen2Device(shellypro4pm, 3);
module.exports = {
shellypro4pm: shellypro4pm
};

@@ -9,4 +9,4 @@ /* jshint -W097 */

const datapoints = require(__dirname + '/../datapoints');
const fetch = require('node-fetch');
const DigestFetch = require('digest-fetch');
const axios = require('axios');
const crypto = require('crypto');

@@ -49,3 +49,2 @@ function recursiveSubStringReplace(source, pattern, replacement) {

this.active = true;
this.states = {};

@@ -66,2 +65,3 @@ this.device = {};

this.nonceCount = 0;
this.httptimeout = 8 * 1000;

@@ -76,33 +76,88 @@

return new Promise((resolve, reject) => {
if (this.adapter.config.httppassword) {
if (this.getDeviceGen() === 1) {
this.adapter.log.silly(`[requestAsync] HTTP request to gen 1 device with basic auth: "${url}"`);
const client = new DigestFetch(this.adapter.config.httpusername, this.adapter.config.httppassword, { basic: true });
client.fetch(url, {timeout: this.httptimeout})
.then(res => res.text())
.then(text => {
this.adapter.log.silly(`[requestAsync] HTTP response of gen 1 device with basic auth: "${url}" -> "${text}"`);
resolve(text);
let axiosRequestObj = {
method: 'get',
responseType: 'text',
transformResponse: (res) => {
return res; // Avoid automatic json parse
},
baseURL: `http://${this.getIP()}`,
timeout: this.httptimeout,
url: url
};
if (this.getDeviceGen() === 1) {
if (this.adapter.config.httpusername && this.adapter.config.httppassword) {
// Add basic auth if configured
this.adapter.log.silly(`[requestAsync] HTTP request to gen 1 device with basic auth: "${axiosRequestObj.baseURL}${url}"`);
axiosRequestObj = {
...axiosRequestObj,
auth: {
username: this.adapter.config.httpusername,
password: this.adapter.config.httppassword
}
}
} else {
this.adapter.log.silly(`[requestAsync] HTTP request to gen 1 device: "${axiosRequestObj.baseURL}${url}"`);
}
axios(
axiosRequestObj
)
.then(response => {
this.adapter.log.silly(`[requestAsync] HTTP response of gen 1 device: "${axiosRequestObj.baseURL}${url}" -> "${response.data}"`);
resolve(response.data);
})
.catch(reject);
} else if (this.getDeviceGen() === 2) {
this.adapter.log.silly(`[requestAsync] HTTP request to gen 2 device (with digest auth): "${axiosRequestObj.baseURL}${url}"`);
axios(
axiosRequestObj
)
.then(response => {
this.adapter.log.silly(`[requestAsync] HTTP response of gen 2 device without auth: "${axiosRequestObj.baseURL}${url}" -> "${response.data}"`);
resolve(response.data);
})
.catch(err => {
if (err && err.response && err.response.status === 401) {
const authDetails = err.response.headers['www-authenticate'].split(', ').map(v => v.split('='));
const username = 'admin';
const password = this.adapter.config.httppassword;
this.nonceCount++;
const nonceCount = ('00000000' + this.nonceCount).slice(-8);
const cnonce = crypto.randomBytes(24).toString('hex');
const realm = authDetails[1][1].replace(/"/g, '');
const nonce = authDetails[2][1].replace(/"/g, '');
const sha256 = str => crypto.createHash('sha256').update(str).digest('hex');
const HA1 = sha256(`${username}:${realm}:${password}`);
const HA2 = sha256(`GET:${url}`);
const response = sha256(`${HA1}:${nonce}:${nonceCount}:${cnonce}:auth:${HA2}`);
const authorization = `Digest username="${username}", realm="${realm}", nonce="${nonce}", uri="${url}", cnonce="${cnonce}", nc=${nonceCount}, qop=auth, response="${response}", algorithm=SHA-256`;
axios(
{
...axiosRequestObj,
headers: {
'Authorization': authorization
}
}
).then(response => {
this.adapter.log.silly(`[requestAsync] HTTP response of gen 2 device with digest auth: "${axiosRequestObj.baseURL}${url}" -> "${response.data}"`);
resolve(response.data);
})
.catch(reject);
} else if (this.getDeviceGen() === 2) {
this.adapter.log.silly(`[requestAsync] HTTP request to gen 2 device with digest auth: "${url}"`);
const client = new DigestFetch('admin', this.adapter.config.httppassword, { algorithm: 'MD5' }); // Username is always admin
client.fetch(url, {timeout: this.httptimeout})
.then(res => res.text())
.then(text => {
this.adapter.log.silly(`[requestAsync] HTTP response of gen 2 device with digest auth: "${url}" -> "${text}"`);
resolve(text);
})
.catch(reject);
}
} else {
this.adapter.log.silly(`[requestAsync] HTTP request to gen ${this.getDeviceGen()} device without auth: "${url}"`);
fetch(url, {timeout: this.httptimeout})
.then(res => res.text())
.then(text => {
this.adapter.log.silly(`[requestAsync] HTTP response of gen ${this.getDeviceGen()} device without auth: "${url}" -> "${text}"`);
resolve(text);
})
.catch(reject);
} else {
reject(err);
}
})
.catch(reject);
}

@@ -139,3 +194,3 @@ });

/**
* Returns a string for logging with the IP address and name of Shelly device and type
* Returns a string for logging with the IP address, name of device and type
*/

@@ -198,3 +253,3 @@ getName() {

/**
* Missing data will be pulled by http
* Missing data will be pulled by HTTP
*/

@@ -207,14 +262,17 @@ async httpIoBrokerState() {

this.adapter.log.silly(`[httpIoBrokerState] Running for ${this.getName()}: ${JSON.stringify(this.http)}`);
let polltime = this.getPolltime();
for (const i in this.http) {
const states = this.http[i];
for (const httpUrl in this.http) {
const states = this.http[httpUrl];
try {
const body = await this.requestAsync('http://' + this.getIP() + i);
const body = await this.requestAsync(httpUrl);
for (const j in states) {
const state = this.device[states[j]];
if (state && state.state) {
const deviceid = this.getDeviceName();
const stateid = deviceid + '.' + state.state;
const stateid = `${this.getDeviceName()}.${state.state}`;
let value = body;
try {
this.adapter.log.silly(`[httpIoBrokerState] Updating state ${stateid} for ${this.getName()}: ${body}`);
if (state[this.type] && state[this.type].http_publish_funct) {

@@ -235,13 +293,7 @@ value = isAsync(state[this.type].http_publish_funct) ? await state[this.type].http_publish_funct(value, this) : state[this.type].http_publish_funct(value, this);

}
} catch (error) {
if (error.name && error.name.startsWith('TypeError')) {
this.adapter.log.debug(`Could not find property for state ${stateid} for ${this.getName()}: ${error}`);
} catch (err) {
if (err.name && err.name.startsWith('TypeError')) {
this.adapter.log.debug(`[httpIoBrokerState] Could not find property for state ${stateid} for ${this.getName()}: ${err}`);
} else {
if (polltime > 0 && polltime < 60) polltime = 60;
if (body && body === '401 Unauthorized') {
this.adapter.log.error(`Error in function httpIoBrokerState for state ${stateid} for ${this.getName()}: Wrong http username or http password! Please enter user credentials for restricted login.`);
break;
} else {
this.adapter.log.error(`Error in function httpIoBrokerState for state ${stateid} for ${this.getName()}: ${error} - value: "${value}"`);
}
this.adapter.log.error(`[httpIoBrokerState] Error for state ${stateid} for ${this.getName()}: ${err} - value: "${value}"`);
}

@@ -253,4 +305,12 @@ }

this.objectHelper.processObjectQueue(() => { });
} catch (error) {
this.adapter.log.debug(`HTTP request (httpIoBrokerState) error: ${JSON.stringify(error)}`);
} catch (err) {
// Increase polltime on http error
if (polltime > 0 && polltime < 60) polltime = 60;
if (err && err.response && err.response.status == 401) {
this.adapter.log.error(`[httpIoBrokerState] HTTP request error for ${this.getName()} "${httpUrl}": Wrong http username or http password! Please enter user credentials for restricted login.`);
} else if (err && err.response && err.response.status == 404) {
this.adapter.log.debug(`[httpIoBrokerState] HTTP request error for ${this.getName()} "${httpUrl}": 404 Not Found - this can happen if the current device configuration doesn't support this feature.`);
} else {
this.adapter.log.debug(`[httpIoBrokerState] HTTP request error for ${this.getName()} "${httpUrl}": ${err}`);
}
}

@@ -272,19 +332,19 @@ }

if (Object.keys(this.device).length === 0) {
let devices = datapoints.getDeviceByType(this.getDeviceId(), this.type);
if (devices) {
let deviceStates = datapoints.getDeviceByType(this.getDeviceId(), this.type);
if (deviceStates) {
if (this.type === 'coap') {
devices = recursiveSubStringReplace(devices, new RegExp('<devicetype>', 'g'), this.getDeviceId());
devices = recursiveSubStringReplace(devices, new RegExp('<deviceid>', 'g'), this.getSerialId());
deviceStates = recursiveSubStringReplace(deviceStates, new RegExp('<devicetype>', 'g'), this.getDeviceId());
deviceStates = recursiveSubStringReplace(deviceStates, new RegExp('<deviceid>', 'g'), this.getSerialId());
}
if (this.type === 'mqtt') {
devices = recursiveSubStringReplace(devices, new RegExp('<mqttprefix>', 'g'), this.mqttprefix);
deviceStates = recursiveSubStringReplace(deviceStates, new RegExp('<mqttprefix>', 'g'), this.mqttprefix);
}
for (const j in devices) {
for (const statename in deviceStates) {
const state = deviceStates[statename];
state.state = statename;
let hasTypeCmd = false;
let hasTypePublishCmd = false;
const statename = j;
const state = devices[statename];
state.state = statename;

@@ -312,2 +372,3 @@ if (this.type === 'coap') {

}
const channel = statename.split('.').slice(0, 1).join();

@@ -326,5 +387,7 @@ if (channel !== statename) {

}
const stateid = deviceid + '.' + statename;
let controlFunction;
// HTTP
if (state[this.type] && state[this.type].http_cmd && !hasTypeCmd) {

@@ -335,2 +398,6 @@ this.adapter.log.silly(`[http controlFunction] Found ${this.type}.http_cmd of state ${stateid} for ${this.getName()}`);

// Confirm new value
this.adapter.setStateAsync(stateid, {val: value, ack: true});
// Modify value with cmd_funct (if exists)
if (state[this.type] && state[this.type].http_cmd_funct) {

@@ -347,19 +414,24 @@ try {

try {
// Append value parameters
const url = new URL('http://' + this.getIP() + state[this.type].http_cmd);
if (typeof value === 'object') {
Object.keys(value).forEach(key => url.searchParams.append(key, value[key]));
}
if (this.getDeviceGen() === 1) {
// Append value parameters
const url = new URL('http://' + this.getIP() + state[this.type].http_cmd);
if (typeof value === 'object') {
Object.keys(value).forEach(key => url.searchParams.append(key, value[key]));
}
this.adapter.log.debug(`[http controlFunction] Executing state.${this.type}.http_cmd of state ${stateid} for ${this.getName()} from url: ${url.href}`);
body = await this.requestAsync(url.href);
this.adapter.log.debug(`[http controlFunction] Executing gen 1 state.${this.type}.http_cmd of state ${stateid} for ${this.getName()} from url: ${url.href}`);
body = await this.requestAsync(url.pathname + url.search);
if (body === 'Bad default state and button type combination!') {
this.adapter.log.error(`[http controlFunction] Error in function state.${this.type}.http_cmd of state ${stateid} for ${this.getName()}: ${body}`);
if (body === 'Bad default state and button type combination!') {
this.adapter.log.error(`[http controlFunction] Error in function state.${this.type}.http_cmd of state ${stateid} for ${this.getName()}: ${body}`);
}
} else if (this.getDeviceGen() === 2) {
// Not supported
}
} catch (error) {
if (body && body === '401 Unauthorized') {
} catch (err) {
if (err && err.response && err.response.status == 401) {
this.adapter.log.error(`[http controlFunction] Error in function state.${this.type}.http_cmd of state ${stateid} for ${this.getName()}: Wrong http username or http password! Please enter user credentials for restricted login.`);
} else {
this.adapter.log.error(`[http controlFunction] Error in function state.${this.type}.http_cmd of state ${stateid} for ${this.getName()}: ${error}`);
this.adapter.log.error(`[http controlFunction] Error in function state.${this.type}.http_cmd of state ${stateid} for ${this.getName()}: ${err}`);
}

@@ -376,3 +448,7 @@ }

controlFunction = async (value) => {
const cmd = state[this.type].mqtt_cmd;
// Confirm new value
this.adapter.setStateAsync(stateid, {val: value, ack: true});
// Modify value with cmd_funct (if exists)
if (state[this.type] && state[this.type].mqtt_cmd_funct) {

@@ -386,4 +462,5 @@ try {

}
this.sendState2Client(cmd, value, this.adapter.config.qos); // TODO: Abstract method?
this.sendState2Client(state[this.type].mqtt_cmd, value, this.adapter.config.qos); // TODO: Abstract method?
delete this.states[stateid];

@@ -393,4 +470,8 @@ };

// Fill this.http object for httpIoBrokerState()
if (state[this.type] && state[this.type].http_publish && !hasTypePublishCmd) {
if (!this.http[state[this.type].http_publish]) this.http[state[this.type].http_publish] = [];
if (!this.http[state[this.type].http_publish]) {
this.http[state[this.type].http_publish] = [];
}
this.http[state[this.type].http_publish].push(statename);

@@ -415,3 +496,3 @@ }

}
this.device = devices;
this.device = deviceStates;
}

@@ -511,6 +592,7 @@

if (this.getDeviceGen() === 1) {
const body = await this.requestAsync('http://' + this.getIP() + '/ota?update=true');
const body = await this.requestAsync('/ota?update=true');
this.adapter.log.debug(`[firmwareUpdate] Update result for ${this.getName()}: ${body}`);
} else if (this.getDeviceGen() === 2) {
// TODO
const body = await this.requestAsync('/rpc/Shelly.Update');
this.adapter.log.debug(`[firmwareUpdate] Update result for ${this.getName()}: ${body}`);
}

@@ -524,23 +606,20 @@ }

destroy() {
if (this.active) {
this.adapter.log.debug(`Destroy ${this.getName()}`);
this.adapter.log.debug(`Destroy ${this.getName()}`);
clearTimeout(this.httpIoBrokerStateTimeout);
clearTimeout(this.firmwareUpdatePollingTimeout);
clearTimeout(this.httpIoBrokerStateTimeout);
clearTimeout(this.firmwareUpdatePollingTimeout);
this.active = false;
this.states = {};
this.device = {};
this.http = {};
this.states = {};
this.device = {};
this.http = {};
this.devicename = undefined;
this.ip = undefined;
this.devicename = undefined;
this.ip = undefined;
this.id = undefined;
this.devicetype = undefined;
this.deviceid = undefined;
this.serialid = undefined;
this.deviceexists = undefined;
this.devicegen = undefined;
}
this.id = undefined;
this.devicetype = undefined;
this.deviceid = undefined;
this.serialid = undefined;
this.deviceexists = undefined;
this.devicegen = undefined;
}

@@ -547,0 +626,0 @@ }

@@ -351,3 +351,3 @@ /* jshint -W097 */

try {
body = await this.requestAsync('http://' + this.getIP() + '/settings');
body = await this.requestAsync('/settings');
if (body) {

@@ -358,7 +358,7 @@ const settings = JSON.parse(body);

}
} catch (error) {
if (body && body === '401 Unauthorized') {
} catch (err) {
if (err && err.response && err.response.status == 401) {
this.adapter.log.error(`[MQTT] Wrong http username or http password! Please enter the user credential from restricted login for ${this.getName()}`);
} else {
this.adapter.log.error(`[MQTT] Error in function setMqttPrefixHttp() for request' + JSON.stringify(params) + ' for ${this.getName()}: ${error}`);
this.adapter.log.error(`[MQTT] Error in function setMqttPrefixHttp() for request ${JSON.stringify(params)} for ${this.getName()}: ${err}`);
}

@@ -461,2 +461,14 @@ }

this.adapter.log.debug(`[MQTT] Publish: ${this.getName()} - topic: ${packet.topic}, payload: ${packet.payload.toString()}`);
// Error handling for Gen 2 devices
if (packet.topic == 'iobroker/rpc') {
try {
const payloadObj = JSON.parse(packet.payload.toString());
if (Object.prototype.hasOwnProperty.call(payloadObj, 'error')) {
this.adapter.log.error(`[MQTT] Received error message from "${payloadObj.src}": ${JSON.stringify(payloadObj.error)}`);
}
} catch (err) {
}
}
}

@@ -463,0 +475,0 @@

@@ -24,30 +24,21 @@ /* jshint -W097 */

/**
* Fahrenheit to Celsius
* @param {number} fahrenheit - 20
*/
function fahrenheitToCelsius(fahrenheit) {
try {
const celsius = (fahrenheit - 32) * 5 / 9;
return Math.round(celsius * 100) / 100;
} catch (error) {
return undefined;
}
}
/**
*
* @param {*} self
* @param {*} devicename - Name of the device like 'livingroom'
* @param {*} name - Name of the device
*/
async function setDeviceName(self, devicename) {
const name = devicename;
const deviceid = self.getDeviceName();
const obj = await self.adapter.getObjectAsync(deviceid);
// if (!name) name = 'Device ' + deviceid;
async function setDeviceName(self, name) {
const deviceId = self.getDeviceName();
const obj = await self.adapter.getObjectAsync(deviceId);
if (name && obj && obj.common && name !== obj.common.name) {
obj.common.name = name;
await self.adapter.setObjectAsync(deviceid, obj);
self.states[deviceid] = name;
await self.adapter.extendObjectAsync(deviceId, {
common: {
name: name
}
});
self.states[deviceId] = name;
}
return devicename;
return name;
}

@@ -58,22 +49,22 @@

* @param {*} self
* @param {*} state - channel like Relay0.Channel
* @param {*} channelename - Name of the channel like 'channel 1 like livingroom'
* @param {*} id - channel id like Relay0
* @param {*} name - Name of the channel
*/
async function setChannelName(self, state, channelename) {
const name = channelename;
const channel = state.split('.').slice(0, -1).join();
if (channel) {
const channelid = self.getDeviceName() + '.' + channel;
const obj = await self.adapter.getObjectAsync(channelid);
// if (!name) name = 'Channel ' + state.split('.').slice(0, 1).join();
if (name && obj && obj.common && name !== obj.common.name) {
obj.common.name = name;
await self.adapter.setObjectAsync(channelid, obj);
self.states[channelid] = name;
}
async function setChannelName(self, id, name) {
const channelId = self.getDeviceName() + '.' + id;
const obj = await self.adapter.getObjectAsync(channelId);
if (name && obj && obj.common && name !== obj.common.name) {
await self.adapter.extendObjectAsync(channelId, {
common: {
name: name
}
});
self.states[channelId] = name;
}
return channelename;
return name;
}
/**

@@ -242,4 +233,2 @@ * returns seconds in format daysDTT:MM:SS

async function getHsvFromRgb(self) {

@@ -285,3 +274,3 @@ const value = await getRGBW(self);

if (statePower && stateReactivePower) {
// let voltage = stateVoltage.val;
// let voltage = stateVoltage.val;
const power = statePower.val;

@@ -311,3 +300,2 @@ const reactive = stateReactivePower.val;

async function getTotalReturnedSumm(self) {

@@ -323,3 +311,2 @@ let calctotal = 0.00;

/**

@@ -417,38 +404,481 @@ * For EM3, it was not a good idea to implement this function. To far away from standard

/**
*
* @param {*} self - self object
* @param {*} id - id of state like relay0.switch
* @param {*} value - value like true
* @param {*} initvalue - value like false
* @param {*} ms - time in ms
* Adds a generic switch definition for gen 2 devices
* @param {*} deviceObj
* @param {*} switchId
*/
function setAndInitValue(self, id, value, initvalue, ms) {
id = self.getDeviceName() + '.' + id;
if (!ms) ms = 100;
if (value != initvalue) setTimeout(async () => {
self.states[id] = initvalue;
await self.adapter.setStateAsync(id, { val: initvalue, ack: true });
}, ms);
return value;
function addSwitchToGen2Device(deviceObj, switchId) {
deviceObj[`Relay${switchId}.Switch`] = {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, `switch:${switchId}`) &&
Object.prototype.hasOwnProperty.call(valueObj.params[`switch:${switchId}`], 'output')
) {
return valueObj.params[`switch:${switchId}`].output;
}
return undefined;
},
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 1, src: 'iobroker', method: 'Switch.Set', params: {id: switchId, on: value}}); }
},
common: {
'name': 'Switch',
'type': 'boolean',
'role': 'switch.power',
'read': true,
'write': true,
'def': false
}
};
deviceObj[`Relay${switchId}.InputMode`] = {
mqtt: {
http_publish: `/rpc/Switch.GetConfig?id=${switchId}`,
http_publish_funct: async (value, self) => { return value ? JSON.parse(value).in_mode : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Switch.SetConfig', params: {id: switchId, config: {in_mode: value}}}); }
},
common: {
'name': 'Input Mode',
'type': 'string',
'role': 'state',
'read': true,
'write': true,
'states': {
'momentary': 'momentary',
'follow': 'follow',
'flip': 'flip',
'detached': 'detached'
}
}
};
deviceObj[`Relay${switchId}.InitialState`] = {
mqtt: {
http_publish: `/rpc/Switch.GetConfig?id=${switchId}`,
http_publish_funct: async (value, self) => { return value ? JSON.parse(value).initial_state : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Switch.SetConfig', params: {id: switchId, config: {initial_state: value}}}); }
},
common: {
'name': 'Initial State',
'type': 'string',
'role': 'state',
'read': true,
'write': true,
'states': {
'on': 'on',
'off': 'off',
'restore_last': 'restore_last',
'match_input': 'match_input'
}
}
};
deviceObj[`Relay${switchId}.ChannelName`] = {
mqtt: {
http_publish: `/rpc/Switch.GetConfig?id=${switchId}`,
http_publish_funct: async (value, self) => { return value ? await setChannelName(self, `Relay${switchId}`, JSON.parse(value).name) : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Switch.SetConfig', params: {id: switchId, config: {name: value}}}); }
},
common: {
'name': 'Channel Name',
'type': 'string',
'role': 'state',
'read': true,
'write': true,
'def': `switch_${switchId}`
}
};
deviceObj[`Relay${switchId}.AutoTimerOn`] = {
mqtt: {
http_publish: `/rpc/Switch.GetConfig?id=${switchId}`,
http_publish_funct: async (value, self) => { return value ? JSON.parse(value).auto_on : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Switch.SetConfig', params: {id: switchId, config: {auto_on: value}}}); }
},
common: {
'name': 'Auto Timer On',
'type': 'boolean',
'role': 'switch.enable',
'def': false,
'read': true,
'write': true
}
};
deviceObj[`Relay${switchId}.AutoTimerOnDelay`] = {
mqtt: {
http_publish: `/rpc/Switch.GetConfig?id=${switchId}`,
http_publish_funct: async (value, self) => { return value ? JSON.parse(value).auto_on_delay : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Switch.SetConfig', params: {id: switchId, config: {auto_on_delay: value}}}); }
},
common: {
'name': 'Auto Timer On Delay',
'type': 'number',
'role': 'level.timer',
'def': 0,
'unit': 's',
'read': true,
'write': true
}
};
deviceObj[`Relay${switchId}.AutoTimerOff`] = {
mqtt: {
http_publish: `/rpc/Switch.GetConfig?id=${switchId}`,
http_publish_funct: async (value, self) => { return value ? JSON.parse(value).auto_off : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Switch.SetConfig', params: {id: switchId, config: {auto_off: value}}}); }
},
common: {
'name': 'Auto Timer Off',
'type': 'boolean',
'role': 'switch.enable',
'def': false,
'read': true,
'write': true
}
};
deviceObj[`Relay${switchId}.AutoTimerOffDelay`] = {
mqtt: {
http_publish: `/rpc/Switch.GetConfig?id=${switchId}`,
http_publish_funct: async (value, self) => { return value ? JSON.parse(value).auto_off_delay : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Switch.SetConfig', params: {id: switchId, config: {auto_off_delay: value}}}); }
},
common: {
'name': 'Auto Timer Off Delay',
'type': 'number',
'role': 'level.timer',
'def': 0,
'unit': 's',
'read': true,
'write': true
}
};
deviceObj[`Relay${switchId}.source`] = {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, `switch:${switchId}`) &&
Object.prototype.hasOwnProperty.call(valueObj.params[`switch:${switchId}`], 'source')
) {
return valueObj.params[`switch:${switchId}`].source;
}
return undefined;
}
},
common: {
'name': 'Source of last command',
'type': 'string',
'role': 'state',
'read': true,
'write': false
}
};
}
/**
*
* @param {*} self - self object
* @param {*} id - id of state like relay0.switch
* @param {*} value - value like false or 'huhu'
* Adds a generic input definition for gen 2 devices
* @param {*} deviceObj
* @param {*} inputId
*/
async function setValueForId(self, id, value) {
id = self.getDeviceName() + '.' + id;
await self.adapter.setStateAsync(id, { val: value, ack: true });
function addInputToGen2Device(deviceObj, inputId) {
deviceObj[`Input${inputId}.Status`] = {
mqtt: {
mqtt_publish: `<mqttprefix>/status/input:${inputId}`,
mqtt_publish_funct: (value) => { return JSON.parse(value).state; }
},
common: {
'name': 'Input Status',
'type': 'boolean',
'role': 'state',
'read': true,
'write': false
}
};
deviceObj[`Input${inputId}.ChannelName`] = {
mqtt: {
http_publish: `/rpc/Input.GetConfig?id=${inputId}`,
http_publish_funct: async (value, self) => { return value ? await setChannelName(self, `Input${inputId}`, JSON.parse(value).name) : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Input.SetConfig', params: {id: inputId, config: {name: value}}}); }
},
common: {
'name': 'Channel Name',
'type': 'string',
'role': 'state',
'read': true,
'write': true,
'def': `input_${inputId}`
}
};
deviceObj[`Input${inputId}.Event`] = {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyEvent' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, 'events')
) {
for (const e in valueObj.params.events) {
const event = valueObj.params.events[e];
if (typeof event === 'object' && event.component === `input:${inputId}`) {
return event.event;
}
}
}
return undefined;
}
},
common: {
'name': 'Input Event',
'type': 'string',
'role': 'state',
'read': true,
'write': false
}
};
deviceObj[`Input${inputId}.InputType`] = {
mqtt: {
http_publish: `/rpc/Input.GetConfig?id=${inputId}`,
http_publish_funct: async (value, self) => { return value ? JSON.parse(value).type : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Input.SetConfig', params: {id: inputId, config: {type: value}}}); }
},
common: {
'name': 'Input Type',
'type': 'string',
'role': 'state',
'read': true,
'write': true,
'states': {
'button': 'button',
'switch': 'switch'
}
}
};
deviceObj[`Input${inputId}.InputInverted`] = {
mqtt: {
http_publish: `/rpc/Input.GetConfig?id=${inputId}`,
http_publish_funct: async (value, self) => { return value ? JSON.parse(value).invert : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Input.SetConfig', params: {id: inputId, config: {invert: value}}}); }
},
common: {
'name': 'Input Inverted',
'type': 'boolean',
'role': 'state',
'read': true,
'write': true
}
};
}
async function getValue(self, id) {
try {
if (id && id[0] !== '.') id = '.' + id;
const state = await self.adapter.getStateAsync(self.getDeviceName() + id);
if (state) { return state.val; } else { return undefined; }
} catch (error) {
return undefined;
}
/**
* Adds a generic cover definition for gen 2 devices
* @param {*} deviceObj
* @param {*} inputId
*/
function addCoverToGen2Device(deviceObj, coverId) {
deviceObj[`Cover${coverId}.Open`] = {
mqtt: {
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Cover.Open', params: {id: coverId}}); }
},
common: {
'name': 'Open',
'type': 'boolean',
'role': 'button',
'read': false,
'write': true
}
};
deviceObj[`Cover${coverId}.InitialState`] = {
mqtt: {
http_publish: `/rpc/Cover.GetConfig?id=${coverId}`,
http_publish_funct: async (value, self) => { return value ? JSON.parse(value).initial_state : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Cover.SetConfig', params: {id: coverId, config: {initial_state: value}}}); }
},
common: {
'name': 'Initial State',
'type': 'string',
'role': 'state',
'read': true,
'write': true,
'states': {
'open': 'oopenn',
'closed': 'closed',
'stopped': 'stopped'
}
}
};
deviceObj[`Cover${coverId}.ChannelName`] = {
mqtt: {
http_publish: `/rpc/Cover.GetConfig?id=${coverId}`,
http_publish_funct: async (value, self) => { return value ? await setChannelName(self, `Cover${coverId}`, JSON.parse(value).name) : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Cover.SetConfig', params: {id: coverId, config: {name: value}}}); }
},
common: {
'name': 'Channel Name',
'type': 'string',
'role': 'state',
'read': true,
'write': true,
'def': `cover_${coverId}`
}
};
deviceObj[`Cover${coverId}.Stop`] = {
mqtt: {
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Cover.Stop', params: {id: coverId}}); }
},
common: {
'name': 'Stop',
'type': 'boolean',
'role': 'button',
'read': false,
'write': true
}
};
deviceObj[`Cover${coverId}.Close`] = {
mqtt: {
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Cover.Close', params: {id: coverId}}); }
},
common: {
'name': 'Close',
'type': 'boolean',
'role': 'button',
'read': false,
'write': true
}
};
deviceObj[`Cover${coverId}.Calibrate`] = {
mqtt: {
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Cover.Calibrate', params: {id: coverId}}); }
},
common: {
'name': 'Calibrate',
'type': 'boolean',
'role': 'button',
'read': false,
'write': true
}
};
deviceObj[`Cover${coverId}.InputSwap`] = {
mqtt: {
http_publish: `/rpc/Cover.GetConfig?id=${coverId}`,
http_publish_funct: async (value, self) => { return value ? JSON.parse(value).swap_inputs : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Cover.SetConfig', params: {id: coverId, config: {swap_inputs: value}}}); }
},
common: {
'name': 'Input Swap',
'type': 'boolean',
'role': 'switch.enable',
'read': true,
'write': true
}
};
deviceObj[`Cover${coverId}.InputMode`] = {
mqtt: {
http_publish: `/rpc/Cover.GetConfig?id=${coverId}`,
http_publish_funct: async (value, self) => { return value ? JSON.parse(value).in_mode : undefined; },
mqtt_cmd: '<mqttprefix>/rpc',
mqtt_cmd_funct: (value) => { return JSON.stringify({id: 0, src: 'iobroker', method: 'Cover.SetConfig', params: {id: coverId, config: {in_mode: value}}}); }
},
common: {
'name': 'Input Mode',
'type': 'string',
'role': 'state',
'read': true,
'write': true,
'states': {
'single': 'single',
'dual': 'dual',
'detached': 'detached'
}
}
};
deviceObj[`Cover${coverId}.Status`] = {
mqtt: {
mqtt_publish: `<mqttprefix>/status/cover:${coverId}`,
mqtt_publish_funct: (value) => { return JSON.parse(value).state; }
},
common: {
'name': 'Cover Status',
'type': 'string',
'role': 'state',
'read': true,
'write': false
}
};
deviceObj[`Cover${coverId}.source`] = {
mqtt: {
mqtt_publish: '<mqttprefix>/events/rpc',
mqtt_publish_funct: (value) => {
const valueObj = JSON.parse(value);
if (
Object.prototype.hasOwnProperty.call(valueObj, 'method') &&
valueObj.method === 'NotifyStatus' &&
Object.prototype.hasOwnProperty.call(valueObj, 'params') &&
Object.prototype.hasOwnProperty.call(valueObj.params, `cover:${coverId}`) &&
Object.prototype.hasOwnProperty.call(valueObj.params[`cover:${coverId}`], 'source')
) {
return valueObj.params[`cover:${coverId}`].source;
}
return undefined;
}
},
common: {
'name': 'Source of last command',
'type': 'string',
'role': 'state',
'read': true,
'write': false
}
};
}

@@ -458,3 +888,2 @@

celsiusToFahrenheit: celsiusToFahrenheit,
fahrenheitToCelsius: fahrenheitToCelsius,
setDeviceName: setDeviceName,

@@ -481,5 +910,5 @@ setChannelName: setChannelName,

getRGBW: getRGBW,
setAndInitValue: setAndInitValue,
setValueForId: setValueForId,
getValue: getValue
addSwitchToGen2Device: addSwitchToGen2Device,
addInputToGen2Device: addInputToGen2Device,
addCoverToGen2Device: addCoverToGen2Device
};
{
"name": "iobroker.shelly",
"version": "5.1.3",
"version": "5.2.0",
"description": "Shelly",

@@ -41,7 +41,7 @@ "author": {

"@iobroker/adapter-core": "^2.5.1",
"axios": "^0.26.0",
"coiot-coap": "^1.0.0",
"digest-fetch": "^1.2.1",
"crypto": "^1.0.1",
"mqtt": "^4.3.5",
"mqtt-connection": "^4.1.0",
"node-fetch": "^2.6.7",
"shelly-iot": "^1.1.2",

@@ -58,17 +58,16 @@ "tcp-ping": "^0.1.1",

"@types/chai": "^4.3.0",
"@types/chai-as-promised": "^7.1.4",
"@types/chai-as-promised": "^7.1.5",
"@types/gulp": "^4.0.9",
"@types/mocha": "^9.1.0",
"@types/node": "^17.0.16",
"@types/node": "^17.0.18",
"@types/proxyquire": "^1.3.28",
"@types/sinon": "^10.0.11",
"@types/sinon-chai": "^3.2.8",
"axios": "^0.25.0",
"chai": "^4.3.6",
"chai-as-promised": "^7.1.1",
"eslint": "^8.8.0",
"eslint": "^8.9.0",
"gulp": "^4.0.2",
"mocha": "^9.2.0",
"proxyquire": "^2.1.3",
"sinon": "^12.0.1",
"sinon": "^13.0.1",
"sinon-chai": "^3.7.0",

@@ -75,0 +74,0 @@ "typescript": "~4.5.4"

@@ -65,2 +65,7 @@ ![Logo](admin/shelly.png)

|Shelly Plus 1 PM (shellyplus1pm)|---|supported since v5.0.0|
|Shelly Plus 2 PM (shellyplus2pm)|---|supported since v5.2.0|
|Shelly Pro 1 (shellypro1)|---|supported since v5.2.0|
|Shelly Pro 1 PM (shellypro1pm)|---|supported since v5.2.0|
|Shelly Pro 2 (shellypro2)|---|supported since v5.2.0|
|Shelly Pro 2 PM (shellypro2pm)|---|supported since v5.2.0|
|Shelly Pro 4 PM (shellypro4pm)|---|supported since v5.0.0|

@@ -86,2 +91,15 @@

-->
### 5.2.0 (2022-02-16)
* (klein0r) Added Shelly Pro 1
* (klein0r) Added Shelly Pro 1 PM
* (klein0r) Added Shelly Pro 2
* (klein0r) Added Shelly Pro 2 PM
* (klein0r) Added Shelly Plus 2 PM
* (klein0r) Allow to change device and channel names of generation 2 devices
* (klein0r) Added auto on/off timers for generation 2 devices
* (klein0r) Added input mode, events and initial state for generation 2 devices
* (klein0r) Added support of covers / shutters for generation 2 devices
* (klein0r) Replaced node-fetch with axios (also for digest auth)
### 5.1.3 (2022-02-13)

@@ -88,0 +106,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc