diff --git a/app/.meteor/packages b/app/.meteor/packages index ee2b624..d910b2f 100644 --- a/app/.meteor/packages +++ b/app/.meteor/packages @@ -30,3 +30,5 @@ standard-minifier-css standard-minifier-js iron:router accolver:twilio-meteor +chart:chart +reactive-var diff --git a/app/.meteor/versions b/app/.meteor/versions index 97783e0..3f64b8b 100644 --- a/app/.meteor/versions +++ b/app/.meteor/versions @@ -15,6 +15,7 @@ boilerplate-generator@1.0.7 caching-compiler@1.0.3 caching-html-compiler@1.0.5 callback-hook@1.0.7 +chart:chart@1.0.1-beta.4 check@1.1.3 coffeescript@1.0.16 ddp@1.2.4 diff --git a/app/client/app.js b/app/client/app.js index a54400f..5982d0b 100644 --- a/app/client/app.js +++ b/app/client/app.js @@ -1,5 +1,5 @@ // at the beginning -Session.set("templateName", "start"); +Session.set("templateName", "alarm"); Template.body.helpers({ template_name: function() { diff --git a/app/client/app.less b/app/client/app.less index dcaaf78..1acbd3e 100644 --- a/app/client/app.less +++ b/app/client/app.less @@ -117,3 +117,11 @@ input:checked + .slider:before { .slider.round:before { border-radius: 50%; } + +#chartHorizontalScroll { + width: 100%; + overflow-x: scroll; + overflow-y: hidden; + white-space:nowrap; + +} diff --git a/app/client/log.html b/app/client/log.html index 3e8aa3f..0907d65 100644 --- a/app/client/log.html +++ b/app/client/log.html @@ -1,12 +1,16 @@ diff --git a/app/client/log.js b/app/client/log.js index a4fa85b..f48f9d0 100644 --- a/app/client/log.js +++ b/app/client/log.js @@ -20,10 +20,188 @@ Template.log.events({ } }); + + +var createChart = function() { + + var self = this; + self.labels = []; + self.temperatures = []; + Tracker.autorun(function() { + sensor_data_collection().forEach(function(sensorReading) { + self.labels.push(moment(sensorReading.lastBoxContact).format('ddd DD.MM. HH:mm:ss')); + for (var i = 0; i < sensorReading.temperatures.length; i++) { + if (!self.temperatures[i]) { + self.temperatures[i] = []; + } + self.temperatures[i].push(sensorReading.temperatures[i]); + } + }); + }); + + + // Get the context of the canvas element we want to select + var chartCanvas = document.getElementById("temperatureChart"); + var lengthOfTemperatures = self.temperatures[0].length * 40 + 10; + chartCanvas.width = (window.innerWidth > lengthOfTemperatures) ? window.innerWidth : lengthOfTemperatures; + var heightOfElementsBefore = chartCanvas.getBoundingClientRect().top; + chartCanvas.height = window.innerHeight - heightOfElementsBefore; + var ctx = chartCanvas.getContext("2d"); + + + + // Set the options + var options = { + + ///Boolean - Whether grid lines are shown across the chart + scaleShowGridLines: true, + + //String - Colour of the grid lines + scaleGridLineColor: "rgba(0,0,0,.05)", + + //Number - Width of the grid lines + scaleGridLineWidth: 1, + + //Boolean - Whether to show horizontal lines (except X axis) + scaleShowHorizontalLines: true, + + //Boolean - Whether to show vertical lines (except Y axis) + scaleShowVerticalLines: true, + + //Boolean - Whether the line is curved between points + bezierCurve: true, + + //Number - Tension of the bezier curve between points + bezierCurveTension: 0.4, + + //Boolean - Whether to show a dot for each point + pointDot: true, + + //Number - Radius of each point dot in pixels + pointDotRadius: 4, + + //Number - Pixel width of point dot stroke + pointDotStrokeWidth: 1, + + //Number - amount extra to add to the radius to cater for hit detection outside the drawn point + pointHitDetectionRadius: 20, + + //Boolean - Whether to show a stroke for datasets + datasetStroke: true, + + //Number - Pixel width of dataset stroke + datasetStrokeWidth: 2, + + //Boolean - Whether to fill the dataset with a colour + datasetFill: true, + + //String - A legend template + legendTemplate: "" + + }; + + var random = function() { + return Math.random() * (100 - 1) + 1; + } + + var colours = [{ // blue + fillColor: "rgba(151,187,205,0.2)", + strokeColor: "rgba(151,187,205,1)", + pointColor: "rgba(151,187,205,1)", + pointStrokeColor: "#fff", + pointHighlightFill: "#fff", + pointHighlightStroke: "rgba(151,187,205,0.8)" + }, { // red + fillColor: "rgba(247,70,74,0.2)", + strokeColor: "rgba(247,70,74,1)", + pointColor: "rgba(247,70,74,1)", + pointStrokeColor: "#fff", + pointHighlightFill: "#fff", + pointHighlightStroke: "rgba(247,70,74,0.8)" + }, { // green + fillColor: "rgba(70,191,189,0.2)", + strokeColor: "rgba(70,191,189,1)", + pointColor: "rgba(70,191,189,1)", + pointStrokeColor: "#fff", + pointHighlightFill: "#fff", + pointHighlightStroke: "rgba(70,191,189,0.8)" + }, { // light grey + fillColor: "rgba(220,220,220,0.2)", + strokeColor: "rgba(220,220,220,1)", + pointColor: "rgba(220,220,220,1)", + pointStrokeColor: "#fff", + pointHighlightFill: "#fff", + pointHighlightStroke: "rgba(220,220,220,0.8)" + }, + + { // yellow + fillColor: "rgba(253,180,92,0.2)", + strokeColor: "rgba(253,180,92,1)", + pointColor: "rgba(253,180,92,1)", + pointStrokeColor: "#fff", + pointHighlightFill: "#fff", + pointHighlightStroke: "rgba(253,180,92,0.8)" + }, { // grey + fillColor: "rgba(148,159,177,0.2)", + strokeColor: "rgba(148,159,177,1)", + pointColor: "rgba(148,159,177,1)", + pointStrokeColor: "#fff", + pointHighlightFill: "#fff", + pointHighlightStroke: "rgba(148,159,177,0.8)" + }, { // dark grey + fillColor: "rgba(77,83,96,0.2)", + strokeColor: "rgba(77,83,96,1)", + pointColor: "rgba(77,83,96,1)", + pointStrokeColor: "#fff", + pointHighlightFill: "#fff", + pointHighlightStroke: "rgba(77,83,96,1)" + } + ]; + var datasets = []; + + for (var i = 0; i < self.temperatures.length; i++) { + // repeat colors once you run out + var colour = colours[i % colours.length]; + var dataset = Object.assign({ + label: "Senzor #", + data: self.temperatures[i] + }, colour); + datasets.push(dataset); + } + + // Set the data + var data = { + labels: self.labels, + datasets: datasets + }; + + // draw the charts + var myLineChart = new Chart(ctx).Line(data, options); + + +}; + +Template.log.onRendered(function() { + createChart(); +}); + +Template.log.resized = function() { + createChart(); + + return Session.get('resize'); +} + +Template.log.orientation = function() { + createChart(); + return Session.get('orientation'); +} + + Template.sensorData.helpers({ created_at_formatted: function() { - return moment(this.created_at).format(/*"DD.MM.YYYY, */ " (HH:mm)") + return moment(this.created_at).format( /*"DD.MM.YYYY, */ " (HH:mm)") }, + all_temperatures: function(temperatures) { var result = ''; if (temperatures.length > 0) { diff --git a/app/client/startup.js b/app/client/startup.js index 4823cbd..5f426d2 100644 --- a/app/client/startup.js +++ b/app/client/startup.js @@ -5,30 +5,10 @@ Tracker.autorun(function() { Meteor.subscribe("controller_state", id); Meteor.subscribe('pictures', id); } + window.addEventListener('orientationchange', function(){ + Session.set("orientation", new Date()); + }); + window.addEventListener('resize', function(){ + Session.set("resized", new Date()); + }); }); - -function safeRoute(route) { - return function () { - var controllerId = this.params.query.controller_id; - - if(controllerId) { - Session.setPersistent('controller_id', controllerId); - Session.setPersistent('hide_controller_selection', true); - } else { - Session.setPersistent('hide_controller_selection', false); - } - console.log('go ', route); - if (Meteor.zoblak.client.accessible(route)) { - Session.set('templateName', route); - } else { - Session.set('templateName', 'no_access') - } - } -} - - -Router.route('/', safeRoute('start')); -Router.route('/alarm', safeRoute('alarm')); -Router.route('/log', safeRoute('log')); -Router.route('/surveillance', safeRoute('surveillance')); -Router.route('/weather', safeRoute('weather')); diff --git a/app/lib/zoblak.js b/app/lib/zoblak.js index ec4c3e1..5bf2d51 100644 --- a/app/lib/zoblak.js +++ b/app/lib/zoblak.js @@ -60,6 +60,7 @@ Meteor.zoblak.shared = { Meteor.zoblak.server = { controller_state: function(controller_id) { + var result = {} if (controller_id) { result = ControllerState.findOne({ @@ -67,6 +68,8 @@ Meteor.zoblak.server = { }); } + console.log("Asked for ", controller_id, " got ", result); + if (!result) { result = {} }; diff --git a/app/router.js b/app/router.js new file mode 100644 index 0000000..038c676 --- /dev/null +++ b/app/router.js @@ -0,0 +1,25 @@ +function safeRoute(route) { + return function () { + var controllerId = this.params.query.controller_id; + + if(controllerId) { + Session.setPersistent('controller_id', controllerId); + Session.setPersistent('hide_controller_selection', true); + } else { + Session.setPersistent('hide_controller_selection', false); + } + console.log('go ', route); + if (Meteor.zoblak.client.accessible(route)) { + Session.set('templateName', route); + } else { + Session.set('templateName', 'no_access') + } + + } +} + +Router.route('/', safeRoute('alarm')); +Router.route('/alarm', safeRoute('alarm')); +Router.route('/log', safeRoute('log')); +Router.route('/surveillance', safeRoute('surveillance')); +Router.route('/weather', safeRoute('weather')); diff --git a/app/server/api.js b/app/server/api.js index beda432..1590181 100644 --- a/app/server/api.js +++ b/app/server/api.js @@ -63,8 +63,10 @@ Api.addRoute('alarm/:id/phonePing', { reactToSensorData = function(nextSensorReading) { - console.log("reacting to sensor"); + var controllerId = nextSensorReading.controllerId; + + console.log("reacting to sensor ", nextSensorReading); var stateObject = stateOrDefault(controllerId); var state = stateObject.state; var config = stateObject.config; @@ -201,8 +203,8 @@ function stateOrDefault(id) { manualInflow: true }, features: { - start: true, - weather: true, + start: false, + weather: false, surveillance: true, log: true, alarm: true diff --git a/app/server/methods.js b/app/server/methods.js index 55c5d18..1d19ddd 100644 --- a/app/server/methods.js +++ b/app/server/methods.js @@ -218,6 +218,7 @@ reactToAlarmData = function(controller_id) { return Meteor.zoblak.shared.valid_temperature(temperature) && is_on; }); + console.log("Konfiguracija: ", controller_id, config); var tooCold = config.minTemperature && (minTemperature(temperatures) < config.minTemperature); diff --git a/app/server/publications.js b/app/server/publications.js index 1031bf3..9ef699a 100644 --- a/app/server/publications.js +++ b/app/server/publications.js @@ -5,8 +5,7 @@ Meteor.publish("sensor_data", function(controllerId) { }, { sort: { created_at: -1 - }, - limit: 100 + } }); }); diff --git a/app/server/startup.js b/app/server/startup.js index c398f6e..f99a402 100644 --- a/app/server/startup.js +++ b/app/server/startup.js @@ -4,6 +4,7 @@ if (Meteor.isServer) { SyncedCron.start(); Meteor.zoblak.server.on_all_controllers(function(controller_id) { + if(!controller_id) { return; }; // protects from null controller_id var jobName = "automatic_alarm_" + controller_id; SyncedCron.remove(jobName);