global name 'mqttClient' is not defined - python

I am new to python. I'm trying to connect my client with the broker. But I am getting an error "global name 'mqttClient' is not defined".
Can anyone help me to what is wrong with my code.
Here is my code,
Test.py
#!/usr/bin/env python
import time, threading
import mqttConnector
class UtilsThread(object):
def __init__(self):
thread = threading.Thread(target=self.run, args=())
thread.daemon = True # Daemonize thread
thread.start() # Start the execution
class SubscribeToMQTTQueue(object):
def __init__(self):
thread = threading.Thread(target=self.run, args=())
thread.daemon = True # Daemonize thread
thread.start() # Start the execution
def run(self):
mqttConnector.main()
def connectAndPushData():
PUSH_DATA = "xxx"
mqttConnector.publish(PUSH_DATA)
def main():
SubscribeToMQTTQueue() # connects and subscribes to an MQTT Queue that receives MQTT commands from the server
LAST_TEMP = 25
try:
if LAST_TEMP > 0:
connectAndPushData()
time.sleep(5000)
except (KeyboardInterrupt, Exception) as e:
print "Exception in RaspberryAgentThread (either KeyboardInterrupt or Other)"
print ("STATS: " + str(e))
pass
if __name__ == "__main__":
main()
mqttConnector.py
#!/usr/bin/env python
import time
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
print("MQTT_LISTENER: Connected with result code " + str(rc))
def on_message(client, userdata, msg):
print 'MQTT_LISTENER: Message Received by Device'
def on_publish(client, userdata, mid):
print 'Temperature Data Published Succesfully'
def publish(msg):
# global mqttClient
mqttClient.publish(TOPIC_TO_PUBLISH, msg)
def main():
MQTT_IP = "IP"
MQTT_PORT = "port"
global TOPIC_TO_PUBLISH
TOPIC_TO_PUBLISH = "xxx/laptop-management/001/data"
global mqttClient
mqttClient = mqtt.Client()
mqttClient.on_connect = on_connect
mqttClient.on_message = on_message
mqttClient.on_publish = on_publish
while True:
try:
mqttClient.connect(MQTT_IP, MQTT_PORT, 180)
mqttClient.loop_forever()
except (KeyboardInterrupt, Exception) as e:
print "MQTT_LISTENER: Exception in MQTTServerThread (either KeyboardInterrupt or Other)"
print ("MQTT_LISTENER: " + str(e))
mqttClient.disconnect()
print "MQTT_LISTENER: " + time.asctime(), "Connection to Broker closed - %s:%s" % (MQTT_IP, MQTT_PORT)
if __name__ == '__main__':
main()
I'm getting this,
Exception in RaspberryAgentThread (either KeyboardInterrupt or Other)
STATS: global name 'mqttClient' is not defined

You have not defined mqttClient globally.
Make the following changes
import time
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
print("MQTT_LISTENER: Connected with result code " + str(rc))
def on_message(client, userdata, msg):
print 'MQTT_LISTENER: Message Received by Device'
def on_publish(client, userdata, mid):
print 'Temperature Data Published Succesfully'
def publish(msg):
global mqttClient
mqttClient.publish(TOPIC_TO_PUBLISH, msg)
def main():
MQTT_IP = "IP"
MQTT_PORT = "port"
global TOPIC_TO_PUBLISH
TOPIC_TO_PUBLISH = "xxx/laptop-management/001/data"
global mqttClient
mqttClient.on_connect = on_connect
mqttClient.on_message = on_message
mqttClient.on_publish = on_publish
while True:
try:
mqttClient.connect(MQTT_IP, MQTT_PORT, 180)
mqttClient.loop_forever()
except (KeyboardInterrupt, Exception) as e:
print "MQTT_LISTENER: Exception in MQTTServerThread (either KeyboardInterrupt or Other)"
print ("MQTT_LISTENER: " + str(e))
mqttClient.disconnect()
print "MQTT_LISTENER: " + time.asctime(), "Connection to Broker closed - %s:%s" % (MQTT_IP, MQTT_PORT)
mqttClient = mqtt.Client()
if __name__ == '__main__':
main()

Error is occurs due to using following line :
mqttClient.on_connect = on_connect
the correct format should be
mqtt.Client.on_connect = on_connect

Related

Python: Websocket client does not print any error

I am using the following example code to connect Binancr Websocket. It all of sudden stopped and halted the program and print None on the screen:
PAIR = 'ethusdt'
WS_ENDPOINT = 'wss://fstream.binance.com/ws/{}#trade'.format(PAIR.lower())
def handle_trades(json_message):
pass
def ws_trades():
def on_ping(wsapp, message):
print("Got a ping! A pong reply has already been automatically sent.")
def on_pong(wsapp, message):
print("Got a pong! No need to respond")
def on_open(wsapp):
print("Initiating Connection")
def on_close(wsapp, close_status_code, close_msg):
print('close_status_code = ', close_status_code)
print('close_msg = ', close_msg)
def on_message(wsapp, message):
# current_time = datetime.datetime.today()
# print(current_time)
json_message = json.loads(message)
handle_trades(json_message)
def on_error(wsapp, error):
print('Error during Websocket connection')
print(error)
wsapp = websocket.WebSocketApp(WS_ENDPOINT, on_message=on_message, on_error=on_error)
wsapp.run_forever()
if __name__ == '__main__':
ws_trades()
How do I learn what is the actual error and how come I keep it running even if it halts for a while due to absence of incoming messages?
Below is the image of the screen.

mqtt client publish based on incoming message conditions

I am experimenting with mqtt with python paho mqtt library and a mqtt client mobile app with the test.mosquito.org server/broker.
This basic script works below connecting to the test.mosquitto server where I can publish a message from a mobile mqtt client app to this script and this script can also publish to the mobile app every 20 seconds a test message via the def publish(client): function.
import random
import time
from paho.mqtt import client as mqtt_client
broker = 'test.mosquitto.org'
port = 1883
# generate client ID with pub prefix randomly
client_id = "test_1"
topic_to_publish = f"laptop/publish"
topic_to_listen = f"mobile/publish"
topic_to_wildcard = f"testing/*"
username = ""
password = ""
def connect_mqtt():
def on_connect(client, userdata, flags, rc):
if rc == 0:
client.subscribe(topic_to_listen)
print(f"Connected to MQTT Broker on topic: {topic_to_wildcard}")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(client_id)
client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(broker, port)
client.on_connect = on_connect # Define callback function for successful connection
client.on_message = on_message # Define callback function for receipt of a message
return client
def publish(client):
msg_count = 0
while True:
time.sleep(20)
msg = f"hello from {client_id}: {msg_count}"
result = client.publish(topic_to_publish, msg)
# result: [0, 1]
status = result[0]
if status == 0:
print(f"Send {msg} to topic {topic_to_publish}")
else:
print(f"Failed to send message to topic {topic_to_publish}")
msg_count += 1
def on_message(client, userdata, msg): # The callback for when a PUBLISH message is received from the server.
print("Message received-> " + msg.topic + " " + str(msg.payload))
def run():
client = connect_mqtt()
client.loop_start()
publish(client)
if __name__ == '__main__':
run()
Can someone give me a tip on how to modify the def publish(client): function not to be a while loop that will fire off messages every 20 seconds but to only publish if the message from the mobile app received equals a string "zone temps"?
Am I on track at all removing the publish(client) from main run function as well as the while loop from def publish(client):? Thanks any tips greatly appreciated. What I am running into is I am missing something when I run this modified version there is no message exchange between at all.
def on_message(client, userdata, msg):
print("Message received-> " + msg.topic + " " + str(msg.payload))
if str(msg.payload) == "zone temps":
publish(client,"avg=72.1;min=66.4;max=78.8")
def run():
client = connect_mqtt()
client.loop_start()
if __name__ == '__main__':
run()
I m also beginner; but ill create a variable to is it publish or listening, like:
phoneAppListener = 0
and also
if str(msg.payload) == "zone temps":
when i print my payload it looks like:
b'payload'
firstly you need to split your payload like:
tempMsgHolder = str(msg.payload).split("'")
when you do this. tempMsgHolder[1] is your pure payload.
if tempMsgHolder[1] == "zone temps": phoneAppListener = 1
phoneAppListener value make the decision 0 is listen, 1 is publish. on your publish loop you set this
phoneAppListener == 1: publish your message
import random
import time
import threading
from paho.mqtt import client as mqtt_client
class moduleDatas:
broker = ('test.mosquitto.org')
port = (1883)
# generate client ID with pub prefix randomly
client_id = "test_1"
topic_to_publish = f"laptop/publish"
topic_to_listen = f"mobile/publish"
topic_to_wildcard = f"testing/*"
username = ""
password = ""
# Create clients object:
# You can create mqtt client obj using same pattern. Client has different on_msg or ex.
mqttClient_1 = mqtt_client.Client(moduleDatas.client_id) # You can create what ever you want to create a new thread
def mqttClientConnect():
mqttClient_1.connect(moduleDatas.broker[0], moduleDatas.port[0])
mqttClient_1.loop_start() # It creates daemon thread while your main thread running, this will handle your mqtt connection.
#mqttClient_1.connect_callback()
def on_connect(client, userdata, flags, rc):
if rc == 0:
print(f"Connected to MQTT Broker on topic: {moduleDatas.topic_to_wildcard}")
else:
print("Failed to connect, return code %d\n", rc)
#mqttClient_1.publish_callback()
def on_publish(client, userdata, mid):
print(mid) # If publish is success its return 1 || If mid = 1 publish success. || You can check your publish msg if it return failed try to send again or check your connection.
#mqttClient_1.message_callback()
def on_message(client, userdata, message):
temp_str = str(message.payload).split("'")
if temp_str[1] == "zone temps":
msg = "hello world" # <-- Your message here. Some func return or simple texts
mqttClient_1.publish(topic= moduleDatas.topic_to_publish, payload= msg, qos= 0)
def mqttClientSubscribe():
mqttClient_1.subscribe(moduleDatas.topic_to_listen)
def threadMqttClient1():
mqttClientConnect()
mqttClientSubscribe()
def buildThreads():
threads= []
t = threading.Thread(target=threadMqttClient1(), daemon= True)
threads.append(t)
# You can create on same pattern and append threads list.
for t in threads:
t.start()
while True: # this will your main thread, you can create an operation, ill go with just idling.
pass
if __name__ == "__main__":
buildThreads()

python paho client MQTT subscriber not getting

I am using python Paho client.
I am using this in to my function.
my code is showing
import paho.mqtt.client as mqtt
import time, logging
broker = "127.0.0.1"
port = 1883
QOS = 0
CLEAN_SESSION = True
# error logging
# use DEBUG,INFO,WARNING
def on_subscribe(client, userdata, mid, granted_qos): # create function for callback
# print("subscribed with qos",granted_qos, "\n")
time.sleep(1)
print("sub acknowledge message id=" + str(mid))
pass
def on_disconnect(client, userdata, rc=0):
print("DisConnected result code " + str(rc))
def on_connect(client, userdata, flags, rc):
print("Connected flags" + str(flags) + "result code " + str(rc))
def on_message(client, userdata, message):
msg = str(message.payload.decode("utf-8"))
print("message received in mqtt_subscriber " + msg)
def on_publish(client, userdata, mid):
print("message published " + str(mid))
topic1 = "test"
client = mqtt.Client("RDAresp", False) # create client object
client.on_subscribe = on_subscribe # assign function to callback
client.on_disconnect = on_disconnect # assign function to callback
client.on_connect = on_connect # assign function to callback
client.on_message = on_message
client.connect(broker, port) # establish connection
time.sleep(1)
client.loop_start()
client.subscribe("RemoteDoorAccess")
count = 1
while True: # runs forever break with CTRL+C
print("publishing on topic ", topic1)
msg = "message : RemoteDoorAccess_resp is published "
client.publish(topic1, msg)
count += 1
time.sleep(5)
and in views.py
def on_message(client, userdata, message):
msg = str(message.payload.decode("utf-8"))
print("message authority resp module " + msg)
def on_subscribe(client, userdata, mid, granted_qos): # create function for callback
print("subscribed with qos", granted_qos, "\n")
time.sleep(1)
pass
def on_disconnect(client, userdata, rc=0):
print("DisConnected result code " + str(rc))
def on_connect(client, userdata, flags, rc):
print("Connected flags" + str(flags) + "result code " + str(rc))
def on_publish(client, userdata, mid):
print("message published " + str(mid))
def mqttConnection():
topic = "RemoteDoorAccess"
client = mqtt.Client("RDA", False) # create client object
client.on_subscribe = on_subscribe # assign function to callback
client.on_disconnect = on_disconnect # assign function to callback
client.on_connect = on_connect # assign function to callback
client.on_message = on_message
client.connect(broker, port) # establish connection
time.sleep(1)
client.subscribe("test")
time.sleep(1)
print("publishing on topic ", topic)
msg = "RemoteDoor Access published"
client.publish(topic, msg)
time.sleep(10)
#api_view(['GET'])
#permission_classes([])
def remotedooraccess_mobile(request):
mqttConnection()
return Response({msg: validation["FDP34"]}, status=status.HTTP_200_OK)
Here the topic 'test' is published but not subscribing.
please check views output
in my views.py on_message function is not called by the topic test.
how can I solve this.
I am totally stuck here.. in view.py subscribe function is not calling.
I am very new to mqtt.
please help
You need to start the client loop in your views.py code otherwise there is nothing to actually run your on_message() callback.
You should also move all your calls to client.subscribe() to into the on_connect callback and remove most of the calls to time.sleep()

Looking for MQTT PUBACK from on_log callback using within a class fails, but it works in a flat script

The first script works, meaning the callbacks are called and it ends printing puback: True
The second script where I use class A to do the work does not work. Callbacks are not called, and it ends with a.puback: False
I'm not sure if my problem is that callbacks don't work this way, in which case how can I get my class to work with these Paho MQTT callbacks? or if it's something more subtle.
WORKS:
def on_log_puback(client, userdata, level, buf):
global puback
if 'PUBACK' in buf:
puback = True
print "PUBACK!"
def on_connect(client, userdata, flags, rc):
print "Connect code: ", rc
def on_disconnect(client, userdata, flags, rc=0):
print "Disconnect code: ", rc
def on_message(client, userdata, msg):
print " Message: ", str(msg.payload.decode("utf-8", "ignore"))
def stop():
print ("stopping loop")
client.loop_stop()
print "disconnecting"
client.disconnect()
import paho.mqtt.client as mqtt
import time
client = mqtt.Client("Luke, I am your client")
mqtt.Client.connected_flag = False
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_log = on_log_puback
client.on_message = on_message
status = client.connect(host="test.mosquitto.org",
keepalive=60, port=1883)
print "connect status: ", status
time.sleep(2)
print "loop_start"
client.loop_start()
time.sleep(1)
sret = client.subscribe("test_topic")
print "subscribe returns sret: ", sret
time.sleep(2)
# initialize global
puback = False
# test publish with qos=1
status, msg_id = client.publish(topic="test_topic",
payload="hello!",
qos=1, retain=True)
print "publish status: ", status
time.sleep(2)
print "puback: ", puback
stop()
DOESN'T WORK:
import paho.mqtt.client as mqtt
import time
class A(object):
def __init__(self):
client = mqtt.Client("Luke, I am your client")
self.client = client
mqtt.Client.connected_flag = False
client.on_connect = self.on_connect
client.on_disconnect = self.on_disconnect
client.on_log = self.on_log_puback
client.on_message = self.on_message
status = client.connect(host="test.mosquitto.org",
keepalive=60, port=1883)
print "connect status: ", status
time.sleep(2)
print "loop_start"
client.loop_start()
time.sleep(1)
sret = client.subscribe("test_topic")
print "subscribe returns: ", sret
time.sleep(2)
# initialize global
puback = False
# test publish with qos=1
status, msg_id = client.publish(topic="test_topic",
payload="hello!",
qos=1, retain=True)
print "publish status: ", status
time.sleep(2)
self.puback = puback
def on_log_puback(client, userdata, level, buf):
global puback
if 'PUBACK' in buf:
puback = True
print "PUBACK!"
def on_connect(client, userdata, flags, rc):
print "Connect code: ", rc
def on_disconnect(client, userdata, flags, rc=0):
print "Disconnect code: ", rc
def on_message(client, userdata, msg):
print " Message: ", str(msg.payload.decode("utf-8", "ignore"))
def stop(self):
print ("stopping loop")
self.client.loop_stop()
print "disconnecting"
self.client.disconnect()
a = A()
time.sleep(2)
print 'a.puback: ', a.puback
a.stop()
Found it. When I moved the callbacks into the class, e.g. on_log_puback(self,...) I'd simply forgotten to add self to the beginning of the arguments. With that, it works nicely now.

Getting data from a task to a connection with asyncio

So this should be fairly simple, i have a client that connects to a server, and it can receive messages from the server just fine. However i need to be able to send messages to the server. I am using asyncio to handle these asynchronously but i have a problem with that. How do i get the user input to my client so it can use its transport to send the data up to the server. Heres the code.
import asyncio, zen_utils, json
from struct import *
class ChatClient(asyncio.Protocol):
def connection_made(self, transport):
self.transport = transport
self.address = transport.get_extra_info('peername')
self.data = b''
print('Accepted connection from {}'.format(self.address))
self.username = b'jacksonm'
json_name = b'{"USERNAME": "'+self.username+b'"}'
length = len(json_name)
code_len = pack(b'!I', length)
message = code_len + json_name
self.json_loaded = False
self.next_length = -1
self.transport.write(message)
def data_received(self, data):
self.data += data
if (self.json_loaded == False):
self.compile_server_data(data)
elif(self.json_loaded):
if (len(self.data) > 4 and self.next_length == -1):
self.next_length = self.data[:4]
self.next_length = unpack(b'!I', self.next_length)[0]
print("LENGTH: ", self.next_length)
elif (len(self.data) >= self.next_length):
self.data = self.data[4:]
print("MESSAGE: ", self.data)
self.next_length = -1
def compile_server_data(self, data):
if (self.data.find(b'}') != -1):
start_index = self.data.find(b'{')
end_index = self.data.find(b'}')
self.json_data = self.data[start_index:end_index + 1]
self.data = self.data[end_index + 1:]
self.json_data = self.json_data.decode('ascii')
self.json_data = json.loads(self.json_data)
self.json_loaded = True
self.print_server_status()
def send_message(self, message):
message = message.encode('ascii')
length = len(message)
code_len = pack(b'!I', length)
message = code_len + message
def parse_message(self, raw_message):
message = {}
message['SRC'] = self.username
message['DEST'] = b'ALL'
message['TIMESTAMP'] = int(time.time())
message['CONTENT'] = b'test_message'
json_message = json.loads(message)
print (json_message)
def print_server_status(self):
print ("USERS:")
for user in self.json_data["USER_LIST"]:
print(user)
print()
print("MESSAGES:")
for message in self.json_data["MESSAGES"][-10:]:
print ("From: ", message[0], " ", "To: ", message[1])
print ("Message: ", message[3])
print()
def get_inital_data(self):
pass
def connection_lost(self, exc):
if exc:
print('Client {} error: {}'.format(self.address, exc))
elif self.data:
print('Client {} sent {} but then closed'
.format(self.address, self.data))
else:
print('Client {} closed socket'.format(self.address))
#asyncio.coroutine
def handle_user_input(loop):
"""reads from stdin in separate thread
if user inputs 'quit' stops the event loop
otherwise just echos user input
"""
while True:
message = yield from loop.run_in_executor(None, input, "> ")
if message == "quit":
loop.stop()
return
print(message)
if __name__ == '__main__':
address = zen_utils.parse_command_line('asyncio server using callbacks')
loop = asyncio.get_event_loop()
coro = loop.create_connection(ChatClient, *address)
server = loop.run_until_complete(coro)
# Start a task which reads from standard input
asyncio.async(handle_user_input(loop))
print('Listening at {}'.format(address))
try:
loop.run_forever()
finally:
server.close()
loop.close()
This is working in my tests by changing one line, using Python 3.4:
Change the run_until_complete() call to receive a (transport,protocol) pair instead of a single value.
Specifically, change server = loop.run_until_complete(coro) to transport, protocol = loop.run_until_complete(coro), because the call executes the coroutine and returns its value which is a pair of items. The first item is the server object, and the second entry is a protocol object which is an instance of ChatClient.
Run the server then the client in different command windows.
Client code:
import asyncio, json #, zen_utils
from struct import *
class ChatClient(asyncio.Protocol):
def connection_made(self, transport):
self.transport = transport
self.address = transport.get_extra_info('peername')
self.data = b''
print('Accepted connection from {}'.format(self.address))
def data_received(self, data):
pass
def compile_server_data(self, data):
pass
def send_message(self, message):
message = message.encode('ascii')
self.transport.write(message)
def parse_message(self, raw_message):
pass
def print_server_status(self):
pass
def get_inital_data(self):
pass
def connection_lost(self, exc):
if exc:
print('Client {} error: {}'.format(self.address, exc))
elif self.data:
print('Client {} sent {} but then closed'
.format(self.address, self.data))
else:
print('Client {} closed socket'.format(self.address))
#asyncio.coroutine
def handle_user_input(loop, protocol):
"""reads from stdin in separate thread
if user inputs 'quit' stops the event loop
otherwise just echos user input
"""
while True:
message = yield from loop.run_in_executor(None, input, "> ")
if message == "quit":
loop.stop()
return
print(message)
protocol.send_message(message)
if __name__ == '__main__':
address = "127.0.0.1"
port = 82
loop = asyncio.get_event_loop()
coro = loop.create_connection(ChatClient, address, port) #*address
transport, protocol = loop.run_until_complete(coro)
# Start a task which reads from standard input
asyncio.async(handle_user_input(loop,protocol))
print('Listening at {}'.format(address))
try:
loop.run_forever()
finally:
transport.close()
loop.close()
Server code, credit goes to this site:
import socket
host = '' # Symbolic name meaning all available interfaces
port = 82 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
conn, addr = s.accept()
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data: break
print( 'Received ', repr(data) )
if repr(data)=="stop": break
conn.sendall(data)
conn.close()

Categories

Resources