mirror of
https://github.com/janishutz/mqtt-remote-gpio.git
synced 2026-10-09 05:06:21 +02:00
feat: working mqtt integration, basic GPIO initialization
This commit is contained in:
1 parent
f044a5b5bd
commit
cf50df31c5
5 files changed
+115
-33
No files matched your search
+81
-18
@@ -1,52 +1,115 @@
|
||||
use gpio::{GpioIn, GpioOut};
|
||||
use rumqttc::Publish;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::conf::{PinMode, Topic};
|
||||
|
||||
pub struct InputPin {
|
||||
pub gpio: gpio::sysfs::SysFsGpioInput,
|
||||
pub id: u16,
|
||||
pub topic: String,
|
||||
}
|
||||
|
||||
pub struct OutputPin {
|
||||
gpio: gpio::sysfs::SysFsGpioOutput,
|
||||
off_timeout: u64,
|
||||
pub id: u16,
|
||||
pub topic: String,
|
||||
}
|
||||
|
||||
/// Split topics into in and out pins. Returns them in this order
|
||||
///
|
||||
/// * `topics`: The topics to use
|
||||
pub fn split_topics_and_configure_pins(topics: Vec<Topic>) -> (Vec<Topic>, Vec<Topic>) {
|
||||
let mut in_pins: Vec<Topic> = Vec::new();
|
||||
let mut out_pins: Vec<Topic> = Vec::new();
|
||||
pub fn split_topics_and_configure_pins(topics: Vec<Topic>) -> (Vec<InputPin>, Vec<OutputPin>) {
|
||||
let mut in_pins: Vec<InputPin> = Vec::new();
|
||||
let mut out_pins: Vec<OutputPin> = Vec::new();
|
||||
let mut in_used: Vec<u16> = Vec::new();
|
||||
let mut out_used: Vec<u16> = Vec::new();
|
||||
for topic in topics {
|
||||
if topic.mode == PinMode::IN {
|
||||
in_pins.push(topic);
|
||||
if in_used.contains(&topic.pin) {
|
||||
println!(
|
||||
"Warning: Pin {} used more than once, all further uses dropped",
|
||||
topic.pin
|
||||
);
|
||||
continue;
|
||||
} else if out_used.contains(&topic.pin) {
|
||||
panic!("Pin {} used for both input and output!", topic.pin)
|
||||
}
|
||||
in_pins.push(InputPin {
|
||||
topic: topic.topic,
|
||||
gpio: gpio::sysfs::SysFsGpioInput::open(topic.pin)
|
||||
.expect(&format!("Unable to find GPIO pin {}", topic.pin)),
|
||||
id: topic.pin,
|
||||
});
|
||||
in_used.push(topic.pin)
|
||||
} else {
|
||||
out_pins.push(topic);
|
||||
if out_used.contains(&topic.pin) {
|
||||
println!(
|
||||
"Warning: Pin {} used more than once, all further uses dropped",
|
||||
topic.pin
|
||||
);
|
||||
continue;
|
||||
} else if in_used.contains(&topic.pin) {
|
||||
panic!("Pin {} used for both input and output!", topic.pin)
|
||||
}
|
||||
out_pins.push(OutputPin {
|
||||
topic: topic.topic,
|
||||
gpio: gpio::sysfs::SysFsGpioOutput::open(topic.pin)
|
||||
.expect(&format!("Unable to find GPIO pin {}", topic.pin)),
|
||||
id: topic.pin,
|
||||
off_timeout: topic.off_timeout,
|
||||
});
|
||||
out_used.push(topic.pin)
|
||||
}
|
||||
}
|
||||
|
||||
return (in_pins, out_pins);
|
||||
}
|
||||
|
||||
pub fn read_pin_value(id: u16) {}
|
||||
pub fn read_pin(pin: &mut gpio::sysfs::SysFsGpioInput) -> u8 {
|
||||
if let gpio::GpioValue::Low = pin.read_value().expect("Failed reading value") {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GPIOController {
|
||||
in_pins: HashMap<String, Topic>,
|
||||
out_pins: HashMap<String, OutputPin>,
|
||||
topics: Vec<String>,
|
||||
}
|
||||
|
||||
impl GPIOController {
|
||||
/// Create a new GPIO controller.
|
||||
/// Note that the move of ownership is intentional behaviour. Only create one instance of this controller!
|
||||
///
|
||||
/// * `topics`: The topics that are going to be managed by this controller (All OUT mode pins
|
||||
/// are dropped without error)
|
||||
pub fn new(topics: Vec<Topic>) -> Self {
|
||||
/// * `pins`: The pins that are going to be managed by this controller
|
||||
pub fn new(pins: Vec<OutputPin>) -> Self {
|
||||
let mut controller = GPIOController {
|
||||
in_pins: HashMap::new(),
|
||||
out_pins: HashMap::new(),
|
||||
topics: Vec::new(),
|
||||
};
|
||||
|
||||
// Build hash maps
|
||||
for topic in topics {
|
||||
if topic.mode == PinMode::IN {
|
||||
controller
|
||||
.in_pins
|
||||
.insert(String::from(topic.topic.as_str()), topic);
|
||||
}
|
||||
for pin in pins {
|
||||
let topic = pin.topic.clone();
|
||||
controller.out_pins.insert(pin.topic.clone(), pin);
|
||||
controller.topics.push(topic);
|
||||
}
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
pub fn handle_event(&self) {}
|
||||
pub fn handle_event(&mut self, instruction: &Publish) {
|
||||
if self.topics.contains(&instruction.topic) {
|
||||
let pin = self
|
||||
.out_pins
|
||||
.get(&instruction.topic)
|
||||
.expect("Failed to load pins data");
|
||||
println!("Hello World, pin {}", pin.id);
|
||||
println!("Payload {}", instruction.payload.first().unwrap());
|
||||
// TODO: Off timeout
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user