SpeechRecognizerPy/state_machine.py

157 lines
6.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Модуль машины состояний (конечный автомат)
import speaker # Для разговоров
import datetime # Для времени
from pyowm import OWM # Использование OpenWeatherMap для получения данных о погоде (pip install pyowm)
import random
import traceback # вывод traceback без остановки работы программы при отлове исключений
machine = None # Конечный автомат
current_state = None # Текущее состояние
weather_api_key = None # Ключ для OpenWeatherMap
myName = None # Имя ассистента
def init(assistant_name):
"""Инициализирует конечный автомат"""
global machine
global current_state
global weather_api_key
global myName
myName = assistant_name
with open("weatherApiKey.txt", "r") as key:
weather_api_key = key.read()
current_state = "Начало"
machine = {
"Начало":{
assistant_name.lower(): switchToListen
},
"Слушаю задание":{
"время": switchToTime,
"погода": switchToWeather,
"привет": switchToHello,
"здравствуй": switchToHello,
"доброе утро": switchToHello,
"добрый день": switchToHello,
"добрый вечер": switchToHello,
"доброй ночи": switchToHello,
"пока": switchToBye,
"до встречи": switchToBye,
"перезапуск": switchToReboot,
"завершение работы": turnOff
},
}
switchToHello()
speaker.speak(f"Ассистент {myName} начинает работу")
def work():
"""Обрабатывает конечный автомат"""
global machine
global current_state
while(True):
word = input().lower() # Пока считаем с клавиатуры предложение
# Если ассистент знает такое слово для перехода
if (word in machine[current_state].keys()):
# Выполняем действия и переход в новое состояние
current_state = machine[current_state][word]()
elif (current_state != 'Начало'):
# иначе переспросим
speaker.speak("Я не понял, пожалуйста повторите")
print("Сейчас автомат в: " + current_state)
# Переход на "Слушаю задание"
def switchToListen():
speaker.speak("Слушаю")
return "Слушаю задание"
# Переход на "Говорю время" и возвращаюсь в "Начало"
def switchToTime():
now = datetime.datetime.now()
speaker.speak(f"Сейчас {now.hour} часов, {now.minute} минут")
return "Начало"
# Переход на "Вопрос локации погоды"
def switchToWeather():
global weather_api_key
# speaker.speak("Дома?")
# word = input().lower() # Пока считаем с клавиатуры предложение
# if (word == "да"):
# location = "Home"
# else:
# speaker.speak("Назовите локацию")
# location = input().lower() # Пока считаем с клавиатуры предложение
location = "Murino,RU"
try:
open_weather_map = OWM(weather_api_key)
# запрос данных о текущем состоянии погоды
weather_manager = open_weather_map.weather_manager()
observation = weather_manager.weather_at_place(location)
weather = observation.weather
except:
speaker.speak("Извините. Ошибка запроса к серверу погоды")
traceback.print_exc() # Вывод трейсбека для отладки
return "Начало"
# разбивание данных на части для удобства работы с ними
status = weather.detailed_status
temperature = int(weather.temperature('celsius')["temp"])
temperature_min = int(weather.temperature('celsius')["temp_min"])
temperature_max = int(weather.temperature('celsius')["temp_max"])
wind_speed = int(weather.wind()["speed"])
# pressure = int(weather.pressure["press"] / 1.333) # переведено из гПА в мм рт.ст.
speaker.speak(f"Сейчас на улице {temperature} градусов, минимальная {temperature_min}, максимальная {temperature_max}, скорость ветра {wind_speed} метров в секунду")
# ", давление {pressure} миллиметров ртутного столба")
return "Начало"
# Переход на приветствие и на "Начало"
def switchToHello():
helloWords = ["Привет", "Здравствуй", "Доброго времени суток"]
random_index = random.randint(0, len(helloWords))
# Если выпадает больше нуля - берем готовую
if (random_index > 0):
hi = helloWords[random_index-1]
else:
# Иначе генерируем время суток
now = datetime.datetime.now()
if (now.hour < 5 or now.hour > 21):
hi = "Доброй ночи"
elif (now.hour < 12):
hi = "Доброе утро"
elif (now.hour < 16):
hi = "Добрый день"
else:
hi = "Добрый вечер"
speaker.speak(hi)
return "Начало"
# Переход на приветствие и на "Начало"
def switchToBye():
helloWords = ["Пока", "Удачи", "Я всегда тут, буду ждать"]
speaker.speak(random.choice(helloWords))
return "Начало"
# Переход на запрос модуля для перезагрузки и на "Начало":
def switchToReboot():
init(myName)
return "Начало"
# Завершение работы
def turnOff():
raise SystemExit