improv-setup/src/main.rs

174 lines
4.8 KiB
Rust
Raw Normal View History

2024-10-15 23:48:06 +02:00
use anyhow::{
Context,
Result,
};
use clap::{
Parser,
Subcommand,
};
use env_logger;
use hex;
use improv_setup::improv::{
IMPROV_HEADER,
IMPROV_VERSION,
RPCCommand,
CurrentState,
calculate_checksum,
2024-10-30 22:03:13 +01:00
ImprovDataToPacket,
2024-12-18 20:00:26 +01:00
ImprovDataFromPacket,
2024-12-18 20:14:25 +01:00
RawPacket,
2024-12-18 21:00:09 +01:00
ImprovPacket,
2024-10-30 22:03:13 +01:00
RequestCurrentStateCommand,
RequestDeviceInformationPacket,
2024-10-15 23:48:06 +02:00
};
use improv_setup::serial;
2024-10-15 23:48:06 +02:00
use log::{
debug,
log_enabled,
info,
Level,
};
use tokio_serial;
#[derive(Subcommand, Clone)]
enum DeviceCommands {
2024-12-18 21:42:43 +01:00
/// Request current state
State,
2024-10-15 23:48:06 +02:00
/// Set wifi credentials
SetWifi {
/// SSID of the network
ssid: String,
/// Password for the SSID
password: String,
},
/// Request device info
Info,
2024-10-15 23:48:06 +02:00
}
2024-12-18 21:42:43 +01:00
impl Default for DeviceCommands {
fn default() -> Self {
return Self::State;
}
}
2024-10-15 23:48:06 +02:00
#[derive(Subcommand, Clone)]
enum Commands {
/// List available serial devices
ListDevices,
/// Device
Device {
/// Path to the serial device
path: String,
/// Baud rate used for connecting to the serial device
#[arg(long, default_value_t = 115200)]
baud_rate: u32,
#[command(subcommand)]
device_command: Option<DeviceCommands>,
},
}
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Option<Commands>,
}
fn to_ascii_debug(bytes: &Vec<u8>) -> String {
let mut out = String::new();
for b in bytes {
if b.is_ascii_graphic() {
out += &b.escape_ascii().to_string();
}
else {
out.push_str(".");
}
}
return out;
}
2024-12-21 14:27:34 +01:00
fn to_bytewise_debug(bytes: &Vec<u8>) -> String {
let mut out = String::new();
for b in bytes {
out += &hex::encode(&[b.clone()]);
out += " ";
if b.is_ascii_graphic() {
out += &b.escape_ascii().to_string();
}
out += "\n";
}
return out;
}
2024-10-15 23:48:06 +02:00
#[tokio::main]
async fn main() -> Result<()>{
env_logger::init();
let cli = Cli::parse();
let command: Commands = match &cli.command {
Some(command) => command.clone(),
None => Commands::ListDevices,
};
match &command {
Commands::ListDevices => {
println!("{}", tokio_serial::available_ports()
.unwrap()
.iter()
.map(|serialport| serialport.port_name.clone())
.fold(String::new(), |a, b| a + &b + &String::from("\n")));
},
Commands::Device {path, baud_rate, device_command} => {
2024-12-18 21:42:43 +01:00
match &device_command.clone().unwrap_or_default() {
DeviceCommands::State => {
2024-12-23 15:56:35 +01:00
let request_current_state_packet = RequestCurrentStateCommand {};
2024-10-15 23:48:06 +02:00
let mut serial_interface = serial::SerialInterface::new(path, *baud_rate).expect("Couldn't init serial interface");
2024-10-15 23:48:06 +02:00
2024-12-23 15:56:35 +01:00
serial_interface.send(&request_current_state_packet).expect("Failed to send improv packet");
2024-10-15 23:48:06 +02:00
let result_bytes = serial_interface.recv_bytes().expect("Couldn't receive any improv packet");
let raw_packet = RawPacket::try_from_bytes(&result_bytes).unwrap();
2024-10-15 23:48:06 +02:00
2024-12-18 21:42:43 +01:00
if let ImprovPacket::CurrentStateResponse(current_state_response) = ImprovPacket::try_from_raw_packet(&raw_packet).unwrap() {
println!("Current state: {}", &current_state_response.current_state);
}
2024-10-15 23:48:06 +02:00
2024-12-18 21:42:43 +01:00
if let ImprovPacket::ErrorState(error_state) = ImprovPacket::try_from_raw_packet(&raw_packet).unwrap() {
println!("Error state: {}", &error_state.error_state);
}
},
DeviceCommands::SetWifi {ssid, password} => {
println!("Not implemented");
},
DeviceCommands::Info => {
2024-12-23 15:56:35 +01:00
let request_device_information_packet = RequestDeviceInformationPacket {};
let mut serial_interface = serial::SerialInterface::new(path, *baud_rate).expect("Couldn't init serial interface");
2024-12-23 15:56:35 +01:00
serial_interface.send(&request_device_information_packet).expect("Failed to send improv packet");
let result_bytes = serial_interface.recv_bytes().expect("Couldn't receive any improv packet");
let raw_packet = RawPacket::try_from_bytes(&result_bytes).unwrap();
if let ImprovPacket::RPCResult(rpc_result) = ImprovPacket::try_from_raw_packet(&raw_packet).unwrap() {
2024-12-21 14:27:34 +01:00
for r in rpc_result.results {
println!("{}", &r);
}
}
},
2024-12-18 21:42:43 +01:00
};
2024-12-18 21:20:00 +01:00
2024-10-15 23:48:06 +02:00
},
};
Ok(())
}