Moved some stuff from main into the libary
This commit is contained in:
parent
2b4ddf82b6
commit
3b6a5e4c07
|
@ -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))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
42
src/main.rs
42
src/main.rs
|
@ -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")
|
||||||
|
|
18
src/mqtt.rs
18
src/mqtt.rs
|
@ -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!");
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user