bcms 0.1.12

Bluetooth Client Manager Service for IoT device management
Documentation
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();
    
    // Initialize logging
    if args.debug {
        tracing_subscriber::fmt::init();
    }
    
    // Parse RPC server address
    let server_addr: SocketAddr = args.rpc_address.parse()
        .map_err(|e| format!("Invalid RPC address '{}': {}", args.rpc_address, e))?;
    
    // Create RPC helper
    let rpc_helper = RpcHelper::new(server_addr);
    
    // Create device info
    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 {
        // Generate realistic blood pressure data
        let systolic = rng.gen_range(90..180);   // Normal range: 90-140 mmHg
        let diastolic = rng.gen_range(60..110);  // Normal range: 60-90 mmHg
        let timestamp = iot_helpers::current_timestamp();
        
        // Create blood pressure data
        let bp_data = iot_helpers::create_blood_pressure_data(
            device.address.clone(),
            systolic,
            diastolic,
            timestamp,
        );
        
        println!("📈 Reading #{}: {}mmHg / {}mmHg (timestamp: {})", 
                 i, systolic, diastolic, timestamp);
        
        // Submit data to BCMS daemon
        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;
            }
        }
        
        // Wait before next reading (except for the last one)
        if i < args.count {
            tokio::time::sleep(tokio::time::Duration::from_millis(args.interval_ms)).await;
        }
    }
    
    // Summary
    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(())
}