Arduino MQTT Mongodb

Ekom Source

I'm working on a DHT11 Temperature and Humidity sensor. I'm using MQTT as my transfer protocol and everything seems to be okay. But i'm having a little problem storing the data in MongoDB. The MQTT broker sees the published messages but I can't seem to find the sensor data in my database. I created the collection in MongoDB but unfortunately it is not collecting any data.

var mqtt = require('mqtt'); //includes mqtt server
var mongodb = require('mongodb'); // includes mongoDB
var mongodbClient = mongodb.MongoClient; //initialises the mongoDB client
var mongodbURI = 'mongodb://localhost:27017/local'; //activating the MongoDB port 27017, here local is the name of the database
var deviceRoot = "demo/status/temperature"; //deviceroot is topic name given in arduino code
var collection,client; //initialise collection and client

mongodbClient.connect(mongodbURI, setupCollection); //connect the database with collecion

function setupCollection(err, db) {
if(err) throw err;
collection=db.collection(test_mqtt); //name of the collection in the database
client=mqtt.connect({ host: 'localhost', port: 1883 }); //connecting the mqtt server with the MongoDB database

client.subscribe(deviceRoot+"+"); //subscribing to the topic name
client.on('message', insertEvent); //inserting the event
}
//function that displays the data in the MongoDataBase
function insertEvent(topic,message) {
var key=topic.replace(deviceRoot,'');

collection.update(
    { _id:key },
    { $push: { events: { event: {  value:message, when:new Date() } } } },
    { upsert:true },

    function(err,docs) {
        if(err) {
            console.log("Insert fail");// Improve error handling
        }
    }

);

}

I would appreciate any help I can get.

node.jsmongodbarduinomqtt

Answers

answered 1 year ago hardillb #1

The mqtt.connect() is asynchronous so the client is not yet connected when you call client.subscribe().

You need to add a client.on('connect') callback and place the subscription code in it.

...
client=mqtt.connect({ host: 'localhost', port: 1883 }); //connecting the mqtt server with the MongoDB database
client.on('connect',function(){
   client.subscribe(deviceRoot+"+");
});
client.on('message',insertEvent);
...

answered 10 months ago Temi Adeyeri #2

The MQTT library you are using is client. You need a broker that is running on the server. Mosca Server is a good one and it supports MongoDB and WebSockets out of the box. It's what I use currently in my IOT project.

A typical setup will look like this:

const mosca = require('mosca');

function setupMqttServer() {
    var mongoUrl = "mongodb://127.0.0.1:27017/mqtt";
    var moscaSettings = {
        port: 1883,
        backend: {
            type: 'mongo',
            url: mongoUrl,
            pubsubCollection: 'moscadata',
            mongo: {}
        },
        persistence: {
            factory: mosca.persistence.Mongo,
            url: mongoUrl
        }
    };
    this.server = new mosca.Server(moscaSettings);
    this.server.on('ready', function () {
        console.log('Mosca server is up and running');
    });


    this.server.on('clientConnected', function (client) {
        console.log('client connected', client.id);
    });
    this.server.on('published', (packet, client) => {
        console.log('Message received : ', `topic-${packet.topic}`, `payload-${packet.payload.toString()}`);
        // You can process received message here.
    });
    this.server.on('subscribed', function (topic, client) {
        console.log('subscribed : ', topic);
    });
    this.server.on('unsubscribed', (topic, client) => {
        console.log('unsubscribed : ', topic);
    });
    this.server.on('clientDisconnecting', (client) => {
        console.log('clientDisconnecting : ', client.id);
    });
    this.server.on('clientDisconnected', (client) => {
        console.log('clientDisconnected : ', client.id);
    });
}

I also use mqtt-regex for parsing the topics.

comments powered by Disqus