Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
a00e8e73a6 | |||
f0f865d2e7 | |||
eea8c9fef5 | |||
c80306271d | |||
dc3fc976d8 | |||
09c73ac619 | |||
28ac67c834 | |||
fbb4b78e41 | |||
60657b2da6 | |||
2823f9d96d | |||
51ba50c0c6 | |||
c52fca4b5a | |||
ceab174d04 | |||
ec50ed3516 | |||
1919a9c518 | |||
78a502e959 | |||
ef726b1853 | |||
23aa026e9f | |||
67a9fc19ec | |||
db763223c6 | |||
0b6794fb89 | |||
9e6e813b4c | |||
ac1848c48e | |||
2358d6eb8f | |||
6ab9bed2b4 | |||
695e283246 | |||
43ab7dd367 |
16
README.md
16
README.md
@ -104,3 +104,19 @@ For ease of adaption, connection, and prototyping I've decided to use Cat 5 ethe
|
|||||||
2 | pause | 5000
|
2 | pause | 5000
|
||||||
3 | igniter_start | 420000
|
3 | igniter_start | 420000
|
||||||
4 | blower_stop | 600000
|
4 | blower_stop | 600000
|
||||||
|
|
||||||
|
# Startup Procedure
|
||||||
|
1. Manually toggle the "I" Igniter switch ON
|
||||||
|
2. Wait 60 seconds
|
||||||
|
3. Manually toggle the "E" Exhaust switch ON
|
||||||
|
4. Using the Hestia Web Portal, set Feed Rate to 2
|
||||||
|
5. Enable the Auger
|
||||||
|
6. Wait up to three minutes for pellets to ignite
|
||||||
|
7. Manually toggle the "I" Ingniter switch OFF
|
||||||
|
8. Monitor fire and adjust feed rates as necessary
|
||||||
|
|
||||||
|
# Timings
|
||||||
|
* 60-90 seconds igniter preheat
|
||||||
|
* 120-180 seconds for pellet ignition
|
||||||
|
* 4 minutes from ignition to PoF Close
|
||||||
|
* 7:30 minutes total
|
45
main.js
45
main.js
@ -9,9 +9,15 @@ portal.start();
|
|||||||
|
|
||||||
dbfn.run(`UPDATE timestamps SET value = ${Date.now()} WHERE key = 'process_start'`).catch(err => console.error(`Error setting process start time: ${err}`));
|
dbfn.run(`UPDATE timestamps SET value = ${Date.now()} WHERE key = 'process_start'`).catch(err => console.error(`Error setting process start time: ${err}`));
|
||||||
|
|
||||||
|
// Initialization, which then calls main()
|
||||||
fn.commands.refreshConfig().then(res => {
|
fn.commands.refreshConfig().then(res => {
|
||||||
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res.status}`);
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res.status}`);
|
||||||
config = res.config;
|
config = res.config;
|
||||||
|
const shutdownNextCycleQuery = "UPDATE status SET value = 0 WHERE key = 'shutdown_next_cycle'";
|
||||||
|
dbfn.run(shutdownNextCycleQuery).then(res => {
|
||||||
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res.status}`);
|
||||||
|
console.log(`[${(Date.now() - config.timestamps.procStart) / 1000}] I: Shutdown flag reset.`);
|
||||||
|
}).catch(err => console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${err}`));
|
||||||
// Setup for use with the Pi's GPIO pins
|
// Setup for use with the Pi's GPIO pins
|
||||||
switch (process.env.ONPI) {
|
switch (process.env.ONPI) {
|
||||||
case 'true':
|
case 'true':
|
||||||
@ -47,6 +53,45 @@ fn.commands.refreshConfig().then(res => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function main(gpio) {
|
function main(gpio) {
|
||||||
|
// Set the Igniter
|
||||||
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: IGN: [${config.status.igniter}] | EXH: [${config.status.exhaust}] | AUG: [${config.status.auger}]`);
|
||||||
|
switch (config.status.igniter) {
|
||||||
|
case '0':
|
||||||
|
fn.igniter.off(gpio).then(res => {
|
||||||
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
fn.igniter.on(gpio).then(res => {
|
||||||
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fn.igniter.off(gpio).then(res => {
|
||||||
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the Exhaust
|
||||||
|
switch (config.status.exhaust) {
|
||||||
|
case '0':
|
||||||
|
fn.exhaust.off(gpio).then(res => {
|
||||||
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
fn.exhaust.on(gpio).then(res => {
|
||||||
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fn.exhaust.off(gpio).then(res => {
|
||||||
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res}`);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// If the auger is enabled
|
// If the auger is enabled
|
||||||
if (config.status.auger == 1) {
|
if (config.status.auger == 1) {
|
||||||
// Run a cycle of the auger
|
// Run a cycle of the auger
|
||||||
|
@ -7,15 +7,20 @@
|
|||||||
* Add actual data into the responses
|
* Add actual data into the responses
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Modules
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
|
const fs = require('fs');
|
||||||
const fn = require('./functions.js').functions;
|
const fn = require('./functions.js').functions;
|
||||||
|
const { dbfn } = require('./functions.js');
|
||||||
|
|
||||||
|
// Grab the current configuration settings from the database to display
|
||||||
var config;
|
var config;
|
||||||
fn.commands.refreshConfig().then(newConfig => {
|
fn.commands.refreshConfig().then(newConfig => {
|
||||||
config = newConfig.config;
|
config = newConfig.config;
|
||||||
});
|
});
|
||||||
const { dbfn } = require('./functions.js');
|
|
||||||
|
|
||||||
|
// Create the server
|
||||||
const app = express();
|
const app = express();
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
app.use(express.urlencoded());
|
app.use(express.urlencoded());
|
||||||
@ -29,28 +34,70 @@ app.set('view engine', 'html');
|
|||||||
|
|
||||||
// A normal load of the root page
|
// A normal load of the root page
|
||||||
app.get('/', (req, res) => {
|
app.get('/', (req, res) => {
|
||||||
// if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${JSON.stringify(config)}`);
|
// Render the page, passing the config along for the front end to use
|
||||||
res.render('index', { config: JSON.stringify(config) });
|
res.render('index', { config: JSON.stringify(config) });
|
||||||
});
|
});
|
||||||
|
|
||||||
// A POST form submission to the root page
|
// A POST form submission to the root page
|
||||||
app.post('/', (req, response) => {
|
app.post('/', (req, response) => {
|
||||||
if (req.body.start != undefined) {
|
if (req.body.augerOn != undefined) {
|
||||||
fn.commands.startup();
|
fn.commands.augerOn();
|
||||||
fn.commands.refreshConfig().then(res => {
|
fn.commands.refreshConfig().then(res => {
|
||||||
config = res.config;
|
config = res.config;
|
||||||
response.render('index', { config: JSON.stringify(config) });
|
response.render('index', { config: JSON.stringify(config) });
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (req.body.shutdown != undefined) {
|
if (req.body.augerOff != undefined) {
|
||||||
fn.commands.shutdown();
|
fn.commands.augerOff();
|
||||||
fn.commands.refreshConfig().then(res => {
|
fn.commands.refreshConfig().then(res => {
|
||||||
config = res.config;
|
config = res.config;
|
||||||
response.render('index', { config: JSON.stringify(config) });
|
response.render('index', { config: JSON.stringify(config) });
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req.body.igniterOn != undefined) {
|
||||||
|
fn.commands.igniterOn();
|
||||||
|
fn.commands.refreshConfig().then(res => {
|
||||||
|
config = res.config;
|
||||||
|
response.render('index', { config: JSON.stringify(config) });
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (req.body.igniterOff != undefined) {
|
||||||
|
fn.commands.igniterOff();
|
||||||
|
fn.commands.refreshConfig().then(res => {
|
||||||
|
config = res.config;
|
||||||
|
response.render('index', { config: JSON.stringify(config) });
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.body.exhaustOn != undefined) {
|
||||||
|
fn.commands.exhaustOn();
|
||||||
|
fn.commands.refreshConfig().then(res => {
|
||||||
|
config = res.config;
|
||||||
|
response.render('index', { config: JSON.stringify(config) });
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (req.body.exhaustOff != undefined) {
|
||||||
|
fn.commands.exhaustOff();
|
||||||
|
fn.commands.refreshConfig().then(res => {
|
||||||
|
config = res.config;
|
||||||
|
response.render('index', { config: JSON.stringify(config) });
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (req.body.reload != undefined) {
|
if (req.body.reload != undefined) {
|
||||||
const updateAugerOffIntervalQuery = `UPDATE intervals SET value = '${2000 - req.body.feedRate}' WHERE key = 'auger_off'`;
|
const updateAugerOffIntervalQuery = `UPDATE intervals SET value = '${2000 - req.body.feedRate}' WHERE key = 'auger_off'`;
|
||||||
const updateAugerOnIntervalQuery = `UPDATE intervals SET value = '${req.body.feedRate}' WHERE key = 'auger_on'`;
|
const updateAugerOnIntervalQuery = `UPDATE intervals SET value = '${req.body.feedRate}' WHERE key = 'auger_on'`;
|
||||||
@ -65,15 +112,24 @@ app.post('/', (req, response) => {
|
|||||||
});
|
});
|
||||||
}).catch(err => console.log(`E: ${err}`));
|
}).catch(err => console.log(`E: ${err}`));
|
||||||
}).catch(err => console.log(`E: ${err}`));
|
}).catch(err => console.log(`E: ${err}`));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (req.body.quit != undefined) {
|
if (req.body.quit != undefined) {
|
||||||
fn.commands.quit();
|
fs.appendFile('quit', ".", err => {
|
||||||
|
if (err) console.error(err);
|
||||||
|
});
|
||||||
fn.commands.refreshConfig().then(res => {
|
fn.commands.refreshConfig().then(res => {
|
||||||
config = res.config;
|
config = res.config;
|
||||||
response.render('index', { config: JSON.stringify(config) });
|
response.render('index', { config: JSON.stringify(config) });
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
fn.commands.refreshConfig().then(res => {
|
||||||
|
config = res.config;
|
||||||
|
response.render('index', { config: JSON.stringify(config) });
|
||||||
|
return;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -127,8 +127,8 @@ const createIntervalsTableQuery = "CREATE TABLE IF NOT EXISTS intervals (key var
|
|||||||
dbfn.run(createIntervalsTableQuery).then(res => {
|
dbfn.run(createIntervalsTableQuery).then(res => {
|
||||||
console.log(res.status);
|
console.log(res.status);
|
||||||
const intervalsEntries = {
|
const intervalsEntries = {
|
||||||
auger_on: 600,
|
auger_on: 500,
|
||||||
auger_off: 1400,
|
auger_off: 1500,
|
||||||
pause: 5000,
|
pause: 5000,
|
||||||
igniter_start: 420000,
|
igniter_start: 420000,
|
||||||
blower_stop: 600000
|
blower_stop: 600000
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
// TODO: Move these to config
|
// TODO: Move these to config
|
||||||
// Physical Pin numbers for GPIO
|
// Physical Pin numbers for GPIO
|
||||||
const augerPin = 7; // Pin for controlling the relay for the pellet auger motor.
|
const augerPin = 7; // Pin for controlling the relay for the pellet auger motor.
|
||||||
|
const igniterPin = 13;
|
||||||
|
const exhaustPin = 15;
|
||||||
|
const pofPin = 16;
|
||||||
|
|
||||||
// Require the package for pulling version numbers
|
// Require the package for pulling version numbers
|
||||||
const package = require('../package.json');
|
const package = require('../package.json');
|
||||||
@ -84,9 +87,83 @@ const functions = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
igniter: {
|
||||||
|
// Gets called once the Igniter Pin has been setup by rpi-gpio
|
||||||
|
ready(err) {
|
||||||
|
if (err) throw err;
|
||||||
|
console.log('Igniter GPIO Ready');
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
// Turns the Igniter on (Pin 7 high)
|
||||||
|
on(gpio) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (process.env.ONPI == 'true') {
|
||||||
|
gpio.write(igniterPin, true, function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
resolve('Igniter turned on.');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve('Simulated Igniter turned on.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
// Turns the Igniter off (pin 7 low)
|
||||||
|
off(gpio) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (process.env.ONPI == 'true') {
|
||||||
|
gpio.write(igniterPin, false, function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
resolve('Igniter turned off.');
|
||||||
|
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve('Simulated Igniter turned off.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
exhaust: {
|
||||||
|
// Gets called once the Exhaust Pin has been setup by rpi-gpio
|
||||||
|
ready(err) {
|
||||||
|
if (err) throw err;
|
||||||
|
console.log('Exhaust GPIO Ready');
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
// Turns the Exhaust on (Pin 7 high)
|
||||||
|
on(gpio) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (process.env.ONPI == 'true') {
|
||||||
|
gpio.write(exhaustPin, true, function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
resolve('Exhaust turned on.');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve('Simulated Exhaust turned on.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
// Turns the Exhaust off (pin 7 low)
|
||||||
|
off(gpio) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (process.env.ONPI == 'true') {
|
||||||
|
gpio.write(exhaustPin, false, function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
resolve('Exhaust turned off.');
|
||||||
|
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve('Simulated Exhaust turned off.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
commands: {
|
commands: {
|
||||||
// Prepare the stove for starting
|
// Prepare the stove for starting
|
||||||
startup() {
|
augerOn() { // FKA startup()
|
||||||
// Basic startup just enables the auger
|
// Basic startup just enables the auger
|
||||||
const enableAugerQuery = "UPDATE status SET value = 1 WHERE key = 'auger'";
|
const enableAugerQuery = "UPDATE status SET value = 1 WHERE key = 'auger'";
|
||||||
dbfn.run(enableAugerQuery).then(res => {
|
dbfn.run(enableAugerQuery).then(res => {
|
||||||
@ -94,7 +171,7 @@ const functions = {
|
|||||||
return;
|
return;
|
||||||
}).catch(err => console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${err}`));
|
}).catch(err => console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${err}`));
|
||||||
},
|
},
|
||||||
shutdown() {
|
augerOff() { // FKA shutdown()
|
||||||
// Basic shutdown only needs to disable the auger
|
// Basic shutdown only needs to disable the auger
|
||||||
const disableAugerQuery = "UPDATE status SET value = 0 WHERE key = 'auger'";
|
const disableAugerQuery = "UPDATE status SET value = 0 WHERE key = 'auger'";
|
||||||
dbfn.run(disableAugerQuery).then(res => {
|
dbfn.run(disableAugerQuery).then(res => {
|
||||||
@ -103,6 +180,36 @@ const functions = {
|
|||||||
return;
|
return;
|
||||||
}).catch(err => console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${err}`));
|
}).catch(err => console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${err}`));
|
||||||
},
|
},
|
||||||
|
igniterOn() {
|
||||||
|
const enableIgniterQuery = "UPDATE status SET value = 1 WHERE key = 'igniter'";
|
||||||
|
dbfn.run(enableIgniterQuery).then(res => {
|
||||||
|
console.log(`[${(Date.now() - config.timestamps.procStart) / 1000}] I: Igniter enabled.`);
|
||||||
|
return;
|
||||||
|
}).catch(err => console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${err}`));
|
||||||
|
},
|
||||||
|
igniterOff() {
|
||||||
|
const disableIgniterQuery = "UPDATE status SET value = 0 WHERE key = 'igniter'";
|
||||||
|
dbfn.run(disableIgniterQuery).then(res => {
|
||||||
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res.status}`);
|
||||||
|
console.log(`[${(Date.now() - config.timestamps.procStart) / 1000}] I: Igniter disabled.`);
|
||||||
|
return;
|
||||||
|
}).catch(err => console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${err}`));
|
||||||
|
},
|
||||||
|
exhaustOn() {
|
||||||
|
const enableExhaustQuery = "UPDATE status SET value = 1 WHERE key = 'blower'";
|
||||||
|
dbfn.run(enableExhaustQuery).then(res => {
|
||||||
|
console.log(`[${(Date.now() - config.timestamps.procStart) / 1000}] I: Exhaust enabled.`);
|
||||||
|
return;
|
||||||
|
}).catch(err => console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${err}`));
|
||||||
|
},
|
||||||
|
exhaustOff() {
|
||||||
|
const disableExhaustQuery = "UPDATE status SET value = 0 WHERE key = 'blower'";
|
||||||
|
dbfn.run(disableExhaustQuery).then(res => {
|
||||||
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res.status}`);
|
||||||
|
console.log(`[${(Date.now() - config.timestamps.procStart) / 1000}] I: Exhaust disabled.`);
|
||||||
|
return;
|
||||||
|
}).catch(err => console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${err}`));
|
||||||
|
},
|
||||||
// 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) => {
|
||||||
@ -158,7 +265,7 @@ const functions = {
|
|||||||
let { status } = config;
|
let { status } = config;
|
||||||
let { rows } = res;
|
let { rows } = res;
|
||||||
status.auger = rows.auger;
|
status.auger = rows.auger;
|
||||||
status.blower = rows.blower;
|
status.exhaust = rows.blower; // TODO update db to use exhaust not blower
|
||||||
status.igniter = rows.igniter;
|
status.igniter = rows.igniter;
|
||||||
status.igniterFinished = rows.igniter_finished;
|
status.igniterFinished = rows.igniter_finished;
|
||||||
status.pof = rows.proof_of_fire;
|
status.pof = rows.proof_of_fire;
|
||||||
@ -170,8 +277,8 @@ const functions = {
|
|||||||
dbfn.all(selectTimestampsQuery).then(res => {
|
dbfn.all(selectTimestampsQuery).then(res => {
|
||||||
let { timestamps } = config;
|
let { timestamps } = config;
|
||||||
let { rows } = res;
|
let { rows } = res;
|
||||||
timestamps.blowerOff = rows.blower_off;
|
timestamps.exhaustOff = rows.blower_off;
|
||||||
timestamps.blowerOn = rows.blower_on;
|
timestamps.exhaustOn = rows.blower_on;
|
||||||
timestamps.igniterOff = rows.igniter_off;
|
timestamps.igniterOff = rows.igniter_off;
|
||||||
timestamps.igniterOn = rows.igniter_on;
|
timestamps.igniterOn = rows.igniter_on;
|
||||||
timestamps.procStart = rows.process_start;
|
timestamps.procStart = rows.process_start;
|
||||||
@ -255,12 +362,25 @@ const functions = {
|
|||||||
gpio.setup(augerPin, gpio.DIR_OUT, (err) => {
|
gpio.setup(augerPin, gpio.DIR_OUT, (err) => {
|
||||||
if (err) reject(err);
|
if (err) reject(err);
|
||||||
if (process.env.DEBUG) console.log('== Auger pin initialized.');
|
if (process.env.DEBUG) console.log('== Auger pin initialized.');
|
||||||
// Resolve the promise now that all pins have been initialized
|
this.auger.ready();
|
||||||
resolve('== GPIO Initialized.');
|
// Init the Igniter pin
|
||||||
|
gpio.setup(igniterPin, gpio.DIR_OUT, (err) => {
|
||||||
|
if (err) reject(err);
|
||||||
|
if (process.env.DEBUG) console.log('== Igniter pin initialized.');
|
||||||
|
this.igniter.ready();
|
||||||
|
// Init the Exhaust pin
|
||||||
|
gpio.setup(exhaustPin, gpio.DIR_OUT, (err) => {
|
||||||
|
if (err) reject(err);
|
||||||
|
if (process.env.DEBUG) console.log('== Exhaust pin initialized.');
|
||||||
|
this.exhaust.ready();
|
||||||
|
// Resolve the promise now that all pins have been initialized
|
||||||
|
resolve('== GPIO Initialized.');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Resolve the promise
|
// Resolve the promise
|
||||||
resolve('== GPIO Not Available');
|
resolve('== GPIO Simulated');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -275,6 +395,11 @@ const functions = {
|
|||||||
if (err) console.log('Error removing the quit file: ' + err);
|
if (err) console.log('Error removing the quit file: ' + err);
|
||||||
config.status.shutdownNextCycle = 1;
|
config.status.shutdownNextCycle = 1;
|
||||||
config.status.auger = 0;
|
config.status.auger = 0;
|
||||||
|
const shutdownNextCycleQuery = "UPDATE status SET value = 1 WHERE key = 'shutdown_next_cycle'";
|
||||||
|
dbfn.run(shutdownNextCycleQuery).then(res => {
|
||||||
|
if (process.env.DEBUG) console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] I: ${res.status}`);
|
||||||
|
console.log(`[${(Date.now() - config.timestamps.procStart) / 1000}] I: Shutting down next cycle.`);
|
||||||
|
}).catch(err => console.log(`[${(Date.now() - config.timestamps.procStart)/1000}] E: ${err}`));
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
2692
package-lock.json
generated
2692
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pscontrolpanel",
|
"name": "hestia",
|
||||||
"version": "0.2.1",
|
"version": "0.3.0",
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {},
|
"packages": {},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -10,6 +10,6 @@
|
|||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"rpi-gpio": "^2.1.7",
|
"rpi-gpio": "^2.1.7",
|
||||||
"sequelize": "^6.28.0",
|
"sequelize": "^6.28.0",
|
||||||
"sqlite3": "^5.1.4"
|
"sqlite3": "^5.1.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
margin: 0 auto;
|
margin: 10;
|
||||||
color: aqua !important;
|
color: aqua !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,3 +96,11 @@ table, th, td {
|
|||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#quit {
|
||||||
|
/* visibility: hidden; */
|
||||||
|
}
|
@ -21,22 +21,28 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="status" class="row">
|
<div id="status" class="row">
|
||||||
<!--
|
<!--
|
||||||
| Auger | rows[0].cells[1] | On Time | rows[0].cells[3] |
|
| Igniter | rows[0].cells[1]
|
||||||
| Feed Rate | rows[1].cells[1] | Off Time | rows[1].cells[3] |
|
| Exhaust | rows[1].cells[1]
|
||||||
|
| Auger | rows[2].cells[1]
|
||||||
|
| Feed Rate | rows[3].cells[1]
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<table id="status-table" class="table table-bordered col-sm-12 col-md-6">
|
<table id="status-table" class="table table-bordered col-sm-12 col-md-6">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Auger</td>
|
<td>Igniter</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>On Time</td>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Exhaust</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Auger</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Feed Rate</td>
|
<td>Feed Rate</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>Off Time</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -47,15 +53,27 @@
|
|||||||
<form action="/" method="post">
|
<form action="/" method="post">
|
||||||
<!-- Start | Shutdown | Reload Settings -->
|
<!-- Start | Shutdown | Reload Settings -->
|
||||||
<div class="button-container d-flex justify-content-between">
|
<div class="button-container d-flex justify-content-between">
|
||||||
<input class="btn btn-outline-secondary" type="submit" id="ignite" value="Enable Auger" name="start">
|
<input class="btn btn-outline-secondary" type="submit" id="igniter-off" value="Disable Igniter" name="igniterOff">
|
||||||
<input class="btn btn-outline-secondary" type="submit" id="shutdown" value="Disable Auger" name="shutdown">
|
<input class="btn btn-outline-secondary" type="submit" id="igniter-on" value="Enable Igniter" name="igniterOn">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="button-container d-flex justify-content-between">
|
||||||
|
<input class="btn btn-outline-secondary" type="submit" id="exhaust-off" value="Disable Exhaust" name="exhaustOff">
|
||||||
|
<input class="btn btn-outline-secondary" type="submit" id="exhaust-on" value="Enable Exhaust" name="exhaustOn">
|
||||||
|
</div>
|
||||||
|
<div class="button-container d-flex justify-content-between">
|
||||||
|
<input class="btn btn-outline-secondary" type="submit" id="auger-off" value="Disable Auger" name="augerOff">
|
||||||
|
<input class="btn btn-outline-secondary" type="submit" id="auger-on" value="Enable Auger" name="augerOn">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- Set feed rates -->
|
<!-- Set feed rates -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="feedRate">Feed Rate: </label>
|
<label for="feedRate">Feed Rate: </label>
|
||||||
<select name="feedRate" class="form-control" id="feed-rate-select">
|
<select name="feedRate" class="form-control" id="feed-rate-select">
|
||||||
<option value="600">Low</option>
|
<option value="500">Low</option>
|
||||||
<option value="800">Medium</option>
|
<option value="625">Medium-Low</option>
|
||||||
|
<option value="750">Medium</option>
|
||||||
|
<option value="875">Medium-High</option>
|
||||||
<option value="1000">High</option>
|
<option value="1000">High</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -64,12 +82,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="text-center my-4">
|
<div class="text-center my-4">
|
||||||
<img src="./dancing_jesus.gif" class="img-fluid">
|
<img src="./dancing_jesus.gif" class="img-fluid">
|
||||||
</div> -->
|
</div>
|
||||||
<div class="controls-container">
|
<div class="controls-container">
|
||||||
<form action="/" method="POST">
|
<form action="/" method="POST">
|
||||||
<input class="btn btn-danger" type="submit" id="quit" value="Quit!!" name="quit" style="visibility: hidden;">
|
<input class="btn btn-danger" type="submit" id="quit" value="Quit!!" name="quit">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<!-- <script src="./main.js"></script> -->
|
<!-- <script src="./main.js"></script> -->
|
||||||
@ -113,30 +131,38 @@
|
|||||||
|
|
||||||
// Get the elements we need to update
|
// Get the elements we need to update
|
||||||
const statusTable = document.getElementById('status-table');
|
const statusTable = document.getElementById('status-table');
|
||||||
const augerStatus = statusTable.rows[0].cells[1];
|
const igniterStatus = statusTable.rows[0].cells[1];
|
||||||
const augerOn = statusTable.rows[0].cells[3];
|
const exhaustStatus = statusTable.rows[1].cells[1];
|
||||||
const augerOff = statusTable.rows[1].cells[3];
|
const augerStatus = statusTable.rows[2].cells[1];
|
||||||
const feedRate = statusTable.rows[1].cells[1];
|
const feedRate = statusTable.rows[3].cells[1];
|
||||||
const feedRateSelect = document.getElementById('feed-rate-select');
|
const feedRateSelect = document.getElementById('feed-rate-select');
|
||||||
|
|
||||||
// console.log(config);
|
// console.log(config);
|
||||||
|
|
||||||
|
igniterStatus.innerHTML = parseStatus(config.status.igniter);
|
||||||
|
exhaustStatus.innerHTML = parseStatus(config.status.exhaust);
|
||||||
augerStatus.innerHTML = parseStatus(config.status.auger);
|
augerStatus.innerHTML = parseStatus(config.status.auger);
|
||||||
augerOn.innerHTML = config.intervals.augerOn;
|
|
||||||
augerOff.innerHTML = config.intervals.augerOff;
|
|
||||||
|
|
||||||
switch (config.intervals.augerOn) {
|
switch (config.intervals.augerOn) {
|
||||||
case '600':
|
case '500':
|
||||||
feedRate.innerHTML = 'Low';
|
feedRate.innerHTML = 'Low';
|
||||||
feedRateSelect.selectedIndex = 0;
|
feedRateSelect.selectedIndex = 0;
|
||||||
break;
|
break;
|
||||||
case '800':
|
case '625':
|
||||||
feedRate.innerHTML = 'Medium';
|
feedRate.innerHTML = 'Medium-Low';
|
||||||
feedRateSelect.selectedIndex = 1;
|
feedRateSelect.selectedIndex = 1;
|
||||||
break;
|
break;
|
||||||
|
case '750':
|
||||||
|
feedRate.innerHTML = 'Medium';
|
||||||
|
feedRateSelect.selectedIndex = 2;
|
||||||
|
break;
|
||||||
|
case '875':
|
||||||
|
feedRate.innerHTML = 'Medium-High';
|
||||||
|
feedRateSelect.selectedIndex = 3;
|
||||||
|
break;
|
||||||
case '1000':
|
case '1000':
|
||||||
feedRate.innerHTML = 'High';
|
feedRate.innerHTML = 'High';
|
||||||
feedRateSelect.selectedIndex = 2;
|
feedRateSelect.selectedIndex = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
feedRate.innerHTML = 'Unknown';
|
feedRate.innerHTML = 'Unknown';
|
||||||
|
Loading…
Reference in New Issue
Block a user