Is it possible to use variables in GCode scripts for the starting temp of the print file

So I have a starting GCode script that draws a prime line on the right side of the bed. I have it set to use 200c for the hot end and 60c for the bed. But if I want to use a different filament, I need to go into those GCode script settings and manually change it there. Is there any way to use a variable there? I just want it to use the initial temperature that the GCode file itself uses. Similar to the Preheat Plugin.

Why not set this in your slicer's start script? I believe most slicers support those variable type settings.

I actually use a couple different slicers and also Astroprint. I just liked having Octoprint be the one place for my start script. Now if I make a change to my start script I can just change it in one place. If I use my slicers, I have to change it in a few places. Although that might be easier than changing the temperature in OP every time. I was just hoping there might be a solution that gives me the best of both worlds.

It looks like you could use a plugin with the octoprint-comm-protocol-scripts hook to supply a variable to those gcode scripts it seems. Check out Example 2. The trick would be pulling that variable from somewhere to set it.

There appears to be some interesting tricks as well. You may want to look into Snippets and Context.

I just found out a possible solution for you. The only requirement would be that you have to name your files with the temperature you want the nozzle to preheat to using 3 digits. Then in the before print started GCODE setting you would reference it as follows.

{% if event.name[:3] is number %}
M109 S{{ event.name[:3] }}
{% else %}
M117 {{ event.name }} doesn't start with a temperature.
{% endif %}

If the filename was 180 filename.gcode the temperature will be set to 180 when the command is sent to the printer. If it doesn't then a prompt will be shown on the printer's display that the filename doesn't start with a temperature. You could of course omit the else part and stuff all of your gcodes in the if section.

2 Likes

You can go to the temperature tab of octoprint and once it's done with the prime and the temp changes, you can override the temp there.

Wow, what a clever solution!

Thanks, I'm the master of the workaround.

Thanks. That’s a clever workaround and I’m definitely going to have to keep this technique in mind for the future. But I don’t think it will work well with my workflow since I so often use AstroPrint to push my print jobs to OP.

That said, I was looking into this some more and saw the pry of this link:

https://docs.octoprint.org/en/master/features/gcode_scripts.html

Where it says you can grab variables from plugins using ‘ plugins.myplugin.myvariable’. Since the Preheat plugin already grabs this value from the GCODE file, I would think it should be fairly easy to have it expose the variables for the bed temp and the nozzle temp. Just need to figure that out.

Yeah, the plugin would have to supply the variable in the octoprint-comm-protocol-scripts hook as a return value. The example provided shows the process returning a variable of myvariable, so in your gcode script if you put M117 {{ plugins.gcode_script_variables.myvariable }} it will display on the printer the text in that variable Hi! I'm a variable!.

Save this file as gcode_script_variables.py in your ~/.octoprint/plugins folder and restart OctoPrint.

# coding=utf-8

def gcode_script_variables(comm, script_type, script_name, *args, **kwargs):
    if not script_type == "gcode" or not script_name == "beforePrintStarted":
        return None

    prefix = None
    postfix = None
    variables = dict(myvariable="Hi! I'm a variable!")
    return prefix, postfix, variables

__plugin_name__ = "gcode script variables"
__plugin_hooks__ = {"octoprint.comm.protocol.scripts": gcode_script_variables}

I played with this a bit but couldn't figure out how to get the filename to read through looking for the temp setting. If that logic is already done in the preheat plugin, then dependent on how that temperature is stored if it would be available to the scripts hook.

1 Like

Wow. This is great. Thank you so much for this. I don’t know Python at all, but I think with you have given me I should be able to figure this out. That preheat plugin does have that logic in there to read the file and get the first instance of bed temp and first instance of nozzle temp.

I actually just thew this together as a test after looking at the Preheat button plugin, and it does work. Use the following in your GCODE Scripts section {{ plugins.preheat.tool0|int() }} for the tool temperature reported by preheat button fork linked below (install using the URL in plugin manager). I will submit a pull request to the official preheat button repo to see if they will integrate the changes officially or not. To reference the bed temperature use {{ plugins.preheat.bed|int() }}

https://github.com/jneilliii/octoprint-preheat/archive/variables.zip

Damn. I’ve always been impressed with your contributions to this community but this is next level. Thank you so much for this. You put all this together before I had a chance to really dig deep into. I’ll look into this later tonight.

1 Like

No problem. Luckily the preheat button plugin was programmed in a way that made this incredibly easy. I just had to add the hook and call one of it's already built-in functions to be able to retrieve the temperatures and return them as a script variable.

@jneilliii Thanks again for your help with this. I finally got around to playing with this. I actually used the final code the Preheat author put up on his github. I think your code checked to see what GCODE script was being used, whereas his didn't care. I manually edited the .py file for the plugin since he hasn't released it yet. It worked perfectly.

The only thing I want to add, in case there is someone else that was wanting to do this is that in the GCODE, I had to use the code below. Note the 'S' right before the variable. I think it worked for the M140 command without the S, but the M104 needed it. Not really sure what that does. I also learned that if you issue the M140 and the M104 back to back, it will heat the tool and the bed at the same time. Which would cut a minute or 2 off the print start time. Before I had the M190 following the M140 command and it had to wait for the bed to heat up before starting on the tool. Of course, you will need to pay attention to the power requirements when heating multiple things at once, but I would imagine most printers can handle it. My Ender 5 works great doing that:

M140 S{{ plugins.preheat.bed|int() }}
M104 S{{ plugins.preheat.tool0|int() }}

M190 S{{ plugins.preheat.bed|int() }}
M109 S{{ plugins.preheat.tool0|int() }}

Both commands need it. The S specifies the temperature to heat up to. It's simply part of how GCODE is structured that you have parameter prefixes (M117 is the only exception that comes to mind). Take a look here for some docs.

Yeah, he merged in my changes and then took away the script check to be able to apply it to any of the scripts. I believe it to be on his master repo, maybe just not released yet.