You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
3.8 KiB

use profirust::dp;
use profirust::fdl;
use profirust::phy;
mod tester_io;
mod valve_terminal;
// Bus Parameters
const MASTER_ADDRESS: u8 = 1;
const BUS_DEVICE: &'static str = "/dev/ttyUSB0";
const BAUDRATE: profirust::Baudrate = profirust::Baudrate::B500000;
fn main() -> ! {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
.format_timestamp_micros()
.init();
log::info!("Ventilinsel Teststation");
let mut dp_scanner = dp::scan::DpScanner::new();
let mut dp_master = dp::DpMaster::new(vec![]);
let mut tester_io = tester_io::TesterIo::new(&mut dp_master, BAUDRATE);
let mut valve_terminal = valve_terminal::ValveTerminal::new(&mut dp_master, BAUDRATE);
let mut fdl = fdl::FdlActiveStation::new(
fdl::ParametersBuilder::new(MASTER_ADDRESS, BAUDRATE)
// We use a rather large T_slot time because USB-RS485 converters
// can induce large delays at times.
.slot_bits(2500)
// 2 Sekunden Watchdog Timeout
.watchdog_timeout(profirust::time::Duration::from_secs(2))
.build_verified(&dp_master),
);
// We must not poll() too often or to little. T_slot / 2 seems to be a good compromise.
let sleep_time: std::time::Duration = (fdl.parameters().slot_time() / 2).into();
log::info!("Verbindung mit dem Bus wird aufgebaut...");
let mut phy = phy::LinuxRs485Phy::new(BUS_DEVICE, fdl.parameters().baudrate);
fdl.set_online();
dp_master.enter_operate();
loop {
fdl.poll_multi(
profirust::time::Instant::now(),
&mut phy,
&mut [&mut dp_master, &mut dp_scanner],
);
let dp_events = dp_master.take_last_events();
tester_io.update(&mut dp_master, &dp_events);
valve_terminal.update(&mut dp_master, &dp_events);
// Ventil Zustände von den Eingängen auf die Ventilausgänge übertragen.
valve_terminal.update_valve_states(tester_io.valve_states());
if valve_terminal.is_running(&mut dp_master) {
tester_io.set_state(tester_io::TesterStatus::ValveTerminalConnected);
} else if valve_terminal.error() {
tester_io.set_state(tester_io::TesterStatus::Error);
} else {
tester_io.set_state(tester_io::TesterStatus::Ready);
}
let scanner_event = dp_scanner.take_last_event();
match scanner_event {
Some(dp::scan::DpScanEvent::PeripheralFound(desc)) => {
if valve_terminal.check_ident(desc.ident) {
// Wenn die Ventilinsel nicht erreichbar ist, wird eine neue Adresse vom "DP Scanner"
// übernommen.
if !valve_terminal.is_running(&mut dp_master) {
log::info!(
"Ventilinsel an Adresse #{} gefunden. Parametrieren...",
desc.address
);
valve_terminal.init_at_address(desc.address, &mut dp_master);
} else {
// Alte Ventilinsel ist noch aktiv??
log::warn!(
"Neue Ventilinsel an Adresse #{} gefunden, obwohl alte noch aktiv. Wird ignoriert.",
desc.address
);
}
} else {
log::info!("Andere Station an Adresse #{} gefunden:", desc.address);
log::info!(" - Ident: 0x{:04x}", desc.ident);
}
}
Some(dp::scan::DpScanEvent::PeripheralLost(address)) => {
log::info!("Station an Adresse #{} verloren.", address);
}
_ => (),
}
std::thread::sleep(sleep_time);
}
}