Simplified device conversions and switched device list to hashmap to allow lookup by name
This commit is contained in:
parent
68cbccd72c
commit
c9bbc35f74
|
@ -1,36 +1,56 @@
|
|||
mod ikea_outlet;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::{mqtt::Listener, state::StateOnOff};
|
||||
|
||||
pub use self::ikea_outlet::IkeaOutlet;
|
||||
|
||||
pub trait Device {
|
||||
pub trait AsListener {
|
||||
fn from(&mut self) -> Option<&mut dyn Listener> {
|
||||
None
|
||||
}
|
||||
}
|
||||
impl<T: Device + Listener> AsListener for T {
|
||||
fn from(&mut self) -> Option<&mut dyn Listener> {
|
||||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AsStateOnOff {
|
||||
fn from(&mut self) -> Option<&mut dyn StateOnOff> {
|
||||
None
|
||||
}
|
||||
}
|
||||
impl<T: Device + StateOnOff> AsStateOnOff for T {
|
||||
fn from(&mut self) -> Option<&mut dyn StateOnOff> {
|
||||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Device: AsListener + AsStateOnOff {
|
||||
fn get_identifier(&self) -> &str;
|
||||
|
||||
fn as_state_on_off(&mut self) -> Option<&mut dyn StateOnOff>;
|
||||
|
||||
fn as_listener(&mut self) -> Option<&mut dyn Listener>;
|
||||
}
|
||||
|
||||
pub struct Devices {
|
||||
devices: Vec<Box<dyn Device>>,
|
||||
devices: HashMap<String, Box<dyn Device>>,
|
||||
}
|
||||
|
||||
impl Devices {
|
||||
pub fn new() -> Self {
|
||||
Self { devices: Vec::new() }
|
||||
Self { devices: HashMap::new() }
|
||||
}
|
||||
|
||||
pub fn add_device<T: Device + 'static>(&mut self, device: T) {
|
||||
self.devices.push(Box::new(device));
|
||||
self.devices.insert(device.get_identifier().to_owned(), Box::new(device));
|
||||
}
|
||||
|
||||
pub fn as_listeners(&mut self) -> Vec<&mut dyn Listener> {
|
||||
self.devices.iter_mut().filter_map(|device| device.as_listener()).collect()
|
||||
pub fn get_listeners(&mut self) -> Vec<&mut dyn Listener> {
|
||||
self.devices.iter_mut().filter_map(|(_, device)| AsListener::from(device.as_mut())).collect()
|
||||
}
|
||||
|
||||
pub fn get_device(&mut self, index: usize) -> Option<&mut dyn Device> {
|
||||
if let Some(device) = self.devices.get_mut(index) {
|
||||
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());
|
||||
}
|
||||
return None;
|
||||
|
@ -39,7 +59,7 @@ impl Devices {
|
|||
|
||||
impl Listener for Devices {
|
||||
fn notify(&mut self, message: &rumqttc::Publish) {
|
||||
self.as_listeners().iter_mut().for_each(|listener| {
|
||||
self.get_listeners().iter_mut().for_each(|listener| {
|
||||
listener.notify(message);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -23,14 +23,6 @@ impl Device for IkeaOutlet {
|
|||
fn get_identifier(& self) -> &str {
|
||||
&self.zigbee.get_friendly_name()
|
||||
}
|
||||
|
||||
fn as_state_on_off(&mut self) -> Option<&mut dyn StateOnOff> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn as_listener(&mut self) -> Option<&mut dyn Listener> {
|
||||
Some(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::{time::Duration, rc::Rc, cell::RefCell, process::exit};
|
|||
|
||||
use dotenv::dotenv;
|
||||
|
||||
use automation::{devices::{Devices, IkeaOutlet}, zigbee::Zigbee, mqtt::Notifier};
|
||||
use automation::{devices::{Devices, IkeaOutlet, AsStateOnOff}, zigbee::Zigbee, mqtt::Notifier};
|
||||
use rumqttc::{MqttOptions, Transport, Client};
|
||||
|
||||
fn get_required_env(name: &str) -> String {
|
||||
|
@ -34,11 +34,8 @@ fn main() {
|
|||
|
||||
let mut notifier = Notifier::new();
|
||||
|
||||
{
|
||||
let mut temp = devices.borrow_mut();
|
||||
let a = temp.get_device(0);
|
||||
a.unwrap().as_state_on_off().unwrap().set_state(false);
|
||||
}
|
||||
// Update the state of the kettle
|
||||
AsStateOnOff::from(devices.borrow_mut().get_device("kitchen/kettle").unwrap()).unwrap().set_state(false);
|
||||
|
||||
notifier.add_listener(Rc::downgrade(&devices));
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user