Плагин Modbus



  • Скачал плагин v0.0.9 с github. Показания не считываются, выдает вот такой лог:

    01.07 07:32:51.201 modbus2: Plugin modbus2 has started.
    01.07 07:32:51.220 modbus2: config=[ { id: 'ch1',
        vartype: 'uint16',
        unit: 'modbus2',
        usek: false,
        ks: 100,
        ks0: 0,
        gr: false,
        pollp: true,
        desc: 'AI',
        chan: 'ch1',
        kh0: 0,
        address: '30018',
        fcr: '3',
        useactions: false,
        actions: [ [Object] ],
        kh: 100,
        unitid: 0,
        inv: false,
        inv_out: false,
        prop: '',
        op: '',
        value: '',
        calc_out: '',
        dn: 'T',
        calc: '',
        nofb: false } ]
    01.07 07:32:51.225 modbus2: polls=[ { length: 1,
        unitid: 0,
        desc: 'AI',
        fcr: '3',
        address: 30018,
        ref: [ [Object] ] } ]
    01.07 07:32:51.300 modbus2: Connected to 77.244.70.15:45016
    01.07 07:32:51.301 modbus2: sendNext item={ length: 1,
      unitid: 0,
      desc: 'AI',
      fcr: '3',
      address: 30018,
      ref: [ { id: 'ch1', vartype: 'uint16le', widx: 0 } ] }
    01.07 07:32:51.302 modbus2: READ unitid=0 FC=3 address=30018 (0x7542) length=1
    01.07 07:32:51.355 modbus2: ERROR: Error: Modbus exception 2
        at TelnetPort. <anonymous>(/var/lib/intrahouse-c/plugins/modbus/node_modules/modbus-serial/index.js:288:42)
        at emitOne (events.js:115:13)
        at TelnetPort.emit (events.js:210:7)
        at TelnetPort._emitData (/var/lib/intrahouse-c/plugins/modbus/node_modules/modbus-serial/ports/telnetport.js:154:10)
        at Socket.onData (/var/lib/intrahouse-c/plugins/modbus/node_modules/modbus-serial/ports/telnetport.js:100:22)
        at emitOne (events.js:115:13)
        at Socket.emit (events.js:210:7)
        at addChunk (_stream_readable.js:264:12)
        at readableAddChunk (_stream_readable.js:251:11)
        at Socket.Readable.push (_stream_readable.js:209:10)
    01.07 07:32:51.364 IH: Plugin exit with code 1
    01.07 07:32:51.365 IH: restart timer 5</anonymous>
    
    


  • @gis:

    Скачал плагин v0.0.9 с github. Показания не считываются, выдает вот такой лог:

    > 01.07 07:32:51.302 modbus2: READ unitid=0 FC=3 address=30018 (0x7542) length=1
    > 01.07 07:32:51.355 modbus2: ERROR: Error: Modbus exception 2
    > 
    > 
    

    Не указан Unit ID (адрес устройства на шине).

    Проверьте, пожалуйста, в настройке канала



  • Спасибо! Согласно инструкции на тепловычислитель, если используется подключение RS232 (а оно используется через преобразователь интерфейсов), то адрес устройства = 0. Я такой адрес и установил в настройках плагина. Следует ли использовать адрес устройства =1?



  • Поставил адрес устройства =1 Аналогичная картина:

    01.07 18:48:17.041 modbus2: sendNext item={ length: 1,
      unitid: 1,
      desc: 'AI',
      fcr: '3',
      address: 30018,
      ref: [ { id: 'ch1', vartype: 'uint16le', widx: 0 } ] }
    01.07 18:48:17.042 modbus2: READ unitid=1 FC=3 address=30018 (0x7542) length=1
    01.07 18:48:17.092 modbus2: ERROR: Error: Modbus exception 2
    
    

    Что означает ERROR: Error: Modbus exception 2



  • @gis:

    Поставил адрес устройства =1 Аналогичная картина:

    > 01.07 18:48:17.042 modbus2: READ unitid=1 FC=3 address=30018 (0x7542) length=1
    > 01.07 18:48:17.092 modbus2: ERROR: Error: Modbus exception 2
    > 
    

    Что означает ERROR: Error: Modbus exception 2

    Сейчас подключение у Вас произошло. 2 - это стандартная ошибка адресации уровня Modbus:

    Modbus exception 2 - Illegal Data Address. The data address received in the query is not an allowable address for the slave

    Попробуйте адресоваться внутри таблицы, как в modpoll - адрес 17



  • Похоже проблема с адресаций. Поставил 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 выдает всю информацию.


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