1
0
mirror of https://github.com/MarkParker5/STARK.git synced 2025-07-02 22:36:54 +02:00
Files
STARK/Controls/VoiceAssistant/VoiceAssistant.py

145 lines
4.6 KiB
Python
Raw Normal View History

2021-08-21 02:09:37 +03:00
#!/usr/local/bin/python3.8
import os
from Controls.Control import Control
from General import SpeechRecognition, Text2Speech
from Features.Command import Command
import config
2021-08-21 02:09:37 +03:00
if config.double_clap_activation:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(12, GPIO.IN)
2021-09-12 15:07:34 +03:00
GPIO.add_event_detect(12, GPIO.RISING, callback = VoiceAssistant().checkClap)
2021-08-21 02:09:37 +03:00
class VoiceAssistant(Control):
listener = SpeechRecognition.SpeechToText()
voice = Text2Speech.Engine()
threads = []
reports = []
memory = []
voids = 0
lastClapTime = 0
doubleClap = False
# Singleton
def __new__(cls):
if not hasattr(cls, 'instance'):
cls.instance = super(VoiceAssistant, cls).__new__(cls)
return cls.instance
def start(self):
2021-08-31 23:03:48 +03:00
self.listener.listen_noise()
2021-08-21 02:09:37 +03:00
os.system('clear')
while True:
2021-08-31 23:03:48 +03:00
if self.voids >= 3:
self.voids = 0
2021-08-21 02:09:37 +03:00
if config.double_clap_activation:
print('\nSleep (-_-)zzZZ\n')
sleep()
print('\nYou: ', end='')
2021-08-31 23:03:48 +03:00
speech = self.listener.listen()
2021-08-21 02:09:37 +03:00
print(speech.get('text') or '', end='')
while True:
if speech['status'] == 'error':
break
if speech['status'] == 'void':
2021-08-31 23:03:48 +03:00
self.voids += 1
2021-08-21 02:09:37 +03:00
break
text = speech['text']
cmd, params = Command.reg_find(text).values()
try: response = cmd.start(params)
except: break
2021-08-31 23:03:48 +03:00
self.reply(response)
self.check_threads()
self.report()
2021-08-21 02:09:37 +03:00
if response.callback:
speech = recognize(response.callback, {})
else:
break
def recognize(self, callback, params):
print('\nYou: ', end='')
2021-08-31 23:03:48 +03:00
speech = self.listener.listen()
2021-08-21 02:09:37 +03:00
if speech['status'] in ['error', 'void']:
return speech
text = speech['text']
print(text, end='')
while True:
2021-08-31 23:03:48 +03:00
self.check_threads()
2021-08-21 02:09:37 +03:00
if not callback: break
try:
if response := callback.answer(text):
2021-08-31 23:03:48 +03:00
self.reply(response)
2021-08-21 02:09:37 +03:00
except:
break
2021-08-31 23:03:48 +03:00
self.memory.insert(0, {
2021-08-21 02:09:37 +03:00
'text': text,
'cmd': cmd,
'response': response,
})
speech = recognize(response.callback, params)
if callback.once: break
return speech
def report(self):
2021-08-31 23:03:48 +03:00
for response in self.reports:
2021-08-21 02:09:37 +03:00
if response.voice:
2021-08-31 23:03:48 +03:00
self.voice.generate(response.voice).speak()
2021-08-21 02:09:37 +03:00
time.sleep(2)
2021-08-31 23:03:48 +03:00
self.reports = []
2021-08-21 02:09:37 +03:00
def reply(self, response):
if response.text: # print answer
print('\nArchie: '+response.text)
if response.voice: # say answer
2021-08-31 23:03:48 +03:00
self.voice.generate(response.voice).speak()
2021-08-21 02:09:37 +03:00
if response.thread: # add background thread to stack
2021-08-31 23:03:48 +03:00
self.threads.append(response.thread)
2021-08-21 02:09:37 +03:00
def check_threads(self):
2021-08-31 23:03:48 +03:00
for thread in self.threads:
2021-08-21 02:09:37 +03:00
if not thread['finish_event'].is_set(): continue
response = thread['thread'].join()
2021-08-31 23:03:48 +03:00
self.reply(response)
2021-08-21 02:09:37 +03:00
if response.callback:
if response.callback.quiet:
response.callback.start()
else:
for _ in range(3):
print('\nYou: ', end='')
2021-08-31 23:03:48 +03:00
speech = self.listener.listen()
2021-08-21 02:09:37 +03:00
if speech['status'] == 'ok':
print(speech['text'], '\n')
new_response = response.callback.answer(speech['text'])
2021-08-31 23:03:48 +03:00
self.reply(new_response)
2021-08-21 02:09:37 +03:00
break
else:
2021-08-31 23:03:48 +03:00
self.reports.append(response)
2021-08-21 02:09:37 +03:00
thread['finish_event'].clear()
del thread
# check double clap from arduino microphone module
def checkClap(self, channel):
now = time.time()
2021-08-31 23:03:48 +03:00
delta = now - self.lastClapTime
2021-08-21 02:09:37 +03:00
if 0.1 < delta < 0.6:
2021-08-31 23:03:48 +03:00
self.doubleClap = True
2021-08-21 02:09:37 +03:00
else:
2021-08-31 23:03:48 +03:00
self.lastClapTime = now
2021-08-21 02:09:37 +03:00
# waiting for double clap
def sleep(self):
2021-08-31 23:03:48 +03:00
self.lastClapTime = 0
while not self.doubleClap:
self.check_threads()
2021-08-21 02:09:37 +03:00
time.sleep(1)
else:
2021-08-31 23:03:48 +03:00
self.doubleClap = False
2021-08-21 02:09:37 +03:00
if __name__ == '__main__':
VoiceAssistant().start()