diff --git a/admin/i18n/de/translations.json b/admin/i18n/de/translations.json index 13d4b71..bb4a2b6 100644 --- a/admin/i18n/de/translations.json +++ b/admin/i18n/de/translations.json @@ -1,6 +1,7 @@ { - "gree-hvac adapter settings": "Gree HVAC Adapter Einstellungen", - "devicelist": "Geräte-IPs, begrenzt durch Semikolon", - "pollInterval": "Polierintervall in Millisekunden" - -} \ No newline at end of file + "gree-hvac adapter settings": "Gree HVAC-Adaptereinstellungen", + "devicelist": "Geräte-IPs", + "pollInterval": "Abfrageintervall in Millisekunden", + "deviceIp": "Geräte-IP", + "enterDeviceIp": "Geben Sie die Geräte-IP ein" + } \ No newline at end of file diff --git a/admin/i18n/en/translations.json b/admin/i18n/en/translations.json index fd01eef..b500f46 100644 --- a/admin/i18n/en/translations.json +++ b/admin/i18n/en/translations.json @@ -1,5 +1,7 @@ { - "gree-hvac adapter settings": "Gree HVAC adapter settings", - "devicelist": "Device IPs, delimited by semicolon", - "pollInterval": "Polling interval in milliseconds" + "gree-hvac adapter settings": "Gree HVAC-Adaptereinstellungen", + "devicelist": "Geräte-IPs", + "pollInterval": "Abfrageintervall in Millisekunden", + "deviceIp": "Geräte-IP", + "enterDeviceIp": "Geben Sie die Geräte-IP ein" } \ No newline at end of file diff --git a/admin/i18n/es/translations.json b/admin/i18n/es/translations.json index 52d8920..bb72941 100644 --- a/admin/i18n/es/translations.json +++ b/admin/i18n/es/translations.json @@ -1,5 +1,7 @@ { "gree-hvac adapter settings": "Ajustes de adaptador HVAC Gree", - "devicelist": "IPs de dispositivos, delimitados por semicolon", - "pollInterval": "Intervalo de votación en milisegundos" + "pollInterval": "Intervalo de votación en milisegundos", + "deviceList": "IP del dispositivo", + "deviceIp": "IP del dispositivo", + "enterDeviceIp": "Ingrese la IP del dispositivo" } \ No newline at end of file diff --git a/admin/i18n/fr/translations.json b/admin/i18n/fr/translations.json index 1e73f88..705cdcf 100644 --- a/admin/i18n/fr/translations.json +++ b/admin/i18n/fr/translations.json @@ -1,5 +1,7 @@ { "gree-hvac adapter settings": "Paramètres de l'adaptateur Gree CVC", - "devicelist": "IP du périphérique, délimité par un point-virgule", - "pollInterval": "Intervalle de scrutin en millisecondes" + "pollInterval": "Intervalle de scrutin en millisecondes", + "deviceList": "IP des appareils", + "deviceIp": "IP de l'appareil", + "enterDeviceIp": "Entrez l'adresse IP de l'appareil" } \ No newline at end of file diff --git a/admin/i18n/it/translations.json b/admin/i18n/it/translations.json index 794cfdc..ad0eb26 100644 --- a/admin/i18n/it/translations.json +++ b/admin/i18n/it/translations.json @@ -1,5 +1,7 @@ { "gree-hvac adapter settings": "Impostazioni dell'adattatore Gree HVAC", - "devicelist": "Dispositivi IP, delimitati da semicolon", - "pollInterval": "Intervallo di inquinamento in millisecondi" + "pollInterval": "Intervallo di inquinamento in millisecondi", + "deviceList": "IP del dispositivo", + "deviceIp": "IP del dispositivo", + "enterDeviceIp": "Inserisci l'IP del dispositivo" } \ No newline at end of file diff --git a/admin/i18n/nl/translations.json b/admin/i18n/nl/translations.json index fd59641..92729fc 100644 --- a/admin/i18n/nl/translations.json +++ b/admin/i18n/nl/translations.json @@ -1,5 +1,7 @@ { "gree-hvac adapter settings": "Gree HVAC-adapterinstellingen", - "devicelist": "Apparaat IP's, afgebakend door puntkomma", - "pollInterval": "Berekeninterval in milliseconden" + "pollInterval": "Berekeninterval in milliseconden", + "deviceList": "Apparaat-IP's", + "deviceIp": "Apparaat-IP", + "enterDeviceIp": "Voer het apparaat-IP in" } \ No newline at end of file diff --git a/admin/i18n/pl/translations.json b/admin/i18n/pl/translations.json index 126c601..e1c9f61 100644 --- a/admin/i18n/pl/translations.json +++ b/admin/i18n/pl/translations.json @@ -1,5 +1,7 @@ { "gree-hvac adapter settings": "Ustawienia adaptera Gree HVAC", - "devicelist": "Urządzenie IP, wyznaczone przez średnik", - "pollInterval": "Odstęp między badaniami w milisekundach" + "pollInterval": "Odstęp między badaniami w milisekundach", + "deviceList": "Adresy IP urządzeń", + "deviceIp": "Adres IP urządzenia", + "enterDeviceIp": "Wprowadź adres IP urządzenia" } \ No newline at end of file diff --git a/admin/i18n/pt/translations.json b/admin/i18n/pt/translations.json index de0dbd8..fc59b13 100644 --- a/admin/i18n/pt/translations.json +++ b/admin/i18n/pt/translations.json @@ -1,5 +1,7 @@ { "gree-hvac adapter settings": "Configurações do adaptador de HVAC da Gree", - "devicelist": "IPs do dispositivo, delimitado por ponto e vírgula", - "pollInterval": "Intervalo de polimento em milissegundos" + "pollInterval": "Intervalo de polimento em milissegundos", + "deviceList": "IPs de dispositivos", + "deviceIp": "IP do dispositivo", + "enterDeviceIp": "Insira o IP do dispositivo" } \ No newline at end of file diff --git a/admin/i18n/ru/translations.json b/admin/i18n/ru/translations.json index 43d662b..8dbe282 100644 --- a/admin/i18n/ru/translations.json +++ b/admin/i18n/ru/translations.json @@ -1,5 +1,7 @@ { "gree-hvac adapter settings": "Настройки адаптера Gree HVAC", - "devicelist": "IP устройств, разделенные точкой с запятой", - "pollInterval": "Интервал опроса в миллисекундах" + "devicelist": "IP устройств", + "pollInterval": "Интервал опроса в миллисекундах", + "deviceIp":"IP адрес устройства", + "enterDeviceIp": "Введите IP адрес устройства" } \ No newline at end of file diff --git a/admin/i18n/uk/translations.json b/admin/i18n/uk/translations.json index 93a73e9..797346d 100644 --- a/admin/i18n/uk/translations.json +++ b/admin/i18n/uk/translations.json @@ -1,5 +1,7 @@ { "gree-hvac adapter settings": "Налаштування адаптеру Gree HVAC", - "devicelist": "IP пристроїв, розділені крапкою з зап'ятою", - "pollInterval": "Інтервал опитування в міллісекундах" + "devicelist": "IP пристроїв", + "pollInterval": "Інтервал опитування в міллісекундах", + "deviceIp":"IP адреса пристрою", + "enterDeviceIp": "Введіть IP адресу пристрою" } \ No newline at end of file diff --git a/admin/i18n/zh-cn/translations.json b/admin/i18n/zh-cn/translations.json index 58c7440..884522f 100644 --- a/admin/i18n/zh-cn/translations.json +++ b/admin/i18n/zh-cn/translations.json @@ -1,5 +1,7 @@ { "gree-hvac adapter settings": "Gree HVAC 适配器设置", - "devicelist": "设备 IP, 用分号分隔", - "pollInterval": "投票间隔( 毫秒)" + "pollInterval": "投票间隔( 毫秒)", + "deviceList": "设备IP", + "deviceIp": "设备IP", + "enterDeviceIp": "输入设备IP" } \ No newline at end of file diff --git a/admin/jsonConfig.json b/admin/jsonConfig.json index 74333b3..470512e 100644 --- a/admin/jsonConfig.json +++ b/admin/jsonConfig.json @@ -3,14 +3,30 @@ "type": "panel", "items": { "devicelist": { - "type": "text", + "type": "table", "label": "devicelist", - "newLine": true + "newLine": true, + "items": [ + { + "type": "text", + "attr": "deviceIp", + "width": "200px", + "title": "deviceIp", + "tooltip": "enterDeviceIp", + "filter": false, + "sort": false, + "default": "" + } + ] }, "pollInterval": { "type": "number", "label": "pollInterval", - "newLine": true + "min": 1000, + "max": 60000, + "newLine": true, + "step": 1000, + "default": 5000 } } } \ No newline at end of file diff --git a/lib/connection.js b/lib/connection.js index 25b54d7..a732e3b 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -42,14 +42,12 @@ class Connection extends EventEmitter { return this.devices[deviceId] || defaultKey; } - scan(networks) { + scan(ipAddresses) { const message = Buffer.from(JSON.stringify({ t: 'scan' })); - this.socket.setBroadcast(true); - - networks.split(';').forEach((networkAddress) => { - this.logger.info(`Scanning network ${networkAddress} for available devices...`); - this.socket.send(message, 0, message.length, 7000, networkAddress); + ipAddresses.split(';').forEach((deviceAddress) => { + this.logger.info(`Test address ${deviceAddress} for available device`); + this.socket.send(message, 0, message.length, 7000, deviceAddress); }); } diff --git a/main.js b/main.js index dc07254..436dd8a 100644 --- a/main.js +++ b/main.js @@ -44,7 +44,7 @@ class GreeHvac extends utils.Adapter { this.log.error('You should config device list in adapter configuration page'); await this.stop(); } - this.log.info('Device list: ' + this.config.devicelist); + this.log.info('Device list: ' + JSON.stringify(this.config.devicelist)); this.log.info('Poll interval: ' + this.config.pollInterval); if (!this.validateIPList(this.config.devicelist)) { @@ -57,7 +57,10 @@ class GreeHvac extends utils.Adapter { await this.stop(); } - this.deviceManager = new DeviceManager(this.config.devicelist, this.log); + const devicesArray = this.config.devicelist.map(item => item.deviceIp); + const devices = devicesArray.join(';'); + + this.deviceManager = new DeviceManager(devices, this.log); this.deviceManager.on('device_bound', async (deviceId, device) => { try { @@ -66,6 +69,7 @@ class GreeHvac extends utils.Adapter { const deviceInterval = setInterval(() => this.getDeviceStatus(deviceId), this.config.pollInterval); this.intervals[deviceId] = deviceInterval; } catch (error) { + this.log.error(`Error in device_bound event for device ${deviceId}: ${error}`); this.sendError(error, `Error in device_bound event for device ${deviceId}`); } }); @@ -85,6 +89,7 @@ class GreeHvac extends utils.Adapter { async processDeviceStatus(deviceId, deviceStatus) { try { + deviceId = this.nameToId(deviceId); for (const key in deviceStatus) { if (Object.prototype.hasOwnProperty.call(deviceStatus, key)) { const value = deviceStatus[key]; @@ -103,43 +108,53 @@ class GreeHvac extends utils.Adapter { async processDevice(deviceId, device) { try { + deviceId = this.nameToId(deviceId); this.log.info(`Device ${deviceId} bound`); await this.setObjectNotExistsAsync(deviceId, { - type: 'state', + type: 'device', common: { name: deviceId, + }, + native: {}, + }); + + await this.setObjectNotExistsAsync(`${deviceId}.deviceInfo`, { + type: 'state', + common: { + name: 'Device Info', type: 'string', - role: 'variable', + role: 'info', read: true, write: false, }, - native: {}, + native: {} }); - await this.setStateAsync(deviceId, { val: JSON.stringify(device), ack: true }); + await this.setStateAsync(`${deviceId}.deviceInfo`, { val: JSON.stringify(device), ack: true }); for (const property of propertiesMap) { await this.setObjectNotExistsAsync(`${deviceId}.${property.name}`, JSON.parse(property.definition)); } - this.subscribeStates(`${deviceId}.*`); + this.subscribeStates('*'); } catch (error) { this.sendError(error, `Error in processDevice for device ${deviceId}`); } } + nameToId(pName) { + return (pName || '').replace(adapter.FORBIDDEN_CHARS, '_'); + } + validateIPList(ipList) { try { // Regular expression for IP address const ipPattern = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; - // Split the list by semicolon - const ips = ipList.split(';'); - // Validate each IP - for (const ip of ips) { - if (!ipPattern.test(ip)) { + for (const networkItem of ipList) { + if (!ipPattern.test(networkItem.deviceIp)) { return false; } } @@ -147,7 +162,7 @@ class GreeHvac extends utils.Adapter { // If all IPs are valid return true; } catch (error) { - this.sendError(error, 'Error in validateIPList'); + this.log.error(`Error in validateIPList: ${error}`); return false; } } @@ -175,7 +190,7 @@ class GreeHvac extends utils.Adapter { */ async onStateChange(id, state) { try { - if (state.ack === false) { + if (state && state.ack === false) { const { deviceId, devicePath, property } = this.getDeviceInfo(id); const mapItem = propertiesMap.find(item => item.name === property); if (mapItem) {