aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Barnett <noreply@jamesbarnett.xyz>2018-10-21 19:12:36 +0100
committerJames Barnett <noreply@jamesbarnett.xyz>2018-10-21 19:12:36 +0100
commitc571c1d59031eaf510e560f3bdc62df2374ba45f (patch)
tree6d7365ca0353e03dba46ff19384549aafdc9c66c
parent8cecaff1ae7240902249676b7d24fadca03fc5a9 (diff)
downloadtplink-energy-monitor-log-realtime-usage.tar.xz
tplink-energy-monitor-log-realtime-usage.zip
Add configurable log interval and max log limitlog-realtime-usage
-rw-r--r--logger-config.json4
-rw-r--r--public/javascripts/dash.js6
-rw-r--r--routes/ws.js2
-rw-r--r--services/data-logger.js101
4 files changed, 76 insertions, 37 deletions
diff --git a/logger-config.json b/logger-config.json
new file mode 100644
index 0000000..639d9a5
--- /dev/null
+++ b/logger-config.json
@@ -0,0 +1,4 @@
+{
+ "logIntervalSeconds": 1,
+ "maxLogEntries": 1440
+} \ No newline at end of file
diff --git a/public/javascripts/dash.js b/public/javascripts/dash.js
index 11a8b0a..a2aa73f 100644
--- a/public/javascripts/dash.js
+++ b/public/javascripts/dash.js
@@ -244,11 +244,11 @@ var dash = {
addLogEntry: function (logEntry, updateChart) {
- dash.usageLogChart.data.labels.push(moment(logEntry.timestamp, 'x').format("MMM Do hh:mm"),);
+ dash.usageLogChart.data.labels.push(moment(logEntry.ts, 'x').format("MMM Do HH:mm"),);
dash.usageLogChart.data.datasets.forEach(function (dataset) {
dataset.data.push({
- x: logEntry.timestamp,
- y: logEntry.power
+ x: logEntry.ts,
+ y: logEntry.pw
});
});
if (updateChart) {
diff --git a/routes/ws.js b/routes/ws.js
index 86eec0d..1599721 100644
--- a/routes/ws.js
+++ b/routes/ws.js
@@ -21,7 +21,7 @@ router.ws('/', function(ws, req) {
ws.send(dataBroadcaster.generatePayload('dailyUsage', deviceId, cachedData.dailyUsage));
ws.send(dataBroadcaster.generatePayload('monthlyUsage', deviceId, cachedData.monthlyUsage));
ws.send(dataBroadcaster.generatePayload('powerState', deviceId, cachedData.powerState));
- dataLogger.getAllEntries(deviceId, (loggedData) => {
+ dataLogger.getLogEntriesForDevice(deviceId, (loggedData) => {
ws.send(dataBroadcaster.generatePayload('loggedData', deviceId, loggedData));
});
diff --git a/services/data-logger.js b/services/data-logger.js
index 0948221..9c23de1 100644
--- a/services/data-logger.js
+++ b/services/data-logger.js
@@ -1,9 +1,58 @@
const fs = require('fs');
const dataBroadcaster = require('./data-broadcaster');
+let logIntervalMs;
+let maxLogEntries;
+
+loadLogConfig();
+
+function loadLogConfig() {
+ try {
+ let config = JSON.parse(fs.readFileSync('logger-config.json', 'utf8'));
+ logIntervalMs = (config.logIntervalSeconds * 1000);
+ maxLogEntries = config.maxLogEntries;
+
+ }
+ catch (err) {
+ console.warn('Error reading logger config. Reverting to defaults.', err);
+ logIntervalMs = 60000 // 1 min
+ maxLogEntries = 1440 // 24 hrs at 1/min
+ }
+}
+
function startLogging(device) {
- setInterval(() => { log(device); }, 60000);
- console.log('Logging started for ' + device.alias + ' [' + device.deviceId + ']');
+ setInterval(() => { log(device); }, logIntervalMs);
+ console.log('Logging started for ' + device.alias + ' [' + device.deviceId + '] every ' + (logIntervalMs/1000) + ' seconds');
+}
+
+function writeLog(filePath, log) {
+ fs.writeFile(filePath, JSON.stringify(log), { flag: 'w' }, (err) => {
+ if (err) {
+ console.warn('Error writing log for ' + device.alias + ' [' + device.deviceId + ']', err);
+ }
+ });
+}
+
+function getLogEntries(filePath, callback) {
+
+ fs.access(filePath, fs.constants.F_OK, (err) => {
+ if(err) {
+ // No log file, init empty one
+ writeLog(filePath, []);
+ callback([]);
+ }
+ else {
+ fs.readFile(filePath, 'utf8', (err, data) => {
+ if (err) {
+ console.warn('Error reading usage log ' + filePath, err);
+ callback([]);
+ }
+ else {
+ callback(JSON.parse(data));
+ }
+ });
+ }
+ });
}
function log(device) {
@@ -11,49 +60,35 @@ function log(device) {
device.emeter.getRealtime().then(response => {
let logEntry = {
- timestamp: Date.now(),
- power: (('power_mw' in response) ? (response.power_mw / 1000) : response.power)
+ ts: Date.now(),
+ pw: (('power_mw' in response) ? (response.power_mw / 1000) : response.power)
}
- // TODO only log up to a max number of entries
+ let filePath = getLogPath(device.deviceId);
- fs.writeFile(device.deviceId + '-log.json', JSON.stringify(logEntry) + '\n', { flag: 'a' }, (err) => {
- if(err) {
- console.warn('Error writing log entry for ' + device.alias + ' [' + device.deviceId + ']', err);
- }
- else {
- dataBroadcaster.broadcastNewLogEntry(device.deviceId, logEntry);
- }
+ getLogEntries(filePath, (entries) => {
+ entries.push(logEntry)
+
+ // Remove old entries
+ entries.splice(0, entries.length - maxLogEntries);
- });
+ writeLog(filePath, entries);
+ dataBroadcaster.broadcastNewLogEntry(device.deviceId, logEntry);
+ })
});
-
}
-function getAllEntries(deviceId, callback) {
- fs.readFile(deviceId + '-log.json', 'utf8', (err, data) => {
- if(err) {
- console.warn('Error reading usage log ' + deviceId + '-log.json', err);
- return;
- }
- else {
- let logLines = data.split(/\r?\n/);
- let logEntries = [];
-
- logLines.forEach(line => {
- if(line.length > 0) {
- logEntries.push(JSON.parse(line))
- }
- });
+function getLogPath(deviceId) {
+ return deviceId + '-log.json';
+}
- callback(logEntries);
- }
- });
+function getLogEntriesForDevice(deviceId, callback) {
+ return getLogEntries(getLogPath(deviceId), callback);
}
module.exports = {
startLogging: startLogging,
log: log,
- getAllEntries: getAllEntries
+ getLogEntriesForDevice: getLogEntriesForDevice
} \ No newline at end of file