Config improvements and make shellies have a topic parameter

This commit is contained in:
Nadja Reitzenstein 2021-12-05 19:23:35 +01:00
parent eeb0ff306b
commit 6d3e08955a
5 changed files with 52 additions and 26 deletions

View File

@ -1,14 +1,15 @@
-- { actor_connections = [] : List { _1 : Text, _2 : Text } -- { actor_connections = [] : List { _1 : Text, _2 : Text }
{ actor_connections = { actor_connections =
-- Link up machines to actors -- Link up machines to actors
[ { _1 = "Testmachine", _2 = "Shelly_1234" } [ { machine = "Testmachine", actor = "Shelly1234" }
, { _1 = "Another", _2 = "Bash" } , { machine = "Another", actor = "Bash" }
-- One machine can have as many actors as it wants -- One machine can have as many actors as it wants
, { _1 = "Yetmore", _2 = "Bash2" } , { machine = "Yetmore", actor = "Bash2" }
, { _1 = "Yetmore", _2 = "FailBash"} , { machine = "Yetmore", actor = "FailBash"}
] ]
, actors = , actors =
{ Shelly_1234 = { module = "Shelly", params = {=} } { Shelly_1234 = { module = "Shelly", params =
{ topic = "Topic1234" }}
, Bash = { module = "Process", params = , Bash = { module = "Process", params =
{ cmd = "./examples/actor.sh" { cmd = "./examples/actor.sh"
, args = "your ad could be here" , args = "your ad could be here"
@ -21,10 +22,10 @@
{ cmd = "./examples/fail-actor.sh" { cmd = "./examples/fail-actor.sh"
}} }}
} }
, init_connections = [] : List { _1 : Text, _2 : Text } --, init_connections = [] : List { machine : Text, initiator : Text }
--, init_connections = [{ _1 = "Initiator", _2 = "Testmachine" }] , init_connections = [{ machine = "Testmachine", initiator = "Initiator" }]
, initiators = {=} , initiators = --{=}
--{ Initiator = { module = "Dummy", params = {=} } } { Initiator = { module = "Dummy", params = {=} } }
, listens = , listens =
[ { address = "127.0.0.1", port = Some 59661 } [ { address = "127.0.0.1", port = Some 59661 }
, { address = "::1", port = Some 59661 } , { address = "::1", port = Some 59661 }

View File

@ -172,7 +172,7 @@ fn load_single(
.map(|a| a.into_boxed_actuator()) .map(|a| a.into_boxed_actuator())
} }
"Shelly" => { "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); error!(log, "No actor found with name \"{}\", configured as \"{}\".", module_name, name);

View File

@ -15,6 +15,18 @@ pub fn read(path: &Path) -> Result<Config> {
.map_err(Into::into) .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)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config { pub struct Config {
/// A list of address/port pairs to listen on. /// A list of address/port pairs to listen on.
@ -34,8 +46,8 @@ pub struct Config {
pub mqtt_url: String, pub mqtt_url: String,
pub actor_connections: Box<[(String, String)]>, pub actor_connections: Box<[ActorConn]>,
pub init_connections: Box<[(String, String)]>, pub init_connections: Box<[InitiatorConn]>,
pub db_path: PathBuf, pub db_path: PathBuf,
@ -101,10 +113,12 @@ impl Default for Config {
initiators, initiators,
mqtt_url: "tcp://localhost:1883".to_string(), mqtt_url: "tcp://localhost:1883".to_string(),
actor_connections: Box::new([ actor_connections: Box::new([
("Testmachine".to_string(), "Actor".to_string()), ActorConn { machine: "Testmachine".to_string(), actor: "Actor".to_string() },
]), ]),
init_connections: Box::new([ 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"), db_path: PathBuf::from("/run/bffh/database"),

View File

@ -41,7 +41,7 @@ use error::Error;
use slog::Logger; use slog::Logger;
use paho_mqtt::AsyncClient; use paho_mqtt::AsyncClient;
use crate::config::Config; use crate::config::{ActorConn, Config, InitiatorConn};
fn main() { fn main() {
use clap::{crate_version, crate_description, crate_name}; use clap::{crate_version, crate_description, crate_name};
@ -182,18 +182,18 @@ fn maybe(matches: clap::ArgMatches, log: Arc<Logger>) -> Result<(), Error> {
let mut network = network::Network::new(machines, actor_map, init_map); let mut network = network::Network::new(machines, actor_map, init_map);
for (a,b) in config.actor_connections.iter() { for ActorConn { machine, actor } in config.actor_connections.iter() {
if let Err(e) = network.connect_actor(a,b) { if let Err(e) = network.connect_actor(machine, actor) {
error!(log, "{}", e); 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() { for InitiatorConn { initiator, machine } in config.init_connections.iter() {
if let Err(e) = network.connect_init(a,b) { if let Err(e) = network.connect_init(initiator, machine) {
error!(log, "{}", e); error!(log, "{}", e);
} }
info!(log, "[Initi] Connected {} to {}", a, b); info!(log, "[Initi] Connected {} to {}", initiator, machine);
} }
for actor in actors.into_iter() { for actor in actors.into_iter() {

View File

@ -1,3 +1,4 @@
use std::collections::HashMap;
use slog::Logger; use slog::Logger;
use crate::db::machine::Status; use crate::db::machine::Status;
@ -19,12 +20,23 @@ pub struct Shelly {
log: Logger, log: Logger,
name: String, name: String,
client: mqtt::AsyncClient, client: mqtt::AsyncClient,
topic: String,
} }
impl Shelly { impl Shelly {
pub fn new(log: Logger, name: String, client: mqtt::AsyncClient) -> Self { pub fn new(log: Logger, name: String, client: mqtt::AsyncClient, params: &HashMap<String, String>) -> Self {
debug!(log, "Starting shelly module for {}", &name); let topic = if let Some(topic) = params.get("topic") {
Shelly { log, name, client, } 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 /// 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 { impl Actuator for Shelly {
fn apply(&mut self, state: MachineState) -> BoxFuture<'static, ()> { fn apply(&mut self, state: MachineState) -> BoxFuture<'static, ()> {
info!(self.log, "Machine Status changed: {:?}", state); info!(self.log, "Machine Status changed: {:?}", state);
let topic = format!("shellies/{}/relay/0/command", self.name);
let pl = match state.state { let pl = match state.state {
Status::InUse(_) => "on", Status::InUse(_) => "on",
_ => "off", _ => "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(|_| ()); let f = self.client.publish(msg).map(|_| ());
return Box::pin(f); return Box::pin(f);