Start integration

This commit is contained in:
suchmememanyskill
2024-10-24 23:08:03 +02:00
parent 6a9023eb8d
commit 337a26be3d
5 changed files with 39 additions and 317 deletions

View File

@@ -9,6 +9,7 @@
#include "http_client.h"
#include "../ui/ui_utils.h"
#include "macros_query.h"
#include "printer_integration.hpp"
Printer printer = {0};
PrinterMinimal *printer_minimal;
@@ -128,317 +129,34 @@ int last_slicer_time_query = -15000;
void fetch_printer_data()
{
freeze_request_thread();
PRINTER_CONFIG *config = get_current_printer_config();
SETUP_HTTP_CLIENT("/printer/objects/query?extruder&heater_bed&toolhead&gcode_move&virtual_sdcard&print_stats&webhooks&fan&display_status")
int httpCode = client.GET();
delay(10);
if (httpCode == 200)
if (get_current_printer_data()->state == PrinterStateOffline)
{
int printer_state = printer.state;
if (printer.state == PRINTER_STATE_OFFLINE)
if (!get_current_printer()->connect())
{
printer.state = PRINTER_STATE_ERROR;
LOG_LN("Failed to connect to printer");
unfreeze_request_thread();
return;
}
klipper_request_consecutive_fail_count = 0;
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto status = doc["result"]["status"];
bool emit_state_update = false;
delay(10);
unfreeze_request_thread();
freeze_render_thread();
if (status.containsKey("webhooks"))
{
const char *state = status["webhooks"]["state"];
const char *message = status["webhooks"]["state_message"];
if (strcmp(state, "ready") == 0 && printer.state == PRINTER_STATE_ERROR)
{
printer_state = PRINTER_STATE_IDLE;
}
else if ((strcmp(state, "shutdown") == 0 || strcmp(state, "error") == 0) && printer.state != PRINTER_STATE_ERROR)
{
printer_state = PRINTER_STATE_ERROR;
}
if (printer.state_message == NULL || strcmp(printer.state_message, message))
{
if (printer.state_message != NULL)
{
free(printer.state_message);
}
printer.state_message = (char *)malloc(strlen(message) + 1);
strcpy(printer.state_message, message);
emit_state_update = true;
}
}
if (printer_state != PRINTER_STATE_ERROR)
{
if (status.containsKey("extruder"))
{
printer.extruder_temp = status["extruder"]["temperature"];
printer.extruder_target_temp = status["extruder"]["target"];
bool can_extrude = status["extruder"]["can_extrude"];
printer.pressure_advance = status["extruder"]["pressure_advance"];
printer.smooth_time = status["extruder"]["smooth_time"];
printer.can_extrude = can_extrude == true;
}
if (status.containsKey("heater_bed"))
{
printer.bed_temp = status["heater_bed"]["temperature"];
printer.bed_target_temp = status["heater_bed"]["target"];
}
if (status.containsKey("toolhead"))
{
const char *homed_axis = status["toolhead"]["homed_axes"];
printer.homed_axis = strcmp(homed_axis, "xyz") == 0;
}
if (status.containsKey("gcode_move"))
{
printer.position[0] = status["gcode_move"]["gcode_position"][0];
printer.position[1] = status["gcode_move"]["gcode_position"][1];
printer.position[2] = status["gcode_move"]["gcode_position"][2];
printer.gcode_offset[0] = status["gcode_move"]["homing_origin"][0];
printer.gcode_offset[1] = status["gcode_move"]["homing_origin"][1];
printer.gcode_offset[2] = status["gcode_move"]["homing_origin"][2];
bool absolute_coords = status["gcode_move"]["absolute_coordinates"];
if (lock_absolute_relative_mode_swap > 0)
{
lock_absolute_relative_mode_swap--;
}
else
{
printer.absolute_coords = absolute_coords == true;
}
printer.speed_mult = status["gcode_move"]["speed_factor"];
printer.extrude_mult = status["gcode_move"]["extrude_factor"];
printer.feedrate_mm_per_s = status["gcode_move"]["speed"];
printer.feedrate_mm_per_s /= 60; // convert mm/m to mm/s
}
if (status.containsKey("fan"))
{
printer.fan_speed = status["fan"]["speed"];
}
if (status.containsKey("virtual_sdcard"))
{
printer.print_progress = status["virtual_sdcard"]["progress"];
}
if (status.containsKey("print_stats"))
{
const char *filename = status["print_stats"]["filename"];
strcpy(filename_buff, filename == NULL ? "" : filename);
printer.print_filename = filename_buff;
printer.elapsed_time_s = status["print_stats"]["total_duration"];
printer.printed_time_s = status["print_stats"]["print_duration"];
printer.filament_used_mm = status["print_stats"]["filament_used"];
printer.total_layers = status["print_stats"]["info"]["total_layer"];
printer.current_layer = status["print_stats"]["info"]["current_layer"];
const char *state = status["print_stats"]["state"];
if (state == nullptr)
{
// Continue
}
else if (strcmp(state, "printing") == 0)
{
printer_state = PRINTER_STATE_PRINTING;
}
else if (strcmp(state, "paused") == 0)
{
printer_state = PRINTER_STATE_PAUSED;
}
else if (strcmp(state, "complete") == 0 || strcmp(state, "cancelled") == 0 || strcmp(state, "standby") == 0)
{
printer_state = PRINTER_STATE_IDLE;
}
}
if (status.containsKey("display_status"))
{
printer.print_progress = status["display_status"]["progress"];
const char* message = status["display_status"]["message"];
if (!global_config.disable_m117_messaging)
{
lv_create_popup_message(message, 10000);
}
}
if (printer.state == PRINTER_STATE_PRINTING && printer.print_progress > 0)
{
float remaining_time_s_percentage = (printer.printed_time_s / printer.print_progress) - printer.printed_time_s;
float remaining_time_s_slicer = 0;
if (printer.slicer_estimated_print_time_s > 0)
{
remaining_time_s_slicer = printer.slicer_estimated_print_time_s - printer.printed_time_s;
}
if (remaining_time_s_slicer <= 0 || config->remaining_time_calc_mode == REMAINING_TIME_CALC_PERCENTAGE)
{
printer.remaining_time_s = remaining_time_s_percentage;
}
else if (config->remaining_time_calc_mode == REMAINING_TIME_CALC_INTERPOLATED)
{
printer.remaining_time_s = remaining_time_s_percentage * printer.print_progress + remaining_time_s_slicer * (1 - printer.print_progress);
}
else if (config->remaining_time_calc_mode == REMAINING_TIME_CALC_SLICER)
{
printer.remaining_time_s = remaining_time_s_slicer;
}
}
if (printer.remaining_time_s < 0)
{
printer.remaining_time_s = 0;
}
if (printer.state == PRINTER_STATE_IDLE)
{
printer.slicer_estimated_print_time_s = 0;
}
lv_msg_send(DATA_PRINTER_DATA, &printer);
}
if (printer.state != printer_state || emit_state_update)
{
printer.state = printer_state;
lv_msg_send(DATA_PRINTER_STATE, &printer);
}
if (printer.state == PRINTER_STATE_PRINTING && millis() - last_slicer_time_query > 30000 && printer.slicer_estimated_print_time_s <= 0)
{
delay(10);
last_slicer_time_query = millis();
printer.slicer_estimated_print_time_s = get_slicer_time_estimate_s();
}
unfreeze_render_thread();
}
else
bool fetch_result = get_current_printer()->fetch();
unfreeze_request_thread();
freeze_render_thread();
if (!fetch_result)
{
unfreeze_request_thread();
klipper_request_consecutive_fail_count++;
if (klipper_request_consecutive_fail_count == 5)
{
freeze_render_thread();
printer.state = PRINTER_STATE_OFFLINE;
lv_msg_send(DATA_PRINTER_STATE, &printer);
unfreeze_render_thread();
}
LOG_F(("Failed to fetch printer data: %d\n", httpCode))
LOG_LN("Failed to fetch printer data")
get_current_printer()->disconnect();
}
get_current_printer()->AnnouncePrinterData();
unfreeze_render_thread();
}
void fetch_printer_data_minimal()
{
PrinterMinimal data[PRINTER_CONFIG_COUNT] = {0};
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++){
PRINTER_CONFIG *config = &global_config.printer_config[i];
if (!config->ip_configured)
{
data[i].state = PRINTER_STATE_OFFLINE;
continue;
}
delay(10);
HTTPClient client;
configure_http_client(client, get_full_url("/printer/objects/query?webhooks&print_stats&virtual_sdcard", config), true, 1000, config);
freeze_request_thread();
int httpCode = client.GET();
delay(10);
if (httpCode == 200)
{
if (data[i].state == PRINTER_STATE_OFFLINE)
{
data[i].state = PRINTER_STATE_ERROR;
}
data[i].power_devices = power_devices_count(config);
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto status = doc["result"]["status"];
unfreeze_request_thread();
if (status.containsKey("webhooks"))
{
const char *state = status["webhooks"]["state"];
if (strcmp(state, "ready") == 0 && data[i].state == PRINTER_STATE_ERROR)
{
data[i].state = PRINTER_STATE_IDLE;
}
else if (strcmp(state, "shutdown") == 0 && data[i].state != PRINTER_STATE_ERROR)
{
data[i].state = PRINTER_STATE_ERROR;
}
}
if (data[i].state != PRINTER_STATE_ERROR)
{
if (status.containsKey("virtual_sdcard"))
{
data[i].print_progress = status["virtual_sdcard"]["progress"];
}
if (status.containsKey("print_stats"))
{
const char *state = status["print_stats"]["state"];
if (state == nullptr)
{
data[i].state = PRINTER_STATE_ERROR;
}
else if (strcmp(state, "printing") == 0)
{
data[i].state = PRINTER_STATE_PRINTING;
}
else if (strcmp(state, "paused") == 0)
{
data[i].state = PRINTER_STATE_PAUSED;
}
else if (strcmp(state, "complete") == 0 || strcmp(state, "cancelled") == 0 || strcmp(state, "standby") == 0)
{
data[i].state = PRINTER_STATE_IDLE;
}
}
}
}
else
{
data[i].state = PRINTER_STATE_OFFLINE;
data[i].power_devices = power_devices_count(config);
unfreeze_request_thread();
}
}
freeze_render_thread();
memcpy(printer_minimal, data, sizeof(PrinterMinimal) * PRINTER_CONFIG_COUNT);
lv_msg_send(DATA_PRINTER_MINIMAL, NULL);
unfreeze_render_thread();
// TODO
}
void data_loop()
@@ -468,7 +186,7 @@ TaskHandle_t background_loop;
void data_setup()
{
printer_minimal = (PrinterMinimal *)calloc(sizeof(PrinterMinimal), PRINTER_CONFIG_COUNT);
printer_minimal = (PrinterMinimal*)calloc(sizeof(PrinterMinimal), PRINTER_CONFIG_COUNT);
semaphore_init();
printer.print_filename = filename_buff;
fetch_printer_data();

View File

@@ -462,6 +462,7 @@ PrinterDataMinimal KlipperPrinter::fetch_min()
void KlipperPrinter::disconnect()
{
// Nothing to disconnect, everything is http request based
printer_data.state = PrinterStateOffline;
}
Macros KlipperPrinter::get_macros()

View File

@@ -6,9 +6,8 @@
static void set_fan_speed_text(lv_event_t * e) {
lv_obj_t * label = lv_event_get_target(e);
KlipperPrinter* printer = (KlipperPrinter*)get_current_printer(); // TODO: pass by ref
char data[16];
sprintf(data, "Fan: %.0f%%", printer->printer_data.fan_speed * 100);
sprintf(data, "Fan: %.0f%%", get_current_printer_data()->fan_speed * 100);
lv_label_set_text(label, data);
}
@@ -43,7 +42,7 @@ static void set_zoffset_text_ex(lv_event_t * e) {
lv_obj_t * label = lv_event_get_target(e);
KlipperPrinter* printer = (KlipperPrinter*)get_current_printer(); // TODO: pass by ref
char data[32];
sprintf(data, "Z Offset: %.03f, Z: %.03f", printer->gcode_offset[2], printer->printer_data.position[2]);
sprintf(data, "Z Offset: %.03f, Z: %.03f", printer->gcode_offset[2], get_current_printer_data()->position[2]);
lv_label_set_text(label, data);
}
@@ -82,9 +81,8 @@ lv_button_column_t zoffset_columns[] = {
static void set_speed_mult_text(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
KlipperPrinter* printer = (KlipperPrinter*)get_current_printer(); // TODO: pass by ref
char data[16];
sprintf(data, "Speed: %.0f%%", printer->printer_data.speed_mult * 100);
sprintf(data, "Speed: %.0f%%", get_current_printer_data()->speed_mult * 100);
lv_label_set_text(label, data);
}
@@ -99,8 +97,8 @@ static void set_speed_mult(lv_event_t * e){
static void set_speed_mult_offset(lv_event_t * e){
int speed = (int)lv_event_get_user_data(e);
KlipperPrinter* printer = (KlipperPrinter*)get_current_printer(); // TODO: pass by ref
float result = printer->printer_data.speed_mult * 100 + speed;
printer->printer_data.speed_mult = result / 100;
float result = get_current_printer_data()->speed_mult * 100 + speed;
get_current_printer_data()->speed_mult = result / 100;
char gcode[16];
sprintf(gcode, "M220 S%.0f", result);
printer->send_gcode(gcode);
@@ -121,9 +119,8 @@ lv_button_column_t speed_mult_columns[] = {
static void set_extrude_mult_text(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
KlipperPrinter* printer = (KlipperPrinter*)get_current_printer(); // TODO: pass by ref
char data[16];
sprintf(data, "Flow: %.0f%%", printer->printer_data.extrude_mult * 100);
sprintf(data, "Flow: %.0f%%", get_current_printer_data()->extrude_mult * 100);
lv_label_set_text(label, data);
}
@@ -138,8 +135,8 @@ static void set_extrude_mult(lv_event_t * e){
static void set_extrude_mult_offset(lv_event_t * e){
int speed = (int)lv_event_get_user_data(e);
KlipperPrinter* printer = (KlipperPrinter*)get_current_printer(); // TODO: pass by ref
float result = printer->printer_data.extrude_mult * 100 + speed;
printer->printer_data.extrude_mult = result / 100;
float result = get_current_printer_data()->extrude_mult * 100 + speed;
get_current_printer_data()->extrude_mult = result / 100;
char gcode[16];
sprintf(gcode, "M221 S%.0f", result);
printer->send_gcode(gcode);
@@ -160,7 +157,7 @@ static void open_fan_speed_panel(lv_event_t * e){
}
static void open_zoffset_panel(lv_event_t * e){
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_zoffset_text_ex, zoffset_columns, (get_current_printer()->printer_data.state == PrinterStateIdle) ? 3 : 2);
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_zoffset_text_ex, zoffset_columns, get_current_printer_data()->state == PrinterStateIdle ? 3 : 2);
}
static void open_speed_mult_panel(lv_event_t * e){

View File

@@ -69,4 +69,9 @@ BasePrinter* get_current_printer()
BasePrinter* get_printer(int idx)
{
return registered_printers + idx;
}
PrinterData* get_current_printer_data()
{
return printer_data_copy;
}

View File

@@ -132,14 +132,14 @@ class BasePrinter
{
protected:
unsigned char config_index{};
GLOBAL_CONFIG* global_config{};
PrinterData printer_data{};
PRINTER_CONFIG* printer_config{};
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;
@@ -165,4 +165,5 @@ class BasePrinter
BasePrinter* get_current_printer();
BasePrinter* get_printer(int idx);
void initialize_printers();
void initialize_printers();
PrinterData* get_current_printer_data();