Gcode call and wait for it to be executed (recv: ok)

Hello everyone,

i'm currently working on a plugin to "emulate" the bltouch marlin support but in octoprint for close firmware printer (sadly like my alfawise).

i started to do it on server side: i tried to hook the G29 and replace it with my code but i couldnt send gcode in sequence (send a move, then do a M114 to get the answer etc). If there is a way please tell me.

i looked into the client side with a button. i thought i got the solution but sadly it's not working as i wanted :frowning:
i was hoping that the jquery Promise "done" would only be called once the printer actually received it but no :frowning:

is there a way to "wait" for a gcode to be executed ?

i need to move the head and once it moved to get the z height, client or server side both are ok, doesnt matter (i would prefer server of course since i have to play with gpio, but i can use a workaround for it)

i hope i'm clear enough

please help :sweat_smile:

after crawling the doc and forum, I might have found a workaround but i'm not sure about it and not very happy with it:

as far as I understood what i read into the forum, what i want to do isnt straight forward doable ... :frowning:

So i think about it and since the client receive the terminal, I must be able to get that data too and work with it (parse it until i see the M114 result and work with it).

i look for it into the doc and code. i found out the terminalViewModel that i could inject into my viewmodel but i'm not sure it's the proper way to do it.

my thought is that it would be much better on server side :

hook G29 to call my plugin function "leveling"

function leveling:
- move the printer head to measure point X
- send M114
- parse terminal (how to access it?) until i see the response from the printer
- do my stuff with M114, control my GPIO for bltouch etc.
- repeat until no more measure point.

but i dont find how to "parse terminal" until i get the answer. i found out how to hook it but could i have in my "leveling function" a blocking boolean until i unlock it into the hook (when i see the M114 response ? will it work ? something like that:

function leveling2: 
- move the printer head to measure point X
- WaitingM114result = true
- send M114
- while WaitingM114result 
  - sleep 500ms (or nothing)

- do my stuff using M114, control my GPIO for bltouch etc.
- repeat until no more measure point.
hook [octoprint.comm.protocol.gcode.received]:
 - if WaitingM114result 
        - parse data 
        - if data is M114result, store result
        - WaitingM114result = !WaitingM114result 

@foosel could you provide me some guideline ? i would really appreciate it since i'm kinda stuck :frowning:

In your particular case, considering that you want to wait for an M114 to complete you could just wait for an PositionUpdated event to be (asynchronously) fired.

If that doesn't work for you, then the only way you have is to do something like listen for GCODE to be sent, set flag, read lines in received hook, if flag is set & line matches do whatever you want to do. What you should not do is fully block some request from the client until your response is received since that will effectively block the whole web server. Look into how to signal across multiple threads in python (hint: threading.Event) and use that.

In general though, the communication with the printer is asynchronous and due to several technical limitations (especially with a ton of buggy firmware out there) it is also not trivial and often not even possible to associate sent commands with received output from them and hence make the full command lifecycle transparent. Sucks, but that's what we have to deal with here sadly.

thanks a lot foosel for your help foosel.
i looked into event before, but i discard this lead since it seems that i cant catch event in a plugin. it's made for independant call (ie: growl). if i'm wrong how can i do that ?

i will look into your other lead threading.event