Raspberry Pi MQTT Broker Install (Mosquitto)

336 views
Skip to first unread message

Julian Knight

unread,
Nov 29, 2015, 5:41:12 PM11/29/15
to Node-RED
Hi all,

Just in case anyone else needs this info. The easy way to install Mosquitto as your MQTT broker on a Raspberry Pi is to add the Debian repo from mosquitto.org.

That gets you the latest ARM version complete with websockets enabled. No need to manually compile it.

To use websockets, all you need to do is to add a suitable conf file to /etc/mosquitto/conf.d/

Something like:

# Standard Listener
listener 1883
protocol mqtt
#allow_anonymous false
#password_file /etc/mosquitto/passwords.txt

# Websockets Listener
listener 9001
#http_dir
#Set the protocol to accept for this listener. Can be mqtt (the default), or websockets.
protocol websockets


NB: Don't forget to configure for certificate based security if you will be exposing the broker over the Internet. You can have multiple websockets listeners too so that you can, for example, have one with a restricted set of topics available. Ideal for sharing sensor data over the internet without exposing your control topics.

Once you have that, get hold of MQTT.js for the browser and you can do some interesting things with web pages. 
I have an example using REACT that is just a few lines of code that will show all subscribed topics in a list along with the current data. 
If you want to see it, let me know & I'll post it up somewhere.

Have fun, Julian.

Zenofmud

unread,
Jan 2, 2016, 7:56:14 PM1/2/16
to node...@googlegroups.com

> On Nov 29, 2015, at 5:41 PM, Julian Knight <j.kni...@gmail.com> wrote:

<…snip…>
> Once you have that, get hold of MQTT.js for the browser and you can do some interesting things with web pages.
> I have an example using REACT that is just a few lines of code that will show all subscribed topics in a list along with the current data.
> If you want to see it, let me know & I'll post it up somewhere.
<…/snip…>

Julian, I’d love to see it.
Paul

Julian Knight

unread,
Jan 2, 2016, 8:21:19 PM1/2/16
to Node-RED
No problem :)

mqtest.html:
<html>
<head>
<title>test Ws mqtt.js</title>
</head>
<body>
<div id="msgList"></div>
<!--<div id="deviceStatus"></div>-->
<script src="js/browserMqtt.js"></script>
<script>

// {marked(this.props.children.toString())}
//client.publish("mqtt/demo", "hello world!");
</script>
<script type="text/babel" src="js/browserMqtt.jsx"></script>
</body>
</html>

browserMqtt.jsx
/*jshint browser: true, jquery: true*/
/*global mqtt, React, ReactDOM, _, console */

/***
 ***/

// Create connection to the websockets port of our MQTT broker
var client = mqtt.connect('ws://192.168.1.167:9001', {
'keepalive': 15, // keepalive: 10 seconds, set to 0 to disable
'clientId' : 'mqttjs_browser', // clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8)
// protocolId: 'MQTT'
// protocolVersion: 4
'clean' : false, // true, set to false to receive QoS 1 and 2 messages while offline
//'reconnectPeriod' : 1000 // 1000 milliseconds, interval between two reconnections
// connectTimeout: 30 * 1000 milliseconds, time to wait before a CONNACK is received
// username: the username required by your broker, if any
// password: the password required by your broker, if any
// incomingStore: a Store for the incoming packets
// outgoingStore: a Store for the outgoing packets
// will: a message that will sent by the broker automatically when the client disconnect badly. The format is:
//    topic: the topic to publish
//    payload: the message to publish
//    qos: the QoS
//    retain: the retain flag
'will' : { 'topic':'DEVICES/MQTTJS/DEBUG', 'payload':'Offline', 'qos':1}
});
// On successfull (re)connection
client.on("connect", function(connack) {
// Send birth message
client.publish('DEVICES/MQTTJS/DEBUG', 'Online', { 'qos' : 1 });
// Listen to DEVICES messages
client.subscribe("#", {'qos':1});
});

var DeviceList = React.createClass({
render: function() {
var deviceNodes = this.props.data.map(function(dev) {
// the key is used to track what to update
return (
<li key={dev.id}>
{dev.id} : {dev.status}
</li>
);
});
return (
<ul className="deviceList">
{deviceNodes}
</ul>
);
}
});
var DeviceStatusList = React.createClass({
render: function() {
return (
<div className="devices">
<h1>Status for Devices</h1>
<DeviceList data={this.props.data} />
</div>
);
}
});

// Fn to render the REACT elements
// NB1: We simply re-render whenever the data changes because REACT is super efficient at working out what to actuall change
//    so no need to mess about with this.state
// NB2: We use lodash's toArray because REACT needs an array not an object but we want an object so that our array doesn't keep
// growing. REACT uses the 'id' of the array to keep track of what and where to change things.
var reRender = function(){
ReactDOM.render(
<DeviceStatusList data={_.toArray(deviceData)} />,
document.getElementById('deviceStatus')
);
};


var Topics = React.createClass({
render: function() {
//console.dir(this.props.data);
var topics = this.props.data.map(function(topic) {
return (
<tr>
<td key={topic.id}>{topic.id}</td>
<td>{topic.payload}</td>
<td>{topic.qos}</td>
<td>{topic.retain}</td>
</tr>
);
});
return (
<table><thead>
<th>Topic</th>
<th>Payload</th>
<th>QoS</th>
<th>Retain</th>
</thead><tbody>
{topics}
</tbody></table>
);
}
});
var TopicHeadings = React.createClass({
render: function() {
//console.dir(this.props.data);
var topicHeadings = this.props.data.map(function(tHead) {
return (
<section>
<h1 key={tHead.id}>{tHead.id}</h1>
<Topics data={_.toArray(tHead.topics)} />
</section>
);
});
return (
<section>
<h1>MQTT Topic Headings</h1>
{topicHeadings}
</section>
);
}
});
var reRender2 = function(){
//console.dir(_.sortBy(dd,'id'));
ReactDOM.render(
<TopicHeadings data={_.sortBy(dd,'id')} />,
document.getElementById('msgList')
);
};



var deviceData = {}, dd = {};

/***
 * @param {string} topic   - The topic of the message recieved
 * @param {buffer} payload - The payload of the message (use payload.toString())
 * @param {Object} packet  - {cmd:'publish', dup:true/false, length:nn, payload:buff, qos:0/1/2, retain:0/1, topic:string}
 ***/
client.on("message", function(topic, payload, packet) {
var t = topic.split('/'),
tHead = t[0]
;
//var shortTopic = (_.rest(t)).join('/');
if ( ! (tHead in dd) ) {
dd[ tHead ] = { 
'id'   : tHead,
'topics' : {}
};
}
var dd2 = dd[ tHead ].topics;
dd2[topic] = {
'id' : topic,
'payload': payload.toString(),
'qos' : packet.qos,
'retain' : packet.retain
};
deviceData[topic] = {
'id' : topic,
'status' : payload.toString()
};
//reRender();
reRender2();
//console.dir(deviceData);
//console.dir(dd);
//console.dir(packet);
//client.end();
});

//reRender();

Not terribly efficient as this compiles the jsx on the fly in the browser but it works.

The code subscribes to "#" so it picks up everything.

Zenofmud

unread,
Jan 2, 2016, 8:58:02 PM1/2/16
to node...@googlegroups.com
thanks, I’ll try to play with this tomorrow (if I can sneak away from the grand kids)

On Jan 2, 2016, at 8:21 PM, Julian Knight <j.kni...@gmail.com> wrote:

No problem :)


<…snip…>

Not terribly efficient as this compiles the jsx on the fly in the browser but it works.

The code subscribes to "#" so it picks up everything.


On Sunday, 3 January 2016 00:56:14 UTC, Paul Woodard wrote:

> On Nov 29, 2015, at 5:41 PM, Julian Knight <j.kni...@gmail.com> wrote:

<…snip…>
> Once you have that, get hold of MQTT.js for the browser and you can do some interesting things with web pages.
> I have an example using REACT that is just a few lines of code that will show all subscribed topics in a list along with the current data.
> If you want to see it, let me know & I'll post it up somewhere.
<…/snip…>

Julian, I’d love to see it.
Paul


--
http://nodered.org
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages