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