В этих статьях — Часть1, Часть 2, Часть 3 и Часть 4 я рассматривал голосовое управление приборами X10 через ROS. Добавим к данной системе будильник с голосовым оповещением.
Задача ставилась следующая — для каждой записи будильника установить:
время срабатывания
количество повторений срабатывания и интервал
дни недели для данного будильника
действия по срабатыванию будильника, пока такие:
голосовое оповещение
запуск короткого музыкального файла (рингтона)
отправка команд для управления приборами x10
Скрипт node_x10_alarm_pub.py создает узел node_x10_alarm_events, который будет ожидать время срабатывания (либо повторного оповещения) будильников. Список будильников находится в двумерном массиве alarm_events
Для каждой записи, например
[«06:20″,3,5,[0,1,2,3,4],{1:»rington6.mp3;17»,2:»Подъём пора на работу, вставай Виктор Александрович «,4:»12»}],
06:20 — время срабатывания
3 — количество повторений
5 мин — интервал между повторениями
дни недели (0-4 — понедельник — пятница)
действия
1 — публикация в тему x10_alarm_mediaplayer (имя звукового файла) для запуска медиапроигрывателя
2 — публикация в тему x10_alarm_festival голосовое сообщение (запуск программы festival)
3 — получение текущего времени и публикация в тему x10_alarm_festival для голосового сообщения (запуск программы festival)
4 — публикация в тему x10_voicetotext посылка команды для приборов x10 в тему
Перед голосовым оповещением о текущем времени, время переводится в строковое сообщение а затем строка отправляется в тему x10_alarm_festival.
Запуск узла node_x10_alarm_pub.py
rosrun vp_x10_voice node_x10_alarm_pub.py
Содержимое файла node_x10_alarm_pub.py
#!/usr/bin/env python #-*-coding:utf-8 -*- # # Ожидание событий будильника # # и отправка команд в темы для # x10, festival(голос), медиаплейер(музыка),x10 (свет x10) # import roslib; roslib.load_manifest('vp_x10_voice') import rospy import subprocess import shlex import time from datetime import datetime, timedelta from std_msgs.msg import String from std_msgs.msg import Int16 alarm_events=[ ["06:30",2,5,[0,1,2,3,4,5,6],{1:"rington2.mp3;23",2:"Надо прогулять Графа "}], ["06:15",3,3,[0,1,2,3,4,5,6],{1:"rington6.mp3;17",2:"Подъём пора на работу, вставай Виктор Александрович "},4:"12"], ["9:20",500,1,[0,1,2,3,4,5,6],{1:"rington6.mp3;19",3:"Время "}], ["18:30",2,5,[0,1,2,3,4,5,6],{1:"rington2.mp3;23",2:"Надо прогулять Графа "}], ["23:00",2,5,[0,1,2,3,4,5,6],{1:"rington2.mp3;23",2:"Надо прогулять Графа "}], ]; name_hours=[ [{1,21},"час"], [{2,3,4,22,23},"часа"], [{5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20},"часов"], ] name_minutes=[ [{1,21,31,41,51},"минута"], [{2,3,4,22,23,24,32,33,34,42,43,44,52,53,54},"минуты"], [{5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,25,26,27,28,29,30,35,36,37,38,39,40,45,46,47,48,49,50,55,56,57,58,59},"минут"], ] def my_alarm(): pub1 = rospy.Publisher('x10_alarm_mediaplayer',String) pub2 = rospy.Publisher('x10_alarm_festival', String) rospy.init_node('node_x10_alarm_events') d=datetime.today() dh=d.hour;dm=d.minute; while not rospy.is_shutdown(): d=datetime.today() if(d.hour!=dh or d.minute!=dm): for element in alarm_events: for dt in range(element[1]): # кол-во повторений element[1] alarm_time=element[0] dminutes=dt*element[2] # промежуток повторения dd=timedelta(minutes=dminutes) d1=d-dd if(d.hour<10): this_time="0"+str(d.hour) else: this_time=str(d.hour) if(d.minute<10): this_time+=":0"+str(d.minute) else: this_time+=":"+str(d.minute) #this_time=str(d.hour)+":"+str(d.minute) cor_this_time=str(d1.hour)+":"+str(d1.minute) #rospy.loginfo(this_time) try: element[3].index(d.weekday()) if (alarm_time==cor_this_time): rospy.loginfo("!!!!!!!!!!!!==="+alarm_time+"---"+this_time) for key in element[4]: if key==1: rington_file=element[4][key].split(";")[0]; pub1.publish(rington_file) time.sleep(int(element[4][key].split(";")[1])) rospy.loginfo("program 1 ") elif key==2: pub2.publish(element[4][key]) time.sleep(5) rospy.loginfo("program 2 ") elif key==3: for ho in name_hours: if d.hour in ho[0]: strtime1= str(d.hour)+" "+ho[1] break if d.minute>0: for mi in name_minutes: if d.minute in mi[0]: strtime2=" "+str(d.minute)+" "+mi[1] break strtime2=strtime2.replace("01","одна") strtime2=strtime2.replace("21","двадцать одна") strtime2=strtime2.replace("31","тридцать одна") strtime2=strtime2.replace("41","сорок одна") strtime2=strtime2.replace("51","пятьдесят одна") strtime2=strtime2.replace("02","две") strtime2=strtime2.replace("22","двадцать две") strtime2=strtime2.replace("32","тридцать две") strtime2=strtime2.replace("42","сорок две") strtime2=strtime2.replace("52","пятьдесят две") pub2.publish(element[4][key]+strtime1+strtime2) time.sleep(5) rospy.loginfo("program 3 ") elif key==4: pub4.publish(int(element[4][key])) time.sleep(1) rospy.loginfo("program 4 ") else: pass except ValueError: pass dh=d.hour;dm=d.minute; else: time.sleep(10) if __name__ == '__main__': try: my_alarm() except rospy.ROSInterruptException: pass
Теперь создаем два узла subscriber — получателей сообщений из тем x10_alarm_festival и x10_alarm_mediaplayer.
Узел node_x10_alarm_mediaplayer получает сообщение String из темы nx10_alarm_mediaplayer и запускает программу проигрывания звуковых файлов. Я запускаю программу smplayer, можно любой проигрыватель.
Содержимое файла node_x10_mediaplayer_sub.py
#!/usr/bin/env python #-*-coding:utf-8 -*- # # Слушатель x10_mediaplayer # # и запуск медиапроигрывателя # # import roslib; roslib.load_manifest('vp_x10_voice') import rospy import subprocess import shlex from std_msgs.msg import String PATH_RINGTONS="ros_pkgs/vp_x10_voice/nodes/ringtons/" def controller(data): rington_file = data.data command1='smplayer "' command1+=PATH_RINGTONS+rington_file+'"' subprocess.Popen(command1,shell=True).communicate() rospy.loginfo(command1) def listener(): rospy.init_node('node_x10_alarm_mediaplayer') sub = rospy.Subscriber("x10_alarm_mediaplayer",String,controller) rospy.spin() if __name__ == '__main__': listener()
Узел node_x10_alarm_festival получает сообщение String из темы x10_alarm_festival и запускает программу festival.
Содержимое файла node_x10_festival_sub.py
#!/usr/bin/env python #-*-coding:utf-8 -*- # # Слушатель x10_festival # # и произношение голосом # import roslib; roslib.load_manifest('vp_x10_voice') import rospy import subprocess import shlex from std_msgs.msg import String def controller(data): fraza = data.data #command1="festival -b '(begin (SayText " #command1+='"'+fraza+'"' #command1+="))'" command1='echo "' command1+=fraza+'"' command1+=" | festival --language russian --tts" subprocess.Popen(command1,shell=True).communicate() rospy.loginfo(command1) def listener(): rospy.init_node('node_x10_alarm_festival') sub = rospy.Subscriber("x10_alarm_festival",String,controller) rospy.spin() if __name__ == '__main__': listener()
Для управления приборами X10 запускаем узел node_x10_texttocommand
rosrun vp_x10_voice node_x10_texttocommand.py
и посылаем в него номер сценария из массива arr_commands файла node_x10_texttocommand.py
Составляем список пробных будильников
Запускаем
1 терминал
roscore
2 терминал
rosrun vp_x10_voice node_x10_alarm_pub.py
3 терминал
rosrun vp_x10_voice node_x10_festival_sub.py
4 терминал
rosrun vp_x10_voice node_x10_mediaplayer_sub.py
5 терминал
rosrun vp_x10_voice node_x10_texttocommand.py
Файлы проекта можно скачать в репозитории