NEWS
Проблема со скриптом
-
Имеется приборчик PZEM-004t - китайский измеритель напряжения, тока, мощности и суммарного потребления. Подключен к iobroker через esp8266 с прошивкой wifi-iot по mqtt. Показания исправно приходят в iobroker. Появилось желание сделать расчет суточного потребления и его стоимости.
Написал скрипт:
var T1 = 3; //Стоимость тарифа Т1 var difference = 0; //Разница между старым и новым значением createState('energy_count.Day', 0, {name: 'Day energy count', type: 'number', read: true, write: true, unit:'kWh'}); createState('energy_count.DayCost', 0, {name: 'Day energy cost', type: 'number', read: true, write: true, unit:'руб'}); createState('energy_count.costT1', T1, {name: 'Cost T1 per kWh', read: true, write: true, unit: 'руб/kWh'}); on({id: "mqtt.0.ESP00163EB3.pmwh", change: "gt"}, function (obj) { if (obj.newState.val >= obj.oldState.val) { difference = (obj.newState.val - obj.oldState.val)/1000; var mD = Math.round (parseFloat (getState("javascript.0.energy_count.Day").val + difference)*1000)/1000; var mDC = Math.round (parseFloat (getState("javascript.0.energy_count.DayCost").val + (difference * T1))*1000)/1000; setState('javascript.0.energy_count.Day', mD, true); setState('javascript.0.energy_count.DayCost', mDC, true); } }); schedule("0 0 0 * * *", function () { //Каждый день в 00:00:00 обнуляем дневные показания setState('javascript.0.energy_count.Day', 0, true); setState('javascript.0.energy_count.DayCost', 0, true); });Сначала скрипт считает все нормально, значения плюсуются исправно, но в какой-то момент начинает складывать не понятные мне значения:

http://pics.4minipc.ru/images/2017/03/30/2.png" />http://pics.4minipc.ru/images/2017/03/30/1.png" />
Причем исходные данные от PZEM идут как положено.
Есть идеи?~~~~
-
Сначала скрипт считает все нормально, значения плюсуются исправно, но в какой-то момент начинает складывать не понятные мне значения:
Причем исходные данные от PZEM идут как положено.
Есть идеи? `
Я бы первым делом сделал так:! ````
var T1 = 3; //Стоимость тарифа Т1
var difference = 0; //Разница между старым и новым значением
createState('energy_count.Day', 0, {name: 'Day energy count', type: 'number', read: true, write: true, unit:'kWh'});
createState('energy_count.DayCost', 0, {name: 'Day energy cost', type: 'number', read: true, write: true, unit:'руб'});
createState('energy_count.costT1', T1, {name: 'Cost T1 per kWh', read: true, write: true, unit: 'руб/kWh'});
! on({id: "mqtt.0.ESP00163EB3.pmwh", change: "gt"}, function (obj) {
log('obj.newState.val = '+ obj.newState.val);
log('obj.oldState.val = '+ obj.oldState.val);
if (obj.newState.val >= obj.oldState.val) {
difference = parseFloat((parseFloat(obj.newState.val) - parseFloat(obj.oldState.val))/1000);
log('difference = '+ difference);
var mD = Math.round ((parseFloat (getState("javascript.0.energy_count.Day").val) + difference)*1000)/1000;
var mDC = Math.round ((parseFloat (getState("javascript.0.energy_count.DayCost")).val + (difference * T1))*1000)/1000;
log('mD = '+ mD);
log('mDC = '+ mDC);
setState('javascript.0.energy_count.Day', mD, true);
setState('javascript.0.energy_count.DayCost', mDC, true);}});
! schedule("0 0 0 * * *", function () { //Каждый день в 00:00:00 обнуляем дневные показания
setState('javascript.0.energy_count.Day', 0, true);
setState('javascript.0.energy_count.DayCost', 0, true);
}); -
Сделал по рекоммендации. Несколько часов нормальной работы и опять…
Вот что нарыл в логе:
Последнее нормальное значение:
2017-03-31 11:30:13.025 - [32minfo[39m: javascript.0 script.js.common.energy-cost: obj.newState.val = 7837
2017-03-31 11:30:13.026 - [32minfo[39m: javascript.0 script.js.common.energy-cost: obj.oldState.val = 7836
2017-03-31 11:30:13.027 - [32minfo[39m: javascript.0 script.js.common.energy-cost: difference = 0.001
2017-03-31 11:30:13.029 - [32minfo[39m: javascript.0 script.js.common.energy-cost: mD = 0.081
2017-03-31 11:30:13.029 - [32minfo[39m: javascript.0 script.js.common.energy-cost: mDC = 0.243
Следующее, уже не правильное:
2017-03-31 11:30:23.000 - [32minfo[39m: javascript.0 script.js.common.energy-cost: obj.newState.val = 7837
2017-03-31 11:30:23.001 - [32minfo[39m: javascript.0 script.js.common.energy-cost: obj.oldState.val = 0
2017-03-31 11:30:23.002 - [32minfo[39m: javascript.0 script.js.common.energy-cost: difference = 7.837
2017-03-31 11:30:23.003 - [32minfo[39m: javascript.0 script.js.common.energy-cost: mD = 7.918
2017-03-31 11:30:23.004 - [32minfo[39m: javascript.0 script.js.common.energy-cost: mDC = 23.754
Прошло еще немного времени:
2017-03-31 11:38:38.110 - [32minfo[39m: javascript.0 script.js.common.energy-cost: obj.newState.val = 7841
2017-03-31 11:38:38.111 - [32minfo[39m: javascript.0 script.js.common.energy-cost: obj.oldState.val = 7840
2017-03-31 11:38:38.112 - [32minfo[39m: javascript.0 script.js.common.energy-cost: difference = 0.001
2017-03-31 11:38:38.114 - [32minfo[39m: javascript.0 script.js.common.energy-cost: mD = 172.526
2017-03-31 11:38:38.115 - [32minfo[39m: javascript.0 script.js.common.energy-cost: mDC = 517.578
Куда то временами пропадает obj.oldState.val.
Как быть?
-
Сделал проверку на "0".
Скрипт не производит арифметику, если obj.oldState.val = 0. Теперь считает нормально. Но отсюда получаем новый глюк:
15:06:08.297 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7937
15:06:08.298 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0
15:06:28.269 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7938
15:06:28.270 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0
15:06:48.298 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7938
15:06:48.300 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0
15:07:03.191 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7938
15:07:03.192 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0
15:07:08.324 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7939
15:07:08.327 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 7938
15:07:08.327 [info] javascript.0 script.js.common.energy-cost: difference = 0.001
15:07:08.327 [info] javascript.0 script.js.common.energy-cost: mD = 0.007
15:07:08.327 [info] javascript.0 script.js.common.energy-cost: mDC = 0.021
он пропускает значения, т.к. obj.oldState.val для 7939 это 7938, а последний раз он отработал по 7937.
-
Сделал проверку на "0".
Скрипт не производит арифметику, если obj.oldState.val = 0. Теперь считает нормально. Но отсюда получаем новый глюк:
15:06:08.297 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7937
15:06:08.298 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0
15:06:28.269 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7938
15:06:28.270 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0
15:06:48.298 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7938
15:06:48.300 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0
15:07:03.191 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7938
15:07:03.192 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0
15:07:08.324 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7939
15:07:08.327 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 7938
15:07:08.327 [info] javascript.0 script.js.common.energy-cost: difference = 0.001
15:07:08.327 [info] javascript.0 script.js.common.energy-cost: mD = 0.007
15:07:08.327 [info] javascript.0 script.js.common.energy-cost: mDC = 0.021
он пропускает значения, т.к. obj.oldState.val для 7939 это 7938, а последний раз он отработал по 7937. `
OldVal не сохраняется при перезгрузке. IoBroker перезапустил - 0 получил. -
Наверное у тебя приходят нули по mqtt но ты их не печатает, т.к. смотришь, чтоб новое значение было больше.
Поставь проверку на ноль и печатай лог `
Так лог ведь печатается:
!
15:06:08.297 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7937 15:06:08.298 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0 15:06:28.269 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7938 15:06:28.270 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0 15:06:48.298 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7938 15:06:48.300 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0 15:07:03.191 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7938 15:07:03.192 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 0 15:07:08.324 [info] javascript.0 script.js.common.energy-cost: obj.newState.val = 7939 15:07:08.327 [info] javascript.0 script.js.common.energy-cost: obj.oldState.val = 7938 15:07:08.327 [info] javascript.0 script.js.common.energy-cost: difference = 0.001 15:07:08.327 [info] javascript.0 script.js.common.energy-cost: mD = 0.007 15:07:08.327 [info] javascript.0 script.js.common.energy-cost: mDC = 0.021 !А вот и весь код. Что куда добавить?
! ````
var T1 = 3; //Стоимость тарифа Т1
var difference = 0; //Разница между старым и новым значением
createState('energy_count.Day', 0, {name: 'Day energy count', type: 'number', read: true, write: true, unit:'kWh'});
createState('energy_count.DayCost', 0, {name: 'Day energy cost', type: 'number', read: true, write: true, unit:'руб'});
createState('energy_count.costT1', T1, {name: 'Cost T1 per kWh', read: true, write: true, unit: 'руб/kWh'});
! on({id: "mqtt.0.ESP00163EB3.pmwh", change: "gt"}, function (obj) {
log('obj.newState.val = '+ obj.newState.val);
log('obj.oldState.val = '+ obj.oldState.val);
if (obj.newState.val > obj.oldState.val && obj.oldState.val > 0) {
difference = parseFloat((parseFloat(obj.newState.val) - parseFloat(obj.oldState.val))/1000);
log('difference = '+ difference);
var mD = Math.round ((parseFloat (getState("javascript.0.energy_count.Day").val) + difference)*1000)/1000;
var mDC = Math.round ((parseFloat (getState("javascript.0.energy_count.DayCost")).val + (difference * T1))*1000)/1000;
log('mD = '+ mD);
log('mDC = '+ mDC);
setState('javascript.0.energy_count.Day', mD, true);
setState('javascript.0.energy_count.DayCost', mDC, true);}});
! schedule("0 0 0 * * *", function () { //Каждый день в 00:00:00 обнуляем дневные показания
setState('javascript.0.energy_count.Day', 0, true);
setState('javascript.0.energy_count.DayCost', 0, true);
}); -
! ````
var T1 = 3; //Стоимость тарифа Т1
var difference = 0; //Разница между старым и новым значением
createState('energy_count.Day', 0, {name: 'Day energy count', type: 'number', read: true, write: true, unit:'kWh'});
createState('energy_count.DayCost', 0, {name: 'Day energy cost', type: 'number', read: true, write: true, unit:'руб'});
createState('energy_count.costT1', T1, {name: 'Cost T1 per kWh', read: true, write: true, unit: 'руб/kWh'});
! on({id: "mqtt.0.ESP00163EB3.pmwh", change: "any"}, function (obj) {
log('obj.newState.val = '+ obj.newState.val);
log('obj.oldState.val = '+ obj.oldState.val);
if (obj.newState.val > obj.oldState.val && obj.oldState.val > 0) {
difference = parseFloat((parseFloat(obj.newState.val) - parseFloat(obj.oldState.val))/1000);
log('difference = '+ difference);
var mD = Math.round ((parseFloat (getState("javascript.0.energy_count.Day").val) + difference)*1000)/1000;
var mDC = Math.round ((parseFloat (getState("javascript.0.energy_count.DayCost")).val + (difference * T1))*1000)/1000;
log('mD = '+ mD);
log('mDC = '+ mDC);
setState('javascript.0.energy_count.Day', mD, true);
setState('javascript.0.energy_count.DayCost', mDC, true);}});
! schedule("0 0 0 * * *", function () { //Каждый день в 00:00:00 обнуляем дневные показания
setState('javascript.0.energy_count.Day', 0, true);
setState('javascript.0.energy_count.DayCost', 0, true);
});Обрати внимание на "change: "any"" -
! ````
var T1 = 3; //Стоимость тарифа Т1
var difference = 0; //Разница между старым и новым значением
createState('energy_count.Day', 0, {name: 'Day energy count', type: 'number', read: true, write: true, unit:'kWh'});
createState('energy_count.DayCost', 0, {name: 'Day energy cost', type: 'number', read: true, write: true, unit:'руб'});
createState('energy_count.costT1', T1, {name: 'Cost T1 per kWh', read: true, write: true, unit: 'руб/kWh'});
! on({id: "mqtt.0.ESP00163EB3.pmwh", change: "any"}, function (obj) {
log('obj.newState.val = '+ obj.newState.val);
log('obj.oldState.val = '+ obj.oldState.val);
if (obj.newState.val > obj.oldState.val && obj.oldState.val > 0) {
difference = parseFloat((parseFloat(obj.newState.val) - parseFloat(obj.oldState.val))/1000);
log('difference = '+ difference);
var mD = Math.round ((parseFloat (getState("javascript.0.energy_count.Day").val) + difference)*1000)/1000;
var mDC = Math.round ((parseFloat (getState("javascript.0.energy_count.DayCost")).val + (difference * T1))*1000)/1000;
log('mD = '+ mD);
log('mDC = '+ mDC);
setState('javascript.0.energy_count.Day', mD, true);
setState('javascript.0.energy_count.DayCost', mDC, true);}});
! schedule("0 0 0 * * *", function () { //Каждый день в 00:00:00 обнуляем дневные показания
setState('javascript.0.energy_count.Day', 0, true);
setState('javascript.0.energy_count.DayCost', 0, true);
});Обрати внимание на "change: "any"" `Сделал проще - включил сохранение истории для mqtt.0.ESP00163EB3.pmwh.
Вот что она показала:
!

<link_text text="http://pics.4minipc.ru/images/2017/03/3 ... -59-43.png">http://pics.4minipc.ru/images/2017/03/31/2017-03-31_22-59-43.png</link_text>" /><link_text text="http://pics.4minipc.ru/images/2017/03/3 ... -12-22.png">http://pics.4minipc.ru/images/2017/03/31/2017-03-31_23-12-22.png</link_text>" />~~~~ ~~~~Была у меня мысль, что косячить может mqtt, но я никогда не замечал изменения значений. Судя по истории ноль появляется на несколько секунд. Выходит все мороки со скриптом напрасны, он и в начальной версии работал правильно.
!
Буду дальше искать варианты выполнить "хотелку".
Спасибо!~~~~
-
В общем проблему решил так:
! ````
var T1 = 3; //Стоимость тарифа Т1
var difference = 0; //Разница между старым и новым значением
createState('energy_count.Day', 0, {name: 'Day energy count', type: 'number', read: true, write: true, unit:'kWh'});
createState('energy_count.DayCost', 0, {name: 'Day energy cost', type: 'number', read: true, write: true, unit:'руб'});
createState('energy_count.costT1', T1, {name: 'Cost T1 per kWh', read: true, write: true, unit: 'руб/kWh'});
createState('energy_count.pmwh', 0, {name: 'pmwh без глюка', read: true, write: true, unit: 'kWh'});
! on({id: "javascript.0.energy_count.pmwh", change: "any"}, function (obj) {
if (obj.newState.val > obj.oldState.val && obj.oldState.val > 0) {
setState('javascript.0.energy_count.pmwh', obj.newState.val, true);
}
});
! on({id: "mqtt.0.ESP00163EB3.pmwh", change: "gt"}, function (obj) {
log('obj.newState.val = '+ obj.newState.val);
log('obj.oldState.val = '+ obj.oldState.val);
if (obj.newState.val > obj.oldState.val && obj.oldState.val > 0) {
difference = parseFloat((parseFloat(obj.newState.val) - parseFloat(obj.oldState.val))/1000);
log('difference = '+ difference);
var mD = Math.round ((parseFloat (getState("javascript.0.energy_count.Day").val) + difference)*1000)/1000;
var mDC = Math.round ((parseFloat (getState("javascript.0.energy_count.DayCost")).val + (difference * T1))*1000)/1000;
log('mD = '+ mD);
log('mDC = '+ mDC);
setState('javascript.0.energy_count.Day', mD, true);
setState('javascript.0.energy_count.DayCost', mDC, true);}
});! schedule("0 0 0 * * *", function () { //Каждый день в 00:00:00 обнуляем дневные показания
setState('javascript.0.energy_count.Day', 0, true);
setState('javascript.0.energy_count.DayCost', 0, true);
});Теперь работает стабильно и без пропусков. На очереди сохранение значения при перезагрузке.
Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.
Hast du es satt, bei jedem Besuch durch die gleichen Beiträge zu scrollen? Wenn du dich für ein Konto anmeldest, kommst du immer genau dorthin zurück, wo du zuvor warst, und kannst dich über neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und Beiträge positiv bewerten, um anderen Community-Mitgliedern deine Wertschätzung zu zeigen.
Mit deinem Input könnte dieser Beitrag noch besser werden 💗
Registrieren Anmelden