Modbus RTU, работа с полученными данными

Добрый вечер!
Получить данные по Modbus и отправить по SNMP с помощью контроллера WB6.
Доп. ветка: Настройка SNMP agent
Получаем по Modbus RTU параметры с 2-х параллельно соединенных батарей, в плане до 24шт.
Требуется получить:

  1. Среднее значение (average) “Battery voltage, V” 2-х батарей, среднее значение SOC;
  2. Общий ток (general) “Current, A” 2-х батарей, общую емкость батареи “Nominal Capacity, Ah”.

    Полученные значения необходимо будет передать через SNMP.
    Заранее спасибо за поддержку!

Добрый день.
Совсем не понял вопроса… Что-то не получается?
Покажите код, логи.

Поясняю, мы имеем сейчас 2 значения напряжения с обоих батарей: 51,46 и 52, 34.
Необходимо в отдельном окне иметь среднее значение напряжения: 51,9 в этом же окне общий ток батареи (нагрузки на АКБ нет, поэтому ток на скриншоте по нулям): Iакб1 +Iакб2
В веб-интерфейсе функцию работы с полученными значениями я не нашел. Может быть это можно организовать через написание соответствующего скрипта? Можете подсказать?

Например, в папке /etc/wb-mqtt-mbgate.conf, скрипт напряжений на двух этих батареях выглядит так:

{
    "scale": 1,
    "byteswap": false,
    "format": "signed",
    "max": 0,
    "address": 36504,
    "enabled": false,
    "topic": "wb-modbus-0-0/Battery Voltage",
    "meta_type": "voltage",
    "unitId": 244,
    "wordswap": false,
    "size": 2
   },
{
    "scale": 1,
    "byteswap": false,
    "format": "signed",
    "max": 0,
    "address": 27527,
    "enabled": false,
    "topic": "wb-modbus-0-1/Battery Voltage",
    "meta_type": "voltage",
    "unitId": 52,
    "wordswap": false,
    "size": 2
   },

Среднее наприяжение в скрипте считается так:

Vavg = (dev["wb-modbus-0-0/Battery Voltage"] + dev["wb-modbus-0-1/Battery Voltage"])/2;

Ток - аналогично. Если хотите вывести в отдельное виртуальное устройство - то достаточно его, устройство описать, например так:

//12_02_test_03.js

defineVirtualDevice("battery", {
    title: "Battery",
    cells: {
	Vavg: {
	    type: "value",
	    value: 0
	},
   Cavg: {
	    type: "value",
	    value: 0
	}
    }
});

defineRule("ChangeV", {
  whenChanged: ["wb-modbus-0-0/Battery Voltage","wb-modbus-0-1/Battery Voltage"], //при изменении
  then: function (newValue, devName, cellName) { //выполняй следующие действия
    log.info(newValue)
    dev["battery"]["Vavg"] = (dev["wb-modbus-0-0/Battery Voltage"] + dev["wb-modbus-0-1/Battery Voltage"])/2;;
  }
});

Добрый день!
Спасибо большое, с суммой и средним значением в rules все получилось.
Следующий вопрос такой:
У батареи есть серийный номер, в предыдущем письме прикладывал скриншот.

Из описания Modbus для SN:

Доп. информация от производителя:
The Register address from 65333 - 65343, Each 16bit HEX you need to convert to ASCII
Let say you have 3830 3030 3031 3039 3032 3938 3230 3230 3030 3231
Means that 80 00 01 09 02 98 20 20 00 21

Мы в свою очередь имеем батарею с SN: 80000041069820200009.
При настройки отображения SN выбрали: 8-bit ASCII char. Другого подходящего формата значения из всплывающего списка не было:

К сожалению мы получаем на выходе “0”:

Также пробовал другие значения формата, увы, единственно, что мог получить мало-мальски схожее, это только первые 4 группы цифр HEX при выборе 32-bit BCD:


Возможно это всего лишь совпадение.

Опрашивая через Serial port monitor, получаю следующее:

Т.е. значения идут корректные.

Напишите, пож-та, как решить данную проблему?

К сожалению, сейчас нельзя настроить чтение такого параметра.

Здравствуйте! Пока, к сожалению, у драйвера нет полноценной поддержки работы со строками. Можно только считать один 8-битный символ из 16-разрядного регистра.
Думаю, можно считывать данные из регистров и отправлять в десятичном виде и уже преобразовывать в ASCII-символы на стороне получателя.

Или же с помощью правил сделать нужные преобразования на контроллере и публиковать полученную строку в отдельный топик или виртуальное устройство. А из них уже отправлять получателю.

Коллега предлагает следующее: Создать для устройства в шаблоне 10 полей типа “value”
Так как производитель сохраняет ASC2 код символа в регистр - собирать требуемую строку вже отдельным правилом.

Мне нужен пример/описание, без него к сожалению, реализовать данную задачу не смогу.
Заранее спасибо!

Подскажите пожалуйста, где я могу найти топики вновь созданных значений, чтобы передавать по SNMP?

Нстройки - Каналы MQTT
Перечислены все топики.

На примере виртуального устройства можно сделать так:

       
defineVirtualDevice("test_device", {
  title: "Test Device",
  cells: {
    "serial_reg1": {
    type: "text",
    format: "u64",
    value: "3830303030303431"
    },
        "serial_reg2": {
    type: "text",
    format: "u64",
    value: "3036393832303230"
    },
        "serial_reg3": {
    type: "text",
    format: "u32",
    value: "30303039"
    },
    "serial_reg4": {
    type: "text",
    format: "u16",
    value: "0000"
    },
  }
});


function hex2ascii(hex_val) {
    //log ("input value: " + hex_val);
    var string_hex = hex_val.toString(16);//force conversion
    //log ("hex string: " + string_hex);
    var str = '';
    for (var i = 0; i < string_hex.length; i += 2)
        str += String.fromCharCode(parseInt(string_hex.substr(i, 2), 16));
    //log (str);
    return str;
}

var complete_serial = dev["test_device"]["serial_reg1"].toString() + dev["test_device"]["serial_reg2"].toString() + dev["test_device"]["serial_reg3"].toString() + dev["test_device"]["serial_reg4"].toString();
log("comlete serial number = " + complete_serial);

//hex2ascii('38303030303034313036393832303230303030390000');
log("serial in ascii = " + hex2ascii(complete_serial));

То есть считываются данные в hex-формате в несколько переменных (каналов устройства), затем из них составляется строка, затем строка преобразуется в символы ascii.

1 Like

Добрый день!
Залил скрипт в Rules.
На выходе получаю следующее:

Из данного скрипта мне непонятно откуда берется значение серийного номера, руками прописывать не вариант.
Полагаю, что-то сделал не так…

Еще один вопрос.
Оборудование выдает по Modbus статус состояния в числовом виде:


Есть таблица соответствия числа и описания.
Необходим скрипт в котором будут прописаны соответствия числу своя запись.
Например 2000 - “normal”

И вместо числа будет выдаваться данная запись.

@alfa

Вот готовая функция, заполните условиями switch и запускайте её с параметрами, например, так
log(getTextStatus(2000));

Wb-rules использует JS-подобный язык, основы языка хорошо описаны в учебнике: https://learn.javascript.ru/

// конвертер
function getTextStatus(NumberStatus) {
    switch (NumberStatus) {
        case 2000:
            return "normal";

        case 4000:
            return "error";

        default:
            return "unknown";
    }
}

Так как у меня нет аналогичного устройства, то я создал виртуальное устройство, создал виртуальные каналы и задал им вручную значения.
Вам нужно дополнить ваш шаблон каналами с данными из регистров серийного номера в аналогичном формате. С частью данных это у вас это уже получилось:
image. Аналогично создайте Serial Number 1, Serial Number 2…
Можно использовать формат u64 (чтобы меньше каналов создавать) и тип text. То есть 2 канала с данными u64, один u32 и одни u16. В сумме будет 22 байта данных. Затем эти данные объединить и преобразовать, как показано в примере. Результат можно опубликовать в отдельный топик или виртуальное устройство. Затем использовать эти данные аналогично имеющимся.

Спасибо. С серийным номером получилось.
Осталось опубликовать в отдельный топик. Подскажите, пожалуйста, как создать такой топик.

Для существующего устройства?
Например так: Как дабавить кнопку в панель устройств к действующему устройству? - #2 от пользователя BrainRoot

Эта тема была автоматически закрыта через 7 дней после последнего ответа. В ней больше нельзя отвечать.