Coverage for src / zooc / run / temps_scan.py: 44%
58 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 21:45 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 21:45 +0000
1"""Methods for measuring Z-offset at given temperature ranges."""
2from __future__ import annotations
4import logging
5from abc import ABC, abstractmethod
6from collections.abc import Callable
7from dataclasses import dataclass
8from typing import override
10from zooc.data.offset_temp import OffsetTemp
11from zooc.data.temps import Temps
13from .measure_z import MeasureZ
14from .run_calibrate import RunCalibrate
16logger = logging.getLogger(__name__)
19@dataclass(kw_only=True)
20class TempScan(RunCalibrate, ABC):
21 """Base class for various methods scanning through temperatures and measuring Z-offset.
23 :param klipper_module: See parent class: :py:class:`.run_calibrate.RunCalibrate`.
24 :param gcmd: See parent class: :py:class:`.run_calibrate.RunCalibrate`.
25 :param run_config: See parent class: :py:class:`.run_calibrate.RunCalibrate`.
26 """
28 @abstractmethod
29 def get_temp_steps(self) -> int:
30 """Get the number of temperature steps in the scan.
32 :return: Number of temperature steps.
33 """
35 @abstractmethod
36 def scan(self, measure_z: MeasureZ, temps_set: Callable[[Temps], None]) -> list[OffsetTemp]:
37 """Scan temperatures and run the Z-measurement method on each state.
39 Heat the printer through the temperatures and run the Z-measurement method.
41 :param measure_z: Z-measure method. Takes care of settling etc.
42 :param temps_set: Callback to set temperatures.
43 :return: List of measured Z-offsets for each scanned temperature.
44 """
47@dataclass(kw_only=True)
48class TempScanSimple(TempScan):
49 """Simple and fast temperature scan.
51 Heat the system to selected temperatures while keeping the other at reference value and call callback.
53 :param klipper_module: See parent class: :py:class:`TempScan`.
54 :param gcmd: See parent class: :py:class:`TempScan`.
55 :param run_config: See parent class: :py:class:`TempScan`.
56 """
58 @override
59 def get_temp_steps(self) -> int:
60 return len(self.run_config.bed_temps) + len(self.run_config.extruder_temps)
62 @override
63 def scan(self, measure_z: MeasureZ, temps_set: Callable[[Temps], None]) -> list[OffsetTemp]:
64 measure_datas = []
65 # Run bed temps at reference extruder temp
66 extruder_temp_ref = self.run_config.temps_ref.extruder_temp
67 for bed_temp in self.run_config.bed_temps:
68 temps = Temps.klipper(bed_temp, extruder_temp_ref)
69 temps_set(temps)
70 z_offset, aux_data = measure_z.measure()
71 measure_datas.append(OffsetTemp.build(temps=temps, z_offset=z_offset, aux_data=aux_data))
73 # Run extruder temps at reference bed temp
74 bed_temp_ref = self.run_config.temps_ref.bed_temp
75 for extruder_temp in self.run_config.extruder_temps:
76 temps = Temps.klipper(bed_temp_ref, extruder_temp)
77 temps_set(temps)
78 z_offset, aux_data = measure_z.measure()
79 measure_datas.append(OffsetTemp.build(temps=temps, z_offset=z_offset, aux_data=aux_data))
81 return measure_datas
84@dataclass(kw_only=True)
85class TempScanFull(TempScan):
86 """Scan all bed and extruder temperatures, i.e. full matrix.
88 :param klipper_module: See parent class: :py:class:`TempScan`.
89 :param gcmd: See parent class: :py:class:`TempScan`.
90 :param run_config: See parent class: :py:class:`TempScan`.
91 """
93 @override
94 def get_temp_steps(self) -> int:
95 return len(self.run_config.bed_temps) * len(self.run_config.extruder_temps)
97 @override
98 def scan(self, measure_z: MeasureZ, temps_set: Callable[[Temps], None]) -> list[OffsetTemp]:
99 measure_datas = []
101 bed_temps: list[float] = self.run_config.bed_temps
102 extruder_temps: list[float] = list(self.run_config.extruder_temps) # make copy
104 for bed_temp in bed_temps:
105 for extruder_temp in extruder_temps:
106 temps = Temps.klipper(bed_temp, extruder_temp)
107 temps_set(temps)
108 z_offset, aux_data = measure_z.measure()
109 logger.info(f"Z-offset measured at {temps} z={z_offset:.3f} mm")
110 logger.debug(f"aux_data={aux_data}")
111 measure_datas.append(OffsetTemp.build(temps=temps, z_offset=z_offset, aux_data=aux_data))
112 # Next round, start from the previous extruder temperature, i.e. in reversed order.
113 extruder_temps.reverse() # reverse in-place
114 return measure_datas