MoonrakerClient API
The MoonrakerClient is the core component for communicating with Moonraker via WebSocket.
Struct Definition
pub struct MoonrakerClient {
// Internal implementation details
}Methods
connect
Establishes a WebSocket connection to Moonraker.
pub async fn connect(url: &str) -> Result<Self>Parameters:
url- WebSocket URL (e.g.,ws://192.168.1.100:7125/websocket)
Returns:
Result<MoonrakerClient>- Connected client or error
Example:
let client = MoonrakerClient::connect("ws://localhost:7125/websocket").await?;send_gcode
Sends a G-code command to the printer.
pub async fn send_gcode(&mut self, gcode: &str) -> Result<()>Parameters:
gcode- G-code command or Klipper macro to execute
Returns:
Result<()>- Success or error
Special Handling:
- M112 commands trigger emergency stop
- Commands are sent via
printer.gcode.scriptJSON-RPC method
Example:
client.send_gcode("G28").await?;
client.send_gcode("M104 S200").await?;
client.send_gcode("PRINT_START").await?;get_macros
Retrieves available G-code commands and macros from Klipper.
pub async fn get_macros(&mut self) -> Result<Vec<String>>Returns:
Result<Vec<String>>- List of available command names
Example:
let macros = client.get_macros().await?;
for macro_name in macros {
println!("{}", macro_name);
}try_receive_message
Non-blocking check for incoming messages from Moonraker.
pub fn try_receive_message(&mut self) -> Option<String>Returns:
Some(String)- Message if availableNone- No message ready
Example:
while let Some(msg) = client.try_receive_message() {
println!("Received: {}", msg);
}disconnect
Closes the WebSocket connection gracefully.
pub async fn disconnect(self) -> Result<()>Example:
client.disconnect().await?;Helper Functions
format_response
Formats and prints a Moonraker response with appropriate coloring.
pub fn format_response(response: &str)Parameters:
response- Raw JSON-RPC response from Moonraker
Color Coding:
- Green: Successful responses, "ok" messages
- Cyan: Informational messages
- Yellow: Warnings, "//" prefixed messages
- Red: Errors, "!!" prefixed messages
Example:
let msg = client.try_receive_message();
if let Some(response) = msg {
format_response(&response);
}Message Flow
Connection
- Client calls
connect(url) - WebSocket established
- Client subscribes to printer status updates
- Client is ready for commands
Sending Commands
- Client calls
send_gcode(command) - Command wrapped in JSON-RPC request
- Sent via WebSocket
- Moonraker processes command
- Responses arrive asynchronously
Receiving Messages
Messages from Moonraker come in several forms:
Response Messages
{
"jsonrpc": "2.0",
"result": "ok",
"id": 1
}Notification Messages
{
"jsonrpc": "2.0",
"method": "notify_gcode_response",
"params": ["// Homing complete"]
}Status Updates
{
"jsonrpc": "2.0",
"method": "notify_status_update",
"params": [{
"eventtime": 123456.789,
"status": {
"extruder": {
"temperature": 200.5,
"target": 200.0
}
}
}]
}Error Handling
All methods return Result<T> using the anyhow crate:
use anyhow::Result;
async fn example() -> Result<()> {
let mut client = MoonrakerClient::connect("ws://localhost:7125/websocket").await?;
client.send_gcode("G28").await?;
client.disconnect().await?;
Ok(())
}Complete Example
use moonriver::moonraker::MoonrakerClient;
use anyhow::Result;
#[tokio::main]
async fn main() -> Result<()> {
// Connect
let mut client = MoonrakerClient::connect(
"ws://192.168.1.100:7125/websocket"
).await?;
// Send commands
client.send_gcode("G28").await?;
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
client.send_gcode("M105").await?;
tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
// Process responses
while let Some(msg) = client.try_receive_message() {
moonriver::moonraker::format_response(&msg);
}
// Disconnect
client.disconnect().await?;
Ok(())
}Thread Safety
MoonrakerClient is not thread-safe. Use one client per connection and don't share across threads without proper synchronization.
For multiple printers, create multiple client instances.
Async Requirements
All I/O methods are async and require a Tokio runtime:
#[tokio::main]
async fn main() -> Result<()> {
// Your async code here
}Next Steps
- REPL API - Interactive interface
- Usage Examples - Practical examples
- Source Code - Implementation details