/** * 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: 'a-qz0da4-dfwwdkmkzr', appKey: '9txJEf3Cjy7hkSOvkv', 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', */ module.exports = { pingTimer: 0, statuses: {}, sockets: null, watches: {}, client: null, projector: 'Projector', lighting: 'Lighting', heating: 'Heating', myID: 0, connected: false, options: { keepalive: 3600, 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://' + mqttConfig.orgId + '.messaging.internetofthings.ibmcloud.com', this.options); this.client.on('connect', function() { logger.info('Connected to IBM'); 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 _callback = callback || {}; if (!this.client) { return -1; } var destinationName = mqttConfig.prefix + this.projector + '/cmd/' + 'ON' + '/fmt/json'; this.client.publish(destinationName, 'ON', _callback); this.emitter.emit('sendSocket',{id: this.projector, status: true}); }, projectorOff: function(callback) { var _callback = callback || {}; if (!this.client) { return -1; } var destinationName = mqttConfig.prefix + this.projector + '/cmd/' + 'OFF' + '/fmt/json'; this.client.publish(destinationName, 'OFF', _callback); this.emitter.emit('sendSocket',{id: this.projector, status: false}); }, 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); }, 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'); }, connectWS: function(connectCB) { logger.debug('Going to connect WS'); var self = this; var hostname = 'qz0da4' + '.messaging.internetofthings.ibmcloud.com'; var clientId = 'a:' + 'qz0da4' + ':' + Date.now(); var api_key = 'a-qz0da4-dfwwdkmkzr'; var auth_token = '9txJEf3Cjy7hkSOvkv'; var wsClient = new Messaging.Client(hostname, 8883, clientId); var clientStatus = {connected: false, subscribed: false, deviceConnected: false}; var sensorData = {}; var watches = {}; wsClient.onMessageArrived = function(msg) { //Logger.info("Message from :" + msg.destinationName); 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('+ onConnectionLost'); logger.error(e); logger.error('- 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) { logger.error('MQTT connection failed at ' + Date.now() + '\nerror: ' + e.errorCode + ' : ' + e.errorMessage); }; 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; } };