I've been trying to find answers or info about this question but without results yet. The idea is to publish the same topic into two different MQTT servers with python. I mean, something like this:
import paho.mqtt.client as paho
import datetime, time
mqttc = paho.Client()
host1 = "broker.hivemq.com" # the address of 1st mqtt broker
host2 = "192.168.1.200" # the address of 2nd mqtt broker
topic= "testingTopic"
port = 1883
def on_connect(mosq, obj, rc):
print("on_connect() "+str(rc))
mqttc.on_connect = on_connect
print("Connecting to " + host)
mqttc.connect(host1, port, 60)
mqttc.connect(host2, port, 60)
while 1:
# publish some data at a regular interval
now = datetime.datetime.now()
mqttc.publish(topic, now.strftime('%H:%M:%S')) #Publishing to MQTT1
mqttc.publish(topic, now.strftime('%H:%M:%S')) #Publishing to MQTT2
time.sleep(1)
So, the question is about the while statment... how can I do to publish the same topic into MQTT1 and MQTT2?
As you can see, I want to have to posibility to publish that payload in MQTT broker that is running in internet, but if I lose internet connection, then I can pub/sub to MQTT broker in my LAN.
You can't just connect the same client to 2 different brokers. You need 2 separate instances of the of the client that you connect to the separate brokers.
...
mqttc1 = paho.Client()
mqttc2 = paho.Client()
...
mqttc1.connect(host1, port, 60)
mqttc2.connect(host2, port, 60)
...
mqttc1.publish(topic, now.strftime('%H:%M:%S')) #Publishing to MQTT1
mqttc2.publish(topic, now.strftime('%H:%M:%S')) #Publishing to MQTT2
Related
It's my first time trying to connect to a mqtt broker and it's not really going great. I've been trying to get data from the broker but am unable to figure out how to connect. I've been handed a username, password, port and encrypted port aswell as "Topics. When trying to connect the "client.connect"-line responds with "0". I changed the username and password and I still get the same result so there is something wrong with my configuration. Any help would be much appreciated!
I'm running python 3.6.5
import paho.mqtt.client as mqtt
import time
username="temp"
password="temp"
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("extapi/data/esm")
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set(username, password)
client.connect("example.io", 1883, 60)
I want to test the mosquitto MQTT Python client ports.
import json
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
"""Called when connected to MQTT broker."""
client.subscribe("hermes/intent/#")
client.subscribe("hermes/nlu/intentNotRecognized")
print("Connected. Waiting for intents.")
def on_disconnect(client, userdata, flags, rc):
"""Called when disconnected from MQTT broker."""
client.reconnect()
def on_message(client, userdata, msg):
"""Called each time a message is received on a subscribed topic."""
nlu_payload = json.loads(msg.payload)
if msg.topic == "hermes/nlu/intentNotRecognized":
sentence = "Unrecognized command!"
print("Recognition failure")
else:
# Intent
print("Got intent:", nlu_payload["intent"]["intentName"])
# Speak the text from the intent
sentence = nlu_payload["input"]
site_id = nlu_payload["siteId"]
client.publish("hermes/tts/say", json.dumps({"text": sentence, "siteId": site_id}))
# Create MQTT client and connect to broker
client = mqtt.Client()
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message
client.connect("localhost", 1883)
client.loop_forever()
I run it with the command
$ python script.py`
Connected. Waiting for intents.
Does mosquitto send a POST request? or do I have to start a request with mosquitto? How should I create a request so that I get
Got intent: SetTimer
MQTT is not HTTP, POST is a HTTP verb that has no meaning in a MQTT context.
MQTT is a pub/sub protocol, where as HTTP is a request/response protocol.
The code you have posted only subscribes to 2 topics, it doesn't publish anything (until it receives a message). So unless you have another application that will publish a message to 1 of the 2 topics the python code has subscribed to it will just sit there and wait for a message.
You can use the mosquitto command line tools to send a message if needed. e.g.
mosquitto_pub -t hermes/intent/foo -m '{"intent": { "intentName": "SetTimer"}}'
Hi I have a mqtt broker up and running. I am connecting to it from python using paho-mqtt.
Code
def on_connect(client, userdata, flags, rc):
if rc==0:
print("connected OK Returned code=",rc)
else:
print("Bad connection Returned code=",rc)
print("Subscribing to topic","data/#")
client.subscribe("data/#")
def on_disconnect(client, userdata, rc):
print("Client Got Disconnected")
if rc != 0:
print('Unexpected MQTT disconnection. Will auto-reconnect')
else:
print('rc value:' + str(rc))
broker_address="ip"
port = 'port'
print("creating new instance")
client = mqtt.Client(clean_session=True) #create new instance
client.on_connect = on_connect
client.on_message = on_message #attach function to callback
client.on_disconnect = on_disconnect
print("connecting to broker")
client.connect(broker_address, port=port,) #connect to broker
client.loop_forever() #stop the loop
I am using the same code in multiple scripts ,connecting to broker and subscribing to a topic. The frequency of disconnection was less when there were 5-6 scripts. I have around 12-13 scripts connecting to the broker and frequency of disconnects has increased significantly. Is there some thing wrong with the connection in the scripts or its about the broker. Can someone help me with this?
My guess though is your broker does not like the fact that the Python client defaults to a null clientid. As per the spec it should treat this as an indication it must assign a unique id to your client, but it may be implementing the spec improperly?
Please try passing a randomly generated / unique client id in your connect(), as this will guarantee your clients are all unique, rather than all having the same id which for your broker means it's kicking out any connected client when a new one with the same id tries to connect.
How do you generate packets for PUBACK and PUBREL and most importantly, how do you know what the packetId of the received message is?
I would like to be able to handle the logic for PUBREL and PUBACKs myself. The code below should give a hint of what I'm trying to do.
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
from multiprocessing import Process, Queue
# The callback for when the client receives a CONNACK response from
the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("/test")
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
def my_function(id):
client = mqtt.Client(client_id="id", clean_session=False,userdata=None, protocol=MQTTv311)
client.on_connect = on_connect
client.on_message = on_message
client.connect("127.0.0.1", 1883, 60)
msgs = [{'topic':"/test", 'payload':"ClientId: " +id }, 'QoS': 2, 'retain': False),
{'topic':"/test", 'payload':"ClientId: " +id }, 'QoS': 2, 'retain': False),
{'topic':"/test", 'payload':"ClientId: " +id }, 'QoS': 2, 'retain': False)]
publish.multiple(msgs, hostname="127.0.0.1", port=1883,client_id=id, keepalive=60,will=None, auth=None, tls=None, protocol=mqtt.MQTTv311)
# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()
for i in range(0,10):
p = Process(target=my_function, args=(str(i))
I came across this while working on exploiting a possible MQTT vulnerability. To my knowledge Paho doesn't have any modules to handle more low-level packets, for that you could use Scapy's MQTT module.
Scapy is a module in Python that allows you to handle packets of a variety of protocols, here's how to send an MQTT CONNECT using scapy:
from scapy.contrib.mqtt import MQTTConnect
from scapy.all import send, IP, TCP
mqtt_broker_ip = '192.168.0.1'
mqtt_broker_port = 1883
ip_pkt = IP(dst=mqtt_broker_ip)
tcp_pkt = TCP(dport=mqtt_broker_port)
mqtt_pkt = MQTTConnect(clientId='my_client_id')
# use slashes (/) to stack protocols
final_pkt = ip_pkt/tcp_pkt/mqtt_pkt
send(mqtt_pkt)
I'm using the Mosquitto (now Paho) python MQTT client to connect to a HiveMQ broker. The code is very basic, as taken from their documentation here - https://pypi.python.org/pypi/paho-mqtt
#SUBSCRIBER
import paho.mqtt.client as mqtt
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, rc):
client.subscribe("GB/node0/", 2)
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print "Topic: ", msg.topic+'\nMessage: '+str(msg.payload)
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("192.168.15.4", 1883, 60)
# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
client.loop_forever()
As you notice in client.subscribe(), the QoS is 2. This is the only modification to the official documentation's code.
The publishing client's code is-
#PUBLISHER
import paho.mqtt.client as mqtt
mqttc = mqtt.Client("python_pub")
mqttc.connect("192.168.15.4", 1883, 60)
mqttc.publish("GB/node0/", "Hello, World baby!",2)
Here also, the QoS is 2.
This modification of QoS results in only 20 messages being received by the subscriber. Upon further probing, I realized the problem is probably due to max_inflight_messages_set(), which is an option function which sets the maximum number of messages with QoS>0 that can be part way through their network flow at once. The default is 20.
However, changing it to any other value does not work. Also, why does the client think these messages are still inflight when they've been received? How do I resolve the problem? How do I ensure that the client understands these messages are not "inflight" and have been delivered?
Try calling mqttc.loop(2,10) after the mqttc.publish() in the publisher so the publisher can handle the QOS2 acknowledgement from the broker that it has received the publish.
The 2 second timeout and the 10 packets is probably more than is needed but it should work
#hardillb is right, you need some form of loop*() call. To be more certain, do this:
import paho.mqtt.client as mqtt
def on_publish(client, userdata, mid):
client.disconnect()
mqttc = mqtt.Client() # There's normally no need to set a client id.
mqttc.on_publish = on_publish
mqttc.connect("192.168.15.4", 1883, 60)
mqttc.publish("GB/node0/", "Hello, World baby!",2)
mqttc.loop_forever()
Or:
import paho.mqtt.publish as paho
paho.single("GB/node0/", "Hello, World baby!", qos=2, hostname="192.168.15.4")