mirror of
https://github.com/MarkParker5/STARK.git
synced 2024-11-24 08:12:13 +02:00
move CommandsContext to separate class
and other improvements
This commit is contained in:
parent
e517fc70be
commit
9204341956
88
ArchieCore/Commands/CommandsContext.py
Normal file
88
ArchieCore/Commands/CommandsContext.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
from abc import ABC, abstractmethod
|
||||||
|
import asyncio
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from ArchieCore import ACTime
|
||||||
|
from .CommandsManager import CommandsManager
|
||||||
|
from .Command import Command
|
||||||
|
from .Response import Response, ResponseAction
|
||||||
|
from .ThreadData import ThreadData
|
||||||
|
|
||||||
|
class CommandsContextDelegate:
|
||||||
|
@abstractmethod
|
||||||
|
def commandsContextDidReceiveResponse(self, response: Response): pass
|
||||||
|
|
||||||
|
class CommandsContext:
|
||||||
|
|
||||||
|
delegate: CommandsContextDelegate
|
||||||
|
|
||||||
|
commandsManager = CommandsManager()
|
||||||
|
lastInteractTime: ACTime = ACTime()
|
||||||
|
commandsContext: list[list[Command]] = [CommandsManager().allCommands,]
|
||||||
|
threads: list[ThreadData] = []
|
||||||
|
reports: list[Response] = []
|
||||||
|
memory: list[Response] = []
|
||||||
|
delaysReports: False # if True, reports will be delayed to next interaction; if False send reports immediately
|
||||||
|
|
||||||
|
def __init__(self, delegate: CommandsContextDelegate):
|
||||||
|
self.delegate = delegate
|
||||||
|
|
||||||
|
def processString(self, string: str, data: dict[str, Any] = {}):
|
||||||
|
currentContext = self.commandsContext[0] if self.commandsContext else None
|
||||||
|
|
||||||
|
while self.commandsContext:
|
||||||
|
if searchResults := self.commandsManager.search(string = string, commands = currentContext):
|
||||||
|
for searchResult in searchResults:
|
||||||
|
commandResponse = searchResult.command.start(params = searchResult.parameters)
|
||||||
|
commandResponse.data = data
|
||||||
|
|
||||||
|
match commandResponse.action:
|
||||||
|
case ResponseAction.popContext:
|
||||||
|
self.commandsContext.pop(0)
|
||||||
|
case ResponseAction.popToRootContext:
|
||||||
|
self.commandsContext = [self.commandsManager.allCommands,]
|
||||||
|
case ResponseAction.sleep:
|
||||||
|
self.speechRecognizer.isRecognizing = False
|
||||||
|
case ResponseAction.repeatLastAnswer:
|
||||||
|
if self.memory:
|
||||||
|
previousResponse = self.memory[-1]
|
||||||
|
self.delegate.didReceiveCommandsResponse(previousResponse)
|
||||||
|
case ResponseAction.answerNotFound:
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.parse(commandResponse)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
currentContext = self.commandsContext.pop(0)
|
||||||
|
else:
|
||||||
|
self.commandsContext.append(self.commandsManager.allCommands)
|
||||||
|
|
||||||
|
async def asyncCheckThreads(self):
|
||||||
|
while True:
|
||||||
|
await asyncio.sleep(5)
|
||||||
|
checkThreads()
|
||||||
|
|
||||||
|
def checkThreads(self):
|
||||||
|
for threadData in self.threads:
|
||||||
|
if not threadData.finishEvent.is_set(): continue
|
||||||
|
|
||||||
|
response = threadData.thread.join()
|
||||||
|
self.parse(response, delaysReports = delaysReports and ACTime() - self.lastInteractTime > 30)
|
||||||
|
threadData.finishEvent.clear()
|
||||||
|
|
||||||
|
del threadData
|
||||||
|
|
||||||
|
def parse(self, response, delaysReports: bool = False):
|
||||||
|
self.reports.insert(0, response)
|
||||||
|
if response.thread:
|
||||||
|
self.threads.append(response.thread)
|
||||||
|
if response.context:
|
||||||
|
self.commandsContext.insert(0, response.context)
|
||||||
|
if not delaysReports:
|
||||||
|
self.report()
|
||||||
|
self.memory.append(response)
|
||||||
|
|
||||||
|
def report(self):
|
||||||
|
for response in self.reports:
|
||||||
|
self.delegate.commandsContextDidReceiveResponse(response)
|
||||||
|
self.reports = []
|
@ -44,7 +44,7 @@ class CommandsManager:
|
|||||||
|
|
||||||
if results: return results
|
if results: return results
|
||||||
elif qa := self.QA: return [SearchResult(qa, {'string': acstring,}),]
|
elif qa := self.QA: return [SearchResult(qa, {'string': acstring,}),]
|
||||||
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def append(self, command):
|
def append(self, command):
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import Optional
|
from typing import Optional, Any
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from .Command import Command
|
from .Command import Command
|
||||||
from .ThreadData import ThreadData
|
from .ThreadData import ThreadData
|
||||||
@ -8,6 +8,7 @@ class ResponseAction(Enum):
|
|||||||
popToRootContext = auto()
|
popToRootContext = auto()
|
||||||
sleep = auto()
|
sleep = auto()
|
||||||
repeatLastAnswer = auto()
|
repeatLastAnswer = auto()
|
||||||
|
answerNotFound = auto()
|
||||||
|
|
||||||
class Response:
|
class Response:
|
||||||
voice: str
|
voice: str
|
||||||
@ -15,6 +16,7 @@ class Response:
|
|||||||
context: list[Command]
|
context: list[Command]
|
||||||
thread: Optional[ThreadData]
|
thread: Optional[ThreadData]
|
||||||
action: Optional[ResponseAction]
|
action: Optional[ResponseAction]
|
||||||
|
data: dict[str, Any]
|
||||||
|
|
||||||
def __init__(self, voice, text, context = [], thread = None, action = None):
|
def __init__(self, voice, text, context = [], thread = None, action = None):
|
||||||
self.voice = voice
|
self.voice = voice
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
from .Command import *
|
from .Command import Command
|
||||||
from .Response import *
|
from .Response import Response, ResponseAction
|
||||||
from .CommandsManager import CommandsManager, SearchResult
|
from .CommandsManager import CommandsManager, SearchResult
|
||||||
|
from .CommandsContext import CommandsContext, CommandsContextDelegate
|
||||||
|
@ -3,68 +3,53 @@
|
|||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
import config
|
import config
|
||||||
from ArchieCore import Command
|
from ArchieCore import Command, CommandsContext, CommandsContextDelegate
|
||||||
from General import Text2Speech
|
from General import Text2Speech
|
||||||
from ..Control import Control
|
from ..Control import Control
|
||||||
from .MyTeleBot import MyTeleBot
|
from .MyTeleBot import MyTeleBot
|
||||||
|
|
||||||
class TelegramBot(Control):
|
class TelegramBot(Control, CommandsContextDelegate):
|
||||||
threads = []
|
threads = []
|
||||||
online = True
|
online = True
|
||||||
voids = 0
|
voids = 0
|
||||||
memory = []
|
memory = []
|
||||||
voice = Text2Speech.Engine()
|
voice = Text2Speech.Engine()
|
||||||
bot = MyTeleBot(config.telebot)
|
bot = MyTeleBot(config.telebot)
|
||||||
|
commandsContext: CommandsContext
|
||||||
|
|
||||||
|
# Control
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
self.commandsContext = CommandsContext(delegate = self)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
print("Start polling...")
|
||||||
|
self.bot.polling(callback = self.commandsContext.checkThreads)
|
||||||
|
except Exception as e:
|
||||||
|
print(e, "\nPolling failed")
|
||||||
|
time.sleep(10)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def main(self, id, text):
|
||||||
|
self.commandsContext.processString(text.lower(), data = {'id': id})
|
||||||
|
|
||||||
|
# CommandsContextDelegate
|
||||||
|
|
||||||
|
def commandsContextDidReceiveResponse(self, response):
|
||||||
|
id = response.data.get('id')
|
||||||
|
if not id: return
|
||||||
|
|
||||||
def reply(self, id, response):
|
|
||||||
if response.text:
|
if response.text:
|
||||||
self.bot.send_message(id, response.text)
|
self.bot.send_message(id, response.text)
|
||||||
if response.voice:
|
if response.voice:
|
||||||
if bytes := self.voice.generate(response.voice).getBytes():
|
if bytes := self.voice.generate(response.voice).getBytes():
|
||||||
self.bot.send_voice(id, bytes)
|
self.bot.send_voice(id, bytes)
|
||||||
if response.thread: # add background thread to list
|
|
||||||
response.thread['id'] = id
|
|
||||||
self.threads.append(response.thread)
|
|
||||||
|
|
||||||
def check_threads(self, threads):
|
# Telebot
|
||||||
for thread in threads:
|
|
||||||
if thread['finish_event'].is_set():
|
|
||||||
response = thread['thread'].join()
|
|
||||||
self.reply(thread['id'], response)
|
|
||||||
thread['finish_event'].clear()
|
|
||||||
del thread
|
|
||||||
|
|
||||||
def main(self, id, text):
|
|
||||||
text = text.lower()
|
|
||||||
if Command.isRepeat(text):
|
|
||||||
self.reply(id, self.memory[0]['response']);
|
|
||||||
return
|
|
||||||
if self.memory:
|
|
||||||
response = self.memory[0]['response']
|
|
||||||
if response.callback:
|
|
||||||
if new_response := response.callback.answer(text):
|
|
||||||
self.reply(id, new_response)
|
|
||||||
memory.insert(0, {
|
|
||||||
'cmd': response.callback,
|
|
||||||
'params': None,
|
|
||||||
'response': new_response,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
cmd, params = self.memory[0]['cmd'].checkContext(text).values()
|
|
||||||
if self.memory[0].get('params'): params = {**memory[0].get('params'), **params}
|
|
||||||
except:
|
|
||||||
cmd, params = Command.reg_find(text).values()
|
|
||||||
response = cmd.start(params)
|
|
||||||
self.reply(id, response)
|
|
||||||
self.memory.insert(0, {
|
|
||||||
'cmd': cmd,
|
|
||||||
'params': params,
|
|
||||||
'response': response,
|
|
||||||
})
|
|
||||||
|
|
||||||
@bot.message_handler(commands=['vlc', 'queue', 'cmd'])
|
@bot.message_handler(commands=['vlc', 'queue', 'cmd'])
|
||||||
def simple_commands(msg):
|
def simple_commands(msg):
|
||||||
@ -80,17 +65,4 @@ class TelegramBot(Control):
|
|||||||
|
|
||||||
@bot.message_handler(content_types = ['text'])
|
@bot.message_handler(content_types = ['text'])
|
||||||
def execute(msg):
|
def execute(msg):
|
||||||
TelegramBot().main(msg.chat.id, msg.text)
|
self.commandsContext.processString(msg.text.lower(), data = {'id': msg.chat.id})
|
||||||
|
|
||||||
def start(self):
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
print("Start polling...")
|
|
||||||
self.bot.polling(callback = self.check_threads, args = (self.threads,) )
|
|
||||||
except Exception as e:
|
|
||||||
print(e, "\nPolling failed")
|
|
||||||
time.sleep(10)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
TelegramBot().start()
|
|
||||||
|
@ -1,111 +1,58 @@
|
|||||||
#!/usr/local/bin/python3.8
|
#!/usr/local/bin/python3.8
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
|
||||||
|
|
||||||
import config
|
import config
|
||||||
from ..Control import Control
|
from ..Control import Control
|
||||||
from General import SpeechRecognizer, Text2Speech
|
from General import SpeechRecognizer, SpeechRecognizerDelegate, Text2Speech
|
||||||
from ArchieCore import CommandsManager, Command, Response, ResponseAction, ThreadData, ACTime
|
from ArchieCore import ACTime, CommandsContext, CommandsContextDelegate
|
||||||
|
|
||||||
class VoiceAssistant(Control):
|
class VoiceAssistant(Control, SpeechRecognizerDelegate, CommandsContextDelegate):
|
||||||
commandsManager = CommandsManager()
|
|
||||||
speechRecognizer = SpeechRecognizer()
|
speechRecognizer: SpeechRecognizer
|
||||||
|
commandsContext: CommandsContext
|
||||||
voice = Text2Speech.Engine()
|
voice = Text2Speech.Engine()
|
||||||
|
|
||||||
commandsContext: list[list[Command]] = []
|
|
||||||
threads: list[ThreadData] = []
|
|
||||||
reports: list[Response] = []
|
|
||||||
memory: list[Response] = []
|
|
||||||
|
|
||||||
voids: int = 0
|
voids: int = 0
|
||||||
lastInteractTime: ACTime = ACTime()
|
|
||||||
lastClapTime: float = 0
|
lastClapTime: float = 0
|
||||||
doubleClap: bool = False
|
doubleClap: bool = False
|
||||||
|
|
||||||
|
# Control
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
self.speechRecognizer = SpeechRecognizer(delegate = self)
|
||||||
|
self.commandsContext = CommandsContext(delegate = self)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.commandsContext = [self.commandsManager.allCommands,]
|
self.speechRecognizer.delegate = self
|
||||||
self.speechRecognizer.didReceivePartialResult = lambda string: self.speechRecognizerReceivePartialResult(string)
|
print('Listen...')
|
||||||
self.speechRecognizer.didReceiveFinalResult = lambda string: self.speechRecognizerReceiveFinalResult(string)
|
|
||||||
self.speechRecognizer.didReceiveEmptyResult = lambda: self.speechRecognizerReceiveEmptyResult()
|
|
||||||
|
|
||||||
asyncio.get_event_loop().run_until_complete(
|
asyncio.get_event_loop().run_until_complete(
|
||||||
self.listenAndCheckThreads()
|
self.speechRecognizer.startListening()
|
||||||
)
|
)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.speechRecognizer.stopListening()
|
self.speechRecognizer.stopListening()
|
||||||
|
|
||||||
def speechRecognizerReceiveEmptyResult(self):
|
# SpeechRecognizerDelegate
|
||||||
self.voids += 1
|
|
||||||
|
def speechRecognizerReceiveFinalResult(self, result: str):
|
||||||
|
self.voids = 0
|
||||||
|
self.commandsContext.lastInteractTime = ACTime()
|
||||||
|
print(f'\rYou: {result}')
|
||||||
|
|
||||||
|
self.commandsContext.processString(result)
|
||||||
|
|
||||||
def speechRecognizerReceivePartialResult(self, result: str):
|
def speechRecognizerReceivePartialResult(self, result: str):
|
||||||
print(f'\rYou: \x1B[3m{result}\x1B[0m', end = '')
|
print(f'\rYou: \x1B[3m{result}\x1B[0m', end = '')
|
||||||
|
|
||||||
def speechRecognizerReceiveFinalResult(self, result: str):
|
def speechRecognizerReceiveEmptyResult(self):
|
||||||
self.voids = 0
|
self.voids += 1
|
||||||
self.lastInteractTime = ACTime()
|
|
||||||
print(f'\rYou: {result}')
|
|
||||||
|
|
||||||
currentContext = self.commandsContext[0] if self.commandsContext else None
|
# CommandsContextDelegate
|
||||||
|
|
||||||
while self.commandsContext:
|
def commandsContextDidReceiveResponse(self, response):
|
||||||
if searchResults := self.commandsManager.search(string = result, commands = currentContext):
|
|
||||||
for searchResult in searchResults:
|
|
||||||
commandResponse = searchResult.command.start(params = searchResult.parameters)
|
|
||||||
self.parse(commandResponse)
|
|
||||||
|
|
||||||
match commandResponse.action:
|
|
||||||
case ResponseAction.popContext:
|
|
||||||
self.commandsContext.pop(0)
|
|
||||||
case ResponseAction.popToRootContext:
|
|
||||||
self.commandsContext = [self.commandsManager.allCommands,]
|
|
||||||
case ResponseAction.sleep:
|
|
||||||
self.speechRecognizer.isRecognizing = False
|
|
||||||
case ResponseAction.repeatLastAnswer:
|
|
||||||
if self.memory:
|
|
||||||
previousResponse = self.memory[-1]
|
|
||||||
self.reply(previousResponse)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
currentContext = self.commandsContext.pop(0)
|
|
||||||
else:
|
|
||||||
self.commandsContext.append(self.commandsManager.allCommands)
|
|
||||||
|
|
||||||
async def listenAndCheckThreads(self):
|
|
||||||
while True:
|
|
||||||
await self.speechRecognizer.startListening()
|
|
||||||
|
|
||||||
for threadData in self.threads:
|
|
||||||
if not threadData.finishEvent.is_set(): continue
|
|
||||||
|
|
||||||
response = threadData.thread.join()
|
|
||||||
self.parse(response, silent = ACTime() - self.lastInteractTime > 30)
|
|
||||||
threadData.finishEvent.clear()
|
|
||||||
|
|
||||||
del threadData
|
|
||||||
|
|
||||||
def parse(self, response, silent: bool = False):
|
|
||||||
self.reports.insert(0, response)
|
|
||||||
if not silent:
|
|
||||||
self.report()
|
|
||||||
if response.thread:
|
|
||||||
self.threads.append(response.thread)
|
|
||||||
if response.context:
|
|
||||||
self.commandsContext.insert(0, response.context)
|
|
||||||
self.memory.append(response)
|
|
||||||
|
|
||||||
def report(self):
|
|
||||||
for response in self.reports:
|
|
||||||
self.reply(response)
|
|
||||||
self.reports = []
|
|
||||||
|
|
||||||
def reply(self, response):
|
|
||||||
if response.text:
|
if response.text:
|
||||||
print(f'\nArchie: {response.text}')
|
print(f'Archie: {response.text}')
|
||||||
if response.voice:
|
if response.voice:
|
||||||
wasRecognizing = self.speechRecognizer.isRecognizing
|
wasRecognizing = self.speechRecognizer.isRecognizing
|
||||||
self.speechRecognizer.isRecognizing = False
|
self.speechRecognizer.isRecognizing = False
|
||||||
@ -121,6 +68,8 @@ class VoiceAssistant(Control):
|
|||||||
else:
|
else:
|
||||||
self.lastClapTime = now
|
self.lastClapTime = now
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if config.double_clap_activation:
|
if config.double_clap_activation:
|
||||||
import RPi.GPIO as GPIO
|
import RPi.GPIO as GPIO
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from bs4 import BeautifulSoup as BS
|
from bs4 import BeautifulSoup as BS
|
||||||
from ArchieCore import CommandsManager, Command, Response
|
from ArchieCore import CommandsManager, Command, Response, ResponseAction
|
||||||
import wikipedia as wiki
|
import wikipedia as wiki
|
||||||
import requests
|
import requests
|
||||||
import random
|
import random
|
||||||
@ -57,7 +57,7 @@ class QAHelper():
|
|||||||
|
|
||||||
@Command.new()
|
@Command.new()
|
||||||
def qa_start(params):
|
def qa_start(params):
|
||||||
query = params['string']
|
query = params['string'].value
|
||||||
if 'вики' in query:
|
if 'вики' in query:
|
||||||
query = query.replace('википедия', '').replace('вики', '').strip()
|
query = query.replace('википедия', '').replace('вики', '').strip()
|
||||||
try: search = QAHelper.googleSearch(query)
|
try: search = QAHelper.googleSearch(query)
|
||||||
@ -72,7 +72,9 @@ def qa_start(params):
|
|||||||
try: search = QAHelper.googleSearch(query)
|
try: search = QAHelper.googleSearch(query)
|
||||||
except: search = ''
|
except: search = ''
|
||||||
voice = text = search or random.choice(['Не совсем понимаю, о чём вы.', 'Вот эта последняя фраза мне не ясна.', 'А вот это не совсем понятно.', 'Можете сказать то же самое другими словами?', 'Вот сейчас я совсем вас не понимаю.', 'Попробуйте выразить свою мысль по-другому',])
|
voice = text = search or random.choice(['Не совсем понимаю, о чём вы.', 'Вот эта последняя фраза мне не ясна.', 'А вот это не совсем понятно.', 'Можете сказать то же самое другими словами?', 'Вот сейчас я совсем вас не понимаю.', 'Попробуйте выразить свою мысль по-другому',])
|
||||||
return Response(text = text, voice = voice)
|
|
||||||
|
action = ResponseAction.answerNotFound if not text and not voice else None
|
||||||
|
|
||||||
|
return Response(text = text, voice = voice, action = action)
|
||||||
|
|
||||||
CommandsManager().QA = qa_start
|
CommandsManager().QA = qa_start
|
||||||
print(CommandsManager().QA, 'CommandsManager Sets QA')
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
from .SmallTalk import SmallTalk
|
from .SmallTalk import SmallTalk
|
||||||
from .Raspi import Raspi
|
from .Raspi import Raspi
|
||||||
from .Zieit import Zieit
|
from .Zieit import Zieit
|
||||||
|
from .QA import QA
|
||||||
|
|
||||||
try: from .SmartHome import SmartHome
|
try: from .SmartHome import SmartHome
|
||||||
except: pass
|
except: pass
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from typing import Callable, Optional
|
from typing import Callable, Optional
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
import asyncio
|
import asyncio
|
||||||
import os, sys
|
import os, sys
|
||||||
import queue
|
import queue
|
||||||
@ -11,16 +12,26 @@ import config
|
|||||||
|
|
||||||
vosk.SetLogLevel(-1)
|
vosk.SetLogLevel(-1)
|
||||||
|
|
||||||
|
class SpeechRecognizerDelegate(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def speechRecognizerReceiveFinalResult(self, result: str): pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def speechRecognizerReceivePartialResult(self, result: str): pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def speechRecognizerReceiveEmptyResult(self): pass
|
||||||
|
|
||||||
|
|
||||||
class SpeechRecognizer:
|
class SpeechRecognizer:
|
||||||
didReceivePartialResult: Callable[[str], None] = lambda _: None
|
|
||||||
didReceiveFinalResult: Callable[[str], None] = lambda _: None
|
delegate: SpeechRecognizerDelegate
|
||||||
didReceiveEmptyResult: Callable[[], None] = lambda: None
|
|
||||||
|
|
||||||
lastResult: Optional[str] = ""
|
lastResult: Optional[str] = ""
|
||||||
lastPartialResult: str = ""
|
lastPartialResult: str = ""
|
||||||
|
|
||||||
_isListening = False
|
|
||||||
isRecognizing = True
|
isRecognizing = True
|
||||||
|
_isListening = False
|
||||||
|
|
||||||
audioQueue = queue.Queue()
|
audioQueue = queue.Queue()
|
||||||
model = vosk.Model(config.vosk_model)
|
model = vosk.Model(config.vosk_model)
|
||||||
@ -31,14 +42,14 @@ class SpeechRecognizer:
|
|||||||
channels = 1
|
channels = 1
|
||||||
kaldiRecognizer = vosk.KaldiRecognizer(model, samplerate)
|
kaldiRecognizer = vosk.KaldiRecognizer(model, samplerate)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, delegate: SpeechRecognizerDelegate):
|
||||||
callback = lambda indata, frames, time, status: self.audioInputCallback(indata, frames, time, status)
|
self.delegate = delegate
|
||||||
self.parameters = {
|
self.parameters = {
|
||||||
'samplerate': self.samplerate,
|
'samplerate': self.samplerate,
|
||||||
'blocksize': self.blocksize,
|
'blocksize': self.blocksize,
|
||||||
'dtype': self.dtype,
|
'dtype': self.dtype,
|
||||||
'channels': self.channels,
|
'channels': self.channels,
|
||||||
'callback': callback
|
'callback': self.audioInputCallback
|
||||||
}
|
}
|
||||||
|
|
||||||
def audioInputCallback(self, indata, frames, time, status):
|
def audioInputCallback(self, indata, frames, time, status):
|
||||||
@ -62,12 +73,12 @@ class SpeechRecognizer:
|
|||||||
result = json.loads(self.kaldiRecognizer.Result())
|
result = json.loads(self.kaldiRecognizer.Result())
|
||||||
if (string := result.get('text')) and string != self.lastResult:
|
if (string := result.get('text')) and string != self.lastResult:
|
||||||
self.lastResult = string
|
self.lastResult = string
|
||||||
self.didReceiveFinalResult(string)
|
self.delegate.speechRecognizerReceiveFinalResult(string)
|
||||||
else:
|
else:
|
||||||
self.lastResult = None
|
self.lastResult = None
|
||||||
self.didReceiveEmptyResult()
|
self.delegate.speechRecognizerReceiveEmptyResult()
|
||||||
else:
|
else:
|
||||||
result = json.loads(self.kaldiRecognizer.PartialResult())
|
result = json.loads(self.kaldiRecognizer.PartialResult())
|
||||||
if (string := result.get('partial')) and string != self.lastPartialResult:
|
if (string := result.get('partial')) and string != self.lastPartialResult:
|
||||||
self.lastPartialResult = string
|
self.lastPartialResult = string
|
||||||
self.didReceivePartialResult(result['partial'])
|
self.delegate.speechRecognizerReceivePartialResult(result['partial'])
|
||||||
|
@ -1 +1 @@
|
|||||||
from .SpeechRecognition import SpeechRecognizer
|
from .SpeechRecognition import SpeechRecognizer, SpeechRecognizerDelegate
|
||||||
|
2
start.py
2
start.py
@ -7,7 +7,7 @@ import Controls
|
|||||||
def main():
|
def main():
|
||||||
controls = [
|
controls = [
|
||||||
Controls.VoiceAssistant(),
|
Controls.VoiceAssistant(),
|
||||||
#Controls.TelegramBot(),
|
Controls.TelegramBot(),
|
||||||
#Controls.RemoteControl(),
|
#Controls.RemoteControl(),
|
||||||
#Controls.Django(),
|
#Controls.Django(),
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user