В связи с выходом крупного обновления 5.9.х, приглашаем вас принять участие в вебинаре 09.06.2022 в 15:00. Участвовать

Плагин Modbus



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



  • Спасибо! Все заработало, регистры читаются, но остался один вопрос - количество тепловой энергии 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 просто означает, что плагин в текущий момент запущен, но еще не прислал сообщений с момента открытия отладчика 😞



  • @intrapro Про флаг в настройках шлюза WB - да, так и есть. Спасибо, заработало.
    А вот с параметром "позиция байта в слове для 1-байтовых значений" вопрос: там в настройках плагина выпадающий список из двух значений, по дефолту значение есть и убрать его мы не смогли.
    Есть вопрос с параметром канала "смещение" - это что? и как это должно работать? Просто у нас ничего не меняется от этого параметра.
    И еще вопрос стабильности возникает, который возможно и является причиной ложных ошибок: например сегодня однобайтовые в тех же устройствах берет без ошибки, но зато через раз лог выглядит так: (с задвоениями)

    20.12 05:31:23.090 modbus1: READ: unitId = 2, FC = 3, address = 0x9C40 (0x9c40), length = 2
    20.12 05:31:23.090 modbus1: READ: unitId = 2, FC = 3, address = 0x9C40 (0x9c40), length = 2
    20.12 05:31:23.120 IH: get [ { id: 'ch17', value: 33620271 } ]
    set { parse_kdl: { aval: 1, err: 0 } }
    20.12 05:31:23.120 IH: get [ { id: 'ch17', value: 33620271 } ]
    set { parse_kdl: { aval: 1, err: 0 } }
    20.12 05:31:23.320 modbus1: READ: unitId = 2, FC = 3, address = 0x9C87 (0x9c87), length = 1
    20.12 05:31:23.320 modbus1: READ: unitId = 2, FC = 3, address = 0x9C87 (0x9c87), length = 1
    20.12 05:31:23.348 IH: get [ { id: 'ch18', value: 187 } ]
    set { ch71: { aval: 187, err: 0 } }
    20.12 05:31:23.348 IH: get [ { id: 'ch18', value: 187 } ]
    set { ch71: { aval: 187, err: 0 } }
    20.12 05:31:23.549 modbus1: READ: unitId = 1, FC = 4, address = 0x5000 (0x5000), length = 2
    20.12 05:31:23.549 modbus1: READ: unitId = 1, FC = 4, address = 0x5000 (0x5000), length = 2
    20.12 05:31:23.610 IH: get [ { id: 'ch10', value: -223084544 } ]
    set {}
    
    

    В чем причина?



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

    А вот с параметром "позиция байта в слове для 1-байтовых значений" вопрос: там в настройках плагина выпадающий список из двух значений, по дефолту значение есть и убрать его мы не смогли.

    Убирать не надо. Проблема была, что там как раз не было значения (undefined) при обновлении плагина, так как до 14 версии параметра "порядок для 1-байтовых значений" не было.
    В целом, важно проверить порядок байт в параметрах. Для WB все настройки порядка байт должны быть BigEndian (в том числе 4-байтовое значение, там по умолчанию стоит swap BE).

    Есть вопрос с параметром канала "смещение" - это что? и как это должно работать? Просто у нас ничего не меняется от этого параметра.

    Смещение планировали использовать, если задавать адрес внутри регистра, а не чистый адрес Modbus. Но отказались от этой идеи, поэтому смещение в новой версии убрали совсем.

    И еще вопрос стабильности возникает, который возможно и является причиной ложных ошибок: например сегодня однобайтовые в тех же устройствах берет без ошибки, но зато через раз лог выглядит так: (с задвоениями)
    В чем причина?

    Пытались у себя смоделировать задвоение, но не удалось.
    Это не двойной опрос по модбас, время совпадает до милисекунд.
    Вероятно, это связано не с плагином, а с подпиской на сообщения отладчика, просто сервер отдает каждое сообщение дважды 😞

    Опубликован новый релиз плагина v0.0.16:
    https://github.com/intrahouseio/intraHouse.plugin-Modbus/releases/tag/v0.0.16

    • убрано смещение
    • изменена функция записи
    • исправлена ошибка: в случае ошибки плагин не останавливался командой Stop, а продолжал Try reconnect.

Log in to reply