UNPKG

iobroker.mercury

Version:

Receiving data from electricity meters Mercury

1,006 lines (1,001 loc) 133 kB
'use strict'; const EventEmitter = require('events'); const event = new EventEmitter(); event.setMaxListeners(10); module.exports = event; const translate = function (w){ // PLEASE HELP WITH THE TRANSLATION const word = { 'DateTime': {ru: 'Дата/Время', en: 'Date Time'}, 'Serial number': {ru: 'Серийный номер', en: 'Serial number'}, 'Production date': {ru: 'Дата изготовления', en: 'Production date'}, 'Software version': {ru: 'Версия ПО', en: 'Software version'}, 'power': {ru: 'Мощность', en: 'Power'}, 'current': {ru: 'Ток', en: 'Current'}, 'voltage': {ru: 'Напряжение', en: 'Voltage'}, 'oneTarrifEnergyActive': {ru: 'Энергия по 1 тарифу', en: 'Energy at 1 tariff'}, 'twoTarrifEnergyActive': {ru: 'Энергия по 2 тарифу', en: 'Energy at 2 tariff'}, 'threeTarrifEnergyActive': {ru: 'Энергия по 3 тарифу', en: 'Energy at 3 tariff'}, 'fourTarrifEnergyActive': {ru: 'Энергия по 4 тарифу', en: 'Energy at 4 tariff'}, 'TotalEnergyActive': {ru: 'Энергия итого', en: 'Total energy'}, 'oneTarrifEnergy': {ru: 'Энергия по 1 тарифу', en: 'Energy at 1 tariff'}, 'twoTarrifEnergy': {ru: 'Энергия по 2 тарифу', en: 'Energy at 2 tariff'}, 'threeTarrifEnergy': {ru: 'Энергия по 3 тарифу', en: 'Energy at 3 tariff'}, 'fourTarrifEnergy': {ru: 'Энергия по 4 тарифу', en: 'Energy at 4 tariff'}, 'TotalEnergy': {ru: 'Энергия итого', en: 'Total energy'}, 'battery': {ru: 'Напряжение батарейки', en: 'Battery voltage'}, 'voltageOn': {ru: 'Время последнего включения напряжения', en: 'Time of the last voltage turn on'}, 'voltageOff': {ru: 'Время последнего отключения напряжения', en: 'Time of the last voltage turn off'}, 'limitPower': {ru: 'Лимит мощности', en: 'Power limit'}, 'limitEnergyMonth': {ru: 'Лимит энергии за месяц', en: 'Monthly energy limit'}, 'totalEnergyActivePlus': {ru: 'Энергия А+ итого', en: 'Energy A+ total'}, 'totalEnergyActiveMinus': {ru: 'Энергия А- итого', en: 'Energy A- total'}, 'totalEnergyReactivePlus': {ru: 'Энергия R+ итого', en: 'Energy R+ total'}, 'totalEnergyReactiveMinus': {ru: 'Энергия R- итого', en: 'Energy R- total'}, 'currentYearTotalEnergyActivePlus': {ru: 'Энергия А+ итого', en: 'Energy A+ total'}, 'currentYearTotalEnergyActiveMinus': {ru: 'Энергия А- итого', en: 'Energy A- total'}, 'currentYearTotalEnergyReactivePlus': {ru: 'Энергия R+ итого', en: 'Energy R+ total'}, 'currentYearTotalEnergyReactiveMinus': {ru: 'Энергия R- итого', en: 'Energy R- total'}, 'currentDayTotalEnergyActivePlus': {ru: 'Энергия А+ итого', en: 'Energy A+ total'}, 'currentDayTotalEnergyActiveMinus': {ru: 'Энергия А- итого', en: 'Energy A- total'}, 'currentDayTotalEnergyReactivePlus': {ru: 'Энергия R+ итого', en: 'Energy R+ total'}, 'currentDayTotalEnergyReactiveMinus': {ru: 'Энергия R- итого', en: 'Energy R- total'}, 'oneTarrifEnergyActivePlus': {ru: 'Энергия А+ 1 тариф', en: 'Energy A+ 1 tariff'}, 'oneTarrifEnergyActiveMinus': {ru: 'Энергия А- 1 тариф', en: 'Energy A- 1 tariff'}, 'oneTarrifEnergyReactivePlus': {ru: 'Энергия R+ 1 тариф', en: 'Energy R+ 1 tariff'}, 'oneTarrifEnergyReactiveMinus': {ru: 'Энергия R- 1 тариф', en: 'Energy R- 1 tariff'}, 'twoTarrifEnergyActivePlus': {ru: 'Энергия А+ 2 тариф', en: 'Energy A+ 1 tariff'}, 'twoTarrifEnergyActiveMinus': {ru: 'Энергия А- 2 тариф', en: 'Energy A- 1 tariff'}, 'twoTarrifEnergyReactivePlus': {ru: 'Энергия R+ 2 тариф', en: 'Energy R+ 1 tariff'}, 'twoTarrifEnergyReactiveMinus': {ru: 'Энергия R- 2 тариф', en: 'Energy R- 1 tariff'}, 'threeTarrifEnergyActivePlus': {ru: 'Энергия А+ 3 тариф', en: 'Energy A+ 1 tariff'}, 'threeTarrifEnergyActiveMinus': {ru: 'Энергия А- 3 тариф', en: 'Energy A- 1 tariff'}, 'threeTarrifEnergyReactivePlus': {ru: 'Энергия R+ 3 тариф', en: 'Energy R+ 1 tariff'}, 'threeTarrifEnergyReactiveMinus': {ru: 'Энергия R- 3 тариф', en: 'Energy R- 1 tariff'}, 'fourTarrifEnergyActivePlus': {ru: 'Энергия А+ 4 тариф', en: 'Energy A+ 1 tariff'}, 'fourTarrifEnergyActiveMinus': {ru: 'Энергия А- 4 тариф', en: 'Energy A- 1 tariff'}, 'fourTarrifEnergyReactivePlus': {ru: 'Энергия R+ 4 тариф', en: 'Energy R+ 1 tariff'}, 'fourTarrifEnergyReactiveMinus': {ru: 'Энергия R- 4 тариф', en: 'Energy R- 1 tariff'}, 'powerTotal': {ru: 'Активная мощность итого', en: 'Active power total'}, 'powerPhase1': {ru: 'Активная мощность 1 фаза', en: 'Active power 1 phase'}, 'powerPhase2': {ru: 'Активная мощность 2 фаза', en: 'Active power 2 phase'}, 'powerPhase3': {ru: 'Активная мощность 3 фаза', en: 'Active power 3 phase'}, 'voltagePhase1': {ru: 'Напряжение 1 фаза', en: 'Voltage 1 phase'}, 'voltagePhase2': {ru: 'Напряжение 2 фаза', en: 'Voltage 2 phase'}, 'voltagePhase3': {ru: 'Напряжение 3 фаза', en: 'Voltage 3 phase'}, 'currentPhase1': {ru: 'Ток 1 фаза', en: 'Current 1 phase'}, 'currentPhase2': {ru: 'Ток 2 фаза', en: 'Current 2 phase'}, 'currentPhase3': {ru: 'Ток 3 фаза', en: 'Current 3 phase'}, 'cosfTotal': {ru: 'Коэффициент мощности среднее', en: 'Power factor total'}, 'cosfPhase1': {ru: 'Коэффициент мощности 1 фаза', en: 'Power factor 1 phase'}, 'cosfPhase2': {ru: 'Коэффициент мощности 2 фаза', en: 'Power factor 2 phase'}, 'cosfPhase3': {ru: 'Коэффициент мощности 3 фаза', en: 'Power factor 3 phase'}, 'powerSTotal': {ru: 'Полная мощность итого', en: 'Apparent power total'}, 'powerSPhase1': {ru: 'Полная мощность 1 фаза', en: 'Full power 1-phase'}, 'powerSPhase2': {ru: 'Полная мощность 2 фаза', en: 'Full power 2-phase'}, 'powerSPhase3': {ru: 'Полная мощность 3 фаза', en: 'Full power 3-phase'}, 'powerQTotal': {ru: 'Реактивная мощность итого', en: 'Total reactive power'}, 'powerQPhase1': {ru: 'Реактивная мощность 1 фаза', en: 'Reactive power 1 phase'}, 'powerQPhase2': {ru: 'Реактивная мощность 2 фаза', en: 'Reactive power 2 phase'}, 'powerQPhase3': {ru: 'Реактивная мощность 3 фаза', en: 'Reactive power 3 phase'}, 'frequency': {ru: 'Частота сети', en: 'Mains frequency'}, 'temperature': {ru: 'Температура внутри прибора', en: 'The temperature inside the device'}, 'Location': {ru: 'Location', en: 'Location'}, 'Energy Class A+': {ru: 'Energy Class A+', en: 'Energy Class A+'}, 'Energy Class R+': {ru: 'Energy Class R+', en: 'Energy Class R+'}, 'Rated voltage': {ru: 'Rated voltage', en: 'Rated voltage'}, 'Rated current': {ru: 'Rated current', en: 'Rated current'}, 'Number of destinations': {ru: 'Number of destinations', en: 'Number of destinations'}, 'Temperature Range': {ru: 'Temperature Range', en: 'Temperature Range'}, 'Medium Capacity Profile capacities': {ru: 'Medium Capacity Profile capacities', en: 'Medium Capacity Profile capacities'}, 'Number of phases': {ru: 'Number of phases', en: 'Number of phases'}, 'Counter constant': {ru: 'Counter constant', en: 'Counter constant'}, 'Phase Summation': {ru: 'Phase Summation', en: 'Phase Summation'}, 'Tariff': {ru: 'Tariff', en: 'Tariff'}, 'Counter type': {ru: 'Counter type', en: 'Counter type'}, 'Execution option': {ru: 'Execution option', en: 'Execution option'}, 'Memory': {ru: 'Memory', en: 'Memory'}, 'Built-in PLM Modem': {ru: 'Built-in PLM Modem', en: 'Built-in PLM Modem'}, 'Built-in GSM Modem': {ru: 'Built-in GSM Modem', en: 'Built-in GSM Modem'}, 'Optical port': {ru: 'Optical port', en: 'Optical port'}, 'Interface type': {ru: 'Interface type', en: 'Interface type'}, 'External power': {ru: 'External power', en: 'External power'}, 'Top Seal Electronic Seal': {ru: 'Top Seal Electronic Seal', en: 'Top Seal Electronic Seal'}, 'Built-in load shedding relay': {ru: 'Built-in load shedding relay', en: 'Built-in load shedding relay'}, 'LCD backlight': {ru: 'LCD backlight', en: 'LCD backlight'}, 'Tariff metering of maximum power': {ru: 'Tariff metering of maximum power', en: 'Tariff metering of maximum power'}, 'Electronic seal of protective cover': {ru: 'Electronic seal of protective cover', en: 'Electronic seal of protective cover'}, 'Interface2': {ru: 'Interface2', en: 'Interface2'}, 'Built-in Power Interface1': {ru: 'Built-in Power Interface1', en: 'Built-in Power Interface1'}, 'PCE control': {ru: 'PCE control', en: 'PCE control'}, 'Phase energy metering A+': {ru: 'Phase energy metering A+', en: 'Phase energy metering A+'}, 'Integrated PLC2 Modem': {ru: 'Integrated PLC2 Modem', en: 'Integrated PLC2 Modem'}, 'Profile2': {ru: 'Profile2', en: 'Profile2'}, 'Modular compartment electronic seal': {ru: 'Modular compartment electronic seal', en: 'Modular compartment electronic seal'}, 'Tariff switching by external voltage': {ru: 'Tariff switching by external voltage', en: 'Tariff switching by external voltage'}, 'CRC16 software': {ru: 'CRC16 software', en: 'CRC16 software'}, 'Voltage transformation ratio': {ru: 'Voltage transformation ratio', en: 'Voltage transformation ratio'}, 'Current transformer ratio': {ru: 'Current transformer ratio', en: 'Current transformer ratio'} }; if (word[w]){ return word[w]['ru']; } else { event.emit('info', 'Пришлите эту строку с переводом разработчику - [ ' + '\'' + w + '\': {ru: \'' + 'ВАШ_ПЕРЕВОД\'' + ', en: \'' + 'YOUR_TRANSLATION\'}, ] '); return w; } }; module.exports.template = { 1: { conf: { model: {val: null, name: '', desc: 'model'}, name: {val: '', desc: 'name'}, user: {val: 1, desc: 'user'}, addr: {val: null, desc: 'address'}, protocol: {val: null, desc: 'protocol'} }, info: {}, metering: { EnergyMonth: { Current: { T1: {val: null, unit: 'kWh', desc: 'Энергия за текущий месяц по тарифу 1'}, T2: {val: null, unit: 'kWh', desc: 'Энергия за текущий месяц по тарифу 2'}, T3: {val: null, unit: 'kWh', desc: 'Энергия за текущий месяц по тарифу 3'}, T4: {val: null, unit: 'kWh', desc: 'Энергия за текущий месяц по тарифу 4'}, Total: {val: null, unit: 'kWh', desc: 'Энергия за текущий месяц Итого'} } } } }, 2: { conf: { model: {val: null, name: '', desc: 'model'}, name: {val: '', desc: 'name'}, addr: {val: null, desc: 'address'}, user: {val: 1, desc: 'user'}, pwd: {val: null, desc: 'password'}, protocol: {val: null, desc: 'protocol'}, isExtended: {val: false, desc: 'extended'} }, info: {}, metering: { EnergyMonth: { Current: { T1: {val: null, unit: 'kWh', desc: 'Энергия за текущий месяц по тарифу 1'}, T2: {val: null, unit: 'kWh', desc: 'Энергия за текущий месяц по тарифу 2'}, T3: {val: null, unit: 'kWh', desc: 'Энергия за текущий месяц по тарифу 3'}, T4: {val: null, unit: 'kWh', desc: 'Энергия за текущий месяц по тарифу 4'}, Total: {val: null, unit: 'kWh', desc: 'Энергия за текущий месяц Итого'} } } } } }; function setDevState(device, index, param){ const arr = param.name.split('.'); const obj = {val: param.val, unit: param.unit ? param.unit :'', desc: param.desc ? param.desc :arr[arr.length - 1]}; if (arr.length > 3) return device; for (let i = 0; i < arr.length; i++) { if (i === 0 && device[index][arr[0]] === undefined){ device[index][arr[0]] = {}; if (arr.length - 1 === i){ device[index][arr[0]] = obj; } } else if (i === 0 && device[index][arr[0]].val !== undefined){ device[index][arr[0]].val = param.val; } if (i === 1 && device[index][arr[0]][arr[1]] === undefined){ device[index][arr[0]][arr[1]] = {}; if (arr.length - 1 === i){ device[index][arr[0]][arr[1]] = obj; } } else if (i === 1 && device[index][arr[0]][arr[1]].val !== undefined){ device[index][arr[0]][arr[1]].val = param.val; } if (i === 2 && device[index][arr[0]][arr[1]][arr[2]] === undefined){ device[index][arr[0]][arr[1]][arr[2]] = {}; if (arr.length - 1 === i){ device[index][arr[0]][arr[1]][arr[2]] = obj; } } else if (i === 2 && device[index][arr[0]][arr[1]][arr[2]].val !== undefined){ device[index][arr[0]][arr[1]][arr[2]].val = param.val; } } //event.emit('debug', 'device: ' + JSON.stringify(device)); return device; } //******* Для 1 фазных счетчиков ********// const ff = { readSN: function (device, index, cmd, response){ event.emit('debug', 'readSN - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'info.sn', desc: translate('Serial number'), val: response.readUInt32BE(5) }); } catch (e) { event.emit('debug', e); } return device; }, dateProd: function (device, index, cmd, response){ event.emit('debug', 'dateProd - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'info.dateProd', desc: translate('Production date'), val: parseDate(response[5], response[6], response[7]) }); } catch (e) { event.emit('debug', e); } return device; }, identCounter: function (device, index, cmd, response){ event.emit('debug', 'identCounter - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'info.firmware', desc: translate('Software version'), val: response[5].toString(16) + '.' + response[6].toString(16) }); setDevState(device, index, { name: 'info.firmwareDate', desc: translate('firmware date'), //Дата версии прошивки val: parseDate(response[8], response[9], response[10]) }); } catch (e) { event.emit('debug', e); } return device; }, optronFunc: function (device, index, cmd, response){ event.emit('debug', 'optronFunc - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { const vars = { 0: '5000 imp/kW', 1: '10000 imp/kW', 2: 'freq quartz/8', 3: 'load control' }; setDevState(device, index, { name: 'info.ir', desc: translate('Optical port'), val: vars[parseInt(response[5])] }); } catch (e) { event.emit('debug', e); } return device; }, variantExecution: function (device, index, cmd, response){ event.emit('debug', 'variantExecution - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'info.twoCurrentSensors', desc: translate('twoCurrentSensors'), val: response[5] > 0 }); setDevState(device, index, { name: 'info.internalRele', desc: translate('internalRele'), val: response[6] > 0 }); } catch (e) { event.emit('debug', e); } return device; }, batteryVolt: function (device, index, cmd, response){ event.emit('debug', 'batteryVolt - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'metering.battery', desc: translate('battery'), unit: 'V', val: response[5] + '.' + zeroConcat(response[6]) }); } catch (e) { event.emit('debug', e); } return device; }, totalEnergy: function (device, index, cmd, response){ event.emit('debug', 'totalEnergy - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { const {t1, t2, t3, t4} = parseEnergy(response, 100); setDevState(device, index, { name: 'metering.Total.T1', desc: translate('oneTarrifEnergyActive'), unit: 'kWh', val: t1 }); setDevState(device, index, { name: 'metering.Total.T2', desc: translate('twoTarrifEnergyActive'), unit: 'kWh', val: t2 }); setDevState(device, index, { name: 'metering.Total.T3', desc: translate('threeTarrifEnergyActive'), unit: 'kWh', val: t3 }); setDevState(device, index, { name: 'metering.Total.T4', desc: translate('fourTarrifEnergyActive'), unit: 'kWh', val: t4 }); setDevState(device, index, { name: 'metering.Total.Total', desc: translate('TotalEnergyActive'), unit: 'kWh', val: +(t1 + t2 + t3 + t4).toFixed(2) }); } catch (e) { event.emit('debug', e); } return device; }, readUIP: function (device, index, cmd, response){ event.emit('debug', 'readUIP - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { const u = parseInt(response[5].toString(16) + zeroConcat(response[6].toString(16))); const i = parseInt(response[7].toString(16) + zeroConcat(response[8])); const p = parseInt(response[9].toString(16) + zeroConcat(response[10]) + zeroConcat(response[11])); setDevState(device, index, { name: 'metering.MainsParameters.voltage', desc: translate('voltage'), unit: 'V', val: u > 999 ? u / 10 :u }); setDevState(device, index, { name: 'metering.MainsParameters.current', desc: translate('current'), unit: 'A', val: i / 100 }); setDevState(device, index, { name: 'metering.MainsParameters.power', desc: translate('power'), unit: 'W', val: p// / 1000 }); } catch (e) { event.emit('debug', e); } return device; }, voltageOff: function (device, index, cmd, response){ event.emit('debug', 'voltageOff - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { let date = parseDate(response[9], response[10], response[11]); date += ' ' + parseTime(response[6], response[7], response[8]); setDevState(device, index, { name: 'metering.voltageOff', desc: translate('voltageOff'), val: date }); } catch (e) { event.emit('debug', e); } return device; }, voltageOn: function (device, index, cmd, response){ event.emit('debug', 'voltageOn - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { let date = parseDate(response[9], response[10], response[11]); date += ' ' + parseTime(response[6], response[7], response[8]); setDevState(device, index, { name: 'metering.voltageOn', desc: translate('voltageOn'), val: date }); } catch (e) { event.emit('debug', e); } return device; }, readDateTime: function (device, index, cmd, response){ event.emit('debug', 'readDateTime - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { let date = parseDate(response[9], response[10], response[11]); date += ' ' + parseTime(response[6], response[7], response[8]); setDevState(device, index, { name: 'metering.DateTime', desc: translate('DateTime'), val: date }); } catch (e) { event.emit('debug', e); } return device; }, limitPower: function (device, index, cmd, response){ event.emit('debug', 'limitPower - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'metering.limitPower', desc: translate('limitPower'), unit: 'kW', val: response[5].toString(16) + '.' + response[6].toString(16) }); } catch (e) { event.emit('debug', e); } return device; }, limitEnergyMonth: function (device, index, cmd, response){ event.emit('debug', 'limitEnergyMonth - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'metering.limitEnergyMonth', desc: translate('limitEnergyMonth'), unit: 'kWh', val: parseInt(response[5].toString(16) + response[6].toString(16)) }); } catch (e) { event.emit('debug', e); } return device; }, /*currentPower: function (device, index, cmd, response){ event.emit('debug','currentPower - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); //[0,14,31,155,38,0,65,129,51] event.emit('debug','*************************' + response[5].toString(16) + '.' + zeroConcat(response[6])); try { setDevState(device, index, { name: 'metering.MainsParameters.currentPower', desc: translate('currentPower'), unit: 'kW', val: response[5].toString(16) + '.' + zeroConcat(response[6]) }); } catch (e) { event.emit('debug',e); } return device; },*/ month12Energy: function (device, index, cmd, response){ event.emit('debug', 'month12Energy - cmd: ' + JSON.stringify(cmd) + ' index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { const month = parseInt(cmd[5]) + 1; if (month !== 16 && device[index].metering.EnergyMonth[month] === undefined){ device[index].metering.EnergyMonth[month] = { T1: {val: null, unit: 'kWh', desc: translate('oneTarrifEnergy')}, T2: {val: null, unit: 'kWh', desc: translate('twoTarrifEnergy')}, T3: {val: null, unit: 'kWh', desc: translate('threeTarrifEnergy')}, T4: {val: null, unit: 'kWh', desc: translate('fourTarrifEnergy')}, Total: {val: null, unit: 'kWh', desc: translate('TotalEnergy')} }; } let {t1, t2, t3, t4} = parseEnergy(response, 100); t1 = Number.isFinite(t1) ? t1 :0; t2 = Number.isFinite(t2) ? t2 :0; t3 = Number.isFinite(t3) ? t3 :0; t4 = Number.isFinite(t4) ? t4 :0; let ttl = +(t1 + t2 + t3 + t4).toFixed(2); if (ttl > -5 && ttl < 0) ttl = 0; if (month !== 16){ device[index].metering.EnergyMonth[month].T1.val = t1; device[index].metering.EnergyMonth[month].T2.val = t2; device[index].metering.EnergyMonth[month].T3.val = t3; device[index].metering.EnergyMonth[month].T4.val = t4; device[index].metering.EnergyMonth[month].Total.val = ttl; } else if (month === 16){ device[index].metering.EnergyMonth.Current.T1.val = t1; device[index].metering.EnergyMonth.Current.T2.val = t2; device[index].metering.EnergyMonth.Current.T3.val = t3; device[index].metering.EnergyMonth.Current.T4.val = t4; device[index].metering.EnergyMonth.Current.Total.val = ttl; } } catch (e) { event.emit('debug', e); } return device; }, readMaxU: function (device, index, cmd, response){ event.emit('debug', 'readMaxU - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { //V-hh-mm-ss-dd-mon-yy //I-hh-mm-ss-dd-mon-yy //m-hh-mm-ss-dd-mon-yy /*setDevState(device, index, { name: 'metering.MaxreadMaxU', desc: translate('readMaxU'), val: response[5].toString(16) + '.' + response[6].toString(16) });*/ } catch (e) { event.emit('debug', e); } return device; }, readDay: function (device, index, cmd, response){ event.emit('debug', 'readMaxU - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { /*setDevState(device, index, { name: 'metering.MaxreadMaxU', desc: translate('readMaxU'), val: response[5].toString(16) + '.' + response[6].toString(16) });*/ } catch (e) { event.emit('debug', e); } return device; }, runningTime: function (device, index, cmd, response){ event.emit('debug', 'runningTime - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { //ADDR-CMD-DATA24 -CRC /*setDevState(device, index, { name: 'metering.runningTime.On', desc: translate('readMaxU'), val: response[5].toString(16) + '.' + response[6].toString(16) });*/ } catch (e) { event.emit('debug', e); } return device; }, readFreq: function (device, index, cmd, response){ event.emit('debug', 'readFreq - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { const hz = parseInt(response[5].toString(16) + zeroConcat(response[6].toString(16))); setDevState(device, index, { name: 'metering.MainsParameters.frequency', desc: translate('frequency'), unit: 'Hz', val: hz / 100 }); } catch (e) { event.emit('debug', e); } return device; }, readParams0: function (device, index, cmd, response){ event.emit('debug', 'readParams0 - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { //[2,145,154,168,134, 0,0,1,114, 240,186] const pq = parseInt(response[6].toString(16) + zeroConcat(response[7]) + zeroConcat(response[8])); setDevState(device, index, { name: 'metering.MainsParameters.powerQTotal', desc: translate('powerQTotal'), unit: 'var', val: pq }); } catch (e) { event.emit('debug', e); } return device; }, readParams2: function (device, index, cmd, response){ event.emit('debug', 'readParams2 - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { const znak = (7 >> response[6]) & 1; response[6] &= ~(1 << 1); const cosf = parseInt(response[6].toString(16) + zeroConcat(response[7])) / 1000; const p = parseInt(response[8].toString(16) + zeroConcat(response[9]) + zeroConcat(response[10])); setDevState(device, index, { name: 'metering.MainsParameters.cosfTotal', desc: translate('cosfTotal'), val: znak ? cosf :cosf * (-1) }); setDevState(device, index, { name: 'metering.MainsParameters.powerSTotal', desc: translate('powerSTotal'), unit: 'VA', val: p }); } catch (e) { event.emit('debug', e); } return device; }, }; //******* Для 3 фазных счетчиков ********// const f = { readSnAndDate: function (device, index, cmd, response){ event.emit('debug', 'readSnAndDate - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'info.sn', desc: translate('Serial number'), val: parseInt(response.slice(1, 5).join('')) }); setDevState(device, index, { name: 'info.dateProd', desc: translate('Production date'), val: (parseInt(response[5]) < 10 ? '0' :'') + response[5] + '.' + (parseInt(response[6]) < 10 ? '0' :'') + response[6] + '.' + '20' + response[7] }); } catch (e) { event.emit('debug', e); } return device; }, firmwareVersion: function (device, index, cmd, response){ event.emit('debug', 'firmwareVersion - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'info.firmware', desc: translate('Software version'), val: response.slice(1, 4).join('.') }); } catch (e) { event.emit('debug', e); } return device; }, crcDevice: function (device, index, cmd, response){ event.emit('debug', 'crcDevice - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'info.crcDevice', desc: translate('CRC16 software'), val: response.slice(1, 3).toString('hex').toUpperCase() }); } catch (e) { event.emit('debug', e); } return device; }, variantExecution: function (device, index, cmd, response){ event.emit('debug', 'variantExecution - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { //1 setDevState(device, index, { name: 'info.classEnergyA', desc: translate('Energy Class A+'), val: getVariant(1, 4, (response[1] >> 6) & 3) }); setDevState(device, index, { name: 'info.classEnergyR', desc: translate('Energy Class R+'), val: getVariant(1, 3, (response[1] >> 4) & 3) }); setDevState(device, index, { name: 'info.nomU', desc: translate('Rated voltage'), val: getVariant(1, 2, (response[1] >> 2) & 3) }); setDevState(device, index, { name: 'info.nomI', desc: translate('Rated current'), val: getVariant(1, 1, (response[1] >> 0) & 3) }); //2 setDevState(device, index, { name: 'info.dest', desc: translate('Number of destinations'), val: getVariant(2, 5, (response[2] >> 7) & 1) }); setDevState(device, index, { name: 'info.temperature', desc: translate('Temperature Range'), val: getVariant(2, 4, (response[2] >> 6) & 1) }); setDevState(device, index, { name: 'info.mediumPowerProfile', desc: translate('Medium Capacity Profile capacities'), val: getVariant(2, 3, (response[2] >> 5) & 1) }); setDevState(device, index, { name: 'info.numPhases', desc: translate('Number of phases'), val: getVariant(2, 2, (response[2] >> 4) & 1) }); setDevState(device, index, { name: 'info.counterConst', desc: translate('Counter constant'), val: getVariant(2, 1, (response[2] >> 0) & 15) }); //3 setDevState(device, index, { name: 'info.SummPhases', desc: translate('Phase Summation'), val: getVariant(3, 4, (response[3] >> 7) & 1) }); setDevState(device, index, { name: 'info.Tarifficator', desc: translate('Tariff'), val: getVariant(3, 3, (response[3] >> 6) & 1) }); setDevState(device, index, { name: 'info.typeCount', desc: translate('Counter type'), val: getVariant(3, 2, (response[3] >> 4) & 3) }); setDevState(device, index, { name: 'info.executionOption', desc: translate('Execution option'), val: parseInt((response[3] >> 0) & 15) }); //4 setDevState(device, index, { name: 'info.memSize', desc: translate('Memory'), val: getVariant(4, 7, (response[4] >> 7) & 1) }); setDevState(device, index, { name: 'info.intPlm', desc: translate('Built-in PLM Modem'), val: getVariant(4, 6, (response[4] >> 6) & 1) }); setDevState(device, index, { name: 'info.intGsm', desc: translate('Built-in GSM Modem'), val: getVariant(4, 5, (response[4] >> 5) & 1) }); setDevState(device, index, { name: 'info.ir', desc: translate('Optical port'), val: getVariant(4, 4, (response[4] >> 4) & 1) }); setDevState(device, index, { name: 'info.interface', desc: translate('Interface type'), val: getVariant(4, 3, (response[4] >> 2) & 3) }); setDevState(device, index, { name: 'info.extPower', desc: translate('External power'), val: getVariant(4, 2, (response[4] >> 1) & 1) }); setDevState(device, index, { name: 'info.elecSealTopCover', desc: translate('Top Seal Electronic Seal'), val: getVariant(4, 1, (response[4] >> 0) & 1) }); //5 setDevState(device, index, { name: 'info.internalRelay', desc: translate('Built-in load shedding relay'), val: getVariant(5, 8, (response[5] >> 7) & 1) }); setDevState(device, index, { name: 'info.backlightDisp', desc: translate('LCD backlight'), val: getVariant(5, 7, (response[5] >> 7) & 1) }); setDevState(device, index, { name: 'info.tariffMeteringOfMaxPower', desc: translate('Tariff metering of maximum power'), val: getVariant(6, 5, (response[5] >> 7) & 1) }); setDevState(device, index, { name: 'info.elecSealCover', desc: translate('Electronic seal of protective cover'), val: getVariant(5, 5, (response[5] >> 7) & 1) }); setDevState(device, index, { name: 'info.interface2', desc: translate('Interface2'), val: getVariant(5, 4, (response[5] >> 7) & 1) }); setDevState(device, index, { name: 'info.intPower', desc: translate('Built-in Power Interface1'), val: getVariant(5, 3, (response[5] >> 7) & 1) }); setDevState(device, index, { name: 'info.controlPke', desc: translate('PCE control'), val: getVariant(5, 2, (response[5] >> 7) & 1) }); setDevState(device, index, { name: 'info.phaseMeteringEnergyA', desc: translate('Phase energy metering A+'), val: getVariant(5, 1, (response[5] >> 7) & 1) }); //6 setDevState(device, index, { name: 'info.internalPlc2', desc: translate('Integrated PLC2 Modem'), val: getVariant(6, 5, (response[6] >> 4) & 1) }); setDevState(device, index, { name: 'info.profile2', desc: translate('Profile2'), val: getVariant(6, 4, (response[6] >> 3) & 1) }); setDevState(device, index, { name: 'info.electronicSealModuleBay', desc: translate('Modular compartment electronic seal'), val: getVariant(6, 3, (response[6] >> 2) & 1) }); setDevState(device, index, { name: 'info.externalVoltageTariffSwitch', desc: translate('Tariff switching by external voltage'), val: getVariant(6, 2, (response[6] >> 1) & 1) }); } catch (e) { event.emit('debug', e); } return device; }, readLocation: function (device, index, cmd, response){ event.emit('debug', 'readLocation - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'info.location', desc: translate('Location'), val: response.toString('ascii', 1, 5) }); } catch (e) { event.emit('debug', e); } return device; }, transformRatio: function (device, index, cmd, response){ event.emit('debug', 'transformRatio - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { setDevState(device, index, { name: 'info.voltageTransformationRatio', desc: translate('Voltage transformation ratio'), val: response.readInt16BE(1) }); setDevState(device, index, { name: 'info.currentTransformationRatio', desc: translate('Current transformer ratio'), val: response.readInt16BE(3) }); } catch (e) { event.emit('debug', e); } return device; }, totalEnergy: function (device, index, cmd, response){ event.emit('debug', 'totalEnergy - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { if (response.length === 19){ const {one, two, three, four} = getFour32LE(response, 1000); setDevState(device, index, { name: 'metering.Total.totalEnergyActivePlus', desc: translate('totalEnergyActivePlus'), unit: 'kWh', val: one }); setDevState(device, index, { name: 'metering.Total.totalEnergyActiveMinus', desc: translate('totalEnergyActiveMinus'), unit: 'kWh', val: two }); setDevState(device, index, { name: 'metering.Total.totalEnergyReactivePlus', desc: translate('totalEnergyReactivePlus'), unit: 'kvar', val: three }); setDevState(device, index, { name: 'metering.Total.totalEnergyReactiveMinus', desc: translate('totalEnergyReactiveMinus'), unit: 'kvar', val: four }); /*setDevState(device, index, { name: 'metering.Total.totalEnergy', desc: translate('totalEnergy'), unit: 'kWh', val: parseFloat((one + two + three + four).toFixed(2)) });*/ } } catch (e) { event.emit('debug', e); } return device; }, currentDayEnergy: function (device, index, cmd, response){ event.emit('debug', 'currentDayEnergy - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { if (response.length === 19){ const {one, two, three, four} = getFour32LE(response, 1000); setDevState(device, index, { name: 'metering.Day.TotalEnergyActivePlus', desc: translate('currentDayTotalEnergyActivePlus'), unit: 'kWh', val: one }); setDevState(device, index, { name: 'metering.Day.TotalEnergyActiveMinus', desc: translate('currentDayTotalEnergyActiveMinus'), unit: 'kWh', val: two }); setDevState(device, index, { name: 'metering.Day.TotalEnergyReactivePlus', desc: translate('currentDayTotalEnergyReactivePlus'), unit: 'kvar', val: three }); setDevState(device, index, { name: 'metering.Day.TotalEnergyReactiveMinus', desc: translate('currentDayTotalEnergyReactiveMinus'), unit: 'kvar', val: four }); /*setDevState(device, index, { name: 'metering.Day.EnergyTotal', desc: translate('currentDayEnergyTotal'), unit: 'kWh', val: parseFloat((one + two + three + four).toFixed(2)) });*/ } } catch (e) { event.emit('debug', e); } return device; }, oneTarrif: function (device, index, cmd, response){ event.emit('debug', 'oneTarrif - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { if (response.length === 19){ const {one, two, three, four} = getFour32LE(response, 1000); setDevState(device, index, { name: 'metering.Total.oneTarrifEnergyActivePlus', desc: translate('oneTarrifEnergyActivePlus'), unit: 'kWh', val: one }); setDevState(device, index, { name: 'metering.Total.oneTarrifEnergyActiveMinus', desc: translate('oneTarrifEnergyActiveMinus'), unit: 'kWh', val: two }); setDevState(device, index, { name: 'metering.Total.oneTarrifEnergyReactivePlus', desc: translate('oneTarrifEnergyReactivePlus'), unit: 'kvar', val: three }); setDevState(device, index, { name: 'metering.Total.oneTarrifEnergyReactiveMinus', desc: translate('oneTarrifEnergyReactiveMinus'), unit: 'kvar', val: four }); /*setDevState(device, index, { name: 'metering.Total.oneTarrifEnergyTotal', desc: translate('oneTarrifEnergyTotal'), unit: 'kWh', val: parseFloat((one + two + three + four).toFixed(2)) });*/ } } catch (e) { event.emit('debug', e); } return device; }, twoTarrif: function (device, index, cmd, response){ event.emit('debug', 'twoTarrif - index: ' + JSON.stringify(index) + ' response: ' + JSON.stringify(response) + ' length: ' + response.length); try { if (response.length === 19){ const {one, two, three, four} = getFour32LE(response, 1000); setDevState(device, index, { name: 'metering.Total.twoTarrifEnergyActivePlus', desc: translate('twoTarrifEnergyActivePlus'), unit: 'kWh', val: one }); setDevState(device, index, { name: 'metering.Total.twoTarrifEnergyActiveMinus', desc: translate('twoTarrifEnergyActiveMinus'), unit: 'kWh', val: two }); setDevState(device, index, { name: 'metering.Total.twoTarrifEnergyReactivePlus', desc: translate('twoTarrifEnergyReactivePlus'), unit: 'kvar', val: three }); setDevState(device, index, { name: 'metering.Total.twoTarrifEnergyReactiveMinus', desc: translate('twoTarrifEnergyReactiveMinus'), unit: 'kvar', val: four }); /*setDevState(device, index, { name: 'metering.Total.twoTarrifEnergyTotal', desc: translate('twoTarrifEnergyTotal'), unit: 'kWh', val