Голосовое управление освещением X10 (см. Часть1, Часть2, Часть3, Часть4) и Голосовое оповещение для дома. Будильник в системе ROS являются частью умного дома на ROS.
Добавим в эту систему получение данных с сервера домашней метеостанции (здесь и добавление функционала).
При произнесении фразы «Погода» — компьютор должен голосом сообщить данные о температуре воздуха на улице, влажности воздуха и атмосферного давления. Сервер домашней метеостанции при обращении к нему по адресу в домашней сети (192.168.1.111:10001) отдает показания в формате JSON.
Сначала в проекте vp_x10_voice создадим дополнительный узел node_x10_alarm_weather_meteo1, который будет являться слушателем (subscriber) темы x10_alarm_weather, в тему публикуются данные std_msgs/Int16 — числовой аргумент (номер датчика ), узел обращается к серверу домашней метеостанции, расположенному в сети, получает данные в формате JSON, выбирает данные для нужного датчика и формирует фразу (строку std_msgs/String). Далее фраза публикуется в тему x10_alarm_festival для произнесения фразы голосом (см. Голосовое оповещение для дома. Будильник в системе ROS).
К примеру мы произносим фразу «погода улица», узел node_x10_voicetotext распознает ее и отправляет сообщение в тему x10_alarm_weather, считываются данные по запросу к серверу домашней метеостанции и формируется фраза, например «Температура воздуха 17 градусов относительная влажность 60 процентов», фраза публикуется в тему x10_alarm_festival и программа festival произносит эту фразу голосом.
Меня интересуют данные
temp4 — температура на улице с датчика DH11
humidity4 — влажность на улице с датчика DH11
pressure5 — атмосферное давление
Предусмотрим в программе этот момент (формирование фразы для festival для данных с разных датчиков). Пишем скрипт node_x10_weather_meteo1_sub.py
#!/usr/bin/env python
#-*-coding:utf-8 -*-
#
# Слушатель x10_weather
# по запросу в тему x10_alarm_weather
# получение данных с сервера домашней метеостанции
# и отправка данных для голосового сообщения
# в тему x10_alarm_festival
#
import roslib; roslib.load_manifest(‘vp_x10_voice’)
import rospy
import subprocess
import shlex
import urllib2
import json
from std_msgs.msg import String
from std_msgs.msg import Int16
URL_METEO=»http://192.168.0.111:10001″
def controller(data):
number = data.data
pub1 = rospy.Publisher(‘x10_alarm_festival’, String)
message=»»
global temps
global humiditys
global pressures
res=urllib2.urlopen(URL_METEO).read()
data_sensors=json.loads(res)
if number==1 :
try:
temps=data_sensors[‘meteo’][‘temp1’]
tt=int(float(temps)+0.5)
message=»Температура воздуха «+str(tt)+» градусов»
except ValueError:
message=»Ошибка считывания с датчика температуры 1 »
elif number==2 :
try:
temps=data_sensors[‘meteo’][‘temp2’]
tt=int(float(temps)+0.5)
message=»Температура воздуха «+str(tt)+» градусов»
except ValueError:
message=»Ошибка считывания с датчика температуры 2 »
elif number==3 :
try:
temps=data_sensors[‘meteo’][‘temp3’]
tt=int(float(temps)+0.5)
message=»Температура воздуха «+str(tt)+» градусов»
except ValueError:
message=»Ошибка считывания с датчика температуры 3 »
elif number==4 :
try:
temps=data_sensors[‘meteo’][‘temp4’]
humiditys=data_sensors[‘meteo’][‘humidity4’]
tt=int(float(temps)+0.5)
dd=int(float(humiditys)+0.5)
message=»Температура воздуха «+str(tt)+» градусов»
message+=» относительная влажность «+str(dd)+» процентов»
except ValueError:
message=»Ошибка считывания с датчиков 4 »
elif number==5 :
try:
temps=data_sensors[‘meteo’][‘temp5’]
pressures=data_sensors[‘meteo’][‘pressure5’]
tt=int(float(temps)+0.5)
pp=int(float(pressures)+0.5)
message=»Температура воздуха «+str(tt)+» градусов»
message+=» давление «+str(dd)+» миллиметров ртутного столба»
except ValueError:
message=»Ошибка считывания с датчиков 5 »
elif number==99 : #запрос по голосу Погода
try:
temps=data_sensors[‘meteo’][‘temp5’]
pressures=data_sensors[‘meteo’][‘pressure5’]
humiditys=data_sensors[‘meteo’][‘humidity4’]
tt=int(float(temps)+0.5)
dd=int(float(humiditys)+0.5)
pp=int(float(pressures)+0.5)
message=»Температура воздуха «+str(tt)+» градусов»
message+=» относительная влажность «+str(dd)+» процентов»
message+=» давление «+str(dd)+» миллиметров ртутного столба»
except ValueError:
message=»Ошибка считывания с датчиков »
#temps=[meteo1[‘temp3’] for meteo1 in data_sensors[‘meteo’]]
rospy.loginfo(temps)
pub1.publish(message)
def listener():
rospy.init_node(‘node_x10_alarm_weather_meteo1’)
sub = rospy.Subscriber(«x10_alarm_weather»,Int16,controller)
rospy.spin()
if __name__ == ‘__main__’:
listener()
Теперь необходимо добавить в скрипт node_x10_voicetotext.py распознование фразы «погода» и отправка сообщения ( std_msgs/Int16 =99) в тему x10_alarm_weather.
Измененный скрипт node_x10_voicetotext.py:
#!/usr/bin/env python
#-*-coding:utf-8 -*-
import roslib; roslib.load_manifest(‘vp_x10_voice’)
import rospy
import subprocess
import shlex
from std_msgs.msg import String
from std_msgs.msg import Int16
fraza=[«люстра»,»лента»,»лампа»,»ночник»,»елка»,
«люстра включить»,»лента гори»,»лампа включить»,»ночник включить»,»елка гори»,
«отбой»,
«программа 1″,»программа 2″,»программа 3″,»программа 4″,»программа 5»,
«погода»]
matrix = [[«люстра»,»быстро»],
[«лента»],
[«лампа»,»лапа»],
[«ночник»,»начни»],
[«елка»,»елочка»],
[«люстра включить»,»люстра ключи»,»быстро включить»],
[«лента гори»,»mp3″],
[«лампа включить»,»лампа включи»,»лампа ключи»],
[«ночник ключи»,»ночник включить»,»ночник включи»,»ночник горит»,»ночник гори»],
[«елка гори»,»елочка гори»,»елка горит»],
[«отбой»,»всем спать»,»я спать»],
[«программа 1″,»драма 1»],
[«программа 2″,»драма 2»],
[«программа 3″,»драма 3″,»программа тв»],
[«программа 4″,»драма 4»],
[«программа 5″,»драма 5»],
[«погода»]]
def talker():
pub1 = rospy.Publisher(‘x10_voicetotext’, Int16)
pub2 = rospy.Publisher(‘x10_alarm_weather’, Int16)
rospy.init_node(‘node_x10_voicetotext’)
while not rospy.is_shutdown():
rospy.loginfo(«ожидание записи с микрофона»)
subprocess.Popen(‘rec -q -c 1 -r 16000 current.wav silence 1 0.2 3% 1 0.2 3%’,shell=True,cwd = ‘/home/petin/ros_pkgs/vp_x10_voice/nodes/’).communicate()
rospy.loginfo(«wav — ok»)
subprocess.Popen(‘flac -f -s current.wav -o current.flac’,shell=True,cwd = ‘/home/petin/ros_pkgs/vp_x10_voice/nodes/’).communicate()
rospy.loginfo(«flac — ok»)
proc3=subprocess.Popen(‘php textfromgoogle.php’,shell=True, stdout = subprocess.PIPE,cwd = ‘/home/petin/ros_pkgs/vp_x10_voice/nodes/’)
result=proc3.communicate()[0]
str1 = «result api google = %s»%result
rospy.loginfo(str1)
str2=»»
index=0
for ind,elements in enumerate(matrix):
for element in elements:
if result.count(element)>0:
str2=fraza[ind]
index=ind+1
if(index=17):
pub2.publish(99)
rospy.loginfo(str2)
elif(index>0):
pub1.publish(index)
rospy.loginfo(str2)
if __name__ == ‘__main__’:
try:
talker()
except rospy.ROSInterruptException: pass
Теперь при запуске дополнительного узла
$ rosrun vp_x10_voice node_x10_weather_meteo1_sub.py
и произнесении фразы «погода», компьютер выдает голосовое сообщение вида «Температура воздуха XX градусов относительная влажность YY процентов давление ZZZ миллиметров ртутного столба».
В прикрепленном файле архив с проектом vp_x10_voice для ROS.
Прикрепленные файлы:
- vp_x10_voice2.tar (5680 Кб)