mdot_server/app/js/mdot.js
Martin Donnelly de8af028e5 Updated to use PGSql backend
Before convertion of graph object to use AMCharts..
2016-08-11 15:34:52 +01:00

403 lines
13 KiB
JavaScript

'use strict';
/* global Backbone, _, $ */
/* global mainview */
/* jshint browser: true , devel: true*/
(function($) {
var mqttConfig = {
orgId: 'qz0da4',
userName: 'a-qz0da4-dfwwdkmkzr',
appKey: '9txJEf3Cjy7hkSOvkv',
prefix: 'iot-2/type/mDot/id/'
};
var sendAuthentication = function(xhr) {
var user = 'a-qz0da4-dfwwdkmkzr'; // Your actual username
var pass = '9txJEf3Cjy7hkSOvkv'; // Your actual password
var token = user.concat(':', pass);
xhr.setRequestHeader('Authorization', ('Basic '.concat(btoa(token))));
console.log('Auth:', ('Basic '.concat(btoa(token))));
};
var EventsModel = Backbone.Model.extend({
initialize: function() {
_.bindAll(this, 'processAdded');
this.on('all',function(d) {
console.log('model:all',d);
this.temporal = {low: 0,high: 0};
});
this.on('add',function() {
this.processAdded();
});
},
processAdded: function() {
console.log('Model:ProcessAdded');
var tempCollection = new Backbone.Collection();
_.invoke(DeviceCollection.toArray(), 'destroy');
this.temporal = {low: 0,high: 0};
_(this.get('events')).each(function(i) {
if (this.temporal.low === 0 || this.temporal.low > i.timestamp) {
this.temporal.low = i.timestamp;
}
if (this.temporal.high === 0 || this.temporal.high < i.timestamp) {
this.temporal.high = i.timestamp;
}
tempCollection.add({dt: i.timestamp,lux: i.lux, temp: i.temp, co2: i.co2, humid: i.humidity, noise: i.sound});
}, this);
DeviceCollection.temporal = this.temporal;
DeviceCollection.models = tempCollection.models;
DeviceCollection.trigger('update');
console.log('temporal:', this.temporal);
},
decoder: function(data) {
var _obj = {};
var _data = window.atob(data).split('');
var bytes = _data.map(i => i.charCodeAt());
_obj.light = parseInt('0x' + ('0' + bytes[0]).substr(-2) + ('0' + bytes[1]).substr(-2));
_obj.co2 = parseInt(_data[2] + _data[3] + _data[4] + _data[5] + _data[6], 10);
_obj.temp = (parseInt(_data[7] + _data[8] + _data[9] + _data[10] + _data[11], 10) - 1000) / 10;
_obj.humid = (parseInt(_data[12] + _data[13] + _data[14] + _data[15] + _data[16], 10) / 10);
_obj.noise = parseInt('0x' + ('0' + bytes[17]).substr(-2) + ('0' + bytes[18]).substr(-2));
_obj.binData = bytes;
return _obj;
},
dateTime: function($date) {
var dateTime = new Date.create($date);
var date = dateTime.format('{yyyy}-{MM}-{dd}');
var time = dateTime.format('{HH}:{mm}:{ss}');
return {dateTime: dateTime.format('{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}'), date: date, time: time};
}
});
var mDotCollection = Backbone.Collection.extend({
model: EventsModel,
url: 'https://qz0da4.internetofthings.ibmcloud.com/api/v0002/historian/types/mDot/devices/',
initialize: function() {
this.on('update', function() {
// Console.log('Collection:update',this);
});
}
});
var ItemView = Backbone.View.extend({
tagName: 'div', className: 'item mui-container', initialize: function() {
this.template = _.template($('#item-template').html());
console.log('ItemView:Init');
// This.render();
}, render: function() {
console.log('ItemView:Render');
_(this.model.events).each(function(i) {
this.$el.append(this.template({item: i}));
}, this);
return this;
}
});
var MDOT = Backbone.View.extend({
model: EventsModel, el: $('#output'),
events: {
'click button#refresh': 'refresh'
}, initialize: function() {
_.bindAll(this, 'render', 'refresh', 'update');
this.collection.bind('change reset add remove', this.render, this);
this.template = _.template($('#list-template').html());
this.render();
}, refresh: function() {
}, update: function() {
console.log('MDOT:update');
this.collection.each(function(model) {
// Var events = model.get('events');
// var e = new ItemView({model: model.toJSON()});
});
}, render: function() {
console.log('MDOT:render');
var that = this;
this.$el.empty();
this.collection.each(function(model) {
var events = model.get('events');
var e = new ItemView({model: model.toJSON()}).render().el;
console.log('render:done:');
that.$el.append(e);
});
console.log('bah');
return this;
}
});
var MainModel = Backbone.Model.extend({});
var MainView = Backbone.View.extend({
el: $('#main'),
template: _.template($('#main-template').html()),
events: {
'change select#device': 'changeDevice',
'click button#refresh': 'updateDevice',
'change input#from': 'changeDate',
'change input#to': 'changeDate',
submit: function(event) {}
},
initialize: function() {
_.bindAll(this, 'render','changeDevice', 'updateDevice');
this.model.on('change',this.updateDevice);
console.log('MainView:', this);
this.render();
},
render: function() {
$(this.el).html(this.template());
return this;
},changeDate: function(elm) {
console.log('ChangeDate', elm);
if (elm.currentTarget.valueAsDate === null) {
this.model.unset(elm.currentTarget.id);
} else {
this.model.set(elm.currentTarget.id, elm.currentTarget.valueAsDate);
}
},
changeDevice: function() {
var newDevice;
console.log('MainView:ChangeDevice');
newDevice = this.$el.find('#device')[0].value;
this.model.set('device', newDevice);
},
updateDevice: function() {
var fetchObj = {beforeSend: sendAuthentication};
var rangeObj = {start: null, end: null};
console.log('MainView:Updatedevice');
if (this.model.has('from') && this.model.has('to')) {
rangeObj.start = this.model.get('from');
rangeObj.end = this.model.get('to');
fetchObj.data = $.param(rangeObj);
}
if (this.model.has('device')) {
// FetchObj.data = $.param({key:'"'+ this.model.get('device') + '"'});
// this.collection.url = 'https://qz0da4.internetofthings.ibmcloud.com/api/v0002/historian/types/mDot/devices/' + this.model.get('device');
// this.collection.url = '/api/mdot/' + this.model.get('device');
this.collection.url = '/apiv2/mdot/' + this.model.get('device');
// this.collection.url = 'http://127.0.0.1:5984/mdot/_design/getDevice/_view/getDevice';
this.collection.fetch(fetchObj);
} else {
console.error('Nothing to get!');
}
}
});
var GraphView = Backbone.View.extend({
el: $('#graph'),
template: _.template($('#graph-template').html()),
initialize: function() {
this.modes = ['','lux','temp','co2','humid','noise'];
this.mode = 0;
this.xmlns = 'http://www.w3.org/2000/svg';
console.log('GraphView!');
_.bindAll(this, 'render', 'changeMode', 'updateGraph');
this.collection.on('update',function(d) {
if (this.mode > 0) {
this.updateGraph();
}
}, this);
this.render();
},
events: {
'change select#displaymode': 'changeMode'
},
render: function() {
$(this.el).html(this.template());
this.$line = $(this.el).find('#line');
this.$maxY = $(this.el).find('#maxY');
this.$datapoints = $(this.el).find('#datapoints');
this.$baseline = $(this.el).find('#baseline');
return this;
},
changeMode: function() {
this.mode = this.$el.find('#displaymode')[0].value;
this.updateGraph();
console.log('new mode:', this.mode);
},
updateGraph: function() {
var calcArray;
var startX;
var xstep;
var scale;
let ceiling, ceilingLimit;
let points = [];
let data = [];
let circle, title;
let getMode = this.modes[this.mode];
var occupied;
_(this.collection.models).each(function(i) {
// Console.log(i);
points.push(i.get(getMode));
data.push(i.get('dt') + ' / ' + i.get(getMode));
}, this);
ceiling = points.reduce(function(p, v) {
return (Math.abs(p) > Math.abs(v) ? Math.abs(p) : Math.abs(v));
});
ceilingLimit = (Math.ceil((Math.round(ceiling) + 1) / 10) * 10);
if (ceilingLimit > 1000) {
ceilingLimit = (Math.ceil((Math.round(ceiling) + 1) / 50) * 50);
}
this.$datapoints.empty();
this.$baseline.empty();
scale = 124 / ceilingLimit;
xstep = 234 / points.length;
console.log('Points length:', points.length);
console.log(xstep);
//Xstep = 2.34;
startX = 46 ;
if (points.length < 100) {
startX = 46 + (100 - points.length) * xstep;
}
calcArray = [];
for (var x = 0;x < points.length;x++) {
calcArray.push((startX + (x * xstep)).toFixed(2) + ',' + (136 - ((points[x]) * scale)).toFixed(2));
title = document.createElementNS(this.xmlns,'title');
if (parseInt(this.mode) === 5) {
occupied = (points[x] > 920) ? 'purple' : 'red';
} else if (parseInt(this.mode) === 3) {
occupied = (points[x] > 579) ? 'purple' : 'red';
} else {
occupied = 'red';
}
if (occupied !== 'red') {
circle = document.createElementNS(this.xmlns,'circle');
circle.setAttributeNS(null,'fill',occupied);
circle.setAttributeNS(null,'cx',(startX + (x * xstep)).toFixed(2).toString());
circle.setAttributeNS(null,'cy',(136 - ((points[x]) * scale)).toFixed(2).toString());
circle.setAttributeNS(null,'r','2');
circle.setAttributeNS(null,'stroke-width','1');
title.textContent = data[x];
circle.appendChild(title);
this.$datapoints[0].appendChild(circle);
}
}
console.log('This.mode = ', this.mode);
if (parseInt(this.mode) === 3 || parseInt(this.mode) === 5) {
var avgLine = (parseInt(this.mode) === 3) ? 526 : 852;
var bline = document.createElementNS(this.xmlns,'line');
bline.setAttributeNS(null,'x1',46);
bline.setAttributeNS(null,'y1',(136 - (avgLine * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'x2',280);
bline.setAttributeNS(null,'y2',(136 - (avgLine * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'stroke','#00ff00');
bline.setAttributeNS(null,'stroke-width','1');
this.$baseline[0].appendChild(bline);
bline = document.createElementNS(this.xmlns,'line');
bline.setAttributeNS(null,'x1',46);
bline.setAttributeNS(null,'y1',(136 - (4884 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'x2',280);
bline.setAttributeNS(null,'y2',(136 - (4884 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'stroke','#00ff55');
bline.setAttributeNS(null,'stroke-width','1');
this.$baseline[0].appendChild(bline);
}
if (parseInt(this.mode) === 3) {
var bline = document.createElementNS(this.xmlns,'line');
bline.setAttributeNS(null,'x1',46);
bline.setAttributeNS(null,'y1',(136 - (632 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'x2',280);
bline.setAttributeNS(null,'y2',(136 - (632 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'stroke','yellow');
bline.setAttributeNS(null,'stroke-width','1');
this.$baseline[0].appendChild(bline);
var bline = document.createElementNS(this.xmlns,'line');
bline.setAttributeNS(null,'x1',46);
bline.setAttributeNS(null,'y1',(136 - (1045 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'x2',280);
bline.setAttributeNS(null,'y2',(136 - (1045 * scale)).toFixed(2).toString());
bline.setAttributeNS(null,'stroke','red');
bline.setAttributeNS(null,'stroke-width','1');
this.$baseline[0].appendChild(bline);
}
this.$line[0].setAttribute('points',calcArray.join(' '));
this.$maxY[0].textContent = ceilingLimit;
}
});
var DeviceCollection = new Backbone.Collection;
var mdotCollection = new mDotCollection();
var mainSettings = new MainModel();
var mainview = new MainView({collection: mdotCollection, model: mainSettings});
var mdot = new MDOT({collection: mdotCollection});
var grapher = new GraphView({collection: DeviceCollection});
})(jQuery);