use std::time::Duration; use serde::{Deserialize, Serialize}; use tracing::{debug, info}; #[derive(Debug, Clone, Serialize, Deserialize)] pub enum PrinterVendor { Bambu, Prusa, Klipper, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DiscoveredPrinter { pub vendor: PrinterVendor, pub host: String, pub serial: Option, } /// Periodically sweeps the LAN for printers (SSDP for Bambu, mDNS for /// PrusaLink/Moonraker) and reports newly-seen devices upstream. /// /// This is intentionally a stub: production discovery would bind a UDP /// multicast socket per protocol. It's structured so each protocol's probe /// can be dropped in independently without touching the polling loop. pub async fn run(interval: Duration, tx: tokio::sync::mpsc::Sender) { let mut ticker = tokio::time::interval(interval); loop { ticker.tick().await; debug!("running LAN discovery sweep"); for printer in sweep().await { info!(host = %printer.host, ?printer.vendor, "discovered printer"); if tx.send(printer).await.is_err() { return; } } } } async fn sweep() -> Vec { // TODO: SSDP probe (Bambu), mDNS `_prusalink._tcp` / `_moonraker._tcp` probes. Vec::new() }