diff --git a/companion/HELP.md b/companion/HELP.md index 4816652..1927660 100644 --- a/companion/HELP.md +++ b/companion/HELP.md @@ -166,9 +166,12 @@ Enter the IP address, port of the media player. If a password is required, enter ## Version History +### Version 2.0.2 +- Minor fixes + ### Version 2.0.1 - Add action & feedback subscription callbacks -- Update package.josn +- Update package.json - Update companion-module-base to 1.7.0 ### Version 2.0.0 diff --git a/companion/manifest.json b/companion/manifest.json index 39a29eb..17fd817 100644 --- a/companion/manifest.json +++ b/companion/manifest.json @@ -1,9 +1,9 @@ { "id": "tascam-cd", "name": "tascam-cd", - "shortname": "SS-CDR250N / SS-R250N", + "shortname": "SS-CDR250N", "description": "Bitfocus Companion module for the Tascam SS-CDR250N and SS-R250N", - "version": "2.0.1", + "version": "2.0.2", "license": "MIT", "repository": "git+https://github.com/bitfocus/companion-module-tascam-cd.git", "bugs": "https://github.com/bitfocus/companion-module-tascam-cd/issues", diff --git a/package.json b/package.json index 0050c48..0470376 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tascam-cd", - "version": "2.0.1", + "version": "2.0.2", "main": "src/main.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", diff --git a/src/actions.js b/src/actions.js index b44a77c..0bc3a8c 100644 --- a/src/actions.js +++ b/src/actions.js @@ -8,7 +8,7 @@ module.exports = function (self) { description: 'STOP puts the controlled device into the stop state and also takes the controlled device out of input monitor mode.', options: [], - callback: async () => { + callback: () => { self.addCmdtoQueue(SOM + cmd.stop) }, }, @@ -17,7 +17,7 @@ module.exports = function (self) { description: 'Play puts the controlled device into playback mode and also brings the controlled device from record ready mode to recording mode.', options: [], - callback: async () => { + callback: () => { self.addCmdtoQueue(SOM + cmd.play) }, }, @@ -34,7 +34,7 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.record + options.mode) }, }, @@ -42,7 +42,7 @@ module.exports = function (self) { name: 'Pause', description: 'READY puts the controlled device into playback standby mode or record ready mode.', options: [], - callback: async () => { + callback: () => { self.addCmdtoQueue(SOM + cmd.pause + '01') }, }, @@ -58,7 +58,7 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.jog + options.mode) }, }, @@ -75,7 +75,7 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.shuttle + options.mode) }, }, @@ -83,7 +83,7 @@ module.exports = function (self) { name: 'Flash Load', description: 'FLASH LOAD puts the controlled device into Flash Load mode.', options: [], - callback: async () => { + callback: () => { self.addCmdtoQueue(SOM + cmd.flashLoad) }, }, @@ -92,7 +92,7 @@ module.exports = function (self) { description: 'EJECT ejects a CD Media from the controlled device. (If the controlled device is SS-R250N, it returns ILLEGAL [F2].) If the device selected on the controlled device is not CD, this command is ignored.', options: [], - callback: async () => { + callback: () => { self.addCmdtoQueue(SOM + cmd.eject) }, }, @@ -108,7 +108,7 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.skip + options.mode) }, }, @@ -117,7 +117,7 @@ module.exports = function (self) { description: 'CALL locates the controlled device to a call point and puts the controlled device into the ready state.', options: [], - callback: async () => { + callback: () => { self.addCmdtoQueue(SOM + cmd.call) }, }, @@ -133,11 +133,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoCueLevelPreset + options.mode) + self.addCmdtoQueue(SOM + cmd.autoCueLevelPreset + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.autoCueLevelPreset + 'FF') }, }, @@ -153,11 +154,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoTrackLevelPreset + options.mode) + self.addCmdtoQueue(SOM + cmd.autoTrackLevelPreset + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.autoTrackLevelPreset + 'FF') }, }, @@ -175,14 +177,14 @@ module.exports = function (self) { tooltip: 'Enter a 1 to 4 digit track number.', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { let num = ('0000' + options.track).substr(-4) let track = num.substr(2) track += num.substr(0, 2) self.addCmdtoQueue(SOM + cmd.directTrackSearchPreset + track) }, - //learn: async () => {}, - //subscribe: async () => {}, + //learn: () => {}, + //subscribe: () => {}, }, syncRecLevelPreset: { name: 'Sync Rec Level Preset', @@ -196,11 +198,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoTrackLevelPreset + options.mode) + self.addCmdtoQueue(SOM + cmd.autoTrackLevelPreset + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.autoTrackLevelPreset + 'FF') }, }, @@ -216,11 +219,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoCueSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.autoCueSelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.autoCueSelect + 'FF') }, }, @@ -236,11 +240,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoTrackSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.autoTrackSelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.autoTrackSelect + 'FF') }, }, @@ -256,11 +261,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.pitchControlSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.pitchControlSelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.pitchControlSelect + 'FF') }, }, @@ -276,11 +282,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoReadySelect + options.mode) + self.addCmdtoQueue(SOM + cmd.autoReadySelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.autoReadySelect + 'FF') }, }, @@ -296,11 +303,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.repeatModeSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.repeatModeSelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.repeatModeSelect + 'FF') }, }, @@ -316,11 +324,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.syncRecSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.syncRecSelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.syncRecSelect + 'FF') }, }, @@ -336,11 +345,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.incrPlaySelect + options.mode) + self.addCmdtoQueue(SOM + cmd.incrPlaySelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.incrPlaySelect + 'FF') }, }, @@ -356,11 +366,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.keyControlSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.keyControlSelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.keyControlSelect + 'FF') }, }, @@ -376,11 +387,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.remoteLocalModeSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.remoteLocalModeSelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.remoteLocalModeSelect + 'FF') }, }, @@ -396,11 +408,14 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.playModeSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.playModeSense) + }, + //learn: () => {}, + subscribe: () => { + self.addCmdtoQueue(SOM + cmd.playModeSense) }, - //learn: async () => {}, - //subscribe: async () => {}, }, specifiedDeviceStatusSense: { name: 'Specified Device Status Sense', @@ -415,11 +430,11 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.specifiedDeviceStatusSense + options.mode) }, - //learn: async () => {}, - //subscribe: async () => {}, + //learn: () => {}, + //subscribe: () => {}, }, currentTrackTime: { name: 'Current Track Time Sense', @@ -434,12 +449,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.recorder.track.currentTrackTime = options.mode self.addCmdtoQueue(SOM + cmd.currentTrackTimeSense + self.recorder.track.currentTrackTime) }, - //learn: async () => {}, - //subscribe: async () => {}, + //learn: () => {}, + //subscribe: () => {}, }, powerControl: { name: 'Power Control', @@ -453,11 +468,11 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.powerControl + options.mode) }, - //learn: async () => {}, - //subscribe: async () => {}, + //learn: () => {}, + //subscribe: () => {}, }, deviceSelect: { name: 'Device Select', @@ -471,11 +486,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.deviceSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.deviceSelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.deviceSelect + 'FF') }, }, @@ -484,7 +500,7 @@ module.exports = function (self) { description: 'The File currently in playback standby mode on the controlled device is divided into two files at that point.', options: [], - callback: async () => { + callback: () => { self.addCmdtoQueue(SOM + cmd.divide) }, }, @@ -492,7 +508,7 @@ module.exports = function (self) { name: 'Delete', description: 'The file(s) for the current track on the controlled device are deleted.', options: [], - callback: async () => { + callback: () => { self.addCmdtoQueue(SOM + cmd.delete) }, }, @@ -508,11 +524,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.playAreaSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.playAreaSelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.playAreaSelect + 'FF') }, }, @@ -528,11 +545,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.fileNameSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.fileNameSelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.fileNameSelect + 'FF') }, }, @@ -548,11 +566,11 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.mediaFormat + options.mode) }, - //learn: async () => {}, - //subscribe: async () => {}, + //learn: () => {}, + //subscribe: () => {}, }, inputSelect: { name: 'Input Select', @@ -566,11 +584,12 @@ module.exports = function (self) { default: '000000', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.inputSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.inputSelect + 'FF') }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.inputSelect + 'FF') }, }, diff --git a/src/config.js b/src/config.js index 0a4c508..1d56063 100644 --- a/src/config.js +++ b/src/config.js @@ -35,7 +35,7 @@ module.exports = { label: 'Password', width: 6, default: 'SS-CDR250N', - regex: '/^.{0,10}/g', + regex: '/^.{0,10}/', tooltip: 'Defaults to model name: SS-CDR250N / SS-R250N', }, ] diff --git a/src/consts.js b/src/consts.js index d42a97d..586ac9c 100644 --- a/src/consts.js +++ b/src/consts.js @@ -1,5 +1,6 @@ export const msgDelay = 20 // Make sure that commands are sent at a minimum of 20-millisecond intervals. export const keepAliveInterval = 1000 +export const timeOutInterval = 15000 export const SOM = '0' export const EOM = '\r\n' export const EndSession = 'exit' @@ -79,6 +80,7 @@ export const cmd = { export const resp = { password: 'Enter Password', loginSuccess: 'Login Successful', + loginFail: 'Password is different', keepAlive: 'FA', infoReturn: '8F', flashLoadAck: '97', diff --git a/src/feedbacks.js b/src/feedbacks.js index 92617db..e512e07 100644 --- a/src/feedbacks.js +++ b/src/feedbacks.js @@ -23,7 +23,7 @@ module.exports = async function (self) { callback: ({ options }) => { return options.status == self.recorder.repeat }, - subscribe: async () => { + subscribe: () => { self.addCmdtoQueue(SOM + cmd.repeatModeSelect + 'FF') }, }, @@ -47,7 +47,7 @@ module.exports = async function (self) { callback: ({ options }) => { return options.status == self.recorder.incrPlay }, - subscribe: async () => { + subscribe: () => { self.addCmdtoQueue(SOM + cmd.incrPlaySelect + 'FF') }, }, @@ -71,7 +71,7 @@ module.exports = async function (self) { callback: ({ options }) => { return options.status == self.recorder.remoteLocal }, - subscribe: async () => { + subscribe: () => { self.addCmdtoQueue(SOM + cmd.remoteLocalModeSelect + 'FF') }, }, @@ -95,6 +95,9 @@ module.exports = async function (self) { callback: ({ options }) => { return options.status == self.recorder.playMode }, + subscribe: () => { + self.addCmdtoQueue(SOM + cmd.playModeSense) + }, }, mechaStatus: { name: 'Mecha Status', @@ -179,7 +182,7 @@ module.exports = async function (self) { callback: ({ options }) => { return options.device == self.recorder.device }, - subscribe: async () => { + subscribe: () => { self.addCmdtoQueue(SOM + cmd.deviceSelect + 'FF') }, }, @@ -203,7 +206,7 @@ module.exports = async function (self) { callback: ({ options }) => { return options.playArea == self.recorder.playArea }, - subscribe: async () => { + subscribe: () => { self.addCmdtoQueue(SOM + cmd.playAreaSelect + 'FF') }, }, diff --git a/src/main.js b/src/main.js index 6c0c08d..d9b389c 100644 --- a/src/main.js +++ b/src/main.js @@ -7,39 +7,35 @@ const config = require('./config.js') const choices = require('./choices.js') const tcp = require('./tcp.js') const processCmd = require('./processcmd.js') -const { EndSession, msgDelay } = require('./consts.js') +const { EndSession } = require('./consts.js') class TASCAM_SS_CDR250N extends InstanceBase { constructor(internal) { super(internal) Object.assign(this, { ...config, ...tcp, ...processCmd, ...choices }) - this.keepAliveTimer = {} - this.cmdTimer = {} this.cmdQueue = [] } async init(config) { this.updateStatus('Starting') this.config = config - this.cmdTimer = setTimeout(() => { - this.processCmdQueue() - }, msgDelay) this.initVariables() this.updateActions() // export actions this.updateFeedbacks() // export feedbacks this.updateVariableDefinitions() // export variable definitions this.updateVariableValues() this.initTCP() + this.startTimeOut() } // When module gets deleted async destroy() { this.log('debug', `destroy. ID: ${this.id}`) - clearTimeout(this.keepAliveTimer) - clearTimeout(this.cmdTimer) - this.keepAliveTimer = null - this.cmdTimer = null + this.stopCmdQueue() + this.stopTimeOut() + this.stopKeepAlive() if (this.socket) { this.sendCommand(EndSession) this.socket.destroy() + delete this.socket } this.updateStatus(InstanceStatus.Disconnected) } @@ -56,6 +52,7 @@ class TASCAM_SS_CDR250N extends InstanceBase { initVariables() { this.recorder = { + loggedIn: false, mechaStatus: 'unknown', repeat: 'unknown', incrPlay: 'unknown', diff --git a/src/processcmd.js b/src/processcmd.js index e9b5758..f36e3d8 100644 --- a/src/processcmd.js +++ b/src/processcmd.js @@ -1,21 +1,32 @@ const { resp, cmd, cmdOnLogin, SOM } = require('./consts.js') module.exports = { - async processCmd(chunk) { + processCmd(chunk) { let reply = chunk.toString() this.log('debug', `response recieved: ${reply}`) switch (reply) { case resp.password: - this.addCmdtoQueue(this.config.password) + this.sendCommand(this.config.password) return true case resp.loginSuccess: this.updateStatus('ok', 'Logged in') this.log('info', 'OK: Logged In') + this.recorder.loggedIn = true + this.stopTimeOut() + this.startCmdQueue() + this.startKeepAlive() for (let i = 0; i < cmdOnLogin.length; i++) { this.addCmdtoQueue(SOM + cmdOnLogin[i]) } return true + case resp.loginFail: + this.recorder.loggedIn = false + this.log('error', 'Password is incorrect') + this.stopCmdQueue() + this.stopKeepAlive() + this.startTimeOut() + return false } while (reply[0] != SOM && reply.length > 0) { reply = reply.slice(1) @@ -25,6 +36,7 @@ module.exports = { } let response = reply.substr(1, 2) let venderCmd = reply.substr(1, 6) + venderCmd = venderCmd.substr(0, 4) == resp.deviceSelectReturn ? venderCmd.substr(0, 4) : venderCmd let param = [] let varList = [] switch (response) { @@ -136,7 +148,7 @@ module.exports = { this.addCmdtoQueue(SOM + cmd.cautionSense) break case resp.illegalStatus: - this.log('warn', 'Illegal Status: Invalid Command') + this.log('warn', `Illegal Status, Invalid Command: ${reply.substr(3)}`) break case resp.powerOnStatus: this.log('info', 'powerOnStatus') diff --git a/src/tcp.js b/src/tcp.js index 64c5f9d..c076900 100644 --- a/src/tcp.js +++ b/src/tcp.js @@ -1,19 +1,29 @@ const { InstanceStatus, TCPHelper } = require('@companion-module/base') -const { msgDelay, cmd, cmdOnKeepAlive, SOM, EOM, EndSession, keepAliveInterval, cmdOnLogin } = require('./consts.js') +const { + msgDelay, + cmd, + cmdOnKeepAlive, + SOM, + EOM, + EndSession, + keepAliveInterval, + timeOutInterval, + cmdOnLogin, +} = require('./consts.js') module.exports = { - async addCmdtoQueue(msg) { + addCmdtoQueue(msg) { if (msg !== undefined && msg.length > 0) { - await this.cmdQueue.push(msg) + this.cmdQueue.push(msg) return true } this.log('warn', `Invalid command: ${msg}`) return false }, - async processCmdQueue() { - if (this.cmdQueue.length > 0) { - this.sendCommand(await this.cmdQueue.splice(0, 1)) + processCmdQueue() { + if (this.cmdQueue.length > 0 && this.recorder.loggedIn) { + this.sendCommand(this.cmdQueue.splice(0, 1)) this.cmdTimer = setTimeout(() => { this.processCmdQueue() }, msgDelay) @@ -21,11 +31,28 @@ module.exports = { } this.cmdTimer = setTimeout(() => { this.processCmdQueue() - }, msgDelay / 4) + }, msgDelay) return undefined }, - async sendCommand(msg) { + startCmdQueue() { + this.log('debug', 'starting cmdTimer') + if (this.cmdTimer) { + clearTimeout(this.cmdTimer) + delete this.cmdTimer + } + this.cmdTimer = setTimeout(() => { + this.processCmdQueue() + }, msgDelay) + }, + + stopCmdQueue() { + this.log('debug', 'stopping cmdTimer') + clearTimeout(this.cmdTimer) + delete this.cmdTimer + }, + + sendCommand(msg) { if (msg !== undefined) { if (this.socket !== undefined && this.socket.isConnected) { this.log('debug', `Sending Command: ${msg}`) @@ -41,9 +68,13 @@ module.exports = { }, //queries made on initial connection. - async queryOnConnect() { + queryOnConnect() { this.sendCommand(' ') if (this.config.password == '') { + this.recorder.loggedIn = true + this.stopTimeOut() + this.startCmdQueue() + this.startKeepAlive() for (let i = 0; i < cmdOnLogin.length; i++) { this.addCmdtoQueue(SOM + cmdOnLogin[i]) } @@ -62,12 +93,59 @@ module.exports = { }, keepAliveInterval) }, + startKeepAlive() { + this.log('debug', 'starting keepAlive') + if (this.keepAliveTimer) { + clearTimeout(this.keepAliveTimer) + delete this.keepAliveTimer + } + this.keepAliveTimer = setTimeout(() => { + this.keepAlive() + }, keepAliveInterval) + }, + + stopKeepAlive() { + this.log('debug', 'stopping keepAlive') + clearTimeout(this.keepAliveTimer) + delete this.keepAliveTimer + }, + + timeOut() { + //dump cmdQueue to prevent excessive queuing of old commands + this.log('debug', 'timeout reached purging queued commands') + this.cmdQueue = [] + this.timeOutTimer = setTimeout(() => { + this.timeOut() + }, timeOutInterval) + }, + + startTimeOut() { + this.log('debug', 'starting timeOutTimer') + if (this.timeOutTimer) { + clearTimeout(this.timeOutTimer) + delete this.timeOutTimer + } + this.timeOutTimer = setTimeout(() => { + this.timeOut() + }, timeOutInterval) + }, + + stopTimeOut() { + this.log('debug', 'stopping timeOutTimer') + clearTimeout(this.timeOutTimer) + delete this.timeOutTimer + }, + initTCP() { this.receiveBuffer = '' if (this.socket !== undefined) { this.sendCommand(EndSession) this.socket.destroy() delete this.socket + this.recorder.loggedIn = false + this.startTimeOut() + this.stopCmdQueue() + this.stopKeepAlive() } if (this.config.host) { this.log('debug', 'Creating New Socket') @@ -80,14 +158,16 @@ module.exports = { }) this.socket.on('error', (err) => { this.log('error', `Network error: ${err.message}`) - clearTimeout(this.keepAliveTimer) + this.recorder.loggedIn = false + this.stopKeepAlive() + this.stopCmdQueue() + this.startTimeOut() }) this.socket.on('connect', () => { this.log('info', `Connected to ${this.config.host}:${this.config.port}`) + this.receiveBuffer = '' + this.recorder.loggedIn = false this.queryOnConnect() - this.keepAliveTimer = setTimeout(() => { - this.keepAlive() - }, keepAliveInterval) }) this.socket.on('data', (chunk) => { let i = 0,