diff --git a/CYD-Klipper/src/core/macros_query.cpp b/CYD-Klipper/src/core/macros_query.cpp index 0b6e9b0..9acb12e 100644 --- a/CYD-Klipper/src/core/macros_query.cpp +++ b/CYD-Klipper/src/core/macros_query.cpp @@ -4,15 +4,16 @@ #include #include "../conf/global_config.h" #include +#include static char* macros[64] = {0}; static int macros_count = 0; -static void on_state_change(void * s, lv_msg_t * m) { - if (printer.state == PRINTER_STATE_ERROR || printer.state == PRINTER_STATE_PAUSED){ - return; - } +static char* power_devices[16] = {0}; +static bool power_device_states[16] = {0}; +static int power_devices_count = 0; +static void _macros_query_internal(){ String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/gcode/help"; HTTPClient client; client.useHTTP10(true); @@ -41,10 +42,69 @@ static void on_state_change(void * s, lv_msg_t * m) { } } +static void _power_devices_query_internal(){ + String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/machine/device_power/devices"; + HTTPClient client; + client.useHTTP10(true); + client.begin(url.c_str()); + int httpCode = client.GET(); + if (httpCode == 200){ + JsonDocument doc; + deserializeJson(doc, client.getStream()); + auto result = doc["result"]["devices"].as(); + + for (int i = 0; i < power_devices_count; i++){ + free(power_devices[i]); + } + + power_devices_count = 0; + + for (auto i : result){ + const char * device_name = i["device"]; + const char * device_state = i["status"]; + power_devices[power_devices_count] = (char*)malloc(strlen(device_name) + 1); + strcpy(power_devices[power_devices_count], device_name); + power_device_states[power_devices_count] = strcmp(device_state, "on") == 0; + power_devices_count++; + } + } +} + +static void on_state_change(void * s, lv_msg_t * m) { + if (printer.state == PRINTER_STATE_ERROR || printer.state == PRINTER_STATE_PAUSED){ + return; + } + + _macros_query_internal(); + _power_devices_query_internal(); +} + +bool set_power_state(const char* device_name, bool state) { + String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/machine/device_power/device?device=" + urlEncode(device_name) + "&action=" + (state ? "on" : "off"); + HTTPClient client; + client.useHTTP10(true); + client.begin(url.c_str()); + if (client.POST("") != 200) + return false; + + for (int i = 0; i < power_devices_count; i++){ + if (strcmp(power_devices[i], device_name) == 0){ + power_device_states[i] = state; + return true; + } + } + + return true; +} + MACROSQUERY macros_query() { return {(const char**)macros, (unsigned int)macros_count}; } +POWERQUERY power_devices_query() { + return {(const char**)power_devices, (const bool*)power_device_states, (unsigned int)power_devices_count}; +} + void macros_query_setup(){ lv_msg_subscribe(DATA_PRINTER_STATE, on_state_change, NULL); on_state_change(NULL, NULL); diff --git a/CYD-Klipper/src/core/macros_query.h b/CYD-Klipper/src/core/macros_query.h index 5fdee3f..954350e 100644 --- a/CYD-Klipper/src/core/macros_query.h +++ b/CYD-Klipper/src/core/macros_query.h @@ -5,5 +5,13 @@ typedef struct { uint32_t count; } MACROSQUERY; +typedef struct { + const char** power_devices; + const bool* power_states; + uint32_t count; +} POWERQUERY; + MACROSQUERY macros_query(); -void macros_query_setup(); \ No newline at end of file +POWERQUERY power_devices_query(); +void macros_query_setup(); +bool set_power_state(const char* device_name, bool state); \ No newline at end of file diff --git a/CYD-Klipper/src/ui/main_ui.cpp b/CYD-Klipper/src/ui/main_ui.cpp index 373e54c..a6f1184 100644 --- a/CYD-Klipper/src/ui/main_ui.cpp +++ b/CYD-Klipper/src/ui/main_ui.cpp @@ -40,7 +40,7 @@ void error_ui_macros_open(lv_event_t * e){ lv_label_set_text(label, LV_SYMBOL_CLOSE " Close"); lv_obj_center(label); - macros_panel_add_macros_to_panel(panel, macros_query()); + macros_panel_add_power_devices_to_panel(panel, power_devices_query()); } void error_ui(){ @@ -84,14 +84,14 @@ void error_ui(){ lv_label_set_text(label, "FW Restart"); lv_obj_center(label); - if (macros_query().count >= 1){ + if (power_devices_query().count >= 1){ btn = lv_btn_create(button_row); lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_obj_add_event_cb(btn, error_ui_macros_open, LV_EVENT_CLICKED, NULL); lv_obj_set_flex_grow(btn, 1); label = lv_label_create(btn); - lv_label_set_text(label, "Macros"); + lv_label_set_text(label, "Devices"); lv_obj_center(label); } } diff --git a/CYD-Klipper/src/ui/nav_buttons.cpp b/CYD-Klipper/src/ui/nav_buttons.cpp index 4bc7cb2..fbdd5e6 100644 --- a/CYD-Klipper/src/ui/nav_buttons.cpp +++ b/CYD-Klipper/src/ui/nav_buttons.cpp @@ -109,7 +109,7 @@ void nav_buttons_setup(unsigned char active_panel){ create_button(LV_SYMBOL_COPY, "Idle", btn_click_files, update_printer_data_time, root_panel); // Move - create_button(LV_SYMBOL_CHARGE, "Z?", btn_click_move, update_printer_data_z_pos, root_panel); + create_button(printer.state == PRINTER_STATE_PRINTING ? LV_SYMBOL_EDIT : LV_SYMBOL_CHARGE, "Z?", btn_click_move, update_printer_data_z_pos, root_panel); // Extrude/Temp create_button(LV_SYMBOL_WARNING, "?/?", btn_click_extrude, update_printer_data_temp, root_panel); diff --git a/CYD-Klipper/src/ui/panels/macros_panel.cpp b/CYD-Klipper/src/ui/panels/macros_panel.cpp index 68f2ea0..160cd17 100644 --- a/CYD-Klipper/src/ui/panels/macros_panel.cpp +++ b/CYD-Klipper/src/ui/panels/macros_panel.cpp @@ -3,6 +3,7 @@ #include "../nav_buttons.h" #include "../../core/data_setup.h" #include "../../core/macros_query.h" +#include "../../conf/global_config.h" #include "../ui_utils.h" #include @@ -19,12 +20,7 @@ static void btn_goto_settings(lv_event_t * e){ nav_buttons_setup(3); } -void macros_panel_add_macros_to_panel(lv_obj_t * panel, MACROSQUERY query){ - lv_obj_t * root_panel = lv_create_empty_panel(panel); - lv_obj_set_size(root_panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_MIN_BUTTON_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2); - lv_obj_align(root_panel, LV_ALIGN_TOP_MID, 0, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX + CYD_SCREEN_GAP_PX * 2); - lv_layout_flex_column(root_panel); - +void macros_panel_add_macros_to_panel(lv_obj_t * root_panel, MACROSQUERY query){ for (int i = 0; i < query.count; i++){ const char* macro = query.macros[i]; @@ -52,6 +48,42 @@ void macros_panel_add_macros_to_panel(lv_obj_t * panel, MACROSQUERY query){ } } +static void power_device_toggle(lv_event_t * e){ + auto state = lv_obj_get_state(lv_event_get_target(e)); + bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); + const char* power_device_name = (const char*)lv_event_get_user_data(e); + Serial.printf("Power Device: %s, State: %d -> %d\n", power_device_name, !checked, checked); + + set_power_state(power_device_name, checked); +} + +void macros_panel_add_power_devices_to_panel(lv_obj_t * root_panel, POWERQUERY query){ + for (int i = 0; i < query.count; i++){ + const char* power_device_name = query.power_devices[i]; + const bool power_device_state = query.power_states[i]; + + lv_obj_t * panel = lv_create_empty_panel(root_panel); + lv_layout_flex_row(panel, LV_FLEX_ALIGN_END); + lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 3, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); + + lv_obj_t * label = lv_label_create(panel); + lv_label_set_text(label, power_device_name); + lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_obj_set_flex_grow(label, 1); + + lv_obj_t * toggle = lv_switch_create(panel); + lv_obj_add_event_cb(toggle, power_device_toggle, LV_EVENT_VALUE_CHANGED, (void*)power_device_name); + lv_obj_set_size(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); + if (power_device_state) + lv_obj_add_state(toggle, LV_STATE_CHECKED); + + lv_obj_t * line = lv_line_create(root_panel); + lv_line_set_points(line, line_points, 2); + lv_obj_set_style_line_width(line, 1, 0); + lv_obj_set_style_line_color(line, lv_color_hex(0xAAAAAA), 0); + } +} + void macros_panel_init(lv_obj_t* panel) { lv_obj_t * btn = lv_btn_create(panel); lv_obj_add_event_cb(btn, btn_goto_settings, LV_EVENT_CLICKED, NULL); @@ -63,12 +95,19 @@ void macros_panel_init(lv_obj_t* panel) { lv_obj_center(label); MACROSQUERY query = macros_query(); - if (query.count == 0){ + POWERQUERY power = power_devices_query(); + if (query.count == 0 && power.count == 0){ label = lv_label_create(panel); lv_label_set_text(label, "No macros found.\nMacros with the description\n\"CYD_SCREEN_MACRO\"\nwill show up here."); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); return; } - macros_panel_add_macros_to_panel(panel, query); + lv_obj_t * root_panel = lv_create_empty_panel(panel); + lv_obj_set_size(root_panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_MIN_BUTTON_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2); + lv_obj_align(root_panel, LV_ALIGN_TOP_MID, 0, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX + CYD_SCREEN_GAP_PX * 2); + lv_layout_flex_column(root_panel); + + macros_panel_add_power_devices_to_panel(root_panel, power); + macros_panel_add_macros_to_panel(root_panel, query); } \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/panel.h b/CYD-Klipper/src/ui/panels/panel.h index 1457f9f..d69910a 100644 --- a/CYD-Klipper/src/ui/panels/panel.h +++ b/CYD-Klipper/src/ui/panels/panel.h @@ -10,4 +10,4 @@ void move_panel_init(lv_obj_t* panel); void progress_panel_init(lv_obj_t* panel); void macros_panel_init(lv_obj_t* panel); void stats_panel_init(lv_obj_t* panel); -void macros_panel_add_macros_to_panel(lv_obj_t * panel, MACROSQUERY query); \ No newline at end of file +void macros_panel_add_power_devices_to_panel(lv_obj_t * panel, POWERQUERY query); \ No newline at end of file