# Модуль машины состояний (конечный автомат) import speaker # Для воспроизведения import listener # Для распознавание речи 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 listener.init_listener() # Инициализация распозавания 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() # Пока считаем с клавиатуры предложение word = listener.recognize() # Слушаем и распознаем # Если ассистент знает такое слово для перехода if (word in machine[current_state].keys()): # Выполняем действия и переход в новое состояние current_state = machine[current_state][word]() elif (current_state != 'Начало'): # иначе переспросим speaker.speak("Я не понял, пожалуйста повторите") print("Сейчас автомат в: " + current_state + ". Я услышал: " + word) # Переход на "Слушаю задание" 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