From b76256ec26e737c54bc0eab63926a0edf407c6ce Mon Sep 17 00:00:00 2001 From: chughts Date: Tue, 20 Feb 2018 16:37:10 -0800 Subject: [PATCH 1/3] Added mute option for STT streaming --- README.md | 3 +++ package.json | 2 +- services/speech_to_text/v1.html | 8 ++++++++ services/speech_to_text/v1.js | 17 +++++++++++++---- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9b5ba9a5..0014f8a8 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ Node-RED Watson Nodes for IBM Cloud CLA assistant +### New in version 0.6.6 +- Mute option for STT Node warning status when running in Streaming mode + ### New in version 0.6.5 - Endpoint can now be specified in Natural Language Classifier Node diff --git a/package.json b/package.json index 5b6f56a2..caf1f066 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red-node-watson", - "version": "0.6.5", + "version": "0.6.6", "description": "A collection of Node-RED nodes for IBM Watson services", "dependencies": { "async": "^1.5.2", diff --git a/services/speech_to_text/v1.html b/services/speech_to_text/v1.html index 9ff20709..cd351cee 100644 --- a/services/speech_to_text/v1.html +++ b/services/speech_to_text/v1.html @@ -88,6 +88,12 @@ +
+ + + +
+
@@ -148,6 +154,7 @@ is as per the WebSocket input for Speech To Text, with an action of either start or stop or an audio blob. No token is needed as the node takes care of that step.

+

>The Mute option allows for the supression of session timeout messages.

For more information about the Speech To Text service, read the documentation.

@@ -542,6 +549,7 @@ password: {value: ''}, 'payload-response' :{value: false}, 'streaming-mode' :{value: false}, + 'streaming-mute' :{value: true}, 'default-endpoint' :{value: true}, 'service-endpoint' :{value: 'https://stream.watsonplatform.net/speech-to-text/api'} }, diff --git a/services/speech_to_text/v1.js b/services/speech_to_text/v1.js index 94fbc3d4..4d530abf 100644 --- a/services/speech_to_text/v1.js +++ b/services/speech_to_text/v1.js @@ -28,6 +28,7 @@ module.exports = function (RED) { payloadutils = require('../../utilities/payload-utils'), sttV1 = require('watson-developer-cloud/speech-to-text/v1'), authV1 = require('watson-developer-cloud/authorization/v1'), + muteMode = true; username = '', password = '', sUsername = '', sPassword = '', endpoint = '', sEndpoint = 'https://stream.watsonplatform.net/speech-to-text/api', @@ -133,6 +134,8 @@ module.exports = function (RED) { function configCheck() { var message = ''; + muteMode = config['streaming-mute']; + if (!config.lang) { message = 'Missing audio language configuration, unable to process speech.'; } else if (!config.band) { @@ -397,7 +400,10 @@ module.exports = function (RED) { // Force Expiry of Token, as that is the only Error // response from the service that we have seen. // report the error for verbose testing - payloadutils.reportError(node,newMsg,d.error); + if (!muteMode) { + payloadutils.reportError(node,newMsg,d.error); + } + token = null; getToken(determineService()) .then(() => { @@ -423,7 +429,9 @@ module.exports = function (RED) { ws.on('error', (err) => { socketListening = false; - payloadutils.reportError(node,newMsg,err); + if (!muteMode) { + payloadutils.reportError(node,newMsg,err); + } // console.log('Error Detected'); if (initialConnect) { //reject(err); @@ -472,8 +480,9 @@ module.exports = function (RED) { //websocket.send(a.data); websocket.send(a.data, (error) => { if (error) { - payloadutils.reportError(node,{},error); - } else { + if (!muteMode) { + payloadutils.reportError(node,{},error); + } } }); } From 6feddd00b7833d4e8d72fc1c4261712330c97940 Mon Sep 17 00:00:00 2001 From: chughts Date: Mon, 5 Mar 2018 11:45:32 +0000 Subject: [PATCH 2/3] Socket disconnect test --- package.json | 2 +- services/speech_to_text/v1.js | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index caf1f066..619470fe 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "word-count": "^0.2.2", "is-docx": "^0.0.3", "stream-to-array" : "^2.3.0", - "ws" : "^4.0.0" + "ws" : "^4.1.0" }, "repository": { "type": "git", diff --git a/services/speech_to_text/v1.js b/services/speech_to_text/v1.js index 4d530abf..a92946d0 100644 --- a/services/speech_to_text/v1.js +++ b/services/speech_to_text/v1.js @@ -412,7 +412,8 @@ module.exports = function (RED) { } else if (d && d.state && 'listening' === d.state) { socketListening = true; // Added for verbose testing - node.send(newMsg); + // SC - Web Sockect Test + //node.send(newMsg); //resolve(); } else { node.send(newMsg); @@ -424,6 +425,9 @@ module.exports = function (RED) { websocket = null; socketListening = false; // console.log('STT Socket disconnected'); + if (!muteMode) { + payloadutils.reportError(node,newMsg,'STT Socket Connection closed'); + } setTimeout(connectIfNeeded, 1000); }); From 4a584618d5e9c0174d81bde50a7c5932fceab762 Mon Sep 17 00:00:00 2001 From: chughts Date: Mon, 5 Mar 2018 18:29:41 +0000 Subject: [PATCH 3/3] Added STT Streaming options --- README.md | 7 +- services/discovery/v1-query-builder.html | 13 ++-- services/discovery/v1-query-builder.js | 13 ++-- services/speech_to_text/v1.html | 90 ++++++++++++++++++------ services/speech_to_text/v1.js | 14 ++-- 5 files changed, 98 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 0014f8a8..3c081da6 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,13 @@ Node-RED Watson Nodes for IBM Cloud CLA assistant + ### New in version 0.6.6 -- Mute option for STT Node warning status when running in Streaming mode +- Added Mute option for STT Node warning status when running in Streaming mode +- Discard option for STT Node Streaming listening events. +- Added Auto-Connect mode for STT Node - Will keep connection to service alive, +else connection is restored on demand. +- Fix to Discovery Query Builder Node to return schema options. ### New in version 0.6.5 - Endpoint can now be specified in Natural Language Classifier Node diff --git a/services/discovery/v1-query-builder.html b/services/discovery/v1-query-builder.html index 089fd84e..cb069ed0 100644 --- a/services/discovery/v1-query-builder.html +++ b/services/discovery/v1-query-builder.html @@ -183,7 +183,7 @@ // can be obtained from the service. disQB.hideAll = function() { $('#credentials-not-found').show(); - cv1wm.hideSelectedFields(fields); + //disQB.hideSelectedFields(fields); $('#something-went-wrong').hide(); $('#node-input-environment').parent().hide(); $('#node-input-collection').parent().hide(); @@ -609,7 +609,7 @@ // This is the on edit prepare function, which will be invoked everytime the dialog is shown. - function oneditprepare() { + function disQBoneditprepare() { disQB.hideAll(); disQB.restoreHidden(); @@ -620,6 +620,7 @@ $('.credentials').toggle(!service); // for some reason the getJSON resets the vars so need to restoreHidden again // so again. + disQB.have_credentials = true; disQB.restoreHidden(); if (!service) { // no bound service, so check local settings to see if they are valid @@ -637,7 +638,7 @@ $('#credentials-check').hide(); }) } - // credentials can be set during the oneditprepare process, so check again. + // credentials can be set during the disQBoneditprepare process, so check again. if (disQB.have_credentials || disQB.using_local_credentials) { $('#credentials-check').hide(); @@ -654,7 +655,7 @@ } // Save the values in the dyanmic lists to the hidden fields. - function oneditsave(){ + function disQoneditsave(){ disQB.environment_selected = $('#node-input-environment').val(); $('#node-input-environmenthidden').val(disQB.environment_selected); @@ -736,8 +737,8 @@ labelStyle: function() { return this.name ? "node_label_italic" : ""; }, - oneditprepare: oneditprepare, - oneditsave: oneditsave + oneditprepare: disQBoneditprepare, + oneditsave: disQoneditsave }); })(); diff --git a/services/discovery/v1-query-builder.js b/services/discovery/v1-query-builder.js index e91c2e5c..38e72619 100644 --- a/services/discovery/v1-query-builder.js +++ b/services/discovery/v1-query-builder.js @@ -43,19 +43,16 @@ module.exports = function(RED) { username: sUsername ? sUsername : req.query.un, password: sPassword ? sPassword : req.query.pwd, url: req.query.endpoint ? req.query.endpoint : sEndpoint, - version_date: '2017-09-01', + version_date: '2017-11-07', headers: { 'User-Agent': pkg.name + '-' + pkg.version } }); - console.log('Getting Discovery Environments'); discovery.getEnvironments({}, function(err, response) { if (err) { - console.log(err); res.json(err); } else { - console.log('Returning Envrionments'); res.json(response.environments ? response.environments : response); } }); @@ -67,7 +64,7 @@ module.exports = function(RED) { username: sUsername ? sUsername : req.query.un, password: sPassword ? sPassword : req.query.pwd, url: req.query.endpoint ? req.query.endpoint : sEndpoint, - version_date: '2017-09-01', + version_date: '2017-11-07', headers: { 'User-Agent': pkg.name + '-' + pkg.version } @@ -92,7 +89,7 @@ module.exports = function(RED) { username: sUsername ? sUsername : req.query.un, password: sPassword ? sPassword : req.query.pwd, url: req.query.endpoint ? req.query.endpoint : sEndpoint, - version_date: '2017-09-01', + version_date: '2017-11-07', headers: { 'User-Agent': pkg.name + '-' + pkg.version } @@ -101,7 +98,9 @@ module.exports = function(RED) { discovery.query({ environment_id: req.query.environment_id, collection_id: req.query.collection_id, - query: 'text:a,text:ibm', + //query: 'text:a,text:ibm', + // Need a Query that will return some data! + query: 'text:"Trump",text:"IBM",text:"Watson"', count: 1 }, function(err, response) { diff --git a/services/speech_to_text/v1.html b/services/speech_to_text/v1.html index cd351cee..f8797b08 100644 --- a/services/speech_to_text/v1.html +++ b/services/speech_to_text/v1.html @@ -94,6 +94,18 @@
+
+ + + +
+ +
+ + + +
+
@@ -155,6 +167,7 @@ start or stop or an audio blob. No token is needed as the node takes care of that step.

>The Mute option allows for the supression of session timeout messages.

+

>The Discard Listening option allows for listening events from STT to be discarded.

For more information about the Speech To Text service, read the documentation.

@@ -193,41 +206,61 @@ return self.indexOf(value) === index; } + stt.showSelectedFields = function(fields) { + for (i = 0; i < fields.length; i++) { + $(fields[i]).parent().show(); + } + } + + stt.hideSelectedFields = function(fields) { + for (i = 0; i < fields.length; i++) { + $(fields[i]).parent().hide(); + } + } + + // Function to be used at the start, as don't want to expose any fields, unless the models are // available. The models can only be fetched if the credentials are available. stt.hideEverything = function () { if (!stt.models) { + var fields = []; $('#credentials-not-found').show(); - $('label#node-label-message').parent().hide(); - $('input#node-input-alternatives').parent().hide(); - $('input#node-input-speakerlabels').parent().hide(); - $('input#node-input-smartformatting').parent().hide(); - $('select#node-input-lang').parent().hide(); - $('select#node-input-band').parent().hide(); - $('select#node-input-langcustom').parent().hide(); + + fields.push('#node-label-message' + + ', #node-input-alternatives' + + ', #node-input-speakerlabels' + + ', #node-input-smartformatting' + + ', #node-input-lang' + + ', #node-input-band' + + ', #node-input-langcustom'); + stt.hideSelectedFields(fields); } } // Check if there is a model then can show the fields. // available. The models can only be fetched if the credentials are available. stt.VisibilityCheck = function () { + var showFields = []; + var hideFields = []; if (stt.models) { - $('label#node-label-message').parent().hide(); - $('input#node-input-alternatives').parent().show(); - $('input#node-input-speakerlabels').parent().show(); - $('input#node-input-smartformatting').parent().show(); - $('select#node-input-lang').parent().show(); - //$('select#node-input-langcustom').parent().show(); - $('select#node-input-band').parent().show(); + showFields.push('#node-input-alternatives' + + ', #node-input-speakerlabels' + + ', #node-input-smartformatting' + + ', #node-input-lang' + + ', #node-input-band'); + + hideFields.push('#node-label-message'); } else { - $('label#node-label-message').parent().hide(); - $('input#node-input-alternatives').parent().hide(); - $('input#node-input-speakerlabels').parent().hide(); - $('input#node-input-smartformatting').parent().hide(); - $('select#node-input-lang').parent().hide(); - $('select#node-input-langcustom').parent().hide(); - $('select#node-input-band').parent().hide(); + hideFields.push('#node-label-message' + + ', #node-input-alternatives' + + ', #node-input-speakerlabels' + + ', #node-input-smartformatting' + + ', #node-input-langcustom' + + ', #node-input-lang' + + ', #node-input-band'); } + stt.hideSelectedFields(hideFields); + stt.showSelectedFields(showFields); } @@ -372,6 +405,20 @@ } }); + $('#node-input-streaming-mode').change(function () { + var fields = []; + fields.push('#node-input-streaming-mute' + + ', #node-input-discard-listening' + + ', #node-input-auto-connect'); + + var checked = $('#node-input-streaming-mode').prop('checked') + if (checked) { + stt.showSelectedFields(fields); + } else { + stt.hideSelectedFields(fields); + } + }); + $('#node-input-flushcache').click(function () { stt.flushCache(); }); @@ -550,6 +597,7 @@ 'payload-response' :{value: false}, 'streaming-mode' :{value: false}, 'streaming-mute' :{value: true}, + 'discard-listening' :{value: false}, 'default-endpoint' :{value: true}, 'service-endpoint' :{value: 'https://stream.watsonplatform.net/speech-to-text/api'} }, diff --git a/services/speech_to_text/v1.js b/services/speech_to_text/v1.js index a92946d0..27679353 100644 --- a/services/speech_to_text/v1.js +++ b/services/speech_to_text/v1.js @@ -28,7 +28,7 @@ module.exports = function (RED) { payloadutils = require('../../utilities/payload-utils'), sttV1 = require('watson-developer-cloud/speech-to-text/v1'), authV1 = require('watson-developer-cloud/authorization/v1'), - muteMode = true; + muteMode = true, discardMode = false, autoConnect = true, username = '', password = '', sUsername = '', sPassword = '', endpoint = '', sEndpoint = 'https://stream.watsonplatform.net/speech-to-text/api', @@ -135,6 +135,8 @@ module.exports = function (RED) { var message = ''; muteMode = config['streaming-mute']; + discardMode = config['discard-listening']; + autoConnect = config['auto-connect']; if (!config.lang) { message = 'Missing audio language configuration, unable to process speech.'; @@ -412,8 +414,9 @@ module.exports = function (RED) { } else if (d && d.state && 'listening' === d.state) { socketListening = true; // Added for verbose testing - // SC - Web Sockect Test - //node.send(newMsg); + if (!discardMode) { + node.send(newMsg); + } //resolve(); } else { node.send(newMsg); @@ -426,9 +429,12 @@ module.exports = function (RED) { socketListening = false; // console.log('STT Socket disconnected'); if (!muteMode) { + var newMsg = {payload : 'STT Connection Close Event'}; payloadutils.reportError(node,newMsg,'STT Socket Connection closed'); } - setTimeout(connectIfNeeded, 1000); + if (autoConnect) { + setTimeout(connectIfNeeded, 1000); + } }); ws.on('error', (err) => {