157 lines
6.2 KiB
Python
157 lines
6.2 KiB
Python
# Модуль машины состояний (конечный автомат)
|
||
|
||
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 |