aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--public/javascripts/dash.js62
-rw-r--r--routes/energy-usage.js73
-rw-r--r--views/index.hbs16
3 files changed, 146 insertions, 5 deletions
diff --git a/public/javascripts/dash.js b/public/javascripts/dash.js
index 3d02fd8..c8710db 100644
--- a/public/javascripts/dash.js
+++ b/public/javascripts/dash.js
@@ -7,14 +7,17 @@ var dash = {
realtimeTrendLastSample: 0,
dailyUsageChart: null,
+ monthlyUsageChart: null,
init: function() {
this.initRealtimeGauge();
this.initRealtimeTrendChart();
this.initDailyUsageChart();
+ this.initMonthlyUsageChart();
this.startPolling();
this.getDailyUsageData();
+ this.getMonthlyUsageData();
},
initRealtimeGauge: function() {
@@ -113,6 +116,37 @@ var dash = {
});
},
+ initMonthlyUsageChart: function() {
+ var ctx = document.getElementById('mu-chart').getContext('2d');
+ this.monthlyUsageChart = new Chart(ctx, {
+ type: 'bar',
+ data: {
+ datasets: [{
+ label: "Energy (kWH)",
+ borderColor: 'rgb(255, 99, 132)',
+ backgroundColor: 'rgb(255, 99, 132)',
+ data: []
+ }]
+ },
+ options: {
+ legend: {
+ display: false
+ },
+ scales: {
+ yAxes: [{
+ ticks: {
+ beginAtZero:true
+ }
+ }]
+ },
+ maintainAspectRatio: false,
+ tooltips: {
+ intersect: false
+ },
+ }
+ });
+ },
+
realtimeTrendChartOnRefresh: function(chart) {
chart.data.datasets.forEach(function(dataset) {
dataset.data.push({
@@ -194,7 +228,33 @@ var dash = {
});
dash.dailyUsageChart.update();
- }
+ },
+
+ getMonthlyUsageData: function() {
+ $.ajax({
+ url: "/energy-usage/1/month-stats",
+ type: "GET",
+ success: function(data) {
+ dash.parseMonthlyUsageData(data);
+ },
+ dataType: "json",
+ timeout: 4000
+ });
+ },
+
+ parseMonthlyUsageData: function(usageData) {
+ usageData.forEach(function(entry) {
+ // Months from API response are 1 based
+ var month = moment().month(entry.month -1);
+
+ dash.monthlyUsageChart.data.labels.push(month.format('MMM'));
+ dash.monthlyUsageChart.data.datasets.forEach(function(dataset) {
+ dataset.data.push(entry.energy);
+ });
+ });
+
+ dash.monthlyUsageChart.update();
+ },
};
diff --git a/routes/energy-usage.js b/routes/energy-usage.js
index 5706c75..411c0b6 100644
--- a/routes/energy-usage.js
+++ b/routes/energy-usage.js
@@ -44,14 +44,48 @@ router.get('/:deviceId/day-stats', function(req, res, next) {
let previousMonthStats = fillMissingDays(previousPeriodStats, previousMoment);
let combinedStats = previousMonthStats.concat(currentMonthStats);
- res.json(trimDayStatResults(combinedStats, totalDaysRequired));
+ res.json(trimStatResults(combinedStats, totalDaysRequired));
});
}
else {
let dayStats = fillMissingDays(currentPeriodStats, currentMoment);
- res.json(trimDayStatResults(dayStats, totalDaysRequired));
+ res.json(trimStatResults(dayStats, totalDaysRequired));
+ }
+
+ });
+
+});
+
+router.get('/:deviceId/month-stats', function(req, res, next) {
+ let deviceId = req.params.deviceId;
+
+ // Get last x months
+ let totalMonthsRequired = 12; // TODO currently only works for up to 14 month (2 year) spans
+ let currentMoment = moment();
+ let previousMoment = moment().subtract(totalMonthsRequired, 'months');
+
+ deviceManager.getDevice(deviceId).emeter.getMonthStats(currentMoment.year()).then(currentPeriodStats => {
+
+ // Check if we also need the previous year to meet the required total number of samples
+ if(currentMoment.month() + 1 < totalMonthsRequired) {
+
+ // Get previous year (assuming the totalMonthsRequired limit described above).
+ deviceManager.getDevice(deviceId).emeter.getMonthStats(previousMoment.year()).then(previousPeriodStats => {
+
+ let currentYearStats = fillMissingMonths(currentPeriodStats, currentMoment);
+ let previousYearStats = fillMissingMonths(previousPeriodStats, previousMoment);
+ let combinedStats = previousYearStats.concat(currentYearStats);
+
+ res.json(trimStatResults(combinedStats, totalMonthsRequired));
+
+ });
+ }
+ else {
+ let monthStats = fillMissingMonths(currentPeriodStats, currentMoment);
+
+ res.json(trimStatResults(monthStats, totalMonthsRequired));
}
});
@@ -84,7 +118,40 @@ function fillMissingDays(sparseDayStats, statsMoment) {
return denseDayStats;
}
-function trimDayStatResults(stats, maxSamples) {
+function fillMissingMonths(sparseMonthStats, statsMoment) {
+ let denseMonthStats = [];
+
+ let maxMonths;
+ // Dont fill months in months which havent happened yet
+ if(statsMoment.year() === moment().year()) {
+ maxMonths = moment().month();
+ }
+ else {
+ maxMonths = 12;
+ }
+
+ // Fill in any missing months up to the max amount
+ Array.from({length: maxMonths}, (x,i) => i + 1).forEach(m => {
+
+ let stat = sparseMonthStats.month_list.find(i => i.month === m);
+
+ if(stat === undefined) {
+ denseMonthStats.push({
+ year: statsMoment.year(),
+ month: m,
+ energy: 0
+ })
+ }
+ else {
+ denseMonthStats.push(stat);
+ }
+
+ });
+
+ return denseMonthStats;
+}
+
+function trimStatResults(stats, maxSamples) {
return stats.splice(stats.length - maxSamples, stats.length);
}
diff --git a/views/index.hbs b/views/index.hbs
index ae7dac9..3a8233f 100644
--- a/views/index.hbs
+++ b/views/index.hbs
@@ -104,7 +104,8 @@
</div>
<div class="row">
- <div class="col-md-6 col-sm-6 col-xs-12">
+
+ <div class="col-md-8 col-sm-8 col-xs-12">
<div class="x_panel tile">
<div class="x_title">
<h2>
@@ -118,6 +119,19 @@
</div>
</div>
+ <div class="col-md-4 col-sm-4 col-xs-12">
+ <div class="x_panel tile">
+ <div class="x_title">
+ <h2>
+ <strong>Last 12 months (kWH)</strong>
+ </h2>
+ <div class="clearfix"></div>
+ </div>
+ <div class="x_content">
+ <canvas id="mu-chart" height="270"></canvas>
+ </div>
+ </div>
+ </div>
</div>