Adding some stuff. confirmations, persistent buttons etc.

This commit is contained in:
Martin Donnelly 2016-04-27 11:17:11 +01:00
parent 64d186e4a5
commit 244f0a2b40
13 changed files with 919 additions and 27 deletions

View File

@ -3,6 +3,10 @@
"Promise",
"$"
],
"globals": {
"$": false,
"MicroEvent": false
},
"node":true,
"browser": true,
"boss": true,

29
app.js
View File

@ -27,11 +27,21 @@ 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;
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 app = express();
app.set('port', process.env.PORT || 4545);
@ -55,8 +65,11 @@ app.use(function(req, res, next) {
res.header('Access-Control-Allow-Headers', 'X-Requested-With');
next();
});
// App.use(app.router);
app.use(express.static(path.join(__dirname, 'app')));
// 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);
@ -74,7 +87,7 @@ busEmitter.on('projectorOn', mqttConnect.projectorOn);
busEmitter.on('projectorOff', mqttConnect.projectorOff);
mqttConnect.setupPing();
cal.startController(busEmitter);
app.get('/stop', function(request, response) {
@ -153,8 +166,14 @@ wsServer.on('request', function(request) {
console.log((new Date()) + ' Connection accepted.');
var sendSocketHandler = (obj) => {
// Logger.info('sendSocket: ' , JSON.stringify(obj));
connection.sendUTF(JSON.stringify(obj));
//logger.info('sendSocket: ' , JSON.stringify(obj));
try {
connection.sendUTF(JSON.stringify(obj));
}
catch (err) {
logger.error(err);
}
};
busEmitter.on('sendSocket', sendSocketHandler);

View File

@ -206,6 +206,10 @@
<!-- endbuild -->
<!-- build:js -->
<script src="js/app.js"></script></body>
<script src="js/sowebsocket.js"></script>
<script src="js/colours.js"></script>
<script src="js/appv2.js"></script>
</body>
<!-- endbuild -->
</html>

View File

@ -605,6 +605,7 @@ var show_weather = function(position) {
/*
(function() {
path = 'http://localhost:3000/';
@ -619,6 +620,7 @@ var show_weather = function(position) {
get_weather();
var soWebSocket = new SOWEBSOCKET();
})();
*/
document.addEventListener('deviceready', onDeviceReady, false);

347
app/js/appv2.js Normal file
View File

@ -0,0 +1,347 @@
/*
SO App v2
*/
var skycons = new Skycons({color: '#e5f7fd'});
var SOController = (function() {
'use strict';
var path;
var wsUrl;
var local = true;
var bus = {};
var prevDate;
var prevTime;
var weatherTimer = 0;
var weatherStore = null;
var lastWeatherRequest = 0;
var soWebSocket;
var lightsList = {
off: ['frontLightOff', 'backLightOff'], on: ['frontLightOn', 'backLightOn']
};
if (local) {
path = 'http://localhost:3000/';
wsUrl = 'ws://localhost:3001';
} else {
wsUrl = 'ws://ec2-52-50-147-81.eu-west-1.compute.amazonaws.com:8080';
path = 'http://ec2-52-50-147-81.eu-west-1.compute.amazonaws.com/';
}
MicroEvent.mixin(bus);
var iOS = ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0;
if (iOS) {
$('#iosTaskbar').show();
path = 'http://localhost:3000/';
}
var module = {lights: lightsList};
var storage = {};
storage.supportsLocalStorage = function() {
try {
return !localStorage ? false : true;
}
catch (e) {
return false;
}
};
storage._localStorage = storage.supportsLocalStorage();
if (storage._localStorage) {
storage.LocalStorage = {
save: function(i, v) {
localStorage[i] = v;
}, load: function(i) {
return localStorage[i];
}
};
} else {
storage.LocalStorage = {
save: function(i, v) {
document.cookie = (i) + '=' + encodeURIComponent(v);
}, load: function(i) {
var s;
var p;
s = '; ' + document.cookie + ';';
p = s.indexOf('; ' + i + '=');
if (p < 0) {
return '';
}
p = p + i.length + 3;
var p2 = s.indexOf(';', p + 1);
return decodeURIComponent(s.substring(p, p2));
}
};
}
function updateCalendar(d) {
var $calendar = $('#calendar');
if (d.current !== null && d.current.hasOwnProperty('dtstart')) {
var calString = [
'<div class="mui--text-subhead">', d.current.summary,
'</div>'
].join('');
$('#caltext').html(calString);
$calendar.slideDown();
} else {
$calendar.slideUp();
}
}
function updateDateTime() {
var now = Date.create(new Date());
var $date = $('#date');
var $time = $('#time');
var curTime = now.format('<span class="hour">{24hr}</span>{mm}');
var curDate = now.format('{yyyy}-{MM}-{dd}');
if (prevTime !== curTime) {
$time.html(curTime);
// UpdateCalendar();
prevTime = curTime;
}
if (prevDate !== curDate) {
$date.html(now.format(
'<span class="wd-{do}">{Weekday}</span><br><span class="mo mo-{M}">{Month} {dd}</span><br>{yyyy}'));
prevDate = curDate;
}
}
function turnOnLights(id) {
console.log(id);
$.post(path + 'api/v1/lighting/on', {light: id}, function() {});
}
function turnOffLights(id) {
$.post(path + 'api/v1/lighting/off', {light: id}, function() {});
}
function turnOnHeating() {
$.post(path + 'api/v1/heating/on', {}, function() {});
}
function turnOffHeating() {
$.post(path + 'api/v1/heating/off', {}, function() {});
}
function turnOnProjector() {
$.post(path + 'api/v1/projector/on', {}, function() {});
}
function turnOffProjector() {
$.post(path + 'api/v1/projector/off', {}, function() {});
}
function attachClicks() {
$('#projectorOn').on('click', function() {
turnOnProjector();
});
$('#projectorOff').on('click', function() {
turnOffProjector();
});
$('#heatingOn').on('click', function() {
turnOnHeating();
});
$('#heatingOff').on('click', function() {
turnOffHeating();
});
$('#frontLightOn').on('click', function() {
// 1 for board lights
turnOnLights('o');
});
$('#middleLightOn').on('click', function() {
turnOnLights(2);
});
$('#backLightOn').on('click', function() {
// 3 for board lights
turnOnLights('n');
});
$('#frontLightOff').on('click', function() {
// A for board lights
turnOffLights('f');
});
$('#middleLightOff').on('click', function() {
turnOffLights('b');
});
$('#backLightOff').on('click', function() {
turnOffLights('g');
});
}
function clock() {
updateDateTime();
var now = new Date;
var mod = 60000 - (now.getTime() % 60000);
setTimeout(function() {clock();}, mod + 10);
}
var get_weather = function() {
navigator.geolocation.getCurrentPosition(show_weather,
function(e) {alert(e.code + ' / ' + e.message);});
};
bus.bind('displayWeather', function(data) {
console.log(data.currently);
$('#weatherText').html(parseInt(data.currently.temperature) + '&deg;c&nbsp;');
skycons.add('icon1', data.currently.icon);
});
var weatherClock = function() {
get_weather();
var now = new Date;
var mod = 1800000 - (now.getTime() % 1800000);
weatherTimer = setTimeout(function() {weatherClock();}, mod + 10);
};
var show_weather = function(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
// Show cached first before doing a long request.
// forecast.io is a bit slow.
var doRefresh = false;
if (weatherStore === null) {
var w = storage.LocalStorage.load('weather');
if (typeof w !== 'undefined') {
w = JSON.parse(w);
weatherStore = w;
bus.trigger('displayWeather', w);
} else {
doRefresh = true;
}
} else {
doRefresh = true;
}
// Let's show a map or do something interesting!
if (doRefresh) {
var now = new Date();
if (now.getTime() - lastWeatherRequest < 10000) {
// Sometimes when the app loses focus, and then returns the weather requests queue up
// this ensures that we don't do multiple requests within a ten second window
return -1;
}
lastWeatherRequest = now.getTime();
$.ajax({
type: 'GET',
url: 'https://api.forecast.io/forecast/0657dc0d81c037cbc89ca88e383b6bbf/' + latitude.toString() + ',' + longitude.toString() + '?units=uk2',
data: '',
dataType: 'jsonp',
timeout: 10000,
context: $('body'),
contentType: ('application/json'),
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'PUT, GET, POST, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
},
success: function(data) {
storage.LocalStorage.save('weather', JSON.stringify(data));
weatherStore = data;
console.log('fresh..');
bus.trigger('displayWeather', data);
},
error: function(xhr, type) {
console.error('ajax error');
console.error(xhr);
console.error(type);
}
});
}
};
var browserNotify = function(d) {
console.log('BrowserNotify:', d);
if (Notification.permission !== 'granted')
Notification.requestPermission();
else {
var notification = new Notification('SmartOffice Console', {
icon: '/fav/favicon-96x96.png',
body: d.msg
});
notification.onclick = function() {
//window.open("http://stackoverflow.com/a/13328397/1269037");
console.log('click');
};
}
};
var notifyConfirm = function(r) {
console.log(r);
};
var cordovaNotify = function(d) {
navigator.notification.confirm(
d.msg, // message
notifyConfirm, // callback to invoke with index of button pressed
'Smartoffice Console', // title
['Extend','Ignore'] // buttonLabels
);
};
//
module.init = function() {
attachClicks();
clock();
weatherClock();
soWebSocket = new SOWEBSOCKET(this);
};
module.updateCalendar = function(data) {
updateCalendar(data);
};
module.webSocketURL = function() {
return wsUrl;
};
module.notify = function(d) {
if (window.cordova && !(window.cordova instanceof HTMLElement)) {
document.addEventListener('deviceready', onDeviceReady, false);
} else {
browserNotify(d);
}
};
return module;
})();
function onDeviceReady() {
SOController.init();
}
;(function() {
if (window.cordova && !(window.cordova instanceof HTMLElement)) {
document.addEventListener('deviceready', onDeviceReady, false);
} else {
onDeviceReady();
Notification.requestPermission();
}
})();

200
app/js/colours.js Normal file
View File

@ -0,0 +1,200 @@
var tempColours = [
{
t: 0,
r: 80,
g: 181,
b: 221
},
{
t: 1,
r: 80,
g: 181,
b: 221
},
{
t: 2,
r: 80,
g: 181,
b: 221
},
{
t: 3,
r: 80,
g: 181,
b: 221
},
{
t: 4,
r: 80,
g: 181,
b: 221
},
{
t: 5,
r: 80,
g: 181,
b: 221
},
{
t: 6,
r: 78,
g: 178,
b: 206
},
{
t: 7,
r: 76,
g: 176,
b: 190
},
{
t: 8,
r: 73,
g: 173,
b: 175
},
{
t: 9,
r: 72,
g: 171,
b: 159
},
{
t: 10,
r: 70,
g: 168,
b: 142
},
{
t: 11,
r: 68,
g: 166,
b: 125
},
{
t: 12,
r: 66,
g: 164,
b: 108
},
{
t: 13,
r: 102,
g: 173,
b: 94
},
{
t: 14,
r: 135,
g: 190,
b: 64
},
{
t: 15,
r: 179,
g: 204,
b: 26
},
{
t: 16,
r: 214,
g: 213,
b: 28
},
{
t: 17,
r: 249,
g: 202,
b: 3
},
{
t: 18,
r: 246,
g: 181,
b: 3
},
{
t: 19,
r: 244,
g: 150,
b: 26
},
{
t: 20,
r: 236,
g: 110,
b: 5
},
{
t: 21,
r: 234,
g: 90,
b: 36
},
{
t: 22,
r: 228,
g: 87,
b: 43
},
{
t: 23,
r: 225,
g: 74,
b: 41
},
{
t: 24,
r: 224,
g: 65,
b: 39
},
{
t: 25,
r: 217,
g: 55,
b: 43
},
{
t: 26,
r: 214,
g: 49,
b: 41
},
{
t: 27,
r: 209,
g: 43,
b: 43
},
{
t: 28,
r: 205,
g: 40,
b: 47
},
{
t: 29,
r: 200,
g: 36,
b: 50
},
{
t: 30,
r: 195,
g: 35,
b: 52
},
{
t: 31,
r: 190,
g: 33,
b: 56
},
{
t: 32,
r: 185,
g: 32,
b: 59
}
];

231
app/js/sowebsocket.js Normal file
View File

@ -0,0 +1,231 @@
/**
*
* User: Martin Donnelly
* Date: 2016-04-25
* Time: 12:03
*
*/
'use strict';
var SOWEBSOCKET = function(newController) {
var controller = newController;
this.socket = null;
this.retry = 0;
this.timer = 0;
this.previousTemp = 0;
function rgb(cv) {
return ['rgb(', cv.r, ',', cv.g, ',', cv.b, ')'].join('');
}
this.startWebSocket = function() {
console.log('Starting socket?');
var url = controller.webSocketURL();
var wsCtor = window['MozWebSocket'] ? MozWebSocket : WebSocket;
this.socket = new wsCtor(url, 'stream');
this.socket.onopen = this.handleWebsocketOnOpen.bind(this);
this.socket.onmessage = this.handleWebsocketMessage.bind(this);
this.socket.onclose = this.handleWebsocketClose.bind(this);
this.socket.onerror = function(e) {
console.error('!!WebSocket Error');
console.error(e);
};
};
this.updateHeating = function(obj) {
var $curTemp = $('#curTemp');
if (this.previousTemp !== obj.temp) {
$curTemp.text(obj.temp);
$curTemp.css('color', rgb(tempColours[parseInt(obj.temp)]));
this.previousTemp = obj.temp;
}
};
this.toggleLighting = function(id) {
var _id;
var _off = ['f', 'g'];
var _on = ['o', 'n'];
var $show;
var $hide;
_id = _off.indexOf(id);
// console.log(id,_id);
if (_id > -1) {
// Lights are being turnd off
$hide = ['#', controller.lights.off[_id]].join('');
$show = ['#', controller.lights.on[_id]].join('');
} else {
_id = _on.indexOf(id);
$show = ['#', controller.lights.off[_id]].join('');
$hide = ['#', controller.lights.on[_id]].join('');
}
$($show).show();
$($hide).hide();
};
this.toggleHeating = function(status) {
var $show, $hide;
if (status) {
$hide = $('#heatingOn');
$show = $('#heatingOff');
} else {
$show = $('#heatingOn');
$hide = $('#heatingOff');
}
$($show).show();
$($hide).hide();
};
this.toggleProjector = function(status) {
var $show, $hide;
if (status) {
$hide = $('#projectorOn');
$show = $('#projectorOff');
} else {
$show = $('#projectorOn');
$hide = $('#projectorOff');
}
$($show).show();
$($hide).hide();
};
this.updateLighting = function(obj) {
//Console.log(obj);
$('#lightR').text(obj.Red);
$('#lightG').text(obj.Green);
$('#lightB').text(obj.Blue);
var r = parseInt(obj.Red);
var g = parseInt(obj.Green);
var b = parseInt(obj.Blue);
var newR = Math.floor(((r / 65535.0) * 100) * 255);
var newG = Math.floor(((g / 65535.0) * 100) * 255);
var newB = Math.floor(((b / 65535.0) * 100) * 255);
var w = '#' + ('0' + parseInt(newR).toString(16)).substr(-2,
2) + ('0' + parseInt(newG).toString(16)).substr(-2,
2) + ('0' + parseInt(newB).toString(16)).substr(-2, 2);
$('#lightW').text(w).css('background-color', w);
};
this.updateProj = function(obj) {
//Console.log(obj);
var y;
var r = parseInt(obj.Red);
var g = parseInt(obj.Green);
var b = parseInt(obj.Blue);
var newR = Math.floor(((r / 65535.0) * 100) * 255);
var newG = Math.floor(((g / 65535.0) * 100) * 255);
var newB = Math.floor(((b / 65535.0) * 100) * 255);
$('#projR').text(newR);
$('#projG').text(newG);
$('#projB').text(newB);
y = Math.floor((0.2126 * newR + 0.7152 * newG + 0.0722 * newB));
var w = '#' + ('0' + parseInt(y).toString(16)).substr(-2,
2) + ('0' + parseInt(y).toString(16)).substr(-2, 2) + ('0' + parseInt(
y).toString(16)).substr(-2, 2);
$('#projW').text(w).css('background-color', w);
};
this.handleData = function(d) {
console.log(d.id);
switch (d.id) {
case 'LightingDataReceived':
// This.updateLighting(d.sensorData.d);
break;
case 'ProjectorDataReceived':
// This.updateProj(d.sensorData.d);
break;
case 'HeatingDataReceived':
this.updateHeating(d.sensorData.d);
break;
case 'calendar':
controller.updateCalendar(d);
break;
case 'Lighting':
this.toggleLighting(d.device);
break;
case 'Heating':
this.toggleHeating(d.status);
break;
case 'Projector':
this.toggleProjector(d.status);
break;
case 'announce':
controller.notify(d);
break;
default:
console.log(d);
break;
}
};
this.handleWebsocketOnOpen = function() {
'use strict';
this.retry = 0;
$('#longWait').hide();
$('#noSocket').slideUp();
};
this.handleWebsocketMessage = function(message) {
var command;
try {
command = JSON.parse(message.data);
this.updateDateTime();
}
catch (e) { /* Do nothing */
}
if (command) {
this.handleData.call(this,command);
}
};
this.handleWebsocketClose = function() {
console.error('WebSocket Connection Closed.', this.retry);
var self = this, delay;
if (this.retry > 0) {
$('#noSocket').slideDown();
}
if (this.retry > 12) {
this.retry = 1;
}
if (this.retry === 3) {
$('#longWait').fadeIn();
}
if (this.retry > 0) {
delay = 5000 * this.retry;
} else {
delay = 1500;
}
console.log('Waiting ', delay);
this.timer = setTimeout(function() {self.startWebSocket();},delay);
this.retry++;
};
this.startWebSocket();
};

View File

@ -24,7 +24,7 @@ var filePath = {
};
gulp.task('scripts', function() {
return gulp.src('app/js/**/*.js')
return gulp.src(['app/js/sowebsocket.js','app/js/colours.js','app/js/appv2.js'])
.pipe(jshint('.jshintrc'))
.pipe(jshint.reporter('default'))
.pipe(concat('app.js'))
@ -32,12 +32,6 @@ gulp.task('scripts', function() {
.pipe(gulp.dest('dist/js'));
});
/*
<script src="lib/mui.js"></script>
<script src="lib/jquery.js" integrity="sha256-laXWtGydpwqJ8JA+X9x2miwmaiKhn8tVmOVEigRNtP4=" crossorigin="anonymous"></script>
<script src="lib/chroma.js"></script>
<script src="lib/sugar-date.js"></script>
*/
gulp.task('vendor', function() {
return gulp.src(['bower_components/jquery/dist/jquery.min.js',
'bower_components/mui/packages/cdn/js/mui.min.js',

View File

@ -26,6 +26,8 @@ function randomString(length) {
*/
module.exports = {
pingTimer: 0,
statuses: {},
sockets: null,
watches: {},
client: null,
@ -41,6 +43,12 @@ module.exports = {
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;
},
@ -119,6 +127,8 @@ module.exports = {
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) {
@ -126,18 +136,26 @@ module.exports = {
}
var destinationName = mqttConfig.prefix + this.lighting + '/cmd/' + id + '/fmt/json';
this.client.publish(destinationName, 'ON', _callback);
this.emitter.emit('sendSocket',{id: this.lighting, device: id, status: true});
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);
this.emitter.emit('sendSocket',{id: this.lighting, device: id, status: false});
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);
@ -145,7 +163,31 @@ module.exports = {
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');
@ -165,7 +207,7 @@ module.exports = {
//Logger.info("Message from :" + msg.destinationName);
clientStatus.deviceConnected = true;
sensorData = JSON.parse(msg.payloadString);
logger.debug(sensorData);
// logger.debug(sensorData);
var temp = msg.destinationName.split('/');
if (self.watches.hasOwnProperty(temp[4])) {
@ -179,7 +221,8 @@ module.exports = {
logger.error('+ onConnectionLost');
logger.error(e);
logger.error('- onConnectionLost');
}
};
var connectOptions = {};
connectOptions.keepAliveInterval = 3600;
@ -241,6 +284,7 @@ module.exports = {
return this.sockets;
}
};

View File

@ -53,6 +53,7 @@ function processICAL(ical) {
description: '',
timeStart: null,
timeEnd: null,
actualEnd: null,
duration: 0,
combined: '',
uid: ''
@ -71,6 +72,7 @@ function processICAL(ical) {
if (blockStep.indexOf(segments.meetingEndID) >= 0) {
ws = STRING(block[step].split(segments.meetingEndID)[1]).collapseWhitespace().s;
workBlock.dtend = Date.create(ws);
workBlock.actualEnd = workBlock.dtend;
}
if (blockStep.indexOf(segments.meetingStartAlt) >= 0) {
ws = STRING(block[step].split(segments.meetingStartAlt)[1]).collapseWhitespace().s;
@ -98,16 +100,23 @@ function processICAL(ical) {
}
if (workBlock.dtstart !== null) {
workBlock.timeStart = workBlock.dtstart.format('{12hr}:{mm}:{ss} {tt}');
workBlock.timeStart = workBlock.dtstart.format('{24hr}:{mm}:{ss} {tt}');
workBlock.cronStart = workBlock.dtstart.format('{m} {H} * * *');
// WorkBlock.combined = '<em>' + workBlock.timeStart + '</em> - ';
workBlock.combined = workBlock.timeStart + ' - ';
}
workBlock.combined = workBlock.combined + workBlock.summary;
if (workBlock.dtend !== null) {
workBlock.timeEnd = workBlock.dtend.format('{12hr}:{mm}:{ss} {tt}');
workBlock.cronStop = workBlock.dtend.format('{m} {H} * * *');
var fiveMins;
workBlock.timeEnd = workBlock.actualEnd.format('{24hr}:{mm}:{ss} {tt}');
workBlock.cronStop = workBlock.actualEnd.format('{m} {H} * * *');
//fiveMins = workBlock.actualEnd.rewind({minutes: 5});
fiveMins = Date.create(new Date()).addMinutes('5');
workBlock.cronAlert = fiveMins.format('{m} {H} * * *');
}
if (workBlock.dtstart !== null && workBlock.dtend !== null) {
var elapsedTime = new Elapsed(workBlock.dtstart, workBlock.dtend);
workBlock.duration = elapsedTime.optimal;

View File

@ -78,8 +78,24 @@ var officeController = function(neweventbus) {
logger.debug('+ => cleanUp');
this.cleanUpMeeting(id);
});
eventBus.on('announce', (meeting) => {
logger.debug('+ => announce');
this.announceMeetingEnd(meeting);
});
};
officeController.prototype.announceMeetingEnd = function(meeting) {
logger.debug('announceMeetingEnd',meeting);
var msg = ['The meeting "', meeting.summary, '" is due to end in five minutes. Would you like to extend it by another five minutes?'].join('');
var packet = {id: 'announce', msg: msg, uid: meeting.uid};
eventBus.emit('sendSocket', packet);
};
officeController.prototype.cleanUpMeeting = function(id) {
logger.debug('deleting scheduled item: ' + id);
logger.info('Pre delete Schedule count: ' + Object.keys(this.schedule).length);
@ -92,25 +108,32 @@ officeController.prototype.createMeeting = function(obj,delayStart) {
// Logger.debug(util.inspect(this));
var newMeeting = obj, _delayStart = delayStart || false, cronStartStr;
logger.debug('obj', obj);
logger.debug('Delay start?', delayStart);
var now = new Date.create();
var self = this;
// Logger.debug(newMeeting);
newMeeting.cronJOBS = {start: null, stop: null};
if (_delayStart) {
cronStartStr = now.addSeconds(15).format('{s} {m} {H} * * *');
cronStartStr = now.addSeconds(5).format('{s} {m} {H} * * *');
} else {
cronStartStr = newMeeting.cronStart;
}
newMeeting.cronJOBS.start = cron.schedule(cronStartStr, function() {
var n = new Date();
logger.debug('MEETING STARTED!!!!' , n);
var key = Object.keys(self.schedule)[0];
var curMeeting = {};
self.cloneObject(self.schedule[key], curMeeting);
curMeeting.cronJOBS = null;
// We want to kick of the pre -end timer here.
// Lets turn on some lights!
eventBus.emit('lightingOn','o');
eventBus.emit('lightingOn','n');
@ -118,8 +141,22 @@ officeController.prototype.createMeeting = function(obj,delayStart) {
eventBus.emit('sendSocket', {id: 'calendar',current: curMeeting});
}, true);
newMeeting.cronJOBS.alert = cron.schedule(newMeeting.cronAlert, function() {
var n = new Date();
logger.error('MEETING ends in 5 minutes');
logger.debug(this);
// Announce there are five minutes remaining..
eventBus.emit('announce', newMeeting);
}.bind(this), true);
newMeeting.cronJOBS.stop = cron.schedule(newMeeting.cronStop, function() {
var n = new Date();
logger.debug('MEETING ENDED' + n);

View File

@ -61,7 +61,8 @@
"supertest": "^1.1.0"
},
"scripts": {
"test": "mocha --recursive --reporter spec --bail --check-leaks --timeout 3000"
"test": "mocha --recursive --reporter spec --bail --check-leaks --timeout 3000",
"start": "node app"
},
"author": "Martin Donnelly",
"license": "ISC",

View File

@ -9,13 +9,13 @@ mqttConnect.doConnection();*/
var mqttConnect;
function doLightsOn(id) {
function doLightsOn(id) {
mqttConnect.doConnection().lightingOn(id);
}
function doLightsOff(id) {
mqttConnect.doConnection().lightingOff(id);
}
@ -74,7 +74,7 @@ module.exports = {
doLightsOn: function(id) {
doLightsOn(id);
},
doLightsOff: function(id) {
doLightsOff(id);
}
doLightsOff: function(id) {
doLightsOff(id);
}
};