Even more improved init

This commit is contained in:
Gregor Reitzenstein 2020-12-14 12:39:01 +01:00
parent 5a42b34fe3
commit 1dc8dc4710
6 changed files with 104 additions and 19 deletions

View File

@ -110,7 +110,7 @@ pub fn load(log: &Logger, client: &AsyncClient, config: &Config) -> Result<(Acto
let mut map = HashMap::new();
let actuators = config.actors.iter()
.map(|(k,v)| (k, load_single(log, client, k, &v.name, &v.params)))
.map(|(k,v)| (k, load_single(log, client, k, &v.module, &v.params)))
.filter_map(|(k, n)| match n {
None => None,
Some(a) => Some((k, a))
@ -127,13 +127,30 @@ pub fn load(log: &Logger, client: &AsyncClient, config: &Config) -> Result<(Acto
Ok(( map, v ))
}
fn load_single(log: &Logger, client: &AsyncClient, name: &String, module_name: &String, params: &HashMap<String, String>) -> Option<Box<dyn Actuator + Sync + Send>> {
fn load_single(
log: &Logger,
client: &AsyncClient,
name: &String,
module_name: &String,
params: &HashMap<String, String>
) -> Option<Box<dyn Actuator + Sync + Send>>
{
use crate::modules::*;
match module_name.as_ref() {
"Shelly" => {
Some(Box::new(Shelly::new(log, name.clone(), client.clone())))
if !params.is_empty() {
warn!(log, "\"{}\" module expects no parameters. Configured as \"{}\".",
module_name, name);
}
_ => None,
Some(Box::new(Shelly::new(log, name.clone(), client.clone())))
},
"Dummy" => {
Some(Box::new(Dummy))
}
_ => {
error!(log, "No actor found with name \"{}\", configured as \"{}\".", module_name, name);
None
},
}
}

View File

@ -10,6 +10,7 @@ use serde::{Serialize, Deserialize};
use crate::error::Result;
use crate::machine::MachineDescription;
use crate::db::machine::MachineIdentifier;
use crate::db::access::*;
pub fn read(path: &Path) -> Result<Config> {
serde_dhall::from_file(path)
@ -38,6 +39,9 @@ pub struct Config {
pub initiators: HashMap<String, ModuleConfig>,
pub mqtt_url: String,
pub actor_connections: Box<[(String, String)]>,
pub init_connections: Box<[(String, String)]>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -48,8 +52,7 @@ pub struct Listen {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModuleConfig {
pub name: String,
#[serde(skip_serializing_if = "HashMap::is_empty")]
pub module: String,
pub params: HashMap<String, String>
}
@ -57,16 +60,28 @@ impl Default for Config {
fn default() -> Self {
let mut actors: HashMap::<String, ModuleConfig> = HashMap::new();
let mut initiators: HashMap::<String, ModuleConfig> = HashMap::new();
let mut machines = HashMap::new();
actors.insert("Actor".to_string(), ModuleConfig {
name: "Shelly".to_string(),
module: "Shelly".to_string(),
params: HashMap::new(),
});
initiators.insert("Initiator".to_string(), ModuleConfig {
name: "TCP-Listen".to_string(),
module: "TCP-Listen".to_string(),
params: HashMap::new(),
});
machines.insert("Testmachine".to_string(), MachineDescription {
name: "Testmachine".to_string(),
description: Some("A test machine".to_string()),
privs: PrivilegesBuf {
disclose: PermissionBuf::from_string("lab.test.read".to_string()),
read: PermissionBuf::from_string("lab.test.read".to_string()),
write: PermissionBuf::from_string("lab.test.write".to_string()),
manage: PermissionBuf::from_string("lab.test.admin".to_string()),
},
});
Config {
listens: Box::new([
Listen {
@ -74,10 +89,16 @@ impl Default for Config {
port: Some(DEFAULT_PORT),
}
]),
machines: HashMap::new(),
machines: machines,
actors: actors,
initiators: initiators,
mqtt_url: "tcp://localhost:1883".to_string(),
actor_connections: Box::new([
("Testmachine".to_string(), "Actor".to_string()),
]),
init_connections: Box::new([
("Initiator".to_string(), "Testmachine".to_string()),
]),
}
}
}

View File

@ -2,8 +2,13 @@ use std::pin::Pin;
use std::task::{Poll, Context};
use std::future::Future;
use std::collections::HashMap;
use smol::{Task, Timer};
use slog::Logger;
use paho_mqtt::AsyncClient;
use futures::FutureExt;
use futures::future::BoxFuture;
@ -17,6 +22,7 @@ use crate::db::user::{User, UserId, UserData};
use crate::network::InitMap;
use crate::error::Result;
use crate::config::Config;
pub trait Sensor {
fn run_sensor(&mut self) -> BoxFuture<'static, (Option<User>, MachineState)>;
@ -82,14 +88,44 @@ impl Future for Initiator {
}
}
pub fn load() -> Result<(InitMap, Vec<Initiator>)> {
let d = Box::new(Dummy::new());
let (m, i) = Initiator::wrap(d);
pub fn load(log: &Logger, client: &AsyncClient, config: &Config) -> Result<(InitMap, Vec<Initiator>)> {
let mut map = HashMap::new();
map.insert("Dummy".to_string(), m);
Ok((map, vec![i]))
let initiators = config.initiators.iter()
.map(|(k,v)| (k, load_single(log, client, k, &v.module, &v.params)))
.filter_map(|(k,n)| match n {
None => None,
Some(i) => Some((k, i)),
});
let mut v = Vec::new();
for (name, initiator) in initiators {
let (m, i) = Initiator::wrap(initiator);
map.insert(name.clone(), m);
v.push(i);
}
Ok((map, v))
}
fn load_single(
log: &Logger,
client: &AsyncClient,
name: &String,
module_name: &String,
params: &HashMap<String, String>
) -> Option<BoxSensor>
{
match module_name.as_ref() {
"Dummy" => {
Some(Box::new(Dummy::new()))
},
_ => {
error!(log, "No initiator found with name \"{}\", configured as \"{}\"",
module_name, name);
None
}
}
}
pub struct Dummy {

View File

@ -224,7 +224,7 @@ pub struct MachineDescription {
/// The permission required
#[serde(flatten)]
privs: access::PrivilegesBuf,
pub privs: access::PrivilegesBuf,
}
impl MachineDescription {

View File

@ -139,16 +139,26 @@ fn maybe(matches: clap::ArgMatches, log: Arc<Logger>) -> Result<(), Error> {
let mqtt = AsyncClient::new(config.mqtt_url.clone())?;
let tok = mqtt.connect(paho_mqtt::ConnectOptions::new());
smol::block_on(tok);
smol::block_on(tok)?;
let machines = machine::load(&config)?;
let (mut actor_map, actors) = actor::load(&log, &mqtt, &config)?;
let (mut init_map, initiators) = initiator::load()?;
let (mut init_map, initiators) = initiator::load(&log, &mqtt, &config)?;
let network = network::Network::new(machines, actor_map, init_map);
// TODO: restore connections between initiators, machines, actors
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) {
error!(log, "{}", e);
}
}
// TODO HERE: restore connections between initiators, machines, actors
for (a,b) in config.init_connections.iter() {
if let Err(e) = network.connect_init(a,b) {
error!(log, "{}", e);
}
}
let actor_tasks = actors.into_iter().map(|actor| ex.spawn(actor));
let init_tasks = initiators.into_iter().map(|init| ex.spawn(init));

View File

@ -32,6 +32,7 @@ pub struct Shelly {
impl Shelly {
pub fn new(log_view: &Logger, name: String, client: mqtt::AsyncClient) -> Self {
let log = log_view.new(o!("shelly_name" => name.clone()));
debug!(log, "Starting shelly module for {}", &name);
Shelly { log, name, client, }
}