diff --git a/jsk_robot_common/jsk_robot_startup/README.md b/jsk_robot_common/jsk_robot_startup/README.md index 34c13cdab5..ab240ab2d1 100644 --- a/jsk_robot_common/jsk_robot_startup/README.md +++ b/jsk_robot_common/jsk_robot_startup/README.md @@ -302,16 +302,28 @@ flowchart TB Tweet message with description and image +* `/google_chat_ros/send/goal` (`google_chat_ros/SendMessageActionGoal`) + + Send google chat message with description and image. + ### Parameters * `~sender_address` (String) - + Sender address * `~receiver_address` (String) Receiver address +* `~google_chat_space` (String) + + Receiver Google Chat space name + +* `~google_chat_tmp_image_dir` (String) + + Directory where images are temporarily stored for google_chat_ros + ## launch/safe_teleop.launch This launch file provides a set of nodes for safe teleoperation common to mobile robots. Robot-specific nodes such as `/joy`, `/teleop` or `/cable_warning` must be included in the teleop launch file for each robot, such as [safe_teleop.xml for PR2](https://github.com/jsk-ros-pkg/jsk_robot/blob/master/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_move_base/safe_teleop.xml) or [safe_teleop.xml for fetch](https://github.com/jsk-ros-pkg/jsk_robot/blob/master/jsk_fetch_robot/jsk_fetch_startup/launch/fetch_teleop.xml). diff --git a/jsk_robot_common/jsk_robot_startup/launch/smach_to_mail.launch b/jsk_robot_common/jsk_robot_startup/launch/smach_to_mail.launch new file mode 100644 index 0000000000..3e30979924 --- /dev/null +++ b/jsk_robot_common/jsk_robot_startup/launch/smach_to_mail.launch @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + use_mail: $(arg use_mail) + use_twitter: $(arg use_twitter) + use_google_chat: $(arg use_google_chat) + + + + diff --git a/jsk_robot_common/jsk_robot_startup/package.xml b/jsk_robot_common/jsk_robot_startup/package.xml index 4f28e01411..c86b879736 100644 --- a/jsk_robot_common/jsk_robot_startup/package.xml +++ b/jsk_robot_common/jsk_robot_startup/package.xml @@ -24,6 +24,7 @@ dynamic_reconfigure geometry_msgs gmapping + google_chat_ros jsk_recognition_msgs jsk_topic_tools message_runtime diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py index c481c7243e..1fda55567b 100755 --- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py +++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +import actionlib import base64 import cv2 import datetime @@ -8,6 +9,11 @@ import sys from cv_bridge import CvBridge +from google_chat_ros.msg import Card +from google_chat_ros.msg import Section +from google_chat_ros.msg import SendMessageAction +from google_chat_ros.msg import SendMessageActionGoal +from google_chat_ros.msg import WidgetMarkup from jsk_robot_startup.msg import Email from jsk_robot_startup.msg import EmailBody from sensor_msgs.msg import CompressedImage @@ -21,6 +27,9 @@ def __init__(self): rospy.init_node('server_name') # it should be 'smach_to_mail', but 'server_name' # is the default name of smach_ros + self.use_mail = rospy.get_param("~use_mail", True) + self.use_twitter = rospy.get_param("~use_twitter", True) + self.use_google_chat = rospy.get_param("~use_google_chat", True) self.pub_email = rospy.Publisher("email", Email, queue_size=10) self.pub_twitter = rospy.Publisher("tweet", String, queue_size=10) rospy.Subscriber( @@ -38,7 +47,11 @@ def __init__(self): else: rospy.logerr("Please set rosparam {}/receiver_address".format( rospy.get_name())) - + if self.use_google_chat: + self.gchat_ac = actionlib.SimpleActionClient("/google_chat_ros/send", SendMessageAction) + self.chat_space = rospy.get_param("~google_chat_space") + self.gchat_image_dir = rospy.get_param("~google_chat_tmp_image_dir", "/tmp") + self._gchat_thread = None def _status_cb(self, msg): ''' @@ -125,8 +138,12 @@ def _status_cb(self, msg): for x in self.smach_state_list[caller_id]: rospy.loginfo(" - At {}, Active state is {}{}".format(x['TIME'], x['STATE'], "({})".format(x['INFO']) if x['INFO'] else '')) - self._send_mail(self.smach_state_subject[caller_id], self.smach_state_list[caller_id]) - self._send_twitter(self.smach_state_subject[caller_id], self.smach_state_list[caller_id]) + if self.use_mail: + self._send_mail(self.smach_state_subject[caller_id], self.smach_state_list[caller_id]) + if self.use_twitter: + self._send_twitter(self.smach_state_subject[caller_id], self.smach_state_list[caller_id]) + if self.use_google_chat: + self._send_google_chat(self.smach_state_subject[caller_id], self.smach_state_list[caller_id]) self.smach_state_list[caller_id] = None def _send_mail(self, subject, state_list): @@ -205,6 +222,37 @@ def _send_twitter(self, subject, state_list): if len(text) > 1: self.pub_twitter.publish(String(text)) + def _send_google_chat(self, subject, state_list): + self.gchat_ac.wait_for_server() + goal = SendMessageActionGoal() + if subject: + goal.goal.text = subject + card = Card() + for i, x in enumerate(state_list): + section = Section() + widget = WidgetMarkup() + if 'DESCRIPTION' in x: + text = x['DESCRIPTION'] + section.header = text + if 'IMAGE' in x and x['IMAGE']: + path = os.path.join(self.gchat_image_dir, 'smach_gchat_{}.png'.format(i)) + with open(path, "wb") as f: + f.write(base64.b64decode(x['IMAGE'])) + widget.image.localpath = path + if section.header and widget.image.localpath: + section.widgets.append(widget) + card.sections.append(section) + goal.goal.cards.append(card) + goal.goal.space = self.chat_space + if self._gchat_thread: + goal.goal.thread_name = self._gchat_thread + self.gchat_ac.send_goal(goal.goal) + self.gchat_ac.wait_for_result() + result = self.gchat_ac.get_result() + if not self._gchat_thread: + self._gchat_thread = result.message_result.thread_name + rospy.loginfo("Sending google chat messsage: {} to {} chat space".format(text, self.chat_space)) + rospy.logdebug("Google Chat result: {}".format(self.gchat_ac.get_result())) if __name__ == '__main__': stm = SmachToMail()