Ready for testing on psdev

This commit is contained in:
Skylar Grant 2022-12-21 13:50:09 -05:00
parent 1de8ba78a7
commit 595d46dda2
7 changed files with 127 additions and 54 deletions

View File

@ -1,31 +1 @@
{ {"debugMode":true,"status":{"igniter":0,"blower":0,"auger":0,"igniterFinished":true,"seenFire":false,"shutdown":0,"vacuum":1,"pof":1},"timestamps":{"procStart":1671648471606,"blowerOn":1671648232716,"blowerOff":1671648326617,"igniterOn":1671648232717,"igniterOff":1671648263542},"intervals":{"augerOn":500,"augerOff":1500,"pause":3000,"igniterStart":30000,"blowerStop":10000},"web":{"port":8080,"ip":"127.0.0.1"}}
"debugMode": true,
"status": {
"igniter": 0,
"blower": 0,
"auger": 0,
"igniterFinished": false,
"seenFire": false,
"shutdown": 0,
"vacuum": 1,
"pof": 0
},
"timestamps": {
"procStart": 0,
"blowerOn": 0,
"blowerOff": 0,
"igniterOn": 0,
"igniterOff": 0
},
"intervals": {
"augerOn": 500,
"augerOff": 1500,
"pause": 3000,
"igniterStart": 30000,
"blowerStop": 10000
},
"web": {
"port": 8080,
"ip": "127.0.0.1"
}
}

View File

@ -246,7 +246,8 @@ const functions = {
functions.power.blower.off(gpio).then(res => { functions.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 // TODO eventually we don't want to ever quit the program, so it can be restarted remotely
functions.commands.quit(); // functions.commands.quit();
config.status.shutdown = 0;
}); });
} else { } else {
return "A shutdown has already been initiated and the blower is preventing shutdown."; return "A shutdown has already been initiated and the blower is preventing shutdown.";
@ -254,6 +255,11 @@ const functions = {
} }
}, },
writeConfig() {
fs.writeFile('./config.json', JSON.stringify(config), (err) => {
if (err) throw err;
});
}
}, },
tests: { tests: {
vacuum(gpio) { vacuum(gpio) {
@ -341,7 +347,7 @@ const functions = {
// } // }
// TODO I think this needs to be moved elsewhere, it doesn't finish resolving before the resolve call on line 354 is called (344+10=354) // TODO I think this needs to be moved elsewhere, it doesn't finish resolving before the resolve call on line 354 is called (344+10=354)
functions.power.igniter.off(gpio).then(res => { functions.power.igniter.off(gpio).then(res => {
statusMsg += res; if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
}); });
} else if ((Date.now() > config.timestamps.igniterOff) && (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.timestamps.igniterOff).toISOString()}.`; statusMsg += `The igniter was turned off at ${new Date(config.timestamps.igniterOff).toISOString()}.`;

58
log.txt
View File

@ -0,0 +1,58 @@
[0] I: Not running on a Raspberry Pi.
== Lennox Winslow PS40
== Pellet Stove Control Panel
== Author: Skylar Grant
== Version: v0.2.1
==
== Startup Time: 2022-12-21T18:47:51.607Z
==
== Environment variables:
== == ONTIME=500
== == OFFTIME=1500
== == PAUSETIME=3000
== == DEBUG=true
== == ONPI=false
[0.008] I: == GPIO Not Available
[0.008] I: Pausing for 3000ms
[3.012] I: Pausing for 3000ms
[6.014] I: Pausing for 3000ms
[9.016] I: Pausing for 3000ms
[12.018] I: Pausing for 3000ms
[15.019] I: Pausing for 3000ms
[18.02] I: Pausing for 3000ms
[21.021] I: Pausing for 3000ms
[24.022] I: Pausing for 3000ms
[27.024] I: Pausing for 3000ms
[30.027] I: Pausing for 3000ms
[33.029] I: Pausing for 3000ms
[36.031] I: Pausing for 3000ms
[39.032] I: Pausing for 3000ms
[42.032] I: Pausing for 3000ms
[45.034] I: Pausing for 3000ms
[48.035] I: Pausing for 3000ms
[51.037] I: Pausing for 3000ms
[54.039] I: Pausing for 3000ms
[57.04] I: Pausing for 3000ms
[60.041] I: Pausing for 3000ms
[63.043] I: Pausing for 3000ms
[66.044] I: Pausing for 3000ms
[69.046] I: Pausing for 3000ms
[72.048] I: Pausing for 3000ms
[75.049] I: Pausing for 3000ms
[78.05] I: Pausing for 3000ms
[81.052] I: Pausing for 3000ms
[84.054] I: Pausing for 3000ms
[87.055] I: Pausing for 3000ms
[90.057] I: Pausing for 3000ms
[93.059] I: Pausing for 3000ms
[96.061] I: Pausing for 3000ms
[99.063] I: Pausing for 3000ms
[102.064] I: Pausing for 3000ms
[105.065] I: Pausing for 3000ms
[108.065] I: Pausing for 3000ms
[111.067] I: Pausing for 3000ms
[114.069] I: Pausing for 3000ms
[117.071] I: Pausing for 3000ms
[120.071] I: Pausing for 3000ms
[123.073] I: Pausing for 3000ms
[126.075] I: Pausing for 3000ms

View File

@ -99,14 +99,14 @@ 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.timestamps.procStart)/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
// main(fn, gpio); // main(fn, gpio);
}); });
} else { } else {
if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: Auger Status: ${config.status.auger}`); // if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: Auger Status: ${config.status.auger}`);
fn.commands.pause().then(res => { fn.commands.pause().then(res => {
statusCheck(fn, gpio); statusCheck(fn, gpio);
@ -124,6 +124,7 @@ async function main(fn, gpio) {
} }
function statusCheck(fn, gpio) { function statusCheck(fn, gpio) {
fn.commands.writeConfig();
if (config.status.shutdown == 1) { if (config.status.shutdown == 1) {
console.log(fn.commands.shutdown(gpio) || 'Shutting down...'); console.log(fn.commands.shutdown(gpio) || 'Shutting down...');
main(fn, gpio); main(fn, gpio);
@ -152,7 +153,7 @@ function statusCheck(fn, gpio) {
console.log(fn.commands.shutdown(gpio)); console.log(fn.commands.shutdown(gpio));
main(fn, gpio); main(fn, gpio);
} else { } else {
if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: Vacuum and Proof of Fire OK.`); // if (config.debugMode) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: Vacuum and Proof of Fire OK.`);
main(fn, gpio); main(fn, gpio);
} }
}); });

View File

@ -15,7 +15,7 @@ const config = require('./config.json');
const fs = require('fs'); const fs = require('fs');
// const bodyParser = require('body-parser'); // const bodyParser = require('body-parser');
const core = require('./main.js'); const core = require('./main.js');
const fn = require('./functions.js'); const fn = require('./functions.js').functions;
const gpio = require('rpi-gpio'); const gpio = require('rpi-gpio');
app.use(express.urlencoded()); app.use(express.urlencoded());
@ -31,7 +31,6 @@ app.get('/', (req, res) => {
res.render('index', JSON.parse(data)); res.render('index', JSON.parse(data));
// res.send(200); // res.send(200);
}); });
console.log(req);
}); });
app.post('/', (req, res) => { app.post('/', (req, res) => {
@ -39,11 +38,14 @@ app.post('/', (req, res) => {
// console.log(JSON.parse(data)); // console.log(JSON.parse(data));
res.render('index', JSON.parse(data)); res.render('index', JSON.parse(data));
if (req.body.start != undefined) { if (req.body.start != undefined) {
core.main(fn, gpio); fn.commands.ignite(gpio);
}
if (req.body.shutdown != undefined) {
fn.commands.shutdown(gpio);
} }
// res.send(200); // res.send(200);
}); });
console.log(req.body); // console.log(req.body);
}); });
server.listen(config.web.port, config.web.ip); server.listen(config.web.port, config.web.ip);

1
www/public/config.json Symbolic link
View File

@ -0,0 +1 @@
/Users/voidf1sh/pscontrolpanel/config.json

View File

@ -4,11 +4,11 @@
<title>Pellet Stove Web Portal</title> <title>Pellet Stove Web Portal</title>
<link rel="stylesheet" href="/main.css"> <link rel="stylesheet" href="/main.css">
</head> </head>
<body> <body onload="refreshData()">
<%- include('trial.html') -%> <%- include('trial.html') -%>
<div id="title">Pellet Stove Web Portal</div> <div id="title">Pellet Stove Web Portal</div>
<div id="status">Auger: <%= status.auger %> | Igniter: <%= status.igniter %> | Combustion Blower: <%= status.blower %></div> <div id="status">Auger: <span id="auger-status"></span> | Igniter: <span id="igniter-status"></span> | Combustion Blower: <span id="blower-status"></span></div>
<div id="safeties">Vacuum: <%= status.vacuum %> | Proof of Fire: <%= status.pof %></div> <div id="safeties">Vacuum: <span id="vacuum-status"></span> | Proof of Fire: <span id="pof-status"></span></div>
<div id="controls-container"> <div id="controls-container">
<form action="/" method="post"> <form action="/" method="post">
<!-- Start | Shutdown | Reload Settings --> <!-- Start | Shutdown | Reload Settings -->
@ -16,23 +16,58 @@
<input type="submit" id="ignite" value="Start" name="start"><input type="submit" id="shutdown" value="Shutdown" name="shutdown"><input type="submit" id="reload" value="Reload" name="reload"><br> <input type="submit" id="ignite" value="Start" name="start"><input type="submit" id="shutdown" value="Shutdown" name="shutdown"><input type="submit" id="reload" value="Reload" name="reload"><br>
</div> </div>
<!-- Set feed rates --> <!-- Set feed rates -->
<label for="augerOn">Auger On Interval: </label><input type="number" id="augerOn" name="augerOn" min="500" max="1000" value="<%= intervals.augerOn %>">ms<br> <label for="augerOn">Auger On Interval: </label><input type="number" id="auger-on" name="augerOn" min="500" max="1000" value="<%= intervals.augerOn %>">ms<br>
<label for="augerOff">Auger Off Interval: </label><input type="number" id="augerOff" name="augerOff" min="1000" max="2000" value="<%= intervals.augerOff %>">ms<br> <label for="augerOff">Auger Off Interval: </label><input type="number" id="auger-off" name="augerOff" min="1000" max="2000" value="<%= intervals.augerOff %>">ms<br>
<label for="pauseInt">App Pause Interval: </label><input type="number" id="pauseInt" name="pauseInt" min="1000" max="600000" value="<%= intervals.pause %>">ms<br> <label for="pauseInt">App Pause Interval: </label><input type="number" id="pause-int" name="pauseInt" min="1000" max="600000" value="<%= intervals.pause %>">ms<br>
</form> </form>
</div> </div>
<div id="log-container"> <div id="log-container">
<!-- <button id="refresh-log" onclick="refreshLog()">Refresh Log</button><br> <button id="refresh-log" onclick="refreshLog()">Refresh Log</button><br>
<textarea id="log-area"></textarea> --> <!-- <textarea id="log-area"></textarea> -->
<iframe id="log-area" src="log.txt"></iframe> <iframe id="log-area" src="log.txt"></iframe>
</div> </div>
<script> <script>
function refreshLog() { function sleep(ms) {
console.log('Refresh button hit'); return new Promise((resolve, reject) => {
// TODO setTimeout(() => {
const fs = require('fs'); resolve();
fs.readFile('/log.txt', (err, data) => { }, ms);
document.getElementById('log-area').innerHTML = data; });
}
function readJSON(path) {
var request = new XMLHttpRequest();
request.open("GET", path, false);
request.send(null)
var JSONObj = JSON.parse(request.responseText);
return JSONObj;
}
function refreshData() {
const log = document.getElementById('log-area');
log.contentWindow.location.reload();
sleep(100).then(() => {
document.getElementById('log-area').contentWindow.scrollTo(0, 9999999);
});
const augerStatus = document.getElementById('auger-status');
const augerOn = document.getElementById('auger-on');
const augerOff = document.getElementById('auger-off');
const igniterStatus = document.getElementById('igniter-status');
const blowerStatus = document.getElementById('blower-status');
const pauseInt = document.getElementById('pause-int');
const config = readJSON('./config.json');
augerStatus.innerHTML = config.status.auger;
augerOn.innerHTML = config.intervals.augerOn;
augerOff.innerHTML = config.intervals.augerOff;
igniterStatus.innerHTML = config.status.igniter;
blowerStatus.innerHTML = config.status.blower;
pauseInt.innerHTML = config.intervals.pause;
sleep(2000).then(() => {
refreshData();
}); });
}; };
</script> </script>