2016-04-20 13:48:48 +00:00
'use strict' ;
var calendar = require ( './calendarInterface' ) ;
var mqttClient = require ( '../mqtt/mqttClient' ) ;
var cron = require ( 'node-cron' ) ;
var log4js = require ( 'log4js' ) ;
var logger = log4js . getLogger ( ) ;
var events = require ( 'events' ) ;
var eventBus ;
var util = require ( 'util' ) ;
2016-04-29 11:09:43 +00:00
var apn = require ( 'apn' ) ;
2016-04-29 13:49:18 +00:00
var jsonfile = require ( 'jsonfile' ) ;
var file = 'data/iostokens.json' ;
2016-05-11 16:03:25 +00:00
require ( 'sugar' ) ;
2016-04-29 11:09:43 +00:00
var apnService = new apn . connection ( { key : 'conf/key.pem' ,
cert : 'conf/cert.pem' , production : false } ) ;
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-05-11 16:03:25 +00:00
var officeController = function ( neweventBus ) {
2016-04-29 11:09:43 +00:00
this . iosTokens = [ ] ;
2016-05-11 16:03:25 +00:00
this . masterCRON = { } ;
2016-04-20 13:48:48 +00:00
2016-05-11 16:03:25 +00:00
logger . debug ( ( typeof neweventBus ) ) ;
if ( ( typeof neweventBus !== 'undefined' ) && ( neweventBus !== null ) ) {
eventBus = neweventBus ;
2016-04-20 13:48:48 +00:00
} else {
eventBus = new events ( ) ;
}
console . log ( '~~~ officeController' ) ;
this . cloneObject = function ( from , to ) {
if ( Object . keys ( from ) . length !== 0 ) {
for ( var key in from ) {
if ( from . hasOwnProperty ( key ) ) {
if ( key !== 'cronJOBS' ) {
to [ key ] = from [ key ] ;
}
}
}
}
} ;
2016-05-11 16:03:25 +00:00
jsonfile . readFile ( file , function ( err , obj ) {
if ( err ) {
2016-04-29 13:49:18 +00:00
logger . error ( err ) ;
}
2016-04-29 13:56:16 +00:00
this . iosTokens = obj ;
2016-04-29 13:49:18 +00:00
} . bind ( this ) ) ;
this . saveTimer = 0 ;
2016-04-20 13:48:48 +00:00
var self = this ;
this . schedule = { } ;
this . todaysList = { } ;
this . calendarControl = new calendar . calendarInterface ( ) ;
this . calendarControl . getRoomStatusV2 ( ( todaysList ) => {
this . todaysList = todaysList ;
this . setupNextMeeting ( todaysList ) ;
} ) ;
2016-05-11 16:03:25 +00:00
this . mqtt = new mqttClient . mqttClient ( ) ;
2016-04-20 13:48:48 +00:00
this . task = cron . schedule ( '* * * * *' , function ( ) {
var n = new Date ( ) ;
var curMeeting = { } ;
this . cloneObject ( this . todaysList . current , curMeeting ) ;
curMeeting . cronJobs = { } ;
2016-04-25 09:35:39 +00:00
eventBus . emit ( 'sendSocket' , { id : 'calendar' , current : curMeeting } ) ;
2016-04-20 13:48:48 +00:00
} . bind ( this ) ) ;
this . task = cron . schedule ( '*/5 * * * *' , function ( ) {
2016-05-11 16:03:25 +00:00
//This.task = cron.schedule('*/2 * * * *', function() {
2016-04-20 13:48:48 +00:00
this . calendarControl . getRoomStatusV2 ( ( todaysList ) => {
2016-05-11 16:03:25 +00:00
var _iEnd ;
var _iStart ;
var _now ;
logger . debug ( '+ getRoomStatusV2 CB' ) ;
if ( Object . has ( todaysList . current , 'uid' ) ) {
if ( Object . has ( this . schedule , todaysList . current . uid ) ) {
todaysList . current . actualEnd = this . schedule [ todaysList . current . uid ] . actualEnd ;
}
} else {
// There is no current meeting, check if there should be a meeting
_now = new Date ( ) ;
for ( var item in this . schedule ) {
if ( this . schedule . hasOwnProperty ( item ) ) {
if ( ! this . schedule [ item ] . hasOwnProperty ( 'done' ) ) {
_iStart = Date . create ( this . schedule [ item ] . dtstart ) ;
_iEnd = Date . create ( this . schedule [ item ] . actualEnd ) . addSeconds ( - 1 ) ;
logger . debug ( _now , ' between ' , _iStart , _iEnd ) ;
if ( _now . isBetween ( _iStart , _iEnd ) ) {
todaysList . current = this . schedule [ item ] ;
}
} else {
logger . debug ( 'Meeting ' , item , ' is done with.' ) ;
}
}
}
}
2016-04-20 13:48:48 +00:00
this . todaysList = todaysList ;
this . setupNextMeeting ( todaysList ) ;
var data = todaysList ;
data . id = 'calendarData' ;
eventBus . emit ( 'sendSocket' , data ) ;
2016-05-11 16:03:25 +00:00
logger . debug ( '- getRoomStatusV2 CB' ) ;
2016-04-20 13:48:48 +00:00
} ) ;
} . bind ( this ) ) ;
eventBus . on ( 'setupNextMeeting' , this . setupNextMeeting . bind ( this , this . todaysList ) ) ;
2016-04-29 13:11:12 +00:00
logger . debug ( 'Todayslist' , this . todaysList ) ;
2016-04-20 13:48:48 +00:00
eventBus . on ( 'cleanUp' , ( id ) => {
logger . debug ( '+ => cleanUp' ) ;
this . cleanUpMeeting ( id ) ;
} ) ;
2016-04-27 10:17:11 +00:00
eventBus . on ( 'announce' , ( meeting ) => {
logger . debug ( '+ => announce' ) ;
this . announceMeetingEnd ( meeting ) ;
} ) ;
2016-04-29 13:15:44 +00:00
2016-04-20 13:48:48 +00:00
} ;
2016-04-29 13:49:18 +00:00
officeController . prototype . saveData = function ( ) {
2016-04-29 13:52:26 +00:00
jsonfile . writeFile ( file , this . iosTokens , function ( err , obj ) {
2016-05-11 16:03:25 +00:00
if ( err ) {
2016-04-29 13:52:26 +00:00
logger . error ( err ) ;
}
} ) ;
2016-05-11 16:03:25 +00:00
} ;
2016-04-29 13:49:18 +00:00
2016-04-29 13:00:40 +00:00
officeController . prototype . sendiOSAPN = function ( packet ) {
2016-05-11 16:03:25 +00:00
logger . info ( 'Sending the iOS Push Notifications.' ) ;
2016-04-29 13:00:40 +00:00
var note = new apn . notification ( ) ;
2016-05-11 16:03:25 +00:00
2016-04-29 13:00:40 +00:00
note . setAlertText ( packet . msg ) ;
note . setAlertTitle ( 'Smart Office' ) ;
note . setBadge ( 1 ) ;
note . setSound ( 'dong.aiff' ) ;
note . badge = 1 ;
apnService . pushNotification ( note , this . iosTokens ) ;
} ;
2016-04-27 10:17:11 +00:00
officeController . prototype . announceMeetingEnd = function ( meeting ) {
logger . debug ( 'announceMeetingEnd' , meeting ) ;
2016-05-11 16:03:25 +00:00
var msg = [ 'The meeting "' , meeting . summary , '" is due to end in five minutes. Would you like to extend it?' ] . join ( '' ) ;
2016-04-27 10:17:11 +00:00
var packet = { id : 'announce' , msg : msg , uid : meeting . uid } ;
eventBus . emit ( 'sendSocket' , packet ) ;
2016-04-28 15:57:44 +00:00
2016-04-29 13:15:44 +00:00
this . sendiOSAPN ( packet ) ;
2016-04-28 15:57:44 +00:00
2016-04-27 10:17:11 +00:00
} ;
2016-04-20 13:48:48 +00:00
officeController . prototype . cleanUpMeeting = function ( id ) {
2016-05-11 16:03:25 +00:00
this . schedule [ id ] . done = true ;
delete this . masterCRON [ id ] ;
eventBus . emit ( 'sendSocket' , { id : 'calendar' , current : { } , finished : 'true' } ) ;
2016-04-20 13:48:48 +00:00
} ;
officeController . prototype . createMeeting = function ( obj , delayStart ) {
2016-05-11 16:03:25 +00:00
var newMeeting = obj ;
var _delayStart = delayStart || false ;
var cronStartStr ;
var uid = newMeeting . uid ;
2016-04-20 13:48:48 +00:00
var now = new Date . create ( ) ;
var self = this ;
2016-04-27 10:17:11 +00:00
2016-05-11 16:03:25 +00:00
if ( _delayStart ) {
2016-04-27 10:17:11 +00:00
cronStartStr = now . addSeconds ( 5 ) . format ( '{s} {m} {H} * * *' ) ;
2016-04-20 13:48:48 +00:00
} else {
cronStartStr = newMeeting . cronStart ;
}
2016-05-11 16:03:25 +00:00
if ( ! this . masterCRON . hasOwnProperty ( uid ) ) {
this . masterCRON [ uid ] = { start : null , stop : null , alert : null } ;
}
2016-04-20 13:48:48 +00:00
2016-05-11 16:03:25 +00:00
this . masterCRON [ uid ] . start = cron . schedule ( cronStartStr , function ( ) {
2016-04-20 13:48:48 +00:00
var n = new Date ( ) ;
logger . debug ( 'MEETING STARTED!!!!' , n ) ;
var key = Object . keys ( self . schedule ) [ 0 ] ;
2016-04-27 10:17:11 +00:00
2016-04-20 13:48:48 +00:00
var curMeeting = { } ;
self . cloneObject ( self . schedule [ key ] , curMeeting ) ;
2016-04-27 10:17:11 +00:00
2016-04-25 09:35:39 +00:00
// Lets turn on some lights!
eventBus . emit ( 'lightingOn' , 'o' ) ;
eventBus . emit ( 'lightingOn' , 'n' ) ;
2016-05-20 15:28:26 +00:00
eventBus . emit ( 'projectorOn' ) ;
2016-04-25 09:35:39 +00:00
2016-05-11 16:03:25 +00:00
logger . debug ( 'masterCRON' , self . masterCRON ) ;
2016-04-25 09:35:39 +00:00
eventBus . emit ( 'sendSocket' , { id : 'calendar' , current : curMeeting } ) ;
2016-04-20 13:48:48 +00:00
} , true ) ;
2016-05-11 16:03:25 +00:00
this . masterCRON [ uid ] . alert = cron . schedule ( newMeeting . cronAlert , function ( ) {
logger . error ( 'ORIGINAL MEETING ends in 5 minutes' ) ;
2016-04-27 10:17:11 +00:00
logger . debug ( this ) ;
// Announce there are five minutes remaining..
eventBus . emit ( 'announce' , newMeeting ) ;
} . bind ( this ) , true ) ;
2016-05-11 16:03:25 +00:00
this . masterCRON [ uid ] . stop = cron . schedule ( newMeeting . cronStop , function ( ) {
2016-04-20 13:48:48 +00:00
var n = new Date ( ) ;
2016-05-11 16:03:25 +00:00
logger . debug ( 'ORIGINAL MEETING ENDED' + n ) ;
this . masterCRON [ uid ] . start = null ;
this . masterCRON [ uid ] . stop = null ;
this . masterCRON [ uid ] . alert = null ;
2016-04-20 13:48:48 +00:00
2016-04-25 09:35:39 +00:00
eventBus . emit ( 'lightingOn' , 'f' ) ;
eventBus . emit ( 'lightingOn' , 'g' ) ;
2016-05-11 16:03:25 +00:00
logger . debug ( this . masterCRON [ uid ] ) ;
eventBus . emit ( 'cleanUp' , uid ) ;
2016-04-20 13:48:48 +00:00
} . bind ( this ) , true ) ;
this . schedule [ newMeeting . uid ] = newMeeting ;
2016-05-11 16:03:25 +00:00
newMeeting = null ;
2016-04-20 13:48:48 +00:00
} ;
officeController . prototype . setupNextMeeting = function ( calData ) {
2016-05-11 16:03:25 +00:00
logger . debug ( '+ setupNextMeeting' ) ;
2016-04-20 13:48:48 +00:00
var self = this ;
if ( Object . keys ( calData . current ) . length > 0 ) {
if ( this . schedule . hasOwnProperty ( calData . current . uid ) ) {
logger . debug ( 'Current Meeting exists in schedule' ) ;
2016-05-11 16:03:25 +00:00
logger . debug ( this . schedule [ calData . current . uid ] ) ;
2016-04-20 13:48:48 +00:00
} else {
logger . debug ( 'Current Meeting does NOT exist in schedule' ) ;
this . createMeeting ( calData . current , true ) ;
}
}
if ( calData . upcoming . length > 0 ) {
for ( var uCount = 0 ; uCount < calData . upcoming . length ; uCount ++ ) {
var uEntry = calData . upcoming [ uCount ] ;
if ( this . schedule . hasOwnProperty ( uEntry . uid ) ) {
logger . debug ( 'Upcoming Meeting exists in schedule' ) ;
// Lets check to see if it's changed in anyway..
var origEntry , origStart , origEnd , newStart , newEnd ;
origEntry = this . schedule [ uEntry . uid ] ;
origStart = Date . create ( origEntry . dtstart ) ;
origEnd = Date . create ( origEntry . dtend ) ;
newStart = Date . create ( uEntry . dtstart ) ;
newEnd = Date . create ( uEntry . dtend ) ;
2016-05-11 16:03:25 +00:00
if ( ( origStart . getTime ( ) !== newStart . getTime ( ) ) || ( origEnd . getTime ( ) !== newEnd . getTime ( ) ) ) {
2016-04-20 13:48:48 +00:00
logger . error ( 'WE HAVE A CHANGED ENTRY!!' ) ;
2016-05-11 16:03:25 +00:00
self . masterCRON [ uEntry . uid ] . start . destroy ( ) ;
self . masterCRON [ uEntry . uid ] . stop . destroy ( ) ;
self . masterCRON [ uEntry . uid ] . alert . destroy ( ) ;
2016-04-20 13:48:48 +00:00
origEntry = uEntry ;
this . createMeeting ( origEntry ) ;
}
} else {
logger . debug ( 'Upcoming meeting does NOT exist in schedule' ) ;
var newMeeting = uEntry ;
this . createMeeting ( newMeeting ) ;
}
}
}
} ;
officeController . prototype . startController = function ( eventBus ) {
console . log ( 'Starting.' ) ;
getRoomStatus ( ) ;
2016-05-11 16:03:25 +00:00
this . timer = setInterval ( function ( ) { getRoomStatus ( ) ; } , 300000 ) ;
2016-04-20 13:48:48 +00:00
} ;
officeController . prototype . stopController = function ( ) {
console . log ( 'Stopping.' ) ;
clearInterval ( this . timer ) ;
} ;
officeController . prototype . returnCalendar = function ( ) {
var exportList ;
exportList = this . calendarControl . getCachedStatus ( ) ;
logger . debug ( exportList ) ;
return exportList ;
} ;
2016-04-29 11:09:43 +00:00
officeController . prototype . registeriOSToken = function ( id ) {
if ( this . iosTokens . indexOf ( id ) === - 1 ) {
this . iosTokens . push ( id ) ;
logger . info ( 'C - IOS Device registered.' ) ;
2016-04-29 13:49:18 +00:00
clearTimeout ( this . saveTimer ) ;
2016-05-11 16:03:25 +00:00
this . saveTimer = setTimeout ( function ( ) { this . saveData ( ) ; } . bind ( this ) , 10000 ) ;
2016-04-29 11:09:43 +00:00
}
} ;
2016-05-11 16:03:25 +00:00
officeController . prototype . extendMeeting = function ( data ) {
logger . debug ( '+ officeController.extendMeeting' ) ;
var self = this ;
if ( Object . has ( this . todaysList . current , 'uid' ) ) {
if ( this . todaysList . current . uid === data . uid ) {
var newActualEnd = Date . create ( this . todaysList . current . actualEnd ) . addMinutes ( data . extendBy ) ;
this . todaysList . current . actualEnd = newActualEnd ;
logger . debug ( this . todaysList ) ;
if ( this . schedule . hasOwnProperty ( data . uid ) ) {
logger . info ( 'updating ' , data . uid ) ;
var updateSchedule = this . schedule [ data . uid ] ;
updateSchedule . actualEnd = newActualEnd ;
updateSchedule . timeEnd = updateSchedule . actualEnd . format ( '{24hr}:{mm}:{ss} {tt}' ) ;
updateSchedule . cronStop = updateSchedule . actualEnd . format ( '{m} {H} * * *' ) ;
var fiveMins = Date . create ( updateSchedule . actualEnd ) . addMinutes ( '-5' ) ;
updateSchedule . cronAlert = fiveMins . format ( '{m} {H} * * *' ) ;
logger . debug ( 'cronAlert now ' + updateSchedule . cronAlert ) ;
logger . debug ( 'cronStop now ' + updateSchedule . cronStop ) ;
self . masterCRON [ data . uid ] . stop . destroy ( ) ;
self . masterCRON [ data . uid ] . alert . destroy ( ) ;
logger . debug ( '!!Extended' , self . masterCRON ) ;
self . masterCRON [ data . uid ] . alert = cron . schedule ( updateSchedule . cronAlert , function ( ) {
logger . error ( 'EXTENDED MEETING ends in 5 minutes' ) ;
// Announce there are five minutes remaining..
2016-04-29 11:09:43 +00:00
2016-05-11 16:03:25 +00:00
eventBus . emit ( 'announce' , updateSchedule ) ;
} . bind ( this ) , true ) ;
self . masterCRON [ data . uid ] . stop = cron . schedule ( updateSchedule . cronStop , function ( ) {
var n = new Date ( ) ;
logger . debug ( 'EXTENDED MEETING ENDED' + n ) ;
self . masterCRON [ data . uid ] . start . destroy ( ) ;
self . masterCRON [ data . uid ] . stop . destroy ( ) ;
self . masterCRON [ data . uid ] . alert . destroy ( ) ;
eventBus . emit ( 'lightingOn' , 'f' ) ;
eventBus . emit ( 'lightingOn' , 'g' ) ;
logger . debug ( self . masterCRON [ data . uid ] ) ;
eventBus . emit ( 'cleanUp' , data . uid ) ;
} . bind ( this ) , true ) ;
this . schedule [ data . uid ] = updateSchedule ;
this . todaysList . current = updateSchedule ;
eventBus . emit ( 'sendSocket' , { id : 'calendar' , current : this . todaysList . current , extended : 'true' } ) ;
logger . warn ( '-=-=-=-=-' ) ;
logger . debug ( this . schedule ) ;
logger . warn ( '#=#=#=#=#' ) ;
logger . debug ( this . todaysList ) ;
}
}
}
logger . debug ( '- officeController.extendMeeting' ) ;
} ;
2016-04-20 13:48:48 +00:00
var meetingStates = {
STARTING : 0 ,
INPROGRESS : 1 ,
NONE : 2 ,
FINISHED : 3
} ;
function getRoomStatus ( ) {
return ;
// Var calendarControl = new calendar.calendarInterface();
// var status = calendarControl.getRoomStatusV2();
var status = officeController . calendarControl . getRoomStatusV2 ( ) ;
if ( status == meetingStates . STARTING ) {
console . log ( 'Meeting about to start - turning on.' ) ;
this . mqtt . projectorOn ( ) ;
this . mqtt . lightsOn ( ) ;
}
if ( status == meetingStates . INPROGRESS ) {
console . log ( 'Meeting in progress - do nothing.' ) ;
}
if ( status == meetingStates . NONE ) {
console . log ( 'No meeting - do nothing.' ) ;
}
if ( status == meetingStates . FINISHED ) {
console . log ( 'No meeting - do nothing.' ) ;
this . mqtt . projectorOff ( ) ;
this . mqtt . lightsOff ( ) ;
}
}
module . exports . officeController = officeController ;