diff --git a/src/custom_modules/HestiaClasses.js b/src/custom_modules/HestiaClasses.js index cac9dd3..f78da31 100644 --- a/src/custom_modules/HestiaClasses.js +++ b/src/custom_modules/HestiaClasses.js @@ -3,8 +3,9 @@ const mqtt = require('mqtt'); module.exports = { // State class - State: class State { + State: class State extends EventEmitter { constructor(config) { + super(); this.publisher = 'backend'; this.igniter = { @@ -75,7 +76,7 @@ module.exports = { this.shutdown = { topic: config.mqtt.topics.shutdown }; - console.log(`State initialized.`) + this.emit('announcement', `State initialized.`) return this; }; }, @@ -84,30 +85,31 @@ module.exports = { constructor(state) { super(); this.publisher = state.publisher; + return this; } init(state, config) { // Connect to the MQTT Broker - console.log(`Attempting MQTT connection to broker: ${config.mqtt.address}`); + this.emit('announcement', `Attempting MQTT connection to broker: ${config.mqtt.address}`); this.client = mqtt.connect(config.mqtt.address, { port: config.mqtt.port, }); const { client } = this; client.on('connect', () => { - console.log('Connected to MQTT broker'); + this.emit('announcement', 'Connected to MQTT broker'); // Subscribe to status topics config.states.elements.forEach(element => { client.subscribe(state[element].topic, (err) => { if (!err) { - console.log(`Subscribed to ${state[element].topic}`); + this.emit('announcement', `Subscribed to ${state[element].topic}`); } }); }); }); client.on('disconnect', () => { - console.log('Disconnected from MQTT broker'); + this.emit('announcement', 'Disconnected from MQTT broker'); }); // Handle when the Broker sends us a message @@ -120,14 +122,14 @@ module.exports = { // Since the message is a JSON object, we can parse it const msgJson = JSON.parse(msgStr); // Log the message - // console.log(`Message received on topic ${topic}:`); - // console.log(msgJson); + // this.emit('announcement', `Message received on topic ${topic}:`); + // this.emit('announcement', msgJson); // Check if the message is from the backend if (msgJson.publisher === this.publisher) { - // console.log('Message is from the backend, ignoring'); + // this.emit('announcement', 'Message is from the backend, ignoring'); return; } - // console.log('Message is from the frontend, updating state'); + // this.emit('announcement', 'Message is from the frontend, updating state'); // Update the state state[msgJson.name].on = msgJson.on; // Emit the state change @@ -139,7 +141,7 @@ module.exports = { // Empty block for 'hestia/command' topics this.emit('shutdown'); } else { - console.log(`Unknown topic: ${topic}`); + this.emit('announcement', `Unknown topic: ${topic}`); } }); } @@ -151,7 +153,7 @@ module.exports = { if (err) { console.error('Failed to publish message:', err); } else { - console.log('Message published and retained on topic:', topic); + this.emit('announcement', 'Message published and retained on topic:', topic); } }); } diff --git a/src/custom_modules/functions.js b/src/custom_modules/functions.js index 4799178..640299c 100644 --- a/src/custom_modules/functions.js +++ b/src/custom_modules/functions.js @@ -21,6 +21,9 @@ module.exports = { console.log(`DEBUG: ${message}`); } break; + case 'ERROR': + console.error(`ERROR: ${message}`); + break; default: break; } diff --git a/src/main.js b/src/main.js index c8f656e..ae3cf37 100644 --- a/src/main.js +++ b/src/main.js @@ -1,37 +1,41 @@ -// Variables -process.debug = true; - +/***************************************************************************************/ // Import modules +/***************************************************************************************/ const gpio = require('./custom_modules/VoidGPIO.js'); const config = require('./custom_modules/config.json'); const fn = require('./custom_modules/functions.js'); const { State, Communicator } = require('./custom_modules/HestiaClasses.js'); +/***************************************************************************************/ // Variables +/***************************************************************************************/ +process.debug = true; process.pinMap = new Map(); - for (const pin of config.pins) { process.pinMap.set(pin.key, pin); } -// Initialize state and comlink +/***************************************************************************************/ +// Initialization +/***************************************************************************************/ process.psState = new State(config); -const comms = new Communicator(process.psState); -comms.init(process.psState, config); +process.comlink = new Communicator(process.psState); +process.comlink.init(process.psState, config); +fn.gpio.init(process.comlink, process.psState); -// Initialize GPIO -fn.gpio.init(comms, process.psState); - -// Sensor detection loop +/***************************************************************************************/ +// Loops +/***************************************************************************************/ +// Sensor Detection setInterval(() => { // Iterate through pins for (const pin of config.pins) { // If pin is an input, read it if (pin.mode === 'IN') { - fn.log(`I: Sensor Detection Loop: Reading pin ${pin.board}`); + fn.log(`Sensor Detection Loop: Reading pin ${pin.board}`, 'DEBUG'); // Read pin gpio.readPin(pin.board).then(state => { - fn.log(`I: Sensor Detection Loop: Pin ${pin.board} is ${state}`); + fn.log(`Sensor Detection Loop: Pin ${pin.board} is ${state}`, 'DEBUG'); // Convert the state from string to boolean const boolState = state === '1' ? true : false; // Compare the state to the last known state @@ -39,28 +43,39 @@ setInterval(() => { // Update the state process.psState[pin.key].on = boolState; // Send the state to the MQTT broker - comms.send(config.mqtt.topics[pin.key], JSON.stringify(process.psState[pin.key])); - fn.log(`I: Sensor Detection Loop: ${pin.key}: ${state}`); + process.comlink.send(config.mqtt.topics[pin.key], JSON.stringify(process.psState[pin.key])); + fn.log(`Sensor Detection Loop: ${pin.key}: ${state}`, 'DEBUG'); } - }).catch(e => console.error(`E: Sensor Detection Loop: ${e}`)); + }).catch(e => fn.log(`Sensor Detection Loop: ${e}`, 'ERROR')); } } }, 1000); -// Auger feed loop +// Auger Feed setInterval(fn.routines.cycleAuger, config.augerTotalCycleTime); -comms.on('stateChange', (oldState, state) => { - fn.log(`Event: State change detected.`); +/***************************************************************************************/ +// Event listeners +/***************************************************************************************/ +process.comlink.on('stateChange', (oldState, state) => { + fn.log(`ComLink: State change detected.`, 'INFO'); fn.handlers.stateChange(oldState, state); }); -comms.on('startup', () => { - fn.log(`I: Event: Startup detected.`); - fn.power.start.init(comms, process.psState).catch(e => console.error(`E: Power Start Init: ${e}`)); +process.comlink.on('startup', () => { + fn.log(`ComLink: Startup detected.`, 'INFO'); + fn.power.start.init(process.comlink, process.psState).catch(e => console.error(`E: Power Start Init: ${e}`)); }); -comms.on('shutdown', () => { - fn.log(`I: Event: Shutdown detected.`); - fn.power.stop.init(comms, process.psState).catch(e => console.error(`E: Power Stop Init: ${e}`)); +process.comlink.on('shutdown', () => { + fn.log(`ComLink: Shutdown detected.`, 'INFO'); + fn.power.stop.init(process.comlink, process.psState).catch(e => console.error(`E: Power Stop Init: ${e}`)); +}); + +process.comlink.on('announcement', msg => { + fn.log(`ComLink: ${msg}`, 'INFO'); +}); + +process.psState.on('announcement', msg => { + fn.log(`State: ${msg}`, 'INFO'); }); \ No newline at end of file