#!/usr/bin/env python3 # Copyright 2017 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """A demo of the Google Assistant GRPC recognizer.""" # from google.assistant.library.event import Event, EventType, IterableEventQueue import snowboydecoder import sys, os, signal, time, threading, select,fcntl from subprocess import Popen, PIPE, call, check_output import logging import aiy.assistant.grpc import aiy.audio import aiy.voicehat logging.basicConfig( level=logging.INFO, format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s" ) buttonFlag = False buttonNone = False speakFlag = False status_ui = None detector = None player = None player2= None think = None speak = None arch_v6 = check_output(["uname -a"],shell=True).decode('utf-8') if arch_v6.find("armv6")<0:arch_v6 = False else:arch_v6 = True print ("ArchitectureV6=",arch_v6) # events = IterableEventQueue() interrupted = False def signal_handler(signal, frame): global buttonNone, interrupted aiy.voicehat.get_led().stop() buttonNone = True interrupted = True # capture SIGINT signal, e.g., Ctrl+C signal.signal(signal.SIGINT, signal_handler) def interrupt_callback(): global interrupted return interrupted def detect_callback1(word="t"): global player, detector, interrupted, speakFlag, buttonFlag if player:player.poll() if player.returncode==None: player.stdin.write((word+"\n").encode('utf-8')) player.stdin.flush() if word!="t": return detector.stream_in.stop_stream() speakFlag = True butttonFlag = False interrupted = True status_ui.status('listening') print('Listening...') snowboydecoder.play_audio_file(snowboydecoder.DETECT_DING) # detector.stream_in.start_stream() def detect_callback2(): global buttonFlag, interrupted, detector if buttonFlag==False: buttonFlag = True # events.offer(Event(EventType.ON_NO_RESPONSE,{'button':'ON'})) detector.stream_in.stop_stream() interrupted = True def on_button_press(): global buttonFlag, interrupted, think, speak, speakFlag print('Button pressed') think = False speak = False if speakFlag==True: speakFlag = False return if buttonFlag==False: buttonFlag = True # events.offer(Event(EventType.ON_NO_RESPONSE,{'button':'ON'})) interrupted = True def myTh_out(player): global detector, buttonNone, interrupted, speakFlag, think, speak think = False speak = False # set non-blocking flag while preserving old flags fl = fcntl.fcntl(player.stdout, fcntl.F_GETFL) fcntl.fcntl(player.stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK) while not player.stdout.closed: (ready,_,_) = select.select([player.stdout],[],[],0.1) if ready and not player.stdout.closed: buf = player.stdout.read() if buf: buf = buf.decode().rstrip('\n') print(buf) # if (speak or "Speaking" in buf) and "idle!" in buf: if ("not connected!" in buf) or ("idle!" in buf): if think: think = False speak = True speakFlag = True elif speak==True: if arch_v6: time.sleep(3) speak = False speakFlag = False detector.stream_in.start_stream() else: if "Thinking.." in buf: think = True if "Speaking.." in buf: think = False speak = True continue def myThread(player): global detector, buttonNone, interrupted, speakFlag, speak while not player.stdin.closed: (ready,_,_) = select.select([sys.stdin],[],[],3) if ready: word = input() else: continue if len(word)==0: buttonNone = True interrupted = True return if player:player.poll() if player.returncode==None: if word[0]=="p" or len(word)==1 and word in "tshi1234": speak = False speakFlag = False detect_callback1(word.rstrip('/').replace('/','\n')) continue if word=="q": stop_alexa() break sudo_exec(word.rstrip('/').replace('/','\n')) def stop_alexa(): global player if player:player.poll() if player.returncode==None: player.stdin.write('q\n'.encode('utf-8')) player.stdin.flush() try: outs, errs = player.communicate() except BlockingIOError: Popen(["killall","python3"]) def sudo_exec(word): global player2 print(word) stop_alexa() forAlexa(True) time.sleep(5) if arch_v6: time.sleep(5) player2.stdin.write((word+"\n").encode('utf-8')) player2.stdin.flush() time.sleep(1) player2.stdin.write(("q\n").encode('utf-8')) player2.stdin.flush() outs, errs = player2.communicate() print (str(errs)) time.sleep(1) forAlexa() time.sleep(2) thread = None th_out = None def forAlexa(sudo=False): global thread, player, player2 if sudo: player2 = Popen(["sudo","/home/pi/build/SampleApp/src/SampleApp", \ "/home/pi/build/Integration/AlexaClientSDKConfig.json"],stdin=PIPE) else: player = Popen(["bash","-lc","'/home/pi/startAlexa.sh'"],stdin=PIPE,stdout=PIPE) thread = threading.Thread(target=myThread, args=(player,)) thread.start() th_out = threading.Thread(target=myTh_out, args=(player,)) th_out.start() def main(): global thread, player, status_ui, detector, buttonFlag, buttonNone, \ interrupted, speakFlag, think, speak model = "NeGoogle.pmdl" if len(sys.argv)>1: model = sys.argv[1] status_ui = aiy.voicehat.get_status_ui() status_ui.status('starting') assistant = aiy.assistant.grpc.get_assistant() button = aiy.voicehat.get_button() button.on_press(on_button_press) hotwords = ["resources/alexa_02092017.umdl" , "resources/"+model] senses = [0.2, 0.2] callbacks = [detect_callback1, detect_callback2] detector = snowboydecoder.HotwordDetector(hotwords, sensitivity=senses) forAlexa() print('\033[96mListening\033[0m... Press Ctrl+C to exit') with aiy.audio.get_recorder(): while True: status_ui.status('ready') print('Press the button and speak') # button.wait_for_press() buttonFlag = False interrupted = False detector.start(detected_callback=callbacks, interrupt_check=interrupt_callback, sleep_time=0.05) if buttonFlag==False:    # Hotword検出以外の脱出 if buttonNone: break # Ctrl+C while speakFlag==True: # Alexaの呼び出しの場合 time.sleep(1) continue # Alexa butttonFlag = False # Google呼び出し status_ui.status('listening') print('\033[96mListening\033[0m...') text, audio = assistant.recognize() # Google音声認識 if text: print('You said "', text, '"') if 'Alexa も' in text and '聞いて' in text: # Alexaとの共聴 #                 detect_callback1()の代わり detector.stream_in.stop_stream() player.stdin.write('t\n'.encode('utf-8')) call(["n2tts -o - Alexaからね| aplay"],shell=True) # detect_callback1() player.stdin.flush() text, audio = assistant.recognize()   # Google音声認識 print('You said "', text, '"') if audio: text, audio2 = assistant.recognize() print('Alexa said "', text, '"') if "ニュース" in text: player.stdin.write('2\n2\n'.encode('utf-8')) player.stdin.flush() time.sleep(0.5) player.stdin.write('2\n2\n'.encode('utf-8')) player.stdin.flush() time.sleep(0.5) call(["n2tts -o - Alexa、あとでね?| aplay"],shell=True) #   話の腰を折る speakFlag = True if audio: if speakFlag==False: call(["n2tts -o - そぅだねえ~?| aplay"],shell=True) # 正常発話に相打ちする aiy.audio.play_audio(audio) # 自分の主張 if speakFlag==True: detector.stream_in.stop_stream() call(["n2tts -o - それでAlexaは?ボタンを押すまでね。| aplay"],shell=True) player.stdin.write('1\n1\n'.encode('utf-8')) player.stdin.flush() # Alexaに話を続行させる while speakFlag: text, audio2 = assistant.recognize() print('Alexa said "', text, '"') # Alexa発話の筆記 if text=="": break # ボタン押下又は発話終了 detector.stream_in.start_stream() continue if 'Alexa を' in text and '呼び出し' in text: if '英語' in text: sudo_exec("c\n1\n1\n") elif '日本語' in text: sudo_exec("c\n1\n6\n") detect_callback1() while speakFlag==True: time.sleep(1) continue if text == 'さようなら': print('Bye!') break if audio: aiy.audio.play_audio(audio) detector.stream_in.start_stream() aiy.voicehat.get_led().stop() stop_alexa() if th_out:th_out.join() if thread:thread.join() print("Alexaは打ち切られました ") detector.terminate() Popen(["killall","python3"]) if __name__ == '__main__': main()