Skip to content

Commit

Permalink
use signal INT to exit
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongyihui committed Mar 29, 2018
1 parent bb3474f commit 8f66e71
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 48 deletions.
95 changes: 58 additions & 37 deletions avs/alexa.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,20 @@
import uuid
import base64
import hashlib
import signal
import threading

import requests

try:
if sys.version_info < (3, 0):
import Queue as queue
except ImportError:
else:
import queue
import threading
import datetime

import requests
import datetime
import hyper

from avs.mic import Audio

from avs.interface.alerts import Alerts
from avs.interface.audio_player import AudioPlayer
from avs.interface.speaker import Speaker
Expand Down Expand Up @@ -132,18 +134,22 @@ def run(self):
continue

def _run(self):
conn = hyper.HTTP20Connection('{}:443'.format(self._config['host_url']), force_proto='h2')
conn = hyper.HTTP20Connection('{}:443'.format(
self._config['host_url']), force_proto='h2')

headers = {'authorization': 'Bearer {}'.format(self.token)}
if 'dueros-device-id' in self._config:
headers['dueros-device-id'] = self._config['dueros-device-id']

downchannel_id = conn.request('GET', '/{}/directives'.format(self._config['api']), headers=headers)
downchannel_id = conn.request(
'GET', '/{}/directives'.format(self._config['api']), headers=headers)
downchannel_response = conn.get_response(downchannel_id)
if downchannel_response.status != 200:
raise ValueError("/directive requests returned {}".format(downchannel_response.status))
raise ValueError(
"/directive requests returned {}".format(downchannel_response.status))

ctype, pdict = cgi.parse_header(downchannel_response.headers['content-type'][0].decode('utf-8'))
ctype, pdict = cgi.parse_header(
downchannel_response.headers['content-type'][0].decode('utf-8'))
downchannel_boundary = '--{}'.format(pdict['boundary']).encode('utf-8')
downchannel = conn.streams[downchannel_id]
downchannel_buffer = io.BytesIO()
Expand All @@ -160,7 +166,8 @@ def _run(self):
# logger.info("Waiting for event to send to AVS")
# logger.info("Connection socket can_read %s", conn._sock.can_read)
try:
event, listener, attachment = self.event_queue.get(timeout=0.25)
event, listener, attachment = self.event_queue.get(
timeout=0.25)
except queue.Empty:
event = None

Expand Down Expand Up @@ -206,13 +213,16 @@ def _run(self):
json_part += 'Content-Type: application/json; charset=UTF-8\r\n\r\n'
json_part += json.dumps(metadata)

conn.send(json_part.encode('utf-8'), final=False, stream_id=stream_id)
conn.send(json_part.encode('utf-8'),
final=False, stream_id=stream_id)

if attachment:
attachment_header = '\r\n--{}\r\n'.format(eventchannel_boundary)
attachment_header = '\r\n--{}\r\n'.format(
eventchannel_boundary)
attachment_header += 'Content-Disposition: form-data; name="audio"\r\n'
attachment_header += 'Content-Type: application/octet-stream\r\n\r\n'
conn.send(attachment_header.encode('utf-8'), final=False, stream_id=stream_id)
conn.send(attachment_header.encode('utf-8'),
final=False, stream_id=stream_id)

# AVS_AUDIO_CHUNK_PREFERENCE = 320
for chunk in attachment:
Expand All @@ -224,12 +234,14 @@ def _run(self):

while downchannel.data:
framebytes = downchannel._read_one_frame()
self._read_response(framebytes, downchannel_boundary, downchannel_buffer)
self._read_response(
framebytes, downchannel_boundary, downchannel_buffer)

self.last_activity = datetime.datetime.utcnow()

end_part = '\r\n--{}--'.format(eventchannel_boundary)
conn.send(end_part.encode('utf-8'), final=True, stream_id=stream_id)
conn.send(end_part.encode('utf-8'),
final=True, stream_id=stream_id)

logger.info("wait for response")
resp = conn.get_response(stream_id)
Expand Down Expand Up @@ -309,7 +321,8 @@ def iter_lines(response, delimiter=None):
if 'directive' in json_payload:
directives.append(json_payload['directive'])
else:
logger.info("Finished downloading {} which is {}".format(content_type, content_id))
logger.info("Finished downloading {} which is {}".format(
content_type, content_id))
payload.seek(0)
# TODO, start to stream this to speakers as soon as we start getting bytes
# strip < and >
Expand Down Expand Up @@ -379,7 +392,8 @@ def _handle_directive(self, directive):
if directive_func:
directive_func(directive)
else:
logger.info('{}.{} is not implemented yet'.format(namespace, name))
logger.info(
'{}.{} is not implemented yet'.format(namespace, name))
else:
logger.info('{} is not implemented yet'.format(namespace))

Expand All @@ -399,7 +413,8 @@ def _ping(self, connection):

connection.ping(uuid.uuid4().hex[:8])

logger.debug('ping at {}'.format(datetime.datetime.utcnow().strftime("%a %b %d %H:%M:%S %Y")))
logger.debug('ping at {}'.format(
datetime.datetime.utcnow().strftime("%a %b %d %H:%M:%S %Y")))

# ping every 5 minutes (60 seconds early for latency) to maintain the connection
self._ping_time = datetime.datetime.utcnow() + datetime.timedelta(seconds=240)
Expand All @@ -416,7 +431,8 @@ def token(self):

if 'access_token' in self._config:
if 'expiry' in self._config:
expiry = datetime.datetime.strptime(self._config['expiry'], date_format)
expiry = datetime.datetime.strptime(
self._config['expiry'], date_format)
# refresh 60 seconds early to avoid chance of using expired access_token
if (datetime.datetime.utcnow() - expiry) > datetime.timedelta(seconds=60):
logger.info("Refreshing access_token")
Expand All @@ -435,7 +451,8 @@ def token(self):
# try to request an access token 3 times
for i in range(3):
try:
response = self.requests.post(self._config['refresh_url'], data=payload)
response = self.requests.post(
self._config['refresh_url'], data=payload)
if response.status_code != 200:
logger.warning(response.text)
else:
Expand All @@ -445,12 +462,14 @@ def token(self):
continue

if (response is None) or (not hasattr(response, 'status_code')) or response.status_code != 200:
raise ValueError("refresh token request returned {}".format(response.status))
raise ValueError(
"refresh token request returned {}".format(response.status))

config = response.json()
self._config['access_token'] = config['access_token']

expiry_time = datetime.datetime.utcnow() + datetime.timedelta(seconds=config['expires_in'])
expiry_time = datetime.datetime.utcnow(
) + datetime.timedelta(seconds=config['expires_in'])
self._config['expiry'] = expiry_time.strftime(date_format)
logger.debug(json.dumps(self._config, indent=4))

Expand All @@ -467,9 +486,6 @@ def __exit__(self, exc_type, exc_val, exc_tb):


def main():
import sys
from avs.mic import Audio

logging.basicConfig(level=logging.INFO)

config = None if len(sys.argv) < 2 else sys.argv[1]
Expand All @@ -479,21 +495,26 @@ def main():

audio.link(alexa)

alexa.start()
alexa.start()
audio.start()

while True:
is_quit = threading.Event()

def signal_handler(signal, frame):
print('Quit')
is_quit.set()

signal.signal(signal.SIGINT, signal_handler)

while not is_quit.is_set():
try:
try:
input('press ENTER to talk\n')
except SyntaxError:
pass
except NameError:
pass
input('press ENTER to talk\n')
except SyntaxError:
pass
except NameError:
pass

alexa.listen()
except KeyboardInterrupt:
break
alexa.listen()

alexa.stop()
audio.stop()
Expand Down
28 changes: 17 additions & 11 deletions avs/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@


import sys
import signal
import time
import threading
try:
import logging

if sys.version_info < (3, 0):
import Queue as queue
except ImportError:
else:
import queue

import logging
from avs.alexa import Alexa
from avs.mic import Audio
from respeaker.pixel_ring import pixel_ring


logger = logging.getLogger(__file__)
logging.basicConfig(level=logging.INFO)
Expand Down Expand Up @@ -80,9 +84,6 @@ def run(self):


def main():
from respeaker.pixel_ring import pixel_ring


config = None if len(sys.argv) < 2 else sys.argv[1]

audio = Audio(frames_size=1600)
Expand Down Expand Up @@ -110,11 +111,16 @@ def wakeup(keyword):
kws.start()
audio.start()

while True:
try:
time.sleep(1)
except KeyboardInterrupt:
break
is_quit = threading.Event()

def signal_handler(signal, frame):
print('Quit')
is_quit.set()

signal.signal(signal.SIGINT, signal_handler)

while not is_quit.is_set():
time.sleep(1)

alexa.stop()
kws.stop()
Expand Down

0 comments on commit 8f66e71

Please sign in to comment.