/** * Created by Martin on 08/02/2016. */ 'use strict'; var express = require('express'); var path = require('path'); var http = require('http'); var ejs = require('ejs'); var morgan = require('morgan'); var cookieparser = require('cookie-parser'); var session = require('express-session'); var methodoverride = require('method-override'); var bodyparser = require('body-parser'); var errorhandler = require('errorhandler'); var mqttConnect = require('./lib/mqtt/mqttConnect'); var log4js = require('log4js'); var logger = log4js.getLogger(); var WebSocketServer = require('websocket').server; var EventEmitter = require('events'); var busEmitter = new EventEmitter(); var apn = require('apn'); var calendar = require('./lib/office/officeController.js'); var cal = new calendar.officeController(busEmitter); var lighting_v1 = require('./routes/lighting_v1'); var heating_v1 = require('./routes/heating_v1'); var projector_v1 = require('./routes/projector_v1'); var isProduction = false; var iosTokens = []; var apnTimer = 0; var settings = { gcm: { id: null, // PUT YOUR GCM SERVER API KEY, options: {}, msgcnt: 1, dataDefaults: { delayWhileIdle: false, timeToLive: 4 * 7 * 24 * 3600, // 4 weeks retries: 4 } }, apn: { gateway: 'gateway.sandbox.push.apple.com', badge: 1, defaultData: { expiry: 5, // 4 weeks sound: 'ping.aiff' } }, adm: { client_id: null, // PUT YOUR ADM CLIENT ID, client_secret: null, // PUT YOUR ADM CLIENT SECRET, expiresAfter: 4 * 7 * 24 * 3600, // 4 weeks } }; var push = new require('node-pushnotifications')(settings); mqttConnect.setEmitter(busEmitter); mqttConnect.doConnection(); process.env.NODE_ENV = process.env.NODE_ENV || 'development'; if (process.env.NODE_ENV === 'production') { isProduction = true; } logger.debug('isProduction:', isProduction); var options = { }; var apnConnection = new apn.Connection(options); var app = express(); app.set('port', process.env.PORT || 4545); app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); app.use(morgan('combined')); app.use(cookieparser('your secret here')); app.use(session({ secret: '1234567890QWERTY', resave: false, saveUninitialized: false })); /* 'default', 'short', 'tiny', 'dev' */ app.use(methodoverride()); app.use(bodyparser.urlencoded({extended: false})); // Parse application/json app.use(bodyparser.json()); app.use(function(req, res, next) { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'X-Requested-With'); next(); }); // Run npm start --production to use dist var staticDir = isProduction ? 'dist' : 'app'; app.use(express.static(path.join(__dirname, staticDir))); app.use(errorhandler({dumpExceptions: true, showStack: true})); lighting_v1.use(mqttConnect); heating_v1.use(mqttConnect); projector_v1.use(mqttConnect); // Calendar handler busEmitter.on('lightingOn', lighting_v1.doLightsOn); busEmitter.on('lightingOff', lighting_v1.doLightsOff); busEmitter.on('heatingOn', mqttConnect.heatingOn); busEmitter.on('heatingOff', mqttConnect.heatingOff); busEmitter.on('projectorOn', mqttConnect.projectorOn); busEmitter.on('projectorOff', mqttConnect.projectorOff); mqttConnect.setupPing(); cal.startController(busEmitter); app.get('/stop', function(request, response) { cal.stopController(); }); app.get('/start', function(request, response) { cal.startController(); }); app.get('/api/calendar', function(req, res) { var calJson = cal.returnCalendar(); console.log(calJson); res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(calJson)); }); app.post('/api/calendar/extend', function(req, res) { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({})); }); // Events and sockets busEmitter.on('clientConnected', (socketSet) => { console.log(socketSet.getClientStatus()); heating_v1.setsocket(socketSet).subscribe(); lighting_v1.setsocket(socketSet).subscribe(); projector_v1.setsocket(socketSet).subscribe(); }); busEmitter.on('clientStatusUpdated', (v) => { console.log(v); }); logger.info('Configuring WebSocket Listener...'); var server = http.createServer(function(request, response) { console.log((new Date()) + ' Received request for ' + request.url); response.writeHead(404); response.end(); }); server.listen(3001, function() { console.log((new Date()) + ' Server is listening on port 8080'); }); var wsServer = new WebSocketServer({ httpServer: server, // You should not use autoAcceptConnections for production // applications, as it defeats all standard cross-origin protection // facilities built into the protocol and the browser. You should // *always* verify the connection's origin and decide whether or not // to accept it. autoAcceptConnections: false }); function originIsAllowed(origin) { // Put logic here to detect whether the specified origin is allowed. return true; } wsServer.on('request', function(request) { if (!originIsAllowed(request.origin)) { // Make sure we only accept requests from an allowed origin request.reject(); console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.'); return; } var connection = request.accept('stream', request.origin); console.log((new Date()) + ' Connection accepted.'); var sendSocketHandler = (obj) => { //Logger.info('sendSocket: ' , JSON.stringify(obj)); try { connection.sendUTF(JSON.stringify(obj)); } catch (err) { logger.error(err); } }; busEmitter.on('sendSocket', sendSocketHandler); connection.on('message', function(message) { if (message.type === 'utf8') { console.log('Received Message: ' + message.utf8Data); connection.sendUTF(message.utf8Data); } else if (message.type === 'binary') { console.log('Received Binary Message of ' + message.binaryData.length + ' bytes'); connection.sendBytes(message.binaryData); } }); connection.on('close', function(reasonCode, description) { console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.'); busEmitter.removeListener('sendSocket', sendSocketHandler); }); }); mqttConnect.connectWS(function() { console.log('Ready to plug in sockets...'); }); /*App.get('/', function( req, res) { res.render('index'); });*/ app.post('/api/v1/lighting/off', lighting_v1.turnoff); app.post('/api/v1/lighting/on', lighting_v1.turnon); app.post('/api/v1/heating/off', heating_v1.turnoff); app.post('/api/v1/heating/on', heating_v1.turnon); app.post('/api/v1/projector/off', projector_v1.turnoff); app.post('/api/v1/projector/on', projector_v1.turnon); app.post('/api/v1/register/ios', function(req, res) { var body = req.body, registrationId; logger.debug(body); if (body.hasOwnProperty('registrationId')) { registrationId = body['registrationId']; logger.debug(registrationId); if (iosTokens.indexOf(registrationId) === -1) { iosTokens.push(registrationId); logger.info('IOS Device registered.'); apnTimer = setInterval(function() { /* Var myDevice = new apn.Device(registrationId[0]); var note = new apn.Notification(); note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now. note.badge = 3; note.sound = "ping.aiff"; note.alert = "\uD83D\uDCE7 \u2709 You have a new message"; note.payload = {'messageFrom': 'Caroline'}; apnConnection.pushNotification(note, myDevice);*/ logger.warn('Sending Apple Notifications'); data = {title: 'New push notification' , message: 'Powered by Martin', otherfields: 'optionally add more data'}; push.sendPush(iosTokens, data, function(result) { logger.debug(result); }); }, 30000); } } }); app.listen(3000, function() { console.log('Express listening on 3000'); });