Арифметика с несколькими регистрами

Всех приветствую!
Продолжаю осваивать этот замечательный контроллер , на этот раз встала такая задача :

  • Силами контроллера проводить арифметические операции над несколькими прочитанными регистрами.
    Пример. Имеем некое стороннее устройство на шине Modbus, к примеру пусть это будет трехфазный вольтметр, с регистрами 1,2,3, в которые он пишет измеренные значения, и ничего больше у этого устройства нет. Есть красивый дашборд, на который выводятся эти показания, но хочется ещё добавить среднее значение измерений. Т.е нужно сложить все эти три показания, и разделить их на 3. Собственно , есть какой нибудь красивый и незамороченный способ это сделать? В голову пока только пришло создать виртуальное устройство на wb-rules, и в нем уже проводить такие арифметические действия… Исходя из вышеописанного:
  1. Если решение все - же будет лежать через wb-rules, поделитесь пожалуйста примером, в котором он собирал бы нужные топики и уже потом колдовал бы над ними. Уровень в JS пока околонулевой, собираю с форумов куски кода и потом сижу вникаю)
  2. Если есть иные способы проводить такие операции буду благодарен за подсказки)

Добрый день!

Есть несколько путей решения вашего вопроса:

  1. Виртуальное устройство
    Вы можете создать виртуальное устройство, настроив его через wb-rules. Примеры и подробная документация доступны здесь.
  2. Node-RED
    Используйте Node-RED для создания и визуализации логики. Подробнее о настройке и использовании описано здесь.

Здравствуйте! Спасибо за Ваш ответ. Выбрал все - таки вариант с виртуальным устройством. Если не затруднит, не могли бы проверить код? Если я все правильно написал, то появится виртуальное устройство, которое будет мониторить три топика, складывать их, и делить на число которое я задал в переменной.
Код :

defineVirtualDevice('test', {
    title: 'Test' ,
    cells: {
      AvgValue: {
        title: "Среднее значение",
	    type: "value",
	    value: 0,
        readonly: true,
        order: 1,
	    },
    }
})

var stepVal = 3
defineRule({
  whenChanged: ["/devices/wb-modbus-0-0/controls/L1 - Напряжение"],
  then: function (newValue, devName, cellName) {
	dev["/devices/wb-modbus-0-0/controls/L1 - Напряжение"] + dev["/devices/wb-modbus-0-0/controls/L2 - Напряжение"] + dev["/devices/wb-modbus-0-0/controls/L3 - Напряжение"] / stepVal = newValue;

  }
});

Добрый день!

Рекомендую обратить внимание на следующие моменты:

  1. Убедитесь, что переменная stepVal больше 0, чтобы избежать ошибки деления на ноль.
  2. Вместо работы с топиками напрямую, используйте промежуточные переменные для упрощения чтения кода. Например:
var avgValue = (val1 + val2 + val3) / stepVal;
  1. Если что-то не работает, добавьте временные логи для проверки промежуточных значений. Это поможет отследить, где возникает ошибка. Например:
log("Intermediate value of avgValue: " + avgValue);

должно быть whenChanged: “wb-modbus-0-0/L1 - Напряжение”,
и
dev[“wb-modbus-0-0/L1 - Напряжение”]

2 лайка

Благодарю за ответ. А не подскажите как топик поместить в переменную ? Так-же через var и в квадратных скобках?

Спасибо за ответ! Мой код с первого раза не заработал. Показывает 0(
Попробую внести ваши поправки.

Добрый день!
Да, все верно

У вас там ещё явно ошибка порядка действий:
a + b + c / 3 аналогично c / 3 + b + a.

defineVirtualDevice('test', {
    title: 'Test' ,
    cells: {
      AvgValue: {
        title: "Среднее значение",
	    type: "value",
	    value: 0,
        readonly: true,
        order: 1,
	    },
    }
})

var stepVal = 3
defineRule({
  whenChanged: ["wb-modbus-0-0/L1 - Напряжение"],
  then: function (newValue, devName, cellName) {
	var val1 = dev["wb-modbus-0-0/L1 - Напряжение"];
	var val2 = dev["wb-modbus-0-0/L2 - Напряжение"];
	var val3 = dev["wb-modbus-0-0/L3 - Напряжение"];
	var avgValue = (val1 + val2 + val3) / stepVal; 
	dev["test/AvgValue"] = avgValue;
  }
});
1 лайк

Огромнейшее Вам спасибо! Задача решена. На примере Вашего кода, сделал и другие необходимые вычисления.
Спасибо!

whenChanged: ["wb-modbus-0-0/L1 - Напряжение", "wb-modbus-0-0/L2 - Напряжение", "wb-modbus-0-0/L3 - Напряжение"],

Да не за что.
Я не знаю как у Вас в задаче, но логичнее было бы следить за изменением по любой фазе, а не только первой

1 лайк

Мы мониторим трёхфазный регулируемый источник, напряжение регулируется в диапазоне 0-380. Используется преимущественно в трехфазном режиме, , поэтому для отслеживания и выбрали только одну фазу. Но спасибо за подсказку, пригодится в других моментах)