First messages to light, and changes to Timeout (only when no other timeout) and ReplYContains (allow skip for color) diversions

This commit is contained in:
Ruben van de Ven 2019-04-25 11:12:27 +02:00
parent 6ea2a68bcd
commit cd66a7c6af
3 changed files with 69 additions and 17 deletions

View File

@ -23,6 +23,7 @@ import threading
from hugvey.voice import VoiceStorage
import multiprocessing
from hugvey.speech.recorder import Recorder
from pythonosc import udp_client
mainLogger = logging.getLogger("hugvey")
@ -90,6 +91,13 @@ class CentralCommand(object):
self.panopticon = Panopticon(self, self.config, self.voiceStorage)
self.lightConn = udp_client.SimpleUDPClient(
self.config['light']['ip'],
self.config['light']['port'])
# logger.info("Send light /general 1")
# self.lightConn.send_message("/general", [1])
def loadLanguages(self):
logger.debug('load language files')
@ -348,6 +356,11 @@ class HugveyState(object):
self.notShuttingDown = True # TODO: allow shutdown of object
self.startMsgId = None
self.eventLogger = eventLogger.getChild(f"{self.id}")
self.lightConn = udp_client.SimpleUDPClient(
command.config['light']['ip'],
command.config['light']['port'])
def getStatus(self):
if self.story.isFinished():
@ -410,7 +423,6 @@ class HugveyState(object):
# Allow for both the Hugvey Command, or the Story handle the event.
self.loop.call_soon_threadsafe(self._queueEvent, msg)
def _queueEvent(self, msg):
self.logger.debug(f"Queue event in hugvey loop: {msg}")
self.eventQueue.put_nowait(msg)
@ -433,7 +445,7 @@ class HugveyState(object):
if event['event'] == 'restart':
self.restart()
if event['event'] == 'finish':
self.finish()
self.story.finish()
if event['event'] == 'resume':
self.resume()
@ -508,12 +520,16 @@ class HugveyState(object):
def finish(self):
"""Finish playback"""
self.logger.info('Restart')
self.logger.info('Finish')
self.pause()
if self.story:
self.story.finish()
self.isRunning.clear()
self.status = self.STATE_FINISHED
self.setLightStatus(True)
def setLightStatus(self, on):
status = 1 if on else 0
self.logger.info(f"Send /hugvey {status}")
self.lightConn.send_message("/hugvey", [self.id, status])
def gone(self):
'''Status to 'gone' as in, shutdown/crashed/whatever
@ -541,6 +557,7 @@ class HugveyState(object):
self.streamer.triggerStart()
self.story.setStoryData(self.command.languages[self.language_code])
self.setLightStatus(False)
await self.story.run(startMsgId)
# self.story = None

View File

@ -13,6 +13,7 @@ import faulthandler
from zmq.asyncio import Context
import zmq
import wave
from pythonosc import udp_client
mainLogger = logging.getLogger("hugvey")
logger = mainLogger.getChild("narrative")
@ -53,6 +54,7 @@ class Message(object):
self.variableValues = {}
self.parseForVariables()
self.uuid = None # Have a unique id each time the message is played back.
self.color = None
def setStory(self, story):
self.story = story
@ -63,6 +65,7 @@ class Message(object):
msg = message(data['@id'], data['text'])
msg.isStart = data['beginning'] if 'beginning' in data else False
msg.afterrunTime = data['afterrun'] if 'afterrun' in data else 0.
msg.color = data['color'] if 'color' in data else None
if 'audio' in data and data['audio'] is not None:
msg.audioFile = data['audio']['file']
msg.setStory(story)
@ -244,11 +247,14 @@ class Condition(object):
def __init__(self, id):
self.id = id
self.method = None
self.type = None
self.vars = {}
@classmethod
def initFromJson(conditionClass, data, story):
condition = conditionClass(data['@id'])
condition.type = data['type']
# TODO: should Condition be subclassed?
if data['type'] == "replyContains":
condition.method = condition._hasMetReplyContains
@ -538,7 +544,13 @@ class Diversion(object):
if r is None:
return
logger.info(f"Diverge: reply contains {self.id}")
if 'notForColor' in self.params and self.params['notForColor']:
if story.currentMessage.color.lower() == self.params['notForColor'].lower():
story.logger.debug(f"Skip diversion {self.id} because of section color")
return
story.logger.info(f"Diverge: reply contains {self.id}")
story.stats['diversions']['reply_contains'] += 1
msg = story.get(self.params['msgId'])
@ -589,6 +601,13 @@ class Diversion(object):
if not story.lastMsgFinishTime:
# not during play back
return
# not applicable when timeout is set
directions = story.getCurrentDirections()
for direction in directions:
for condition in direction.conditions:
if condition.type == 'timeout':
return
now = story.timer.getElapsed()
if now - story.lastMsgFinishTime < float(self.params['minTimeAfterMessage']):
@ -1143,9 +1162,10 @@ class Story(object):
self.logger.info(f"Finished story for {self.hugvey.id}")
self.hugvey.eventLogger.info("story: finished")
self.stop()
self.hugvey.pause()
self.finish_time = time.time()
self.timer.pause()
#stop google etc:
self.hugvey.isRunning.clear()
self.hugvey.finish()

View File

@ -444,6 +444,7 @@ class Graph {
div['params']['regex'] = "";
div['params']['returnAfterStrand'] = true;
div['params']['msgId'] = "";
div['params']['notForColor'] = "";
}
else if(type == 'timeout') {
div['params']['interval'] = 20;
@ -592,15 +593,29 @@ class Graph {
}
}, 'Delete diversion'),
crel('label', 'Regex',
crel('input', {
'type': 'text',
'value': div['params']['regex'],
'placeholder': 'regex',
'on': {
'change': (e) => div['params']['regex'] = e.target.value
}
})
),
crel('input', {
'type': 'text',
'value': div['params']['regex'],
'placeholder': 'regex',
'on': {
'change': (e) => div['params']['regex'] = e.target.value
}
})
),
crel('label', 'Ignore for color',
crel('input', {
'type': 'text', // use text instead of color, as color doesn't allow for empty values
'value': typeof div['params']['notForColor'] !== 'undefined' ? div['params']['notForColor'] : "",
'on': {
'change': function(e) {
if(e.target.value.length > 0 && e.target.value.substr(0,1) !== '#') {
alert("Don't forget to have a valid hex including the #-character, eg: #00ff00");
}
div['params']['notForColor'] = e.target.value;
}
}
})
),
crel('label', 'Return to point of departure afterwards',
crel('input', returnAttrs)
),