From b334c7688e9b18add6f5ec235978bd5ca279e53b Mon Sep 17 00:00:00 2001 From: Phillip Pietruschka Date: Wed, 10 Jan 2024 23:37:38 +1100 Subject: [PATCH 1/7] for commands that dont automatically elicit a reply, follow up with a query handle incorrect password start keep alive after login start processing cmdQueue after login --- src/actions.js | 21 ++++++++++++++++++++- src/consts.js | 1 + src/main.js | 1 + src/processcmd.js | 9 ++++++++- src/tcp.js | 27 +++++++++++++++++---------- 5 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/actions.js b/src/actions.js index b44a77c..6835c5e 100644 --- a/src/actions.js +++ b/src/actions.js @@ -135,6 +135,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoCueLevelPreset + options.mode) + self.addCmdtoQueue(SOM + cmd.autoCueLevelPreset + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -155,6 +156,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoTrackLevelPreset + options.mode) + self.addCmdtoQueue(SOM + cmd.autoTrackLevelPreset + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -198,6 +200,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoTrackLevelPreset + options.mode) + self.addCmdtoQueue(SOM + cmd.autoTrackLevelPreset + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -218,6 +221,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoCueSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.autoCueSelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -238,6 +242,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoTrackSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.autoTrackSelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -258,6 +263,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.pitchControlSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.pitchControlSelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -278,6 +284,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.autoReadySelect + options.mode) + self.addCmdtoQueue(SOM + cmd.autoReadySelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -298,6 +305,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.repeatModeSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.repeatModeSelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -318,6 +326,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.syncRecSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.syncRecSelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -338,6 +347,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.incrPlaySelect + options.mode) + self.addCmdtoQueue(SOM + cmd.incrPlaySelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -358,6 +368,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.keyControlSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.keyControlSelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -378,6 +389,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.remoteLocalModeSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.remoteLocalModeSelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -398,9 +410,12 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.playModeSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.playModeSense) }, //learn: async () => {}, - //subscribe: async () => {}, + subscribe: async () => { + self.addCmdtoQueue(SOM + cmd.playModeSense) + }, }, specifiedDeviceStatusSense: { name: 'Specified Device Status Sense', @@ -473,6 +488,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.deviceSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.deviceSelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -510,6 +526,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.playAreaSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.playAreaSelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -530,6 +547,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.fileNameSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.fileNameSelect + 'FF') }, //learn: async () => {}, subscribe: async () => { @@ -568,6 +586,7 @@ module.exports = function (self) { ], callback: async ({ options }) => { self.addCmdtoQueue(SOM + cmd.inputSelect + options.mode) + self.addCmdtoQueue(SOM + cmd.inputSelect + 'FF') }, //learn: async () => {}, subscribe: async () => { diff --git a/src/consts.js b/src/consts.js index d42a97d..544f9d0 100644 --- a/src/consts.js +++ b/src/consts.js @@ -79,6 +79,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/main.js b/src/main.js index 6c0c08d..1aded08 100644 --- a/src/main.js +++ b/src/main.js @@ -56,6 +56,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..a281fdd 100644 --- a/src/processcmd.js +++ b/src/processcmd.js @@ -7,15 +7,21 @@ module.exports = { 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 for (let i = 0; i < cmdOnLogin.length; i++) { this.addCmdtoQueue(SOM + cmdOnLogin[i]) } + this.startKeepAlive() return true + case resp.loginFail: + this.recorder.loggedIn = false + this.log('error', 'Password is incorrect') + return false } while (reply[0] != SOM && reply.length > 0) { reply = reply.slice(1) @@ -25,6 +31,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) { diff --git a/src/tcp.js b/src/tcp.js index 64c5f9d..7b8c226 100644 --- a/src/tcp.js +++ b/src/tcp.js @@ -2,18 +2,18 @@ const { InstanceStatus, TCPHelper } = require('@companion-module/base') const { msgDelay, cmd, cmdOnKeepAlive, SOM, EOM, EndSession, keepAliveInterval, 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 +21,11 @@ module.exports = { } this.cmdTimer = setTimeout(() => { this.processCmdQueue() - }, msgDelay / 4) + }, msgDelay) return undefined }, - async sendCommand(msg) { + sendCommand(msg) { if (msg !== undefined) { if (this.socket !== undefined && this.socket.isConnected) { this.log('debug', `Sending Command: ${msg}`) @@ -43,10 +43,12 @@ module.exports = { //queries made on initial connection. async queryOnConnect() { this.sendCommand(' ') + this.recorder.loggedIn = true if (this.config.password == '') { for (let i = 0; i < cmdOnLogin.length; i++) { this.addCmdtoQueue(SOM + cmdOnLogin[i]) } + this.startKeepAlive() } return true }, @@ -62,6 +64,12 @@ module.exports = { }, keepAliveInterval) }, + startKeepAlive() { + this.keepAliveTimer = setTimeout(() => { + this.keepAlive() + }, keepAliveInterval) + }, + initTCP() { this.receiveBuffer = '' if (this.socket !== undefined) { @@ -80,14 +88,13 @@ module.exports = { }) this.socket.on('error', (err) => { this.log('error', `Network error: ${err.message}`) + this.recorder.loggedIn = false clearTimeout(this.keepAliveTimer) }) this.socket.on('connect', () => { this.log('info', `Connected to ${this.config.host}:${this.config.port}`) + this.recorder.loggedIn = false this.queryOnConnect() - this.keepAliveTimer = setTimeout(() => { - this.keepAlive() - }, keepAliveInterval) }) this.socket.on('data', (chunk) => { let i = 0, From 8d22f41f5a1a8a62afba3d23c0e7687ac4a23341 Mon Sep 17 00:00:00 2001 From: Phillip Pietruschka Date: Thu, 11 Jan 2024 22:15:15 +1100 Subject: [PATCH 2/7] remove redundant asyncs version bump --- companion/HELP.md | 5 +- package.json | 2 +- src/actions.js | 156 +++++++++++++++++++++++----------------------- src/feedbacks.js | 10 +-- src/processcmd.js | 4 +- src/tcp.js | 2 +- 6 files changed, 91 insertions(+), 88 deletions(-) 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/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 6835c5e..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,12 +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') }, }, @@ -154,12 +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') }, }, @@ -177,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', @@ -198,12 +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') }, }, @@ -219,12 +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') }, }, @@ -240,12 +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') }, }, @@ -261,12 +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') }, }, @@ -282,12 +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') }, }, @@ -303,12 +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') }, }, @@ -324,12 +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') }, }, @@ -345,12 +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') }, }, @@ -366,12 +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') }, }, @@ -387,12 +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') }, }, @@ -408,12 +408,12 @@ module.exports = function (self) { default: '00', }, ], - callback: async ({ options }) => { + callback: ({ options }) => { self.addCmdtoQueue(SOM + cmd.playModeSelect + options.mode) self.addCmdtoQueue(SOM + cmd.playModeSense) }, - //learn: async () => {}, - subscribe: async () => { + //learn: () => {}, + subscribe: () => { self.addCmdtoQueue(SOM + cmd.playModeSense) }, }, @@ -430,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', @@ -449,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', @@ -468,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', @@ -486,12 +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') }, }, @@ -500,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) }, }, @@ -508,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) }, }, @@ -524,12 +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') }, }, @@ -545,12 +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') }, }, @@ -566,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', @@ -584,12 +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/feedbacks.js b/src/feedbacks.js index 92617db..5586947 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') }, }, @@ -179,7 +179,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 +203,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/processcmd.js b/src/processcmd.js index a281fdd..7b8c2fa 100644 --- a/src/processcmd.js +++ b/src/processcmd.js @@ -1,7 +1,7 @@ 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}`) @@ -143,7 +143,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 7b8c226..67646aa 100644 --- a/src/tcp.js +++ b/src/tcp.js @@ -41,7 +41,7 @@ module.exports = { }, //queries made on initial connection. - async queryOnConnect() { + queryOnConnect() { this.sendCommand(' ') this.recorder.loggedIn = true if (this.config.password == '') { From 599f8421c20f947e48c924d25999358333865960 Mon Sep 17 00:00:00 2001 From: Phillip Pietruschka Date: Thu, 11 Jan 2024 22:16:00 +1100 Subject: [PATCH 3/7] update manifest --- companion/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/companion/manifest.json b/companion/manifest.json index 39a29eb..f8fc68c 100644 --- a/companion/manifest.json +++ b/companion/manifest.json @@ -3,7 +3,7 @@ "name": "tascam-cd", "shortname": "SS-CDR250N / SS-R250N", "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", From 09ebc2c592bc2bb293e1a4bb1adeb2306554ac25 Mon Sep 17 00:00:00 2001 From: Phillip Pietruschka Date: Fri, 12 Jan 2024 20:28:13 +1100 Subject: [PATCH 4/7] timer saftey --- src/consts.js | 1 + src/main.js | 13 +++++---- src/processcmd.js | 7 ++++- src/tcp.js | 68 ++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/src/consts.js b/src/consts.js index 544f9d0..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' diff --git a/src/main.js b/src/main.js index 1aded08..3f24589 100644 --- a/src/main.js +++ b/src/main.js @@ -7,7 +7,7 @@ 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) { @@ -15,28 +15,27 @@ class TASCAM_SS_CDR250N extends InstanceBase { Object.assign(this, { ...config, ...tcp, ...processCmd, ...choices }) this.keepAliveTimer = {} this.cmdTimer = {} + this.timeOutTimer = {} 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() diff --git a/src/processcmd.js b/src/processcmd.js index 7b8c2fa..f36e3d8 100644 --- a/src/processcmd.js +++ b/src/processcmd.js @@ -13,14 +13,19 @@ module.exports = { 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]) } - this.startKeepAlive() 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) { diff --git a/src/tcp.js b/src/tcp.js index 67646aa..777ddb3 100644 --- a/src/tcp.js +++ b/src/tcp.js @@ -1,5 +1,15 @@ 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 = { addCmdtoQueue(msg) { @@ -25,6 +35,20 @@ module.exports = { return undefined }, + startCmdQueue() { + this.log('debug', 'starting cmdTimer') + clearTimeout(this.cmdTimer) + this.cmdTimer = setTimeout(() => { + this.processCmdQueue() + }, msgDelay) + }, + + stopCmdQueue() { + this.log('debug', 'stopping cmdTimer') + clearTimeout(this.cmdTimer) + this.cmdTimer = null + }, + sendCommand(msg) { if (msg !== undefined) { if (this.socket !== undefined && this.socket.isConnected) { @@ -43,8 +67,8 @@ module.exports = { //queries made on initial connection. queryOnConnect() { this.sendCommand(' ') - this.recorder.loggedIn = true if (this.config.password == '') { + this.recorder.loggedIn = true for (let i = 0; i < cmdOnLogin.length; i++) { this.addCmdtoQueue(SOM + cmdOnLogin[i]) } @@ -65,17 +89,52 @@ module.exports = { }, startKeepAlive() { + this.log('debug', 'starting keepAlive') + clearTimeout(this.keepAliveTimer) this.keepAliveTimer = setTimeout(() => { this.keepAlive() }, keepAliveInterval) }, + stopKeepAlive() { + this.log('debug', 'stopping keepAlive') + clearTimeout(this.keepAliveTimer) + this.keepAliveTimer = null + }, + + 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') + clearTimeout(this.timeOutTimer) + this.timeOutTimer = setTimeout(() => { + this.timeOut() + }, timeOutInterval) + }, + + stopTimeOut() { + this.log('debug', 'stopping timeOutTimer') + clearTimeout(this.timeOutTimer) + this.timeOutTimer = null + }, + 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') @@ -89,10 +148,13 @@ module.exports = { this.socket.on('error', (err) => { this.log('error', `Network error: ${err.message}`) this.recorder.loggedIn = false - clearTimeout(this.keepAliveTimer) + 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() }) From 087a5668e10a82eec2cfc799f61a8113c58d2d57 Mon Sep 17 00:00:00 2001 From: Phillip Pietruschka Date: Fri, 12 Jan 2024 20:41:14 +1100 Subject: [PATCH 5/7] fix manifest shortname regex tweak --- companion/manifest.json | 2 +- src/config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/companion/manifest.json b/companion/manifest.json index f8fc68c..17fd817 100644 --- a/companion/manifest.json +++ b/companion/manifest.json @@ -1,7 +1,7 @@ { "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.2", "license": "MIT", 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', }, ] From f11d7bb70bcfeae0cd58614f7eb09214ce966a73 Mon Sep 17 00:00:00 2001 From: Phillip Pietruschka Date: Fri, 12 Jan 2024 21:10:11 +1100 Subject: [PATCH 6/7] fix queryOnConnect in case on no password --- src/tcp.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tcp.js b/src/tcp.js index 777ddb3..6b8a471 100644 --- a/src/tcp.js +++ b/src/tcp.js @@ -69,10 +69,12 @@ module.exports = { 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]) } - this.startKeepAlive() } return true }, From f291d71545cd81201144e93df6008020bd05e12c Mon Sep 17 00:00:00 2001 From: Phillip Pietruschka Date: Mon, 15 Jan 2024 13:46:27 +1100 Subject: [PATCH 7/7] Play Mode Feedback subscribe callback timer saftey --- src/feedbacks.js | 3 +++ src/main.js | 5 +---- src/tcp.js | 21 +++++++++++++++------ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/feedbacks.js b/src/feedbacks.js index 5586947..e512e07 100644 --- a/src/feedbacks.js +++ b/src/feedbacks.js @@ -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', diff --git a/src/main.js b/src/main.js index 3f24589..d9b389c 100644 --- a/src/main.js +++ b/src/main.js @@ -13,9 +13,6 @@ class TASCAM_SS_CDR250N extends InstanceBase { constructor(internal) { super(internal) Object.assign(this, { ...config, ...tcp, ...processCmd, ...choices }) - this.keepAliveTimer = {} - this.cmdTimer = {} - this.timeOutTimer = {} this.cmdQueue = [] } async init(config) { @@ -32,13 +29,13 @@ class TASCAM_SS_CDR250N extends InstanceBase { // When module gets deleted async destroy() { this.log('debug', `destroy. ID: ${this.id}`) - clearTimeout(this.keepAliveTimer) this.stopCmdQueue() this.stopTimeOut() this.stopKeepAlive() if (this.socket) { this.sendCommand(EndSession) this.socket.destroy() + delete this.socket } this.updateStatus(InstanceStatus.Disconnected) } diff --git a/src/tcp.js b/src/tcp.js index 6b8a471..c076900 100644 --- a/src/tcp.js +++ b/src/tcp.js @@ -37,7 +37,10 @@ module.exports = { startCmdQueue() { this.log('debug', 'starting cmdTimer') - clearTimeout(this.cmdTimer) + if (this.cmdTimer) { + clearTimeout(this.cmdTimer) + delete this.cmdTimer + } this.cmdTimer = setTimeout(() => { this.processCmdQueue() }, msgDelay) @@ -46,7 +49,7 @@ module.exports = { stopCmdQueue() { this.log('debug', 'stopping cmdTimer') clearTimeout(this.cmdTimer) - this.cmdTimer = null + delete this.cmdTimer }, sendCommand(msg) { @@ -92,7 +95,10 @@ module.exports = { startKeepAlive() { this.log('debug', 'starting keepAlive') - clearTimeout(this.keepAliveTimer) + if (this.keepAliveTimer) { + clearTimeout(this.keepAliveTimer) + delete this.keepAliveTimer + } this.keepAliveTimer = setTimeout(() => { this.keepAlive() }, keepAliveInterval) @@ -101,7 +107,7 @@ module.exports = { stopKeepAlive() { this.log('debug', 'stopping keepAlive') clearTimeout(this.keepAliveTimer) - this.keepAliveTimer = null + delete this.keepAliveTimer }, timeOut() { @@ -115,7 +121,10 @@ module.exports = { startTimeOut() { this.log('debug', 'starting timeOutTimer') - clearTimeout(this.timeOutTimer) + if (this.timeOutTimer) { + clearTimeout(this.timeOutTimer) + delete this.timeOutTimer + } this.timeOutTimer = setTimeout(() => { this.timeOut() }, timeOutInterval) @@ -124,7 +133,7 @@ module.exports = { stopTimeOut() { this.log('debug', 'stopping timeOutTimer') clearTimeout(this.timeOutTimer) - this.timeOutTimer = null + delete this.timeOutTimer }, initTCP() {