Initial boilerplate scaffold for continuum-proxy
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
mod gpio;
|
||||
mod serial;
|
||||
|
||||
pub use gpio::SensorState;
|
||||
|
||||
use thiserror::Error;
|
||||
use tracing::{info, warn};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PlateChangerError {
|
||||
#[error("plate changer hardware not responding")]
|
||||
NotResponding,
|
||||
#[error("sensor validation failed: {0}")]
|
||||
SensorMismatch(String),
|
||||
#[error("serial transport error: {0}")]
|
||||
Serial(#[from] serial::SerialError),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum CycleOutcome {
|
||||
Success,
|
||||
Retried,
|
||||
}
|
||||
|
||||
/// Drives a mechanical plate-swap cycle: signal the changer over serial,
|
||||
/// wait for it to report completion, then cross-check the physical sensors
|
||||
/// (plate-present, bed-clear) before releasing the print queue to continue.
|
||||
pub struct PlateChanger {
|
||||
port: serial::SerialPort,
|
||||
}
|
||||
|
||||
impl PlateChanger {
|
||||
pub fn open(path: &str, baud: u32) -> Result<Self, PlateChangerError> {
|
||||
Ok(Self {
|
||||
port: serial::SerialPort::open(path, baud)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn run_cycle(&mut self, slot: u8) -> Result<CycleOutcome, PlateChangerError> {
|
||||
info!(slot, "starting plate change cycle");
|
||||
|
||||
self.port.send_command(&serial::Command::Eject).await?;
|
||||
self.port.await_ack(std::time::Duration::from_secs(30)).await?;
|
||||
|
||||
self.port.send_command(&serial::Command::LoadSlot(slot)).await?;
|
||||
self.port.await_ack(std::time::Duration::from_secs(30)).await?;
|
||||
|
||||
match self.validate_sensors().await {
|
||||
Ok(()) => Ok(CycleOutcome::Success),
|
||||
Err(err) => {
|
||||
warn!(?err, slot, "sensor validation failed, retrying cycle once");
|
||||
self.port.send_command(&serial::Command::LoadSlot(slot)).await?;
|
||||
self.port.await_ack(std::time::Duration::from_secs(30)).await?;
|
||||
self.validate_sensors().await?;
|
||||
Ok(CycleOutcome::Retried)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn validate_sensors(&mut self) -> Result<(), PlateChangerError> {
|
||||
let state = gpio::read_sensor_state().await;
|
||||
if !state.plate_present {
|
||||
return Err(PlateChangerError::SensorMismatch("plate not detected on bed".into()));
|
||||
}
|
||||
if !state.bed_clear {
|
||||
return Err(PlateChangerError::SensorMismatch("bed obstruction detected".into()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user