use std::collections::BTreeMap; use super::models::SensorTypeEnum; use super::MeteoError; mod enviro_phat; mod serial_node; pub trait SensorNode { fn measure(&self, measurement_type: SensorTypeEnum, sensor_id: u32) -> Result; } pub struct NodeRegistry { node_map: BTreeMap, } impl NodeSensorRegistry { fn new() -> NodeSensorRegistry { let nodes = { use crate::db::schema::nodes; nodes::table .load::(&*db_conn) .map_err(|_| MeteoError)? }; let grouped_sensors: Vec> = { Sensor::belonging_to(&nodes) .load::(&*db_conn) .map_err(|_| MeteoError)? .grouped_by(&nodes) }; let nodes_and_sensors: Vec<(Node, Vec)> = nodes.into_iter().zip(grouped_sensors).collect(); let mut node_map = HashMap::new(); for (node, sensor_vec) in nodes_and_sensors { let node = match node.route_type { "serial" => {}, // "enviro_phat" => {} route_type => panic!("Invalid route type '{}' for node ID {}.", route_type, node.public_id); } node_map.insert(node.public_id, node); } NodeRegistry { node_map } } pub fn get_node(&self, node_id: u32) -> Result<&SensorNode, MeteoError> { self.node_map.get(node_id).ok_or(MeteoError) } } pub fn initialize() -> NodeRegistry { NodeRegistry::new() let nodes = { use crate::db::schema::nodes; nodes::table .load::(&*db_conn) .map_err(|_| MeteoError)? }; let grouped_sensors: Vec> = { Sensor::belonging_to(&nodes) .load::(&*db_conn) .map_err(|_| MeteoError)? .grouped_by(&nodes) }; let nodes_and_sensors: Vec<(Node, Vec)> = nodes.into_iter().zip(grouped_sensors).collect(); let mut output_map = HashMap::new(); for (node, sensor_vec) in nodes_and_sensors { let node_map = output_map .entry(node.public_id as u32) .or_insert_with(HashMap::new); for sensor in sensor_vec { node_map .entry(sensor.sensor_type.as_ref().to_string()) .or_insert_with(Vec::new) .push(sensor.public_id as u32); } } Ok(Json(output_map)) }