# Copyright (C) 2022 Justin Schuh # # This file may be distributed under the terms of the GNU GPLv3 license. [gcode_macro set_heater_temperature_scaled] gcode: {% set HEATER = params.HEATER.lower() %} {% set TARGET = params.TARGET|default(0.0)|float %} {% set scaled_heaters = printer["gcode_macro set_heater_scaling"].scaled_heaters %} {% if HEATER in scaled_heaters %} {% set scales = scaled_heaters[HEATER] %} {% set dummy = scales.__setitem__("real_target", TARGET) %} {%if TARGET > 0.0 %} {% set TARGET = (((TARGET + scales.bump) * scales.scale, scales.minimum) | max, scales.maximum)|min %} {% endif %} {% endif %} SET_HEATER_TEMPERATURE HEATER="{HEATER}" TARGET={TARGET} [gcode_macro temperature_wait_scaled] gcode: {% set SENSOR = params.SENSOR.lower() %} {% set heater = SENSOR if not SENSOR.startswith("heater_generic") else SENSOR.split()[1] %} {% set scaled_heaters = printer["gcode_macro set_heater_scaling"].scaled_heaters %} {% if heater in scaled_heaters %} {% set scales = scaled_heaters[heater] %} {% if "MINIMUM" in params and MINIMUM > 0.0 %} {% set MINIMUM = (((MINIMUM + scales.bump) * scales.scale, scales.minimum) | max, scales.maximum)|min %} {% endif %} {% if "MAXIMUM" in params and MINIMUM > 0.0 %} {% set MAXIMUM = (((MAXIMUM + scales.bump) * scales.scale, scales.minimum) | max, scales.maximum)|min %} {% endif %} {% else %} {% set settings = printer.configfile.settings[SENSOR] %} {% set MINIMUM = params.MINIMUM|default(settings.min_temp) %} {% set MAXIMUM = params.MAXIMUM|default(settings.max_temp) %} {% endif %} {% if printer[sensor].temperature < MINIMUM or printer[sensor].temperature > MAXIMUM %} TEMPERATURE_WAIT SENSOR="{SENSOR}" MINIMUM={MINIMUM} MAXIMUM={MAXIMUM} {% endif %} [gcode_macro _gcode_wait_wrapper_inner] gcode: # Macro variables are evaluated at instantiation, so this inner macro is what # gets us a scaled target value. {% set sensor = params.HEATER if params.HEATER in printer.heaters.available_heaters else ("heater_generic " ~ params.HEATER) %} {% set target = printer[sensor].target %} {% if 'R' in params and target > 0.0 %} {% set T = params.T|default("") %} M{params.M}.6245197 S{target} { (" T"~T) if T else "" } {% elif printer[sensor].temperature < target %} TEMPERATURE_WAIT SENSOR="{sensor}" MINIMUM={target} {% endif %} [gcode_macro _gcode_wait_wrapper] gcode: {% set target = params.S | default(params.R | default(0))| float %} SET_HEATER_TEMPERATURE_SCALED HEATER="{params.HEATER}" TARGET={target} _GCODE_WAIT_WRAPPER_INNER{% for k in params %}{' '~k~'="'~params[k]~'"'}{% endfor %} [gcode_macro m109] rename_existing: M109.6245197 gcode: {% set extruder = "extruder" ~ params.T|replace('0', '') if "T" in params else printer.toolhead.extruder %} _GCODE_WAIT_WRAPPER HEATER={extruder}{% for k in params %}{' '~k~'="'~params[k]~'"'}{% endfor %} [gcode_macro m190] rename_existing: M190.6245197 gcode: _GCODE_WAIT_WRAPPER HEATER=heater_bed {% for k in params %}{' '~k~'="'~params[k]~'"'}{% endfor %} [gcode_macro m191] description: Sets chamber temperature (with wait for heating). Usage: M191 [S] gcode: # Just fake the R parameter for the chamber. {% if "R" in params %} {% set dummy = params.__setitem__("S", params.R) %} {% endif %} _GCODE_WAIT_WRAPPER HEATER=chamber {% for k in params %}{' '~k~'="'~params[k]~'"'}{% endfor %} [gcode_macro m104] rename_existing: M104.6245197 gcode: {% set extruder = "extruder" ~ params.T|replace('0', '') if "T" in params else printer.toolhead.extruder %} SET_HEATER_TEMPERATURE_SCALED HEATER={extruder} TARGET={params.S|default(0)} [gcode_macro m140] rename_existing: M140.6245197 gcode: SET_HEATER_TEMPERATURE_SCALED HEATER=heater_bed TARGET={params.S|default(0)} [gcode_macro m141] description: Sets chamber temperature. Usage: M141 [S] gcode: SET_HEATER_TEMPERATURE_SCALED HEATER=chamber TARGET={params.S|default(0)} [gcode_macro _check_heater_params] gcode: {% set HEATER = params.HEATER|lower %} {% set sensor = params.HEATER %} {% if HEATER not in printer.heaters.available_heaters %} {% set sensor = "heater_generic " ~ HEATER %} {% if sensor not in printer.heaters.available_heaters %} { action_raise_error("The value '%s' is not valid for HEATER" | format(HEATER)) } {% endif %} {% endif %} {% set settings = printer.configfile.settings[sensor] %} {% set scaled_heaters = printer["gcode_macro set_heater_scaling"].scaled_heaters %} {% if HEATER is in scaled_heaters %} {% set scales = scaled_heaters[HEATER] %} {% else %} {% set scales = { "scale": 1.0, "bump": 0.0, "minimum": settings.min_temp, "maximum": settings.max_temp, "real_target": printer[sensor].target} %} {% endif %} {% set SCALE = params.SCALE|default(scales.scale)|float %} {% set BUMP = params.BUMP|default(scales.bump)|float %} {% set MINIMUM = params.MINIMUM|default(scales.minimum)|float %} {% set MAXIMUM = params.MAXIMUM|default(scales.maximum)|float %} {% if SCALE <= 0 %} { action_raise_error("SCALE must be a positive value.") } {% elif MINIMUM < settings.min_temp or MINIMUM > settings.max_temp %} { action_raise_error("MINIMUM must be between %.1f and %.1f" | format(settings.min_temp, settings.max_temp)) } {% elif MAXIMUM < settings.min_temp or MAXIMUM > settings.max_temp %} { action_raise_error("MAXIMUM must be between %.1f and %.1f" | format(settings.min_temp, settings.max_temp)) } {% elif MINIMUM >= MAXIMUM %} { action_raise_error("MINIMUM must be less than MAXIMUM.") } {% elif "TARGET" in params and (params.TARGET|float < MINIMUM or params.TARGET|float > MAXIMUM) %} { action_raise_error("TARGET must be between %.1f and %.1f" | format(settings.min_temp, settings.max_temp)) } {% endif %} [gcode_macro set_heater_scaling] description: Sets scaling parameters for heater. If a new target temperature is passed it will be adjusted to the scaling parameters. Usage: SET_HEATER_SCALING [HEATER=] [SCALE=] [BUMP=] [MAXIMUM=] [MINIMUM=] [TARGET=] variable_scaled_heaters: {} gcode: # If no heater is supplied just list out all the scaled heaters. {% if "HEATER" is not in params %} {% set output = [] %} {% for h in scaled_heaters %} {% set dummy = output.append( "%s: Scale: %.2f Bump: %.1f Minimum:%.1f Maximum: %.1f" | format(h, scaled_heaters[h].scale, scaled_heaters[h].bump, scaled_heaters[h].minimum, scaled_heaters[h].maximum)) %} {% endfor %} {% if output %}}{action_respond_info(output|join('\n'))}{% endif %} {% else %} # See if we need a new scaling entry for this heater. {% set HEATER = params.HEATER.lower() %} {% set settings = printer.configfile.settings[HEATER] %} {% if HEATER is not in scaled_heaters %} {% set dummy = scaled_heaters.__setitem__(HEATER, {"scale": 1.0, "bump": 0.0, "minimum": settings.min_temp, "maximum": settings.max_temp, "real_target": printer[HEATER].target}) %} {% endif %} _CHECK_HEATER_PARAMS{% for k in params %}{' '~k~'='~params[k]}{% endfor %} {% set scales = scaled_heaters[HEATER] %} {% set SCALE = params.SCALE|default(scales.scale)|float %} {% set BUMP = params.BUMP|default(scales.bump)|float %} {% set MAXIMUM = params.MAXIMUM|default(scales.maximum)|float %} {% set MINIMUM = params.MINIMUM|default(scales.minimum)|float %} {% set TARGET = params.TARGET|default(scales.real_target)|float %} {% set dummy = scales.__setitem__("scale", SCALE) %} {% set dummy = scales.__setitem__("bump", BUMP) %} {% set dummy = scales.__setitem__("maximum", MAXIMUM) %} {% set dummy = scales.__setitem__("minimum", MINIMUM) %} {% set dummy = scales.__setitem__("real_target", TARGET) %} {% set settings = printer.configfile.settings[HEATER] %} {% if SCALE != 1.0 or BUMP != 0.0 or MINIMUM != settings.min_temp or MAXIMUM != settings.max_temp %} {% set dummy = scaled_heaters.__setitem__(HEATER, scales) %} {% else %} # Remove a redundant scaling entry. {% set dummy = scaled_heaters.__delitem__(HEATER) %} {% endif %} SET_HEATER_TEMPERATURE_SCALED HEATER={HEATER} TARGET={TARGET} {action_respond_info( "%s: Scale: %.2f Bump: %.1f Minimum:%.1f Maximum: %.1f Target: %.1f" | format(HEATER, SCALE, BUMP, MINIMUM, MAXIMUM, TARGET))} {% endif %} # Dummy argument block for Mainsail {% set dummy = None if True else " {% set dummy = params.HEATER|default(e.g. extruder) %} {% set dummy = params.SCALE|default(1.0)|float %} {% set dummy = params.BUMP|default(0.0)|float %} {% set dummy = params.MAXIMUM|default(max_temp)|float %} {% set dummy = params.MINIMUM|default(min_temp)|float %} {% set dummy = params.TARGET|default(current target)|float %} " %} # End argument block for Mainsail [gcode_macro reset_heater_scaling] description: Clears scaling for heater (or all heaters if none specified). Usage: RESET_HEATER_SCALING [HEATER=] gcode: {% if "HEATER" in params %} {% set HEATER = params.HEATER.lower() %} {% if HEATER not in printer.heaters.available_heaters %} { action_raise_error("The value '%s' is not valid for HEATER" | format(HEATER)) } {% endif %} {% set settings = printer.configfile.settings[HEATER] %} SET_HEATER_SCALING HEATER={HEATER } SCALE=1.0 BUMP=0.0 MINIMUM={settings.min_temp } MAXIMUM={settings.max_temp} {% else %} # Clear everything if no heater was provided. SET_GCODE_VARIABLE MACRO=set_heater_scaling VARIABLE=scaled_heaters VALUE={ "{}"} {% endif %}