use clap::{App, Arg, ArgMatches}; use libmodbus::{Modbus, ModbusClient, ModbusRTU, ModbusTCP, ModbusTCPPI}; #[derive(Debug, Eq, PartialEq)] enum Backend { TCP, TCPPI, RTU, } const CLIENT_ID: u8 = 247; fn run(matches: &ArgMatches) -> Result<(), Box<dyn std::error::Error>> { let backend; let mut modbus: Modbus; match matches.value_of("backend").unwrap() { "tcp" => backend = Backend::TCP, "tcppi" => backend = Backend::TCPPI, "rtu" => backend = Backend::RTU, _ => unreachable!(), // because clap ensures that for us } match backend { Backend::RTU => { let serial_interface = matches .value_of("serial_interface") .unwrap_or("/dev/ttyUSB1"); modbus = Modbus::new_rtu(&serial_interface, 9600, 'N', 8, 1)?; modbus.set_slave(CLIENT_ID)?; } Backend::TCP => { modbus = Modbus::new_tcp("127.0.0.1", 1502)?; } Backend::TCPPI => { modbus = Modbus::new_tcp_pi("::1", "1502")?; } } modbus.set_debug(true)?; modbus.connect()?; let mut dest = vec![0u8; 100]; modbus.read_bits(0, 1, &mut dest)?; println!("{:?}", &dest); Ok(()) } fn main() { let matches = App::new("simple-client") .version(env!("CARGO_PKG_VERSION")) .about("Simple Modbus Client with support for the different contextes (rtu, tcp, tcppi)!") .author("Stefan Müller (zzeroo) <s.mueller@it.kls-glt.de>") .arg( Arg::with_name("backend") .help("which backend shoud be used") .long("backend") .short("b") .possible_values(&["rtu", "tcp", "tcppi"]) .takes_value(true) .required(true), ) .arg( Arg::with_name("serial_interface") .help("which backend shoud be used") .long("serial_interface") .short("s") .takes_value(true) .required(false), ) .get_matches(); if let Err(ref err) = run(&matches) { println!("Error: {}", err); std::process::exit(1) } }