ports/rtubufferedport.js
function(path, options) {
    var self = this;

    // options
    if (typeof(options) === "undefined") options = {};

    // disable auto open, as we handle the open
    options.autoOpen = false;

    // internal buffer
    this._buffer = Buffer.alloc(0);
    this._id = 0;
    this._cmd = 0;
    this._length = 0;

    // create the SerialPort
    this._client = new SerialPort(path, options);

    // register the port data event
    this._client.on("data", function onData(data) {
        // add data to buffer
        self._buffer = Buffer.concat([self._buffer, data]);

        // check if buffer include a complete modbus answer
        var expectedLength = self._length;
        var bufferLength = self._buffer.length;

        modbusSerialDebug({ action: "receive serial rtu buffered port", data: data, buffer: self._buffer });

        // check data length
        if (expectedLength < MIN_DATA_LENGTH || bufferLength < EXCEPTION_LENGTH) return;

        // check buffer size for MAX_BUFFER_SIZE
        if (bufferLength > MAX_BUFFER_LENGTH) {
            self._buffer = self._buffer.slice(-MAX_BUFFER_LENGTH);
            bufferLength = MAX_BUFFER_LENGTH;
        }

        // loop and check length-sized buffer chunks
        var maxOffset = bufferLength - EXCEPTION_LENGTH;
        for (var i = 0; i <= maxOffset; i++) {
            var unitId = self._buffer[i];
            var functionCode = self._buffer[i + 1];

            if (unitId !== self._id) continue;

            if (functionCode === self._cmd && i + expectedLength <= bufferLength) {
                self._emitData(i, expectedLength);
                return;
            }
            if (functionCode === (0x80 | self._cmd) && i + EXCEPTION_LENGTH <= bufferLength) {
                self._emitData(i, EXCEPTION_LENGTH);
                return;
            }

            // frame header matches, but still missing bytes pending
            if (functionCode === (0x7f & self._cmd)) break;
        }
    });

    /**
     * Check if port is open.
     *
     * @returns {boolean}
     */
    Object.defineProperty(this, "isOpen", {
        enumerable: true,
        get: function() {
            return this._client.isOpen;
        }
    });

    EventEmitter.call(this);
}
function(path, options) {
    var self = this;

    // options
    if (typeof(options) === "undefined") options = {};

    // disable auto open, as we handle the open
    options.autoOpen = false;

    // internal buffer
    this._buffer = Buffer.alloc(0);
    this._id = 0;
    this._cmd = 0;
    this._length = 0;

    // create the SerialPort
    this._client = new SerialPort(path, options);

    // register the port data event
    this._client.on("data", function onData(data) {
        // add data to buffer
        self._buffer = Buffer.concat([self._buffer, data]);

        // check if buffer include a complete modbus answer
        var expectedLength = self._length;
        var bufferLength = self._buffer.length;

        modbusSerialDebug({ action: "receive serial rtu buffered port", data: data, buffer: self._buffer });

        // check data length
        if (expectedLength < MIN_DATA_LENGTH || bufferLength < EXCEPTION_LENGTH) return;

        // check buffer size for MAX_BUFFER_SIZE
        if (bufferLength > MAX_BUFFER_LENGTH) {
            self._buffer = self._buffer.slice(-MAX_BUFFER_LENGTH);
            bufferLength = MAX_BUFFER_LENGTH;
        }

        // loop and check length-sized buffer chunks
        var maxOffset = bufferLength - EXCEPTION_LENGTH;
        for (var i = 0; i <= maxOffset; i++) {
            var unitId = self._buffer[i];
            var functionCode = self._buffer[i + 1];

            if (unitId !== self._id) continue;

            if (functionCode === self._cmd && i + expectedLength <= bufferLength) {
                self._emitData(i, expectedLength);
                return;
            }
            if (functionCode === (0x80 | self._cmd) && i + EXCEPTION_LENGTH <= bufferLength) {
                self._emitData(i, EXCEPTION_LENGTH);
                return;
            }

            // frame header matches, but still missing bytes pending
            if (functionCode === (0x7f & self._cmd)) break;
        }
    });

    /**
     * Check if port is open.
     *
     * @returns {boolean}
     */
    Object.defineProperty(this, "isOpen", {
        enumerable: true,
        get: function() {
            return this._client.isOpen;
        }
    });

    EventEmitter.call(this);
}
function ( path , options ) { var self = this ; // options if ( typeof ( options ) === "undefined" ) options = { } ; // disable auto open, as we handle the open options . autoOpen = false ; // internal buffer this . _buffer = Buffer . alloc ( 0 ) ; this . _id = 0 ; this . _cmd = 0 ; this . _length = 0 ; // create the SerialPort this . _client = new SerialPort ( path , options ) ; // register the port data event this . _client . on ( "data" , function onData ( data ) { // add data to buffer self . _buffer = Buffer . concat ( [ self . _buffer , data ] ) ; // check if buffer include a complete modbus answer var expectedLength = self . _length ; var bufferLength = self . _buffer . length ; modbusSerialDebug ( { action : "receive serial rtu buffered port" , data : data , buffer : self . _buffer } ) ; // check data length if ( expectedLength < MIN_DATA_LENGTH || bufferLength < EXCEPTION_LENGTH ) return ; // check buffer size for MAX_BUFFER_SIZE if ( bufferLength > MAX_BUFFER_LENGTH ) { self . _buffer = self . _buffer . slice ( - MAX_BUFFER_LENGTH ) ; bufferLength = MAX_BUFFER_LENGTH ; } // loop and check length-sized buffer chunks var maxOffset = bufferLength - EXCEPTION_LENGTH ; for ( var i = 0 ; i <= maxOffset ; i ++ ) { var unitId = self . _buffer [ i ] ; var functionCode = self . _buffer [ i + 1 ] ; if ( unitId !== self . _id ) continue ; if ( functionCode === self . _cmd && i + expectedLength <= bufferLength ) { self . _emitData ( i , expectedLength ) ; return ; } if ( functionCode === ( 0x80 | self . _cmd ) && i + EXCEPTION_LENGTH <= bufferLength ) { self . _emitData ( i , EXCEPTION_LENGTH ) ; return ; } // frame header matches, but still missing bytes pending if ( functionCode === ( 0x7f & self . _cmd ) ) break ; } } ) ; /**
     * Check if port is open.
     *
     * @returns {boolean}
     */ Object . defineProperty ( this , "isOpen" , { enumerable : true , get : function ( ) { return this . _client . isOpen ; } } ) ; EventEmitter . call ( this ) ; }
Simulate a modbus-RTU port using buffered serial connection.

@param path
@param options
@constructor
Simulate a modbus - RTU port using buffered serial connection .