Moved some stuff from main into the libary

This commit is contained in:
Dreaded_X 2022-12-28 04:17:23 +01:00
parent 2b4ddf82b6
commit 3b6a5e4c07
Signed by: Dreaded_X
GPG Key ID: 76BDEC4E165D8AD9
3 changed files with 59 additions and 47 deletions

View File

@ -1,8 +1,11 @@
use std::{fs, error::Error, collections::HashMap}; use std::{fs, error::Error, collections::HashMap};
use log::debug; use log::{debug, trace};
use rumqttc::AsyncClient;
use serde::Deserialize; use serde::Deserialize;
use crate::devices::{DeviceBox, IkeaOutlet, WakeOnLAN};
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Config { pub struct Config {
pub mqtt: MQTTConfig, pub mqtt: MQTTConfig,
@ -67,3 +70,18 @@ impl Config {
Ok(config) Ok(config)
} }
} }
impl Device {
pub fn into(self, identifier: String, client: AsyncClient) -> DeviceBox {
match self {
Device::IkeaOutlet { info, mqtt, kettle } => {
trace!("\tIkeaOutlet [{} in {:?}]", info.name, info.room);
Box::new(IkeaOutlet::new(identifier, info, mqtt, kettle, client))
},
Device::WakeOnLAN { info, mqtt, mac_address } => {
trace!("\tWakeOnLan [{} in {:?}]", info.name, info.room);
Box::new(WakeOnLAN::new(identifier, info, mqtt, mac_address, client))
},
}
}
}

View File

@ -1,13 +1,13 @@
use std::{time::Duration, sync::{Arc, RwLock}, process, net::SocketAddr}; use std::{time::Duration, sync::{Arc, RwLock}, process, net::SocketAddr};
use automation::config::{Config, Device}; use automation::config::Config;
use dotenv::dotenv; use dotenv::dotenv;
use warp::Filter; use warp::Filter;
use rumqttc::{MqttOptions, Transport, AsyncClient}; use rumqttc::{MqttOptions, Transport, AsyncClient};
use env_logger::Builder; use env_logger::Builder;
use log::{error, info, debug, trace, LevelFilter}; use log::{error, info, debug, LevelFilter};
use automation::{devices::{Devices, IkeaOutlet, WakeOnLAN}, mqtt::Notifier}; use automation::{devices::Devices, mqtt::Notifier};
use google_home::{GoogleHome, Request}; use google_home::{GoogleHome, Request};
#[tokio::main] #[tokio::main]
@ -26,8 +26,6 @@ async fn main() {
process::exit(1); process::exit(1);
}); });
debug!("Config: {config:#?}");
info!("Starting automation_rs..."); info!("Starting automation_rs...");
// Create device holder // Create device holder
@ -40,35 +38,23 @@ async fn main() {
mqttoptions.set_keep_alive(Duration::from_secs(5)); mqttoptions.set_keep_alive(Duration::from_secs(5));
mqttoptions.set_transport(Transport::tls_with_default_config()); mqttoptions.set_transport(Transport::tls_with_default_config());
// Create a notifier and move it to a new thread // Create a notifier and start it in a seperate task
// @TODO Maybe rename this to make it clear it has to do with mqtt
let mut notifier = Notifier::new();
let (client, eventloop) = AsyncClient::new(mqttoptions, 10); let (client, eventloop) = AsyncClient::new(mqttoptions, 10);
let mut notifier = Notifier::new(eventloop);
notifier.add_listener(Arc::downgrade(&devices)); notifier.add_listener(Arc::downgrade(&devices));
tokio::spawn(async move { notifier.start();
info!("Connecting to MQTT broker");
notifier.start(eventloop).await;
todo!("Error in MQTT (most likely lost connection to mqtt server), we need to handle these errors!");
});
// Create devices based on config // Create devices based on config
// @TODO Move out of main (config? or maybe devices?) // @TODO Move out of main (config? or maybe devices?)
for (identifier, device_config) in config.devices { config.devices
debug!("Adding device {identifier}"); .into_iter()
.map(|(identifier, device_config)| {
let device: automation::devices::DeviceBox = match device_config { device_config.into(identifier, client.clone())
Device::IkeaOutlet { info, mqtt, kettle } => { })
trace!("\tIkeaOutlet [{} in {:?}]", info.name, info.room); .for_each(|device| {
Box::new(IkeaOutlet::new(identifier, info, mqtt, kettle, client.clone())) debug!("Adding device {}", device.get_id());
},
Device::WakeOnLAN { info, mqtt, mac_address } => {
trace!("\tWakeOnLan [{} in {:?}]", info.name, info.room);
Box::new(WakeOnLAN::new(identifier, info, mqtt, mac_address, client.clone()))
},
};
devices.write().unwrap().add_device(device); devices.write().unwrap().add_device(device);
} });
// Google Home fullfillments // Google Home fullfillments
let fullfillment_google_home = warp::path("google_home") let fullfillment_google_home = warp::path("google_home")

View File

@ -1,20 +1,23 @@
use std::sync::{Weak, RwLock}; use std::sync::{Weak, RwLock};
use log::error; use log::{error, debug};
use rumqttc::{Publish, Event, Incoming, EventLoop}; use rumqttc::{Publish, Event, Incoming, EventLoop};
use log::trace; use log::trace;
use tokio::task::JoinHandle;
pub trait Listener { pub trait Listener {
fn notify(&mut self, message: &Publish); fn notify(&mut self, message: &Publish);
} }
// @TODO Maybe rename this to make it clear it has to do with mqtt
pub struct Notifier { pub struct Notifier {
listeners: Vec<Weak<RwLock<dyn Listener + Sync + Send>>>, listeners: Vec<Weak<RwLock<dyn Listener + Sync + Send>>>,
eventloop: EventLoop,
} }
impl Notifier { impl Notifier {
pub fn new() -> Self { pub fn new(eventloop: EventLoop) -> Self {
return Self { listeners: Vec::new() } return Self { listeners: Vec::new(), eventloop }
} }
fn notify(&mut self, message: Publish) { fn notify(&mut self, message: Publish) {
@ -32,9 +35,11 @@ impl Notifier {
self.listeners.push(listener); self.listeners.push(listener);
} }
pub async fn start(&mut self, mut eventloop: EventLoop) { pub fn start(mut self) -> JoinHandle<()> {
tokio::spawn(async move {
debug!("Listening for MQTT events");
loop { loop {
let notification = eventloop.poll().await; let notification = self.eventloop.poll().await;
match notification { match notification {
Ok(Event::Incoming(Incoming::Publish(p))) => { Ok(Event::Incoming(Incoming::Publish(p))) => {
trace!("{:?}", p); trace!("{:?}", p);
@ -47,5 +52,8 @@ impl Notifier {
}, },
} }
} }
todo!("Error in MQTT (most likely lost connection to mqtt server), we need to handle these errors!");
})
} }
} }