From 89e9d4e1b2a7a865cce1f081db92ed6b1b36f2d8 Mon Sep 17 00:00:00 2001 From: Roger Light Date: Fri, 14 Feb 2014 17:58:55 +0000 Subject: [PATCH] Add paho.mqtt.publish.multiple() helper function. Change-Id: Ic6a39e870f6ff1db89c78096f8629397bfeb08da --- examples/pub-multiple.py | 33 ++++++++++ examples/pub-single.py | 2 +- setup.py | 2 +- src/paho/mqtt/client.py | 2 +- src/paho/mqtt/publish.py | 131 +++++++++++++++++++++++++++++++++------ 5 files changed, 147 insertions(+), 23 deletions(-) create mode 100755 examples/pub-multiple.py diff --git a/examples/pub-multiple.py b/examples/pub-multiple.py new file mode 100755 index 0000000..54bcd84 --- /dev/null +++ b/examples/pub-multiple.py @@ -0,0 +1,33 @@ +#!/usr/bin/python + +# Copyright (c) 2014 Roger Light +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Distribution License v1.0 +# which accompanies this distribution. +# +# The Eclipse Distribution License is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# Contributors: +# Roger Light - initial implementation + +# This shows an example of using the publish.multiple helper function. + +import sys +try: + import paho.mqtt.publish as publish +except ImportError: + # This part is only required to run the example from within the examples + # directory when the module itself is not installed. + # + # If you have the module installed, just use "import paho.mqtt.publish" + import os + import inspect + cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"../src"))) + if cmd_subfolder not in sys.path: + sys.path.insert(0, cmd_subfolder) + import paho.mqtt.publish as publish + +msgs = [{'topic':"paho/test/multiple", 'payload':"multiple 1"}, ("paho/test/multiple", "multiple 2", 0, False)] +publish.multiple(msgs, hostname="test.mosquitto.org") diff --git a/examples/pub-single.py b/examples/pub-single.py index 9f93225..d127a46 100755 --- a/examples/pub-single.py +++ b/examples/pub-single.py @@ -29,4 +29,4 @@ except ImportError: sys.path.insert(0, cmd_subfolder) import paho.mqtt.publish as publish -publish.single("topic", "boo", hostname="test.mosquitto.org") +publish.single("paho/test/single", "boo", hostname="test.mosquitto.org") diff --git a/setup.py b/setup.py index ebddb1e..dcdbffe 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from sys import version from distutils.core import setup setup(name='paho-mqtt', - version='0.4.92', + version='0.4.93', description='MQTT version 3.1 client class', author='Roger Light', author_email='roger@atchoo.org', diff --git a/src/paho/mqtt/client.py b/src/paho/mqtt/client.py index f3f8858..a57586a 100755 --- a/src/paho/mqtt/client.py +++ b/src/paho/mqtt/client.py @@ -47,7 +47,7 @@ else: VERSION_MAJOR=0 VERSION_MINOR=4 -VERSION_REVISION=0 +VERSION_REVISION=93 VERSION_NUMBER=(VERSION_MAJOR*1000000+VERSION_MINOR*1000+VERSION_REVISION) if sys.version_info[0] < 3: diff --git a/src/paho/mqtt/publish.py b/src/paho/mqtt/publish.py index 5d4ebfd..975418d 100644 --- a/src/paho/mqtt/publish.py +++ b/src/paho/mqtt/publish.py @@ -22,30 +22,70 @@ broker, then disconnect and nothing else is required. import paho.mqtt.client as mqtt -def on_connect(c, userdata, rc): - (topic, msg, qos, retain) = userdata - c.publish(topic, msg, qos, retain) +def _do_publish(c): + """Internal function""" + print(len(c._userdata)) + m = c._userdata[0] + c._userdata = c._userdata[1:] + if type(m) is dict: + topic = m['topic'] + try: + payload = m['payload'] + except KeyError: + payload = None + try: + qos = m['qos'] + except KeyError: + qos = 0 + try: + retain = m['retain'] + except KeyError: + retain = False + elif type(m) is tuple: + (topic, payload, qos, retain) = m + else: + raise ValueError('message must be a dict or a tuple') + c.publish(topic, payload, qos, retain) -def on_publish(c, userdata, mid): - c.disconnect() +def _on_connect(c, userdata, rc): + """Internal callback""" + _do_publish(c) + + +def _on_publish(c, userdata, mid): + """Internal callback""" + if len(userdata) == 0: + c.disconnect() + else: + _do_publish(c) -def single(topic, payload=None, qos=0, retain=False, hostname="localhost", - port=1883, client_id="", keepalive=60, will=None, auth=None, - tls=None): - """Publish a single message to a broker, then disconnect cleanly. + +def multiple(msgs, hostname="localhost", port=1883, client_id="", keepalive=60, + will=None, auth=None, tls=None): + """Publish multiple messages to a broker, then disconnect cleanly. This function creates an MQTT client, connects to a broker and publishes a - single message. Once the message has been delivered, it disconnects cleanly - from the broker. + list of messages. Once the messages have been delivered, it disconnects + cleanly from the broker. - topic : the only required argument must be the topic string to which the - payload will be published. - payload : the payload to be published. If "" or None, a zero length payload - will be published. - qos : the qos to use when publishing, default to 0. - retain : set the message to be retained (True) or not (False). + msgs : a list of messages to publish. Each message is either a dict or a + tuple. + + If a dict, only the topic must be present. Default values will be + used for any missing arguments. The dict must be of the form: + + msg = {'topic':"", 'payload':"", 'qos':, + 'retain':} + topic must be present and may not be empty. + If payload is "", None or not present then a zero length payload + will be published. + If qos is not present, the default of 0 is used. + If retain is not present, the default of False is used. + + If a tuple, then it must be of the form: + ("", "", qos, retain) hostname : a string containing the address of the broker to connect to. Defaults to localhost. port : the port to connect to the broker on. Defaults to 1883. @@ -73,10 +113,13 @@ def single(topic, payload=None, qos=0, retain=False, hostname="localhost", Defaults to None, which indicates that TLS should not be used. """ + if type(msgs) is not list: + raise ValueError('msgs must be a list') + client = mqtt.Client(client_id=client_id, - userdata=(topic, payload, qos, retain)) - client.on_publish = on_publish - client.on_connect = on_connect + userdata=msgs) + client.on_publish = _on_publish + client.on_connect = _on_connect if auth is not None: username = auth['username'] @@ -123,5 +166,53 @@ def single(topic, payload=None, qos=0, retain=False, hostname="localhost", ciphers = None client.tls_set(ca_certs, certfile, keyfile, tls_version=tls_version, ciphers=ciphers) + client.connect(hostname, port, keepalive) client.loop_forever() + + +def single(topic, payload=None, qos=0, retain=False, hostname="localhost", + port=1883, client_id="", keepalive=60, will=None, auth=None, + tls=None): + """Publish a single message to a broker, then disconnect cleanly. + + This function creates an MQTT client, connects to a broker and publishes a + single message. Once the message has been delivered, it disconnects cleanly + from the broker. + + topic : the only required argument must be the topic string to which the + payload will be published. + payload : the payload to be published. If "" or None, a zero length payload + will be published. + qos : the qos to use when publishing, default to 0. + retain : set the message to be retained (True) or not (False). + hostname : a string containing the address of the broker to connect to. + Defaults to localhost. + port : the port to connect to the broker on. Defaults to 1883. + client_id : the MQTT client id to use. If "" or None, the Paho library will + generate a client id automatically. + keepalive : the keepalive timeout value for the client. Defaults to 60 + seconds. + will : a dict containing will parameters for the client: will = {'topic': + "", 'payload':", 'qos':, 'retain':}. + Topic is required, all other parameters are optional and will + default to None, 0 and False respectively. + Defaults to None, which indicates no will should be used. + auth : a dict containing authentication parameters for the client: + auth = {'username':"", 'password':""} + Username is required, password is optional and will default to None + if not provided. + Defaults to None, which indicates no authentication is to be used. + tls : a dict containing TLS configuration parameters for the client: + dict = {'ca_certs':"", 'certfile':"", + 'keyfile':"", 'tls_version':"", + 'ciphers':"} + ca_certs is required, all other parameters are optional and will + default to None if not provided, which results in the client using + the default behaviour - see the paho.mqtt.client documentation. + Defaults to None, which indicates that TLS should not be used. + """ + + msg = {'topic':topic, 'payload':payload, 'qos':qos, 'retain':retain} + multiple([msg], hostname, port, client_id, keepalive, will, auth, tls) + -- 2.39.5