Merge branch 'v2-back' of https://git.vfsh.dev/voidf1sh/hestia into v2-back
This commit is contained in:
commit
ff9dfb1f43
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -11,7 +11,7 @@
|
|||||||
"skipFiles": [
|
"skipFiles": [
|
||||||
"<node_internals>/**"
|
"<node_internals>/**"
|
||||||
],
|
],
|
||||||
"program": "${workspaceFolder}/main.js"
|
"program": "${workspaceFolder}/src/main.js"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -5,14 +5,16 @@ module.exports = {
|
|||||||
// State class
|
// State class
|
||||||
State: class State {
|
State: class State {
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
|
this.publisher = 'backend';
|
||||||
|
|
||||||
this.igniter = {
|
this.igniter = {
|
||||||
on: false,
|
on: false,
|
||||||
name: "igniter",
|
name: "igniter",
|
||||||
topic: config.mqtt.topics.igniter,
|
topic: config.mqtt.topics.igniter,
|
||||||
publisher: 'front',
|
publisher: this.publisher,
|
||||||
power: (communicator) => {
|
power: (communicator, pinState) => {
|
||||||
// This *should* toggle the state, asks if state is true, if it is set it false, otherwise set it true
|
// Set the power based on the desired pinState
|
||||||
this.igniter.on ? this.igniter.on = false : this.igniter.on = true;
|
this.igniter.on = pinState === 1 ? true : false;
|
||||||
communicator.send(config.mqtt.topics.igniter, JSON.stringify(this.igniter));
|
communicator.send(config.mqtt.topics.igniter, JSON.stringify(this.igniter));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -21,10 +23,10 @@ module.exports = {
|
|||||||
on: false,
|
on: false,
|
||||||
name: "exhaust",
|
name: "exhaust",
|
||||||
topic: config.mqtt.topics.exhaust,
|
topic: config.mqtt.topics.exhaust,
|
||||||
publisher: 'front',
|
publisher: this.publisher,
|
||||||
power: (communicator) => {
|
power: (communicator, pinState) => {
|
||||||
// This *should* toggle the state, asks if state is true, if it is set it false, otherwise set it true
|
// Set the power based on the desired pinState
|
||||||
this.exhaust.on ? this.exhaust.on = false : this.exhaust.on = true;
|
this.exhaust.on = pinState === 1 ? true : false;
|
||||||
communicator.send(config.mqtt.topics.exhaust, JSON.stringify(this.exhaust));
|
communicator.send(config.mqtt.topics.exhaust, JSON.stringify(this.exhaust));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -34,13 +36,45 @@ module.exports = {
|
|||||||
name: "auger",
|
name: "auger",
|
||||||
feedRate: 500,
|
feedRate: 500,
|
||||||
topic: config.mqtt.topics.auger,
|
topic: config.mqtt.topics.auger,
|
||||||
publisher: 'front',
|
publisher: this.publisher,
|
||||||
power: (communicator) => {
|
power: (communicator, pinState) => {
|
||||||
// This *should* toggle the state, asks if state is true, if it is set it false, otherwise set it true
|
// Set the power based on the desired pinState
|
||||||
this.auger.on ? this.auger.on = false : this.auger.on = true;
|
this.auger.on = pinState === 1 ? true : false;
|
||||||
communicator.send(config.mqtt.topics.auger, JSON.stringify(this.auger));
|
communicator.send(config.mqtt.topics.auger, JSON.stringify(this.auger));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.pof = {
|
||||||
|
on: false,
|
||||||
|
name: "pof",
|
||||||
|
topic: config.mqtt.topics.pof,
|
||||||
|
publisher: this.publisher,
|
||||||
|
power: (communicator, pinState) => {
|
||||||
|
// Set the power based on the desired pinState
|
||||||
|
this.pof.on = pinState === 1 ? true : false;
|
||||||
|
communicator.send(config.mqtt.topics.pof, JSON.stringify(this.pof));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.vacuum = {
|
||||||
|
on: false,
|
||||||
|
name: "vacuum",
|
||||||
|
topic: config.mqtt.topics.vacuum,
|
||||||
|
publisher: this.publisher,
|
||||||
|
power: (communicator, pinState) => {
|
||||||
|
// Set the power based on the desired pinState
|
||||||
|
this.vacuum.on = pinState === 1 ? true : false;
|
||||||
|
communicator.send(config.mqtt.topics.vacuum, JSON.stringify(this.vacuum));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.startup = {
|
||||||
|
topic: config.mqtt.topics.startup
|
||||||
|
};
|
||||||
|
|
||||||
|
this.shutdown = {
|
||||||
|
topic: config.mqtt.topics.shutdown
|
||||||
|
};
|
||||||
console.log(`State initialized.`)
|
console.log(`State initialized.`)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -70,21 +104,43 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on('disconnect', () => {
|
||||||
|
console.log('Disconnected from MQTT broker');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle when the Broker sends us a message
|
// Handle when the Broker sends us a message
|
||||||
client.on('message', (topic, message) => {
|
client.on('message', (topic, message) => {
|
||||||
|
if (topic.startsWith('hestia/status')) {
|
||||||
|
// Save the existing state
|
||||||
|
const oldState = JSON.parse(JSON.stringify(state));
|
||||||
|
// The message is a buffer which will need to be converted to string
|
||||||
const msgStr = message.toString();
|
const msgStr = message.toString();
|
||||||
|
// Since the message is a JSON object, we can parse it
|
||||||
const msgJson = JSON.parse(msgStr);
|
const msgJson = JSON.parse(msgStr);
|
||||||
console.log(`Message received on topic ${topic}: ${msgStr}`);
|
// Log the message
|
||||||
console.log(msgJson);
|
// console.log(`Message received on topic ${topic}:`);
|
||||||
|
// console.log(msgJson);
|
||||||
|
// Check if the message is from the backend
|
||||||
|
if (msgJson.publisher === this.publisher) {
|
||||||
|
// console.log('Message is from the backend, ignoring');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// console.log('Message is from the frontend, updating state');
|
||||||
|
// Update the state
|
||||||
state[msgJson.name].on = msgJson.on;
|
state[msgJson.name].on = msgJson.on;
|
||||||
const change = {
|
// Emit the state change
|
||||||
name: msgJson.name,
|
this.emit('stateChange', oldState, state);
|
||||||
on: msgJson.on
|
} else if (topic === 'hestia/command/startup') {
|
||||||
};
|
// Empty block for 'hestia/command' topics
|
||||||
this.emit('stateChange', change);
|
this.emit('startup');
|
||||||
|
} else if (topic === 'hestia/command/shutdown') {
|
||||||
|
// Empty block for 'hestia/command' topics
|
||||||
|
this.emit('shutdown');
|
||||||
|
} else {
|
||||||
|
console.log(`Unknown topic: ${topic}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
|
const config = require('./config.json');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// Calls the GPIO Interface script to toggle a pin's state opposite of its current state
|
// Calls the GPIO Interface script to toggle a pin's state opposite of its current state
|
||||||
togglePin(pin) {
|
// togglePin(pin) {
|
||||||
return new Promise((resolve, reject) => {
|
// return new Promise((resolve, reject) => {
|
||||||
exec(`python3 src/python/gpio_interface.py toggle ${pin}`, (error, stdout, stderr) => {
|
// exec(`python3 ${config.gpioScript} toggle ${pin}`, (error, stdout, stderr) => {
|
||||||
if (error) reject(error);
|
// if (error) reject(error);
|
||||||
if (stderr) reject(new Error(stderr));
|
// if (stderr) reject(new Error(stderr));
|
||||||
resolve();
|
// resolve();
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
},
|
// },
|
||||||
// Calls the GPIO Interface script to read a pin's state
|
// Calls the GPIO Interface script to read a pin's state
|
||||||
readPin(pin) {
|
readPin(pin) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
exec(`python3 src/python/gpio_interface.py read ${pin}`, (error, stdout, stderr) => {
|
exec(`python3 ${config.gpioScript} read ${pin}`, (error, stdout, stderr) => {
|
||||||
if (error) reject(error);
|
if (error) reject(error);
|
||||||
if (stderr) reject(new Error(stderr));
|
if (stderr) reject(new Error(stderr));
|
||||||
resolve(stdout.trim());
|
resolve(stdout.trim());
|
||||||
@ -24,7 +25,7 @@ module.exports = {
|
|||||||
// Calls the GPIO Interface script to set a pin's state regardless of its current state
|
// Calls the GPIO Interface script to set a pin's state regardless of its current state
|
||||||
setPin(pin, state) {
|
setPin(pin, state) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
exec(`python3 src/python/gpio_interface.py set ${pin} ${state}`, (error, stdout, stderr) => {
|
exec(`python3 ${config.gpioScript} set ${pin} ${state}`, (error, stdout, stderr) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,22 @@
|
|||||||
"topics": {
|
"topics": {
|
||||||
"igniter": "hestia/status/igniter",
|
"igniter": "hestia/status/igniter",
|
||||||
"exhaust": "hestia/status/exhaust",
|
"exhaust": "hestia/status/exhaust",
|
||||||
"auger": "hestia/status/auger"
|
"auger": "hestia/status/auger",
|
||||||
|
"pof": "hestia/status/pof",
|
||||||
|
"vacuum": "hestia/status/vacuum",
|
||||||
|
"startup": "hestia/command/startup",
|
||||||
|
"shutdown": "hestia/command/shutdown"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"states": {
|
"states": {
|
||||||
"elements": [
|
"elements": [
|
||||||
"igniter",
|
"igniter",
|
||||||
"exhaust",
|
"exhaust",
|
||||||
"auger"
|
"auger",
|
||||||
|
"pof",
|
||||||
|
"vacuum",
|
||||||
|
"startup",
|
||||||
|
"shutdown"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"pins": [
|
"pins": [
|
||||||
@ -60,5 +68,6 @@
|
|||||||
"stop": {
|
"stop": {
|
||||||
"exhaustDelay": 600000
|
"exhaustDelay": 600000
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"gpioScript": "src/python/gpio_interface.py"
|
||||||
}
|
}
|
@ -3,10 +3,10 @@ const debug = process.env.DEBUG === "TRUE";
|
|||||||
const config = require('./config.json');
|
const config = require('./config.json');
|
||||||
const { pins } = config;
|
const { pins } = config;
|
||||||
const gpio = require('./VoidGPIO.js');
|
const gpio = require('./VoidGPIO.js');
|
||||||
const pinMap = new Map();
|
process.pinMap = new Map();
|
||||||
|
|
||||||
for (const pin of pins) {
|
for (const pin of pins) {
|
||||||
pinMap.set(pin.key, pin);
|
process.pinMap.set(pin.key, pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@ -19,7 +19,7 @@ module.exports = {
|
|||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
},
|
},
|
||||||
gpio: {
|
gpio: {
|
||||||
setDefaults() {
|
setDefaults(communicator, state) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let stateChanges = [];
|
let stateChanges = [];
|
||||||
|
|
||||||
@ -27,6 +27,14 @@ module.exports = {
|
|||||||
if (pin.mode === 'OUT') {
|
if (pin.mode === 'OUT') {
|
||||||
return gpio.setPin(pin.board, pin.defaultState).then(() => {
|
return gpio.setPin(pin.board, pin.defaultState).then(() => {
|
||||||
stateChanges.push(`Set ${pin.key} pin to ${pin.defaultState}.`);
|
stateChanges.push(`Set ${pin.key} pin to ${pin.defaultState}.`);
|
||||||
|
state[pin.key].power(communicator, pin.defaultState);
|
||||||
|
}).catch(e => console.error(e));
|
||||||
|
} else if (pin.mode === 'IN') {
|
||||||
|
return gpio.readPin(pin.board).then(pinState => {
|
||||||
|
const boolState = pinState === '1' ? true : false;
|
||||||
|
state[pin.key].on = boolState;
|
||||||
|
communicator.send(config.mqtt.topics[pin.key], JSON.stringify(state[pin.key]));
|
||||||
|
stateChanges.push(`${pin.key}: ${state}`);
|
||||||
}).catch(e => console.error(e));
|
}).catch(e => console.error(e));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -37,33 +45,11 @@ module.exports = {
|
|||||||
}).catch(reject);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// Boot up sanity check during debug mode
|
async init(communicator, state) {
|
||||||
async debugInit() {
|
|
||||||
module.exports.log('Resetting all output pins.');
|
module.exports.log('Resetting all output pins.');
|
||||||
module.exports.gpio.setDefaults().then((changes) => {
|
module.exports.gpio.setDefaults(communicator, state).then((changes) => {
|
||||||
module.exports.log(changes);
|
module.exports.log(changes);
|
||||||
}).catch(e => console.error(e));
|
}).catch(e => console.error(e));
|
||||||
|
|
||||||
for (const pin of pins) {
|
|
||||||
switch (pin.mode) {
|
|
||||||
case 'OUT':
|
|
||||||
gpio.togglePin(pin.board).then(() => {
|
|
||||||
module.exports.log(`Toggled ${pin.key}`);
|
|
||||||
}).catch(e => console.error(e));
|
|
||||||
// Wait 1000ms before toggling again.
|
|
||||||
await module.exports.sleep(1000);
|
|
||||||
gpio.togglePin(pin.board).then(() => {
|
|
||||||
module.exports.log(`Toggled ${pin.key}`);
|
|
||||||
}).catch(e => console.error(e));
|
|
||||||
break;
|
|
||||||
case 'IN':
|
|
||||||
gpio.readPin(pin.board).then(state => {
|
|
||||||
module.exports.log(`${pin.key} state: ${state}`);
|
|
||||||
}).catch(e => console.error(e));
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
power: {
|
power: {
|
||||||
@ -78,45 +64,45 @@ module.exports = {
|
|||||||
}).catch(e => console.error(e));
|
}).catch(e => console.error(e));
|
||||||
|
|
||||||
// Power on igniter
|
// Power on igniter
|
||||||
gpio.setPin(pinMap.igniter.board, 1).then(async () => {
|
gpio.setPin(process.pinMap.igniter.board, 1).then(async () => {
|
||||||
// Wait for igniter preheat
|
// Wait for igniter preheat
|
||||||
await module.exports.sleep(config.power.start.exhaustDelay);
|
await module.exports.sleep(config.power.start.exhaustDelay);
|
||||||
}).catch(e => console.error(e));
|
}).catch(e => console.error(e));
|
||||||
|
|
||||||
// Start exhaust
|
// Start exhaust
|
||||||
gpio.setPin(pinMap.exhaust.board, 1).then(async () => {
|
gpio.setPin(process.pinMap.exhaust.board, 1).then(async () => {
|
||||||
// Finish igniter preheat
|
// Finish igniter preheat
|
||||||
await module.exports.sleep(config.power.start.augerDelay);
|
await module.exports.sleep(config.power.start.augerDelay);
|
||||||
}).catch(e => console.error(e));
|
}).catch(e => console.error(e));
|
||||||
|
|
||||||
// Check for vacuum
|
// Check for vacuum
|
||||||
gpio.readPin(pinMap.vacuum.board).then(state => {
|
gpio.readPin(process.pinMap.vacuum.board).then(state => {
|
||||||
if (state === '0') {
|
if (state === '0') {
|
||||||
// Power off exhaust
|
// Power off exhaust
|
||||||
gpio.setPin(pinMap.exhaust.board, 0).then(() => {
|
gpio.setPin(process.pinMap.exhaust.board, 0).then(() => {
|
||||||
// Report vacuum failure
|
// Report vacuum failure
|
||||||
reject(new Error('Vacuum failure.'));
|
reject(new Error('Vacuum failure.'));
|
||||||
return;
|
return;
|
||||||
}).catch(e => console.error(e));
|
}).catch(e => console.error(e));
|
||||||
} else {
|
} else {
|
||||||
// Start auger
|
// Start auger
|
||||||
gpio.setPin(pinMap.auger.board, 1).then(async () => {
|
gpio.setPin(process.pinMap.auger.board, 1).then(async () => {
|
||||||
// Wait for fire
|
// Wait for fire
|
||||||
await module.exports.sleep(config.power.start.fireCheckDelay);
|
await module.exports.sleep(config.power.start.fireCheckDelay);
|
||||||
|
|
||||||
// Power off igniter
|
// Power off igniter
|
||||||
gpio.setPin(pinMap.igniter.board, 0).then(() => {
|
gpio.setPin(process.pinMap.igniter.board, 0).then(() => {
|
||||||
// Check for fire on pof
|
// Check for fire on pof
|
||||||
gpio.readPin(pinMap.pof.board).then(state => {
|
gpio.readPin(process.pinMap.pof.board).then(state => {
|
||||||
if (state === '0') {
|
if (state === '0') {
|
||||||
// Power off auger
|
// Power off auger
|
||||||
gpio.setPin(pinMap.auger.board, 0).then(() => {
|
gpio.setPin(process.pinMap.auger.board, 0).then(() => {
|
||||||
// Report failed ignition
|
// Report failed ignition
|
||||||
reject(new Error('Failed ignition.'));
|
reject(new Error('Failed ignition.'));
|
||||||
}).catch(e => console.error(e));
|
}).catch(e => console.error(e));
|
||||||
} else {
|
} else {
|
||||||
// Power off auger
|
// Power off auger
|
||||||
gpio.setPin(pinMap.auger.board, 0).then(() => {
|
gpio.setPin(process.pinMap.auger.board, 0).then(() => {
|
||||||
// Report successful ignition
|
// Report successful ignition
|
||||||
resolve('Successful ignition.');
|
resolve('Successful ignition.');
|
||||||
}).catch(e => console.error(e));
|
}).catch(e => console.error(e));
|
||||||
@ -133,11 +119,11 @@ module.exports = {
|
|||||||
init() {
|
init() {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
// Power off auger
|
// Power off auger
|
||||||
gpio.setPin(pinMap.auger.board, 0).then(async () => {
|
gpio.setPin(process.pinMap.auger.board, 0).then(async () => {
|
||||||
// Wait for exhaust shutdown delay
|
// Wait for exhaust shutdown delay
|
||||||
await module.exports.sleep(config.power.stop.exhaustDelay);
|
await module.exports.sleep(config.power.stop.exhaustDelay);
|
||||||
// Power off exhaust
|
// Power off exhaust
|
||||||
gpio.setPin(pinMap.exhaust.board, 0).then(() => {
|
gpio.setPin(process.pinMap.exhaust.board, 0).then(() => {
|
||||||
// Report successful shutdown
|
// Report successful shutdown
|
||||||
resolve('Successful shutdown.');
|
resolve('Successful shutdown.');
|
||||||
}).catch(e => console.error(e));
|
}).catch(e => console.error(e));
|
||||||
@ -147,9 +133,23 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
handlers: {
|
handlers: {
|
||||||
stateChange(change) {
|
stateChange(oldState, state) {
|
||||||
gpio.togglePin(pinMap.get(change.name).board).then(() => {
|
const promises = pins.map(pin => {
|
||||||
console.log(`${change.name} toggled.`);
|
if (oldState[pin.key].on !== state[pin.key].on) {
|
||||||
|
if (state[pin.key].on) {
|
||||||
|
return gpio.setPin(pin.board, 1).then(() => {
|
||||||
|
console.log(`${pin.key} powered on.`);
|
||||||
|
}).catch(e => console.error(e));
|
||||||
|
} else {
|
||||||
|
return gpio.setPin(pin.board, 0).then(() => {
|
||||||
|
console.log(`${pin.key} powered off.`);
|
||||||
|
}).catch(e => console.error(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Promise.all(promises).then(() => {
|
||||||
|
console.log('State change complete.');
|
||||||
}).catch(e => console.error(e));
|
}).catch(e => console.error(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
src/main.js
23
src/main.js
@ -9,20 +9,35 @@ const comms = new Communicator(psState);
|
|||||||
|
|
||||||
comms.init(psState, config);
|
comms.init(psState, config);
|
||||||
|
|
||||||
fn.gpio.debugInit();
|
fn.gpio.init(comms, psState);
|
||||||
|
|
||||||
// Sensor detection loop
|
// Sensor detection loop
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
for (const pin of config.pins) {
|
for (const pin of config.pins) {
|
||||||
if (pin.mode === 'IN') {
|
if (pin.mode === 'IN') {
|
||||||
gpio.readPin(pin.board).then(state => {
|
gpio.readPin(pin.board).then(state => {
|
||||||
|
const boolState = state === '1' ? true : false;
|
||||||
|
if (boolState !== psState[pin.key].on) {
|
||||||
|
psState[pin.key].on = boolState;
|
||||||
|
comms.send(config.mqtt.topics[pin.key], JSON.stringify(psState[pin.key]));
|
||||||
fn.log(`${pin.key}: ${state}`);
|
fn.log(`${pin.key}: ${state}`);
|
||||||
|
}
|
||||||
}).catch(e => console.error(e));
|
}).catch(e => console.error(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
comms.on('stateChange', (change) => {
|
comms.on('stateChange', (oldState, state) => {
|
||||||
console.log(`State change detected: ${change.name}`);
|
console.log(`State change detected.`);
|
||||||
fn.handlers.stateChange(change);
|
fn.handlers.stateChange(oldState, state);
|
||||||
|
});
|
||||||
|
|
||||||
|
comms.on('startup', () => {
|
||||||
|
console.log(`Startup detected.`);
|
||||||
|
fn.power.start.init().catch(e => console.error(e));
|
||||||
|
});
|
||||||
|
|
||||||
|
comms.on('shutdown', () => {
|
||||||
|
console.log(`Shutdown detected.`);
|
||||||
|
fn.power.stop.init().catch(e => console.error(e));
|
||||||
});
|
});
|
75
src/python/fake_gpio_interface.py
Normal file
75
src/python/fake_gpio_interface.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
|
# Define the state of the pins
|
||||||
|
PIN_STATES = {
|
||||||
|
7: 0,
|
||||||
|
13: 0,
|
||||||
|
15: 0,
|
||||||
|
16: 0,
|
||||||
|
22: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define a function to get the pin state from the array
|
||||||
|
def get_pin_state(pin):
|
||||||
|
if pin in PIN_STATES:
|
||||||
|
return PIN_STATES[pin]
|
||||||
|
else:
|
||||||
|
print(f"Invalid pin: {pin}")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Modify the read_pin function to use the get_pin_state function
|
||||||
|
def read_pin(pin):
|
||||||
|
try:
|
||||||
|
# Read pin state
|
||||||
|
state = get_pin_state(pin)
|
||||||
|
# Return 1 if pin is HIGH, 0 if LOW
|
||||||
|
return 1 if state == 1 else 0
|
||||||
|
except Exception as e:
|
||||||
|
# Handle errors
|
||||||
|
print(f"Error reading pin {pin}: {e}")
|
||||||
|
# Return -1 on error
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Modify the set_pin_state function to return success always
|
||||||
|
def set_pin_state(pin, state):
|
||||||
|
try:
|
||||||
|
# Set the pin state to either HIGH (1) or LOW (0)
|
||||||
|
# Exit with 0 for success
|
||||||
|
return 0
|
||||||
|
except Exception as e:
|
||||||
|
# Handle errors
|
||||||
|
print(f"Error setting pin {pin} to state {state}: {e}")
|
||||||
|
# Exit with 1 for failure
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print("Usage: python3 gpio_interface.py <command> <pin> [<state>]")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
command = sys.argv[1].lower()
|
||||||
|
pin = int(sys.argv[2])
|
||||||
|
|
||||||
|
if command == "toggle":
|
||||||
|
result = toggle_pin(pin)
|
||||||
|
sys.exit(result)
|
||||||
|
elif command == "read":
|
||||||
|
result = read_pin(pin)
|
||||||
|
print(result)
|
||||||
|
sys.exit(0 if result >= 0 else 1)
|
||||||
|
elif command == "set":
|
||||||
|
if len(sys.argv) < 4:
|
||||||
|
print("Usage: python3 gpio_interface.py set <pin> <state>")
|
||||||
|
sys.exit(1)
|
||||||
|
state = int(sys.argv[3])
|
||||||
|
if state not in [0, 1]:
|
||||||
|
print("Invalid state. Use 0 for LOW or 1 for HIGH.")
|
||||||
|
sys.exit(1)
|
||||||
|
result = set_pin_state(pin, state)
|
||||||
|
sys.exit(result)
|
||||||
|
else:
|
||||||
|
print("Invalid command. Use 'toggle', 'read', or 'set'.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user