aboutsummaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/data-broadcaster.js5
-rw-r--r--services/data-logger.js94
-rw-r--r--services/device-manager.js3
3 files changed, 102 insertions, 0 deletions
diff --git a/services/data-broadcaster.js b/services/data-broadcaster.js
index 60c2368..4905eda 100644
--- a/services/data-broadcaster.js
+++ b/services/data-broadcaster.js
@@ -16,6 +16,10 @@ function broadcastPowerStateUpdate(deviceId, data) {
broadcast(generatePayload('powerState', deviceId, data));
}
+function broadcastNewLogEntry(deviceId, data) {
+ broadcast(generatePayload('newLogEntry', deviceId, data));
+}
+
function broadcast(payload) {
app.getWsClients().forEach(client => {
client.send(payload);
@@ -39,5 +43,6 @@ module.exports = {
broadcastDailyUsageUpdate: broadcastDailyUsageUpdate,
broadcastMonthlyUsageUpdate: broadcastMonthlyUsageUpdate,
broadcastPowerStateUpdate: broadcastPowerStateUpdate,
+ broadcastNewLogEntry: broadcastNewLogEntry,
generatePayload: generatePayload
}
diff --git a/services/data-logger.js b/services/data-logger.js
new file mode 100644
index 0000000..9c23de1
--- /dev/null
+++ b/services/data-logger.js
@@ -0,0 +1,94 @@
+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); }, 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) {
+
+ device.emeter.getRealtime().then(response => {
+
+ let logEntry = {
+ ts: Date.now(),
+ pw: (('power_mw' in response) ? (response.power_mw / 1000) : response.power)
+ }
+
+ let filePath = getLogPath(device.deviceId);
+
+ getLogEntries(filePath, (entries) => {
+ entries.push(logEntry)
+
+ // Remove old entries
+ entries.splice(0, entries.length - maxLogEntries);
+
+ writeLog(filePath, entries);
+ dataBroadcaster.broadcastNewLogEntry(device.deviceId, logEntry);
+ })
+
+ });
+}
+
+function getLogPath(deviceId) {
+ return deviceId + '-log.json';
+}
+
+function getLogEntriesForDevice(deviceId, callback) {
+ return getLogEntries(getLogPath(deviceId), callback);
+}
+
+module.exports = {
+ startLogging: startLogging,
+ log: log,
+ getLogEntriesForDevice: getLogEntriesForDevice
+} \ No newline at end of file
diff --git a/services/device-manager.js b/services/device-manager.js
index e4d18f3..1e17f75 100644
--- a/services/device-manager.js
+++ b/services/device-manager.js
@@ -1,4 +1,5 @@
const { Client } = require('tplink-smarthome-api');
+const dataLogger = require('./data-logger');
const client = new Client();
var devices = [];
@@ -9,6 +10,8 @@ client.startDiscovery({
}).on('plug-new', plug => {
console.log('Found device: ' + plug.alias + ' [' + plug.deviceId + ']');
devices.push(plug);
+
+ dataLogger.startLogging(plug);
});
module.exports.getDevice = function(deviceId) {