feat: check printer storage status before sending

This commit is contained in:
Ian Chua
2026-09-09 18:35:38 +08:00
parent 62791fabfa
commit b0b78c296c
+43 -15
View File
@@ -5,6 +5,7 @@
#include "NetworkAgentFactory.hpp" #include "NetworkAgentFactory.hpp"
#include "OrcaCloudServiceAgent.hpp" #include "OrcaCloudServiceAgent.hpp"
#include "bambu_networking.hpp" #include "bambu_networking.hpp"
#include "json_diff.hpp"
#include <algorithm> #include <algorithm>
#include <atomic> #include <atomic>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
@@ -145,11 +146,8 @@ std::string extract_line_value(const std::string& body, const std::string& key)
// Manual binding uses the OrcaSonar landing page as its sole identity source. // Manual binding uses the OrcaSonar landing page as its sole identity source.
// The page returns device_id and may return device_name/model_id. // The page returns device_id and may return device_name/model_id.
bool probe_orcasonar_landing_page(const std::string& host, bool probe_orcasonar_landing_page(
const std::string& port, const std::string& host, const std::string& port, std::string& device_id, std::string& device_name, std::string& model_id)
std::string& device_id,
std::string& device_name,
std::string& model_id)
{ {
device_name = ORCASONAR_FALLBACK; device_name = ORCASONAR_FALLBACK;
model_id = ORCASONAR_FALLBACK; model_id = ORCASONAR_FALLBACK;
@@ -173,10 +171,7 @@ bool probe_orcasonar_landing_page(const std::string& host,
// SSDP discovery uses the LOCATION URL's UPnP device description as its sole // SSDP discovery uses the LOCATION URL's UPnP device description as its sole
// identity source. OrcaSonar maps device_id/device_name/model_id to UDN, // identity source. OrcaSonar maps device_id/device_name/model_id to UDN,
// friendlyName, and modelNumber respectively. // friendlyName, and modelNumber respectively.
bool parse_orcasonar_device_xml(const std::string& body, bool parse_orcasonar_device_xml(const std::string& body, std::string& device_id, std::string& device_name, std::string& model_id)
std::string& device_id,
std::string& device_name,
std::string& model_id)
{ {
device_name = ORCASONAR_FALLBACK; device_name = ORCASONAR_FALLBACK;
model_id = ORCASONAR_FALLBACK; model_id = ORCASONAR_FALLBACK;
@@ -218,10 +213,7 @@ bool parse_orcasonar_device_xml(const std::string& body,
} }
} }
bool probe_orcasonar_device_xml(const std::string& location, bool probe_orcasonar_device_xml(const std::string& location, std::string& device_id, std::string& device_name, std::string& model_id)
std::string& device_id,
std::string& device_name,
std::string& model_id)
{ {
std::string body; std::string body;
return fetch_orcasonar_body(location, body) && parse_orcasonar_device_xml(body, device_id, device_name, model_id); return fetch_orcasonar_body(location, body) && parse_orcasonar_device_xml(body, device_id, device_name, model_id);
@@ -639,8 +631,7 @@ void OrcaPrinterAgent::set_cloud_agent(std::shared_ptr<ICloudServiceAgent> cloud
BOOST_LOG_TRIVIAL(info) << "OrcaPrinterAgent::set_cloud_agent: status callback result=" << callback_result; BOOST_LOG_TRIVIAL(info) << "OrcaPrinterAgent::set_cloud_agent: status callback result=" << callback_result;
} }
std::unique_ptr<ICameraSignalingChannel> std::unique_ptr<ICameraSignalingChannel> OrcaPrinterAgent::create_camera_signaling_channel(const std::string& dev_id)
OrcaPrinterAgent::create_camera_signaling_channel(const std::string& dev_id)
{ {
std::lock_guard<std::mutex> lock(state_mutex); std::lock_guard<std::mutex> lock(state_mutex);
if (!m_cloud_agent) if (!m_cloud_agent)
@@ -1391,6 +1382,43 @@ int OrcaPrinterAgent::start_send_gcode_to_sdcard(PrintParams params,
std::string http_error; std::string http_error;
std::string response_body; std::string response_body;
// check if printer has enough storage
Http::get(origin + "/server/files/directory?path=gcodes")
.on_complete([&](std::string body, unsigned status) {
if (body.empty()) {
http_status = 400;
http_error = "Failed to get gcodes directory.";
}
int free = 0;
nlohmann::json json = nlohmann::json::parse(body);
if (json.contains("result")) {
json = json["result"];
if (json.contains("disk_usage")) {
json = json["disk_usage"];
if (json.contains("free"))
free = json["free"].get<int>();
}
}
if (free < file_size) {
http_status = 507;
http_error = "Not enough storage on the printer.";
}
})
.on_error([&](std::string body, std::string err, unsigned status) {
http_status = status;
http_error = std::move(err);
response_body = std::move(body);
})
.perform_sync();
if (http_status >= 400) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << " failed with error code: " << http_status << ", " << http_error;
return BAMBU_NETWORK_ERR_PRINT_SG_UPLOAD_FTP_FAILED;
}
auto http = Http::post(origin + "/server/files/upload"); auto http = Http::post(origin + "/server/files/upload");
if (!params.password.empty()) if (!params.password.empty())
http.header("X-Api-Key", params.password); // trusted LAN facades may not require it; harmless when they do not http.header("X-Api-Key", params.password); // trusted LAN facades may not require it; harmless when they do not