feat: off timeout setting respected, topics

This commit is contained in:
janishutz committed 2026-08-25 08:38:59 +02:00
1 parent 55d9aec4f2
commit 0b0efb1a0d
3 files changed
+27 -5

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@ mqtt:
# TODO: Consider adding an auto-off setting for out mode # TODO: Consider adding an auto-off setting for out mode
# Add default setting (also only for out) # Add default setting (also only for out)
topics: topics:
- topic: "" - topic: "" # The pin id is appended as /<id> to the topic.
pin: 0 pin: 0
mode: "in" mode: "in"
offTimeout: -1 # -1 disables automatic switch off of the pin offTimeout: -1 # -1 disables automatic switch off of the pin
+24 -3
View File
@@ -1,6 +1,6 @@
use gpio::{GpioIn}; use gpio::{GpioIn, GpioOut};
use rumqttc::Publish; use rumqttc::Publish;
use std::collections::HashMap; use std::{collections::HashMap, time::SystemTime};
use crate::conf::{PinMode, Topic}; use crate::conf::{PinMode, Topic};
@@ -78,6 +78,7 @@ pub fn read_pin(pin: &mut gpio::sysfs::SysFsGpioInput) -> u8 {
pub struct GPIOController { pub struct GPIOController {
out_pins: HashMap<String, OutputPin>, out_pins: HashMap<String, OutputPin>,
topics: Vec<String>, topics: Vec<String>,
timeout_topics: Vec<(String, SystemTime, u64)>,
} }
impl GPIOController { impl GPIOController {
@@ -89,6 +90,7 @@ impl GPIOController {
let mut controller = GPIOController { let mut controller = GPIOController {
out_pins: HashMap::new(), out_pins: HashMap::new(),
topics: Vec::new(), topics: Vec::new(),
timeout_topics: Vec::new(),
}; };
// Build hash maps // Build hash maps
@@ -101,6 +103,22 @@ impl GPIOController {
return controller; return controller;
} }
pub fn iter_handler(&mut self) {
for i in 0..self.timeout_topics.len() {
let topic = &self.timeout_topics[i];
if topic.1.elapsed().unwrap().as_millis() > (topic.2 as u128) {
let name = topic.0.clone();
self.timeout_topics.remove(i);
self.out_pins
.get_mut(&name)
.expect("Failed to retrieve pin")
.gpio
.set_low()
.unwrap_or_default();
}
}
}
pub fn handle_event(&mut self, instruction: &Publish) { pub fn handle_event(&mut self, instruction: &Publish) {
if self.topics.contains(&instruction.topic) { if self.topics.contains(&instruction.topic) {
let pin = self let pin = self
@@ -109,7 +127,10 @@ impl GPIOController {
.expect("Failed to load pins data"); .expect("Failed to load pins data");
println!("Hello World, pin {}", pin.id); println!("Hello World, pin {}", pin.id);
println!("Payload {}", instruction.payload.first().unwrap()); println!("Payload {}", instruction.payload.first().unwrap());
// TODO: Off timeout if pin.off_timeout > 0 {
self.timeout_topics
.push((pin.topic.clone(), SystemTime::now(), pin.off_timeout));
}
} }
} }
} }
+2 -1
View File
@@ -35,7 +35,7 @@ pub fn handler(config: Config) {
// TODO: handle fails // TODO: handle fails
client client
.publish( .publish(
&topic.topic, String::from(&topic.topic) + &format!("/{}", topic.id),
QoS::AtLeastOnce, QoS::AtLeastOnce,
false, false,
vec![read_pin(&mut topic.gpio)], vec![read_pin(&mut topic.gpio)],
@@ -49,6 +49,7 @@ pub fn handler(config: Config) {
// Main thread listens to topic updates // Main thread listens to topic updates
let mut controller = GPIOController::new(output_pins); let mut controller = GPIOController::new(output_pins);
for (_, notification) in connection.iter().enumerate() { for (_, notification) in connection.iter().enumerate() {
controller.iter_handler();
let msg = notification.unwrap(); let msg = notification.unwrap();
if let Event::Incoming(val) = msg { if let Event::Incoming(val) = msg {
if let Publish(content) = val { if let Publish(content) = val {