diff --git a/src/devices.rs b/src/devices.rs index 6e9e8cc..9f44259 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -14,7 +14,7 @@ impl_cast::impl_cast!(Device, Listener); impl_cast::impl_cast!(Device, Fullfillment); impl_cast::impl_cast!(Device, OnOff); -pub trait Device: AsFullfillment + AsListener + AsOnOff { +pub trait Device: Sync + Send + AsFullfillment + AsListener + AsOnOff { fn get_id(&self) -> String; } @@ -52,10 +52,6 @@ impl Devices { get_cast!(Fullfillment); get_cast!(OnOff); - // pub fn get_google_devices(&mut self) -> HashMap<&str, &mut dyn GoogleHomeDevice> { - // self.devices - // } - pub fn get_device(&mut self, name: &str) -> Option<&mut dyn Device> { if let Some(device) = self.devices.get_mut(name) { return Some(device.as_mut()); diff --git a/src/main.rs b/src/main.rs index ca93832..f1d13bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use std::{time::Duration, rc::Rc, cell::RefCell, process::exit}; +use std::{time::Duration, sync::{Arc, RwLock}, process::exit, thread}; use dotenv::dotenv; @@ -28,21 +28,28 @@ fn main() { let (client, connection) = Client::new(mqttoptions, 10); // Create device holder - let devices = Rc::new(RefCell::new(Devices::new())); + let devices = Arc::new(RwLock::new(Devices::new())); // Create a new device and add it to the holder - devices.borrow_mut().add_device(IkeaOutlet::new("Kettle".into(), Zigbee::new("kitchen/kettle", "zigbee2mqtt/kitchen/kettle"), client.clone())); + devices.write().unwrap().add_device(IkeaOutlet::new("Kettle".into(), Zigbee::new("kitchen/kettle", "zigbee2mqtt/kitchen/kettle"), client.clone())); - devices.borrow_mut().add_device(TestOutlet::new()); + devices.write().unwrap().add_device(TestOutlet::new()); { - for (_, d) in devices.borrow_mut().as_on_offs().iter_mut() { - d.set_on(true).unwrap(); + for (_, d) in devices.write().unwrap().as_on_offs().iter_mut() { + d.set_on(false).unwrap(); } } - let gc = GoogleHome::new("Dreaded_X"); + let ptr = Arc::downgrade(&devices); + { + let mut notifier = Notifier::new(); + notifier.add_listener(ptr); + notifier.start(connection); + } + // Google Home test + let gc = GoogleHome::new("Dreaded_X"); let json = r#"{ "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf", "inputs": [ @@ -74,18 +81,10 @@ fn main() { ] }"#; let request = serde_json::from_str(json).unwrap(); - { - let mut binding = devices.borrow_mut(); - let mut ghd = binding.as_fullfillments(); + let mut binding = devices.write().unwrap(); + let mut ghd = binding.as_fullfillments(); - let response = gc.handle_request(request, &mut ghd).unwrap(); + let response = gc.handle_request(request, &mut ghd).unwrap(); - println!("{response:?}"); - } - - let mut notifier = Notifier::new(); - - notifier.add_listener(Rc::downgrade(&devices)); - - notifier.start(connection); + println!("{response:?}"); } diff --git a/src/mqtt.rs b/src/mqtt.rs index ed22530..c1d35fa 100644 --- a/src/mqtt.rs +++ b/src/mqtt.rs @@ -1,13 +1,13 @@ -use std::{rc::Weak, cell::RefCell}; +use std::sync::{Weak, RwLock}; use rumqttc::{Publish, Connection, Event, Incoming}; -pub trait Listener { +pub trait Listener: Sync + Send { fn notify(&mut self, message: &Publish); } pub struct Notifier { - listeners: Vec>>, + listeners: Vec>>, } impl Notifier { @@ -18,7 +18,7 @@ impl Notifier { fn notify(&mut self, message: Publish) { self.listeners.retain(|listener| { if let Some(listener) = listener.upgrade() { - listener.borrow_mut().notify(&message); + listener.write().unwrap().notify(&message); return true; } @@ -26,7 +26,7 @@ impl Notifier { }) } - pub fn add_listener(&mut self, listener: Weak>) { + pub fn add_listener(&mut self, listener: Weak>) { self.listeners.push(listener); }