jukebox42 / Octoprint-PrusaMMU

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

Integrate with Octodash #20

Closed AndersWinther-Dahl closed 1 year ago

AndersWinther-Dahl commented 1 year ago

Hi Jukebox42, I'm looking into if it's possible to integrate Prusa MMU with OctoDash.

If you could point me in the right direction, I would appreciate.

OctoDash is primarily coded in Angular, which I'm quite experienced in. But I'm not sure where to begin on integrating two different plug-ins.

It would be nice if OctoDash somehow could listen for events from your plug-in, and use the data about the filaments, to present on the small screen.

I don't expect OctoDash's maintainer to code it, so I would try to do it myself and make a PR for OctoDash.

Best regards, Anders

jukebox42 commented 1 year ago

Hey Anders,

I do have some events available that any other plugin should be able to listen to for state changes.

plugin_prusammu_mmu_changed will be fired every time a state change occurs (like loading, unloading, loaded, ect.). This is fired server side. Alternatively you can listen to the nav event fired by prusammu client side. In the prusammu.js file look for onDataUpdaterPluginMessage to see how you can listen to that event.

Either will give you a state string (see developer zone for state strings) and the tool numbers for both the tool and the previous tool.

To get the filament details(like name and color) you will need to get the list of filament and take the state data to figure out which one to display. I expose a function called getFilamentList() in js to let you get that data. Use the function instead of inspecting the plugin settings so you ensure you have accurate data(in the event the user is using a different source). I have an example of using a js function from another plugin inside of that function. You just need to ensure my view is a dependency of yours.

Let me know if that helps!

AndersWinther-Dahl commented 1 year ago

Hi John, Thank you for your good explanations.

I hope it's ok, to ask you for more info :-)

Just to clarify, I'm trying to reproduce / levitate on PrusaMMU in OctoDash. So when PrusaMMU gets activated, I will reproduce the same behavior in OctoDash and prompt for filament. The reason for not reimplementing PrusaMMU in OctoDash, is that I want to let them coexist, so that I can choose filament both in the PrusaMMU modal and on the touchscreen showing OctoDash. OctoDash is actually not a plugin, it runs for itself and integrates with OctoPrint.

Back to the code :-)

I can see that your events/messages gets emitted on OctoPrints WebSocket.

Both as "plugin" and "event" messages, e.g.:

a[{"event":{"type":"plugin_prusammu_show_prompt","payload":null}}]
a[{"plugin":{"plugin":"prusammu","data":{"action":"show"}}}]

OctoDash already monitors those messages, so I "just" have to extend that switch-case handling, and react on plugin_prusammu_show_prompt/ "action: show" (show prompt in OctoDash) and plugin_prusammu_mmu_changed / "action: close" (hide the prompt when set elsewhere OctoPrint GUI or directly on the printer).

Agree?

But how should I go about setting the tool / filament from OctoDash.

I see that the PrusaMMU modal sends a POST to http://octopi.local/api/plugin/prusammu with the payload: {"choice":3,"command":"select"}

Would you recommend me to do the same thing?

And getFilamentList(), now that OctoDash is a separate application, would it make sense to load the prusammu.js and use that? An alternative could be to query http://octopi.local/api/settings > plugins > prusammu > filament and use that for showing in the "Choose Filament" modal in OctoDash.

What's your take on that?

I really appreciate your work and you taking time to answer my questions :-)

jukebox42 commented 1 year ago

Ah, I follow now. Not familiar with OctoDash.

Yep, those are the events you should trigger on. You should prompt the user when you get plugin_prusammu_show_prompt event, change the display with plugin_prusammu_mmu_changed and pass select back with your choice (it's zero indexed). You should also listen to close so you can dismiss it on your side if they select with octoprint. You will also need to implement the timeout of the form on your side. You can inspect the timeout setting for how long you should wait after show before the plugin will use the default configuration (either prompt at the printer or use a default selected extruder). Once the timeout is hit the printer is unpaused and it will take the default action so timeout will be important.

Since you won't have access to the knockout runtime you will likely want to recreate a bit of how getFilamentList() works. I'd ping the api endpoint instead of trying to pull the JS file in so you don't have to fight knockout. And you are of course welcome to copy/paste anything. open source is great :).

The filament array will look like:

[
  {
    enabled: true, // bool - true if the tool is enabled in prusammu
    id: 1, // number - (indexed at 1 so subtract 1 from the value to get the actual tool id, i regret doing this)
    name: "string", // string - the name they gave it
    color: "#hex", // string -the hex color
  },
  ...
]

Also keep in mind prusammu supports 3 filament sources, since you don't have access to the javascript runtime you will likely not be able to support the other sources so I would recommend just defaulting to strings like "Filament 1", "Filament 2" ect if the setting filamentSource is not prusammu. You can push to support them all but maybe as a second iteration, I can't speak to what's going on, on the other side of the call I make.

You should also be sure to handle these situations:

The getFilament function isn't really knockout specific. The only knockout-ey thing in there is the self.settings is an observable which really just means the "values" are getter/setter functions like self.settings.filament() which returns the returns the array instead of calling self.setting.filament to get the list. The rest of that function is just pure JS.

Feel free to ask any questions :). Happy to help you dissect it.

Something I think I will need to add is an even you can fire to dismiss my modal from octodash so, if they select from your end you can close my modal without making a selection. Shouldn't be too hard tho, and not something that will block you, just for completeness and to cover an edge-case.

AndersWinther-Dahl commented 1 year ago

Hi John, I think I'm getting there PrusaMMU in OctoDash

Works as intended, when filament is picked the modal in OctoPrint also disappears. And vice versa :-)

AndersWinther-Dahl commented 1 year ago

Thanks for your help

jukebox42 commented 1 year ago

Awesome! When you get it merged please let me know so I can link to it from the readme :)

AndersWinther-Dahl commented 1 year ago

The author of OctoDash isn't responding to my questions, so I'm afraid it won't happen 😭

jukebox42 commented 1 year ago

Ah, that's a bummer, well if you ever do get it integrated or need some changes to support it let me know!