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
|
|
|
|
2021-02-28 22:22:15 +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};
|
|
|
|
|
|
2021-02-25 22:58:52 +01:00
|
|
|
use async_std;
|
|
|
|
|
use async_std::task;
|
2021-02-28 22:22:15 +01:00
|
|
|
use std::sync::{Arc, Mutex};
|
2021-02-25 22:58:52 +01:00
|
|
|
|
2021-02-11 15:05:10 +01:00
|
|
|
const APP_VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
2021-02-25 22:58:52 +01:00
|
|
|
|
2021-03-01 00:00:42 +01:00
|
|
|
const DEFAULT_CONFIG_FILE_NAME: &str = "/etc/s0_meter.cfg";
|
2021-02-25 23:00:32 +01:00
|
|
|
const DEFAULT_IP_ADDRESS: &str = "127.0.0.1";
|
|
|
|
|
const DEFAULT_IP_PORT: &str = "6310";
|
2021-02-11 15:05:10 +01:00
|
|
|
|
2021-02-28 22:22:15 +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,
|
2021-03-01 00:00:00 +01:00
|
|
|
channel_id: p.pin_id,
|
2021-02-28 22:22:15 +01:00
|
|
|
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)
|
2021-03-01 00:52:00 +01:00
|
|
|
(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")
|
2021-03-01 00:52:00 +01:00
|
|
|
// (@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();
|
|
|
|
|
|
2021-03-01 00:52:00 +01:00
|
|
|
// 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);
|
|
|
|
|
|
2021-02-28 22:22:15 +01:00
|
|
|
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
|
2021-03-01 00:52:00 +01:00
|
|
|
println!(
|
2021-02-28 22:22:15 +01:00
|
|
|
"Error while parsing config file {}: {}",
|
|
|
|
|
config_file_name, err_msg
|
|
|
|
|
);
|
2021-03-01 00:52:00 +01:00
|
|
|
std::process::exit(1);
|
2021-02-28 22:22:15 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#[allow(unused_assignments, unused_mut)]
|
|
|
|
|
let mut pin_manager: Option<
|
|
|
|
|
Arc<Mutex<Box<dyn input_pin_manager::InputPinManager + Send>>>,
|
|
|
|
|
> = None;
|
|
|
|
|
#[cfg(feature = "rppal")]
|
|
|
|
|
{
|
2021-02-25 22:58:52 +01:00
|
|
|
println!("Will access GPIO pins");
|
2021-02-28 22:22:15 +01:00
|
|
|
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"))]
|
|
|
|
|
{
|
2021-02-25 22:58:52 +01:00
|
|
|
println!("Will NOT access GPIO pins");
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-25 23:00:32 +01:00
|
|
|
let rest_ip_addr = DEFAULT_IP_ADDRESS;
|
|
|
|
|
let rest_ip_port = DEFAULT_IP_PORT;
|
|
|
|
|
|
2021-02-28 22:22:15 +01:00
|
|
|
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 {
|
2021-02-25 23:00:32 +01:00
|
|
|
ip_and_port: format!("{}:{}", &rest_ip_addr, &rest_ip_port),
|
2021-02-28 22:22:15 +01:00
|
|
|
data_provider: dp.clone(),
|
2021-02-23 00:08:28 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let _ = task::block_on(rest_api::start(&rest_api_config));
|
|
|
|
|
|
2021-02-28 22:22:15 +01:00
|
|
|
if pin_manager.is_some() {
|
|
|
|
|
&pin_manager.unwrap().lock().unwrap().close_inputs();
|
|
|
|
|
}
|
2021-02-11 15:05:10 +01:00
|
|
|
}
|