Add BambuPrinter::get_version, the first real request/response round trip

Documents request()'s real constraint on BambuMqttSession directly (not
all Bambu commands map 1:1 to a reply, and even where one exists its
shape can differ by protocol version - e.g. pushing.pushall triggers an
ongoing print.push_status stream rather than a direct reply, and
print.calibration data lives inside push_status on BambuMQTT v1 but gets
its own report on v2 - so request() is only correct for genuinely
one-shot, sequence_id-correlated commands like info.get_version).

get_version itself is Bambu-only (no GenericPrinter equivalent, matching
test_tls_handshake/fetch_certificate/ensure_trusted's existing pattern):
builds the request via continuum-schema-instance, sends it through
BambuMqttSession::request, and parses the reply into the existing
hand-written GetVersionResponse - reusing the struct already validated
against real captured Bambu JSON in bambu_commands_demo.rs, rather than
introducing a second response representation.

Verified structurally (no real broker reachable from here - confirmed
this sandbox has no route into the printer's LAN at all, not just a
blocked port): connect fails gracefully against an unreachable host, and
get_version correctly reports "not connected" rather than panicking when
called without a live session.
This commit is contained in:
2026-09-05 21:27:59 +00:00
parent 9643c8b685
commit 416ef6db07
2 changed files with 48 additions and 0 deletions
+27
View File
@@ -343,6 +343,33 @@ impl BambuPrinter {
Err(err) => Err(err),
}
}
/// Bambu-only - no `GenericPrinter` equivalent, since every vendor's
/// way of reporting firmware info (if it has one at all) is shaped
/// completely differently. Same "vendor-only extension" pattern as
/// `test_tls_handshake`/`fetch_certificate`/`ensure_trusted` above:
/// reached by matching `PrinterHandle::Bambu` back out of the enum,
/// not through the shared trait.
///
/// The first real use of `BambuMqttSession::request` -
/// `info.get_version` is a genuine one-shot, `sequence_id`-correlated
/// reply (unlike `pushing.pushall`, see `request`'s doc comment), so
/// this is exactly the case it's for.
pub async fn get_version(&self) -> Result<super::GetVersionResponse, PrinterError> {
let (session, version) =
self.connection.as_ref().ok_or_else(|| PrinterError(format!("{} is not connected", self.base.name)))?;
let body = continuum_schema_instance::build_instance_from_file(&get_schema_for_command(
*version,
"info".into(),
"get_version".into(),
))
.map_err(|err| PrinterError(format!("failed to build get_version request: {err}")))?;
let response = session.request("info", body).await?;
serde_json::from_value(response)
.map_err(|err| PrinterError(format!("failed to parse get_version response: {err}")))
}
}
impl GenericPrinter for BambuPrinter {