Написание драйвера протокола на rs-485

Существует необходимость использования контроллера как шлюза между СКАДА системой и контроллерами диспетчеризации зданий с отличным от стандартного modbus протоколом. Описание протокола имеется. Где можно увидеть инструкцию, или пример описывающий реализацию опроса?

Добрый день.
Прямое чтение и запись в порт описано здесь.

Михаил, спасибо за ссылку.
Я правильно понял, необходимо создать шаблон с командами чтенья/записи в порт и скопировать его в /etc/wb-mqtt-serial.conf.d/templates?

Давайте немного уточним. Вдруг первоначальный вопрос не так мной понят.

Здесь подразумеваете, что к контроллеру будут подключены устройства с “отличным от стандартного modbus протоколом”? Если да, то я верно вас понял.

Я думаю, немного не так. Так было б, если протокол уже описан в драйвере wb-mqtt-serial.

А если протокола нет, то писать самим. Посмотрите пример реализации на wb-rules Шаблон для электрокарниза - #6 от пользователя BrainRoot

Да, мне как раз и нужно самому написать протокол. Расчетное количество тегов для опроса около 100-200 с каждого устройства, устройств много, в каждом из которых набор тегов различен. По этому имеется необходимость написания драйвера, для объявления тегов через web интерфейс (а в идеальной картине мира через загрузку некого csv файла из которого будет браться весь список тегов для отображения в веб интерфейсе)

У вас есть два пути, как я вижу.

  • реализовать поддержку протокола в wb-mqtt-serial. Путь хороший, но требует “эксперного” уровня разработки.
  • использовать специально предназначенный для таких целей RPC. Требования к уровню - на порядок ниже, доступно пользователю.

“наборы тегов” - они реализуются просто списком для каждого экземпляра, как правило.

1 лайк

Благодарю за подсказку! Буду тестировать используя RPC, т.к. на данный момент экспертности при работе с WB для реализации “привольного” решения не достаточно.

Может есть инструкция по работе с интерфейсом в формате “step by step” дополненном скриншотами, куда нажимать, в какую папку перемещать файл и прочее…?

https://wirenboard.com/wiki/index.php?title=Wb-jscript&direction=prev&oldid=58353
Описание RPC, с примерами: GitHub - wirenboard/wb-mqtt-serial: Wiren Board MQTT serial protocol driver

Продолжаю свои эксперименты с написании своего правила по опросу железки с несовсем modbus’ом. Возникли сложности, небольшие сложности, не могу понять как правильно в цикле получать ответ после запроса

var pathRPC = "/rpc/v1/wb-mqtt-serial/port/Load/"; 
var modbusPort = "/dev/ttyRS485-1";
var modbusSpeed = 9600;
var modbusParity = "N";
var modbusStopbit = 2;
var message = "E0300C8000644C9"; //тест
var MainDevName = "Virtual-device_n2";


var period = 5000;
var CountCh=0;

var DevCh = new Array(100);
for (var i = 0; i < 100; i++) {
DevCh[i] = new Array(2);
}


function requestRPC(modbusPort, modbusSpeed, modbusParity, modbusStopbit, clientID, requiestID, messageType, addr, responseSize){

  strJson = JSON.stringify({params: {response_size: responseSize, format: messageType, path: modbusPort, baud_rate: modbusSpeed, parity: modbusParity, "data_bits" : 8, "stop_bits" : modbusStopbit, "msg": message}, "id" : requiestID});

  log("-------------------------------");
  log("strJson =", strJson, " / addr = ", addr);
  publish(pathRPC+DevCh[addr][0], strJson, 1, false); 

  trackMqtt(pathRPC+DevCh[addr][0]+"/reply", function(message){
      if (message.value!=""){
        log(message.value, " / ", addr);
      }
    }); 
  
  
  dev[MainDevName + "/" + DevCh[addr][0]] = dev["wb-adc/V5_0"]; // тест. заполнение виртуального устройства получеными данными 
};


getDevice(MainDevName).controlsList().forEach(function(ctrl) { //функция разбора витруального устройства и наполнение массива индексами топиков для цикличной обработки
    DevCh[CountCh][0] = ctrl.getId();
    DevCh[CountCh][1] = ctrl.getTitle();
    CountCh++;
});


cycle_req();


function thread_req(hex, i) {
  setTimeout(function () {
    requestRPC(modbusPort, modbusSpeed, modbusParity, modbusStopbit, clientID, 1, "HEX", i, 8);     
  }, 500 * i);
}

function cycle_req() { 
setInterval(function() {      
       for (var i =0; i < CountCh; i++){              
          thread_req("HEX", i);                       
        };
}, period);  
};

Ответы возвращаются в trackMqtt, описанный в коде с топиком pathRPC+DevCh[addr][0]+"/reply"
Это асинхронный процесс, ожидать его нет смысла.

Другими славами организовать запрос-ответ в цикле нет возможности?

Может подскажите в каком месте нужно переписать код опроса по modbus, с учетом особенностей протокола опрашиваемого оборудования?

Непонятно… Если ставить цель именно дожидаться ответа на запрос - то просто дождаться надо реакции дравера. Идеологически верно - взводить флаг, например, после отправки запроса. Флаг уже опускать при получении ответа.

Буду признателен если скинете ссылку с примером

Нет готового примера. Но в общем случае, без очереди - использовать глобальную переменную, которую устанавливать в true сразу после публикации в RPC топик. Ну и не публиковать в топик ничего пока значение true. Сбрасывать - в обработчике trackMqtt
Второй, более простой путь, если используется несколько устройств, и несколько типов запроса и надо получать (различать) ответы от них - кроме pathRPC+DevCh[addr][0] добавить идентификатор запроса.

Ок, попробую оба варианта, спасибо за подсказку, по результатам напишу что получилось

А задача - именно обработать ответ на определенный запрос или просто на определенный тип запроса?
просто если речь о modbus - то я получив ответ - из него уже понимаю от какого устройства он, на какую команду.

Глобально задача сделать опрос eстройства по RS-485, протокол отличный от modbus, описание протокола так-же есть. Пытаюсь реализовать протокол с помощью правил.
В данный момент взял паузу, пробую с правил на node-red перейти, использую библиотеку node-red-node-serialport.