esp8266-configurator
Version:
This module allows you to fetch configuration for an ESP8266 device on network connection.
196 lines (167 loc) • 5.44 kB
JavaScript
;
/**
* author : maleficarum [ maleficarum.mx ]
*/
const Datastore = require('nedb');
var Promise = require("bluebird");
const bodyParser = require('body-parser')
const bunyan = require('bunyan');
const fs = require("fs");
const express = require('express');
const exphbs = require('express-handlebars');
const path = require('path');
const dao = require('./db.js');
const argv = require('minimist')(process.argv.slice(2));
const log = bunyan.createLogger({
name: "ESP8266Configurator",
src: false,
streams: [
{
level:'debug',
stream: process.stdout
}
]
});
var config;
var db = { };
var app = express();
module.exports = {
configure:(_config_) => {
config = _config_;
if(argv["db-location"] != null || config.dbLocation != null) {
config.dbLocation = argv["db-location"] || config.dbLocation;
//Verify if the firmware location exists.
try {
fs.statSync(config.dbLocation);
} catch(e) {
log.warn("Creating " + config.dbLocation + " cause doesn't exist");
fs.mkdirSync(config.dbLocation);
}
db.devices = new Datastore({ filename: config.dbLocation + "/devices.db", autoload: true });
db.config = new Datastore({ filename: config.dbLocation + "/configuration.db", autoload: true });
log.info("Creating a persistent store in " + config.dbLocation);
} else {
log.info("Creating a in-memory database");
db.config = new Datastore();
db.devices = new Datastore();
}
if(config.port == undefined) {
config.port = argv["port"] || 3000;
log.info("Setting listen port to ", config.port);
}
dao.configure(db);
//After configure the data store, check whether the config has the devices configuration
//and store it into a store.
if(config.configuration != undefined) {
persistFileConfiguration();
}
},
run:(customApp) => {
if(customApp != undefined) {
log.info("Using provided custom express application.")
app = customApp;
}
app.engine('handlebars', exphbs({
defaultLayout: 'main',
layoutsDir: path.join(__dirname, '/views/layouts'),
partialsDir: __dirname + '/views/partials',
helpers:{
stringify: (obj) => {
return JSON.stringify(obj);
}
}
}));
app.set('view engine', 'handlebars');
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', path.join(__dirname, 'views'));
app.use(bodyParser.json());
app.get('/dh7/configure', fetchConfigurationRoute);
app.post("/dh7/device/save", saveDeviceRoute);
app.post("/dh7/device/config/save", saveDeviceConfigRoute);
if(customApp == undefined) {
app.get('/', rootRoute);
app.listen(config.port, function () {
log.info('Update Service listening on port ' + config.port);
});
} else {
log.warn("I'm not using the root context to serve the configuration; instead I'm using /dh7/configurator");
app.get('/dh7/configurator', rootRoute);
}
}
};
const saveDeviceConfigRoute = (req, res) => {
const json = req.body;
console.log("PAYLOAD ", json);
dao.saveDeviceConfiguration(json, (results) => {
res.status(200).json({"updated": results});
}, (error) => {
res.status(500).json({"error": error});
});
};
const saveDeviceRoute = (req, res) => {
const json = req.body;
log.debug("Trying to store device ", json);
dao.saveDevice({
"deviceId": json.deviceId,
"alias":json.alias,
"metadata": json.metadata,
"latitude": json.latitude,
"longitude": json.longitude,
"model": json.model,
"creationDate": new Date()
}, () => {
res.status(200).json({});
}, () => {
res.status(500).json({});
});
};
const persistFileConfiguration = () => {
config.configuration.forEach((c, idx) => {
if(c.device) {
var device = {
"deviceId": c.device.id,
"alias":c.device.alias,
"metadata": c.device.metadata,
"latitude": c.device.location.latitude,
"longitude": c.device.location.longitude,
"model": c.device.model,
"creationDate": new Date(),
"configuration": c.device.configuration
};
dao.saveDevice(device, () => {
log.info("Persisted device ", device);
//Save the configuration
c.global.forEach((c, idx) => {
c.deviceId = device.deviceId;
dao.saveGlobalConfiguration(c, () => {
log.info("Persisted configuration ", c)
}, () => {});
});
}, () => {
log.error("Error persisting device ", c);
});
}
});
};
const rootRoute = (req, res) => {
dao.fetchDevices((devices) => {
dao.findGlobalConfiguration((configs) => {
res.render('index', { title: 'Device Lists', devicesList: devices, configuration: JSON.stringify(configs) });
}, () => {});
}, () => {});
};
const fetchConfigurationRoute = (req, res) => {
const deviceId = req.query.deviceId;
var found = false;
log.info("Looking for config for device " + deviceId);
dao.findDeviceConfiguration(deviceId, (configs) => {
dao.findGlobalConfiguration((globalConfigs) => {
configs.global = globalConfigs;
res.status(200).json({"configuration":configs});
}, () => {
res.status(404).json({"error": error});
});
}, (error) => {
res.status(404).json({"error": error});
});
};