use bcms::{RpcHelper, RpcDeviceInfo, iot_helpers};
use clap::Parser;
use rand::Rng;
use std::net::SocketAddr;
#[derive(Parser, Debug)]
#[command(name = "rpc-example")]
#[command(about = "Example CLI for submitting IoT data via BCMS RPC")]
struct Args {
#[arg(long, help = "Device MAC address (e.g., AA:BB:CC:DD:EE:FF)")]
device_address: String,
#[arg(long, help = "Human-readable device name")]
device_name: String,
#[arg(long, help = "Device connection type (e.g., bluetooth_le, wifi, cellular, usb)")]
connection_type: String,
#[arg(long, default_value = "127.0.0.1:4567", help = "BCMS daemon RPC address")]
rpc_address: String,
#[arg(long, default_value = "1", help = "Number of blood pressure readings to generate")]
count: usize,
#[arg(long, default_value = "1000", help = "Interval between readings in milliseconds")]
interval_ms: u64,
#[arg(long, help = "Enable debug output")]
debug: bool,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
if args.debug {
tracing_subscriber::fmt::init();
}
let server_addr: SocketAddr = args.rpc_address.parse()
.map_err(|e| format!("Invalid RPC address '{}': {}", args.rpc_address, e))?;
let rpc_helper = RpcHelper::new(server_addr);
let device = RpcDeviceInfo::new(
args.device_address.clone(),
args.device_name.clone(),
args.connection_type.clone(),
);
println!("🩺 BCMS RPC IoT Data Submission Example");
println!("📍 Device: {} ({}) - Type: {}", device.name, device.address, device.connection_type);
println!("🔗 RPC Server: {}", server_addr);
println!("📊 Generating {} blood pressure reading(s)...\n", args.count);
let mut rng = rand::thread_rng();
let mut successful_submissions = 0;
let mut failed_submissions = 0;
for i in 1..=args.count {
let systolic = rng.gen_range(90..180); let diastolic = rng.gen_range(60..110); let timestamp = iot_helpers::current_timestamp();
let bp_data = iot_helpers::create_blood_pressure_data(
device.address.clone(),
systolic,
diastolic,
timestamp,
);
println!("📈 Reading #{}: {}mmHg / {}mmHg (timestamp: {})",
i, systolic, diastolic, timestamp);
match rpc_helper.submit_single_data(device.clone(), bp_data).await {
Ok((true, _)) => {
println!("✅ Successfully submitted reading #{}", i);
successful_submissions += 1;
}
Ok((false, errors)) => {
println!("❌ Failed to submit reading #{}: {:?}", i, errors);
failed_submissions += 1;
}
Err(e) => {
println!("🔥 RPC error for reading #{}: {}", i, e);
failed_submissions += 1;
}
}
if i < args.count {
tokio::time::sleep(tokio::time::Duration::from_millis(args.interval_ms)).await;
}
}
println!("\n📋 Submission Summary:");
println!("✅ Successful: {}", successful_submissions);
println!("❌ Failed: {}", failed_submissions);
println!("📊 Total: {}", args.count);
if successful_submissions > 0 {
println!("\n🎉 Data will be automatically synced to the backend every 3 seconds!");
println!("🔍 Check the BCMS daemon logs to see backend submission status.");
}
if failed_submissions > 0 {
println!("\n⚠️ Some submissions failed. Make sure:");
println!(" - BCMS daemon is running (bcms-daemon)");
println!(" - RPC address is correct ({})", server_addr);
println!(" - Network connectivity is available");
std::process::exit(1);
}
Ok(())
}