Skip to content

Commit cfb2f09

Browse files
Implement filament retract/extrude and load/unload
1 parent fb40977 commit cfb2f09

File tree

12 files changed

+369
-61
lines changed

12 files changed

+369
-61
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ serde = "1.0"
1414
tokio = { version = "1", features = ["full"]}
1515
moonraker-rs = { path = "./moonraker-rs"}
1616
image = { version = "0", default-features = false, features = ["png"] }
17+
optional_struct = "0"
1718

1819
[target.'cfg(unix)'.dependencies]
1920
evdev = "0"

src/config/config.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::HashMap;
22

3-
use crate::config::MoonrakerConfig;
3+
use crate::config::{MoonrakerConfig, OptionalGcodeCommands};
44
use moonraker_rs::printer_objects::TemperatureConfiguration;
55
use serde::Deserialize;
66

@@ -11,4 +11,5 @@ pub struct Config {
1111
pub display: DisplayConfig,
1212
pub moonraker: Option<MoonrakerConfig>,
1313
pub heater_presets: Option<HashMap<String, Vec<u32>>>,
14+
pub gcode_commands: Option<OptionalGcodeCommands>,
1415
}

src/config/gcode_commands.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use optional_struct::optional_struct;
2+
use serde::Deserialize;
3+
4+
#[optional_struct]
5+
#[derive(Deserialize, Debug)]
6+
pub struct GcodeCommands
7+
{
8+
pub extruder_extrude: String,
9+
pub extruder_retract: String,
10+
pub extruder_load_filament: String,
11+
pub extruder_unload_filament: String,
12+
}
13+
14+
impl Default for GcodeCommands {
15+
fn default() -> Self {
16+
Self {
17+
extruder_extrude: "M83\nG1 E25 F300".into(),
18+
extruder_retract: "M83\nG1 E-25 F300".into(),
19+
extruder_load_filament: "LOAD_FILAMENT".into(),
20+
extruder_unload_filament: "UNLOAD_FILAMENT".into(),
21+
}
22+
}
23+
}

src/config/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub mod display_default;
55
#[cfg(unix)]
66
pub mod display_fb;
77
pub mod moonraker;
8+
pub mod gcode_commands;
89

910
pub use cli::*;
1011
pub use config::*;
@@ -13,3 +14,4 @@ pub use display_default::*;
1314
#[cfg(unix)]
1415
pub use display_fb::*;
1516
pub use moonraker::*;
17+
pub use gcode_commands::*;

src/main.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use moonraker_rs::{
1010
use slint::{Image, Model, ModelRc, Rgba8Pixel, SharedPixelBuffer, SharedString, VecModel};
1111
use tokio::sync::Mutex;
1212

13-
use crate::{config::MoonrakerConfig, event_loop::EventLoop, hardware::init_display, ui_functions::{register_filesystem_download_thumbnails, register_filesystem_list_files, register_printer_emergency_stop, register_printer_firmware_restart, register_printer_restart, register_temperature_set_new_target_temperature, register_util_format_bytes, register_util_image_exists, register_util_prettify_name}};
13+
use crate::{config::{MoonrakerConfig, OptionalGcodeCommands}, event_loop::EventLoop, hardware::init_display, ui_functions::{register_extruder_extrude, register_extruder_load_filament, register_extruder_retract, register_extruder_unload_filament, register_filesystem_download_thumbnails, register_filesystem_list_files, register_printer_emergency_stop, register_printer_firmware_restart, register_printer_restart, register_temperature_set_new_target_temperature, register_util_format_bytes, register_util_image_exists, register_util_prettify_name}};
1414

1515
mod application_error;
1616
mod config;
@@ -95,6 +95,12 @@ async fn main() -> Result<(), Box<dyn Error>> {
9595
register_printer_firmware_restart(&ui, &moonraker_connection);
9696
register_printer_restart(&ui, &moonraker_connection);
9797

98+
let gcode_command_config = &config.gcode_commands.unwrap_or(OptionalGcodeCommands::default());
99+
register_extruder_extrude(&ui, &moonraker_connection, gcode_command_config);
100+
register_extruder_retract(&ui, &moonraker_connection, gcode_command_config);
101+
register_extruder_load_filament(&ui, &moonraker_connection, gcode_command_config);
102+
register_extruder_unload_filament(&ui, &moonraker_connection, gcode_command_config);
103+
98104
tokio::task::block_in_place(|| {
99105
ui.run().unwrap();
100106
});

src/ui_functions/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod temperature_set_new_target_temperature;
77
pub mod printer_emergency_stop;
88
pub mod printer_restart;
99
pub mod printer_firmware_restart;
10+
pub mod printer_execute_gcode_command;
1011

1112
pub use util_format_bytes::*;
1213
pub use filesystem_download_thumbnail::*;
@@ -16,4 +17,5 @@ pub use util_prettify_name::*;
1617
pub use temperature_set_new_target_temperature::*;
1718
pub use printer_emergency_stop::*;
1819
pub use printer_restart::*;
19-
pub use printer_firmware_restart::*;
20+
pub use printer_firmware_restart::*;
21+
pub use printer_execute_gcode_command::*;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use std::sync::Arc;
2+
3+
use moonraker_rs::{moonraker_connection::{MoonrakerConnection}, requests::PrinterAdministrationRequestHandler};
4+
use slint::ComponentHandle;
5+
6+
use crate::{config::OptionalGcodeCommands, config::GcodeCommands as GcodeCommandsConfig, AppWindow, GcodeCommands};
7+
8+
9+
pub fn run_command(moonraker_connection : &Arc<MoonrakerConnection>, command : &str)
10+
{
11+
let command = command.to_string();
12+
let moonraker_connection = Arc::clone(moonraker_connection);
13+
// TODO: For other callbacks that don't use the slint main thread, maybe don't run them on the slint event loop?
14+
tokio::spawn(async move {
15+
if let Err(e) = moonraker_connection.run_gcode_script(&command).await
16+
{
17+
moonraker_connection.send_request_error(format!("Failed to send G-code command '{}': {}", command, e));
18+
}
19+
});
20+
}
21+
22+
pub fn register_extruder_extrude(ui: &AppWindow, moonraker_connection : &Arc<MoonrakerConnection>, gcode_command_config : &OptionalGcodeCommands)
23+
{
24+
let command = gcode_command_config.extruder_extrude.clone().unwrap_or(GcodeCommandsConfig::default().extruder_extrude);
25+
let moonraker_connection = Arc::clone(moonraker_connection);
26+
27+
ui.global::<GcodeCommands>().set_extruder_extrude_available(!command.is_empty());
28+
ui.global::<GcodeCommands>().on_extruder_extrude(move || {
29+
run_command(&moonraker_connection, &command);
30+
});
31+
}
32+
33+
pub fn register_extruder_retract(ui: &AppWindow, moonraker_connection : &Arc<MoonrakerConnection>, gcode_command_config : &OptionalGcodeCommands)
34+
{
35+
let command = gcode_command_config.extruder_retract.clone().unwrap_or(GcodeCommandsConfig::default().extruder_retract);
36+
let moonraker_connection = Arc::clone(moonraker_connection);
37+
38+
ui.global::<GcodeCommands>().set_extruder_retract_available(!command.is_empty());
39+
ui.global::<GcodeCommands>().on_extruder_retract(move || {
40+
run_command(&moonraker_connection, &command);
41+
});
42+
}
43+
44+
pub fn register_extruder_load_filament(ui: &AppWindow, moonraker_connection : &Arc<MoonrakerConnection>, gcode_command_config : &OptionalGcodeCommands)
45+
{
46+
let command = gcode_command_config.extruder_load_filament.clone().unwrap_or(GcodeCommandsConfig::default().extruder_load_filament);
47+
let moonraker_connection = Arc::clone(moonraker_connection);
48+
49+
ui.global::<GcodeCommands>().set_extruder_load_filament_available(!command.is_empty());
50+
ui.global::<GcodeCommands>().on_extruder_load_filament(move || {
51+
run_command(&moonraker_connection, &command);
52+
});
53+
}
54+
55+
pub fn register_extruder_unload_filament(ui: &AppWindow, moonraker_connection : &Arc<MoonrakerConnection>, gcode_command_config : &OptionalGcodeCommands)
56+
{
57+
let command = gcode_command_config.extruder_unload_filament.clone().unwrap_or(GcodeCommandsConfig::default().extruder_unload_filament);
58+
let moonraker_connection = Arc::clone(moonraker_connection);
59+
60+
ui.global::<GcodeCommands>().set_extruder_unload_filament_available(!command.is_empty());
61+
ui.global::<GcodeCommands>().on_extruder_unload_filament(move || {
62+
run_command(&moonraker_connection, &command);
63+
});
64+
}

ui/assets/arrow-down.svg

Lines changed: 1 addition & 0 deletions
Loading

ui/assets/eject.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)