Плагин Modbus



  • Похоже проблема с адресаций. Поставил 17 ошибок не выдает:

    1.07 22:52:17.171 modbus2: sendNext item={ length: 2,
      unitid: 0,
      desc: 'AI',
      fcr: '3',
      address: 17,
      ref: [ { id: 'ch1', vartype: 'int32le', widx: 0 } ] }
    01.07 22:52:17.172 modbus2: READ unitid=0 FC=3 address=17 (0x11) length=2
    01.07 22:52:17.220 IH: set {"T":{"aval":0,"err":0}}
    01.07 22:52:17.221 modbus2: {"type":"Buffer","data":[0,0,0,0]}
    01.07 22:52:17.721 modbus2: sendNext item={ length: 2,
      unitid: 0,
      desc: 'AI',
      fcr: '3',
      address: 17,
      ref: [ { id: 'ch1', vartype: 'int32le', widx: 0 } ] }
    01.07 22:52:17.723 modbus2: READ unitid=0 FC=3 address=17 (0x11) length=2
    01.07 22:52:17.770 IH: set {"T":{"aval":0,"err":0}}
    01.07 22:52:17.771 modbus2: {"type":"Buffer","data":[0,0,0,0]}
    
    

    Но значение =0

    modpoll при этом выдает значение 1160.



  • @gis:

    Похоже проблема с адресаций. Поставил 17 ошибок не выдает:

    Но значение =0

    modpoll при этом выдает значение 1160.

    Можно для эксперимента соседние адреса почитать.



  • Соседние адреса читал, результат аналогичный. Если это поможет - могу дать удаленный доступ к устройству и описание регистров от производителя. Отписал в личку.



  • Спасибо! Все заработало, регистры читаются, но остался один вопрос - количество тепловой энергии Q ( а также часть других показателей) храниться в двух регистрах, отдельно целая и дробная части. Как в introhouse объединить эти части в единое число?



  • @gis:

    Спасибо! Все заработало, регистры читаются, но остался один вопрос - количество тепловой энергии Q ( а также часть других показателей) храниться в двух регистрах, отдельно целая и дробная части. Как в introhouse объединить эти части в единое число?

    Самый простой вариант - сделать сценарий. Можно мультисценарий для всех таких случаев

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

    /** 
    * @name Сложить целое и дробное показания
    * @version 4 
    */
    const Q_int = Device("SensorA","Целое показание"); 
    const Q_dec = Device("SensorA","Дробное показание"); 
    const Q = Device("Meter","Счетчик"); 
    
    startOnChange(Q_dec); 
    
    script({
        start() {
           this.assign(Q, 'aval', Q_int.value+Q_dec.value);
        } 
    });
    
    

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

    Другой вариант - специализированный плагин для этого типа счетчиков.



  • Будет ли работать плагин Modbus в режиме RTU over TCP с преобразователем интерфейсов RS-485/RS-232 В ETHERNET С2000-ETHERNET фирмы Болид? Очень актуальное оборудование для связи систем охраны.

    Производитель заявляет поддержку UDP, ICMP (ping), ARP (хотя про настройку прибора в ICMP (ping) ни слова). Из руководства следует, что пакеты RS-485/RS-232 передаются в UDP протоколе, в том числе и modbus.
    C-2000.jpg



  • Вопрос к разработке: при подключении к серверу устройств через переходник Wirenboard (протокол rtu over tcp) плагин modbus версии 13 опрашивает регистры циклически. При отключении одного из устройств от линии modbus, либо отсутствии ответа по одному из регистров плагин встает и пишет разрыв соединения. Как обойти остановку плагина и сделать циклический опрос последующих устройств и их регистров с простым выводом в лог ошибки без остановки плагина? Какая команда в agent.js отвечает за переход в следующему каналу по списку?



  • @Viktor

    Можно сделать так: в функции this.modbusReadCommand стр 160 добавить после обработки ошибки продолжение опроса that.sendNext();

    this.modbusReadCommand(fcr, address, length)
          .then(res => {
            // Получили ответ - разбираем и передаем на сервер
            this.plugin.sendDataToServer(protocol.getDataFromResponse(res.buffer, ref));
    
            that.plugin.log(res.buffer, 2); // Это сырой буфер
    
            return sleep(this.plugin.params.polldelay || 1); // Интервал между запросами
          })
          .then(() => {
            that.sendNext();
          })
          .catch(e => {
            that.checkError(e);
            that.sendNext(); // ДОБАВИТЬ ЭТУ СТРОКУ
          });
    

    в функции checkError стр 269 закомментировать выход плагина

    checkError(e) {
        if (e.errno && networkErrors.includes(e.errno)) {
          this.plugin.log('Network ERROR: ' + e.errno, 0);
        } else {
          this.plugin.log('ERROR: ' + util.inspect(e), 0);
        }
        // TODO - проверить ошибку и не всегда выходить
        // this.stop();  ЭТО ЗАКОММЕНТИРОВАТЬ
        // process.exit(1);  ЭТО ЗАКОММЕНТИРОВАТЬ
      },
    


  • @intrapro Да, мы тоже так думали. Однако в таком виде он начинает выдавать бесконечную ошибку (на картинке). При чем нет даже паузЦикл.jpg



  • @Viktor
    Похоже при ошибке соединение закрывается
    Можно тогда при ошибке со своей стороны закрывать и заново делать connect. Попробуйте так - стр 151:

    read({ unitid, fcr, address, length, ref }) {
        let that = this;
    
        this.client.setID(unitid);
        this.plugin.log(
          'READ unitid=' + unitid + ' FC=' + fcr + ' address=' + this.showAddress(address), 1
        );
    
         this.modbusReadCommand(fcr, address, length)
         .then(res => {
           this.plugin.sendDataToServer(protocol.getDataFromResponse(res.buffer, ref));
           that.plugin.log(res.buffer, 2); 
           return sleep(this.plugin.params.polldelay || 1); 
         })
         .catch(e => {
           that.checkError(e);
           that.client.close();  // Закрыть 
           return sleep(that.plugin.params.polldelay || 1); // сделать задержку. Ее можно увеличить
         })
         .then(() => {
           if (!that.client.isOpen())  return that.connect();
         })
         .then(() => {
            that.sendNext();
         })
        .catch(e => {
              that.plugin.log(' REconnection error:' + JSON.stringify(e), 0);  
              that.stop();
              process.exit(1);
        }); 
      },
    


  • @intrapro
    При

    read({ unitid, fcr, address, length, ref }) {
        let that = this;
    
        this.client.setID(unitid);
        this.plugin.log(
          'READ unitid=' + unitid + ' FC=' + fcr + ' address=' + this.showAddress(address), 1
        );
    
         this.modbusReadCommand(fcr, address, length)
         .then(res => {
           this.plugin.sendDataToServer(protocol.getDataFromResponse(res.buffer, ref));
           that.plugin.log(res.buffer, 2); 
           return sleep(this.plugin.params.polldelay || 1); 
         })
         .catch(e => {
           that.checkError(e);
           that.client.close();  // Закрыть 
           return sleep(that.plugin.params.polldelay || 1); // сделать задержку. Ее можно увеличить
         })
         .then(() => {
           if (!that.client.isOpen())  return that.connect();
         })
         .then(() => {
            that.sendNext();
         })
        .catch(e => {
              that.plugin.log(' REconnection error:' + JSON.stringify(e), 0);  
              that.stop();
              process.exit(1);
        }); 
      },
    

    и

      checkError(e) {
        if (e.errno && networkErrors.includes(e.errno)) {
          this.plugin.log('Network ERROR: ' + e.errno, 0);
        } else {
          this.plugin.log('ERROR: ' + util.inspect(e), 0);
        }
        // TODO - проверить ошибку и не всегда выходить
        //this.stop();
        //process.exit(1);
      },
    

    суть не меняется, + 1 строчка лога
    reconnection.jpg



  • Участник @Viktor написал в Плагин Modbus:

    при подключении к серверу устройств через переходник Wirenboard (протокол rtu over tcp)

    Уточните, какой переходник используете. Вероятно WB-MIO-E? У нас есть некоторый набор оборудования WirenBoard. Попробуем у себя.



  • @intrahouse
    WB-MGE



  • Из-за чего может быть так?

    Температурные датчики аналоговые PT1000, подключены к контроллеру отопления.
    На нем если строить график, то он гладкий. Т.е. никаких наводок в проводах между датчиками и контроллером нет.
    alt text
    Дальше по модбас получаю значения в IH, и строю график.
    График получается с хаотическими скачками в 0,3 градуса.
    alt text
    На каком этапе может такая погрешность вносится?

    У контроллера беда - если включить логирование для графиков, оно сд-карту убивает быстро.
    Поэтому у контроллера график старый.



  • @Erik
    Возможно контроллер сохраняет показания датчиков в сглаженном (интегрированном) виде. Для минимизации объемов хранимой информации. А в modbus выдает всю информацию.



  • Участник @Viktor написал в Плагин Modbus:

    Вопрос к разработке: при подключении к серверу устройств через переходник Wirenboard (протокол rtu over tcp) плагин modbus версии 13 опрашивает регистры циклически. При отключении одного из устройств от линии modbus, либо отсутствии ответа по одному из регистров плагин встает и пишет разрыв соединения. Как обойти остановку плагина и сделать циклический опрос последующих устройств и их регистров с простым выводом в лог ошибки без остановки плагина? Какая команда в agent.js отвечает за переход в следующему каналу по списку?

    Мы проверили. Действительно, при отключении одного из устройств от линии Modbus, плагин останавливался или уходил в перезагрузку.
    Проблема решена. Плагин Modbus обновили. V0.0.15
    На данный момент его можно скачать с GitHub https://github.com/intrahouseio/intraHouse.plugin-Modbus/releases
    Просьба проверить и написать по результату. После этого опубликуем на сайте для обновления.



  • @intrahouse
    Спасибо, проверим, напишем



  • @intrahouse
    Плагин V14 при наличии хотя бы одного заданного канала INT8 или UINT8 1 байт падает, выдает ошибку типаINT_UINT_V14.jpg
    при смене INT8 или UINT8 1 байт на любое 2х и более байтное - стартует.
    Плагин V15 при выборе в канале INT8 или UINT8 1 байт стартует, но впечатление, что однобайтовые принимает как двухбайтовые. Во всяком случае приходящее значение не то.
    Пока смотрим дальше...



  • @intrahouse
    Итак по тестам:

    1. Плагин V15 далеко не всегда стартует сам без бубна. Во всяком случае лог выводит только одну строчку. Интересный момент: каждый старт - стоп лога плагина при возникновении такой ошибки добавляет такую же строчку в лог и все.v_15.jpg
    2. Плагин V15 начал обрабатывать отключение одного из устройств в линии но! есть большое но! Он обрабатывает только первый заход, начиная со второго захода он не видит устройство с другим адресом
    //отключение питания счетчика ABB
    19.12 21:40:07.247 modbus1: READ: unitId = 1, FC = 4, address = 0x502D (0x502d), length = 1
    19.12 21:40:10.252 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:10.464 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:10.464 modbus1: READ: unitId = 1, FC = 4, address = 0x5294 (0x5294), length = 1
    19.12 21:40:13.460 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:13.666 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:13.667 modbus1: READ: unitId = 2, FC = 3, address = 0x9C40 (0x9c40), length = 2
    19.12 21:40:13.699 IH: get [ { id: 'ch17', value: 33620271 } ]
    set {}   //значение устройства №2 пришло
    19.12 21:40:13.900 modbus1: READ: unitId = 1, FC = 4, address = 0x5000 (0x5000), length = 2
    19.12 21:40:16.901 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:17.102 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:17.111 modbus1: READ: unitId = 1, FC = 4, address = 0x5001 (0x5001), length = 2
    19.12 21:40:20.146 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:20.313 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:20.324 modbus1: READ: unitId = 1, FC = 4, address = 0x5002 (0x5002), length = 2
    19.12 21:40:23.402 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:23.527 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:23.529 modbus1: READ: unitId = 1, FC = 4, address = 0x5003 (0x5003), length = 2
    19.12 21:40:26.530 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:26.730 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:26.732 modbus1: READ: unitId = 1, FC = 4, address = 0x500A (0x500a), length = 1
    19.12 21:40:29.734 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:29.937 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:29.939 modbus1: READ: unitId = 1, FC = 4, address = 0x500B (0x500b), length = 1
    19.12 21:40:32.940 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:33.223 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:33.223 modbus1: READ: unitId = 1, FC = 4, address = 0x500C (0x500c), length = 1
    19.12 21:40:36.145 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:36.433 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:36.433 modbus1: READ: unitId = 1, FC = 4, address = 0x500D (0x500d), length = 1
    19.12 21:40:39.355 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:39.555 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:39.560 modbus1: READ: unitId = 1, FC = 4, address = 0x500F (0x500f), length = 1
    19.12 21:40:42.561 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:42.764 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:42.766 modbus1: READ: unitId = 1, FC = 4, address = 0x5010 (0x5010), length = 1
    19.12 21:40:45.768 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:45.970 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:45.973 modbus1: READ: unitId = 1, FC = 4, address = 0x5011 (0x5011), length = 1
    19.12 21:40:48.973 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:49.173 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:49.179 modbus1: READ: unitId = 1, FC = 4, address = 0x501F (0x501f), length = 2
    19.12 21:40:52.180 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:52.381 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:52.397 modbus1: READ: unitId = 1, FC = 4, address = 0x502D (0x502d), length = 1
    19.12 21:40:55.398 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:55.598 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:55.601 modbus1: READ: unitId = 1, FC = 4, address = 0x5294 (0x5294), length = 1
    19.12 21:40:58.602 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:40:58.803 modbus1: Port is not open! TRY RECONNECT
    19.12 21:40:58.805 modbus1: READ: unitId = 2, FC = 3, address = 0x9C40 (0x9c40), length = 2
    19.12 21:41:01.808 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:41:02.010 modbus1: Port is not open! TRY RECONNECT
    //устройство №2 отвалилось
    19.12 21:41:02.018 modbus1: READ: unitId = 1, FC = 4, address = 0x5000 (0x5000), length = 2
    19.12 21:41:05.018 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:41:05.219 modbus1: Port is not open! TRY RECONNECT
    19.12 21:41:05.229 modbus1: READ: unitId = 1, FC = 4, address = 0x5001 (0x5001), length = 2
    19.12 21:41:22.880 modbus1: undefined  //проскакивающая ошибка
    19.12 21:41:24.271 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:41:24.472 modbus1: Port is not open! TRY RECONNECT
    19.12 21:41:24.475 modbus1: READ: unitId = 1, FC = 4, address = 0x500D (0x500d), length = 1
    19.12 21:41:27.476 modbus1: Network ERROR: ETIMEDOUT
    19.12 21:41:27.676 modbus1: Port is not open! TRY RECONNECT
    
    

    плюс проскакивает ошибка undefined на ровном месте.
    3. когда у нас не запускался V15 пытались пробовать V14 для своих тестов, там отваливается все при разных настройках double/int/uint
    INT_UINT_V14.jpg



  • @Viktor, добрый день, спасибо за тестирование!

    1. Плагин V15 начал обрабатывать отключение одного из устройств в линии но! есть большое но! Он обрабатывает только первый заход, начиная со второго захода он не видит устройство с другим адресом

    Попробовали воспроизвести ситуацию.
    У WB шлюза есть флаг - Сбрасывать старые соединения:
    wb-mge.jpg

    Если этот флаг убрать, то действительно со второго раза соединение не восстанавливается.
    При установленном флаге переподключение к существующим адресам у нас происходит нормально.

    1. Не запускается V14.

    Там добавлен новый параметр в настройках плагина:
    "Позиция байта в слове (для 1-байтовых значений)"
    Если его оставить пустым, то происходит вот это: unit8undefined
    Поправим, чтобы было значение по дефолту, но плагин должен работать.

    Ну а сообщение modbus1: undefined просто означает, что плагин в текущий момент запущен, но еще не прислал сообщений с момента открытия отладчика 😞


Авторизуйтесь, чтобы ответить