Skip to content

Commit

Permalink
Merge pull request #265 from stanford-oval/wip/audio-control-protocol
Browse files Browse the repository at this point in the history
Changes to support the audio control protocol
  • Loading branch information
gcampax committed Sep 17, 2021
2 parents fb3bf8f + 02ce626 commit 854cc25
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 61 deletions.
34 changes: 25 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"resolutions": {},
"dependencies": {
"@js-temporal/polyfill": "^0.2.0",
"body-parser": "^1.17.2",
"color-scheme": "^1.0.0",
"connect-flash": "^0.1.1",
Expand Down
78 changes: 27 additions & 51 deletions src/routes/conversation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,12 @@

import express from 'express';
import * as Genie from 'genie-toolkit';
import * as Tp from 'thingpedia';
import WebSocket from 'ws';

class WebsocketAssistantDelegate implements Genie.DialogueAgent.ConversationDelegate {
private _ws : WebSocket;

constructor(ws : WebSocket) {
this._ws = ws;
}

async setHypothesis(hypothesis : string) {
this._ws.send(JSON.stringify({ type: 'hypothesis', hypothesis }));
}

async setExpected(what : string|null) {
this._ws.send(JSON.stringify({ type: 'askSpecial', ask: what }));
}

async addDevice(uniqueId : string, state : Tp.BaseDevice.DeviceState) {
this._ws.send(JSON.stringify({ type: 'new-device', uniqueId, state }));
}

async addMessage(msg : Genie.DialogueAgent.Protocol.Message) {
this._ws.send(JSON.stringify(msg));
}
}

export default function conversationHandler(ws : WebSocket, req : express.Request, next : express.NextFunction) {
Promise.resolve().then(async () => {
const engine = req.app.genie;

const delegate = new WebsocketAssistantDelegate(ws);

let opened = false;
const conversationId = String(req.query.id || 'main');
ws.on('error', (err) => {
Expand All @@ -61,39 +34,42 @@ export default function conversationHandler(ws : WebSocket, req : express.Reques
});
ws.on('close', () => {
if (opened)
conversation.removeOutput(delegate);
wrapper.stop();
opened = false;
});
const conversation = await engine.assistant.getOrOpenConversation(conversationId, {
showWelcome: true,
debug: true,
syncDevices: !!req.query.sync_devices
});
await conversation.addOutput(delegate, !req.query.skip_history);
await conversation.startRecording();
opened = true;
ws.send(JSON.stringify({ type: 'id', id : conversation.id }));

let initQueue : any[] = [];
ws.on('message', (data) => {
Promise.resolve().then(() => {
Promise.resolve().then(async () => {
const parsed = JSON.parse(String(data));
switch (parsed.type) {
case 'command':
return conversation.handleCommand(parsed.text);
case 'parsed':
return conversation.handleParsedCommand(parsed.json, parsed.title);
case 'tt':
return conversation.handleThingTalk(parsed.code);
default:
throw new Error('Invalid command type ' + parsed.type);
}
if (opened)
await wrapper.handle(parsed);
else
initQueue.push(parsed);
}).catch((e) => {
console.error(e.stack);
ws.send(JSON.stringify({ type: 'error', error:e.message }));
// either the message didn't parse as json, or we had an error sending the error
// (ie the websocket is closed)
// eat the error and close the socket
ws.terminate();
});
});
const conversation = await engine.assistant.getOrOpenConversation(conversationId, {
showWelcome: true,
debug: true,
log: true
});
const wrapper = new Genie.DialogueAgent.Protocol.WebSocketConnection(conversation, async (msg) => ws.send(JSON.stringify(msg)), {
syncDevices: !!req.query.sync_devices,
replayHistory: !req.query.skip_history
});
await wrapper.start();
for (const msg of initQueue)
await wrapper.handle(msg);
opened = true;
initQueue = [];

}).catch((e) => {
console.error('Error in API websocket: ' + e.message);
ws.close();
ws.terminate();
});
}
3 changes: 2 additions & 1 deletion src/service/platform/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import Gettext from 'node-gettext';
import * as path from 'path';
import * as util from 'util';
import * as Genie from 'genie-toolkit';
import { Temporal } from '@js-temporal/polyfill';

import * as _graphicsApi from './graphics';

Expand Down Expand Up @@ -328,7 +329,7 @@ export class ServerPlatform extends Tp.BasePlatform {
this._locale = this._locale.split(/[-_.@]/).slice(0, 2).join('-');
this._gettext.setLocale(this._locale);

this._timezone = process.env.TZ!;
this._timezone = Temporal.Now.timeZone().id;
this._prefs = new Tp.Helpers.FilePreferences(this._filesDir + '/prefs.db');
this._cacheDir = getCacheDir();
safeMkdirSync(this._cacheDir);
Expand Down

0 comments on commit 854cc25

Please sign in to comment.