From fd901fd1e1fa1aebab3732bb838b88943d0c48c7 Mon Sep 17 00:00:00 2001 From: JonatanRek <vasek@steelants.cz> Date: Mon, 10 Mar 2025 11:49:05 +0100 Subject: [PATCH] Working Print FIle Action --- __init__.py | 18 ++++++++++++++++++ automation.h | 36 ++++++++++++++++++++++++++---------- marlin2.cpp | 38 ++++++++++++++++++++++++++++++++++---- marlin2.h | 4 +++- 4 files changed, 81 insertions(+), 15 deletions(-) diff --git a/__init__.py b/__init__.py index 451369f..b07e26c 100644 --- a/__init__.py +++ b/__init__.py @@ -27,6 +27,7 @@ CONF_MARLIN2_ID = "marlin2_id" Marlin2 = cg.esphome_ns.class_('Marlin2', cg.Component) WriteAction = cg.esphome_ns.class_("WriteAction", automation.Action) +PrintFileAction = cg.esphome_ns.class_("PrintFileAction", automation.Action) CONFIG_SCHEMA = cv.All( cv.Schema({ @@ -56,6 +57,11 @@ OPERATION_BASE_SCHEMA = cv.Schema({ cv.Required(CONF_VALUE): cv.templatable(cv.string_strict), }) +OPERATION_BASE_SCHEMA_2 = cv.Schema({ + cv.GenerateID(): cv.use_id(Marlin2), + cv.Required(CONF_VALUE): cv.templatable(cv.string_strict), +}) + @automation.register_action( "marlin2.write", WriteAction, @@ -63,6 +69,18 @@ OPERATION_BASE_SCHEMA = cv.Schema({ ) async def marlin2_write_to_code(config, action_id, template_arg, args): + paren = await cg.get_variable(config[CONF_ID]) + var = cg.new_Pvariable(action_id, template_arg, paren) + template_ = await cg.templatable(config[CONF_VALUE], args, cg.std_string) + cg.add(var.set_value(template_)) + return var + +@automation.register_action( + "marlin2.print_file", + PrintFileAction, + OPERATION_BASE_SCHEMA_2, +) +async def marlin2_print_file_to_code(config, action_id, template_arg, args): paren = await cg.get_variable(config[CONF_ID]) var = cg.new_Pvariable(action_id, template_arg, paren) template_ = await cg.templatable(config[CONF_VALUE], args, cg.std_string) diff --git a/automation.h b/automation.h index 327979a..767c407 100644 --- a/automation.h +++ b/automation.h @@ -5,18 +5,34 @@ #include "marlin2.h" namespace esphome { + static const char *TAG = "marlin2"; -template<typename... Ts> class WriteAction : public Action<Ts...> { - public: - explicit WriteAction(Marlin2 *marlin2) : marlin2_(marlin2) {} - TEMPLATABLE_VALUE(std::string, value) + template<typename... Ts> class WriteAction : public Action<Ts...> { + public: + explicit WriteAction(Marlin2 *marlin2) : marlin2_(marlin2) {} + TEMPLATABLE_VALUE(std::string, value) - void play(Ts... x) override { - this->marlin2_->write(this->value_.value(x...)); - } + void play(Ts... x) override { + this->marlin2_->write(this->value_.value(x...)); + } - protected: - Marlin2 *marlin2_; -}; + protected: + Marlin2 *marlin2_; + }; + + template<typename... Ts> class PrintFileAction : public Action<Ts...> { + public: + explicit PrintFileAction(Marlin2 *marlin2) : marlin2_(marlin2) {} + TEMPLATABLE_VALUE(std::string, value) + + void play(Ts... x) override { + std::string file_name = this->marlin2_->to_dos_name(this->value_.value(x...)); + ESP_LOGD(TAG, "->FILE: %s", file_name.c_str()); + this->marlin2_->write(str_sprintf("M32 P !%s#", file_name.c_str())); + } + + protected: + Marlin2 *marlin2_; + }; } // namespace esphome \ No newline at end of file diff --git a/marlin2.cpp b/marlin2.cpp index 1a7ba7c..83bd693 100644 --- a/marlin2.cpp +++ b/marlin2.cpp @@ -33,11 +33,13 @@ namespace esphome { } #endif - void Marlin2::setup() { MarlinOutput.reserve(256); MarlinOutput = ""; + MarlinResponseOutput.reserve(256); + MarlinResponseOutput = ""; + MarlinTime.reserve(32); PrinterState.reserve(32); @@ -52,7 +54,6 @@ namespace esphome { void Marlin2::write(std::string gcode) { ESP_LOGD(TAG, "->GCODE: %s", gcode.c_str()); - write_str((std::string("\r\n\r\n") + gcode + std::string("\r\n")).c_str()); flush(); } @@ -61,6 +62,7 @@ namespace esphome { while (available()) { char c = read(); if( c == '\n' || c == '\r' ) { + ESP_LOGD(TAG, "#%s#",MarlinOutput.c_str()); process_line(); } else { MarlinOutput += c; @@ -78,8 +80,6 @@ namespace esphome { } void Marlin2::process_line() { - ESP_LOGD(TAG, "#%s#",MarlinOutput.c_str()); - if(MarlinOutput.size() < 3) { MarlinOutput=""; return; @@ -300,4 +300,34 @@ namespace esphome { #endif } + std::string Marlin2::to_dos_name(std::string filename) { + std::string shortName; + size_t dotPos = filename.find_last_of('.'); + + // Extract name and extension + std::string namePart = (dotPos != std::string::npos) ? filename.substr(0, dotPos) : filename; + std::string extPart = (dotPos != std::string::npos) ? filename.substr(dotPos + 1) : ""; + + // Truncate name to 6 characters + ~1 + if (namePart.length() > 6) { + namePart = namePart.substr(0, 6) + "~1"; + } + + // Truncate extension to 3 characters + if (extPart.length() > 3) { + extPart = extPart.substr(0, 3); + } + + // Construct 8.3 filename + shortName = namePart; + if (!extPart.empty()) { + shortName += "." + extPart; + } + + // Convert to uppercase (DOS filenames are case-insensitive, usually stored in uppercase) + std::transform(shortName.begin(), shortName.end(), shortName.begin(), ::toupper); + + return shortName; + } + } // namespace esphome \ No newline at end of file diff --git a/marlin2.h b/marlin2.h index e34561e..ea52446 100644 --- a/marlin2.h +++ b/marlin2.h @@ -25,6 +25,7 @@ class Marlin2 : public PollingComponent, public uart::UARTDevice { text_sensor::TextSensor* find_text_sensor(std::string key); #endif void write(std::string status); + std::string to_dos_name(std::string file_name); float get_setup_priority() const override { return setup_priority::LATE; } void setup() override; @@ -32,6 +33,7 @@ class Marlin2 : public PollingComponent, public uart::UARTDevice { protected: std::string MarlinOutput; + std::string MarlinResponseOutput; std::string MarlinTime; std::string PrinterState; @@ -50,7 +52,7 @@ class Marlin2 : public PollingComponent, public uart::UARTDevice { int process_temp_msg(float* ext_temperature, float* ext_set_temperature, float* bed_temperature, float* bed_set_temperature); float process_progress_msg(); int process_print_time_msg(double* current, double* remaining, float progress); - + private: unsigned long millisProgress=0; };