2022-05-16 08:48:01 +00:00
# Модуль машины состояний (конечный автомат)
import speaker # Для разговоров
import datetime # Для времени
2022-05-16 09:33:50 +00:00
from pyowm import OWM # Использование OpenWeatherMap для получения данных о погоде (pip install pyowm)
import random
2022-05-16 10:09:04 +00:00
import traceback # вывод traceback без остановки работы программы при отлове исключений
2022-05-16 08:48:01 +00:00
machine = None # Конечный автомат
current_state = None # Текущее состояние
weather_api_key = None # Ключ для OpenWeatherMap
2022-05-16 09:44:51 +00:00
myName = None # Имя ассистента
2022-05-16 08:48:01 +00:00
def init ( assistant_name ) :
""" Инициализирует конечный автомат """
global machine
global current_state
global weather_api_key
2022-05-16 09:44:51 +00:00
global myName
myName = assistant_name
2022-05-16 08:48:01 +00:00
with open ( " weatherApiKey.txt " , " r " ) as key :
weather_api_key = key . read ( )
current_state = " Начало "
machine = {
" Начало " : {
assistant_name . lower ( ) : switchToListen
} ,
" Слушаю задание " : {
" время " : switchToTime ,
2022-05-16 09:33:50 +00:00
" погода " : switchToWeather ,
" привет " : switchToHello ,
" здравствуй " : switchToHello ,
" доброе утро " : switchToHello ,
" добрый день " : switchToHello ,
" добрый вечер " : switchToHello ,
" доброй ночи " : switchToHello ,
" пока " : switchToBye ,
2022-05-16 09:44:51 +00:00
" до встречи " : switchToBye ,
" перезапуск " : switchToReboot ,
" завершение работы " : turnOff
} ,
2022-05-16 08:48:01 +00:00
}
2022-05-16 09:44:51 +00:00
switchToHello ( )
speaker . speak ( f " Ассистент { myName } начинает работу " )
2022-05-16 08:48:01 +00:00
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 ] ( )
2022-05-16 10:05:29 +00:00
elif ( current_state != ' Начало ' ) :
2022-05-16 08:48:01 +00:00
# иначе переспросим
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
2022-05-16 10:02:59 +00:00
# speaker.speak("Дома?")
# word = input().lower() # Пока считаем с клавиатуры предложение
# if (word == "да"):
# location = "Home"
# else:
# speaker.speak("Назовите локацию")
# location = input().lower() # Пока считаем с клавиатуры предложение
location = " Murino,RU "
2022-05-16 08:48:01 +00:00
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
2022-05-16 10:02:59 +00:00
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} миллиметров ртутного столба")
2022-05-16 08:48:01 +00:00
2022-05-16 09:33:50 +00:00
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 ) )
2022-05-16 09:44:51 +00:00
return " Начало "
# Переход на запрос модуля для перезагрузки и на "Начало":
def switchToReboot ( ) :
init ( myName )
return " Начало "
# Завершение работы
def turnOff ( ) :
raise SystemExit