From 9a6fce854cd5b4990567968a7be67c93aa25770f Mon Sep 17 00:00:00 2001 From: suchmememanyskill <38142618+suchmememanyskill@users.noreply.github.com> Date: Sun, 20 Oct 2024 22:27:31 +0200 Subject: [PATCH] In progress --- .../klipper/klipper_printer_integration.cpp | 148 +++++++++++++++++ .../klipper/klipper_printer_integration.hpp | 44 +++++ CYD-Klipper/src/core/printer_integration.cpp | 0 CYD-Klipper/src/core/printer_integration.hpp | 150 ++++++++++++++++++ CYD-Klipper/src/ui/panels/error_panel.cpp | 2 +- 5 files changed, 343 insertions(+), 1 deletion(-) create mode 100644 CYD-Klipper/src/core/klipper/klipper_printer_integration.cpp create mode 100644 CYD-Klipper/src/core/klipper/klipper_printer_integration.hpp create mode 100644 CYD-Klipper/src/core/printer_integration.cpp create mode 100644 CYD-Klipper/src/core/printer_integration.hpp diff --git a/CYD-Klipper/src/core/klipper/klipper_printer_integration.cpp b/CYD-Klipper/src/core/klipper/klipper_printer_integration.cpp new file mode 100644 index 0000000..2f38c0c --- /dev/null +++ b/CYD-Klipper/src/core/klipper/klipper_printer_integration.cpp @@ -0,0 +1,148 @@ +#include "klipper_printer_integration.hpp" +#include "../../conf/global_config.h" +#include +#include + +void configure_http_client(HTTPClient &client, String url_part, bool stream, int timeout, PRINTER_CONFIG* printer) +{ + if (stream){ + client.useHTTP10(true); + } + + if (timeout > 0){ + client.setTimeout(timeout); + client.setConnectTimeout(timeout); + } + + client.begin("http://" + String(printer->klipper_host) + ":" + String(printer->klipper_port) + url_part); + + if (printer->auth_configured) { + client.addHeader("X-Api-Key", printer->klipper_auth); + } +} + +bool KlipperPrinter::send_gcode(const char *gcode, bool wait) +{ + HTTPClient client; + configure_http_client(client, "/printer/gcode/script?script=" + urlEncode(gcode), false, wait ? 5000 : 750, printer_config); + LOG_F(("Sending gcode: %s\n", gcode)) + + try + { + client.GET(); + return true; + } + catch (...) + { + LOG_LN("Failed to send gcode"); + return false; + } +} + +bool KlipperPrinter::move_printer(const char* axis, float amount, bool relative) +{ + if (!printer_data.homed_axis || printer_data.state == PrinterStatePrinting) + return true; + + char gcode[64]; + const char* extra = (amount > 0) ? "+" : ""; + const char* start = ""; + const char* end = ""; + + if (printer_data.absolute_coords && relative) { + start = "G91\n"; + } + else if (!printer_data.absolute_coords && !relative) { + start = "G90\n"; + } + + if (printer_data.absolute_coords && relative) { + end = "\nG90"; + } + else if (!printer_data.absolute_coords && !relative) { + end = "\nG91"; + } + + sprintf(gcode, "%sG1 %s%s%.3f F6000%s", start, axis, extra, amount, end); + send_gcode(gcode); + + lock_absolute_relative_mode_swap = 2; +} + +bool KlipperPrinter::execute_feature(PrinterFeatures feature) +{ + HTTPClient client; + + switch (feature) + { + case PrinterFeatureRestart: + return send_gcode("RESTART", false); + case PrinterFeatureFirmwareRestart: + return send_gcode("FIRMWARE_RESTART", false); + case PrinterFeatureHome: + return send_gcode("G28"); + case PrinterFeatureDisableSteppers: + return send_gcode("M18"); + case PrinterFeaturePause: + return send_gcode("PAUSE"); + case PrinterFeatureResume: + return send_gcode("RESUME"); + case PrinterFeatureStop: + return send_gcode("CANCEL_PRINT"); + case PrinterFeatureEmergencyStop: + LOG_LN("Sending estop"); + send_gcode("M112", false); + configure_http_client(client, "/printer/emergency_stop", false, 5000, printer_config); + + try + { + client.GET(); + } + catch (...) + { + LOG_LN("Failed to send estop"); + } + + return true; + case PrinterFeatureExtrude: + if (printer_data.state == PrinterStatePrinting) + { + return false; + } + + if (printer_config->custom_filament_move_macros) + { + return send_gcode("FILAMENT_EXTRUDE"); + } + else + { + return send_gcode("M83") && send_gcode("G1 E25 F300"); + } + case PrinterFeatureRetract: + if (printer_data.state == PrinterStatePrinting) + { + return false; + } + + if (get_current_printer_config()->custom_filament_move_macros) + { + return send_gcode("FILAMENT_RETRACT"); + } + else + { + return send_gcode("M83") && send_gcode("G1 E-25 F300"); + } + case PrinterFeatureCooldown: + return send_gcode("M104 S0") && send_gcode("M140 S0"); + default: + LOG_F(("Unsupported printer feature %d", feature)); + return false; + } +} + +bool KlipperPrinter::connect() +{ + // Pass +} + + diff --git a/CYD-Klipper/src/core/klipper/klipper_printer_integration.hpp b/CYD-Klipper/src/core/klipper/klipper_printer_integration.hpp new file mode 100644 index 0000000..ea299ef --- /dev/null +++ b/CYD-Klipper/src/core/klipper/klipper_printer_integration.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "../printer_integration.hpp" + +class KlipperPrinter : BasePrinter +{ + private: + unsigned char lock_absolute_relative_mode_swap{}; + + public: + KlipperPrinter(int index) : BasePrinter(index) + { + supported_features = PrinterFeatureRestart + | PrinterFeatureFirmwareRestart + | PrinterFeatureHome + | PrinterFeatureDisableSteppers + | PrinterFeaturePause + | PrinterFeatureResume + | PrinterFeatureStop + | PrinterFeatureEmergencyStop + | PrinterFeatureExtrude + | PrinterFeatureRetract + | PrinterFeatureCooldown; + + supported_temperature_devices = PrinterTemperatureDeviceBed + | PrinterTemperatureDeviceNozzle1; + } + + bool move_printer(const char* axis, float amount, bool relative) = 0; + bool execute_feature(PrinterFeatures feature) = 0; + bool connect() = 0; + bool fetch(PrinterData& data) = 0; + void commit_fetch(PrinterData& data) = 0; + bool fetch_min(PrinterDataMinimal& data) = 0; + void disconnect() = 0; + bool get_macros(Macros& macros) = 0; + bool execute_macro(const char* macro) = 0; + bool get_power_devices(PowerDevices& power_devices) = 0; + bool set_power_device_state(const char* device_name, bool state) = 0; + bool get_files(Files& files) = 0; + bool start_file(const char* file) = 0; + bool set_target_temperature(PrinterTemperatureDevice device, float temperature) = 0; + bool send_gcode(const char* gcode, bool wait = true); +}; \ No newline at end of file diff --git a/CYD-Klipper/src/core/printer_integration.cpp b/CYD-Klipper/src/core/printer_integration.cpp new file mode 100644 index 0000000..e69de29 diff --git a/CYD-Klipper/src/core/printer_integration.hpp b/CYD-Klipper/src/core/printer_integration.hpp new file mode 100644 index 0000000..7bd233b --- /dev/null +++ b/CYD-Klipper/src/core/printer_integration.hpp @@ -0,0 +1,150 @@ +#pragma once +#include "lvgl.h" +#include "../conf/global_config.h" + +#define BIT(x) 1 << x + +enum PrinterFeatures { + PrinterFeatureRestart = BIT(0), + PrinterFeatureFirmwareRestart = BIT(1), + PrinterFeatureHome = BIT(2), + PrinterFeatureDisableSteppers = BIT(3), + PrinterFeaturePause = BIT(4), + PrinterFeatureResume = BIT(5), + PrinterFeatureStop = BIT(6), + PrinterFeatureEmergencyStop = BIT(7), + PrinterFeatureExtrude = BIT(8), + PrinterFeatureRetract = BIT(9), + PrinterFeatureLoadFilament = BIT(10), + PrinterFeatureUnloadFilament = BIT(11), + PrinterFeatureCooldown = BIT(12), +}; + +inline PrinterFeatures operator|(PrinterFeatures a, PrinterFeatures b) +{ + return static_cast(static_cast(a) | static_cast(b)); +} + +enum PrinterTemperatureDevice +{ + PrinterTemperatureDeviceBed = BIT(0), + PrinterTemperatureDeviceNozzle1 = BIT(1), + PrinterTemperatureDeviceNozzle2 = BIT(2), + PrinterTemperatureDeviceNozzle3 = BIT(3), + PrinterTemperatureDeviceNozzle4 = BIT(4), + PrinterTemperatureDeviceNozzle5 = BIT(5), + PrinterTemperatureDeviceNozzle6 = BIT(6), + PrinterTemperatureDeviceNozzle7 = BIT(7), + PrinterTemperatureDeviceNozzle8 = BIT(8), + PrinterTemperatureDeviceChamber = BIT(9), +}; + +inline PrinterTemperatureDevice operator|(PrinterTemperatureDevice a, PrinterTemperatureDevice b) +{ + return static_cast(static_cast(a) | static_cast(b)); +} + +enum PrinterState { + PrinterStateOffline = 0, + PrinterStateError = 1, + PrinterStateIdle = 2, + PrinterStatePrinting = 3, + PrinterStatePaused = 4, +}; + +typedef struct _PrinterData { + union { + struct { + bool can_extrude : 1; + bool homed_axis : 1; + bool absolute_coords : 1; + }; + unsigned char rawState; + }; + PrinterState state; + char* state_message; + float temperatures[10]; + float target_temperatures[10]; + PrinterTemperatureDevice AvailableDevices; + float position[3]; + float elapsed_time_s; + float printed_time_s; + float remaining_time_s; + float filament_used_mm; + char* print_filename; + float print_progress; // 0 -> 1 + float fan_speed; // 0 -> 1 + float speed_mult; + float extrude_mult; + int total_layers; + int current_layer; + float pressure_advance; + float smooth_time; + int feedrate_mm_per_s; +} PrinterData; + +typedef struct _PrinterDataMinimal { + unsigned char state; + float print_progress; // 0 -> 1 + unsigned int power_devices; +} PrinterDataMinimal; + +typedef struct { + const char** macros; + unsigned int count; +} Macros; + +typedef struct { + const char** power_devices; + const bool* power_states; + unsigned int count; +} PowerDevices; + +typedef struct { + const char** available_files; + unsigned int count; +} Files; + +typedef struct { + lv_event_ct_b set_label; + lv_event_ct_b open_panel; +} PrinterUiPanel; + +class BasePrinter +{ + protected: + unsigned char config_index{}; + + public: + PrinterData printer_data{}; + PrinterFeatures supported_features{}; + PrinterTemperatureDevice supported_temperature_devices{}; + PrinterUiPanel* custom_menus{}; + PRINTER_CONFIG* printer_config{}; + GLOBAL_CONFIG* global_config{}; + unsigned char custom_menus_count{}; + + virtual bool move_printer(const char* axis, float amount, bool relative) = 0; + virtual bool execute_feature(PrinterFeatures feature) = 0; + virtual bool connect() = 0; + virtual bool fetch(PrinterData& data) = 0; + virtual void commit_fetch(PrinterData& data) = 0; + virtual bool fetch_min(PrinterDataMinimal& data) = 0; + virtual void disconnect() = 0; + virtual bool get_macros(Macros& macros) = 0; + virtual bool execute_macro(const char* macro) = 0; + virtual bool get_power_devices(PowerDevices& power_devices) = 0; + virtual bool set_power_device_state(const char* device_name, bool state) = 0; + virtual bool get_files(Files& files) = 0; + virtual bool start_file(const char* file) = 0; + virtual bool set_target_temperature(PrinterTemperatureDevice device, float temperature) = 0; + + BasePrinter(unsigned char index) { + config_index = index; + // TODO: Fetch printer config and global config + } +}; + +BasePrinter* get_current_printer(); +BasePrinter* get_printer(int idx); +void initialize_printer(); \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/error_panel.cpp b/CYD-Klipper/src/ui/panels/error_panel.cpp index 10a28ba..d24e0c5 100644 --- a/CYD-Klipper/src/ui/panels/error_panel.cpp +++ b/CYD-Klipper/src/ui/panels/error_panel.cpp @@ -28,7 +28,7 @@ void error_panel_init(lv_obj_t* panel) lv_label_set_text(label, printer.state_message); lv_obj_set_width(label, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2); lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP); - + lv_obj_t * button_row = lv_create_empty_panel(panel); lv_obj_set_size(button_row, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_layout_flex_row(button_row);