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
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);
|
|
}
|
|
}
|