diff --git a/README.md b/README.md index 318b3c02117165fd1ac6e24730a209771baf2759..1bb1c2ecf502d0e296ec48237fe70b793b4e2b99 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,10 @@ Parameters under `mqtt` section are used for creating paho's `mqtt.Client` and i See `mqtt_bridge.mqtt_client` for detail. +### mqtt private path + +If `mqtt/private_path` parameter is set, leading `~/` in MQTT topic path will be replaced by this value. For example, if `mqtt/pivate_path` is set as "device/001", MQTT path "~/value" will be converted to "device/001/value". + ### selializer and deselializer `mqtt_bridge` uses `json` as a selializer in default. But you can also configure other selializers. For example, if you want to use messagepack for selialization, add following configuration. diff --git a/config/demo_params.yaml b/config/demo_params.yaml index e6fa3de44cf5442213dad2f49b85e9f12c22dfa3..6ac90efdfb394134814e38912dd717ba6193263a 100644 --- a/config/demo_params.yaml +++ b/config/demo_params.yaml @@ -5,6 +5,7 @@ mqtt: host: localhost port: 1883 keepalive: 60 + private_path: device/001 selializer: msgpack:dumps deselializer: msgpack:loads bridge: @@ -26,3 +27,12 @@ bridge: msg_type: std_msgs.msg:String topic_from: echo topic_to: /back + # private path + - factory: mqtt_bridge.bridge:RosToMqttBridge + msg_type: std_msgs.msg:String + topic_from: /private/echo + topic_to: ~/echo + - factory: mqtt_bridge.bridge:MqttToRosBridge + msg_type: std_msgs.msg:String + topic_from: ~/echo + topic_to: /private/back diff --git a/src/mqtt_bridge/app.py b/src/mqtt_bridge/app.py index ad627a2508a7ee5e1fe8bd76ea1ff10e92a5223f..7f5a1dfa52929a73baae0880701dcad56e233ebc 100644 --- a/src/mqtt_bridge/app.py +++ b/src/mqtt_bridge/app.py @@ -6,18 +6,21 @@ import paho.mqtt.client as mqtt import rospy from .bridge import create_bridge +from .mqtt_client import create_private_path_extractor from .util import lookup_object -def create_config(mqtt_client, selializer, deselializer): +def create_config(mqtt_client, selializer, deselializer, mqtt_private_path): if isinstance(selializer, basestring): selializer = lookup_object(selializer) if isinstance(deselializer, basestring): deselializer = lookup_object(deselializer) + private_path_extractor = create_private_path_extractor(mqtt_private_path) def config(binder): binder.bind('selializer', selializer) binder.bind('deselializer', deselializer) binder.bind(mqtt.Client, mqtt_client) + binder.bind('mqtt_private_path_extractor', private_path_extractor) return config @@ -29,6 +32,7 @@ def mqtt_bridge_node(): params = rospy.get_param("~", {}) mqtt_params = params.pop("mqtt", {}) conn_params = mqtt_params.pop("connection") + mqtt_private_path = mqtt_params.pop("private_path", "") bridge_params = params.get("bridge", []) # create mqtt client @@ -42,7 +46,8 @@ def mqtt_bridge_node(): deselializer = params.get('deselializer', 'json:loads') # dependency injection - config = create_config(mqtt_client, selializer, deselializer) + config = create_config( + mqtt_client, selializer, deselializer, mqtt_private_path) inject.configure(config) # configure and connect to MQTT broker diff --git a/src/mqtt_bridge/bridge.py b/src/mqtt_bridge/bridge.py index e87f2548cc43badadee1b597e50dc2ea0040c5cd..2aa22d9a3fba8f696b18e19c78ed055fea1f08b8 100644 --- a/src/mqtt_bridge/bridge.py +++ b/src/mqtt_bridge/bridge.py @@ -46,6 +46,7 @@ class Bridge(object): _mqtt_client = inject.attr(mqtt.Client) _selialize = inject.attr('selializer') _deselialize = inject.attr('deselializer') + _extract_private_path = inject.attr('mqtt_private_path_extractor') class RosToMqttBridge(Bridge): @@ -59,7 +60,7 @@ class RosToMqttBridge(Bridge): def __init__(self, topic_from, topic_to, msg_type, frequency=None): self._topic_from = topic_from - self._topic_to = topic_to + self._topic_to = self._extract_private_path(topic_to) self._last_published = rospy.get_time() self._interval = 0 if frequency is None else 1.0 / frequency rospy.Subscriber(topic_from, msg_type, self._callback_ros) @@ -88,7 +89,7 @@ class MqttToRosBridge(Bridge): def __init__(self, topic_from, topic_to, msg_type, frequency=None, queue_size=10): - self._topic_from = topic_from + self._topic_from = self._extract_private_path(topic_from) self._topic_to = topic_to self._msg_type = msg_type self._queue_size = queue_size diff --git a/src/mqtt_bridge/mqtt_client.py b/src/mqtt_bridge/mqtt_client.py index 3093c0e820580d7827fdb9087cd225c4853c28cf..bf4498a095a82b000db5b7d7e948bef6388a63b8 100644 --- a/src/mqtt_bridge/mqtt_client.py +++ b/src/mqtt_bridge/mqtt_client.py @@ -53,4 +53,12 @@ def default_mqtt_client_factory(params): return client -__all__ = ["default_mqtt_client_factory"] +def create_private_path_extractor(mqtt_private_path): + def extractor(topic_path): + if topic_path.startswith('~/'): + return '{}/{}'.format(mqtt_private_path, topic_path[2:]) + return topic_path + return extractor + + +__all__ = ['default_mqtt_client_factory', 'create_private_path_extractor']