Skip to content

Instantly share code, notes, and snippets.

@vbalexr
Created January 22, 2018 06:09
Show Gist options
  • Save vbalexr/f0ba2f253a0e9b64bbaedd0860c6b701 to your computer and use it in GitHub Desktop.
Save vbalexr/f0ba2f253a0e9b64bbaedd0860c6b701 to your computer and use it in GitHub Desktop.
ThingsBoard Server Monitor
// Requires node.js and mqtt library installed.
var mqtt = require('mqtt');
var os = require("os");
const thingsboardHost = "SERVERNAME";
// Reads the access token from arguments
const accessToken = 'ACCESS_TOKEN';
// Default topics. See http://thingsboard.io/docs/reference/mqtt-api/ for more details.
const attributesTopic = 'v1/devices/me/attributes';
const telemetryTopic = 'v1/devices/me/telemetry';
const attributesRequestTopic = 'v1/devices/me/attributes/request/1';
const attributesResponseTopic = attributesRequestTopic.replace('request',
'response');
// Initialization of mqtt client using Thingsboard host and device access token
console.log('Connecting to: %s using access token: %s', thingsboardHost, accessToken);
var client = mqtt.connect('mqtt://' + thingsboardHost, {username: accessToken});
var firmwareVersion = '0.0.1';
var appState;
// Telemetry upload is once per 5 seconds by default;
var currentFrequency = 5;
var uploadInterval;
// Triggers when client is successfully connected to the Thingsboard server
client.on('connect', function () {
console.log('Client connected!');
// Upload firmware version and serial number as device attribute using 'v1/devices/me/attributes' MQTT topic
client.publish(attributesTopic, JSON.stringify({
'firmwareVersion': '0.0.1',
'hostname': os.hostname(),
'ram': Math.ceil(os.totalmem()/1000000),
'type': os.type(),
'ipv4': getIPv4(),
'ipv6': getIPv6()
}));
// Subscribe to shared attribute changes on the server side
client.subscribe(attributesTopic);
// Publish request for 'appState' client attribute
// and two shared attributes 'uploadFrequency' and 'latestVersion'
client.publish(attributesRequestTopic, JSON.stringify({
'clientKeys': 'appState,ram',
'sharedKeys': 'uploadFrequency,latestFirmwareVersion'
}));
// Schedule OS stats upload
console.log('Uploading OS stats with interval %s (sec)...', currentFrequency);
uploadInterval = setInterval(uploadStats, currentFrequency * 1000);
});
client.on('message', function (topic, message) {
if (topic === attributesTopic) {
// Process attributes update notification
console.log('Received attribute update notification: %s',
message.toString());
var data = JSON.parse(message);
if (data.uploadFrequency && data.uploadFrequency != currentFrequency) {
// Reschedule upload using new frequency
rescheduleStatsUpload(data.uploadFrequency);
}
if (data.latestFirmwareVersion && data.latestFirmwareVersion != firmwareVersion) {
// Received new upload frequency configuration
console.log('New firmware version is available: %s', data.latestFirmwareVersion);
}
} else if (topic === attributesResponseTopic) {
// Process response to attributes request
console.log('Received response to attribute request: %s', message.toString());
var data = JSON.parse(message);
if (data.client && data.client.appState) {
appState = data.client.appState+1;
client.publish(attributesTopic, JSON.stringify({'appState': appState}));
} else {
appState = 1;
client.publish(attributesTopic, JSON.stringify({'appState': appState}));
}
if (data.shared) {
if (data.shared.uploadFrequency && data.shared.uploadFrequency != currentFrequency) {
// Received new upload frequency configuration
rescheduleStatsUpload(data.shared.uploadFrequency);
}
if (data.shared.latestFirmwareVersion && data.shared.latestFirmwareVersion != firmwareVersion) {
// Received new upload frequency configuration
console.log('New firmware version is available: %s', data.shared.latestFirmwareVersion);
}
}
}
})
// Reschedule of stats upload timer
function rescheduleStatsUpload(uploadFrequency) {
clearInterval(uploadInterval);
currentFrequency = uploadFrequency;
console.log('Uploading OS stats with new interval %s (sec)...', currentFrequency);
uploadInterval = setInterval(uploadStats, currentFrequency * 1000);
}
// Upload OS stats using 'v1/devices/me/telemetry' MQTT topic
function uploadStats() {
var data = {};
data.uptime = os.uptime();
data.fmem = Math.ceil(os.freemem()/1000000);
data.mem = os.freemem() / os.totalmem();
data.load = os.loadavg()[0];
// console.log('Publishing OS info & stats: %s', JSON.stringify(data));
client.publish(telemetryTopic, JSON.stringify(data));
}
function getIPv4() {
var ifaces = os.networkInterfaces();
var address = "";
for (var dev in ifaces){
for(var i in ifaces[dev]){
if(ifaces[dev][i].family=="IPv4" &&
!ifaces[dev][i].internal){
address += ifaces[dev][i].address+ " ";
}
}
}
return address;
}
function getIPv6() {
var ifaces = os.networkInterfaces();
var address = "";
for (var dev in ifaces){
for(var i in ifaces[dev]){
if(ifaces[dev][i].family=="IPv6" && !ifaces[dev][i].internal && ifaces[dev][i].scopeid==0 ){
address += ifaces[dev][i].address+ " ";
}
}
}
return address;
}
// Catches ctrl+c event
process.on('SIGINT', function () {
console.log();
console.log('Disconnecting...');
client.end();
console.log('Exited!');
process.exit(2);
});
// Catches uncaught exceptions
process.on('uncaughtException', function (e) {
console.log('Uncaught Exception...');
console.log(e.stack);
process.exit(99);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment