I'm trying to write a script that saves mqtt data and sends it to influxDB. The issue I'm having is that the callback function of the mqtt-paho module keeps giving the error:
AttributeError: 'Client' object has no attribute 'write_api'
. I think this is because of the self
in the internal 'Client' class of the mqtt-paho. My full script can be found below:
# Imported modules
# standard time module
from datetime import datetime
import time
# InfluxDB specific modules
from influxdb_client import InfluxDBClient, Point, WritePrecision
from influxdb_client.client.write_api import SYNCHRONOUS
#MQTT paho specific modules
import paho.mqtt.client as mqtt
class data_handler(): # Default namespaces are just for all the ESPs.
def __init__(self, namespace_list=["ESP01","ESP02","ESP03","ESP04","ESP05","ESP06","ESP07","ESP08"]):
# initialize influxdb client and define access token and data bucket
token = "XXXXXXXXXX" # robotlab's token
self.org = "Home"
self.bucket = "HomeSensors"
self.flux_client = InfluxDBClient(url="http://localhost:8086", token=token)
self.write_api = self.flux_client.write_api(write_options=SYNCHRONOUS)
# Initialize and establish connection to MQTT broker
broker_address="XXX.XXX.XXX.XXX"
self.mqtt_client = mqtt.Client("influx_client") #create new instance
self.mqtt_client.on_message=data_handler.mqtt_message #attach function to callback
self.mqtt_client.connect(broker_address) #connect to broker
# Define list of namespaces
self.namespace_list = namespace_list
print(self.namespace_list)
def mqtt_message(self, client, message):
print("message received " ,str(message.payload.decode("utf-8")))
print("message topic=",message.topic)
print("message qos=",message.qos)
print("message retain flag=",message.retain)
sequence = [message.topic, message.payload.decode("utf-8")]
self.write_api.write(self.bucket, self.org, sequence)
def mqtt_listener(self):
for namespace in self.namespace_list:
self.mqtt_client.loop_start() #start the loop
print("Subscribing to topics!")
message = namespace+"/#"
self.mqtt_client.subscribe(message, 0)
time.sleep(4) # wait
self.mqtt_client.loop_stop() #stop the loop
def main():
influxHandler = data_handler(["ESP07"])
influxHandler.mqtt_listener()
if __name__ == '__main__':
main()
The code works fine until I add self.someVariable
in the callback function. What would be a good way to solve this problem? I don't really want to be making global variables hence why I chose to use a class.
Thanks in advance!