feat(printer): add direct thermal backend and debug controls
This commit is contained in:
@@ -22,6 +22,7 @@ esp_err_t rest_server_print_submit_raster_job_and_reply(httpd_req_t *req,
|
||||
uint16_t width,
|
||||
uint16_t height,
|
||||
const char *density,
|
||||
bool direct_ignore_precheck,
|
||||
const char *warning,
|
||||
const char *trace_id);
|
||||
|
||||
|
||||
@@ -53,12 +53,31 @@ static const char *s_web_index =
|
||||
"\n"
|
||||
" <label>Printer Name</label>\n"
|
||||
" <input id='printerName' type='text' value='TQPrinter'>\n"
|
||||
" <label>Printer Backend</label>\n"
|
||||
" <select id='printerBackend' style='max-width:220px'>\n"
|
||||
" <option value='direct' selected>Direct (GPIO)</option>\n"
|
||||
" <option value='ble'>BLE</option>\n"
|
||||
" </select>\n"
|
||||
" <div class='row'>\n"
|
||||
" <button id='btnConnect'>Connect Printer</button>\n"
|
||||
" <button id='btnAutoConnect' class='alt'>Auto Connect</button>\n"
|
||||
" <button id='btnDisconnect' class='warn'>Disconnect</button>\n"
|
||||
" </div>\n"
|
||||
"\n"
|
||||
" <label>Paper Detect</label>\n"
|
||||
" <div class='row'>\n"
|
||||
" <button id='btnPaperCheck' class='alt'>Check Paper</button>\n"
|
||||
" </div>\n"
|
||||
" <div id='paperState' class='small'>纸张状态:未知</div>\n"
|
||||
" <div id='paperMeta' class='small'>Backend: -, Connected: -, Transport: -, GPIO: -, Expect: -</div>\n"
|
||||
" <div class='row'>\n"
|
||||
" <label style='margin:0;display:flex;align-items:center;gap:6px;'>\n"
|
||||
" <input id='ignorePrecheck' type='checkbox' style='width:auto;'>\n"
|
||||
" Ignore direct precheck (paper/temp/battery)\n"
|
||||
" </label>\n"
|
||||
" </div>\n"
|
||||
" <div class='small'>Only effective on Direct backend. Use for sensor bring-up/debug.</div>\n"
|
||||
"\n"
|
||||
" <label>Text to Print</label>\n"
|
||||
" <textarea id='printText'>Hello from ESP32-S3!\nOrder: A1024\nThank you</textarea>\n"
|
||||
" <div class='row'>\n"
|
||||
@@ -121,6 +140,10 @@ static const char *s_web_index =
|
||||
" const out = document.getElementById('out');\n"
|
||||
" const apiKeyEl = document.getElementById('apiKey');\n"
|
||||
" const printerNameEl = document.getElementById('printerName');\n"
|
||||
" const printerBackendEl = document.getElementById('printerBackend');\n"
|
||||
" const paperStateEl = document.getElementById('paperState');\n"
|
||||
" const paperMetaEl = document.getElementById('paperMeta');\n"
|
||||
" const ignorePrecheckEl = document.getElementById('ignorePrecheck');\n"
|
||||
" const printTextEl = document.getElementById('printText');\n"
|
||||
" const imagePromptEl = document.getElementById('imagePrompt');\n"
|
||||
" const imgSizeEl = document.getElementById('imgSize');\n"
|
||||
@@ -168,6 +191,46 @@ static const char *s_web_index =
|
||||
" return new Promise((resolve) => setTimeout(resolve, ms));\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" function selectedPrinterBackend() {\n"
|
||||
" const v = (printerBackendEl && printerBackendEl.value) ? String(printerBackendEl.value).toLowerCase() : 'ble';\n"
|
||||
" return v === 'direct' ? 'direct' : 'ble';\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" function selectedIgnorePrecheck() {\n"
|
||||
" return !!(ignorePrecheckEl && ignorePrecheckEl.checked);\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" function syncPaperUi(st) {\n"
|
||||
" if (!paperStateEl || !paperMetaEl) {\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
" if (!st || typeof st !== 'object') {\n"
|
||||
" paperStateEl.textContent = '纸张状态:未知';\n"
|
||||
" paperMetaEl.textContent = 'Backend: -, Connected: -, Transport: -, GPIO: -, Expect: -';\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" const hasPaper = !!st.has_paper;\n"
|
||||
" paperStateEl.textContent = hasPaper ? '纸张状态:有纸' : '纸张状态:缺纸';\n"
|
||||
"\n"
|
||||
" const backend = st.printer_backend ? String(st.printer_backend) : '-';\n"
|
||||
" const connected = !!st.printer_connected;\n"
|
||||
" const transportReady = !!st.printer_transport_ready;\n"
|
||||
" const paperLevel = (st.paper_gpio_level === undefined || st.paper_gpio_level === null) ? '-' : String(st.paper_gpio_level);\n"
|
||||
" const paperExpect = (st.paper_present_level === undefined || st.paper_present_level === null) ? '-' : String(st.paper_present_level);\n"
|
||||
" paperMetaEl.textContent = 'Backend: ' + backend + ', Connected: ' + connected + ', Transport: ' + transportReady + ', GPIO: ' + paperLevel + ', Expect: ' + paperExpect;\n"
|
||||
"\n"
|
||||
" if (printerBackendEl && (backend === 'ble' || backend === 'direct')) {\n"
|
||||
" printerBackendEl.value = backend;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" async function fetchPrinterStatus() {\n"
|
||||
" const st = await callApi('/v1/printer/status', 'GET');\n"
|
||||
" syncPaperUi(st);\n"
|
||||
" return st;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" function voiceRoundBusy(st) {\n"
|
||||
" if (!st) return false;\n"
|
||||
" const state = (st.voice_dialog_state || '').toLowerCase();\n"
|
||||
@@ -363,6 +426,7 @@ static const char *s_web_index =
|
||||
" threshold: toInt(imgThresholdEl.value, 160, 0, 255),\n"
|
||||
" max_height: toInt(imgMaxHeightEl.value, 2200, 64, 3000),\n"
|
||||
" density: imgDensityEl.value || '中等',\n"
|
||||
" ignore_precheck: selectedIgnorePrecheck(),\n"
|
||||
" scale_to_width: imgScaleToWidthEl.checked,\n"
|
||||
" invert: imgInvertEl.checked,\n"
|
||||
" timeout_ms: toInt(imgTimeoutEl.value, 45000, 5000, 180000),\n"
|
||||
@@ -393,24 +457,41 @@ static const char *s_web_index =
|
||||
" }\n"
|
||||
"\n"
|
||||
" document.getElementById('btnHealth').onclick = () => run(() => callApi('/v1/health', 'GET'));\n"
|
||||
" document.getElementById('btnStatus').onclick = () => run(() => callApi('/v1/printer/status', 'GET'));\n"
|
||||
" document.getElementById('btnStatus').onclick = () => run(() => fetchPrinterStatus());\n"
|
||||
" document.getElementById('btnJobs').onclick = () => run(() => callApi('/v1/jobs', 'GET'));\n"
|
||||
"\n"
|
||||
" document.getElementById('btnConnect').onclick = () => run(() => callApi('/v1/printer/connect', 'POST', {\n"
|
||||
" name: printerNameEl.value.trim() || 'TQPrinter',\n"
|
||||
" timeout_ms: 15000\n"
|
||||
" }));\n"
|
||||
" document.getElementById('btnConnect').onclick = () => run(async () => {\n"
|
||||
" const data = await callApi('/v1/printer/connect', 'POST', {\n"
|
||||
" backend: selectedPrinterBackend(),\n"
|
||||
" name: printerNameEl.value.trim() || 'TQPrinter',\n"
|
||||
" timeout_ms: 15000\n"
|
||||
" });\n"
|
||||
" syncPaperUi(data);\n"
|
||||
" return data;\n"
|
||||
" });\n"
|
||||
"\n"
|
||||
" document.getElementById('btnAutoConnect').onclick = () => run(() => callApi('/v1/printer/connect', 'POST', {\n"
|
||||
" name: '*',\n"
|
||||
" timeout_ms: 20000\n"
|
||||
" }));\n"
|
||||
" document.getElementById('btnAutoConnect').onclick = () => run(async () => {\n"
|
||||
" const data = await callApi('/v1/printer/connect', 'POST', {\n"
|
||||
" backend: selectedPrinterBackend(),\n"
|
||||
" name: '*',\n"
|
||||
" timeout_ms: 20000\n"
|
||||
" });\n"
|
||||
" syncPaperUi(data);\n"
|
||||
" return data;\n"
|
||||
" });\n"
|
||||
"\n"
|
||||
" document.getElementById('btnDisconnect').onclick = () => run(() => callApi('/v1/printer/disconnect', 'POST', {}));\n"
|
||||
" document.getElementById('btnDisconnect').onclick = () => run(async () => {\n"
|
||||
" const data = await callApi('/v1/printer/disconnect', 'POST', {});\n"
|
||||
" try { await fetchPrinterStatus(); } catch (_) {}\n"
|
||||
" return data;\n"
|
||||
" });\n"
|
||||
"\n"
|
||||
" document.getElementById('btnPaperCheck').onclick = () => run(() => fetchPrinterStatus());\n"
|
||||
"\n"
|
||||
" document.getElementById('btnPrintText').onclick = () => run(() => callApi('/v1/print/text', 'POST', {\n"
|
||||
" text: printTextEl.value,\n"
|
||||
" density: '中等',\n"
|
||||
" ignore_precheck: selectedIgnorePrecheck(),\n"
|
||||
" scale: 2,\n"
|
||||
" line_spacing: 2,\n"
|
||||
" max_height: 1800\n"
|
||||
@@ -447,6 +528,9 @@ static const char *s_web_index =
|
||||
" setVoiceTalkButtonState(false);\n"
|
||||
" (async () => {\n"
|
||||
" try {\n"
|
||||
" await fetchPrinterStatus();\n"
|
||||
" } catch (_) {}\n"
|
||||
" try {\n"
|
||||
" await refreshVoiceStatus();\n"
|
||||
" } catch (_) {}\n"
|
||||
" })();\n"
|
||||
|
||||
@@ -2,11 +2,42 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "control_plane.h"
|
||||
#include "domain.h"
|
||||
|
||||
static const char *printer_backend_str(printer_backend_t backend) {
|
||||
switch (backend) {
|
||||
case PRINTER_BACKEND_BLE:
|
||||
return "ble";
|
||||
case PRINTER_BACKEND_DIRECT:
|
||||
return "direct";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static bool parse_printer_backend(const cJSON *json, printer_backend_t *out_backend) {
|
||||
if (json == NULL || out_backend == NULL) {
|
||||
return false;
|
||||
}
|
||||
cJSON *jbackend = cJSON_GetObjectItemCaseSensitive((cJSON *)json, "backend");
|
||||
if (!cJSON_IsString(jbackend) || jbackend->valuestring == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (strcasecmp(jbackend->valuestring, "ble") == 0) {
|
||||
*out_backend = PRINTER_BACKEND_BLE;
|
||||
return true;
|
||||
}
|
||||
if (strcasecmp(jbackend->valuestring, "direct") == 0) {
|
||||
*out_backend = PRINTER_BACKEND_DIRECT;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void fill_runtime_diag_json(cJSON *root) {
|
||||
runtime_diag_snapshot_t snapshot = {0};
|
||||
runtime_diag_get_snapshot(&snapshot);
|
||||
@@ -54,12 +85,20 @@ static void fill_runtime_json(cJSON *root) {
|
||||
cJSON_AddStringToObject(root, "wifi_mode", "sta");
|
||||
cJSON_AddStringToObject(root, "ip", ip);
|
||||
|
||||
cJSON_AddBoolToObject(root, "ble_connected", st.connected);
|
||||
cJSON_AddBoolToObject(root, "ble_notify_ready", st.notify_ready);
|
||||
cJSON_AddStringToObject(root, "printer_backend", printer_backend_str(st.backend));
|
||||
cJSON_AddBoolToObject(root, "printer_connected", st.connected);
|
||||
cJSON_AddBoolToObject(root, "printer_transport_ready", st.transport_ready);
|
||||
cJSON_AddBoolToObject(root, "ble_connected", st.backend == PRINTER_BACKEND_BLE && st.connected);
|
||||
cJSON_AddBoolToObject(root, "ble_notify_ready", st.backend == PRINTER_BACKEND_BLE && st.notify_ready);
|
||||
cJSON_AddBoolToObject(root, "printer_busy", st.busy);
|
||||
cJSON_AddBoolToObject(root, "has_paper", st.has_paper);
|
||||
cJSON_AddNumberToObject(root, "paper_gpio_level", st.paper_gpio_level);
|
||||
cJSON_AddNumberToObject(root, "paper_present_level", st.paper_present_level);
|
||||
cJSON_AddNumberToObject(root, "battery_percent", st.battery_percent);
|
||||
cJSON_AddNumberToObject(root, "temperature", st.temperature);
|
||||
cJSON_AddBoolToObject(root, "supports_gap_move", st.supports_gap_move);
|
||||
cJSON_AddBoolToObject(root, "supports_label_offset", st.supports_label_offset);
|
||||
cJSON_AddBoolToObject(root, "supports_ota", st.supports_ota);
|
||||
cJSON_AddNumberToObject(root, "queue_depth", st.queue_depth);
|
||||
cJSON_AddNumberToObject(root, "mtu", st.mtu);
|
||||
cJSON_AddNumberToObject(root, "last_status_ms", (double)st.last_status_ms);
|
||||
@@ -117,6 +156,8 @@ esp_err_t rest_server_connect_post(httpd_req_t *req) {
|
||||
char *body = NULL;
|
||||
char name[32] = "TQPrinter";
|
||||
uint32_t timeout_ms = runtime_policy_rest_printer_connect_timeout_ms();
|
||||
printer_backend_t backend = printer_protocol_get_backend();
|
||||
bool backend_specified = false;
|
||||
|
||||
if (req->content_len > 0) {
|
||||
esp_err_t body_err = rest_server_read_body(req, &body);
|
||||
@@ -140,21 +181,53 @@ esp_err_t rest_server_connect_post(httpd_req_t *req) {
|
||||
timeout_ms = (uint32_t)jtimeout->valuedouble;
|
||||
}
|
||||
|
||||
cJSON *jbackend = cJSON_GetObjectItemCaseSensitive(json, "backend");
|
||||
if (jbackend != NULL) {
|
||||
backend_specified = true;
|
||||
if (!parse_printer_backend(json, &backend)) {
|
||||
cJSON_Delete(json);
|
||||
free(body);
|
||||
return rest_server_send_error(req, "400 Bad Request", "backend must be ble or direct");
|
||||
}
|
||||
}
|
||||
|
||||
cJSON_Delete(json);
|
||||
free(body);
|
||||
}
|
||||
|
||||
esp_err_t err = printer_protocol_connect(name, timeout_ms);
|
||||
printer_connect_options_t opt = {
|
||||
.backend = backend,
|
||||
.name = backend == PRINTER_BACKEND_BLE ? name : NULL,
|
||||
.timeout_ms = timeout_ms,
|
||||
};
|
||||
char connect_err[96] = {0};
|
||||
esp_err_t err = printer_protocol_connect_ex(&opt, connect_err, sizeof(connect_err));
|
||||
if (err != ESP_OK) {
|
||||
if (err == ESP_ERR_TIMEOUT) {
|
||||
return rest_server_send_error(req, "504 Gateway Timeout", "connect timeout");
|
||||
return rest_server_send_error(req,
|
||||
"504 Gateway Timeout",
|
||||
connect_err[0] != '\0' ? connect_err : "connect timeout");
|
||||
}
|
||||
return rest_server_send_error(req, "500 Internal Server Error", "connect failed");
|
||||
if (err == ESP_ERR_NOT_SUPPORTED || err == ESP_ERR_INVALID_STATE) {
|
||||
return rest_server_send_error(req,
|
||||
"409 Conflict",
|
||||
connect_err[0] != '\0' ? connect_err : "connect failed");
|
||||
}
|
||||
if (err == ESP_ERR_INVALID_ARG) {
|
||||
return rest_server_send_error(req,
|
||||
"400 Bad Request",
|
||||
connect_err[0] != '\0' ? connect_err : "invalid connect params");
|
||||
}
|
||||
return rest_server_send_error(req,
|
||||
"500 Internal Server Error",
|
||||
connect_err[0] != '\0' ? connect_err : "connect failed");
|
||||
}
|
||||
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
cJSON_AddBoolToObject(root, "ok", true);
|
||||
cJSON_AddStringToObject(root, "message", "connected");
|
||||
cJSON_AddStringToObject(root, "backend", printer_backend_str(backend));
|
||||
cJSON_AddBoolToObject(root, "backend_specified", backend_specified);
|
||||
fill_runtime_json(root);
|
||||
|
||||
err = rest_server_send_json(req, "200 OK", root);
|
||||
|
||||
@@ -18,27 +18,33 @@ esp_err_t rest_server_print_submit_raster_job_and_reply(httpd_req_t *req,
|
||||
uint16_t width,
|
||||
uint16_t height,
|
||||
const char *density,
|
||||
bool direct_ignore_precheck,
|
||||
const char *warning,
|
||||
const char *trace_id) {
|
||||
const char *trace = trace_id_or_default(trace_id);
|
||||
ESP_LOGI(TAG,
|
||||
"print submit start, trace=%s, raster_bytes=%u, size=%ux%u, density=%s",
|
||||
"print submit start, trace=%s, raster_bytes=%u, size=%ux%u, density=%s, ignore_precheck=%d",
|
||||
trace,
|
||||
(unsigned)raw_len,
|
||||
(unsigned)width,
|
||||
(unsigned)height,
|
||||
density != NULL ? density : "中等");
|
||||
density != NULL ? density : "中等",
|
||||
direct_ignore_precheck);
|
||||
|
||||
char submit_err[128] = {0};
|
||||
uint32_t job_id = 0;
|
||||
esp_err_t submit_rc = printer_protocol_submit_raster_job(raw,
|
||||
raw_len,
|
||||
width,
|
||||
height,
|
||||
density,
|
||||
&job_id,
|
||||
submit_err,
|
||||
sizeof(submit_err));
|
||||
printer_print_options_t options = {
|
||||
.direct_ignore_precheck = direct_ignore_precheck,
|
||||
};
|
||||
esp_err_t submit_rc = printer_protocol_submit_raster_job_ex(raw,
|
||||
raw_len,
|
||||
width,
|
||||
height,
|
||||
density,
|
||||
&options,
|
||||
&job_id,
|
||||
submit_err,
|
||||
sizeof(submit_err));
|
||||
if (submit_rc != ESP_OK) {
|
||||
ESP_LOGW(TAG,
|
||||
"print submit failed, trace=%s, rc=0x%x, msg=%s",
|
||||
@@ -56,6 +62,7 @@ esp_err_t rest_server_print_submit_raster_job_and_reply(httpd_req_t *req,
|
||||
cJSON_AddBoolToObject(root, "ok", true);
|
||||
cJSON_AddNumberToObject(root, "job_id", job_id);
|
||||
cJSON_AddStringToObject(root, "state", "queued");
|
||||
cJSON_AddBoolToObject(root, "ignore_precheck", direct_ignore_precheck);
|
||||
if (warning != NULL && warning[0] != '\0') {
|
||||
cJSON_AddStringToObject(root, "warning", warning);
|
||||
}
|
||||
@@ -87,6 +94,7 @@ esp_err_t rest_server_print_raster_post(httpd_req_t *req) {
|
||||
cJSON *jencoding = cJSON_GetObjectItemCaseSensitive(json, "encoding");
|
||||
cJSON *jdata = cJSON_GetObjectItemCaseSensitive(json, "data");
|
||||
cJSON *jdensity = cJSON_GetObjectItemCaseSensitive(json, "density");
|
||||
cJSON *jignore = cJSON_GetObjectItemCaseSensitive(json, "ignore_precheck");
|
||||
|
||||
if (!cJSON_IsNumber(jwidth) || !cJSON_IsNumber(jheight) ||
|
||||
!cJSON_IsString(jencoding) || !cJSON_IsString(jdata)) {
|
||||
@@ -102,6 +110,7 @@ esp_err_t rest_server_print_raster_post(httpd_req_t *req) {
|
||||
const char *density = (cJSON_IsString(jdensity) && jdensity->valuestring != NULL)
|
||||
? jdensity->valuestring
|
||||
: "中等";
|
||||
bool direct_ignore_precheck = rest_server_json_bool_with_default(jignore, false);
|
||||
|
||||
uint8_t *raw = NULL;
|
||||
size_t raw_len = 0;
|
||||
@@ -117,6 +126,7 @@ esp_err_t rest_server_print_raster_post(httpd_req_t *req) {
|
||||
(uint16_t)jwidth->valuedouble,
|
||||
(uint16_t)jheight->valuedouble,
|
||||
density,
|
||||
direct_ignore_precheck,
|
||||
NULL,
|
||||
NULL);
|
||||
free(raw);
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct {
|
||||
bool invert;
|
||||
uint16_t max_height;
|
||||
const char *density;
|
||||
bool direct_ignore_precheck;
|
||||
} image_print_options_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -68,7 +69,8 @@ static void parse_image_upload_options(httpd_req_t *req,
|
||||
uint8_t *out_threshold,
|
||||
bool *out_invert,
|
||||
uint16_t *out_max_height,
|
||||
const char **out_density) {
|
||||
const char **out_density,
|
||||
bool *out_direct_ignore_precheck) {
|
||||
if (out_scale_to_width != NULL) {
|
||||
*out_scale_to_width = true;
|
||||
}
|
||||
@@ -84,6 +86,9 @@ static void parse_image_upload_options(httpd_req_t *req,
|
||||
if (out_density != NULL) {
|
||||
*out_density = "中等";
|
||||
}
|
||||
if (out_direct_ignore_precheck != NULL) {
|
||||
*out_direct_ignore_precheck = false;
|
||||
}
|
||||
|
||||
if (req == NULL) {
|
||||
return;
|
||||
@@ -138,6 +143,14 @@ static void parse_image_upload_options(httpd_req_t *req,
|
||||
*out_density = map_density_text(value);
|
||||
}
|
||||
|
||||
if (httpd_query_key_value(query, "ignore_precheck", value, sizeof(value)) == ESP_OK &&
|
||||
out_direct_ignore_precheck != NULL) {
|
||||
bool parsed = *out_direct_ignore_precheck;
|
||||
if (parse_bool_text(value, &parsed)) {
|
||||
*out_direct_ignore_precheck = parsed;
|
||||
}
|
||||
}
|
||||
|
||||
free(query);
|
||||
}
|
||||
|
||||
@@ -150,6 +163,7 @@ static void image_print_options_set_defaults(image_print_options_t *out) {
|
||||
out->invert = false;
|
||||
out->max_height = 2200;
|
||||
out->density = "中等";
|
||||
out->direct_ignore_precheck = false;
|
||||
}
|
||||
|
||||
static void parse_image_print_options_from_json(cJSON *json, image_print_options_t *out) {
|
||||
@@ -162,6 +176,7 @@ static void parse_image_print_options_from_json(cJSON *json, image_print_options
|
||||
cJSON *jinvert = cJSON_GetObjectItemCaseSensitive(json, "invert");
|
||||
cJSON *jmaxh = cJSON_GetObjectItemCaseSensitive(json, "max_height");
|
||||
cJSON *jdensity = cJSON_GetObjectItemCaseSensitive(json, "density");
|
||||
cJSON *jignore = cJSON_GetObjectItemCaseSensitive(json, "ignore_precheck");
|
||||
|
||||
out->scale_to_width = rest_server_json_bool_with_default(jscale, out->scale_to_width);
|
||||
out->invert = rest_server_json_bool_with_default(jinvert, out->invert);
|
||||
@@ -174,6 +189,7 @@ static void parse_image_print_options_from_json(cJSON *json, image_print_options
|
||||
if (cJSON_IsString(jdensity) && jdensity->valuestring != NULL) {
|
||||
out->density = map_density_text(jdensity->valuestring);
|
||||
}
|
||||
out->direct_ignore_precheck = rest_server_json_bool_with_default(jignore, out->direct_ignore_precheck);
|
||||
}
|
||||
|
||||
static bool parse_image_size_text(const char *text, uint32_t *out_w, uint32_t *out_h) {
|
||||
@@ -345,21 +361,24 @@ static esp_err_t rest_server_print_image_binary(httpd_req_t *req) {
|
||||
bool invert = false;
|
||||
uint16_t max_height = 2200;
|
||||
const char *density = "中等";
|
||||
bool direct_ignore_precheck = false;
|
||||
parse_image_upload_options(req,
|
||||
&scale_to_width,
|
||||
&threshold,
|
||||
&invert,
|
||||
&max_height,
|
||||
&density);
|
||||
&density,
|
||||
&direct_ignore_precheck);
|
||||
|
||||
ESP_LOGI(TAG,
|
||||
"image process start (upload), png_bytes=%u, scale_to_width=%d, threshold=%u, invert=%d, max_height=%u, density=%s",
|
||||
"image process start (upload), png_bytes=%u, scale_to_width=%d, threshold=%u, invert=%d, max_height=%u, density=%s, ignore_precheck=%d",
|
||||
(unsigned)req->content_len,
|
||||
scale_to_width,
|
||||
(unsigned)threshold,
|
||||
invert,
|
||||
(unsigned)max_height,
|
||||
density != NULL ? density : "中等");
|
||||
density != NULL ? density : "中等",
|
||||
direct_ignore_precheck);
|
||||
|
||||
char *body = NULL;
|
||||
esp_err_t body_err = rest_server_read_body(req, &body);
|
||||
@@ -407,6 +426,7 @@ static esp_err_t rest_server_print_image_binary(httpd_req_t *req) {
|
||||
width,
|
||||
height,
|
||||
density,
|
||||
direct_ignore_precheck,
|
||||
NULL,
|
||||
NULL);
|
||||
free(raster);
|
||||
@@ -458,12 +478,13 @@ static esp_err_t rest_server_print_image_generate(httpd_req_t *req) {
|
||||
(unsigned)gen_opt.timeout_ms,
|
||||
(unsigned)gen_opt.fetch_timeout_ms);
|
||||
ESP_LOGI(TAG,
|
||||
"image process config, scale_to_width=%d, threshold=%u, invert=%d, max_height=%u, density=%s",
|
||||
"image process config, scale_to_width=%d, threshold=%u, invert=%d, max_height=%u, density=%s, ignore_precheck=%d",
|
||||
print_opt.scale_to_width,
|
||||
(unsigned)print_opt.threshold,
|
||||
print_opt.invert,
|
||||
(unsigned)print_opt.max_height,
|
||||
print_opt.density != NULL ? print_opt.density : "中等");
|
||||
print_opt.density != NULL ? print_opt.density : "中等",
|
||||
print_opt.direct_ignore_precheck);
|
||||
|
||||
image_generation_request_t gen_req = {
|
||||
.prompt = gen_opt.prompt,
|
||||
@@ -553,6 +574,7 @@ static esp_err_t rest_server_print_image_generate(httpd_req_t *req) {
|
||||
width,
|
||||
height,
|
||||
print_opt.density,
|
||||
print_opt.direct_ignore_precheck,
|
||||
warning,
|
||||
request_id);
|
||||
|
||||
|
||||
@@ -159,6 +159,7 @@ esp_err_t rest_server_print_qr_post(httpd_req_t *req) {
|
||||
cJSON *jscale = cJSON_GetObjectItemCaseSensitive(json, "module_scale");
|
||||
cJSON *jmargin = cJSON_GetObjectItemCaseSensitive(json, "margin_modules");
|
||||
cJSON *jmaxh = cJSON_GetObjectItemCaseSensitive(json, "max_height");
|
||||
cJSON *jignore = cJSON_GetObjectItemCaseSensitive(json, "ignore_precheck");
|
||||
|
||||
if (!cJSON_IsString(jtext) || jtext->valuestring == NULL || jtext->valuestring[0] == '\0') {
|
||||
cJSON_Delete(json);
|
||||
@@ -168,6 +169,7 @@ esp_err_t rest_server_print_qr_post(httpd_req_t *req) {
|
||||
const char *density = (cJSON_IsString(jdensity) && jdensity->valuestring != NULL)
|
||||
? jdensity->valuestring
|
||||
: "中等";
|
||||
bool direct_ignore_precheck = rest_server_json_bool_with_default(jignore, false);
|
||||
|
||||
uint8_t ecc_level = 3; /* default H */
|
||||
if (cJSON_IsString(jecc) && jecc->valuestring != NULL) {
|
||||
@@ -224,6 +226,7 @@ esp_err_t rest_server_print_qr_post(httpd_req_t *req) {
|
||||
width,
|
||||
height,
|
||||
density,
|
||||
direct_ignore_precheck,
|
||||
NULL,
|
||||
NULL);
|
||||
free(raster);
|
||||
@@ -250,6 +253,7 @@ esp_err_t rest_server_print_label_post(httpd_req_t *req) {
|
||||
cJSON *jdensity = cJSON_GetObjectItemCaseSensitive(json, "density");
|
||||
cJSON *jgap = cJSON_GetObjectItemCaseSensitive(json, "gap_move_before");
|
||||
cJSON *joffset = cJSON_GetObjectItemCaseSensitive(json, "offset_tenths_mm");
|
||||
cJSON *jignore = cJSON_GetObjectItemCaseSensitive(json, "ignore_precheck");
|
||||
|
||||
bool gap_move_before = rest_server_json_bool_with_default(jgap, true);
|
||||
bool has_offset = cJSON_IsNumber(joffset);
|
||||
@@ -287,6 +291,7 @@ esp_err_t rest_server_print_label_post(httpd_req_t *req) {
|
||||
const char *density = (cJSON_IsString(jdensity) && jdensity->valuestring != NULL)
|
||||
? jdensity->valuestring
|
||||
: "中等";
|
||||
bool direct_ignore_precheck = rest_server_json_bool_with_default(jignore, false);
|
||||
|
||||
uint16_t width = 0;
|
||||
uint16_t height = 0;
|
||||
@@ -313,6 +318,7 @@ esp_err_t rest_server_print_label_post(httpd_req_t *req) {
|
||||
width,
|
||||
height,
|
||||
density,
|
||||
direct_ignore_precheck,
|
||||
NULL,
|
||||
NULL);
|
||||
free(raster);
|
||||
@@ -341,6 +347,7 @@ esp_err_t rest_server_print_text_post(httpd_req_t *req) {
|
||||
cJSON *jscale = cJSON_GetObjectItemCaseSensitive(json, "scale");
|
||||
cJSON *jline = cJSON_GetObjectItemCaseSensitive(json, "line_spacing");
|
||||
cJSON *jmaxh = cJSON_GetObjectItemCaseSensitive(json, "max_height");
|
||||
cJSON *jignore = cJSON_GetObjectItemCaseSensitive(json, "ignore_precheck");
|
||||
|
||||
if (!cJSON_IsString(jtext) || jtext->valuestring == NULL) {
|
||||
cJSON_Delete(json);
|
||||
@@ -350,6 +357,7 @@ esp_err_t rest_server_print_text_post(httpd_req_t *req) {
|
||||
const char *density = (cJSON_IsString(jdensity) && jdensity->valuestring != NULL)
|
||||
? jdensity->valuestring
|
||||
: "中等";
|
||||
bool direct_ignore_precheck = rest_server_json_bool_with_default(jignore, false);
|
||||
uint8_t scale = 2;
|
||||
uint8_t line_spacing = 2;
|
||||
uint16_t max_height = 2000;
|
||||
@@ -394,6 +402,7 @@ esp_err_t rest_server_print_text_post(httpd_req_t *req) {
|
||||
width,
|
||||
height,
|
||||
density,
|
||||
direct_ignore_precheck,
|
||||
render_msg,
|
||||
NULL);
|
||||
free(raster);
|
||||
@@ -422,6 +431,7 @@ esp_err_t rest_server_print_receipt_post(httpd_req_t *req) {
|
||||
cJSON *jfooter = cJSON_GetObjectItemCaseSensitive(json, "footer");
|
||||
cJSON *jdensity = cJSON_GetObjectItemCaseSensitive(json, "density");
|
||||
cJSON *jscale = cJSON_GetObjectItemCaseSensitive(json, "scale");
|
||||
cJSON *jignore = cJSON_GetObjectItemCaseSensitive(json, "ignore_precheck");
|
||||
|
||||
const char *title = (cJSON_IsString(jtitle) && jtitle->valuestring != NULL)
|
||||
? jtitle->valuestring
|
||||
@@ -432,6 +442,7 @@ esp_err_t rest_server_print_receipt_post(httpd_req_t *req) {
|
||||
const char *density = (cJSON_IsString(jdensity) && jdensity->valuestring != NULL)
|
||||
? jdensity->valuestring
|
||||
: "中等";
|
||||
bool direct_ignore_precheck = rest_server_json_bool_with_default(jignore, false);
|
||||
uint8_t scale = 2;
|
||||
if (cJSON_IsNumber(jscale) && jscale->valuedouble >= 1 && jscale->valuedouble <= 4) {
|
||||
scale = (uint8_t)jscale->valuedouble;
|
||||
@@ -516,6 +527,7 @@ esp_err_t rest_server_print_receipt_post(httpd_req_t *req) {
|
||||
width,
|
||||
height,
|
||||
density,
|
||||
direct_ignore_precheck,
|
||||
render_msg,
|
||||
NULL);
|
||||
free(raster);
|
||||
|
||||
Reference in New Issue
Block a user