Добрый день,
Не доволен дребезгом импульсных расходомеров, сигнал с которых сразу подаю на контроллер через дискретные входы W1_IN и W2-IN. Решил создать собственное правило, но что-то не получается никак. При получении импульса, бегунок реагирует и переключается, а вот числовое значение не хочет меняться совсем. Вот уже которую неделю бьюсь как рыба об лёд. Ниже правило, которое у меня не работает. Пожалуйста, помогите допилить!
var deviceName = “water_meters”;
defineVirtualDevice (deviceName, { // Создаем виртуальный девайс для отображения в веб интерфейсе.
title: “Счетчики воды”,
cells: {
impuls_1: {
title: “Импульс”,
type: “switch”,
value: false
},
impuls_2: {
title: “Значение”,
type: “value”,
value: 0
},
}
});
defineRule(“water_meter_1”, {
whenChanged: “wb-gpio/W2_IN”,
then: function(newValue) {
dev [deviceName+“/impuls_1”] = newValue;
//dev[deviceName+“/impuls_2”] = 0;
}
});
defineRule(“water_meter_2”, {
whenChanged: “wb-gpio/W2_IN”,
then: function makeCounter() {
var a = 1;
var b = deviceName+“/impuls_2”
return function () {
return a+b
};
var counter = makeCounter();
dev[deviceName+“/impuls_2”] = aler( counter() );
}
});
Если в переменную b вы хотите присвоить текущее значение контрола, то строка должна выглядеть так:
var b = dev[deviceName+“/impuls_2”];
В противном случае вы в переменную b присваиваете текст “water_meters/impuls_2” и далее пытаетесь к текстовому значению прибавить значение переменной а (т.е. 1 )
Если что-то не работает так ка вы этого хотите, то выводите в log() промежуточные значения или результаты операций - так вам будет понятно что и где работает не так
В вашем случае если под строчку
var b = deviceName+“/impuls_2”
Добавить что-то такое
log("значение переменное а = ", a, " Значение переменой b = ", b);
То вы бы заметили ошибку.
Спасибо, немного продвинулся дальше, даже заработало правило. Вот рабочая версия. Однако, хотелось бы в dev[deviceName+”/impuls_3”] = newValue + 0.01; видеть показания с тремя знаками, после запятой, а у меня сейчас бесконечность чисел. Помогите, пожалуйста.
PS. в логе, получается, а в dev не получается.
var deviceName = “water_meters”;
defineVirtualDevice (deviceName, { // Создаем виртуальный девайс для отображения в веб интерфейсе.
title: “Счетчики воды”,
cells: {
impuls_1: {
title: “Импульс”,
type: “switch”,
value: false
},
impuls_2: {
title: “Количество”,
type: “value”,
value: 0,
readonly: false,
},
impuls_3: {
title: “Значение”,
type: “value”,
value: 0,
readonly: false,
units: “m3”
},
}
});
defineRule(“water_meter_1”, {
whenChanged: “wb-gpio/W2_IN”,
then: function(newValue) {
dev [deviceName+“/impuls_1”] = newValue;
//dev[deviceName+“/impuls_2”] = 0;
}
});
defineRule(“water_meter_2”, {
whenChanged: (“wb-gpio/W2_IN”,deviceName+“/impuls_1”),
then: function (newValue) {
if (newValue === true) {
var a = 1;
var b = dev[deviceName+“/impuls_2”];
dev[deviceName+“/impuls_2”] = a+b;
//log (“значение a+b = “, a+b);
}}
});
defineRule(“water_meter_3”, {
whenChanged: (“wb-gpio/W2_IN”, deviceName+”/impuls_1”),
then: function (newValue) {
log (“newValue_1 = “, newValue);
if (newValue === true) {
var newValue = dev[deviceName+”/impuls_3”];
//var newValue = (dev[deviceName+“/impuls_3”]).toFixed(3);
log (“newValue = “, newValue.toFixed(3));
dev[deviceName+”/impuls_3”] = newValue + 0.01;
log (“сумма = “, (dev[deviceName+”/impuls_3”]).toFixed(3));
}
}
});
Вы в контрол виртуального устройства (то, что отображается у вас на экране в WEB интерфейсе) публикуете НЕ форматированное значение
dev[deviceName+”/impuls_3”] = newValue + 0.01;
В то время как в лог вы выводите (предварительно считав из контрола не форматированное значение) значение с форматированием “три знака после запятой” т.е. .toFixed(3)
log (“newValue = “, newValue.toFixed(3));
...
log (“сумма = “, (dev[deviceName+”/impuls_3”]).toFixed(3));
Вывод (решение) - опубликуйте в контрол предварительно отформатированное значение.
Рекомендую не использовать переменную newValue на все случаи жизни - это усложняет чтение кода ив какой-то момент времени может сыграть злую шутку (неконтролируемое изменение значения).
Опять же, как рекомендация (чтобы научиться разбираться в подобных проблемах самостоятельно) - не стесняйтесь делить задачу на мелкие шаги и контролировать (log()) каждый шаг, например:
if (newValue === true) {
// Считать текущее значение контрола
var CurrentValue = dev[deviceName+”/impuls_3”];
// Проверим, а что там считалось?
log (“Из контрола мы считали вот это = “, CurrentValue);
// инкрементируем значение контрола на величину "шага" 0.01
var NextStep = CurrentValue + 0.01;
// Посмотрим, а что там получилось и в каком виде представлено?
log (“Инкрементировали значение на 0.01 и получили вот это = “, NextStep);
// Ух ты! бардак! А что если отформатировать значение?
var NextStepFormated = NextStep.toFixed(3) ;
// Проверим, а что там получилось после форматирования?
log (“Отформатировали полученное значение до трех знаков после запятой = ",
NextStepFormated, " Получилось ли то, что ожидали? );
// Если все получилось как надо, то публикуем значение в контрол
dev[deviceName+”/impuls_3”] = NextStepFormated;
// И что же теперь имеем в контроле? Считаем значение в лог..
log (“Что же в итоге получили? Сумма = “, dev[deviceName+”/impuls_3”] );
}
Это, естественно, отладочный фрагмент кода, который расставит вам все точки над Ё
После этого удалите из кода все лишнее , как минимум вывод в логи - не стоит плодить файлы логов большого размера и содержащие много ненужного в нормальной работе “мусора”, и пользуйтесь.
Комментарии лучше оставлять в коде (если вы еще не супер спец в программировании, который одним взглядом на листинг из полторы тысячи строк легко разберется в логике работы скрипта и за одно обнажить ошибки в коде или логике его работы )
PS код выше я не проверял - писал сразу в чат “в живую”. Надеюсь все запятые там на месте
PPS у элементов виртуального устройства есть нет свойства precision (см, например, тему Количество знаков после запятой )- т.е. значение контрола будет “отформатировано” с указанной точностью, но у меня не всегда это срабатывает, поэтому я “по старинке” сам форматирую значения перед выводом их в контролы виртуальных устройств.
PPPS безусловно, приведенный выше код можно сократить буквально до одной/двух строк. Он может стать менее “читаемым” для новичка, но от этого не утратит своей функциональности и заодно сократит размер “портянки” скрипта
Удачи в освоении!
Спасибо, вроде получилось. Правда пришлось добавить знак “+” в строчке:
dev[deviceName+“/impuls_3”] = +NextStepFormated;
defineRule(“water_meter_3”, {
whenChanged: (“wb-gpio/W2_IN”, deviceName+“/impuls_1”),
then: function (newValue) {
log (“newValue = “, newValue);
if (newValue === true) {
var CurrentValue = dev[deviceName+”/impuls_3”]; // Считываем текущее значение контрола
log ("Из контрола мы считали вот это = ", CurrentValue); // Проверим, а что там считалось?
var NextStep = CurrentValue + 0.01; // инкрементируем значение контрола на величину “шага” 0.01
log ("Инкрементировали значение на 0.01 и получили вот это = ", NextStep); // Посмотрим, а что там получилось и в каком виде представлено?
var NextStepFormated = NextStep.toFixed(3) ; // Ух ты! бардак! А что если отформатировать значение?
log (“Отформатировали полученное значение до трех знаков после запятой = “, NextStepFormated) // Проверяем форматирование до трёх знаков после запятой.
dev[deviceName+”/impuls_3”] = +NextStepFormated; // Если все получилось как надо, то публикуем значение в контрол
log (“Что же в итоге получили? Сумма = “, dev[deviceName+”/impuls_3”] ); // И что же теперь имеем в контроле? Считаем значение в лог…
}
}
});
// Итоговое рабочее правило для импульсных счётчиков.
var deviceName = “Water_Meters”;
defineVirtualDevice (deviceName, { // Создаем виртуальный девайс для отображения в веб интерфейсе.
title: “Счетчики воды”,
cells: {
cold: {
title: “Холодная вода”,
type: “value”,
value: 0,
readonly: false, // “fals” делает поле редактируемым, “true” просто показывает значение
units: “m3”
},
hot: {
title: “Горячая вода”,
type: “value”,
value: 0,
readonly: false,
units: “m3”
},
}
});
defineRule(“Cold_Water_Metr”, {
whenChanged: (“wb-gpio/W1_IN”),
then: function (newValue) {
if (newValue === true) {
var CurrentValue = dev[deviceName+“/cold”]; // Считываем текущее значение контрола холодной воды// log ("CurrentValueCold = ", CurrentValue);
var NextStep = CurrentValue + 0.01; // инкрементируем значение контрола на величину “шага” 0.01 // log ("Инкрементация значения на 0.01 = ", NextStep);
var NextStepFormated = NextStep.toFixed(3) ; // log (“Отформатировали полученное значение до трех знаков после запятой = “, NextStepFormated);
dev[deviceName+”/cold”] = +NextStepFormated; // Публикуем значение с разрядом три знака поле запятой в контрол // log (“Новое значение счётчика ХВС = “, dev[deviceName+”/cold”] );
}
}
});
defineRule(“Hot_Water_Metr”, {
whenChanged: (“wb-gpio/W2_IN”),
then: function (newValue) {
log (“newValue = “, newValue);
if (newValue === true) {
var CurrentValue = dev[deviceName+”/hot”]; // log (“CurrentValueHot = “, CurrentValue);
var NextStep = CurrentValue + 0.01;
var NextStepFormated = NextStep.toFixed(3) ;
dev[deviceName+”/hot”] = +NextStepFormated; // log (“Новое значение счётчика ГВС = “, dev[deviceName+”/hot”] );
}
}
});
Спасибо большое за помощь!