2016-04-13 09:01:28 +00:00
/ * *
* Created by Martin on 08 / 02 / 2016.
* /
2016-04-25 09:35:39 +00:00
'use strict' ;
2016-04-20 13:48:48 +00:00
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' ) ;
2016-04-13 09:01:28 +00:00
var mqttConnect = require ( './lib/mqtt/mqttConnect' ) ;
var log4js = require ( 'log4js' ) ;
var logger = log4js . getLogger ( ) ;
2016-04-28 15:57:44 +00:00
2016-04-13 09:01:28 +00:00
var WebSocketServer = require ( 'websocket' ) . server ;
2016-04-20 13:48:48 +00:00
var EventEmitter = require ( 'events' ) ;
2016-04-13 09:01:28 +00:00
var busEmitter = new EventEmitter ( ) ;
2016-04-29 09:14:00 +00:00
var apn = require ( 'apn' ) ;
2016-04-20 13:48:48 +00:00
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' ) ;
2016-04-27 10:17:11 +00:00
var isProduction = false ;
2016-04-20 13:48:48 +00:00
2016-04-28 15:57:44 +00:00
var iosTokens = [ ] ;
2016-04-29 09:14:00 +00:00
var apnTimer = 0 ;
2016-04-28 15:57:44 +00:00
2016-04-29 10:04:14 +00:00
var apn = require ( 'apn' ) ;
2016-04-29 10:12:32 +00:00
var apnService = new apn . connection ( { key : 'conf/key.pem' ,
cert : 'conf/cert.pem' , production : false } ) ;
2016-04-29 10:04:14 +00:00
apnService . on ( 'connected' , function ( ) {
logger . debug ( 'APN Connected' ) ;
} ) ;
apnService . on ( 'transmitted' , function ( notification , device ) {
logger . debug ( 'APN Notification transmitted to:' + device . token . toString ( 'hex' ) ) ;
} ) ;
apnService . on ( 'transmissionError' , function ( errCode , notification , device ) {
logger . error ( 'APNNotification caused error: ' + errCode + ' for device ' , device , notification ) ;
if ( errCode === 8 ) {
logger . error ( 'A error code of 8 indicates that the device token is invalid. This could be for a number of reasons - are you using the correct environment? i.e. Production vs. Sandbox' ) ;
}
} ) ;
apnService . on ( 'timeout' , function ( ) {
logger . debug ( 'Connection Timeout' ) ;
} ) ;
apnService . on ( 'disconnected' , function ( ) {
logger . debug ( 'Disconnected from APNS' ) ;
} ) ;
apnService . on ( 'socketError' , logger . error ) ;
2016-04-20 13:48:48 +00:00
2016-04-29 09:52:15 +00:00
2016-04-29 09:27:26 +00:00
2016-04-13 09:01:28 +00:00
mqttConnect . setEmitter ( busEmitter ) ;
mqttConnect . doConnection ( ) ;
2016-04-27 10:17:11 +00:00
process . env . NODE _ENV = process . env . NODE _ENV || 'development' ;
if ( process . env . NODE _ENV === 'production' ) {
isProduction = true ;
}
logger . debug ( 'isProduction:' , isProduction ) ;
2016-04-13 09:01:28 +00:00
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 ( {
2016-04-20 13:48:48 +00:00
secret : '1234567890QWERTY' , resave : false , saveUninitialized : false
2016-04-13 09:01:28 +00:00
} ) ) ;
/* 'default', 'short', 'tiny', 'dev' */
app . use ( methodoverride ( ) ) ;
app . use ( bodyparser . urlencoded ( { extended : false } ) ) ;
2016-04-25 09:35:39 +00:00
// Parse application/json
2016-04-13 09:01:28 +00:00
app . use ( bodyparser . json ( ) ) ;
2016-04-20 13:48:48 +00:00
app . use ( function ( req , res , next ) {
2016-04-25 09:35:39 +00:00
res . header ( 'Access-Control-Allow-Origin' , '*' ) ;
res . header ( 'Access-Control-Allow-Headers' , 'X-Requested-With' ) ;
2016-04-20 13:48:48 +00:00
next ( ) ;
2016-04-13 09:01:28 +00:00
} ) ;
2016-04-27 10:17:11 +00:00
// Run npm start --production to use dist
var staticDir = isProduction ? 'dist' : 'app' ;
app . use ( express . static ( path . join ( _ _dirname , staticDir ) ) ) ;
2016-04-13 09:01:28 +00:00
app . use ( errorhandler ( { dumpExceptions : true , showStack : true } ) ) ;
lighting _v1 . use ( mqttConnect ) ;
heating _v1 . use ( mqttConnect ) ;
projector _v1 . use ( mqttConnect ) ;
2016-04-20 13:48:48 +00:00
// Calendar handler
2016-04-25 09:35:39 +00:00
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 ) ;
2016-04-27 10:17:11 +00:00
mqttConnect . setupPing ( ) ;
2016-04-20 13:48:48 +00:00
cal . startController ( busEmitter ) ;
2016-04-25 09:35:39 +00:00
app . get ( '/stop' , function ( request , response ) {
2016-04-20 13:48:48 +00:00
cal . stopController ( ) ;
2016-04-25 09:35:39 +00:00
} ) ;
2016-04-20 13:48:48 +00:00
2016-04-25 09:35:39 +00:00
app . get ( '/start' , function ( request , response ) {
2016-04-20 13:48:48 +00:00
cal . startController ( ) ;
2016-04-25 09:35:39 +00:00
} ) ;
2016-04-20 13:48:48 +00:00
2016-04-25 09:35:39 +00:00
app . get ( '/api/calendar' , function ( req , res ) {
2016-04-20 13:48:48 +00:00
var calJson = cal . returnCalendar ( ) ;
console . log ( calJson ) ;
res . setHeader ( 'Content-Type' , 'application/json' ) ;
res . end ( JSON . stringify ( calJson ) ) ;
2016-04-25 09:35:39 +00:00
} ) ;
2016-04-13 09:01:28 +00:00
2016-04-20 13:48:48 +00:00
app . post ( '/api/calendar/extend' , function ( req , res ) {
res . setHeader ( 'Content-Type' , 'application/json' ) ;
res . end ( JSON . stringify ( { } ) ) ;
2016-04-25 09:35:39 +00:00
} ) ;
2016-04-20 13:48:48 +00:00
// 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 ( ) ;
} ) ;
2016-04-13 09:01:28 +00:00
busEmitter . on ( 'clientStatusUpdated' , ( v ) => {
2016-04-20 13:48:48 +00:00
console . log ( v ) ;
2016-04-13 09:01:28 +00:00
} ) ;
2016-04-20 13:48:48 +00:00
2016-04-13 09:01:28 +00:00
logger . info ( 'Configuring WebSocket Listener...' ) ;
2016-04-20 13:48:48 +00:00
var server = http . createServer ( function ( request , response ) {
console . log ( ( new Date ( ) ) + ' Received request for ' + request . url ) ;
response . writeHead ( 404 ) ;
response . end ( ) ;
2016-04-13 09:01:28 +00:00
} ) ;
2016-04-20 14:29:30 +00:00
server . listen ( 3001 , function ( ) {
2016-04-20 13:48:48 +00:00
console . log ( ( new Date ( ) ) + ' Server is listening on port 8080' ) ;
2016-04-13 09:01:28 +00:00
} ) ;
var wsServer = new WebSocketServer ( {
2016-04-20 13:48:48 +00:00
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
2016-04-13 09:01:28 +00:00
} ) ;
function originIsAllowed ( origin ) {
2016-04-25 09:35:39 +00:00
// Put logic here to detect whether the specified origin is allowed.
2016-04-20 13:48:48 +00:00
return true ;
2016-04-13 09:01:28 +00:00
}
2016-04-20 13:48:48 +00:00
wsServer . on ( 'request' , function ( request ) {
2016-04-13 09:01:28 +00:00
2016-04-20 13:48:48 +00:00
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 ;
}
2016-04-13 09:01:28 +00:00
2016-04-20 13:48:48 +00:00
var connection = request . accept ( 'stream' , request . origin ) ;
console . log ( ( new Date ( ) ) + ' Connection accepted.' ) ;
2016-04-13 09:01:28 +00:00
2016-04-20 13:48:48 +00:00
var sendSocketHandler = ( obj ) => {
2016-04-28 15:57:44 +00:00
//Logger.info('sendSocket: ' , JSON.stringify(obj));
2016-04-27 10:17:11 +00:00
try {
connection . sendUTF ( JSON . stringify ( obj ) ) ;
}
catch ( err ) {
logger . error ( err ) ;
}
2016-04-25 09:35:39 +00:00
} ;
2016-04-13 09:01:28 +00:00
2016-04-20 13:48:48 +00:00
busEmitter . on ( 'sendSocket' , sendSocketHandler ) ;
2016-04-13 09:01:28 +00:00
2016-04-20 13:48:48 +00:00
connection . on ( 'message' , function ( message ) {
if ( message . type === 'utf8' ) {
console . log ( 'Received Message: ' + message . utf8Data ) ;
connection . sendUTF ( message . utf8Data ) ;
2016-04-25 09:35:39 +00:00
} else if ( message . type === 'binary' ) {
2016-04-20 13:48:48 +00:00
console . log ( 'Received Binary Message of ' + message . binaryData . length + ' bytes' ) ;
connection . sendBytes ( message . binaryData ) ;
}
} ) ;
2016-04-13 09:01:28 +00:00
2016-04-20 13:48:48 +00:00
connection . on ( 'close' , function ( reasonCode , description ) {
console . log ( ( new Date ( ) ) + ' Peer ' + connection . remoteAddress + ' disconnected.' ) ;
busEmitter . removeListener ( 'sendSocket' , sendSocketHandler ) ;
} ) ;
2016-04-13 09:01:28 +00:00
} ) ;
2016-04-20 13:48:48 +00:00
mqttConnect . connectWS ( function ( ) {
console . log ( 'Ready to plug in sockets...' ) ;
2016-04-13 09:01:28 +00:00
} ) ;
2016-04-25 09:35:39 +00:00
/*App.get('/ ' , function ( req , res ) {
2016-04-13 09:01:28 +00:00
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 ) ;
2016-04-28 15:57:44 +00:00
app . post ( '/api/v1/register/ios' , function ( req , res ) {
2016-04-29 08:48:34 +00:00
var body = req . body , registrationId ;
2016-04-29 08:42:11 +00:00
2016-04-29 08:44:33 +00:00
logger . debug ( body ) ;
2016-04-29 08:48:34 +00:00
if ( body . hasOwnProperty ( 'registrationId' ) ) {
registrationId = body [ 'registrationId' ] ;
logger . debug ( registrationId ) ;
2016-04-29 08:42:11 +00:00
2016-04-29 08:48:34 +00:00
if ( iosTokens . indexOf ( registrationId ) === - 1 ) {
iosTokens . push ( registrationId ) ;
2016-04-29 08:42:11 +00:00
logger . info ( 'IOS Device registered.' ) ;
2016-04-29 09:14:00 +00:00
apnTimer = setInterval ( function ( ) {
2016-04-29 10:08:13 +00:00
logger . info ( 'Sending the same notification each of the devices with one call to pushNotification.' ) ;
var note = new apn . notification ( ) ;
note . setAlertText ( 'Hello, from node-apn!' ) ;
2016-04-29 10:21:39 +00:00
note . setAlertTitle ( 'Smart Office' ) ;
note . setBadge ( 1 ) ;
note . setSound ( 'dong.aiff' ) ;
2016-04-29 10:08:13 +00:00
note . badge = 1 ;
2016-04-29 09:14:00 +00:00
2016-04-29 10:08:13 +00:00
apnService . pushNotification ( note , iosTokens ) ;
2016-04-29 09:14:00 +00:00
} , 30000 ) ;
2016-04-29 08:42:11 +00:00
}
}
2016-04-28 15:57:44 +00:00
} ) ;
2016-04-20 13:48:48 +00:00
app . listen ( 3000 , function ( ) {
console . log ( 'Express listening on 3000' ) ;
2016-04-13 09:01:28 +00:00
} ) ;