Assistant event refactor: always explicitly pass the assistant object.

Also added match_condition override for ResponseEvent to capture the
assistant response text, when available, and prevent the default
response - it should solve #86.
This commit is contained in:
Fabio Manganiello 2019-11-26 00:16:32 +01:00
parent 0ddfce3dce
commit 9b04570e49
3 changed files with 34 additions and 30 deletions

View File

@ -5,14 +5,12 @@
import json import json
import os import os
import subprocess
import time import time
import google.oauth2.credentials import google.oauth2.credentials
from google.assistant.library import Assistant from google.assistant.library import Assistant
from google.assistant.library.event import EventType, AlertType from google.assistant.library.event import EventType, AlertType
from google.assistant.library.file_helpers import existing_file
from platypush.backend import Backend from platypush.backend import Backend
from platypush.message.event.assistant import \ from platypush.message.event.assistant import \
@ -100,17 +98,17 @@ class AssistantGoogleBackend(Backend):
self._has_error = False self._has_error = False
if event.type == EventType.ON_CONVERSATION_TURN_STARTED: if event.type == EventType.ON_CONVERSATION_TURN_STARTED:
self.bus.post(ConversationStartEvent()) self.bus.post(ConversationStartEvent(assistant=self))
elif event.type == EventType.ON_CONVERSATION_TURN_FINISHED: elif event.type == EventType.ON_CONVERSATION_TURN_FINISHED:
if not event.args.get('with_follow_on_turn'): if not event.args.get('with_follow_on_turn'):
self.bus.post(ConversationEndEvent()) self.bus.post(ConversationEndEvent(assistant=self))
elif event.type == EventType.ON_CONVERSATION_TURN_TIMEOUT: elif event.type == EventType.ON_CONVERSATION_TURN_TIMEOUT:
self.bus.post(ConversationTimeoutEvent()) self.bus.post(ConversationTimeoutEvent(assistant=self))
elif event.type == EventType.ON_NO_RESPONSE: elif event.type == EventType.ON_NO_RESPONSE:
self.bus.post(NoResponseEvent()) self.bus.post(NoResponseEvent(assistant=self))
elif hasattr(EventType, 'ON_RENDER_RESPONSE') and \ elif hasattr(EventType, 'ON_RENDER_RESPONSE') and \
event.type == EventType.ON_RENDER_RESPONSE: event.type == EventType.ON_RENDER_RESPONSE:
self.bus.post(ResponseEvent(response_text=event.args.get('text'))) self.bus.post(ResponseEvent(assistant=self, response_text=event.args.get('text')))
elif hasattr(EventType, 'ON_RESPONDING_STARTED') and \ elif hasattr(EventType, 'ON_RESPONDING_STARTED') and \
event.type == EventType.ON_RESPONDING_STARTED and \ event.type == EventType.ON_RESPONDING_STARTED and \
event.args.get('is_error_response', False) is True: event.args.get('is_error_response', False) is True:
@ -118,21 +116,21 @@ class AssistantGoogleBackend(Backend):
elif event.type == EventType.ON_RECOGNIZING_SPEECH_FINISHED: elif event.type == EventType.ON_RECOGNIZING_SPEECH_FINISHED:
phrase = event.args['text'].lower().strip() phrase = event.args['text'].lower().strip()
self.logger.info('Speech recognized: {}'.format(phrase)) self.logger.info('Speech recognized: {}'.format(phrase))
self.bus.post(SpeechRecognizedEvent(phrase=phrase)) self.bus.post(SpeechRecognizedEvent(assistant=self, phrase=phrase))
elif event.type == EventType.ON_ALERT_STARTED: elif event.type == EventType.ON_ALERT_STARTED:
if event.args.get('alert_type') == AlertType.ALARM: if event.args.get('alert_type') == AlertType.ALARM:
self.bus.post(AlarmStartedEvent()) self.bus.post(AlarmStartedEvent(assistant=self))
elif event.args.get('alert_type') == AlertType.TIMER: elif event.args.get('alert_type') == AlertType.TIMER:
self.bus.post(TimerStartedEvent()) self.bus.post(TimerStartedEvent(assistant=self))
else: else:
self.bus.post(AlertStartedEvent()) self.bus.post(AlertStartedEvent(assistant=self))
elif event.type == EventType.ON_ALERT_FINISHED: elif event.type == EventType.ON_ALERT_FINISHED:
if event.args.get('alert_type') == AlertType.ALARM: if event.args.get('alert_type') == AlertType.ALARM:
self.bus.post(AlarmEndEvent()) self.bus.post(AlarmEndEvent(assistant=self))
elif event.args.get('alert_type') == AlertType.TIMER: elif event.args.get('alert_type') == AlertType.TIMER:
self.bus.post(TimerEndEvent()) self.bus.post(TimerEndEvent(assistant=self))
else: else:
self.bus.post(AlertEndEvent()) self.bus.post(AlertEndEvent(assistant=self))
elif event.type == EventType.ON_ASSISTANT_ERROR: elif event.type == EventType.ON_ASSISTANT_ERROR:
self._has_error = True self._has_error = True
if event.args.get('is_fatal'): if event.args.get('is_fatal'):
@ -140,19 +138,16 @@ class AssistantGoogleBackend(Backend):
else: else:
self.logger.warning('Assistant error') self.logger.warning('Assistant error')
def start_conversation(self): def start_conversation(self):
""" Starts an assistant conversation """ """ Starts an assistant conversation """
if self.assistant: if self.assistant:
self.assistant.start_conversation() self.assistant.start_conversation()
def stop_conversation(self): def stop_conversation(self):
""" Stops an assistant conversation """ """ Stops an assistant conversation """
if self.assistant: if self.assistant:
self.assistant.stop_conversation() self.assistant.stop_conversation()
def run(self): def run(self):
super().run() super().run()

View File

@ -70,6 +70,18 @@ class ResponseEvent(ConversationEndEvent):
super().__init__(*args, response_text=response_text, **kwargs) super().__init__(*args, response_text=response_text, **kwargs)
def matches_condition(self, condition):
"""
Overrides matches condition, and stops the conversation to prevent the
default assistant response if the event matched some event hook condition
"""
result = super().matches_condition(condition)
if result.is_match and self._assistant:
self._assistant.stop_conversation()
return result
class NoResponseEvent(ConversationEndEvent): class NoResponseEvent(ConversationEndEvent):
""" """

View File

@ -142,42 +142,39 @@ class AssistantGooglePushtotalkPlugin(AssistantPlugin):
self._install_device_handlers() self._install_device_handlers()
@staticmethod def on_conversation_start(self):
def on_conversation_start():
""" Conversation start handler """ """ Conversation start handler """
def handler(): def handler():
get_bus().post(ConversationStartEvent()) get_bus().post(ConversationStartEvent(assistant=self))
return handler return handler
@staticmethod def on_conversation_end(self):
def on_conversation_end():
""" Conversation end handler """ """ Conversation end handler """
def handler(with_follow_on_turn): def handler(with_follow_on_turn):
get_bus().post(ConversationEndEvent(with_follow_on_turn=with_follow_on_turn)) get_bus().post(ConversationEndEvent(assistant=self, with_follow_on_turn=with_follow_on_turn))
return handler return handler
def on_speech_recognized(self): def on_speech_recognized(self):
""" Speech recognized handler """ """ Speech recognized handler """
def handler(phrase): def handler(phrase):
get_bus().post(SpeechRecognizedEvent(phrase=phrase)) get_bus().post(SpeechRecognizedEvent(assistant=self, phrase=phrase))
self.interactions.append({'request': phrase}) self.interactions.append({'request': phrase})
return handler return handler
@staticmethod def on_volume_changed(self):
def on_volume_changed():
""" Volume changed event """ """ Volume changed event """
def handler(volume): def handler(volume):
get_bus().post(VolumeChangedEvent(volume=volume)) get_bus().post(VolumeChangedEvent(assistant=self, volume=volume))
return handler return handler
def on_response(self): def on_response(self):
""" Response handler """ """ Response handler """
def handler(response): def handler(response):
get_bus().post(ResponseEvent(response_text=response)) get_bus().post(ResponseEvent(assistant=self, response_text=response))
if not self.interactions: if not self.interactions:
self.interactions.append({'response': response}) self.interactions.append({'response': response})
@ -254,7 +251,7 @@ class AssistantGooglePushtotalkPlugin(AssistantPlugin):
self.conversation_stream.stop_playback() self.conversation_stream.stop_playback()
self.conversation_stream.stop_recording() self.conversation_stream.stop_recording()
get_bus().post(ConversationEndEvent()) get_bus().post(ConversationEndEvent(assistant=self))
def _install_device_handlers(self): def _install_device_handlers(self):
self.device_handler = device_helpers.DeviceRequestHandler(self.device_id) self.device_handler = device_helpers.DeviceRequestHandler(self.device_id)