354 lines
12 KiB
JavaScript
354 lines
12 KiB
JavaScript
/**
|
|
* Created by Martin on 08/02/2016.
|
|
*/
|
|
'use strict';
|
|
var mqtt = require('mqtt');
|
|
|
|
var Messaging = require('mqtt_over_websockets');
|
|
var log4js = require('log4js');
|
|
var logger = log4js.getLogger();
|
|
|
|
var mqttConfig = {
|
|
orgId: 'qz0da4',
|
|
userName: 'martind2000',
|
|
appKey: 'MPReoa43',
|
|
prefix: 'iot-2/type/Ti-CC3200/id/'
|
|
};
|
|
|
|
function randomString(length) {
|
|
return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
|
|
}
|
|
|
|
/*
|
|
Projector: 'ProjectorISP15',
|
|
lighting: 'LightingISP15',
|
|
heating: 'HeatingISP15',
|
|
|
|
*/
|
|
var live = true;
|
|
|
|
logger.warn('!!! Live? ', live);
|
|
module.exports = {
|
|
restartTimer : 0,
|
|
pingTimer: 0,
|
|
statuses: {},
|
|
sockets: null,
|
|
wsClient: null,
|
|
watches: {},
|
|
client: null,
|
|
projector: live ? 'Projector' : 'ProjectorISP15',
|
|
lighting: live ? 'Lighting' : 'LightingISP15',
|
|
heating: live ? 'Heating' : 'HeatingISP15',
|
|
myID: 0,
|
|
connected: false,
|
|
options: {
|
|
// Keepalive: 3600,
|
|
keepalive: 60,
|
|
clientId: 'a:' + mqttConfig.orgId + ':' + Date.now(),
|
|
username: mqttConfig.userName,
|
|
password: new Buffer(mqttConfig.appKey)
|
|
|
|
},
|
|
lightList: {o: 'frontLight', f: 'frontLight',n: 'backLight', g: 'backLight'},
|
|
updateStatus: function(id, packet) {
|
|
this.statuses[id] = packet;
|
|
logger.info('Statuses:', this.statuses);
|
|
},
|
|
|
|
setEmitter: function(newEmitter) {
|
|
this.emitter = newEmitter;
|
|
},
|
|
doConnection: function(cb) {
|
|
console.log('Do connection');
|
|
var self = this;
|
|
if (this.client === null) {
|
|
this.client = mqtt.connect('mqtt://' + 'silvrtree.co.uk', this.options);
|
|
|
|
this.client.on('connect', function() {
|
|
logger.info('Connected to SilvrBroker');
|
|
self.connected = this.connected;
|
|
});
|
|
this.client.on('connected', function() {
|
|
logger.debug('mqttConnect - doConnection - Connected');
|
|
|
|
});
|
|
this.client.on('disconnect', function(e) {
|
|
logger.error('mqttConnect - doConnection - disconnect');
|
|
logger.error(e);
|
|
});
|
|
this.client.on('error', function(e) {
|
|
logger.error('mqttConnect - doConnection - disconnect');
|
|
logger.error(e);
|
|
});
|
|
|
|
}
|
|
return this;
|
|
},
|
|
isConnected: function() {
|
|
return this.connected;
|
|
},
|
|
sendCommand: function(deviceID, command) {
|
|
var payload = {
|
|
id: 'd',
|
|
text: command
|
|
|
|
};
|
|
},
|
|
projectorOn: function(callback) {
|
|
var packet;
|
|
console.log('projectorOn:');
|
|
var _callback = callback || {};
|
|
|
|
if (!this.client) {
|
|
return -1;
|
|
}
|
|
packet = {id: this.projector, status: true};
|
|
var destinationName = mqttConfig.prefix + this.projector + '/cmd/' + 'ON' + '/fmt/json';
|
|
this.client.publish(destinationName, 'ON', _callback);
|
|
this.emitter.emit('sendSocket',packet);
|
|
logger.debug('Storing status...');
|
|
this.updateStatus('projector', packet);
|
|
},
|
|
projectorOff: function(callback) {
|
|
var packet;
|
|
var _callback = callback || {};
|
|
if (!this.client) {
|
|
return -1;
|
|
}
|
|
packet = {id: this.projector, status: false};
|
|
var destinationName = mqttConfig.prefix + this.projector + '/cmd/' + 'OFF' + '/fmt/json';
|
|
this.client.publish(destinationName, 'OFF', _callback);
|
|
this.emitter.emit('sendSocket',packet);
|
|
console.log('Storing status...');
|
|
this.updateStatus('projector', packet);
|
|
|
|
},
|
|
projectorCmd: function(id, callback) {
|
|
var packet;
|
|
var _callback = callback || {};
|
|
if (!this.client) {
|
|
return -1;
|
|
}
|
|
|
|
var destinationName = mqttConfig.prefix + this.projector + '/cmd/' + id + '/fmt/json';
|
|
this.client.publish(destinationName, 'cmd', _callback);
|
|
},
|
|
heatingOn: function(callback) {
|
|
console.log('Turn heating on...');
|
|
var _callback = callback || null;
|
|
if (!this.client) {
|
|
return -1;
|
|
}
|
|
var destinationName = mqttConfig.prefix + this.heating + '/cmd/' + 'on' + '/fmt/json';
|
|
this.client.publish(destinationName, 'ON', _callback);
|
|
this.emitter.emit('sendSocket',{id: this.heating, status: true});
|
|
},
|
|
heatingOff: function(callback) {
|
|
var _callback = callback || {};
|
|
if (!this.client) {
|
|
return -1;
|
|
}
|
|
var destinationName = mqttConfig.prefix + this.heating + '/cmd/' + 'off' + '/fmt/json';
|
|
this.client.publish(destinationName, 'OFF', _callback);
|
|
this.emitter.emit('sendSocket',{id: this.heating, status: false});
|
|
},
|
|
lightingOn: function(id, callback) {
|
|
var packet;
|
|
|
|
console.log('lightingOn:' + id);
|
|
var _callback = callback || null;
|
|
if (!this.client) {
|
|
return -1;
|
|
}
|
|
var destinationName = mqttConfig.prefix + this.lighting + '/cmd/' + id + '/fmt/json';
|
|
this.client.publish(destinationName, 'ON', _callback);
|
|
packet = {id: this.lighting, device: id, status: true};
|
|
this.emitter.emit('sendSocket',packet);
|
|
logger.debug('Storing status...');
|
|
this.updateStatus(this.lightList[id], packet);
|
|
},
|
|
lightingOff: function(id, callback) {
|
|
var packet;
|
|
var _callback = callback || null;
|
|
if (!this.client) {
|
|
return -1;
|
|
}
|
|
var destinationName = mqttConfig.prefix + this.lighting + '/cmd/' + id + '/fmt/json';
|
|
this.client.publish(destinationName, 'OFF', _callback);
|
|
packet = {id: this.lighting, device: id, status: false};
|
|
this.emitter.emit('sendSocket', packet);
|
|
this.updateStatus(this.lightList[id], packet);
|
|
},
|
|
lightingCommand: function(id, callback) {
|
|
var packet;
|
|
var _callback = callback || null;
|
|
if (!this.client) {
|
|
return -1;
|
|
}
|
|
var destinationName = mqttConfig.prefix + this.lighting + '/cmd/' + id + '/fmt/json';
|
|
this.client.publish(destinationName, 'cmd', _callback);
|
|
},
|
|
|
|
setupEvents: function() {
|
|
|
|
this.emitter.on('lightingOn', this.lightingOn);
|
|
this.emitter.on('lightingOff', this.lightingOff);
|
|
this.emitter.on('heatingOn', this.heatingOn);
|
|
this.emitter.on('heatingOff', this.heatingOff);
|
|
this.emitter.on('projectorOn', this.projectorOn);
|
|
this.emitter.on('projectorOff', this.projectorOff);
|
|
},
|
|
setupPing: function() {
|
|
logger.warn('Starting ping timer...');
|
|
|
|
this.pingTimer = setTimeout(function() {this.ping();}.bind(this), 10000);
|
|
},
|
|
ping: function() {
|
|
//Logger.error('Ping!');
|
|
this.sendRefresh();
|
|
var now = new Date;
|
|
var mod = 10000 - (now.getTime() % 10000);
|
|
|
|
setTimeout(function() {this.ping();}.bind(this),mod + 10);
|
|
|
|
},
|
|
sendRefresh: function() {
|
|
// logger.debug('+ Send refresh', this.statuses);
|
|
|
|
for (var item in this.statuses) {
|
|
if (this.statuses.hasOwnProperty(item)) {
|
|
console.log(this.statuses[item]);
|
|
this.emitter.emit('sendSocket', this.statuses[item]);
|
|
}
|
|
}
|
|
// logger.debug('+ Send refresh');
|
|
},
|
|
preRestartConnection: function() {
|
|
logger.debug('Restart connection...');
|
|
//this.emitter.emit('restartMQTTSocket', this);
|
|
//logger.debug(this);
|
|
this.restartMQTTSocket();
|
|
},
|
|
startMQTTSocket:function() {
|
|
logger.warn('Restarting socket?');
|
|
this.connectWS();
|
|
},
|
|
restartMQTTSocket: function() {
|
|
this.wsClient.disconnect();
|
|
// setTimeout(this.startMQTTSocket.bind(this), 15000);
|
|
},
|
|
connectWS: function(connectCB) {
|
|
|
|
logger.debug('Going to connect WS');
|
|
var self = this;
|
|
var hostname = 'silvrtree.co.uk';
|
|
var clientId = 'a:' + 'qz0da4' + ':' + Date.now();
|
|
|
|
var api_key = 'martind2000';
|
|
var auth_token = 'MPReoa43';
|
|
|
|
this.wsClient =new Messaging.Client(hostname, 8883, clientId);
|
|
//var wsClient = new Messaging.Client(hostname, 8883, clientId);
|
|
var wsClient = this.wsClient;
|
|
var clientStatus = {connected: false, subscribed: false, deviceConnected: false};
|
|
var sensorData = {};
|
|
|
|
|
|
this.restartTimer = setTimeout(this.preRestartConnection.bind(this), 60000);
|
|
|
|
wsClient.onMessageArrived = function(msg) {
|
|
//logger.info("Message from :" + msg.destinationName);
|
|
clearTimeout(self.restartTimer);
|
|
self.restartTimer = setTimeout(self.preRestartConnection.bind(self), 60000);
|
|
clientStatus.deviceConnected = true;
|
|
sensorData = JSON.parse(msg.payloadString);
|
|
// Logger.debug(sensorData);
|
|
var temp = msg.destinationName.split('/');
|
|
if (self.watches.hasOwnProperty(temp[4])) {
|
|
|
|
// Logger.info('Emit: ' + JSON.stringify({id:self.watches[temp[4]],sensorData:sensorData}));
|
|
|
|
self.emitter.emit('sendSocket',{id: self.watches[temp[4]],sensorData: sensorData});
|
|
}
|
|
|
|
};
|
|
wsClient.onConnectionLost = function(e) {
|
|
logger.error('+ wsClient.onConnectionLost');
|
|
logger.error(e);
|
|
logger.warn('Going to force a restart of the Socket.. Hold on.');
|
|
setTimeout(self.startMQTTSocket.bind(self), 15000);
|
|
//self.emitter.emit('sendSocket',{id: 'deviceLost',data: e});
|
|
//var wsReconnectTimer = setTimeout(function() {logger.debug('TRYING TO RECONNECT TO MQTT');self.emitter.emit('connectWS');}.bind(this),30000);
|
|
logger.error('- wsClient.onConnectionLost');
|
|
};
|
|
|
|
|
|
var connectOptions = {};
|
|
connectOptions.keepAliveInterval = 3600;
|
|
connectOptions.useSSL = true;
|
|
connectOptions.userName = api_key;
|
|
connectOptions.password = auth_token;
|
|
|
|
connectOptions.onSuccess = function() {
|
|
clientStatus.connected = true;
|
|
logger.info('MQTT connected to host: ' + wsClient.host + ' port : ' + wsClient.port + ' at ' + Date.now());
|
|
|
|
self.emitter.emit('clientStatusUpdated', clientStatus);
|
|
self.emitter.emit('clientConnected', self.sockets);
|
|
};
|
|
|
|
connectOptions.onFailure = function(e) {
|
|
self.emitter.emit('sendSocket',{id: 'deviceNotConnecting'});
|
|
logger.error('wsClient onFailure', e);
|
|
logger.error('MQTT connection failed at ' + Date.now() + '\nerror: ' + e.errorCode + ' : ' + e.errorMessage);
|
|
//var wsReconnectTimer = setTimeout(function() {logger.debug('TRYING TO RECONNECT TO MQTT');self.emitter.emit('connectWS');}.bind(this),30000);
|
|
};
|
|
|
|
logger.debug('about to connect to ' + wsClient.host);
|
|
wsClient.connect(connectOptions);
|
|
|
|
this.sockets = {
|
|
|
|
getClientStatus: function() {
|
|
return clientStatus;
|
|
},
|
|
subscribe: function(deviceId, emitterId) {
|
|
logger.debug('trying to subscribe');
|
|
var subscribeTopic = 'iot-2/type/Ti-CC3200/id/' + deviceId + '/evt/+/fmt/json';
|
|
logger.debug(subscribeTopic);
|
|
|
|
var subscribeOptions = {
|
|
qos: 0,
|
|
onSuccess: function() {
|
|
logger.info('subscribed to ' + subscribeTopic);
|
|
clientStatus.subscribed = true;
|
|
// $rootScope.$broadcast("clientStatusUpdated", clientStatus);
|
|
|
|
self.emitter.emit('clientStatusUpdated', clientStatus);
|
|
self.watches[deviceId] = emitterId;
|
|
},
|
|
onFailure: function() {
|
|
logger.error('Failed to subscribe to ' + subscribeTopic);
|
|
logger.error('As messages are not available, visualization is not possible');
|
|
}
|
|
};
|
|
|
|
/*If (IoTFconnector.prototype.clientStatus.subscribeTopic != "") {
|
|
console.log("Unsubscribing to " + subscribeTopic);
|
|
wsClient.unsubscribe(IoTFconnector.prototype.clientStatus.subscribeTopic);
|
|
};*/
|
|
|
|
wsClient.subscribe(subscribeTopic, subscribeOptions);
|
|
}
|
|
};
|
|
|
|
|
|
return this.sockets;
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|