@@ -138,18 +138,27 @@ class Configfile(BaseModel):
138138
139139
140140class TemperatureDataPoint :
141+ type : str = "temperature_sensor"
142+ id : str = ""
143+ hadTarget : bool = True
141144 actual : float = 0.0
142145 target : float = 0.0
143146
144- def __init__ (self , actual : float = 0.0 , target : float = 0.0 ):
147+ def __init__ (self , type : str = "temperature_sensor" , id : str = "" , hasTarget : bool = True , actual : float = 0.0 , target : float = 0.0 ):
148+ self .type = type
149+ self .id = id
150+ self .hasTarget = hasTarget
145151 self .actual = actual
146152 self .target = target
147153
148154 def __str__ (self ):
149- return f"{ self .actual } / { self .target } "
155+ if self .hasTarget :
156+ return f"{ self .actual } / { self .target } "
157+ else :
158+ return f"{ self .actual } "
150159
151160 def __repr__ (self ):
152- return f"TemperatureDataPoint({ self .actual } , { self .target } )"
161+ return f"TemperatureDataPoint({ self .type } , { self . id } , { self . hasTarget } , { self . actual } , { self .target } )"
153162
154163
155164class KlipperState (enum .Enum ):
@@ -245,6 +254,11 @@ def on_moonraker_print_detected(
245254 def on_moonraker_server_info (self , server_info : dict [str , Any ]) -> None :
246255 pass
247256
257+ def on_moonraker_temperature_store_update (
258+ self , data : dict [str , TemperatureDataPoint ]
259+ ) -> None :
260+ pass
261+
248262 def on_moonraker_file_tree_updated (
249263 self , root : str , path : str , tree : dict [str , dict [str , InternalFile ]]
250264 ) -> None :
@@ -300,15 +314,12 @@ class MoonrakerClient(JsonRpcClient):
300314 WEBSOCKET_URL = "ws://{host}:{port}/websocket"
301315 HTTP_URL = "http://{host}:{port}"
302316
303- GENERIC_HEATER_PREFIX = "heater_generic "
304317 GENERIC_EXTRUDER_PREFIX = "extruder"
305- GENERIC_TEMPERATURE_FAN_PREFIX = "temperature_fan "
306- GENERIC_TEMPERATURE_PROBE_PREFIX = "temperature_probe "
307- GENERIC_TEMPERATURE_SENSOR_PREFIX = "temperature_sensor "
308318 GENERIC_TMC_PREFIX = "tmc"
309319 TMC_HAVE_TEMPERATURE = [
310320 "tmc2240" ,
311321 ]
322+ HEATERS = ();
312323 MACRO_PREFIX = "gcode_macro "
313324
314325 RELEVANT_PRINTER_OBJECTS = (
@@ -323,10 +334,6 @@ class MoonrakerClient(JsonRpcClient):
323334 x
324335 for x in obj_list
325336 if x .startswith (MoonrakerClient .GENERIC_EXTRUDER_PREFIX )
326- or x .startswith (MoonrakerClient .GENERIC_HEATER_PREFIX )
327- or x .startswith (MoonrakerClient .GENERIC_TEMPERATURE_FAN_PREFIX )
328- or x .startswith (MoonrakerClient .GENERIC_TEMPERATURE_PROBE_PREFIX )
329- or x .startswith (MoonrakerClient .GENERIC_TEMPERATURE_SENSOR_PREFIX )
330337 or x .startswith (MoonrakerClient .GENERIC_TMC_PREFIX )
331338 or x .startswith (MoonrakerClient .MACRO_PREFIX )
332339 ],
@@ -355,6 +362,7 @@ def __init__(
355362 self ._klipper_state_subscription = False
356363 self ._subbed_objs : list [str ] = []
357364
365+ self ._temperature_store_received = False
358366 self ._log_history_received = False
359367
360368 self ._heaters : list [str ] = []
@@ -527,9 +535,10 @@ def on_server_info(future: Future) -> None:
527535 f"Connected to Moonraker { moonraker_version } , API version { api_version } " ,
528536 )
529537
538+ self .get_printer_config ()
530539 self .fetch_console_history ()
531540 self .fetch_job_history ()
532- self .subscribe_to_updates ()
541+ # self.subscribe_to_updates()
533542
534543 else :
535544 # log error
@@ -538,7 +547,7 @@ def on_server_info(future: Future) -> None:
538547 self ._dual_log (logging .ERROR , error )
539548
540549 except Exception as exc :
541- self ._logger .exception ("Error while retrieving server info" )
550+ self ._logger .exception (f "Error while retrieving server info: { exc } " )
542551 error_str = f"Error while retrieving server info: { str (exc )} . Please check moonraker.log for details."
543552 self ._listener .on_moonraker_disconnected (error = error_str )
544553
@@ -560,7 +569,7 @@ def on_printer_objects(future: Future) -> None:
560569 obj_list = printer_objects .get ("objects" , [])
561570
562571 matched_objs = []
563- for obj in self .RELEVANT_PRINTER_OBJECTS :
572+ for obj in self .RELEVANT_PRINTER_OBJECTS + self . HEATERS :
564573 if isinstance (obj , str ) and obj in obj_list :
565574 matched_objs .append (obj )
566575
@@ -581,11 +590,8 @@ def on_printer_objects(future: Future) -> None:
581590 for obj in matched_objs
582591 if obj in ("heater_bed" )
583592 or obj .startswith (self .GENERIC_EXTRUDER_PREFIX )
584- or obj .startswith (self .GENERIC_HEATER_PREFIX )
585- or obj .startswith (self .GENERIC_TEMPERATURE_FAN_PREFIX )
586- or obj .startswith (self .GENERIC_TEMPERATURE_PROBE_PREFIX )
587- or obj .startswith (self .GENERIC_TEMPERATURE_SENSOR_PREFIX )
588593 or obj .startswith (self .GENERIC_TMC_PREFIX )
594+ or obj in self .HEATERS
589595 ]
590596
591597 self .query_printer_objects (matched_objs )
@@ -640,6 +646,21 @@ def on_result(future: Future) -> None:
640646 future .add_done_callback (on_result )
641647 return future
642648
649+ def get_printer_config (self ) -> Future :
650+ def on_result (future : Future ) -> None :
651+ try :
652+ results = future .result ()
653+
654+ config = results ["status" ]["configfile" ]["config" ]
655+ self .fetch_temperature_store (config = config )
656+ except Exception as e :
657+ self ._logger .exception (f"Error while fetching klipper config: { e } " )
658+
659+ params = {"objects" : {"configfile" : None }}
660+ self .call_method ("printer.objects.query" , params = params ).add_done_callback (
661+ on_result
662+ )
663+
643664 def subscribe_printer_objects (self , objs : list [str ] = None ) -> Future :
644665 if objs is None :
645666 objs = self ._subbed_objs
@@ -674,6 +695,53 @@ def on_status(future: Future) -> None:
674695 )
675696 return result_future
676697
698+ def fetch_temperature_store (self , config : dict ) -> Future :
699+ def on_result (future : Future ) -> None :
700+ try :
701+ results = future .result ()
702+ for section in results :
703+ if section .startswith (self .GENERIC_EXTRUDER_PREFIX ):
704+ continue ;
705+
706+ if section not in config :
707+ self ._logger .warning (f"{ section } not found in config" )
708+ continue
709+
710+ sectionconfig = config [section ]
711+ if "gcode_id" not in sectionconfig :
712+ self ._logger .warning (f"skipping { section } , no gcode_id" )
713+ continue
714+
715+ if " " in section :
716+ type , name = section .split (maxsplit = 1 )
717+ else :
718+ type = ""
719+ name = section
720+
721+ if name not in self ._current_temperatures :
722+ self ._current_temperatures [name ] = TemperatureDataPoint (
723+ type = type ,
724+ id = sectionconfig ["gcode_id" ],
725+ hasTarget = True if "target" in sectionconfig else False
726+ )
727+
728+ if section not in self .HEATERS :
729+ self .HEATERS += (section ,)
730+
731+ if section not in self ._heaters :
732+ self ._heaters .append (section )
733+
734+ self ._temperature_store_received = True
735+ self ._listener .on_moonraker_temperature_store_update (self ._current_temperatures )
736+ self .subscribe_to_updates ()
737+
738+ except Exception as e :
739+ self ._logger .exception (f"Error while fetching temperature store: { e } " )
740+
741+ self .call_method ("server.temperature_store" ).add_done_callback (
742+ on_result
743+ )
744+
677745 def fetch_console_history (self , count : int = 100 , force : bool = False ) -> Future :
678746 if self ._log_history_received and not force :
679747 return
@@ -1084,41 +1152,49 @@ def _process_update(self, payload: dict[str, Any]) -> None:
10841152 self ._update_gcode_move (payload )
10851153 self ._update_idle_timeout (payload )
10861154 self ._update_print_stats (payload )
1087- self ._update_temperatures (payload )
1155+ if self ._temperature_store_received :
1156+ self ._update_temperatures (payload )
10881157 self ._update_virtual_sdcard (payload )
10891158
10901159 def _update_temperatures (self , payload : dict [str , Any ]) -> None :
10911160 dirty_actual = False
10921161 dirty_target = False
1162+ dirty_sensorslist = False
10931163
10941164 for heater in self ._heaters :
10951165 if heater not in payload :
10961166 continue
10971167
1098- if heater .startswith (self .GENERIC_HEATER_PREFIX ):
1099- name = heater [len (self .GENERIC_HEATER_PREFIX ) :]
1100- elif heater .startswith (self .GENERIC_TEMPERATURE_FAN_PREFIX ):
1101- name = heater [len (self .GENERIC_TEMPERATURE_FAN_PREFIX ) :]
1102- elif heater .startswith (self .GENERIC_TEMPERATURE_PROBE_PREFIX ):
1103- name = heater [len (self .GENERIC_TEMPERATURE_PROBE_PREFIX ) :]
1104- elif heater .startswith (self .GENERIC_TEMPERATURE_SENSOR_PREFIX ):
1105- name = heater [len (self .GENERIC_TEMPERATURE_SENSOR_PREFIX ) :]
1106- elif heater .startswith (self .GENERIC_TMC_PREFIX ):
1107- name = heater [8 :]
1108- driver = heater [:7 ]
1109- if driver not in self .TMC_HAVE_TEMPERATURE :
1110- continue
1168+ if " " in heater :
1169+ type , name = heater .split (maxsplit = 1 )
11111170 else :
1171+ type = ""
11121172 name = heater
11131173
1114- data = self ._current_temperatures .get (name , TemperatureDataPoint ())
1174+ if heater .startswith (self .GENERIC_TMC_PREFIX ) and type not in self .TMC_HAVE_TEMPERATURE :
1175+ continue
1176+
1177+ if name not in self ._current_temperatures :
1178+ dirty_sensorslist = True
1179+ self ._logger .warning (f"Adding { heater } to temperatures list" )
1180+
1181+ data = self ._current_temperatures .get (name , TemperatureDataPoint (type = type ))
1182+
1183+ if heater .startswith (self .GENERIC_TMC_PREFIX ) and data .hasTarget :
1184+ data .hasTarget = False
1185+
11151186 if "temperature" in payload [heater ]:
11161187 data .actual = payload [heater ]["temperature" ] or 0
11171188 dirty_actual = True
11181189 if "target" in payload [heater ]:
11191190 data .target = payload [heater ]["target" ]
11201191 dirty_target = True
11211192 self ._current_temperatures [name ] = data
1193+ if data .id == "C" and name != "chamber" :
1194+ self ._current_temperatures ["chamber" ] = data
1195+
1196+ if dirty_sensorslist :
1197+ self ._listener .on_moonraker_temperature_store_update (self ._current_temperatures )
11221198
11231199 if dirty_actual or dirty_target :
11241200 now = time .monotonic ()
0 commit comments