Comparing version 1.0.1 to 1.0.2
@@ -128,2 +128,3 @@ 'use strict'; | ||
_this._promiseResolvers = null; | ||
_this._drainPromise = null; | ||
@@ -365,3 +366,5 @@ _this._messageObserver = null; | ||
if (startFrom === 0) { | ||
this.startMessage(CMD.RESET, 0, { destination: BROADCAST_ADDRESS }).endMessage(); | ||
this.startMessage(CMD.RESET, 0, { destination: BROADCAST_ADDRESS }).endMessage().subscribe(function (err) { | ||
_this2._messageObserver.error(err); | ||
}); | ||
} | ||
@@ -382,3 +385,2 @@ | ||
this._createMessageObserver(); | ||
this.setDaisyLine(false); | ||
@@ -390,3 +392,3 @@ | ||
// Set daisy and send first address | ||
this.port.drain(function () { | ||
this._drainPromise.then(function () { | ||
_this2.setDaisyLine(true); | ||
@@ -526,3 +528,3 @@ _this2._sendBytes(startFrom); | ||
// Fill in missing data | ||
// Fill in missing data | ||
if (!this._msgOptions.responseMsg && this._sentLen < this._fullDataLen) { | ||
@@ -534,30 +536,30 @@ var missingLen = this._fullDataLen - this._sentLen; | ||
// Send CRC | ||
// Add CRC | ||
var crcValue = _crc2.default.crc16modbus(this._crc, 0xFFFF); | ||
var crcBytes = this._convert16bitTo8(crcValue); | ||
this._sendBytes(crcBytes, false); | ||
// Reset daisy and end message | ||
this.setDaisyLine(false); | ||
this._msgDone = true; | ||
// Resolve message observer | ||
if (this._messageObserver) { | ||
// Send and resolve | ||
var obs = this._messageObserver; | ||
this._sendBytes(crcBytes, false).catch(function (sendErr) { | ||
var errMsg = 'Error sending data: ' + sendErr; | ||
_this4.emit('error', errMsg); | ||
obs.error(errMsg); | ||
}).then(function () { | ||
// Ending error | ||
if (error) { | ||
this.emit('error', error); | ||
this._messageObserver.error(error); | ||
return this; | ||
_this4.emit('error', error); | ||
obs.error(error); | ||
return _this4; | ||
} | ||
this.port.drain(function (err) { | ||
if (err) { | ||
var errMsg = 'Error sending data: ' + err; | ||
_this4.emit('error', errMsg); | ||
_this4._messageObserver.error(errMsg); | ||
// Completed | ||
else { | ||
obs.complete(); | ||
} | ||
_this4._messageObserver.complete(); | ||
}); | ||
} | ||
}); | ||
// Reset daisy and clean up | ||
this.setDaisyLine(false); | ||
this._msgDone = true; | ||
return this; | ||
@@ -661,3 +663,3 @@ } | ||
} else { | ||
this.port.drain(function () { | ||
this._drainPromise.then(function () { | ||
_this6._restartResponseTimer(); | ||
@@ -788,9 +790,9 @@ }); | ||
var timeout = this._addressing ? this.timeouts.addressing : this.timeouts.nodeResponse; | ||
this._stopResponseTimer(); | ||
if (this._msgDone) return; | ||
// Start timer once data has sent | ||
this.port.drain(function () { | ||
var timeout = _this7._addressing ? _this7.timeouts.addressing : _this7.timeouts.nodeResponse; | ||
this._drainPromise.then(function () { | ||
_this7._responseTimer = setTimeout(_this7._handleResponseTimeout.bind(_this7), timeout); | ||
@@ -828,2 +830,4 @@ }); | ||
* @param {boolean} updateCRC Set this to false to not update the CRC with this byte | ||
* | ||
* @return {Promise} Resolves when the data has been sent to the device (after drain) | ||
*/ | ||
@@ -834,19 +838,31 @@ | ||
value: function _sendBytes(values) { | ||
var _this8 = this; | ||
var updateCRC = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1]; | ||
var buff = void 0; | ||
this._drainPromise = new Promise(function (resolve, reject) { | ||
var buff = void 0; | ||
if (typeof values.length !== 'undefined') { | ||
buff = Buffer.from(values); | ||
} else { | ||
buff = Buffer.from([values]); | ||
} | ||
if (typeof values.length !== 'undefined') { | ||
buff = Buffer.from(values); | ||
} else { | ||
buff = Buffer.from([values]); | ||
} | ||
this.port.write(buff); | ||
_this8.port.write(buff, function (err) { | ||
if (err) return reject(err); | ||
if (updateCRC) { | ||
for (var i = 0; i < buff.length; i++) { | ||
this._crc.push(buff.readUInt8(i)); | ||
_this8.port.drain(function (err) { | ||
if (err) reject(err);else resolve(); | ||
}); | ||
}); | ||
if (updateCRC) { | ||
for (var i = 0; i < buff.length; i++) { | ||
_this8._crc.push(buff.readUInt8(i)); | ||
} | ||
} | ||
} | ||
}); | ||
return this._drainPromise; | ||
} | ||
@@ -889,3 +905,3 @@ | ||
* @param {Any} value The value | ||
* @param {number} nodeAddr The node address associated with this value. | ||
* @param {number} nodeAddr The node address associated with this value. | ||
*/ | ||
@@ -892,0 +908,0 @@ function BusSubscriberNextVal(type, value) { |
{ | ||
"name": "discobus", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "The Disco Bus protocol, is a versatile master/slave protocol well suited for multidrop networks, like RS485.", | ||
@@ -16,4 +16,4 @@ "author": "Jeremy Gillick", | ||
"prepublish": "npm run build", | ||
"test": "node_modules/mocha/bin/mocha", | ||
"test_watch": "node_modules/mocha/bin/mocha --watch", | ||
"test": "node_modules/mocha/bin/mocha --bail", | ||
"test_watch": "node_modules/mocha/bin/mocha --watch --bail", | ||
"build": "babel src --out-dir dist -s", | ||
@@ -20,0 +20,0 @@ "build_watch": "babel src --out-dir dist -s --watch", |
@@ -14,4 +14,4 @@ 'use strict'; | ||
const SerialPort = DiscoBusMocks.SerialPort; | ||
/** | ||
@@ -22,3 +22,3 @@ * General object construction | ||
let bus; | ||
beforeEach(function(){ | ||
@@ -101,3 +101,3 @@ bus = new DiscoBusMaster(); | ||
; | ||
bus.on('error', errorEmitterSpy); | ||
@@ -170,5 +170,7 @@ bus.setDaisyLine(true); | ||
}); | ||
bus.port.drain = function(cb) { | ||
cb('Error thing'); | ||
} | ||
}; | ||
bus.endMessage(); | ||
@@ -194,5 +196,5 @@ }); | ||
it('forces array for responseDefault', function() { | ||
bus.startMessage(0x09, 2, { | ||
bus.startMessage(0x09, 2, { | ||
responseMsg: true, | ||
responseDefault: 'not array' | ||
responseDefault: 'not array' | ||
}); | ||
@@ -370,3 +372,3 @@ expect(bus._msgOptions.responseDefault).to.deep.equal([0, 0]); | ||
} | ||
}, null, | ||
}, null, | ||
() => { // complete | ||
@@ -381,3 +383,3 @@ expect(bus.messageResponse).to.have.lengthOf(5); | ||
}); | ||
// Send data for first 1.5 node sections | ||
@@ -415,3 +417,3 @@ bus.port.receiveData(Buffer.from([1, 2, 3])); | ||
it('toggles daisy line before and after addressing', function() { | ||
it('toggles daisy line before and after addressing', function(done) { | ||
let daisySpy = sinon.spy(bus, 'setDaisyLine'); | ||
@@ -422,14 +424,25 @@ let portSpy = sinon.spy(bus.port, 'set'); | ||
.subscribe(null, null, () => { | ||
expect(portSpy).to.have.been.calledWith({ rts:false }); | ||
try { | ||
expect(daisySpy.callCount).to.be.equal(4); | ||
expect(portSpy.firstCall).to.have.been.calledWith({ rts:false }); // on connect | ||
expect(portSpy.secondCall).to.have.been.calledWith({ rts:false }); // on start address | ||
expect(portSpy.thirdCall).to.have.been.calledWith({ rts:true }); // after sending address | ||
done(); | ||
} catch(e) { | ||
done(e); | ||
} | ||
}); | ||
expect(daisySpy).to.have.been.called; | ||
expect(portSpy).to.have.been.calledWith({ rts:true }); | ||
}); | ||
it('should reset nodes first', function() { | ||
it('should reset nodes first', function(done) { | ||
bus.startAddressing(); | ||
expect(bus.port.buffer).to.deep.equal([ | ||
0xFF, 0xFF, 0, 0, 0xFA, 1, 0, 161, 5, // Reset message | ||
0xFF, 0xFF, 3, 0, 0xFB, 0, 2, 0 // Addressing header | ||
]) | ||
bus._drainPromise.then(() => { | ||
try { | ||
expect(bus.port.buffer).to.deep.equal([ | ||
0xFF, 0xFF, 0, 0, 0xFA, 1, 0, 161, 5, // Reset message | ||
0xFF, 0xFF, 3, 0, 0xFB, 0, 2, 0 // Addressing header | ||
]); | ||
done(); | ||
} catch(e) { done(e); } | ||
}); | ||
}); | ||
@@ -479,5 +492,7 @@ | ||
.subscribe(null, null, () => { | ||
expect(bus.nodeNum).to.be.equal(1); | ||
expect(Date.now() - lastNodeTime).to.be.at.least(bus.timeouts.addressing); | ||
done(); | ||
try { | ||
expect(bus.nodeNum).to.be.equal(1); | ||
expect(Date.now() - lastNodeTime).to.be.at.least(bus.timeouts.addressing); | ||
done(); | ||
} catch(e) { done(e); } | ||
}); | ||
@@ -507,3 +522,5 @@ | ||
.subscribe((n) => { | ||
expect(n.type).to.be.equal('error'); | ||
try { | ||
expect(n.type).to.be.equal('error'); | ||
} catch(e) { done(e); } | ||
}, null, done); | ||
@@ -516,12 +533,13 @@ | ||
it('cancels addressing on too many invalid addresses', function(done) { | ||
let tries, | ||
finished = false; | ||
let tries; | ||
bus.startAddressing() | ||
.subscribe(null, (err) => { | ||
expect(tries).to.be.equal(10); | ||
done(); | ||
try { | ||
expect(tries).to.be.within(10, 11); | ||
done(); | ||
} catch(e) { done(e); } | ||
}); | ||
for (tries = 0; !finished && tries < 100; tries++) { | ||
for (tries = 0; !bus._msgDone && tries < 100; tries++) { | ||
bus.port.receiveData(Buffer.from([5])); | ||
@@ -534,15 +552,20 @@ } | ||
.subscribe(null, null, () => { | ||
expect(bus.port.buffer).to.deep.equal([ | ||
0xFF, 0xFF, // end of addressing | ||
0, 0, 0xFF, 0, // null message header | ||
212, 65] // CRC | ||
); | ||
done(); | ||
try { | ||
expect(bus.port.buffer).to.deep.equal([ | ||
0xFF, 0xFF, // end of addressing | ||
0, 0, 0xFF, 0, // null message header | ||
212, 65] // CRC | ||
); | ||
done(); | ||
} catch(e) { done(e); } | ||
}); | ||
// Register 1 node | ||
bus.port.receiveData(Buffer.from([1])); | ||
bus.port.buffer = []; | ||
bus._drainPromise | ||
.then(() => { | ||
bus.port.receiveData(Buffer.from([1])); | ||
bus.port.buffer = []; | ||
}); | ||
}); | ||
}); |
@@ -10,3 +10,3 @@ 'use strict'; | ||
// Stub out SerialPort module | ||
class SerialPortMock extends EventEmitter { | ||
class SerialPortMock extends EventEmitter { | ||
constructor (dev, options) { | ||
@@ -24,4 +24,5 @@ super(); | ||
write(data) { | ||
this.buffer.push.apply(this.buffer, data); | ||
write(data, cb) { | ||
this.buffer.push.apply(this.buffer, data); | ||
cb(); | ||
} | ||
@@ -42,3 +43,3 @@ drain (cb) { | ||
// Module updates | ||
var DiscoBus = proxyquire('../../dist/discobus', { | ||
var DiscoBus = proxyquire('../../dist/discobus', { | ||
'serialport': SerialPortMock | ||
@@ -45,0 +46,0 @@ }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3944619
1827
2