diff options
author | Naveen Bobbili <nbobbili@amazon.com> | 2018-11-12 16:12:38 -0800 |
---|---|---|
committer | Naveen Bobbili <nbobbili@amazon.com> | 2018-11-13 15:05:41 -0800 |
commit | b6abca2edcb36c0c0848d1cd8dc291f23293aa80 (patch) | |
tree | a838812e0b66f0695cb6cf0f8bebfa38315ce8b8 /htdocs/binding.js | |
parent | be70712f89eacd20dca413bcce46e4aa26b5709e (diff) |
SPEC-1924: AGL Speech Framework's Voice Service High Level 1.0 Release.
Details:
1) Control plugin implementation for VSHL 1.0
2) Exposed APIs that are documented in the confluence page
https://confluence.automotivelinux.org/display/SPE/Speech+EG+Architecture
3) Implemented 39 unit tests based on GTest framework to test all the low
level components of VSHL binding.
4) Implemented a HTML5 based VSHL API tester application to test VSHL APIs.
API specification:
https://confluence.automotivelinux.org/display/SPE/Speech+EG+Architecture#SpeechEGArchitecture-HighLevelVoiceService
Test performed:
1) Tested AGL service running Alexa Auto SDK https://github.com/alexa/aac-sdk on Ubuntu 16.04 and Renesas R-Car M3 board.
License:
Apache 2.0
Developers/Owners:
Naveen Bobbili (nbobbili@amazon.com)
Prakash Buddhiraja (buddhip@amazon.com)
Shotaro Uchida (shotaru@amazon.co.jp)
Change-Id: I3370f4ad65aff030f24f4ad571fb02d525bbfbca
Signed-off-by: Naveen Bobbili <nbobbili@amazon.com>
Diffstat (limited to 'htdocs/binding.js')
-rw-r--r-- | htdocs/binding.js | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/htdocs/binding.js b/htdocs/binding.js new file mode 100644 index 0000000..c24d62e --- /dev/null +++ b/htdocs/binding.js @@ -0,0 +1,226 @@ +var afb = new AFB("api", "mysecret"); +var ws; +var evtIdx = 0; +var count = 0; + + +//********************************************** +// Logger +//********************************************** +var log = { + command: function (api, verb, query) { + console.log("subscribe api=" + api + " verb=" + verb + " query=", query); + var question = urlWS + "/" + api + "/" + verb + "?query=" + JSON.stringify(query); + log._write("question", count + ": " + log.syntaxHighlight(question)); + }, + + event: function (obj) { + console.log("gotevent:" + JSON.stringify(obj)); + log._write("outevt", (evtIdx++) + ": " + JSON.stringify(obj)); + }, + + reply: function (obj) { + console.log("replyok:" + JSON.stringify(obj)); + log._write("output", count + ": OK: " + log.syntaxHighlight(obj)); + }, + + error: function (obj) { + console.log("replyerr:" + JSON.stringify(obj)); + log._write("output", count + ": ERROR: " + log.syntaxHighlight(obj)); + }, + + _write: function (element, msg) { + var el = document.getElementById(element); + el.innerHTML += msg + '\n'; + + // auto scroll down + setTimeout(function () { + el.scrollTop = el.scrollHeight; + }, 100); + }, + + syntaxHighlight: function (json) { + if (typeof json !== 'string') { + json = JSON.stringify(json, undefined, 2); + } + json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); + return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { + var cls = 'number'; + if (/^"/.test(match)) { + if (/:$/.test(match)) { + cls = 'key'; + } else { + cls = 'string'; + } + } else if (/true|false/.test(match)) { + cls = 'boolean'; + } else if (/null/.test(match)) { + cls = 'null'; + } + return '<span class="' + cls + '">' + match + '</span>'; + }); + }, +}; + +//********************************************** +// Generic function to call binder +//*********************************************** +function callbinder(api, verb, query) { + log.command(api, verb, query); + + // ws.call return a Promise + return ws.call(api + '/' + verb, query) + .then(function (res) { + log.reply(res); + count++; + return res; + }) + .catch(function (err) { + log.reply(err); + count++; + throw err; + }); +}; + +//********************************************** +// Init - establish Websocket connection +//********************************************** +function init(elemID, api, verb, query) { + + function onopen() { + document.getElementById("main").style.visibility = "visible"; + document.getElementById("connected").innerHTML = "Binder WS Active"; + document.getElementById("connected").style.background = "lightgreen"; + ws.onevent("*", log.event); + } + + function onabort() { + document.getElementById("main").style.visibility = "hidden"; + document.getElementById("connected").innerHTML = "Connected Closed"; + document.getElementById("connected").style.background = "red"; + } + + ws = new afb.ws(onopen, onabort); +} + +function clearPre(preId) { + const pre = document.getElementById(preId); + while (pre && pre.firstChild) { + pre.removeChild(pre.firstChild); + } +} + +function fetchAndRenderVoiceAgents() { + const agentsDiv = document.getElementById('agentsDiv'); + while (agentsDiv.firstChild) { + agentsDiv.removeChild(agentsDiv.firstChild); + } + + const api = 'vshl'; + const verb = 'enumerateVoiceAgents'; + const query = {}; + + log.command(api, verb, query); + + return ws.call(api + '/' + verb, query) + .then(function (res) { + log.reply(res); + for (let index = 0; index < res.response.agents.length; ++index) { + let voiceAgent = res.response.agents[index]; + addVoiceAgent(agentsDiv, voiceAgent, res.response.default == voiceAgent.id); + } + }) + .catch(function (err) { + log.reply(err); + console.log(JSON.stringify(err)); + }); +} + +function addVoiceAgent(containerDiv, voiceAgent, isDefault) { + const agentDiv = document.createElement("div"); + + const agentName = document.createElement("h2"); + agentName.innerHTML = voiceAgent.name; + agentDiv.appendChild(agentName); + + const agentDescription = document.createElement("p"); + agentDescription.innerHTML = voiceAgent.description; + agentDiv.appendChild(agentDescription); + + if (!isDefault) { + const setDefaultBtn = document.createElement("button"); + setDefaultBtn.addEventListener('click', (evt) => { + const query = {"id": voiceAgent.id}; + callbinder('vshl', 'setDefaultVoiceAgent', query); + fetchAndRenderVoiceAgents(); + }); + setDefaultBtn.innerHTML = 'SetDefault'; + agentDiv.appendChild(setDefaultBtn); + } + + const subscribeBtn = document.createElement("button"); + subscribeBtn.addEventListener('click', (evt) => { + showAgentEventChooserDialog(voiceAgent.id); + }); + subscribeBtn.innerHTML = 'Subscribe'; + agentDiv.appendChild(subscribeBtn); + + containerDiv.appendChild(agentDiv); +} + +function showAgentEventChooserDialog(voiceAgentId) { + const modal = document.getElementById('agent-event-chooser'); + const subscribeBtn = document.getElementById('agent-subscribe-btn'); + + subscribeBtn.addEventListener('click', (evt) => { + const authState = document.getElementById('authstate').checked; + const dialogState = document.getElementById('dialogstate').checked; + const connectionState = document.getElementById('connectionstate').checked; + + const query = { + "va_id": voiceAgentId, + "events":[] + }; + if (authState) + query.events.push('voice_authstate_event'); + if (dialogState) + query.events.push('voice_dialogstate_event'); + if (connectionState) + query.events.push('voice_connectionstate_event'); + + callbinder('vshl', 'subscribe', query); + modal.close(); + }); + + // makes modal appear (adds `open` attribute) + modal.showModal(); +} + +function showTemplateUIEventChooserDialog() { + const modal = document.getElementById('templateui-event-chooser'); + const subscribeBtn = document.getElementById('templateui-subscribe-btn'); + + subscribeBtn.addEventListener('click', (evt) => { + const renderTemplate = document.getElementById('render_template').checked; + const clearTemplate = document.getElementById('clear_template').checked; + const renderPlayerInfo = document.getElementById('render_player_info').checked; + const clearPlayerInfo = document.getElementById('clear_player_info').checked; + + const query = {"actions":[]}; + + if (renderTemplate) + query.actions.push('render_template'); + if (clearTemplate) + query.actions.push('clear_template'); + if (renderPlayerInfo) + query.actions.push('render_player_info'); + if (clearPlayerInfo) + query.actions.push('clear_player_info'); + + callbinder('vshl', 'guiMetadata/subscribe', query); + modal.close(); + }); + + // makes modal appear (adds `open` attribute) + modal.showModal(); +}
\ No newline at end of file |