Improperly reporting Klipper tool temperature

What is the problem?
I have a 2 filament, shared nozzle/heater extruder setup. While using the second extruder (T1), OctoPrint does not update the tool temperature. I'm using klipper as the firmware, and the response to M105 uses T0. When I'm using T0, the temperature is properly updated, but if I switch to T1, the temperature stays frozen from the point in time that I switched to T1.

What did you already try to solve it?
I've tried disabling plugins and messing with shared heaters settings on both octoprint and klipper. It seems like OctoPrint is resolving the T0 in the M105 to be T0 only, even though shared_heaters is checked under the printer profile.

Logs (octoprint.log, serial.log or output on terminal tab at a minimum, browser error console if UI issue ... no logs, no support!)

Send: N9814 M105*19
Recv: ok B:40.0 /40.0 T0:205.0 /205.0

Additional information about your setup (OctoPrint version, OctoPi version, printer, firmware, browser, operating system, ... as much data as possible)
OctoPrint 1.4.0
Latest klipper version

Hello @shdwshinobi!

When Klipper reports

Recv: ok B:40.0 /40.0 T0:205.0 /205.0

from a M105 command and not T0 and T1, I assume it's a issue with Klipper.
Also when you use two separate hotends, you may not check shared nozzle in the printer profile.

If I understand this configuration, there is only one nozzle, only one heater, but two stepper motors. Which stepper motor runs is determined by T0 or T1.

The Marlin M105 temperature report with one extruder is:

Recv: ok T:22.25 /0.00 B:22.21 /0.00 @:0 B@:0

Marlin M105 with two extruders, two nozzles:

Recv: ok T:23.31 /0.00 B:24.36 /0.00 T0:23.31 /0.00 T1:23.34 /0.00 @:0 B@:0 @0:0 @1:100:

The T: temperature reported appears to be the extruder last referenced in the M104 (M109) command. A T0 or a T1 don't change the temperature report. The T0: and T1: temperatures are for each extruder.

I don't have a printer with a shared nozzle/heater like yours, so I don't know what the Marlin output would look like but I'm guessing that the Klipper output isn't matching what OctoPrint is expecting.

1 Like

A solution may writing a pretty small plugin which reformats the return into the two extruder format.

Edit:
https://docs.octoprint.org/en/master/plugins/hooks.html#octoprint-comm-protocol-temperatures-received

Ooops - overseeen that.

In that case I can confirm what @b-morgan says: It's like the Prusa with MMU, there is also only one nozzle temperature.

@linuxpaul A plugin just might work. I wish the "example" in the documentation actually existed. If I had that, I think I could fashion a plugin to try.

It may be easier than it seems, you'll need just the introduction and the first chapter of the Plugin tutorial and a pretty example how a hook works. My mistake was seeing a hook like a callback but it is more loke fishing. Catch the fish with the hook, modiy the fish and than you may bring it back to the water :slight_smile: Meanwhile very most of the plugins I use are selfwritten, modified or fixed.

This is a single file plugin example which just need to be copied to the plugin dir and use the temperatur hook :slight_smile: LedStripePlugin.zip (1,4 KB)

Thanks for the example. Even though I'm a retired software engineer, I'm a noob with Python and OctoPrint plugins. But if you give me a good example, I can usually turn that into something else that works!

Don't forget to take a look to this one:
https://docs.octoprint.org/en/master/plugins/gettingstarted.html and Python is pure fun bringing fuctionality into code, e.g connectiing to octoprints REST from commandline outside the octoprints emvironment. Have Fun :slight_smile:

Curious if your printer profile is configured properly @shdwshinobi. Do you have it like this?

image

Assuming the printer profile is configured correctly, I believe OctoPrint is expecting a temperature report with two temperatures in it (both the same because they are, in reality, the same single nozzle).

The following assumes that you have figured out how to SSH into your RPi using PuTTY (on Windows), ssh (on Linux), or something else on macOS. I have tested this on my LulzBot TAZ 6 with both a single extruder and a dual extruder and with the single extruder, it modifies the parsed_temperatures to report two temperatures.

Connect to octopi via SSH (or login as the effective octoprint user on your machine) copy this snippet and paste it straight into the terminal:

cat > /home/pi/.octoprint/plugins/Fix_Klipper_Temp.py << EOF
# coding=utf-8
from __future__ import absolute_import

import octoprint.plugin

class fix_klipper_temp(octoprint.plugin.OctoPrintPlugin):
	def FixKlipperTemp(self, comm_instance, parsed_temperatures, *args, **kwargs):
		self._logger.debug("Before: %s" % parsed_temperatures)
		if 'T0' not in parsed_temperatures.keys(): return parsed_temperatures
		if 'T1' in parsed_temperatures.keys(): return parsed_temperatures
		parsed_temperatures[u'T1'] = (parsed_temperatures['T0'][0],parsed_temperatures['T0'][1])
		self._logger.debug("After: %s" % parsed_temperatures)
		return parsed_temperatures

__plugin_name__ = "Fix Klipper Temp"
__plugin_version__ = "1.0.5"
__plugin_description__ = "Fix Klipper Temperature Report"
__plugin_pythoncompat__ = ">=2.7,<4"

def __plugin_load__():
	global __plugin_implementation__
	__plugin_implementation__ = fix_klipper_temp()

	global __plugin_hooks__
	__plugin_hooks__ = {
		"octoprint.comm.protocol.temperatures.received": __plugin_implementation__.FixKlipperTemp
	}
EOF

sudo service octoprint restart

If you want to see the _logger output (in ~/.octoprint/logs/octoprint.log), you will need to add an entry to OctoPrint's Settings, Logging to look like:

Nice @b-morgan, looks like it worked. You might want to wrap it and make it distributable via the plugin repo. If you'd like, I'd be happy to do that for you or help you through it.

b-morgan,

That definitely worked! I'm planning on putting in a couple more extruder motors, same nozzle. So I believe I'll have to alter your code, but this is a great starting point! I'd have to read more into the octoprint codebase since I'm not sure what's available, but it'd be nice to be able to see if shared_heater was checked and see how many extruders are in the active printer profile.

Yep, that's exactly what it looks like for the printer profile.

Yeah pulling the quantity of extruders from the default printer profile settings is trivial. Then you could use that as an iterator, or simply do a slight different comparison using in possibly like foosel mentioned in discord I think.

Alright, I grabbed the info from printer profiles and it should expand out if sharedNozzle is selected.

from __future__ import absolute_import

import octoprint.plugin

class fix_klipper_temp(octoprint.plugin.OctoPrintPlugin):
  def FixKlipperTemp(self, comm_instance, parsed_temperatures, *args, **kwargs):
    extruders = self._printer_profile_manager.get_current_or_default()["extruder"]["count"]
    sharedNozzle = self._printer_profile_manager.get_current_or_default()["extruder"]["sharedNozzle"]
    self._logger.debug("Before: %s" % parsed_temperatures)
    if 'T0' not in parsed_temperatures.keys(): return parsed_temperatures
    if sharedNozzle is True and extruders > 1 and 'T1' not in parsed_temperatures.keys():
      for i in range(1, extruders):
        parsed_temperatures[u'T' + str(i)] = (parsed_temperatures['T0'][0],parsed_temperatures['T0'][1])
    self._logger.debug("After: %s" % parsed_temperatures)
    return parsed_temperatures

__plugin_name__ = "Fix Klipper Temp"
__plugin_version__ = "1.0.5"
__plugin_description__ = "Fix Klipper Temperature Report"
__plugin_pythoncompat__ = ">=2.7,<4"

def __plugin_load__():
  global __plugin_implementation__
  __plugin_implementation__ = fix_klipper_temp()

  global __plugin_hooks__
  __plugin_hooks__ = {
    "octoprint.comm.protocol.temperatures.received": __plugin_implementation__.FixKlipperTemp
  }


1 Like

If you think it should be a full-fledged plugin then I nominate @shdwshinobi for that honor. It sounds like he is in a position to both test and expand on my start. I'm hesitant to "own" something I can't actually test. I'm sure he would welcome your help.

IMO, the ability to create these single-file solutions is a hidden OctoPrint "gem" and I'm just happy to let them "shine" on their own.

So I've never tried installing one of these gems, you just drop it in the plugins folder or can you install via wen interface upload? That's my biggest point. If it's beneficial to the masses, it's easier to get it out there if it's registered in the repo. I question if the vast majority of the users even connect to ssh on their pi to reset their password.