Finish changing config file updates

This commit is contained in:
Skylar Grant 2022-12-18 13:14:34 -05:00
parent d1ac00f737
commit ca333e5603
4 changed files with 76 additions and 65 deletions

View File

@ -19,7 +19,7 @@
"Log if in Debug mode": { "Log if in Debug mode": {
"scope": "javascript", "scope": "javascript",
"prefix": "log", "prefix": "log",
"body": "if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: $1`);\n$0", "body": "if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: $1`);\n$0",
"description": "Log output to console if in debug mode" "description": "Log output to console if in debug mode"
}, },
"Run only on Pi": { "Run only on Pi": {

View File

@ -9,7 +9,7 @@
"shutdown": 0 "shutdown": 0
}, },
"timestamps": { "timestamps": {
"startup": 0, "procStart": 0,
"blowerOff": 0, "blowerOff": 0,
"igniterOn": 0, "igniterOn": 0,
"igniterOff": 0 "igniterOff": 0

View File

@ -66,19 +66,19 @@ const functions = {
// Turn the auger on // Turn the auger on
this.on(gpio).then((res) => { this.on(gpio).then((res) => {
// Log action if in debug mode // Log action if in debug mode
if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: ${res}`); if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
// Sleep for the time set in env variables // Sleep for the time set in env variables
functions.sleep(config.augerOnTime).then((res) => { functions.sleep(config.intervals.augerOn).then((res) => {
// Log action if in debug mode // Log action if in debug mode
if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: ${res}`); if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
// Turn the auger off // Turn the auger off
this.off(gpio).then((res) => { this.off(gpio).then((res) => {
// Log action if in debug mode // Log action if in debug mode
if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: ${res}`); if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
// Sleep for the time set in env variables // Sleep for the time set in env variables
functions.sleep(config.augerOffTime).then((res) => { functions.sleep(config.intervals.augerOff).then((res) => {
// Log action if in debug mode // Log action if in debug mode
if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: ${res}`); if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
// Resolve the promise, letting the main script know the cycle is complete // Resolve the promise, letting the main script know the cycle is complete
resolve("Cycle complete."); resolve("Cycle complete.");
}); });
@ -88,6 +88,19 @@ const functions = {
}); });
}, },
}, },
blower: {
canShutdown() {
// If the blowerOff timestamp hasn't been set, return false as the blower hasn't been asked to turn off yet
if (config.timestamps.blowerOff == 0) return false;
// If the current time is past the blowerOff timestamp, we can turn off the blower
if (Date.now() > config.timestamps.blowerOff) {
return true;
// Otherwise, return false because we're not ready to
} else {
return false;
}
}
},
files: { files: {
// Check for a preset-list of files in the root directory of the app // Check for a preset-list of files in the root directory of the app
check() { check() {
@ -146,9 +159,9 @@ const functions = {
// Pauses the script for the time defined in env variables // Pauses the script for the time defined in env variables
pause() { pause() {
return new Promise((resolve) => { return new Promise((resolve) => {
if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: Pausing for ${config.pauseTime}ms`); if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: Pausing for ${config.intervals.pause}ms`);
functions.sleep(config.pauseTime).then(() => { resolve(); }); functions.sleep(config.intervals.pause).then(() => { resolve(); });
}); });
}, },
// Reload the environment variables on the fly // Reload the environment variables on the fly
@ -164,7 +177,7 @@ const functions = {
// Print out the new environment variables // Print out the new environment variables
// This should be printed regardless of debug status, maybe prettied up TODO? // This should be printed regardless of debug status, maybe prettied up TODO?
console.log('Reloaded environment variables.'); console.log('Reloaded environment variables.');
console.log(`ONTIME=${config.augerOnTime}\nOFFTIME=${config.augerOffTime}\nPAUSETIME=${config.pauseTime}\nDEBUG=${config.debugMode}\nONPI=${process.env.ONPI}`); console.log(`ONTIME=${config.intervals.augerOn}\nOFFTIME=${config.intervals.augerOff}\nPAUSETIME=${config.intervals.pause}\nDEBUG=${config.debugMode}\nONPI=${process.env.ONPI}`);
// Resolve the promise, letting the main script know we're done reloading the variables and the cycle can continue // Resolve the promise, letting the main script know we're done reloading the variables and the cycle can continue
resolve(); resolve();
}); });
@ -186,12 +199,12 @@ const functions = {
ignite(gpio) { ignite(gpio) {
config.status.igniter = 1; config.status.igniter = 1;
config.status.auger = 1; config.status.auger = 1;
config.igniterOnTime = Date.now(); config.timestamps.igniterOn = Date.now();
config.igniterOffTime = config.igniterOnTime + config.igniterWaitTime; // 7 Minutes, 420,000ms config.timestamps.igniterOff = config.timestamps.igniterOn + config.intervals.igniterStart; // 7 Minutes, 420,000ms
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fs.unlink('./ignite', (err) => { fs.unlink('./ignite', (err) => {
if (err) reject(err); if (err) reject(err);
if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: Delete the ignite file.`); if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: Delete the ignite file.`);
}); });
if (process.env.ONPI == 'true') { if (process.env.ONPI == 'true') {
gpio.write(igniterPin, true, (err) => { gpio.write(igniterPin, true, (err) => {
@ -204,6 +217,10 @@ const functions = {
}); });
}, },
shutdown(gpio) { shutdown(gpio) {
// Only run if a shutdown isn't already started
if (config.status.shutdown == 0) {
// set shutdown flag to 1
config.status.shutdown = 1;
// If the auger is enabled, disable it // If the auger is enabled, disable it
if (config.status.auger == 1) { if (config.status.auger == 1) {
config.status.auger = 0; config.status.auger = 0;
@ -211,17 +228,17 @@ const functions = {
// If the igniter is on, shut it off. // If the igniter is on, shut it off.
if (config.status.igniter == 1) { if (config.status.igniter == 1) {
functions.power.igniter.off(gpio).then(res => { functions.power.igniter.off(gpio).then(res => {
if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: Shut off igniter.`); if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: Shut off igniter.`);
}); // TODO catch an error here }); // TODO catch an error here
} }
// TODO Change this so it gives a delay after shutting down so smoke doesn't enter the house // TODO Change this so it gives a delay after shutting down so smoke doesn't enter the house
if (config.status.blower == 1) { if (config.status.blower == 1) {
config.times.blowerOff = Date.now() + 600000; // 10 minutes, TODO move to config // Set the timestamp to turn the blower off at
// TODO Move this to another function, to run after tests pass config.timestamps.blowerOff = Date.now() + config.intervals.blowerStop;
// functions.power.blower.off(gpio).then(res => { }
// if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: Shut off blower.`); return "Shutdown has been initiated.";
} else {
// }); return "A shutdown has already been initiated.";
} }
}, },
}, },
@ -252,15 +269,15 @@ const functions = {
} else { } else {
reject("E: Unable to determine igniter status."); reject("E: Unable to determine igniter status.");
} }
if (config.igniterOnTime > 0) { if (config.timestamps.igniterOn > 0) {
const humanStartTime = new Date(config.igniterOnTime).toISOString(); const humanStartTime = new Date(config.timestamps.igniterOn).toISOString();
const humanEndTime = new Date(config.igniterOffTime).toISOString(); const humanEndTime = new Date(config.timestamps.igniterOff).toISOString();
if (Date.now() < config.igniterOffTime && config.status.igniter == 1) { if (Date.now() < config.timestamps.igniterOff && config.status.igniter == 1) {
statusMsg += `Igniter started: ${humanStartTime}.\n`; statusMsg += `Igniter started: ${humanStartTime}.\n`;
statusMsg += `Igniter scheduled to stop: ${humanEndTime}.\n`; statusMsg += `Igniter scheduled to stop: ${humanEndTime}.\n`;
} }
// Shut the igniter off if it's past the waiting period // Shut the igniter off if it's past the waiting period
if ((Date.now() > config.igniterOffTime) && (config.status.igniter == 1)) { if ((Date.now() > config.timestamps.igniterOff) && (config.status.igniter == 1)) {
if (process.env.ONPI == 'true') { if (process.env.ONPI == 'true') {
gpio.write(igniterPin, false, (err) => { gpio.write(igniterPin, false, (err) => {
if (err) throw(err); if (err) throw(err);
@ -280,8 +297,8 @@ const functions = {
config.status.igniter = 0; config.status.igniter = 0;
statusMsg += `${new Date().toISOString()} I: Simulated igniter turned off.`; statusMsg += `${new Date().toISOString()} I: Simulated igniter turned off.`;
} }
} else if ((Date.now() > config.igniterOffTime) && (config.status.igniter == 0)) { } else if ((Date.now() > config.timestamps.igniterOff) && (config.status.igniter == 0)) {
statusMsg += `The igniter was turned off at ${new Date(config.igniterOffTime).toISOString()}.`; statusMsg += `The igniter was turned off at ${new Date(config.timestamps.igniterOff).toISOString()}.`;
} }
} else { } else {
statusMsg += 'The igniter hasn\'t been started yet.'; statusMsg += 'The igniter hasn\'t been started yet.';
@ -290,13 +307,7 @@ const functions = {
}); });
}, },
blowerOffDelay() { blowerOffDelay() {
if (config.times.blowerOff == 0) return false;
// TODO Implement the blower shutdown delay as a test here
if (Date.now() > config.times.blowerOff) {
return true;
} else {
return false;
}
}, },
}, },
power: { power: {
@ -366,9 +377,9 @@ const functions = {
== Startup Time: ${new Date().toISOString()} == Startup Time: ${new Date().toISOString()}
== ==
== Environment variables: == Environment variables:
== == ONTIME=${config.augerOnTime} == == ONTIME=${config.intervals.augerOn}
== == OFFTIME=${config.augerOffTime} == == OFFTIME=${config.intervals.augerOff}
== == PAUSETIME=${config.pauseTime} == == PAUSETIME=${config.intervals.pause}
== == DEBUG=${config.debugMode} == == DEBUG=${config.debugMode}
== == ONPI=${process.env.ONPI}`); == == ONPI=${process.env.ONPI}`);
// Set up GPIO 4 (pysical pin 7) as output, then call functions.auger.ready() // Set up GPIO 4 (pysical pin 7) as output, then call functions.auger.ready()

32
main.js
View File

@ -12,32 +12,32 @@ const fn = require('./functions.js').functions;
// Config File // Config File
const config = require('./config.json'); const config = require('./config.json');
config.startTime = Date.now(); config.timestamps.procStart = Date.now();
// Environment Variables Importing // Environment Variables Importing
const dotenv = require('dotenv').config(); const dotenv = require('dotenv').config();
// Setup for use with the Pi's GPIO pins // Setup for use with the Pi's GPIO pins
if (process.env.ONPI == 'true') { if (process.env.ONPI == 'true') {
console.log(`[${(Date.now() - config.startTime)/1000}] == Running on a Raspberry Pi.`); console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] == Running on a Raspberry Pi.`);
const gpio = require('rpi-gpio'); const gpio = require('rpi-gpio');
fn.init(gpio).then((res) => { fn.init(gpio).then((res) => {
console.log(`[${(Date.now() - config.startTime)/1000}] I: ${res}`); console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
main(fn, gpio); main(fn, gpio);
}).catch(rej => { }).catch(rej => {
console.error(`[${(Date.now() - config.startTime)/1000}] E: ${rej}`); console.error(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${rej}`);
}); });
} else if (process.env.ONPI == 'false') { } else if (process.env.ONPI == 'false') {
console.log(`[${(Date.now() - config.startTime)/1000}] I: Not running on a Raspberry Pi.`); console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: Not running on a Raspberry Pi.`);
const gpio = 'gpio'; const gpio = 'gpio';
fn.init(gpio).then(res => { fn.init(gpio).then(res => {
console.log(`[${(Date.now() - config.startTime)/1000}] I: ${res}`); console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
main(fn, gpio); main(fn, gpio);
}).catch(rej => { }).catch(rej => {
console.error(rej); console.error(rej);
}); });
} else { } else {
console.error(`[${Date.now() - config.startTime}] E: Problem with ENV file.`); console.error(`[${Date.now() - config.timestamps.procStart}] E: Problem with ENV file.`);
} }
// TODO Add logic for other sensors // TODO Add logic for other sensors
@ -49,7 +49,7 @@ async function main(fn, gpio) {
// Check for the existence of certain files // Check for the existence of certain files
fn.files.check().then((res,rej) => { fn.files.check().then((res,rej) => {
// Log the result of the check if in debug mode // Log the result of the check if in debug mode
if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: File Check: ${res}`); if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: File Check: ${res}`);
// Choose what to do depending on the result of the check // Choose what to do depending on the result of the check
switch (res) { switch (res) {
case "pause": case "pause":
@ -65,7 +65,7 @@ async function main(fn, gpio) {
// Rerun this function once the reload has finished // Rerun this function once the reload has finished
main(fn, gpio); main(fn, gpio);
}).catch(rej => { }).catch(rej => {
console.error(`[${(Date.now() - config.startTime)/1000}] E: ${rej}`); console.error(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${rej}`);
}); });
break; break;
case "quit": case "quit":
@ -78,7 +78,7 @@ async function main(fn, gpio) {
if (config.debugMode) console.log(res); if (config.debugMode) console.log(res);
statusCheck(fn, gpio); statusCheck(fn, gpio);
}).catch(rej => { }).catch(rej => {
console.error(`[${(Date.now() - config.startTime)/1000}] E: ${rej}`); console.error(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${rej}`);
fn.commands.shutdown(gpio).then(res => { fn.commands.shutdown(gpio).then(res => {
fn.commands.quit(); fn.commands.quit();
}).catch(rej => { }).catch(rej => {
@ -100,7 +100,7 @@ async function main(fn, gpio) {
if (config.status.auger == 1) { if (config.status.auger == 1) {
fn.auger.cycle(gpio).then((res) => { fn.auger.cycle(gpio).then((res) => {
// Log the auger cycle results if in debug mode. // Log the auger cycle results if in debug mode.
if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: ${res}`); if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
// Run the status check function // Run the status check function
statusCheck(fn, gpio); statusCheck(fn, gpio);
// Rerun this function once the cycle is complete // Rerun this function once the cycle is complete
@ -115,7 +115,7 @@ async function main(fn, gpio) {
default: default:
// If we don't get a result from the file check, or for some reason it's an unexpected response, log it and quit the script. // If we don't get a result from the file check, or for some reason it's an unexpected response, log it and quit the script.
console.error(`[${(Date.now() - config.startTime)/1000}] E: No result was received, something is wrong.\nres: ${res}`); console.error(`[${(Date.now() - config.timestamps.procStart)/1000}] E: No result was received, something is wrong.\nres: ${res}`);
fn.commands.quit(); fn.commands.quit();
break; break;
} }
@ -124,7 +124,7 @@ async function main(fn, gpio) {
function statusCheck(fn, gpio) { function statusCheck(fn, gpio) {
fn.tests.igniter(gpio).then((res) => { fn.tests.igniter(gpio).then((res) => {
if (config.debugMode) console.log(`[${(Date.now() - config.startTime)/1000}] I: ${res}`); if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
main(fn, gpio); main(fn, gpio);
}); });
@ -139,15 +139,15 @@ function statusCheck(fn, gpio) {
// Check the Proof of Fire Switch // Check the Proof of Fire Switch
fn.tests.pof(gpio).then(status => { fn.tests.pof(gpio).then(status => {
// If the igniter has finished running and no proof of fire is seen, shutdown the stove // If the igniter has finished running and no proof of fire is seen, shutdown the stove
// TODO Shutdown will handle checks if it's being called repeatedly.
if (config.status.igniterFinished && (!status)) fn.commands.shutdown(gpio); if (config.status.igniterFinished && (!status)) fn.commands.shutdown(gpio);
}); });
// blowerOffDelay() returns true only if the blower shutdown has // blower.canShutdown() returns true only if the blower shutdown has
// been initiated AND the specified cooldown time has passed // been initiated AND the specified cooldown time has passed
if(fn.tests.blowerOffDelay()) { if(fn.blower.canShutdown()) {
fn.power.blower.off(gpio).then(res => { fn.power.blower.off(gpio).then(res => {
// Since the blower shutting off is the last step in the shutdown, we can quit. // Since the blower shutting off is the last step in the shutdown, we can quit.
// TODO eventually we don't want to ever quit the program, so it can be restarted remotely
fn.commands.quit(); fn.commands.quit();
}); });
} }