-#!/usr/bin/env python3.8
+#!/usr/bin/env python3
import websockets,asyncio
import sys
from pyaudio import PyAudio, Stream, paInt16
-from contextlib import asynccontextmanager, contextmanager, AsyncExitStack
+from contextlib import asynccontextmanager, contextmanager, AsyncExitStack, ExitStack
from typing import AsyncGenerator, Generator
from urllib.parse import urlencode, quote
global config
try:
if config["debug"]:
- print("Skipping: ", seconds)
+ print("Skipping: ", seconds)
bufs = int((seconds)*source._rate/source._frames_per_buffer)
for i in range(bufs):
buffer = source.read(source._frames_per_buffer)
except:
pass
+def Silence(speaker, seconds):
+ buf = bytes(speaker._frames_per_buffer)
+ bufs = int((seconds)*speaker._rate/speaker._frames_per_buffer)
+ for i in range(bufs):
+ speaker.write(buf)
+
def PlayBack(pyaud, text, mic = None):
global config, last_time
decoder = MP3Decoder(req)
speaker = pyaud.open(output=True, format=paInt16, channels=decoder.num_channels, rate=decoder.sample_rate)
+ Silence(speaker, 0.3)
for chunk in decoder:
speaker.write(chunk)
if command_url:
try:
+ if config["debug"]:
+ print('Preparing command')
if command_user:
my_headers = urllib3.util.make_headers(basic_auth=command_user+':'+command_pwd)
else:
my_headers = urllib3.util.make_headers()
my_headers['Content-Type']='text/plain'
my_headers['Accept']='apllication/json'
- http.request('POST',command_url,headers=my_headers,body=command.encode('UTF-8'))
- if reply_url:
- sleep(0.5)
- res="NULL"
- for i in range(api_attempts):
- try:
- if command_user:
- my_headers = urllib3.util.make_headers(basic_auth=command_user+':'+command_pwd)
- else:
- my_headers = urllib3.util.make_headers()
- req=http.request('GET',reply_url,headers=my_headers).data
- res = json.loads(req)['state'].strip()
- if config["debug"]:
- print(res)
- if not(res == 'NULL'):
- break
- sleep(1)
- except KeyboardInterrupt:
- raise
- except:
- sleep(1)
- if res and not(res=="NULL"):
- PlayBack(pyaud, res, mic=mic)
- elif res=="NULL":
- PlayBack(pyaud, "Сервер не ответил", mic=mic)
- http.request('POST',command_url, headers=my_headers, body="")
+ if config["debug"]:
+ print('Sending command')
+ sent = False
+ for i in range(api_attempts):
+ try:
+ http.request('POST',command_url,headers=my_headers,body=command.encode('UTF-8'))
+ sent = True
+ break
+ except Exception as e:
+ print('Exception: '+str(e))
+ sleep(0.5)
+ if sent:
+ if config["debug"]:
+ print('Command sent')
+ if reply_url:
+ sleep(0.5)
+ res="NULL"
+ for i in range(api_attempts):
+ try:
+ if command_user:
+ my_headers = urllib3.util.make_headers(basic_auth=command_user+':'+command_pwd)
+ else:
+ my_headers = urllib3.util.make_headers()
+ req=http.request('GET',reply_url,headers=my_headers).data
+ res = json.loads(req)['state'].strip()
+ if config["debug"]:
+ print(res)
+ if not(res == 'NULL'):
+ break
+ sleep(1)
+ except KeyboardInterrupt:
+ raise
+ except Exception as e:
+ print('Exception: '+str(e))
+ sleep(1)
+ if res and not(res=="NULL"):
+ PlayBack(pyaud, res, mic=mic)
+ elif res=="NULL":
+ PlayBack(pyaud, "Сервер не ответил", mic=mic)
+ if command_user:
+ my_headers = urllib3.util.make_headers(basic_auth=command_user+':'+command_pwd)
+ else:
+ my_headers = urllib3.util.make_headers()
+ my_headers['Content-Type']='text/plain'
+ my_headers['Accept']='apllication/json'
+ command=""
+ http.request('POST',command_url, headers=my_headers, body=command.encode('UTF-8'))
+ else:
+ PlayBack(pyaud, "Сервер недоступен", mic=mic)
except KeyboardInterrupt:
raise
- except:
+ except Exception as e:
try:
+ print('Exception: '+str(e))
http.request('POST',command_url, headers=my_headers, body="")
except:
pass
except websockets.exceptions.ConnectionClosedError:
raise
except:
- raise
return '',0
-async def hello(uri):
+async def main_loop(uri):
global config, last_time
rec_attempts = config["rec_attempts"]
commands = config["commands"]
- async with AsyncExitStack() as stack:
- ws = await stack.enter_async_context(websockets.connect(uri))
- print('Type Ctrl-C to exit')
- phrases = config["commands"]
- phrases.append(config["keyphrase"])
- phrases = json.dumps(phrases, ensure_ascii=False)
- await ws.send('{"config" : { "phrase_list" : '+phrases+', "sample_rate" : 16000.0}}')
-
- ws = await stack.enter_async_context(_polite_websocket(ws))
- p = stack.enter_context(_pyaudio())
- s = stack.enter_context(_pyaudio_open_stream(p,
+
+ with ExitStack() as audio_stack:
+ p = audio_stack.enter_context(_pyaudio())
+ s = audio_stack.enter_context(_pyaudio_open_stream(p,
format = paInt16,
channels = 1,
rate = 16000,
input = True,
frames_per_buffer = 2000))
- while True:
- phrase, confidence = await ListenPhrase(s, ws)
- if config["debug"]:
- print(phrase,confidence)
- if phrase == keyphrase and confidence>=confidence_treshold :
- PlayBack(p, "Я жду команду", mic=s)
- command = ""
-
- for i in range(rec_attempts):
- phrase, confidence = await ListenPhrase(s, ws)
- if config["debug"]:
- print(phrase,confidence)
- if confidence > confidence_treshold:
- if (not commands) or (phrase in commands):
- if config["debug"]:
- print("Command: ", phrase)
- command = phrase
- RunCommand(command, p, s)
- break
- else:
- PlayBack(p, "Не знаю такой команды: "+phrase, mic=s)
- else:
- PlayBack(p, "Не поняла, слишком неразборчиво", mic=s)
-
- if not command:
- PlayBack(p, "Так команду и не поняла...", mic=s)
+ while True:
+ try:
+ async with AsyncExitStack() as web_stack:
+ ws = await web_stack.enter_async_context(websockets.connect(uri))
+ print('Type Ctrl-C to exit')
+ phrases = [] + config["commands"]
+ phrases.append(config["keyphrase"])
+ phrases = json.dumps(phrases, ensure_ascii=False)
+ await ws.send('{"config" : { "phrase_list" : '+phrases+', "sample_rate" : 16000.0}}')
+
+ ws = await web_stack.enter_async_context(_polite_websocket(ws))
+ while True:
+ phrase, confidence = await ListenPhrase(s, ws)
+ if config["debug"]:
+ print(phrase,confidence)
+ if phrase == keyphrase and confidence>=confidence_treshold :
+ PlayBack(p, "Я жду команду", mic=s)
+ command = ""
+
+ for i in range(rec_attempts):
+ phrase, confidence = await ListenPhrase(s, ws)
+ if config["debug"]:
+ print(phrase,confidence)
+ if confidence > confidence_treshold:
+ if (not commands) or (phrase in commands):
+ if config["debug"]:
+ print("Command: ", phrase)
+ command = phrase
+ RunCommand(command, p, s)
+ break
+ else:
+ PlayBack(p, "Не знаю такой команды: "+phrase, mic=s)
+ else:
+ PlayBack(p, "Не поняла, слишком неразборчиво", mic=s)
+
+ if not command:
+ PlayBack(p, "Так команду и не поняла...", mic=s)
+ except KeyboardInterrupt:
+ raise
+ except Exception as e:
+ print('Exception: '+str(e))
+ pass
def get_config(path):
loop = asyncio.get_event_loop()
loop.run_until_complete(
- hello(f'ws://' + server))
+ main_loop(f'ws://' + server))
except (Exception, KeyboardInterrupt) as e:
loop.run_until_complete(