diff --git a/examples/bffh.dhall b/examples/bffh.dhall index e85c3ac..fd33768 100644 --- a/examples/bffh.dhall +++ b/examples/bffh.dhall @@ -1,14 +1,15 @@ -- { actor_connections = [] : List { _1 : Text, _2 : Text } { actor_connections = -- Link up machines to actors - [ { _1 = "Testmachine", _2 = "Shelly_1234" } - , { _1 = "Another", _2 = "Bash" } + [ { machine = "Testmachine", actor = "Shelly1234" } + , { machine = "Another", actor = "Bash" } -- One machine can have as many actors as it wants - , { _1 = "Yetmore", _2 = "Bash2" } - , { _1 = "Yetmore", _2 = "FailBash"} + , { machine = "Yetmore", actor = "Bash2" } + , { machine = "Yetmore", actor = "FailBash"} ] , actors = - { Shelly_1234 = { module = "Shelly", params = {=} } + { Shelly_1234 = { module = "Shelly", params = + { topic = "Topic1234" }} , Bash = { module = "Process", params = { cmd = "./examples/actor.sh" , args = "your ad could be here" @@ -21,10 +22,10 @@ { cmd = "./examples/fail-actor.sh" }} } - , init_connections = [] : List { _1 : Text, _2 : Text } ---, init_connections = [{ _1 = "Initiator", _2 = "Testmachine" }] -, initiators = {=} - --{ Initiator = { module = "Dummy", params = {=} } } + --, init_connections = [] : List { machine : Text, initiator : Text } +, init_connections = [{ machine = "Testmachine", initiator = "Initiator" }] +, initiators = --{=} + { Initiator = { module = "Dummy", params = {=} } } , listens = [ { address = "127.0.0.1", port = Some 59661 } , { address = "::1", port = Some 59661 } diff --git a/src/actor.rs b/src/actor.rs index a8efaec..ec29c36 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -172,7 +172,7 @@ fn load_single( .map(|a| a.into_boxed_actuator()) } "Shelly" => { - Some(Box::new(Shelly::new(log, name.clone(), client))) + Some(Box::new(Shelly::new(log, name.clone(), client, params))) } _ => { error!(log, "No actor found with name \"{}\", configured as \"{}\".", module_name, name); diff --git a/src/config.rs b/src/config.rs index 1196b73..e83c665 100644 --- a/src/config.rs +++ b/src/config.rs @@ -15,6 +15,18 @@ pub fn read(path: &Path) -> Result { .map_err(Into::into) } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ActorConn { + pub machine: String, + pub actor: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct InitiatorConn { + pub machine: String, + pub initiator: String, +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Config { /// A list of address/port pairs to listen on. @@ -34,8 +46,8 @@ pub struct Config { pub mqtt_url: String, - pub actor_connections: Box<[(String, String)]>, - pub init_connections: Box<[(String, String)]>, + pub actor_connections: Box<[ActorConn]>, + pub init_connections: Box<[InitiatorConn]>, pub db_path: PathBuf, @@ -101,10 +113,12 @@ impl Default for Config { initiators, mqtt_url: "tcp://localhost:1883".to_string(), actor_connections: Box::new([ - ("Testmachine".to_string(), "Actor".to_string()), + ActorConn { machine: "Testmachine".to_string(), actor: "Actor".to_string() }, ]), init_connections: Box::new([ - ("Initiator".to_string(), "Testmachine".to_string()), + InitiatorConn { + initiator: "Initiator".to_string(), machine: "Testmachine".to_string() + }, ]), db_path: PathBuf::from("/run/bffh/database"), diff --git a/src/main.rs b/src/main.rs index 5543f88..07afdb7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,7 +41,7 @@ use error::Error; use slog::Logger; use paho_mqtt::AsyncClient; -use crate::config::Config; +use crate::config::{ActorConn, Config, InitiatorConn}; fn main() { use clap::{crate_version, crate_description, crate_name}; @@ -182,18 +182,18 @@ fn maybe(matches: clap::ArgMatches, log: Arc) -> Result<(), Error> { let mut network = network::Network::new(machines, actor_map, init_map); - for (a,b) in config.actor_connections.iter() { - if let Err(e) = network.connect_actor(a,b) { + for ActorConn { machine, actor } in config.actor_connections.iter() { + if let Err(e) = network.connect_actor(machine, actor) { error!(log, "{}", e); } - info!(log, "[Actor] Connected {} to {}", a, b); + info!(log, "[Actor] Connected {} to {}", machine, actor); } - for (a,b) in config.init_connections.iter() { - if let Err(e) = network.connect_init(a,b) { + for InitiatorConn { initiator, machine } in config.init_connections.iter() { + if let Err(e) = network.connect_init(initiator, machine) { error!(log, "{}", e); } - info!(log, "[Initi] Connected {} to {}", a, b); + info!(log, "[Initi] Connected {} to {}", initiator, machine); } for actor in actors.into_iter() { diff --git a/src/modules/shelly.rs b/src/modules/shelly.rs index 3ae1975..843e2a3 100644 --- a/src/modules/shelly.rs +++ b/src/modules/shelly.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use slog::Logger; use crate::db::machine::Status; @@ -19,12 +20,23 @@ pub struct Shelly { log: Logger, name: String, client: mqtt::AsyncClient, + topic: String, } impl Shelly { - pub fn new(log: Logger, name: String, client: mqtt::AsyncClient) -> Self { - debug!(log, "Starting shelly module for {}", &name); - Shelly { log, name, client, } + pub fn new(log: Logger, name: String, client: mqtt::AsyncClient, params: &HashMap) -> Self { + let topic = if let Some(topic) = params.get("topic") { + format!("shellies/{}/relay/0/command", topic) + } else { + format!("shellies/{}/relay/0/command", name) + }; + debug!(log, + "Starting shelly module for {name} with topic '{topic}'", + name = &name, + topic = &topic, + ); + + Shelly { log, name, client, topic, } } /// Set the name to a new one. This changes the shelly that will be activated @@ -39,12 +51,11 @@ impl Shelly { impl Actuator for Shelly { fn apply(&mut self, state: MachineState) -> BoxFuture<'static, ()> { info!(self.log, "Machine Status changed: {:?}", state); - let topic = format!("shellies/{}/relay/0/command", self.name); let pl = match state.state { Status::InUse(_) => "on", _ => "off", }; - let msg = mqtt::Message::new(topic, pl, 0); + let msg = mqtt::Message::new(&self.topic.clone(), pl, 0); let f = self.client.publish(msg).map(|_| ()); return Box::pin(f);