diff --git a/README.md b/README.md index 9b5ba9a5..3c081da6 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,14 @@ Node-RED Watson Nodes for IBM Cloud CLA assistant + +### New in version 0.6.6 +- 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/package.json b/package.json index 5b6f56a2..619470fe 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", @@ -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/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 9ff20709..f8797b08 100644 --- a/services/speech_to_text/v1.html +++ b/services/speech_to_text/v1.html @@ -88,6 +88,24 @@ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+
@@ -148,6 +166,8 @@ 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.

+

>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.

@@ -186,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); } @@ -365,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(); }); @@ -542,6 +596,8 @@ password: {value: ''}, '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 94fbc3d4..27679353 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, discardMode = false, autoConnect = true, username = '', password = '', sUsername = '', sPassword = '', endpoint = '', sEndpoint = 'https://stream.watsonplatform.net/speech-to-text/api', @@ -133,6 +134,10 @@ module.exports = function (RED) { function configCheck() { 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.'; } else if (!config.band) { @@ -397,7 +402,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(() => { @@ -406,7 +414,9 @@ module.exports = function (RED) { } else if (d && d.state && 'listening' === d.state) { socketListening = true; // Added for verbose testing - node.send(newMsg); + if (!discardMode) { + node.send(newMsg); + } //resolve(); } else { node.send(newMsg); @@ -418,12 +428,20 @@ module.exports = function (RED) { websocket = null; socketListening = false; // console.log('STT Socket disconnected'); - setTimeout(connectIfNeeded, 1000); + if (!muteMode) { + var newMsg = {payload : 'STT Connection Close Event'}; + payloadutils.reportError(node,newMsg,'STT Socket Connection closed'); + } + if (autoConnect) { + setTimeout(connectIfNeeded, 1000); + } }); 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 +490,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); + } } }); }