/*jshint browser: true, jquery: true*/
/*global mqtt, React, ReactDOM, _, console */
/***
***/
// Create connection to the websockets port of our MQTT broker
'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>
);
});
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>{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();