Skip to content

Commit

Permalink
More serial
Browse files Browse the repository at this point in the history
  • Loading branch information
suchmememanyskill committed Nov 8, 2024
1 parent d4ce7a7 commit 747ff4c
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 49 deletions.
1 change: 1 addition & 0 deletions CYD-Klipper/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ platform = espressif32@6.4.0
board = esp32dev
framework = arduino
monitor_speed = 115200
debug_build_flags = -Os
lib_deps =
https://github.com/suchmememanyskill/esp32-smartdisplay#9c1d737
bblanchon/ArduinoJson@^7.0.0
Expand Down
4 changes: 4 additions & 0 deletions CYD-Klipper/src/core/data_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <UrlEncode.h>
#include "printer_integration.hpp"
#include "klipper/klipper_printer_integration.hpp"
#include "klipper-serial/serial_klipper_printer_integration.hpp"
#include "bambu/bambu_printer_integration.hpp"

SemaphoreHandle_t freezeRenderThreadSemaphore, freezeRequestThreadSemaphore;
Expand Down Expand Up @@ -122,6 +123,9 @@ void data_setup()
case PrinterType::PrinterTypeBambuLocal:
available_printers[count++] = new BambuPrinter(i);
break;
case PrinterType::PrinterTypeKlipperSerial:
available_printers[count++] = new SerialKlipperPrinter(i);
break;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
#include "serial_klipper_printer_integration.hpp"
#include <HardwareSerial.h>
#include <UrlEncode.h>
#include "../../ui/serial/serial_console.h"

bool is_semaphores_initialized = false;
SemaphoreHandle_t freeze_serial_thread_semaphore;

void semaphore_init_serial()
{
if (is_semaphores_initialized)
{
return;
}

freeze_serial_thread_semaphore = xSemaphoreCreateMutex();
xSemaphoreGive(freeze_serial_thread_semaphore);
is_semaphores_initialized = true;
}

void freeze_serial_thread()
{
xSemaphoreTake(freeze_serial_thread_semaphore, portMAX_DELAY);
}

void unfreeze_serial_thread()
{
xSemaphoreGive(freeze_serial_thread_semaphore);
}

enum HttpRequestType
{
Expand All @@ -18,62 +44,77 @@ void clear_serial_buffer()

// Request: {timeout} {method} {endpoint}
// Response: {status code} {body}
int make_serial_request(JsonDocument &out, int timeout_ms, HttpRequestType requestType, const char* endpoint)
bool make_serial_request(JsonDocument &out, int timeout_ms, HttpRequestType requestType, const char* endpoint)
{
semaphore_init_serial();
freeze_serial_thread();
serial_console::global_disable_serial_console = true;
temporary_config.debug = false;
char buff[10];
clear_serial_buffer();

// TODO: Add semaphore here
if (!Serial.availableForWrite())
{
return -1;
unfreeze_serial_thread();
return false;
}

char buff[10];
sprintf(buff, "%d ", timeout_ms);

// TODO: Maybe use printf?
Serial.write(buff);
Serial.write(requestType == HttpGet ? "GET" : "POST");
Serial.write(' ');
Serial.write(endpoint);
Serial.write('\n');
Serial.printf("HTTP_REQUEST %d %s %s\n", timeout_ms, requestType == HttpGet ? "GET" : "POST", endpoint);

if (timeout_ms <= 0)
{
return 200;
unfreeze_serial_thread();
return true;
}
unsigned long _m = millis();
while (!Serial.available() && millis() < _m + timeout_ms + 10) delay(1);

if (!Serial.available())
{
return -2;
Serial.println("Timeout...");
unfreeze_serial_thread();
return false;
}

Serial.readBytes(buff, 4);
buff[3] = 0;

if (buff[0] < '0' || buff[0] > '9')
{
Serial.println("Invalid error code");
clear_serial_buffer();
return -3;
unfreeze_serial_thread();
return false;
}

int status_code = atoi(buff);

if (status_code < 200 || status_code >= 300)
{
Serial.println("Non-200 error code");
clear_serial_buffer();
return -4;
unfreeze_serial_thread();
return false;
}

auto result = deserializeJson(out, Serial);
return result == DeserializationError::Ok;
Serial.printf("Deserialization result: %s\n", result.c_str());
bool success = result == DeserializationError::Ok;

if (!success)
{
unfreeze_serial_thread();
}

return success;
}

bool make_serial_request_nocontent(HttpRequestType requestType, const char* endpoint)
{
JsonDocument doc;
make_serial_request(doc, 0, requestType, endpoint);
unfreeze_serial_thread();
return true;
}

Expand All @@ -85,7 +126,7 @@ bool SerialKlipperPrinter::connect()
bool SerialKlipperPrinter::fetch()
{
JsonDocument doc;
if (make_serial_request(doc, 1000, HttpGet, "/printer/objects/query?extruder&heater_bed&toolhead&gcode_move&virtual_sdcard&print_stats&webhooks&fan&display_status") == 200)
if (make_serial_request(doc, 1000, HttpGet, "/printer/objects/query?extruder&heater_bed&toolhead&gcode_move&virtual_sdcard&print_stats&webhooks&fan&display_status"))
{
if (printer_data.state == PrinterStateOffline)
{
Expand All @@ -94,6 +135,7 @@ bool SerialKlipperPrinter::fetch()

klipper_request_consecutive_fail_count = 0;
parse_state(doc);
unfreeze_serial_thread();
}
else
{
Expand Down Expand Up @@ -122,11 +164,11 @@ PrinterDataMinimal SerialKlipperPrinter::fetch_min()

data.success = true;

if (make_serial_request(doc, 1000, HttpGet, "/printer/objects/query?webhooks&print_stats&virtual_sdcard") == 200)
if (make_serial_request(doc, 1000, HttpGet, "/printer/objects/query?webhooks&print_stats&virtual_sdcard"))
{
data.state = PrinterState::PrinterStateIdle;
parse_state_min(doc, &data);
doc.clear();
unfreeze_serial_thread();
data.power_devices = get_power_devices_count();
}
else
Expand All @@ -142,9 +184,10 @@ Macros SerialKlipperPrinter::get_macros()
{
Macros macros = {0};
JsonDocument doc;
if (make_serial_request(doc, 1000, HttpGet, "/printer/gcode/help") == 200)
if (make_serial_request(doc, 1000, HttpGet, "/printer/gcode/help"))
{
return parse_macros(doc);
macros = parse_macros(doc);
unfreeze_serial_thread();
}

return macros;
Expand All @@ -153,9 +196,11 @@ Macros SerialKlipperPrinter::get_macros()
int SerialKlipperPrinter::get_macros_count()
{
JsonDocument doc;
if (make_serial_request(doc, 1000, HttpGet, "/printer/gcode/help") == 200)
if (make_serial_request(doc, 1000, HttpGet, "/printer/gcode/help"))
{
return parse_macros_count(doc);
int count = parse_macros_count(doc);
unfreeze_serial_thread();
return count;
}

return 0;
Expand All @@ -165,9 +210,10 @@ PowerDevices SerialKlipperPrinter::get_power_devices()
{
PowerDevices power_devices = {0};
JsonDocument doc;
if (make_serial_request(doc, 1000, HttpGet, "/machine/device_power/devices") == 200)
if (make_serial_request(doc, 1000, HttpGet, "/machine/device_power/devices"))
{
return parse_power_devices(doc);
power_devices = parse_power_devices(doc);
unfreeze_serial_thread();
}

return power_devices;
Expand All @@ -176,34 +222,70 @@ PowerDevices SerialKlipperPrinter::get_power_devices()
int SerialKlipperPrinter::get_power_devices_count()
{
JsonDocument doc;
if (make_serial_request(doc, 1000, HttpGet, "/machine/device_power/devices") == 200)
if (make_serial_request(doc, 1000, HttpGet, "/machine/device_power/devices"))
{
return parse_power_devices_count(doc);
int count = parse_power_devices_count(doc);
unfreeze_serial_thread();
return count;
}

return 0;
}

bool SerialKlipperPrinter::set_power_device_state(const char* device_name, bool state)
{
JsonDocument doc;
String request = "/machine/device_power/device?device=" + urlEncode(device_name) + "&action=" + (state ? "on" : "off");
return make_serial_request(doc, 1000, HttpPost, request.c_str());
return make_serial_request_nocontent(HttpGet, request.c_str());
}

Files SerialKlipperPrinter::get_files()
{
// TODO: Stubbed
Files files = {0};
files.success = false;
return files;
Files files_result = {0};
files_result.success = false;
JsonDocument doc;
LOG_F(("Heap space pre-file-parse: %d bytes\n", esp_get_free_heap_size()));
std::list<FileSystemFile> files;

auto timer_request = millis();
bool result = make_serial_request(doc, 5000, HttpGet, "/server/files/list");
auto timer_parse = millis();

if (!result)
{
return files_result;
}

parse_file_list(doc, files, 20);
unfreeze_serial_thread();

files_result.available_files = (char**)malloc(sizeof(char*) * files.size());

if (files_result.available_files == NULL){
LOG_LN("Failed to allocate memory");

for (auto file : files){
free(file.name);
}

return files_result;
}

for (auto file : files){
files_result.available_files[files_result.count++] = file.name;
}

files_result.success = true;

LOG_F(("Heap space post-file-parse: %d bytes\n", esp_get_free_heap_size()))
LOG_F(("Got %d files. Request took %dms, parsing took %dms\n", files.size(), timer_parse - timer_request, millis() - timer_parse))
return files_result;
}

bool SerialKlipperPrinter::start_file(const char* filename)
{
JsonDocument doc;
String request = "/printer/print/start?filename=" + urlEncode(filename);
return make_serial_request(doc, 1000, HttpPost, request.c_str());
return make_serial_request_nocontent(HttpGet, request.c_str());;
}

Thumbnail SerialKlipperPrinter::get_32_32_png_image_thumbnail(const char* gcode_filename)
Expand All @@ -218,16 +300,25 @@ bool SerialKlipperPrinter::send_gcode(const char* gcode, bool wait)
{
JsonDocument doc;
String request = "/printer/gcode/script?script=" + urlEncode(gcode);
return wait
? make_serial_request(doc, 5000, HttpGet, request.c_str())
: make_serial_request_nocontent(HttpGet, request.c_str());

if (!wait)
{
return make_serial_request_nocontent(HttpGet, request.c_str());
}

bool result = make_serial_request(doc, 5000, HttpGet, request.c_str());
unfreeze_serial_thread();
return result;
}

KlipperConnectionStatus connection_test_serial_klipper(PrinterConfiguration* config)
{
serial_console::global_disable_serial_console = true;
temporary_config.debug = false;
JsonDocument doc;
if (make_serial_request(doc, 1000, HttpGet, "/printer/info") != 200)
if (make_serial_request(doc, 1000, HttpGet, "/printer/info"))
{
unfreeze_serial_thread();
return KlipperConnectionStatus::ConnectOk;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ class SerialKlipperPrinter : public KlipperPrinter
{
public:
SerialKlipperPrinter(int index) : KlipperPrinter(index)
{

}
{}

bool connect();
bool fetch();
Expand All @@ -20,4 +18,6 @@ class SerialKlipperPrinter : public KlipperPrinter
bool start_file(const char* filename);
Thumbnail get_32_32_png_image_thumbnail(const char* gcode_filename);
bool send_gcode(const char* gcode, bool wait = true);
};
};

KlipperConnectionStatus connection_test_serial_klipper(PrinterConfiguration* config);
5 changes: 0 additions & 5 deletions CYD-Klipper/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,11 @@ void setup() {
screen_setup();
lv_setup();
LOG_LN("Screen init done");
LOG_F(("Free heap: %d bytes\n", esp_get_free_heap_size()));

wifi_init();
LOG_F(("Free heap after wifi setup: %d bytes\n", esp_get_free_heap_size()));
ota_init();
LOG_F(("Free heap after ota setup: %d bytes\n", esp_get_free_heap_size()));
ip_init();
LOG_F(("Free heap after ip setup: %d bytes\n", esp_get_free_heap_size()));
data_setup();
LOG_F(("Free heap after data setup: %d bytes\n", esp_get_free_heap_size()));

nav_style_setup();
main_ui_setup();
Expand Down
Loading

0 comments on commit 747ff4c

Please sign in to comment.