# Модуль машины состояний (конечный автомат) import speaker # Для разговоров import datetime # Для времени from pyowm import OWM # Использование OpenWeatherMap для получения данных о погоде (pip install pyowm) import random machine = None # Конечный автомат current_state = None # Текущее состояние weather_api_key = None # Ключ для OpenWeatherMap def init(assistant_name): """Инициализирует конечный автомат""" global machine global current_state global weather_api_key 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 } } def work(): """Обрабатывает конечный автомат""" global machine global current_state speaker.speak(f"Доброго времени суток! Ассистент начинает работу") while(True): word = input().lower() # Пока считаем с клавиатуры предложение # Если ассистент знает такое слово для перехода if (word in machine[current_state].keys()): # Выполняем действия и переход в новое состояние current_state = machine[current_state][word]() else: # иначе переспросим 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() # Пока считаем с клавиатуры предложение 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 = weather.temperature('celsius')["temp"] wind_speed = weather.wind()["speed"] pressure = int(weather.pressure["press"] / 1.333) # переведено из гПА в мм рт.ст. speaker.speak(f"Сейчас на улице {temperature} градусов, скорость ветра {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 "Начало"