Logic flow started

This commit is contained in:
Skylar Grant 2024-08-18 21:14:42 -04:00
parent 4666d84905
commit 6f4d94c17b
4 changed files with 152 additions and 27 deletions

View File

@ -1,14 +1,14 @@
# In Progress # In Progress
1. ~~Strip to bones~~ 1. ~~Strip to bones~~
2. Better commenting 2. Better commenting
2. Add startup and shutdown logic (start half implemented, not tested)
# Done # Done
1. GPIO Interface 1. GPIO Interface
1. Duplicate and adapt `HestiaClasses` from branch `v2-front`
# Immediate To-Do # Immediate To-Do
1. Duplicate and adapt `HestiaClasses` from branch `v2-front` 1. Connect to MQTT
2. Add startup and shutdown logic
3. Connect to MQTT
# Roadmap # Roadmap
1. Add wiring and sensors for safeties 1. Add wiring and sensors for safeties

View File

@ -1,29 +1,81 @@
export class State { export class State {
constructor(config) { constructor(config) {
config.mqtt.subscriptions.forEach(subscription => { this.igniter = {
this[subscription.name] = {
on: false, on: false,
topic: subscription.topic, name: "igniter",
publisher: 'back', topic: config.mqtt.topics.igniter,
publisher: 'front',
power: (communicator) => { power: (communicator) => {
// This *should* toggle the state, asks if state is true, if it is set it false, otherwise set it true // This *should* toggle the state, asks if state is true, if it is set it false, otherwise set it true
this[subscription.name].on ? this[subscription.name].on = false : this[subscription.name].on = true; this.igniter.on ? this.igniter.on = false : this.igniter.on = true;
communicator.send(subscription.name, JSON.stringify(this)); communicator.send(config.mqtt.topics.igniter, JSON.stringify(this.igniter));
} }
}; };
});
this.exhaust = {
on: false,
name: "exhaust",
topic: config.mqtt.topics.exhaust,
publisher: 'front',
power: (communicator) => {
// This *should* toggle the state, asks if state is true, if it is set it false, otherwise set it true
this.exhaust.on ? this.exhaust.on = false : this.exhaust.on = true;
communicator.send(config.mqtt.topics.exhaust, JSON.stringify(this.exhaust));
}
};
this.auger = {
on: false,
name: "auger",
feedRate: 500,
topic: config.mqtt.topics.auger,
publisher: 'front',
power: (communicator) => {
// This *should* toggle the state, asks if state is true, if it is set it false, otherwise set it true
this.auger.on ? this.auger.on = false : this.auger.on = true;
communicator.send(config.mqtt.topics.auger, JSON.stringify(this.auger));
}
};
console.log(`State initialized.`)
}; };
}; };
export class Communicator { export class Communicator {
constructor(state) { constructor(state) {
// Connect to the MQTT Broker this.publisher = state.publisher;
this.client = mqtt.connect(config.mqtt.address); return this;
}
init(state, config) {
// Connect to the MQTT Broker
console.log(`Attempting MQTT connection to broker: ${config.mqtt.address}, with username: ${config.mqtt.username}`);
this.client = mqtt.connect(config.mqtt.address, {
username: config.mqtt.username,
password: config.mqtt.password
});
const { client } = this;
client.on('connect', () => {
console.log('Connected to MQTT broker');
// Subscribe to status topics // Subscribe to status topics
config.mqtt.subscriptions.forEach(subscription => { config.states.elements.forEach(element => {
this.client.subscribe(subscription.topic); client.subscribe(state[element].topic, (err) => {
state[subscription.name].topic = subscription.topic; if (!err) {
console.log(`Subscribed to ${state[element].topic}`);
}
});
});
});
// Handle when the Broker sends us a message
client.on('message', (topic, message) => {
const msgStr = message.toString();
const msgJson = JSON.parse(msgStr);
console.log(`Message received on topic ${topic}: ${msgStr}`);
console.log(msgJson);
state[msgJson.name].on = msgJson.on;
window.refreshState(window.document, state);
}); });
} }
@ -32,9 +84,9 @@ export class Communicator {
// Publish with retain flag set to true // Publish with retain flag set to true
this.client.publish(topic, message, { retain: true }, (err) => { this.client.publish(topic, message, { retain: true }, (err) => {
if (err) { if (err) {
throw err; console.error('Failed to publish message:', err);
} else { } else {
// TODO: Pass back a success message console.log('Message published and retained on topic:', topic);
} }
}); });
} }

View File

@ -50,5 +50,15 @@
"bcm": 25, "bcm": 25,
"mode": "IN" "mode": "IN"
} }
] ],
"power": {
"start": {
"exhaustDelay": 30000,
"augerDelay": 60000,
"fireCheckDelay": 420000
},
"stop": {
"exhaustDelay": 600000
}
}
} }

View File

@ -2,6 +2,11 @@ const dotenv = require('dotenv').config();
const debug = process.env.DEBUG === "TRUE"; const debug = process.env.DEBUG === "TRUE";
const { pins } = require('./config.json'); const { pins } = require('./config.json');
const gpio = require('./VoidGPIO.js'); const gpio = require('./VoidGPIO.js');
const pinMap = new Map();
for (const pin of pins) {
pinMap.set(pin.key, pin);
}
module.exports = { module.exports = {
log(message) { log(message) {
@ -13,14 +18,32 @@ module.exports = {
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
}, },
gpio: { gpio: {
setDefaults() {
return new Promise((resolve, reject) => {
let stateChanges = [];
for (const pin of pins) {
if (pin.mode === 'OUT') {
gpio.setPin(pin.board, pin.defaultState, (err) => {
if (err) reject(err);
stateChanges.push( `Set ${pin.key} pin to ${pin.defaultState}.`);
})
}
}
resolve(stateChanges.join('\n'));
});
},
// Boot up sanity check during debug mode // Boot up sanity check during debug mode
async debugInit() { debugInit() {
module.exports.log('Resetting all output pins.'); module.exports.log('Resetting all output pins.');
pins.forEach(async (pin) => { module.exports.gpio.setDefaults().then(changes => {
module.exports.log(changes);
}).catch(e => console.error(e));
pins.forEach(pin => {
if (pin.mode === 'OUT') { if (pin.mode === 'OUT') {
gpio.setPin(pin.board, pin.defaultState, err => { gpio.setPin(pin.board, pin.defaultState, err => {
if (err) throw err; if (err) throw err;
module.exports.log(`Set ${pin.key} pin to ${pin.defaultState}.`); module.exports.log();
}); });
}; };
}); });
@ -48,5 +71,45 @@ module.exports = {
} }
}; };
} }
},
power: {
start: {
init() {
return new Promise((resolve, reject) => {
// Check pin states
// Set pins to default states
module.exports.gpio.setDefaults().then(changes => {
module.exports.log(changes);
}).catch(e => console.error(e));
// Power on igniter
gpio.setPin(pinMap.igniter.board, 1, (err) => {
if (err) reject(err);
})
// Wait for igniter preheat
// Start exhaust
// Finish igniter preheat
// Check for vacuum
// Start auger
// Wait for fire
// Check for fire
// Power off igniter
// Report successful ignition
});
}
},
stop: {
init() {
}
}
} }
} }