Rename voice and attempt to fix save & play

This commit is contained in:
Ruben van de Ven 2019-02-14 08:39:31 +01:00
parent 7eb48bd016
commit 31490fe514
7 changed files with 45 additions and 17 deletions

View file

@ -13,9 +13,9 @@ import asyncio
from hugvey.communication import getTopic, zmqSend, zmqReceive from hugvey.communication import getTopic, zmqSend, zmqReceive
from hugvey.panopticon import Panopticon from hugvey.panopticon import Panopticon
from hugvey.story import Story from hugvey.story import Story
from hugvey.voice.google import GoogleVoiceClient from hugvey.speech.google import GoogleVoiceClient
from hugvey.voice.player import Player from hugvey.speech.player import Player
from hugvey.voice.streamer import AudioStreamer from hugvey.speech.streamer import AudioStreamer
import json import json
import logging import logging
import queue import queue
@ -45,7 +45,7 @@ logger = logging.getLogger("command")
class CentralCommand(object): class CentralCommand(object):
"""docstring for CentralCommand.""" """docstring for CentralCommand."""
def __init__(self, debug_mode=False): def __init__(self, args = {}, debug_mode=False):
self.debug = debug_mode self.debug = debug_mode
self.eventQueue = asyncio.Queue() self.eventQueue = asyncio.Queue()
self.commandQueue = asyncio.Queue() self.commandQueue = asyncio.Queue()
@ -55,6 +55,7 @@ class CentralCommand(object):
self.hugveyLock = asyncio.Lock() self.hugveyLock = asyncio.Lock()
self.start_time = time.time() self.start_time = time.time()
self.languageFiles = {} self.languageFiles = {}
self.args = args # cli args
def loadConfig(self, filename): def loadConfig(self, filename):
if hasattr(self, 'config'): if hasattr(self, 'config'):
@ -63,6 +64,10 @@ class CentralCommand(object):
with open(filename, 'r') as fp: with open(filename, 'r') as fp:
logger.debug('Load config from {}'.format(filename)) logger.debug('Load config from {}'.format(filename))
self.config = yaml.safe_load(fp) self.config = yaml.safe_load(fp)
for arg in vars(self.args):
if arg in self.config:
logger.debug("Override argument {}".format(arg))
self.config[arg] = getattr(self.args,arg)
self.hugvey_ids = [i + 1 for i in range(self.config['hugveys'])] self.hugvey_ids = [i + 1 for i in range(self.config['hugveys'])]
@ -127,12 +132,6 @@ class CentralCommand(object):
def _queueCommand(self, hv_id, msg): def _queueCommand(self, hv_id, msg):
self.commandQueue.put_nowait((hv_id, msg)) self.commandQueue.put_nowait((hv_id, msg))
# if msg['action'] == 'play':
# self.commandQueue.put_nowait((hv_id, {
# 'action': 'play',
# 'msg': "This is an interrption",
# 'id': 'test',
# }))
def commandAllHugveys(self, msg): def commandAllHugveys(self, msg):
for hv_id in self.hugvey_ids: for hv_id in self.hugvey_ids:
@ -354,19 +353,27 @@ class HugveyState(object):
if event['event'] == 'change_language': if event['event'] == 'change_language':
self.setLanguage(event['lang_code']) self.setLanguage(event['lang_code'])
if event['event'] == 'play_msg': if event['event'] == 'play_msg':
self.logger.info("DO PLAY :-)") self.logger.info(f"Play given message {event['msg_id']}")
if not self.story: if not self.story:
self.logger.critical("No story to play message in") self.logger.critical("No story to play message in")
else: else:
#restart first so that story loads the new json #restart first so that story loads the new json
self.restart() # self.restart()
if self.story is None:
return
# self.story.stop()
self.pause()
# wait a tat for the restart loops to complete # wait a tat for the restart loops to complete
await asyncio.sleep(.1) await asyncio.sleep(.1)
self.logger.debug('restarted')
msg = self.story.get(event['msg_id']) msg = self.story.get(event['msg_id'])
if not msg: if not msg:
self.logger.critical("Invalid ID to play: {}".format(event['msg_id'])) self.logger.critical("Invalid ID to play: {}".format(event['msg_id']))
else: else:
self.story.setCurrentMessage(msg) self.story.setCurrentMessage(msg)
self.resume()
self.eventQueue = None self.eventQueue = None
@ -438,7 +445,7 @@ class HugveyState(object):
self.ip, self.ip,
int(self.command.config['voice']['port'])) int(self.command.config['voice']['port']))
if self.command.debug: if self.command.config['voyeur']:
self.logger.warn("Debug on: Connecting Audio player") self.logger.warn("Debug on: Connecting Audio player")
self.player = Player( self.player = Player(
self.command.config['voice']['src_rate'], self.command.config['voice']['out_rate']) self.command.config['voice']['src_rate'], self.command.config['voice']['out_rate'])

View file

@ -18,7 +18,7 @@ import queue
import uuid import uuid
logger = logging.getLogger("voice") logger = logging.getLogger("speech")
class RequireRestart(Exception): class RequireRestart(Exception):
pass pass

View file

@ -37,6 +37,7 @@ class Message(object):
self.interruptCount = 0 self.interruptCount = 0
self.afterrunTime = 0. # the time after this message to allow for interrupts self.afterrunTime = 0. # the time after this message to allow for interrupts
self.finishTime = None # message can be finished without finished utterance (with instant replycontains) self.finishTime = None # message can be finished without finished utterance (with instant replycontains)
self.parseForVariables()
@classmethod @classmethod
def initFromJson(message, data, story): def initFromJson(message, data, story):
@ -47,6 +48,12 @@ class Message(object):
msg.audioFile = data['audio']['file'] msg.audioFile = data['audio']['file']
return msg return msg
def parseForVariables(self):
"""
Find variables in text
"""
self.variables = re.findall('\$(\w+)', self.text)
def setReply(self, reply): def setReply(self, reply):
self.reply = reply self.reply = reply
@ -188,7 +195,7 @@ class Condition(object):
logger.debug('Got match on {}'.format(self.vars['regex'])) logger.debug('Got match on {}'.format(self.vars['regex']))
results = result.groupdict() results = result.groupdict()
for captureGroup in results: for captureGroup in results:
story.variables[captureGroup] = results[captureGroup] story.variableValues[captureGroup] = results[captureGroup]
# TODO: implement 'instant match' -> don't wait for isFinished() # TODO: implement 'instant match' -> don't wait for isFinished()
@ -353,6 +360,7 @@ class Story(object):
self.currentReply = None self.currentReply = None
self.timer = Stopwatch() self.timer = Stopwatch()
self.isRunning = False self.isRunning = False
self.variables = {}
def pause(self): def pause(self):
logger.debug('pause hugvey') logger.debug('pause hugvey')
@ -371,6 +379,12 @@ class Story(object):
} }
# print(self.log) # print(self.log)
return summary return summary
def registerVariable(self, variableName, message):
if variableName not in self.variables:
self.variables[variableName] = [message]
else:
self.variables[variableName].append(message)
def setStoryData(self, story_data): def setStoryData(self, story_data):
""" """
@ -385,6 +399,7 @@ class Story(object):
self.diversions = [] self.diversions = []
self.directionsPerMsg = {} self.directionsPerMsg = {}
self.startMessage = None # The entrypoint to the graph self.startMessage = None # The entrypoint to the graph
self.variables = {}
self.reset() self.reset()
for el in self.data: for el in self.data:
@ -412,7 +427,7 @@ class Story(object):
self.lastMsgTime = None self.lastMsgTime = None
self.lastSpeechStartTime = None self.lastSpeechStartTime = None
self.lastSpeechEndTime = None self.lastSpeechEndTime = None
self.variables = {} # captured variables from replies self.variableValues = {} # captured variables from replies
self.finish_time = False self.finish_time = False
self.events = [] # queue of received events self.events = [] # queue of received events

View file

@ -21,6 +21,11 @@ if __name__ == '__main__':
'-v', '-v',
action='count', default=0 action='count', default=0
) )
argParser.add_argument(
'--voyeur',
action='store_true',
help="Listen in on what is being said'."
)
args = argParser.parse_args() args = argParser.parse_args()
# print(coloredlogs.DEFAULT_LOG_FORMAT) # print(coloredlogs.DEFAULT_LOG_FORMAT)
@ -33,6 +38,6 @@ if __name__ == '__main__':
fmt="%(asctime)s %(hostname)s %(name)s[%(process)d,%(threadName)s] %(levelname)s %(message)s" fmt="%(asctime)s %(hostname)s %(name)s[%(process)d,%(threadName)s] %(levelname)s %(message)s"
) )
command = CentralCommand(debug_mode=args.verbose > 0) command = CentralCommand(args=args, debug_mode=args.verbose > 0)
command.loadConfig(args.config) command.loadConfig(args.config)
command.start() command.start()

View file

@ -3,3 +3,4 @@ pyaudio
coloredlogs coloredlogs
pyyaml pyyaml
google-cloud-speech google-cloud-speech
requests-threads