charts are up
This commit is contained in:
@@ -30,3 +30,5 @@ standard-minifier-css
|
|||||||
standard-minifier-js
|
standard-minifier-js
|
||||||
iron:router
|
iron:router
|
||||||
accolver:twilio-meteor
|
accolver:twilio-meteor
|
||||||
|
chart:chart
|
||||||
|
reactive-var
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ boilerplate-generator@1.0.7
|
|||||||
caching-compiler@1.0.3
|
caching-compiler@1.0.3
|
||||||
caching-html-compiler@1.0.5
|
caching-html-compiler@1.0.5
|
||||||
callback-hook@1.0.7
|
callback-hook@1.0.7
|
||||||
|
chart:chart@1.0.1-beta.4
|
||||||
check@1.1.3
|
check@1.1.3
|
||||||
coffeescript@1.0.16
|
coffeescript@1.0.16
|
||||||
ddp@1.2.4
|
ddp@1.2.4
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// at the beginning
|
// at the beginning
|
||||||
Session.set("templateName", "start");
|
Session.set("templateName", "alarm");
|
||||||
|
|
||||||
Template.body.helpers({
|
Template.body.helpers({
|
||||||
template_name: function() {
|
template_name: function() {
|
||||||
|
|||||||
@@ -117,3 +117,11 @@ input:checked + .slider:before {
|
|||||||
.slider.round:before {
|
.slider.round:before {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#chartHorizontalScroll {
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: scroll;
|
||||||
|
overflow-y: hidden;
|
||||||
|
white-space:nowrap;
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
<template name="log">
|
<template name="log">
|
||||||
|
<div id="chartHorizontalScroll">
|
||||||
|
<canvas id="temperatureChart"></canvas>
|
||||||
|
</div>
|
||||||
|
<!--
|
||||||
<div class="hello">
|
<div class="hello">
|
||||||
|
|
||||||
<ul class="no-bullets">
|
<ul class="no-bullets">
|
||||||
{{#each sensorDataCollection}}
|
{{#each sensorDataCollection}}
|
||||||
{{> sensorData}}
|
{{> sensorData}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -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: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%> aaa </ul>"
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
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({
|
Template.sensorData.helpers({
|
||||||
created_at_formatted: function() {
|
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) {
|
all_temperatures: function(temperatures) {
|
||||||
var result = '';
|
var result = '';
|
||||||
if (temperatures.length > 0) {
|
if (temperatures.length > 0) {
|
||||||
|
|||||||
@@ -5,30 +5,10 @@ Tracker.autorun(function() {
|
|||||||
Meteor.subscribe("controller_state", id);
|
Meteor.subscribe("controller_state", id);
|
||||||
Meteor.subscribe('pictures', 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'));
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ Meteor.zoblak.shared = {
|
|||||||
|
|
||||||
Meteor.zoblak.server = {
|
Meteor.zoblak.server = {
|
||||||
controller_state: function(controller_id) {
|
controller_state: function(controller_id) {
|
||||||
|
|
||||||
var result = {}
|
var result = {}
|
||||||
if (controller_id) {
|
if (controller_id) {
|
||||||
result = ControllerState.findOne({
|
result = ControllerState.findOne({
|
||||||
@@ -67,6 +68,8 @@ Meteor.zoblak.server = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("Asked for ", controller_id, " got ", result);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = {}
|
result = {}
|
||||||
};
|
};
|
||||||
|
|||||||
25
app/router.js
Normal file
25
app/router.js
Normal file
@@ -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'));
|
||||||
@@ -63,8 +63,10 @@ Api.addRoute('alarm/:id/phonePing', {
|
|||||||
|
|
||||||
|
|
||||||
reactToSensorData = function(nextSensorReading) {
|
reactToSensorData = function(nextSensorReading) {
|
||||||
console.log("reacting to sensor");
|
|
||||||
var controllerId = nextSensorReading.controllerId;
|
var controllerId = nextSensorReading.controllerId;
|
||||||
|
|
||||||
|
console.log("reacting to sensor ", nextSensorReading);
|
||||||
var stateObject = stateOrDefault(controllerId);
|
var stateObject = stateOrDefault(controllerId);
|
||||||
var state = stateObject.state;
|
var state = stateObject.state;
|
||||||
var config = stateObject.config;
|
var config = stateObject.config;
|
||||||
@@ -201,8 +203,8 @@ function stateOrDefault(id) {
|
|||||||
manualInflow: true
|
manualInflow: true
|
||||||
},
|
},
|
||||||
features: {
|
features: {
|
||||||
start: true,
|
start: false,
|
||||||
weather: true,
|
weather: false,
|
||||||
surveillance: true,
|
surveillance: true,
|
||||||
log: true,
|
log: true,
|
||||||
alarm: true
|
alarm: true
|
||||||
|
|||||||
@@ -218,6 +218,7 @@ reactToAlarmData = function(controller_id) {
|
|||||||
return Meteor.zoblak.shared.valid_temperature(temperature) && is_on;
|
return Meteor.zoblak.shared.valid_temperature(temperature) && is_on;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log("Konfiguracija: ", controller_id, config);
|
||||||
|
|
||||||
var tooCold = config.minTemperature && (minTemperature(temperatures) < config.minTemperature);
|
var tooCold = config.minTemperature && (minTemperature(temperatures) < config.minTemperature);
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ Meteor.publish("sensor_data", function(controllerId) {
|
|||||||
}, {
|
}, {
|
||||||
sort: {
|
sort: {
|
||||||
created_at: -1
|
created_at: -1
|
||||||
},
|
}
|
||||||
limit: 100
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ if (Meteor.isServer) {
|
|||||||
SyncedCron.start();
|
SyncedCron.start();
|
||||||
|
|
||||||
Meteor.zoblak.server.on_all_controllers(function(controller_id) {
|
Meteor.zoblak.server.on_all_controllers(function(controller_id) {
|
||||||
|
if(!controller_id) { return; }; // protects from null controller_id
|
||||||
var jobName = "automatic_alarm_" + controller_id;
|
var jobName = "automatic_alarm_" + controller_id;
|
||||||
|
|
||||||
SyncedCron.remove(jobName);
|
SyncedCron.remove(jobName);
|
||||||
|
|||||||
Reference in New Issue
Block a user