pub use cmds::powerlevel::PowerLevelOperationStatus;
pub use cmds::powerlevel::PowerLevelStatus;
pub use cmds::MeterData;
use cmds::basic::Basic;
use cmds::info::NodeInfo;
use cmds::meter::Meter;
use cmds::powerlevel::PowerLevel;
use cmds::switch_binary::SwitchBinary;
use cmds::CommandClass;
use driver::serial::SerialMsg;
use driver::{Driver, GenericType};
use error::Error;
use std::cell::RefCell;
use std::clone::Clone;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::{thread, time};
pub trait Handler: Send {
fn handle(self, msg: SerialMsg);
}
#[derive(Debug, Clone)]
pub struct Controller<D>
where
D: Driver,
{
driver: Arc<Mutex<D>>,
nodes: Rc<RefCell<Vec<Node<D>>>>,
}
impl<D> Controller<D>
where
D: Driver + Send + 'static,
{
pub fn new(driver: D) -> Result<Controller<D>, Error> {
let controller = Controller {
driver: Arc::new(Mutex::new(driver)),
nodes: Rc::new(RefCell::new(vec![])),
};
controller.discover_nodes()?;
Ok(controller)
}
pub fn discover_nodes(&self) -> Result<(), Error> {
self.nodes.borrow_mut().clear();
let ids = self.driver.lock().unwrap().get_node_ids()?;
for i in ids {
self.nodes
.borrow_mut()
.push(Node::new(self.driver.clone(), i as u8));
}
Ok(())
}
pub fn node<I>(&mut self, id: I) -> Option<Node<D>>
where
I: Into<u8>,
{
let id = id.into();
for n in self.nodes.borrow().iter() {
if id == n.get_id() {
return Some(n.clone());
}
}
None
}
pub fn nodes(&self) -> Vec<u8> {
self.nodes
.borrow()
.iter()
.map(|n| n.id)
.collect::<Vec<u8>>()
}
pub fn handle_messages(&self, h: Box<Fn(SerialMsg) + Send>) {
let driver = self.driver.clone();
let duration = time::Duration::from_millis(50);
thread::spawn(move || loop {
{
let mut m_driver = driver.lock().unwrap();
loop {
match m_driver.read() {
Ok(msg) => h(msg),
Err(_) => break,
}
}
}
thread::sleep(duration);
});
}
}
#[derive(Debug)]
pub struct Node<D>
where
D: Driver,
{
driver: Arc<Mutex<D>>,
id: u8,
types: Vec<GenericType>,
cmds: Vec<CommandClass>,
}
impl<D> Node<D>
where
D: Driver,
{
pub fn new(driver: Arc<Mutex<D>>, id: u8) -> Node<D> {
let mut node = Node {
driver: driver,
id: id,
types: vec![],
cmds: vec![],
};
node.update_node_info().is_ok();
node
}
pub fn update_node_info(&mut self) -> Result<(), Error> {
let (types, cmds) = self.node_info_get()?;
self.types = types;
self.cmds = cmds;
Ok(())
}
pub fn get_id(&self) -> u8 {
self.id
}
pub fn get_commands(&self) -> Vec<CommandClass> {
self.cmds.clone()
}
pub fn node_info_get(&self) -> Result<(Vec<GenericType>, Vec<CommandClass>), Error> {
let mut driver = self.driver.lock().unwrap();
driver.write(NodeInfo::get(self.id))?;
let msg = driver.read()?;
NodeInfo::report(msg.data)
}
pub fn basic_set<V>(&self, value: V) -> Result<u8, Error>
where
V: Into<u8>,
{
self.driver
.lock()
.unwrap()
.write(Basic::set(self.id, value.into()))
}
pub fn basic_get(&self) -> Result<u8, Error> {
let mut driver = self.driver.lock().unwrap();
driver.write(Basic::get(self.id))?;
match driver.read() {
Ok(msg) => Basic::report(msg.data),
Err(err) => Err(err),
}
}
pub fn switch_binary_set<V>(&self, value: V) -> Result<u8, Error>
where
V: Into<bool>,
{
self.driver
.lock()
.unwrap()
.write(SwitchBinary::set(self.id, value))
}
pub fn switch_binary_get(&self) -> Result<bool, Error> {
let mut driver = self.driver.lock().unwrap();
driver.write(SwitchBinary::get(self.id))?;
match driver.read() {
Ok(msg) => SwitchBinary::report(msg.data),
Err(err) => Err(err),
}
}
pub fn powerlevel_set<S, T>(&self, status: S, seconds: T) -> Result<u8, Error>
where
S: Into<PowerLevelStatus>,
T: Into<u8>,
{
self.driver
.lock()
.unwrap()
.write(PowerLevel::set(self.id, status, seconds))
}
pub fn powerlevel_get(&self) -> Result<(PowerLevelStatus, u8), Error> {
let mut driver = self.driver.lock().unwrap();
driver.write(PowerLevel::get(self.id))?;
match driver.read() {
Ok(msg) => PowerLevel::report(msg.data),
Err(err) => Err(err),
}
}
pub fn powerlevel_test_node_set<T, L, F>(
&self,
test_node_id: T,
level: L,
test_frames: F,
) -> Result<u8, Error>
where
T: Into<u8>,
L: Into<PowerLevelStatus>,
F: Into<u16>,
{
self.driver.lock().unwrap().write(PowerLevel::test_node_set(
self.id,
test_node_id,
level,
test_frames,
))
}
pub fn powerlevel_test_node_get(&self) -> Result<(u8, PowerLevelOperationStatus, u16), Error> {
let mut driver = self.driver.lock().unwrap();
self.driver
.lock()
.unwrap()
.write(PowerLevel::test_node_get(self.id))?;
match driver.read() {
Ok(msg) => PowerLevel::test_node_report(msg.data),
Err(err) => Err(err),
}
}
pub fn meter_get(&self) -> Result<MeterData, Error> {
let mut driver = self.driver.lock().unwrap();
driver.write(Meter::get(self.id))?;
match driver.read() {
Ok(msg) => Meter::report(msg.data),
Err(err) => Err(err),
}
}
pub fn meter_get_v2<S>(&self, meter_type: S) -> Result<(MeterData, u16, MeterData), Error>
where
S: Into<MeterData>,
{
let mut driver = self.driver.lock().unwrap();
driver.write(Meter::get_v2(self.id, meter_type.into()))?;
match driver.read() {
Ok(msg) => Meter::report_v2(msg.data),
Err(err) => Err(err),
}
}
}
impl<D> Clone for Node<D>
where
D: Driver,
{
fn clone(&self) -> Node<D> {
Node {
driver: self.driver.clone(),
id: self.id,
types: self.types.clone(),
cmds: self.cmds.clone(),
}
}
}