iobroker.mercury
Version:
Receiving data from electricity meters Mercury
1,006 lines (1,001 loc) • 133 kB
JavaScript
'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