173 lines
5.3 KiB
Python
173 lines
5.3 KiB
Python
import re
|
|
|
|
with open('esp32_serial_backend/esp32_serial_backend.ino', 'r', encoding='utf8') as f:
|
|
content = f.read()
|
|
|
|
# 1. Include img_converters.h
|
|
if '#include "img_converters.h"' not in content:
|
|
content = content.replace('#include "esp_camera.h"', '#include "esp_camera.h"\n#include "img_converters.h"')
|
|
|
|
# 2. Refactor postFrame to take buffer instead of fb
|
|
content = content.replace(
|
|
'''String postFrame(const String &url, camera_fb_t *fb, uint32_t timeoutMs)
|
|
{
|
|
if (!fb)
|
|
return "ERROR no_frame";''',
|
|
'''String postFrame(const String &url, uint8_t *buf, size_t len, uint32_t timeoutMs)
|
|
{
|
|
if (!buf || len == 0)
|
|
return "ERROR no_frame";''')
|
|
|
|
content = content.replace('int code = http.POST(fb->buf, fb->len);', 'int code = http.POST(buf, len);')
|
|
|
|
content = content.replace(
|
|
'''String postFrameWithRetry(const String &url, camera_fb_t *fb, uint32_t timeoutMs, int retries = 1)
|
|
{
|
|
String resp = postFrame(url, fb, timeoutMs);
|
|
while (retries-- > 0)
|
|
{
|
|
if (resp == "HTTP ERR -11" || resp == "HTTP ERR -1")
|
|
{
|
|
delay(250);
|
|
resp = postFrame(url, fb, timeoutMs);
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
return resp;
|
|
}''',
|
|
'''String postFrameWithRetry(const String &url, uint8_t *buf, size_t len, uint32_t timeoutMs, int retries = 1)
|
|
{
|
|
String resp = postFrame(url, buf, len, timeoutMs);
|
|
while (retries-- > 0)
|
|
{
|
|
if (resp == "HTTP ERR -11" || resp == "HTTP ERR -1")
|
|
{
|
|
delay(250);
|
|
resp = postFrame(url, buf, len, timeoutMs);
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
return resp;
|
|
}''')
|
|
|
|
# 3. Replace the entire camera fetching block in handleCommand
|
|
old_camera_block = ''' if (!reinitCamera(PIXFORMAT_JPEG))
|
|
{
|
|
showStatus("GAGAL JEPRET", TFT_RED, "JPEG Init error");
|
|
gBusy = false;
|
|
return false;
|
|
}
|
|
delay(80);
|
|
|
|
camera_fb_t *fb = esp_camera_fb_get();
|
|
if (!fb)
|
|
{
|
|
Serial.println("ERROR no_frame");
|
|
showStatus("KAMERA ERROR", TFT_RED, "Camera fb null");
|
|
gBusy = false;
|
|
return false;
|
|
}
|
|
|
|
// Debug: verify we're actually sending a JPEG.
|
|
if (fb->len >= 3)
|
|
{
|
|
Serial.printf("CAP fmt=%d len=%u magic=%02X %02X %02X\\n",
|
|
(int)fb->format,
|
|
(unsigned)fb->len,
|
|
fb->buf[0], fb->buf[1], fb->buf[2]);
|
|
}
|
|
else
|
|
{
|
|
Serial.printf("CAP fmt=%d len=%u\\n", (int)fb->format, (unsigned)fb->len);
|
|
}
|
|
|
|
// If the frame isn't JPEG or doesn't have JPEG SOI marker, don't upload.
|
|
if (fb->format != PIXFORMAT_JPEG || fb->len < 3 || !(fb->buf[0] == 0xFF && fb->buf[1] == 0xD8 && fb->buf[2] == 0xFF))
|
|
{
|
|
showStatus("BUKAN JPEG", TFT_RED, "Format salah");
|
|
esp_camera_fb_return(fb);
|
|
reinitCamera(PIXFORMAT_RGB565);
|
|
gBusy = false;
|
|
return false;
|
|
}'''
|
|
|
|
new_camera_block = ''' // Kita biarkan kamera di format RGB565 saat ini, encode software
|
|
camera_fb_t *fb = esp_camera_fb_get();
|
|
if (!fb)
|
|
{
|
|
Serial.println("ERROR no_frame");
|
|
showStatus("KAMERA ERROR", TFT_RED, "Camera fb null");
|
|
gBusy = false;
|
|
return false;
|
|
}
|
|
|
|
uint8_t *jpeg_buf = NULL;
|
|
size_t jpeg_len = 0;
|
|
bool is_allocated = false;
|
|
|
|
if (fb->format != PIXFORMAT_JPEG) {
|
|
if (!frame2jpg(fb, 80, &jpeg_buf, &jpeg_len)) {
|
|
showStatus("JPEG ENCODE FAIL", TFT_RED, "");
|
|
esp_camera_fb_return(fb);
|
|
gBusy = false;
|
|
return false;
|
|
}
|
|
is_allocated = true;
|
|
} else {
|
|
jpeg_buf = fb->buf;
|
|
jpeg_len = fb->len;
|
|
}'''
|
|
|
|
content = content.replace(old_camera_block, new_camera_block)
|
|
|
|
# 4. Modify postFrameWithRetry calls in handleCommand
|
|
content = content.replace('postFrameWithRetry(url, fb, 60000);', 'postFrameWithRetry(url, jpeg_buf, jpeg_len, 60000);')
|
|
|
|
# 5. Modify cleanup in handleCommand
|
|
old_cleanup_enroll = ''' showStatus("NAMA KOSONG", TFT_RED, "Silakan isi nama");
|
|
esp_camera_fb_return(fb);
|
|
reinitCamera(PIXFORMAT_RGB565);
|
|
gBusy = false;'''
|
|
new_cleanup_enroll = ''' showStatus("NAMA KOSONG", TFT_RED, "Silakan isi nama");
|
|
if (is_allocated) free(jpeg_buf);
|
|
esp_camera_fb_return(fb);
|
|
gBusy = false;'''
|
|
content = content.replace(old_cleanup_enroll, new_cleanup_enroll)
|
|
|
|
old_cleanup_recog_fail = ''' if (resp.startsWith("HTTP ERR") || resp.startsWith("HTTP 4") || resp.startsWith("HTTP 5") || resp.startsWith("WIFI"))
|
|
{
|
|
Serial.println("[RECOG] upload FAILED");
|
|
showStatus("SERVER DISABLE/RTO", TFT_RED, "");
|
|
esp_camera_fb_return(fb);
|
|
reinitCamera(PIXFORMAT_RGB565);
|
|
gBusy = false;
|
|
return false;
|
|
}'''
|
|
new_cleanup_recog_fail = ''' if (resp.startsWith("HTTP ERR") || resp.startsWith("HTTP 4") || resp.startsWith("HTTP 5") || resp.startsWith("WIFI"))
|
|
{
|
|
Serial.println(String("[RECOG] upload FAILED: ") + resp);
|
|
showStatus("ERR: " + resp, TFT_RED, ""); // show the real error on screen
|
|
if (is_allocated) free(jpeg_buf);
|
|
esp_camera_fb_return(fb);
|
|
gBusy = false;
|
|
return false;
|
|
}'''
|
|
content = content.replace(old_cleanup_recog_fail, new_cleanup_recog_fail)
|
|
|
|
old_final_cleanup = ''' esp_camera_fb_return(fb);
|
|
reinitCamera(PIXFORMAT_RGB565);
|
|
gBusy = false;
|
|
return true;'''
|
|
new_final_cleanup = ''' if (is_allocated) free(jpeg_buf);
|
|
esp_camera_fb_return(fb);
|
|
gBusy = false;
|
|
return true;'''
|
|
content = content.replace(old_final_cleanup, new_final_cleanup)
|
|
|
|
with open('esp32_serial_backend/esp32_serial_backend.ino', 'w', encoding='utf8') as f:
|
|
f.write(content)
|
|
|
|
print("Update complete")
|