use anyhow::Result;
use clap::{Parser, Subcommand, builder::BoolishValueParser};
use lighthouse_manager::{bluetooth, commands};
use tracing::{error, info};
#[derive(Parser)]
#[command(name = "lighthouse-manager")]
#[command(version)]
#[command(about = "Control SteamVR Lighthouse base stations (V1/V2) via Bluetooth LE.", long_about = None)]
struct Cli {
#[arg(short, action = clap::ArgAction::Count)]
verbose: u8,
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
Discover {
#[arg(short, long, default_value_t = 10)]
duration: u64,
},
List {
#[arg(long)]
managed: bool,
#[arg(long)]
json: bool,
},
PowerOn,
PowerOff,
#[command(alias = "blink")]
Identify {
index: usize,
},
SetManaged {
target: String,
#[arg(action = clap::ArgAction::Set, value_parser = BoolishValueParser::new())]
managed: bool,
},
Autostart {
action: String,
},
}
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
let filter = match cli.verbose {
0 => "lighthouse_manager=info",
1 => "lighthouse_manager=debug",
_ => "lighthouse_manager=trace",
};
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new(filter)),
)
.event_format(tracing_subscriber::fmt::format().with_target(false))
.init();
match bluetooth::get_adapter().await {
Ok(_) => info!("Bluetooth adapter ready."),
Err(e) => {
error!("{}", e);
return Err(e);
}
}
let result = match cli.command {
Command::Discover { duration } => commands::discover::run(duration).await,
Command::List { managed, json } => commands::list::run(managed, json),
Command::PowerOn => commands::power::power_on().await,
Command::PowerOff => commands::power::power_off().await,
Command::Identify { index } => commands::identify::run(index).await,
Command::SetManaged { target, managed } => commands::set_managed::run(&target, managed),
Command::Autostart { action } => commands::autostart::run(&action),
};
if let Err(e) = &result {
error!("{}", e);
}
result
}