jukebox42 / Octoprint-PrusaMMU

An Octoprint plugin that adds MMU support.
GNU Affero General Public License v3.0
17 stars 2 forks source link

Octoprint-PrusaMMU

For MK3.5/3.9/5 you cannot use single print profile. You MUST use use the MMU profile with a single filament, what you pick doesn't matter, we will overwrite the filament with the tool you choose.

Description: This plugin adds Prusa MMU support to OctoPrint. The active filament will be displayed in the navbar and you will be prompted to select which filament to use when slicing in "MMU Single" mode. Other settings are available to name each tool and set defaults. This plugin only works for Prusa printers with an MMU. Supports MK3s/3.5/3.9/4 MMU3 firmware 3.X.X.

This plugin was inspired by the MMU2filamentselect plugin. I wanted to try and take it a step further.

Install via the bundled Plugin Manager or manually by selecting the latest zip:

https://github.com/jukebox42/Octoprint-PrusaMMU/releases/latest/download/Octoprint-PrusaMmu.zip

Highlighted Featured

Screenshots

Modal

Navbar

Error

Settings

GCode Interactions

This plugin does some minimal gcode manipulation. This is how it detects tool events and pause the print to provide the dialog.

MK3s MMU 3.X.X - Single Print

The command interactions are as follows:

MK3.5/3.9/4 MMU 3.X.X - Single Print

Note Prusa removed the single print profile which served a Tx we use to do the detection. We use something different for MK3.5+. For MK3.5+ you cannot use single print profile. You MUST use use the MMU profile with a single filament, what you pick doesn't matter, we will overwrite the filament with the tool you choose.

When a print is started, the print is immediately pause and the user is prompted to select a filament. The plugin then stores the selected option and each time a T# is encountered, it rewrites the command to the chosen tool. If the dialog times out, the print will continue with the sliced tool. This behavior varies from the MK3 which will pause at the printer.

This does mean you will always get the prompt modal for every print, but you can click skip and have it preserve the default behavior. In a future release, I will try to read ahead and figure out if only one tool was used in the profile.

MK3s MMU 3.X.X - MMU State Detection

The MMU 3.X.X firmware communicates continuously with the printer. The printer sends the MMU requests, and the MMU sends back responses. The MMU's responses start with the request letter and data, so it just listens for the Responses.

MMU 3.X.X responses come in this format: MMU2:<(Request Letter)(Request Data) (Response Letter)(Response Data)

Several Regex strings are used to parse the MMU 3.X.X responses:

Additionally, it also listens for these lines:

For all instances where command manipulation happens see __init__.py for Gcode Hooks. Also look at function _timeout_prompt where it handles unpausing the printer after the timer and either sending a Tx or T# if useDefaultFilament and defaultFilament settings are set.

MK3.5/3.9/4 MMU 3.X.X - MMU State Detection

It listens to printer responses and does some substring matching. This is done to identify filament events and printer notifications, so it can update the navbar: (gcode_received_hook)

Known Bugs

  1. In rare instances, the "waiting for user input" event can come in directly after a tool change is sent, resulting in the navbar never updating. This will not impact printing, but you will see "Awaiting user input" until the next tool change.
  2. If the Prusa printer prompts the user for a "new version", the select filament modal may not display. You will still be able to select the filament directly on the printer.
  3. MK3 printers will look like MK3S in the debug logs. They operate the same, this was easier to implement.
  4. If the plugin is having trouble detecting the version of Prusa you have, use Prusa Version option in settings to fix it to a version.

Developer Zone

States

Here is a list of states used internally. These will be the state value in events.

Errors

New when using MK3s MMU 3.0.0! (Not available for MK4 users)

When the MMU throws an error you'll see a command come across like MMU2:<X0 E800d. The E Response Letter represents there being an Error and the 800d is the hex Response Data of the error.

We map those hex codes in static/mmuErrors.js to get the details about the errors. Mapping was done by hand (i'll automate it eventually). To get the url of the error you just need to append the code value from the MMU2MmuErrorStrings map to https://prusa.io/ like https://prusa.io/04306.

Events

A number of events are fired you can listen to.

plugin_prusammu_mmu_changed

MMU data changed; Either state, tool, previous tool, response, or response data was updated.

Payload:

{
  state: string
  tool: int
  previousTool: int
  response: string
  responseData: string
  prusaVersion: string
}

plugin_prusammu_mmu_change

MMU data may change. This is fired by a number of things internal to the plugin, what's important is that this does not indicate a change happened, just that one may happen. It's strongly recommended to listen on plugin_prusammu_mmu_changed instead unless you need to react before a change occurs. The plugin internally dedupes these events by comparing the new with the old and only triggering when there's a change.

Payload:

{
  state: string
  tool: int
  previousTool: int
  response: string
  responseData: string
  prusaVersion: string
}

plugin_prusammu_show_prompt

The plugin heard a Tx (or a print was started if you use are using an MK4) and needs to prompt the user to pick the filament.

Payload: None

plugin_prusammu_refresh_nav

Used to force the UI to refresh it's MMU data (like on page refresh).

Payload: None

API Endpoints

This plugin makes use of simpleApiCommand for some instances to stay up to date. You can use these endpoints yourself if you want to get information about the MMU via a POST.

<octoprint server>/api/plugin/prusammu

getmmu

Call to get the current state of the MMU.

Request:

{ "command": "getmmu" }

Response:

{
  lastLine: string
  state: string
  tool: int
  previousTool: int
  response: string
  responseData: string
  prusaVersion: string
}

Response: None

Exposed Javascript Functions

A small set of javascript functions are available to interact with. Look at the getFilamentList() function for how you can interact with them.

getFilamentList()

Returns the filament array. This will contain all the filament data based on the source selected. This is what's used to get the data for the prompt as well as navbar item. The resultset may include 1-5 entries based on what's specified by the source.

Returns:

[
  {id: 1, index: 0, name: "", type: "", color: "", enabled: true},
  {id: 2, index: 1, name: "", type: "", color: "", enabled: true},
  {id: 3, index: 2, name: "", type: "", color: "", enabled: true},
  {id: 4, index: 3, name: "", type: "", color: "", enabled: true},
  {id: 5, index: 4, name: "", type: "", color: "", enabled: true},
]

Filament object properties:

processMmuProgress(responseData)

Given the progress code it returns a string containing the progress message.

If the value of responseData is one of [P, E, F, A, R] than you can pass responseData to get more details about the progress like "Unloading to FINDA".

Returns: string

processMmuError(responseData)

Given the error code it generates an error object with more information.

If the value of response is E (Error) you can send this function responseData to get the error details.

Returns:

{
  code: "04401",
  title: "MMU NOT RESPONDING",
  text: "MMU not responding. Check the wiring and connectors.",
  url: `https://prusa.io/802e`,
}

Object properties:

Working on the PrusaMMU plugin

Adding a Filament Source

If you too would like to add your filament/spool manager as a valid source for this plugin you need to update the following areas:

Debugging

Enable debug logs via the settings menu, ensure logging is set to the debug level for prusammu. Note: This may slow down printing.

Octoprint exposes the viewmodel via:

> OctoPrint.coreui.viewmodels.prusaMMU2ViewModel

Building

You can manually build this project into a zip by running:

$ bash build.sh [VERSION]

# ex:
$ bash build.sh 2022.7.4
=== Building PrusaMMU ===

Settings:
- Version: 2022.7.4

Writing plugin version... done
Disabling debug... done
Zipping... done
Done.

Versioning

Versioning is done by date, so it's clear when the build was installed and made available. Year is four characters long. Month is one or two characters long and does not have a leading zero for sub ten. Day follows the same rules as month. Beta versions are denoted by a "b" directly following the day and then a number describing what beta version it is. Sequentially 2022.1.1a0 comes before 2022.1.1.

Format:

YYYY.M.D
YYYY.M.Da#

Examples:

2022.10.4
2022.1.20
2022.1.20a0

Contribution

I built this plugin for fun, and because I wanted better MMU support. If you catch a bug or think it needs some work feel free to open a PR or cut an issue, and I'll do my best to review it.

You know how some software grows organically and by the time you realize it's gotten out of control it's too late? Yeah that's this. Sorry in advance for those of you trying to parse the code.

Special thanks to:

Useful Link