s0-meter/src/main.rs

144 lines
4.4 KiB
Rust
Raw Normal View History

2021-02-11 15:05:10 +01:00
#[macro_use]
extern crate clap;
2021-02-11 22:09:29 +01:00
mod cfg_reader;
2021-02-25 21:59:09 +01:00
mod pulse_counter;
2021-02-23 00:08:28 +01:00
mod rest_api;
2021-02-11 22:09:29 +01:00
#[cfg(not(feature = "rppal"))]
mod input_pin_manager;
#[cfg(feature = "rppal")]
mod rpi_pin_manager;
// #[cfg(not(feature = "rppal"))]
use input_pin_manager::PinConfiguration;
#[cfg(feature = "rppal")]
use rpi_pin_manager::{input_pin_manager, RPiPinManager};
use async_std;
use async_std::task;
use std::sync::{Arc, Mutex};
2021-02-11 15:05:10 +01:00
const APP_VERSION: &'static str = env!("CARGO_PKG_VERSION");
const DEFAULT_CONFIG_FILE_NAME: &str = "/etc/s0_meter.cfg";
const DEFAULT_IP_ADDRESS: &str = "127.0.0.1";
const DEFAULT_IP_PORT: &str = "6310";
2021-02-11 15:05:10 +01:00
struct PulseDataProvider {
pulse_counter: pulse_counter::PulseCounter,
}
impl rest_api::DataProvider for PulseDataProvider {
fn get_channels(&self) -> Vec<usize> {
self.pulse_counter.get_channels()
}
fn get_pulses_by_channel(
&mut self,
channel_id: usize,
) -> Result<Vec<rest_api::PulseInfo>, std::io::Error> {
match self.pulse_counter.get_pulses_by_channel(channel_id) {
Ok(pulses) => {
let mut pulse_list: Vec<rest_api::PulseInfo> = vec![];
for p in pulses {
pulse_list.push(rest_api::PulseInfo {
timestamp_ns: p.timestamp_ns,
channel_id: p.pin_id,
level: p.level,
})
}
Ok(pulse_list)
}
Err(e) => Err(e),
}
}
}
2021-02-11 15:05:10 +01:00
fn main() {
let cli_args = clap_app!(s0_meter =>
(version: APP_VERSION)
(author: "Harald Kube <harald.kube@gmx.de>")
2021-02-11 15:05:10 +01:00
(about: "Listen for S0 pulses at the given GPIO pins")
// (@arg v: -v ... "Set the verbosity level (up to -vvv)")
2021-02-11 15:05:10 +01:00
(@arg config: -c --config +takes_value "The name of the config file (default: /etc/s0_logger.cfg)")
).get_matches();
// let log_level = cli_args.occurrences_of("v");
// match log_level {
// 0 => println!("No logging"),
// 1 => println!("A little logging"),
// 2 => println!("A little more logging"),
// _ => println!("A lot logging"),
// };
2021-02-11 15:05:10 +01:00
let config_file_name = cli_args
.value_of("config")
.unwrap_or(DEFAULT_CONFIG_FILE_NAME);
println!("Read the config from file '{}'", config_file_name);
let mut pin_config: Vec<PinConfiguration> = vec![];
match cfg_reader::parse_file(config_file_name) {
Ok(config) => {
println!("GPIO-Config:");
for channel in config.channels() {
println!("Channel {} @ GPIO {}", &channel.id, &channel.gpio);
&mut pin_config.push(PinConfiguration {
channel_id: channel.id as usize,
gpio_id: channel.gpio as usize,
});
}
println!("---");
}
Err(err_msg) => {
// TODO Log
println!(
"Error while parsing config file {}: {}",
config_file_name, err_msg
);
std::process::exit(1);
}
};
#[allow(unused_assignments, unused_mut)]
let mut pin_manager: Option<
Arc<Mutex<Box<dyn input_pin_manager::InputPinManager + Send>>>,
> = None;
#[cfg(feature = "rppal")]
{
println!("Will access GPIO pins");
let input_pin_manager_box: Box<dyn input_pin_manager::InputPinManager + Send> =
Box::new(RPiPinManager::new());
pin_manager = Some(Arc::new(Mutex::new(input_pin_manager_box)));
}
#[cfg(not(feature = "rppal"))]
{
println!("Will NOT access GPIO pins");
}
let rest_ip_addr = DEFAULT_IP_ADDRESS;
let rest_ip_port = DEFAULT_IP_PORT;
let mut p_counter = pulse_counter::PulseCounter::new(pin_manager.clone().unwrap(), pin_config);
match p_counter.start() {
Ok(()) => {}
Err(e) => {
// TODO Log
println!("Could not start pulse_counter thread: {:?}", e);
}
}
let dp: Arc<Mutex<Box<dyn crate::rest_api::DataProvider + Send>>> =
Arc::new(Mutex::new(Box::new(PulseDataProvider {
pulse_counter: p_counter,
})));
2021-02-23 00:08:28 +01:00
let rest_api_config = rest_api::RestApiConfig {
ip_and_port: format!("{}:{}", &rest_ip_addr, &rest_ip_port),
data_provider: dp.clone(),
2021-02-23 00:08:28 +01:00
};
let _ = task::block_on(rest_api::start(&rest_api_config));
if pin_manager.is_some() {
&pin_manager.unwrap().lock().unwrap().close_inputs();
}
2021-02-11 15:05:10 +01:00
}