-
-
Notifications
You must be signed in to change notification settings - Fork 53
Beacon/first layer improvements #101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
Conversation
…ints, not the interpolated points.
…E_BEACON_COMPENSATION_MESH
…can compensation mesh issues rather than failing late eg after heat soaking.
…reasonably close to the current beacon coil temp. Currently allowing up to 20C difference as the acceptable range.
…ault name for the beacon scan compensation mesh
…n model according to beacon_contact_calibrate_model_on_print
…ION, now always saves. From discussion with MS there was no known use case for *not* saving, and not saving creates a profile in a confusing ephemeral state which is lost when the profile is reloaded.
- Implement _RAISE_ERROR in python instead of jinja for cleaner error messages - Implement _TRY, the try/except/finally pattern for macros
…tatus instead of raising an error.
…ated functionality
- Change and enhance the set of metadata stored:
- Remove beacon_model_temp as this is not relevant.
- Add bed temperature, mesh kind and probe method.
- Add warnings in create_compensation_mesh() for unapplied z-tilt or QGL
- Add various new gcode commands
- Defer profile deserialization using delayed gcode to ensure that warnings are seen in the console
- Replace/improve checks and warnings/errors
- Enhance preflight checks called from START_PRINT
- Apply extended metadata to all profiles/meshes created via BED_MESH_CALIBRATE
- Support saving via the standard Z_OFFSET_APPLY_PROBE macro - Exclude active IDEX toolhead offset from the saved value
…tions - TEMPERATURE_WAIT now calls TEMPERATURE_WAIT_BASE even when both MINIMUM and MAXIMUM are not specified, allowing the base impl to raise an error
- This can produce a visible improvement in surface quality, and appears to have little if any impact on CPU usage. The change was not applied more widely as other machines may have lower spec host boards, and the change has not been tested on those machines.
During further testing it became clear that changing the governor while klipper is running can occasionally lead to timer too close or other driver communication issues, and for the time being no workaround was found. So removing the feature for now.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
configuration/klippy/ratos.py (2)
523-535: Bug inget_gcode_file_infofor case‑insensitive filename lookupWhen
filenamedoesn’t match any entry inflistexactly, the function returns the raw[filepath, fsize]list fromfiles_by_lowerwithout joining it withsdcard_dirname. That meansprocess_gcode_file()may pass a relative or incorrect path into the RatOS CLI instead of an absolute path underself.sdcard_dirname.Consider normalizing both branches to always return
[fullpath, size], e.g.:def get_gcode_file_info(self, filename): files = self.v_sd.get_file_list(True) flist = [f[0] for f in files] - files_by_lower = { filepath.lower(): [filepath, fsize] for filepath, fsize in files } + files_by_lower = { filepath.lower(): filepath for filepath, _ in files } filepath = filename try: - if filepath not in flist: - filepath = files_by_lower[filepath.lower()] - return filepath - fullpath = os.path.join(self.sdcard_dirname, filepath); - return [fullpath, os.path.getsize(fullpath)] + if filepath not in flist: + filepath = files_by_lower[filepath.lower()] + fullpath = os.path.join(self.sdcard_dirname, filepath) + return [fullpath, os.path.getsize(fullpath)] except: raise self.printer.command_error("Can not get path for file " + filename)This preserves behavior while ensuring the CLI always sees a full filesystem path.
546-565: Defensive handling ofmsganddisplay_statusinconsole_echo
console_echonow unconditionally callsmsg.replace("_N_", "\n"). If it’s ever invoked withmsg=None(e.g. viaCONSOLE_ECHOwithoutMSG), this will raise an exception. It also assumesself.display_statusis always present.To harden this:
def console_echo(self, title, type, msg=''): - color = "white" + color = "white" opacity = 1.0 @@ - msg = msg.replace("_N_","\n") + if msg is None: + msg = "" + msg = msg.replace("_N_", "\n") @@ - if (type == 'error' or type == 'alert'): - logging.error(title + ": " + msg) - self.display_status.message = f"ERROR: {title} (check the console for details)" - if (type == 'warning'): - logging.warning(title + ": " + msg) - self.display_status.message = f"WARNING: {title} (check the console for details)" + if (type == 'error' or type == 'alert'): + logging.error(title + ": " + msg) + if self.display_status is not None: + self.display_status.message = f"ERROR: {title} (check the console for details)" + if (type == 'warning'): + logging.warning(title + ": " + msg) + if self.display_status is not None: + self.display_status.message = f"WARNING: {title} (check the console for details)"This avoids rare but nasty runtime errors from malformed
CONSOLE_ECHOcalls or from unusual setups lackingdisplay_status.
♻️ Duplicate comments (4)
configuration/klippy/beacon_adaptive_heat_soak.py (4)
78-96: Training data path is still tightly bound to module location
_load_training_data()only looks forbeacon_adaptive_heat_soak_model_training.csvnext to this module. That’s usually fine, but it’s brittle if the file lives in the config dir or the module is packaged differently.Consider the earlier suggestion to fall back to the printer’s config directory, e.g.:
- path = os.path.join( - os.path.dirname(os.path.realpath(__file__)), - 'beacon_adaptive_heat_soak_model_training.csv') + module_dir = os.path.dirname(os.path.realpath(__file__)) + path = os.path.join(module_dir, 'beacon_adaptive_heat_soak_model_training.csv') + if not os.path.exists(path): + config_path = os.path.join(self.printer.get_config_dir(), + 'beacon_adaptive_heat_soak_model_training.csv') + if os.path.exists(config_path): + path = config_pathThis keeps behavior for the common case but is more robust across installs.
497-585: Z‑rate loop and progress handling are solid; consider exception chainingThe main adaptive soak loop correctly:
- Enforces
MAXIMUM_WAIT- Streams Z‑rates from
BeaconZRateSession- Maintains moving and level‑2 averages, hold counts, and trend checks
- Feeds progress via
BackgroundDisplayStatusProgressHandlerand always disables it infinally.To preserve original tracebacks when wrapping failures from
get_next_z_rate(), you could use explicit chaining:- except Exception as e: + except Exception as e: if self.printer.is_shutdown(): raise else: - raise self.printer.command_error(f"Error calculating Z-rate, wait ended prematurely: {e}") + raise self.printer.command_error( + f"Error calculating Z-rate, wait ended prematurely: {e}" + ) from eSame pattern applies in
cmd_BEACON_WAIT_FOR_PRINTER_HEAT_SOAK_CAPTURE_Z_RATES.
639-680: Hardcoded config paths under/home/pi/printer_data/configBoth diagnostic commands write to fixed paths under
/home/pi/printer_data/config/:
cmd_BEACON_WAIT_FOR_PRINTER_HEAT_SOAK_CAPTURE_Z_RATES:fullpath = f'/home/pi/printer_data/config/{filename}'cmd_BEACON_WAIT_FOR_PRINTER_HEAT_SOAK_CAPTURE_BEACON_SAMPLES:filename = f'/home/pi/printer_data/config/...txt'This assumes a specific user/home and layout and will misbehave on non‑
pisetups. Prefer deriving the base from Klipper’s config dir:- fullpath = f'/home/pi/printer_data/config/{filename}' + config_dir = self.printer.get_config_dir() + fullpath = os.path.join(config_dir, filename)and similarly for the beacon samples filename.
7-10: Ensurepygamis declared and installed (dependency hygiene)This module imports and relies on
pygamfor the GAM model inThresholdPredictor. Please make surepygamis listed in your project’s install manifests (e.g. requirements, setup, or packaging metadata) and covered by your deployment/CI setup so prediction doesn’t fail at runtime on a missing module.
🧹 Nitpick comments (3)
configuration/klippy/ratos.py (1)
803-870: BackgroundDisplayStatusProgressHandler is a good fit for long‑running flowsThe periodic timer, spinner sequence, and capped progress value provide a simple, reusable way to surface background progress (e.g. adaptive heat soak) via
display_status.message. If you later need UI progress bars, consider also updatingself.display_status.progress = self._progressinside_handle_timer, but it’s fine as‑is for the current text‑only usage.configuration/klippy/beacon_mesh.py (1)
1028-1092:load_extra_mesh_paramsmigration path is sensible, but logs could help on config errorsThe migration from per‑profile config sections into
mesh_paramsis well thought out (version gating, incompatible profile tracking, and optional chamber/bounds metadata). In theexcept Exception:aroundgetsection, you silentlycontinue; if you ever need to debug mis‑named sections, adebug_echothere could be useful, but that’s optional.configuration/z-probe/beacon.cfg (1)
658-741: IDEX‑aware nozzle expansion compensation logic looks correct
_BEACON_SET_NOZZLE_TEMP_OFFSETnow:
- Avoids applying compensation unless both true‑zero and expansion‑compensation features are enabled.
- Handles IDEX modes by only applying the offset to the active/applicable toolhead (with clear
RATOS_ECHOandDEBUG_ECHOwhen skipped).- Derives the expansion offset from calibrated coefficients, multiplier,
beacon_contact_true_zero_temp, and current target temperature.- Tracks and reuses
nozzle_expansion_applied_offsetto make adjustments idempotent.You might consider defaulting
svv.idex_zoffsetto0.0in the lookup, but overall the logic and guardrails look sound.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
configuration/klippy/beacon_adaptive_heat_soak.py(1 hunks)configuration/klippy/beacon_mesh.py(3 hunks)configuration/klippy/ratos.py(10 hunks)configuration/printers/base.cfg(1 hunks)configuration/printers/v-core-4-hybrid/v-core-4-hybrid.cfg(1 hunks)configuration/printers/v-core-4-idex/v-core-4-idex.cfg(1 hunks)configuration/printers/v-core-4/v-core-4.cfg(1 hunks)configuration/scripts/ratos-common.sh(1 hunks)configuration/scripts/ratos-install.sh(1 hunks)configuration/z-probe/beacon.cfg(18 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- configuration/scripts/ratos-common.sh
- configuration/scripts/ratos-install.sh
- configuration/printers/v-core-4-hybrid/v-core-4-hybrid.cfg
- configuration/printers/v-core-4/v-core-4.cfg
- configuration/printers/base.cfg
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-07-28T19:09:05.023Z
Learnt from: miklschmidt
Repo: Rat-OS/RatOS-configurator PR: 101
File: configuration/printers/v-core-4/v-core-4.cfg:7-9
Timestamp: 2025-07-28T19:09:05.023Z
Learning: In Klipper configuration files, duplicate sections (like `[gcode_macro RatOS]`) do not cause errors. Instead, Klipper uses config section merging where later section parameters (chronologically) take precedence over earlier ones. This means multiple definitions of the same section are allowed and the last one processed will override parameters from earlier definitions.
Applied to files:
configuration/printers/v-core-4-idex/v-core-4-idex.cfg
📚 Learning: 2025-06-16T16:44:30.280Z
Learnt from: LucidityCrash
Repo: Rat-OS/RatOS-configurator PR: 89
File: src/templates/v-core-pro.ts:18-20
Timestamp: 2025-06-16T16:44:30.280Z
Learning: In the RatOS configurator project, v-core-pro configuration files are stored in `configuration/printers/v-core-pro/` in the source repository, but are accessed via `RatOS/printers/v-core-pro/` paths in the deployed/installed environment. The include statements in templates should use the runtime paths, not the source repository paths.
Applied to files:
configuration/printers/v-core-4-idex/v-core-4-idex.cfg
🧬 Code graph analysis (3)
configuration/klippy/beacon_mesh.py (2)
configuration/klippy/ratos.py (8)
BackgroundDisplayStatusProgressHandler(803-870)debug_echo(543-544)console_echo(546-572)get_beacon_probing_regions(607-628)enable(823-828)disable(830-837)progress(840-841)progress(844-845)configuration/klippy/beacon_true_zero_correction.py (1)
_probe_finalize(400-426)
configuration/klippy/ratos.py (1)
configuration/klippy/beacon_mesh.py (1)
get_profiles(323-336)
configuration/klippy/beacon_adaptive_heat_soak.py (1)
configuration/klippy/ratos.py (6)
BackgroundDisplayStatusProgressHandler(803-870)set_auto_rate(847-853)enable(823-828)progress(840-841)progress(844-845)disable(830-837)
🪛 Ruff (0.14.7)
configuration/klippy/beacon_mesh.py
205-205: Unused method argument: gcmd
(ARG002)
237-237: Avoid specifying long messages outside the exception class
(TRY003)
299-299: Avoid specifying long messages outside the exception class
(TRY003)
321-321: Avoid specifying long messages outside the exception class
(TRY003)
354-354: Avoid specifying long messages outside the exception class
(TRY003)
388-388: Avoid specifying long messages outside the exception class
(TRY003)
420-420: Avoid specifying long messages outside the exception class
(TRY003)
423-423: Avoid specifying long messages outside the exception class
(TRY003)
446-446: Avoid specifying long messages outside the exception class
(TRY003)
453-453: Avoid specifying long messages outside the exception class
(TRY003)
460-460: Avoid specifying long messages outside the exception class
(TRY003)
463-463: Avoid specifying long messages outside the exception class
(TRY003)
499-499: Avoid specifying long messages outside the exception class
(TRY003)
531-531: Avoid specifying long messages outside the exception class
(TRY003)
541-541: Avoid specifying long messages outside the exception class
(TRY003)
546-546: Consider moving this statement to an else block
(TRY300)
548-548: Avoid specifying long messages outside the exception class
(TRY003)
548-548: Use explicit conversion flag
Replace with conversion flag
(RUF010)
562-562: Avoid specifying long messages outside the exception class
(TRY003)
635-635: Avoid specifying long messages outside the exception class
(TRY003)
710-710: Consider moving this statement to an else block
(TRY300)
724-724: Do not catch blind exception: Exception
(BLE001)
748-751: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
748-751: Create your own exception
(TRY002)
748-751: Avoid specifying long messages outside the exception class
(TRY003)
1026-1026: Avoid specifying long messages outside the exception class
(TRY003)
1026-1026: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1040-1042: try-except-continue detected, consider logging the exception
(S112)
1040-1040: Do not catch blind exception: Exception
(BLE001)
1057-1057: Abstract raise to an inner function
(TRY301)
1057-1057: Avoid specifying long messages outside the exception class
(TRY003)
1063-1063: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1100-1100: Avoid specifying long messages outside the exception class
(TRY003)
1102-1102: Avoid specifying long messages outside the exception class
(TRY003)
1161-1161: Do not catch blind exception: Exception
(BLE001)
1191-1191: Avoid specifying long messages outside the exception class
(TRY003)
1205-1205: Do not catch blind exception: Exception
(BLE001)
1260-1260: Avoid specifying long messages outside the exception class
(TRY003)
1300-1300: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
1300-1300: Avoid specifying long messages outside the exception class
(TRY003)
1300-1300: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1314-1314: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
1329-1329: Avoid specifying long messages outside the exception class
(TRY003)
1359-1359: Do not catch blind exception: Exception
(BLE001)
1387-1390: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
1387-1390: Create your own exception
(TRY002)
1387-1390: Avoid specifying long messages outside the exception class
(TRY003)
1393-1396: Create your own exception
(TRY002)
1393-1396: Avoid specifying long messages outside the exception class
(TRY003)
1546-1546: Avoid specifying long messages outside the exception class
(TRY003)
1563-1563: Avoid specifying long messages outside the exception class
(TRY003)
1572-1572: Avoid specifying long messages outside the exception class
(TRY003)
1600-1600: Avoid specifying long messages outside the exception class
(TRY003)
1620-1620: Avoid specifying long messages outside the exception class
(TRY003)
1643-1643: Avoid specifying long messages outside the exception class
(TRY003)
1660-1660: Avoid specifying long messages outside the exception class
(TRY003)
1688-1688: Avoid specifying long messages outside the exception class
(TRY003)
1722-1722: Avoid specifying long messages outside the exception class
(TRY003)
1731-1731: Avoid specifying long messages outside the exception class
(TRY003)
1772-1772: Avoid specifying long messages outside the exception class
(TRY003)
1812-1813: Avoid specifying long messages outside the exception class
(TRY003)
1822-1822: Avoid specifying long messages outside the exception class
(TRY003)
1834-1836: Avoid specifying long messages outside the exception class
(TRY003)
1840-1842: Avoid specifying long messages outside the exception class
(TRY003)
1899-1899: Function definition does not bind loop variable secondary_idx
(B023)
configuration/klippy/ratos.py
249-249: Avoid specifying long messages outside the exception class
(TRY003)
269-269: Do not catch blind exception: Exception
(BLE001)
270-270: Use explicit conversion flag
Replace with conversion flag
(RUF010)
276-276: Do not catch blind exception: Exception
(BLE001)
277-277: Use explicit conversion flag
Replace with conversion flag
(RUF010)
285-285: Avoid specifying long messages outside the exception class
(TRY003)
516-516: Consider moving this statement to an else block
(TRY300)
661-661: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
663-663: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
696-696: Unused method argument: eventtime
(ARG002)
713-713: Unused method argument: gcmd
(ARG002)
configuration/klippy/beacon_adaptive_heat_soak.py
44-44: Do not catch blind exception: Exception
(BLE001)
70-70: Avoid specifying long messages outside the exception class
(TRY003)
89-89: Avoid specifying long messages outside the exception class
(TRY003)
94-94: Create your own exception
(TRY002)
94-94: Avoid specifying long messages outside the exception class
(TRY003)
179-179: Avoid specifying long messages outside the exception class
(TRY003)
184-184: Avoid specifying long messages outside the exception class
(TRY003)
232-232: Avoid specifying long messages outside the exception class
(TRY003)
366-366: Avoid specifying long messages outside the exception class
(TRY003)
372-372: Avoid specifying long messages outside the exception class
(TRY003)
372-372: f-string without any placeholders
Remove extraneous f prefix
(F541)
409-409: Avoid specifying long messages outside the exception class
(TRY003)
415-415: Avoid specifying long messages outside the exception class
(TRY003)
424-424: Avoid specifying long messages outside the exception class
(TRY003)
427-427: Avoid specifying long messages outside the exception class
(TRY003)
498-498: Probable insecure usage of temporary file or directory: "/tmp/heat_soak_"
(S108)
525-525: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
525-525: Avoid specifying long messages outside the exception class
(TRY003)
619-619: Avoid equality comparisons to True; use moving_average_trend_checks_passed: for truth checks
Replace with moving_average_trend_checks_passed
(E712)
619-619: Avoid equality comparisons to True; use level_2_moving_average_trend_checks_passed: for truth checks
Replace with level_2_moving_average_trend_checks_passed
(E712)
642-642: Avoid specifying long messages outside the exception class
(TRY003)
645-645: Avoid specifying long messages outside the exception class
(TRY003)
670-670: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
670-670: Avoid specifying long messages outside the exception class
(TRY003)
696-696: Avoid specifying long messages outside the exception class
(TRY003)
699-699: Avoid specifying long messages outside the exception class
(TRY003)
714-714: Avoid specifying long messages outside the exception class
(TRY003)
721-721: Function definition does not bind loop variable samples
(B023)
🔇 Additional comments (26)
configuration/printers/v-core-4-idex/v-core-4-idex.cfg (1)
7-12: Adaptive heat soak + split_delta_z wiring looks correctEnabling
variable_beacon_adaptive_heat_soak: Truehere cleanly ties this printer into the new adaptive heat soak flow, and the local[bed_mesh]split_delta_z: 0.001override is safe and consistent with the other Beacon‑ready configs. Klipper’s section‑merge behavior means this extra[gcode_macro RatOS]block will just augment/override earlier defaults as intended.Based on learnings, multiple
[gcode_macro RatOS]sections are merged with later values winning.configuration/klippy/ratos.py (4)
607-650: Beacon probing region + safe home validation looks sound
get_beacon_probing_regions()andget_safe_home_position()correctly centralize beacon geometry and enforce that the configured safe‑home lies inside the intersection of contact and proximity probing bounds, with a controlled shutdown if it doesn’t. The status exposure viaget_status()and use in_MOVE_TO_SAFE_Z_HOMEgive macros a clean, validated API.
651-695:_MOVE_TO_SAFE_Z_HOMEfuzzy mode and clamping behaviorThe fuzzy‑radius logic (random point within a circle, then clamped to the beacon region or printable area) is well‑bounded and logs when clamping alters the intended position. That’s a good trade‑off between randomness and safety, and the recorded
last_move_to_safe_z_home_positionis useful for debugging.
696-705:get_statusextension is consistent with new state fieldsExposing
last_check_bed_mesh_profile_exists_result,safe_home_position, andlast_move_to_safe_z_home_positioninget_status()aligns with how the macros useprinter.ratos.*inbeacon.cfg. The unusedeventtimearg is standard for Klipper status objects and can be left as‑is.
711-801: Stack‑trace utilities are well‑scoped and opt‑in
cmd_DEBUG_ECHO_STACK_TRACE,get_function_arguments_of_type, andget_formatted_extended_stack_traceare only active whenDEBUG_ECHOis enabled, and they avoid emitting frames without useful GCode context. The callback pattern and use oftraceback.FrameSummaryare appropriate; no functional concerns.configuration/klippy/beacon_adaptive_heat_soak.py (3)
323-375: Beacon prep retry loop and timeout handling look reasonableThe three‑attempt wrapper around
_prepare_for_sampling_and_get_sampling_frequency_core()and the 5‑second / 1000‑good‑sample gating handle known flakiness without blocking the reactor excessively. The finalcommand_erroron insufficient good samples gives a clear, user‑visible failure mode. No functional issues here.
421-451: Threshold prediction + forced threshold wiring is consistentMapping
LAYER_QUALITY→ max Z‑change microns, deriving the period fromMAXIMUM_FIRST_LAYER_DURATION + 120, and feeding that intoThresholdPredictormatches the documented assumptions. The forced_FORCE_THRESHOLDpath logs clearly and bypasses the predictor cleanly.
731-749: Duration formatting helper is correct and readable
_format_seconds()covers all hour/minute/second combinations cleanly and is used in user‑facing messages, which should help users interpret waits and thresholds. No issues here.configuration/klippy/beacon_mesh.py (8)
323-337: Profile filtering helperget_profileslooks correctThe helper cleanly restricts to RatOS‑compatible profiles (
ratos_mesh_versionpresent) and optionally filters byratos_mesh_kind. This matches howauto_select_compensation_meshexpects its input.
338-405: Automatic compensation mesh selection behavior is well designed
auto_select_compensation_mesh:
- Filters to
RATOS_MESH_KIND_COMPENSATIONprofiles- Falls back to nominal bed temp when
bed_temperatureis omitted- Detects ambiguous “equally good” profiles and errors out with a detailed console message
- Warns for large bed‑temperature mismatches
This is a nice safety net around automatic selection; no functional issues spotted.
716-799: Local‑low filter multiprocessing helper is appropriate
_apply_local_low_filter()’s use of a child process with a Pipe to offload the numerically heavy_do_local_low_filter()keeps reactor load bounded. The error propagation viaRatOSBeaconMeshError("Error applying local-low filter: %s" % (result,))is clear and scoped to this feature. No correctness issues seen.
800-1024: Cotemporal compensation mesh creation is consistent with Beacon regions and helpersIn
create_compensation_mesh:
- Beacon probing bounds come from
RatOS.get_beacon_probing_regions(), and you intersect contact/proximity regions to define the safe area.- You sensibly fall back from cotemporal offset‑aligned probing to point‑by‑point probing when
can_use_offset_aligned_probing()says no.- Progress is surfaced via
BackgroundDisplayStatusProgressHandlerin both branches and always disabled infinally.- Temporary meshes and extra metadata are only created when requested (
KEEP_TEMP_MESHES), and final compensation meshes are tagged with RatOS mesh parameters.This is complex but internally consistent; I don’t see logic errors in the probing/spacing or mesh‑saving flow.
1197-1262: De‑ridging filter implementation is straightforward and axis‑safe
_do_apply_deridging_filterhandles both primary axes with simple 1D smoothing and correctly treats edge rows/columns. Theprimary_axisvalidation raisingValueErrorfor anything else is appropriate and bubbles up nicely through your multiprocessing wrapper.
1710-1790: Cotemporal probing capability checks are clear and conservative
can_use_offset_aligned_probing()’s validation of beacon offsets againstminimum_spacingandMAXIMUM_SECONDARY_BEACON_OFFSETis a good guardrail. Errors are raised asRatOSBeaconMeshErrorwith detailed messages, which is exactly what the compensation‑mesh path needs.
1791-1918: Offset‑aligned probe action sequence logic is intricate but consistent
generate_probe_action_sequence_beacon_offset_alignedcarefully:
- Validates desired vs minimum spacing
- Enforces bounds on secondary offset
- Picks primary/secondary axes based on offsets
- Computes a resolution from the primary offset and rounds it
- Generates a serpentine pattern over the bed with leading/trailing probe order dependent on beacon lead/lag
- Ensures contact and proximity points align correctly via
ProbeAction.The use of
offset_divisorand the three phases (initial, paired, trailing) is coherent; I don’t see an obvious indexing or bounds error here.
1351-1430: Use consistent exception types for SciPy dependency checks
_do_interpolate_faulty_region_valuesrelies onscipyandscipy.interpolate.RBFInterpolator. When SciPy is missing or lacksRBFInterpolator, raiseRatOSBeaconMeshErrorinstead of bareExceptionfor consistency with the error handling already present in this function (line 1374):- if not self.scipy: + if not self.scipy: try: self.scipy = importlib.import_module("scipy") except ImportError: - raise Exception( + raise RatOSBeaconMeshError( "Could not load `scipy`. To install it, simply run `ratos doctor`. This " "module is required for Beacon contact compensation mesh creation." ) @@ - if not hasattr(self.scipy.interpolate, "RBFInterpolator"): - raise Exception( + if not hasattr(self.scipy.interpolate, "RBFInterpolator"): + raise RatOSBeaconMeshError( "The RBFInterpolator class is missing from the scipy module. Try using `ratos doctor`. This " "class is required for Beacon contact compensation mesh creation." )Also verify that
scipyis declared in your project's install manifests.configuration/z-probe/beacon.cfg (10)
205-215:already_heatedflag wiring inBEACON_RATOS_CALIBRATEis correctTracking
already_heatedto avoid re‑heating duringBEACON_FINAL_CALIBRATIONwhen a scan‑compensation mesh was just created is a nice optimization and is passed through correctly via_AUTOMATED_ALREADY_HEATED. No issues.
276-338: Adaptive‑vs‑fixed heat soak inBEACON_FINAL_CALIBRATIONThe calibration macro cleanly switches between:
- Adaptive soak (
BEACON_WAIT_FOR_PRINTER_HEAT_SOAKwith a relaxed forced threshold and min/max waits from RatOS variables), plus optional extra post‑completion wait.- Legacy fixed‑time bed soak (
bed_heat_soak_time) when adaptive is disabled.The guard on
already_heatedalso correctly skips the entire heating/soak block when the earlier scan‑compensation step has already done the work.
386-403: Use of fastconfig forz_hop_speedis appropriateSwitching from macro variables to
printer.fastconfig.config.ratos_homing.z_hop_speedin bothBEACON_FINAL_CALIBRATIONandBEACON_POKE_TESTcentralizes the z‑hop speed in the fastconfig tree, which is consistent with the rest of the PR.
769-847:BEACON_MEASURE_BEACON_OFFSETcorrectly leveragessafe_home_positionThe offset‑measurement macro:
- Uses
(safe_home_x, safe_home_y) = printer.ratos.safe_home_position, which is exactly what the new RatOS status exposes.- Probes a sensible 3×3 pattern (center, edges, corners) within printable bounds derived from
printable_x_max/printable_y_maxand margins.- Stores relative offsets and summarises them via
_BEACON_ECHO_BEACON_OFFSET.This is a good consumer of the new safe‑home and beacon‑region logic.
918-1059: Scan compensation macro cleanly composes the new Python helpers
BEACON_CREATE_SCAN_COMPENSATION_MESH:
- Wires user parameters (BED_TEMP, CHAMBER_TEMP, PROFILE, KEEP_TEMP_MESHES) straight through to
_BEACON_CREATE_SCAN_COMPENSATION_MESH_CORE.- Handles adaptive heat soak vs fixed bed/hotend soak consistently with
BEACON_FINAL_CALIBRATION.- Forces ABL (Z_TILT / QGL) before compensation and re‑homes Z where appropriate.
- Restores heaters and chamber appropriately, and gives clear console feedback.
The use of
_MOVE_TO_SAFE_Z_HOMEand the IDEX activation block matches the rest of the RatOS flows.
1062-1072:_BEACON_APPLY_SCAN_COMPENSATION_IF_ENABLEDis a nice guard macroThis macro simply logs the current profile + enable flag and conditionally calls
BEACON_APPLY_SCAN_COMPENSATION PROFILE="...". It’s a low‑risk shim that helps keep higher‑level macros concise.
1074-1092: Preflight Beacon model check before START_PRINT is well‑targeted
_START_PRINT_PREFLIGHT_CHECK_BEACON_MODEL:
- Uses fastconfig to detect Beacon usage and Z endstop mode.
- Distinguishes between configurations that require an existing Beacon model (true‑zero without per‑print calibration, or proximity homing with a model) vs those that don’t.
- Fails early with a clear error and LED indication when a model is required but missing.
This should prevent a lot of confusing mid‑print failures.
1096-1111: Preflight scan‑compensation profile validation is a good safety net
_START_PRINT_PREFLIGHT_CHECK_BEACON_SCAN_COMPENSATIONcomputes a bed temperature (either from params or current heater) and, when compensation is enabled, delegates to_VALIDATE_COMPENSATION_MESH_PROFILEwithCOMPARE_BED_TEMPand the “mismatch is error” flag. That matches the new validation logic inbeacon_mesh.pyand will surface misconfigured profiles before printing.
1208-1216: Z_OFFSET_APPLY_PROBE override for runtime offset is coherentOverriding
Z_OFFSET_APPLY_PROBEto:
- Use
_BEACON_SET_RUNTIME_OFFSET {rawparams}when Beacon is configured andbeacon_contact_start_print_true_zerois enabled.- Fall back to
_Z_OFFSET_APPLY_PROBE_BASEotherwiseis a clean way to route true‑zero setups through RatOS’s runtime‑offset management while preserving default Klipper behavior for other setups.
1218-1228: Runtime offset restore macros are consistent with the new save path
_BEACON_RESTORE_RUNTIME_OFFSETand_BEACON_RESTORE_RUNTIME_OFFSET_LOG_BEFORE_AFTERcorrectly:
- Load
beacon_saved_runtime_offsetfromsave_variables- Apply it via
SET_GCODE_OFFSET Z_ADJUST=...- Log both the stored value and before/after offsets with
DEBUG_ECHOThis closes the loop with
_BEACON_SET_RUNTIME_OFFSET.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
configuration/klippy/beacon_adaptive_heat_soak.py (2)
653-653: Hardcoded path/home/pistill present.This was flagged in a past review and marked as addressed, but the hardcoded path remains. This will fail for users with different usernames.
The past review suggested using
self.printer.get_config_dir()or a similar approach to dynamically resolve the path.
707-707: Hardcoded path/home/pistill present.Same issue as line 653 - this hardcoded path should be replaced with a dynamic resolution.
- filename = f'/home/pi/printer_data/config/beacon_adaptive_heat_soak_beacon_samples_{timestamp}.txt' + config_dir = self.printer.get_config_dir() + filename = os.path.join(config_dir, f'beacon_adaptive_heat_soak_beacon_samples_{timestamp}.txt')
🧹 Nitpick comments (7)
configuration/klippy/beacon_adaptive_heat_soak.py (3)
91-94: Consider using a more specific exception type.Re-raising as a generic
Exceptionloses the specific error type. While thefrom echaining preserves the traceback, consider using a custom exception or preserving the original type for better error handling upstream.try: data = np.genfromtxt(path, delimiter=',', names=True) except Exception as e: - raise Exception(f"Failed to load model training data: {e}") from e + raise IOError(f"Failed to load model training data: {path}") from e
197-199: Consider usingcollections.dequefor O(1) sliding window operations.Using
list.pop(0)is O(n) for each removal. Withwindow_size=30, the impact is minimal, but switching tocollections.deque(maxlen=window_size)would provide O(1) popleft and automatic size limiting.+from collections import deque + class BeaconZRateSession: def __init__(self, config, beacon, samples_per_mean=1000, window_size=30, window_step=1): # ... existing code ... - self._mean_distances = [] - self._times = [] + self._mean_distances = deque(maxlen=window_size) + self._times = deque(maxlen=window_size)Then simplify
get_next_z_rate:- if len(self._mean_distances) == self.window_size: - self._mean_distances.pop(0) - self._times.pop(0) + # deque with maxlen handles removal automatically
267-291: Redundant reactor initialization followed by overwrite to None.Line 267 sets
self.reactorfromprinter.get_reactor(), but line 290 immediately overwrites it toNone. This is then set again in_handle_connect. The initial assignment at line 267 is unnecessary and potentially confusing.def __init__(self, config): self.config = config self.name = config.get_name() self.printer = config.get_printer() - self.reactor = self.printer.get_reactor() self.gcode = self.printer.lookup_object('gcode') # ... configuration values ... # Setup self.reactor = None self.beacon = Noneconfiguration/klippy/beacon_true_zero_correction.py (4)
99-109: Unused handler parameters can be prefixed to clarify intent
railsandprint_timeare unused but required by the event signatures. To make this explicit (and silence ARG002), consider prefixing them with an underscore.- def _handle_homing_move_end(self, homing_state, rails): + def _handle_homing_move_end(self, homing_state, _rails): @@ - def _handle_motor_off(self, print_time): + def _handle_motor_off(self, _print_time):
130-207: Tighten diagnostics error handling and f-string usageThe diagnostics flow and CSV capture logic are well structured. Two small improvements:
- Include the actual
ACTIONvalue in the “unknown action” error while fixing the f-string-without-placeholders issue.- (Optional) The hard-coded
/home/pi/...path may not fit all installs; consider deriving it from configuration in the future.- else: - raise self.gcode.error(f"Unknown action.") + else: + # Include action name for easier debugging. + raise self.gcode.error(f"Unknown action '{action}'.")
339-378: Prefer a more specific exception type for repeatrun()callsThe single-run guard is good, but raising a bare
Exceptionis a bit coarse. A standard runtime error reads better and aligns with Ruff’s TRY002 suggestion.- if self._has_run: - raise Exception("ProbingSession has already been run, and cannot be run more than once.") + if self._has_run: + raise RuntimeError("ProbingSession has already been run and cannot be run more than once.")
400-426: Retry logic is correct; consider whethermax_retriesshould be a hard capFiltering z-values by
z_rejection_threshold, sorting, and using the minimal subset is solid. Currently,max_retriesonly affects how many extra points are pre-generated, not how many retry cycles are allowed. If you intended it as a strict retry cap, you could incorporateself.retriesinto the decision to set_finalize_result = 'retry'.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
configuration/klippy/beacon_adaptive_heat_soak.py(1 hunks)configuration/klippy/beacon_true_zero_correction.py(1 hunks)configuration/klippy/ratos_z_offset.py(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-28T19:09:05.023Z
Learnt from: miklschmidt
Repo: Rat-OS/RatOS-configurator PR: 101
File: configuration/printers/v-core-4/v-core-4.cfg:7-9
Timestamp: 2025-07-28T19:09:05.023Z
Learning: In Klipper configuration files, duplicate sections (like `[gcode_macro RatOS]`) do not cause errors. Instead, Klipper uses config section merging where later section parameters (chronologically) take precedence over earlier ones. This means multiple definitions of the same section are allowed and the last one processed will override parameters from earlier definitions.
Applied to files:
configuration/klippy/ratos_z_offset.py
🧬 Code graph analysis (1)
configuration/klippy/beacon_true_zero_correction.py (2)
configuration/klippy/ratos_z_offset.py (1)
set_offset(74-78)configuration/klippy/ratos.py (2)
get_beacon_probing_regions(607-628)console_echo(546-572)
🪛 Ruff (0.14.7)
configuration/klippy/ratos_z_offset.py
83-83: Avoid specifying long messages outside the exception class
(TRY003)
113-113: Unused method argument: eventtime
(ARG002)
configuration/klippy/beacon_true_zero_correction.py
87-87: Avoid specifying long messages outside the exception class
(TRY003)
99-99: Unused method argument: rails
(ARG002)
105-105: Unused method argument: print_time
(ARG002)
207-207: Avoid specifying long messages outside the exception class
(TRY003)
207-207: f-string without any placeholders
Remove extraneous f prefix
(F541)
236-238: Avoid specifying long messages outside the exception class
(TRY003)
305-305: Avoid specifying long messages outside the exception class
(TRY003)
341-341: Create your own exception
(TRY002)
341-341: Avoid specifying long messages outside the exception class
(TRY003)
385-385: Avoid specifying long messages outside the exception class
(TRY003)
393-393: Avoid specifying long messages outside the exception class
(TRY003)
398-398: Avoid specifying long messages outside the exception class
(TRY003)
configuration/klippy/beacon_adaptive_heat_soak.py
44-44: Do not catch blind exception: Exception
(BLE001)
70-70: Avoid specifying long messages outside the exception class
(TRY003)
89-89: Avoid specifying long messages outside the exception class
(TRY003)
94-94: Create your own exception
(TRY002)
94-94: Avoid specifying long messages outside the exception class
(TRY003)
179-179: Avoid specifying long messages outside the exception class
(TRY003)
184-184: Avoid specifying long messages outside the exception class
(TRY003)
232-232: Avoid specifying long messages outside the exception class
(TRY003)
366-366: Avoid specifying long messages outside the exception class
(TRY003)
372-372: Avoid specifying long messages outside the exception class
(TRY003)
409-409: Avoid specifying long messages outside the exception class
(TRY003)
415-415: Avoid specifying long messages outside the exception class
(TRY003)
424-424: Avoid specifying long messages outside the exception class
(TRY003)
427-427: Avoid specifying long messages outside the exception class
(TRY003)
498-498: Probable insecure usage of temporary file or directory: "/tmp/heat_soak_"
(S108)
525-525: Avoid specifying long messages outside the exception class
(TRY003)
619-619: Avoid equality comparisons to True; use moving_average_trend_checks_passed: for truth checks
Replace with moving_average_trend_checks_passed
(E712)
619-619: Avoid equality comparisons to True; use level_2_moving_average_trend_checks_passed: for truth checks
Replace with level_2_moving_average_trend_checks_passed
(E712)
642-642: Avoid specifying long messages outside the exception class
(TRY003)
645-645: Avoid specifying long messages outside the exception class
(TRY003)
670-670: Avoid specifying long messages outside the exception class
(TRY003)
696-696: Avoid specifying long messages outside the exception class
(TRY003)
699-699: Avoid specifying long messages outside the exception class
(TRY003)
714-714: Avoid specifying long messages outside the exception class
(TRY003)
721-721: Function definition does not bind loop variable samples
(B023)
🔇 Additional comments (24)
configuration/klippy/beacon_adaptive_heat_soak.py (6)
37-61: Multiprocessing implementation looks solid for reactor compatibility.The use of
multiprocessing.Pipewithreactor.pausepolling ensures the main thread remains responsive to Klipper's reactor while waiting for the prediction to complete. The daemon process is appropriate here since it's short-lived and always joined before the method returns.
224-260: Clean and efficient circular buffer implementation.The running sum approach provides O(1) operations for both
addandget_average. The implementation correctly handles the transition from filling to rotating the buffer.
716-721: Loop variablesamplescaptured in nested function is safe here.The static analysis warning (B023) about
samplesbeing captured in the closure is a false positive in this case. Thesampleslist is recreated on each iteration of the outerwhileloop before definingcb, and the streaming session completes before the next iteration.
496-498: Using/tmpfor transient debug data is acceptable.The static analysis warning (S108) about insecure
/tmpusage is a false positive here. This file contains transient diagnostic Z-rate data that doesn't need to persist across reboots, and the timestamped filename prevents collisions.
731-748: Clean time formatting utility.The
_format_secondsmethod handles all edge cases correctly (hours only, minutes only, seconds only, and combinations).
750-751: Standard Klipper config loader pattern.The
load_configfunction follows the expected Klipper module pattern.configuration/klippy/ratos_z_offset.py (8)
1-9: LGTM!The module header and constant definitions are clear and appropriate. The offset names are well-defined and the combined offset key is properly distinguished.
10-29: LGTM!The class initialization follows standard Klipper patterns. Event handler registration, G-code command registration, and instance variable initialization are all properly implemented.
37-66: LGTM! Duplication issue successfully addressed.The G-code command implementations are well-structured. The SET_RATOS_Z_OFFSET command now correctly uses the refactored
_validate_and_set_offsetmethod, which addresses the code duplication concern raised in the previous review.
67-88: LGTM! Well-refactored offset management.The offset management methods are clean and well-structured:
- The
_validate_and_set_offsetmethod successfully eliminates the duplication identified in the previous review- The combined offset calculation using
sum()is efficient- Resetting the last position after offset changes ensures consistency with the gcode_move system
- The zero-value handling (removing from dict) keeps the storage clean
Note: Static analysis flags the error message on line 83 (TRY003), but the inline message is appropriate here for clarity and context.
92-105: LGTM! Transform logic is correctly implemented.The gcode_move transform interface implementation is correct:
get_positionremoves the offset from Z, returning the true position to the callermoveadds the offset to Z, transparently applying the correction during movementThis pattern ensures that G-code commands work with logical coordinates while the physical movement incorporates all registered offsets.
109-117: LGTM! Status tracking is properly implemented.The status methods correctly maintain and expose offset information:
- Status is lazily initialized and updated when offsets change
- The dict includes both individual offsets and the combined value
Note: Static analysis flags
eventtimeas unused (ARG002) on line 113, but this parameter is required by Klipper'sget_statusinterface and cannot be removed.
118-119: LGTM!The module loading function follows the standard Klipper pattern for extension loading.
30-33: No action required. Theforce=Trueparameter is necessary for proper transform chain insertion in Klipper's architecture. Z-offset handlers must override existing transforms to apply corrections at the correct position in the transform stack.configuration/klippy/beacon_true_zero_correction.py (10)
18-76: Config-driven enable/disable and event wiring look correctConfig gates (
disabled, presence of[beacon]) and event handler registration are consistent with Klipper patterns; overall initialization logic is sound.
77-98: Command wrapping ofBEACON_AUTO_CALIBRATEis robustPreserving the original handler via
register_command(..., None)and failing fast if it is missing is a good pattern; the added diagnostics command registration is also clean.
110-129: BEACON_AUTO_CALIBRATE wrapper and multi-point probing trigger look goodResetting
true_zero_correction, honoringSKIP_MULTIPOINT_PROBING, and then running the multi-point session around the original command is a clear and minimally-invasive integration.
212-217: Homing check is straightforward and consistentUsing
toolhead.get_status(...).homed_axesand raisingself.gcode.errorwhen any of x/y/z is missing is consistent with other RatOS modules.
218-240: Point generation logic is correct and defensiveThe random point generator correctly enforces
min_distfrom both center (when requested) and existing points, and it fails fast with a clear error if constraints are too strict formax_iter.
242-267: Nozzle geometry helpers are reasonable approximationsExtruder selection with dual carriage and the heuristic for tip diameter vs. orifice size are sensible and localized, which will make future tuning easy.
269-290: Probe command preparation is clear; SENSOR propagation is handledThe split between normal and error-corrected probing, plus conditional SENSOR propagation, is easy to follow and keeps probe arguments centralized.
307-338: ProbingSession setup and sampling strategy look solidThe session tracks retries, pre-seeds the implied zero sample, and derives
_takefrom the configured sampling strategy; this matches the documented behavior.
379-399: Finalize logic and safety clamp are well thought outUsing
_finalize_resultas a state machine output, enforcing a -0.2 mm lower bound, and only then applying the correction toratos_z_offsetgives a nice safety margin against bad data.
428-430: Config hook is minimal and correct
load_configreturns the extension instance as expected for Klipper modules.
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
configuration/klippy/ratos.py (1)
66-69:load_settings()is called twice in__init__.The method
load_settings()is invoked at both line 66 and line 69. This appears to be unintentional and should be cleaned up.self.old_is_graph_files = [] self.load_settings() self.register_commands() self.register_handler() - self.load_settings() self.post_process_success = Falseconfiguration/macros/util.cfg (1)
397-400: Define_RAISE_ERRORmacro or replace withaction_raise_error().The
_STOP_AND_RAISE_ERRORmacro calls_RAISE_ERRORat line 400, but_RAISE_ERRORis not a standard Klipper function and was removed from this file. Either define_RAISE_ERRORmacro elsewhere in the configuration, or replace the call withaction_raise_error MSG="{params.MSG}"to follow standard Klipper error handling patterns.
♻️ Duplicate comments (1)
configuration/klippy/beacon_adaptive_heat_soak.py (1)
653-653: Hardcoded path/home/pi/printer_data/config/limits portability.This was flagged in past reviews. The path assumes the user is
piand the config directory is at a fixed location. Consider using a dynamic approach to get the config directory.Per past review discussion, this was noted to be addressed separately via
ratos-update.shbehavior changes.
🧹 Nitpick comments (11)
configuration/macros/idex/toolheads.cfg (1)
766-766: Minor timing adjustment - verify necessity.The
initial_durationfor_INIT_TOOLHEADSwas increased from 0.1 to 0.2 seconds. If this addresses a race condition or initialization timing issue, consider adding a brief comment explaining the reason.configuration/klippy/ratos.py (1)
263-277: Bareexcept:clause catches all exceptions includingKeyboardInterruptandSystemExit.Using a bare
except:is overly broad. Consider catchingExceptionexplicitly to avoid suppressing critical exceptions.try: self.gcode.run_script_from_command(to_run) - except: + except Exception: if _except: try: self.gcode.run_script_from_command(_except) except Exception as ex: - self.debug_echo("TRY", f"Except command failed: {str(ex)}") + self.debug_echo("TRY", f"Except command failed: {ex!r}") raise finally: if _finally: try: self.gcode.run_script_from_command(_finally) except Exception as ex: - self.debug_echo("TRY", f"Finally command failed: {str(ex)}") + self.debug_echo("TRY", f"Finally command failed: {ex!r}")The
!rconversion flag provides a more informative repr-style output for exceptions.configuration/printers/v-core-4-idex/v-core-4-idex.cfg (1)
7-12: Adaptive heat soak flag and mesh tuning look fine (minor typo)Enabling
variable_beacon_adaptive_heat_soakhere cleanly opts this printer into the new workflow, andbed_mesh.split_delta_z = 0.001is a targeted tuning knob. Only nit: the comment has a typo.-[bed_mesh] -split_delta_z: 0.001 # Avoid visible surface stripe arfetacts +[bed_mesh] +split_delta_z: 0.001 # Avoid visible surface stripe artifacts(Based on learnings, multiple
[gcode_macro RatOS]sections are merged by Klipper, so this extra section is safe.)configuration/printers/v-core-4/v-core-4.cfg (1)
7-12: Mirrored adaptive heat soak and mesh tuning (same typo)This mirrors the idex config: enabling
variable_beacon_adaptive_heat_soakand tighteningbed_mesh.split_delta_z. Functionally good; same minor spelling issue in the comment.-[bed_mesh] -split_delta_z: 0.001 # Avoid visible surface stripe arfetacts +[bed_mesh] +split_delta_z: 0.001 # Avoid visible surface stripe artifacts(Based on learnings, the extra
[gcode_macro RatOS]section will merge with earlier ones rather than error.)configuration/klippy/fastconfig.py (1)
22-41: Fastconfig wrapper design looks solid; consider minor robustness/lint tweaksThe approach of snapshotting
configfile.get_status()once onklippy:connectand exposing it via a Mapping to avoid repeated deep copies is sound and should address thetimer too closeissues from heavy configs.Two small polish points:
- Initialize
_immutable_statusin__init__to avoid any accidental attribute access before_handle_connectruns (e.g., from logging or introspection).- To satisfy linters about the unused
eventtimearg while keeping the Klipperget_status(eventtime)signature, rename it to_eventtime.class ImmutablePrinterConfigStatusWrapper(Mapping): def __init__(self, config): self.name = config.get_name() self._printer = config.get_printer() self._printer.register_event_handler("klippy:connect", self._handle_connect) - self._initialized = False + self._initialized = False + self._immutable_status = {} @@ - def get_status(self, eventtime=None): + def get_status(self, _eventtime=None):The explicit RuntimeError on pre-initialization access is reasonable as a hard guard as long as no macros touch
printer.fastconfigbeforeklippy:connect.If you haven’t already, it’s worth doing a cold Klipper restart on a test printer and exercising any early delayed_gcode that might reference
printer.fastconfigto confirm no pre-connect call paths exist.configuration/macros/idex/vaoc.cfg (1)
719-740: Configurable hotend heat soak is a nice improvementIntroducing
hotend_heat_soak_time(in seconds) with a default of 0 and converting to milliseconds forG4makes the extra soak opt-in and configurable:
- No behavioral change for existing configs (default 0 → no added wait).
- When set, the echo and dwell are consistent with the user-specified seconds.
Looks good; just ensure
hotend_heat_soak_timeis documented wherever RatOS macro variables are described.configuration/klippy/beacon_true_zero_correction.py (2)
176-176: Hardcoded path may not work on all systems.The path
/home/pi/printer_data/config/assumes a specific user directory structure. Consider using a configurable path or deriving from Klipper's config directory.- filename = f'/home/pi/printer_data/config/mpp_capture_{timestamp}.csv' + # Consider making this path configurable or using: + # config_path = self.config.get_printer().get_start_args().get('config_file', '') + # base_dir = os.path.dirname(config_path) if config_path else '/tmp' + filename = f'/home/pi/printer_data/config/mpp_capture_{timestamp}.csv'
207-207: Remove unnecessary f-string prefix.This f-string has no placeholders.
- raise self.gcode.error(f"Unknown action.") + raise self.gcode.error("Unknown action.")configuration/klippy/beacon_adaptive_heat_soak.py (1)
715-726: Loop variablesamplesnot bound in nested function.The static analysis hint B023 is valid here. The
cbfunction defined inside the while loop on line 717 referencessamplesfrom the enclosing scope. While this works correctly in Python (the closure captures by reference, not value), andsamplesis reassigned each iteration beforecbis used, this pattern can be confusing and error-prone.while self.reactor.monotonic() - start_time < duration: if self.printer.is_shutdown(): raise self.printer.command_error(f"{self.name}: Printer is shutting down") samples = [] - def cb(s): + def cb(s, samples=samples): unsmooth_data = s["data"] unsmooth_freq = self.beacon.count_to_freq(unsmooth_data) unsmooth_dist = self.beacon.freq_to_dist(unsmooth_freq, s["temp"]) samples.append((s["time"], s["dist"], unsmooth_dist))However, since
samplesis a mutable list and is reset each iteration beforecbis invoked, the current code works correctly. This is a minor stylistic concern.configuration/klippy/beacon_mesh.py (2)
1384-1397: Add exception chaining for scipy import errors.When re-raising exceptions, use
from eto maintain the exception chain.if not self.scipy: try: self.scipy = importlib.import_module("scipy") except ImportError: - raise Exception( + raise Exception( "Could not load `scipy`. To install it, simply run `ratos doctor`. This " "module is required for Beacon contact compensation mesh creation." - ) + ) from NoneUsing
from Noneexplicitly indicates this is a deliberate chain break with a user-friendly message.
1038-1043: Consider logging exceptions caught during config section lookup.Static analysis flags the bare
except Exception: continueas potentially hiding errors. While this is intentional (some profiles may not have config sections), consider logging at debug level for troubleshooting.try: config_section_name = self.bed_mesh.pmgr.name + " " + profile_name config = self.config.getsection(config_section_name) - except Exception: + except Exception as e: # Skip if no config section exists for this profile + logging.debug(f"{self.name}: No config section for profile '{profile_name}': {e}") continue
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
configuration/klippy/beacon_adaptive_heat_soak_model_training.csvis excluded by!**/*.csv
📒 Files selected for processing (43)
configuration/homing.cfg(8 hunks)configuration/klippy/beacon_adaptive_heat_soak.py(1 hunks)configuration/klippy/beacon_mesh.py(3 hunks)configuration/klippy/beacon_true_zero_correction.py(1 hunks)configuration/klippy/fastconfig.py(1 hunks)configuration/klippy/ratos.py(10 hunks)configuration/klippy/ratos_z_offset.py(1 hunks)configuration/macros.cfg(20 hunks)configuration/macros/idex/idex_is.cfg(2 hunks)configuration/macros/idex/toolheads.cfg(6 hunks)configuration/macros/idex/util.cfg(2 hunks)configuration/macros/idex/vaoc.cfg(5 hunks)configuration/macros/mesh.cfg(9 hunks)configuration/macros/overrides.cfg(8 hunks)configuration/macros/parking.cfg(1 hunks)configuration/macros/priming.cfg(7 hunks)configuration/macros/util.cfg(3 hunks)configuration/moonraker.conf(1 hunks)configuration/printers/base.cfg(1 hunks)configuration/printers/v-core-3-hybrid/macros.cfg(1 hunks)configuration/printers/v-core-3-idex/macros.cfg(2 hunks)configuration/printers/v-core-3/macros.cfg(1 hunks)configuration/printers/v-core-4-hybrid/300.cfg(0 hunks)configuration/printers/v-core-4-hybrid/400.cfg(0 hunks)configuration/printers/v-core-4-hybrid/500.cfg(0 hunks)configuration/printers/v-core-4-hybrid/macros.cfg(2 hunks)configuration/printers/v-core-4-hybrid/v-core-4-hybrid.cfg(1 hunks)configuration/printers/v-core-4-idex/300.cfg(0 hunks)configuration/printers/v-core-4-idex/400.cfg(0 hunks)configuration/printers/v-core-4-idex/500.cfg(0 hunks)configuration/printers/v-core-4-idex/macros.cfg(2 hunks)configuration/printers/v-core-4-idex/v-core-4-idex.cfg(1 hunks)configuration/printers/v-core-4/300.cfg(0 hunks)configuration/printers/v-core-4/400.cfg(0 hunks)configuration/printers/v-core-4/500.cfg(0 hunks)configuration/printers/v-core-4/macros.cfg(1 hunks)configuration/printers/v-core-4/v-core-4.cfg(1 hunks)configuration/printers/v-core-pro/macros.cfg(1 hunks)configuration/scripts/ratos-common.sh(1 hunks)configuration/scripts/ratos-install.sh(1 hunks)configuration/z-probe/beacon.cfg(18 hunks)configuration/z-probe/stowable-probe.cfg(0 hunks)src/server/gcode-processor/Actions.ts(1 hunks)
💤 Files with no reviewable changes (10)
- configuration/printers/v-core-4-idex/500.cfg
- configuration/printers/v-core-4-hybrid/500.cfg
- configuration/printers/v-core-4-idex/300.cfg
- configuration/printers/v-core-4-hybrid/300.cfg
- configuration/printers/v-core-4-hybrid/400.cfg
- configuration/printers/v-core-4/300.cfg
- configuration/printers/v-core-4/500.cfg
- configuration/printers/v-core-4/400.cfg
- configuration/printers/v-core-4-idex/400.cfg
- configuration/z-probe/stowable-probe.cfg
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-07-28T19:09:05.023Z
Learnt from: miklschmidt
Repo: Rat-OS/RatOS-configurator PR: 101
File: configuration/printers/v-core-4/v-core-4.cfg:7-9
Timestamp: 2025-07-28T19:09:05.023Z
Learning: In Klipper configuration files, duplicate sections (like `[gcode_macro RatOS]`) do not cause errors. Instead, Klipper uses config section merging where later section parameters (chronologically) take precedence over earlier ones. This means multiple definitions of the same section are allowed and the last one processed will override parameters from earlier definitions.
Applied to files:
configuration/printers/v-core-4-idex/v-core-4-idex.cfgconfiguration/macros/idex/util.cfgconfiguration/z-probe/beacon.cfgconfiguration/printers/v-core-4/v-core-4.cfgconfiguration/printers/v-core-4-hybrid/v-core-4-hybrid.cfgconfiguration/macros/overrides.cfgconfiguration/macros/util.cfgconfiguration/klippy/ratos_z_offset.py
📚 Learning: 2025-06-16T16:44:30.280Z
Learnt from: LucidityCrash
Repo: Rat-OS/RatOS-configurator PR: 89
File: src/templates/v-core-pro.ts:18-20
Timestamp: 2025-06-16T16:44:30.280Z
Learning: In the RatOS configurator project, v-core-pro configuration files are stored in `configuration/printers/v-core-pro/` in the source repository, but are accessed via `RatOS/printers/v-core-pro/` paths in the deployed/installed environment. The include statements in templates should use the runtime paths, not the source repository paths.
Applied to files:
configuration/printers/v-core-4-idex/v-core-4-idex.cfgconfiguration/printers/v-core-4/v-core-4.cfgconfiguration/printers/v-core-4-hybrid/v-core-4-hybrid.cfg
📚 Learning: 2025-12-02T18:27:19.189Z
Learnt from: tg73
Repo: Rat-OS/RatOS-configurator PR: 101
File: configuration/z-probe/beacon.cfg:100-131
Timestamp: 2025-12-02T18:27:19.189Z
Learning: In Klipper configuration macros using Jinja2 templates, the `|default(value)` filter provides a fallback value when a variable is undefined or missing. For example, `printer["gcode_macro RatOS"].some_variable|default(0)` will return `0` if `variable_some_variable` is not declared in the `[gcode_macro RatOS]` section. This is a standard pattern for optional or backward-compatible settings and does not cause errors.
Applied to files:
configuration/z-probe/beacon.cfg
🧬 Code graph analysis (6)
src/server/gcode-processor/Actions.ts (2)
src/server/gcode-processor/State.ts (2)
gcodeInfo(79-84)gcodeInfo(86-88)src/server/gcode-processor/errors.ts (1)
SlicerNotSupported(36-36)
configuration/klippy/beacon_true_zero_correction.py (2)
configuration/klippy/ratos_z_offset.py (2)
set_offset(74-78)get_position(92-97)configuration/klippy/ratos.py (2)
get_beacon_probing_regions(607-628)console_echo(546-572)
configuration/klippy/ratos_z_offset.py (1)
configuration/klippy/fastconfig.py (3)
items(76-77)get(67-68)values(73-74)
configuration/klippy/ratos.py (2)
configuration/klippy/fastconfig.py (2)
get(67-68)keys(70-71)configuration/klippy/beacon_mesh.py (1)
get_profiles(323-336)
configuration/klippy/beacon_mesh.py (1)
configuration/klippy/ratos.py (6)
BackgroundDisplayStatusProgressHandler(803-870)get_beacon_probing_regions(607-628)enable(823-828)disable(830-837)progress(840-841)progress(844-845)
configuration/klippy/beacon_adaptive_heat_soak.py (1)
configuration/klippy/ratos.py (7)
BackgroundDisplayStatusProgressHandler(803-870)set_auto_rate(847-853)enable(823-828)progress(840-841)progress(844-845)disable(830-837)load_config(875-876)
🪛 Ruff (0.14.7)
configuration/klippy/fastconfig.py
37-37: Unused method argument: eventtime
(ARG002)
39-39: Avoid specifying long messages outside the exception class
(TRY003)
configuration/klippy/beacon_true_zero_correction.py
87-87: Avoid specifying long messages outside the exception class
(TRY003)
99-99: Unused method argument: rails
(ARG002)
105-105: Unused method argument: print_time
(ARG002)
207-207: Avoid specifying long messages outside the exception class
(TRY003)
207-207: f-string without any placeholders
Remove extraneous f prefix
(F541)
236-238: Avoid specifying long messages outside the exception class
(TRY003)
297-297: Avoid specifying long messages outside the exception class
(TRY003)
310-310: Avoid specifying long messages outside the exception class
(TRY003)
346-346: Create your own exception
(TRY002)
346-346: Avoid specifying long messages outside the exception class
(TRY003)
390-390: Avoid specifying long messages outside the exception class
(TRY003)
398-398: Avoid specifying long messages outside the exception class
(TRY003)
403-403: Avoid specifying long messages outside the exception class
(TRY003)
configuration/klippy/ratos_z_offset.py
83-83: Avoid specifying long messages outside the exception class
(TRY003)
113-113: Unused method argument: eventtime
(ARG002)
configuration/klippy/ratos.py
249-249: Avoid specifying long messages outside the exception class
(TRY003)
269-269: Do not catch blind exception: Exception
(BLE001)
270-270: Use explicit conversion flag
Replace with conversion flag
(RUF010)
276-276: Do not catch blind exception: Exception
(BLE001)
277-277: Use explicit conversion flag
Replace with conversion flag
(RUF010)
285-285: Avoid specifying long messages outside the exception class
(TRY003)
516-516: Consider moving this statement to an else block
(TRY300)
661-661: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
663-663: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
696-696: Unused method argument: eventtime
(ARG002)
713-713: Unused method argument: gcmd
(ARG002)
configuration/klippy/beacon_mesh.py
205-205: Unused method argument: gcmd
(ARG002)
237-237: Avoid specifying long messages outside the exception class
(TRY003)
299-299: Avoid specifying long messages outside the exception class
(TRY003)
321-321: Avoid specifying long messages outside the exception class
(TRY003)
354-354: Avoid specifying long messages outside the exception class
(TRY003)
388-388: Avoid specifying long messages outside the exception class
(TRY003)
420-420: Avoid specifying long messages outside the exception class
(TRY003)
423-423: Avoid specifying long messages outside the exception class
(TRY003)
446-446: Avoid specifying long messages outside the exception class
(TRY003)
453-453: Avoid specifying long messages outside the exception class
(TRY003)
460-460: Avoid specifying long messages outside the exception class
(TRY003)
463-463: Avoid specifying long messages outside the exception class
(TRY003)
499-499: Avoid specifying long messages outside the exception class
(TRY003)
531-531: Avoid specifying long messages outside the exception class
(TRY003)
541-541: Avoid specifying long messages outside the exception class
(TRY003)
546-546: Consider moving this statement to an else block
(TRY300)
548-548: Avoid specifying long messages outside the exception class
(TRY003)
548-548: Use explicit conversion flag
Replace with conversion flag
(RUF010)
562-562: Avoid specifying long messages outside the exception class
(TRY003)
635-635: Avoid specifying long messages outside the exception class
(TRY003)
711-711: Consider moving this statement to an else block
(TRY300)
725-725: Do not catch blind exception: Exception
(BLE001)
749-752: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
749-752: Create your own exception
(TRY002)
749-752: Avoid specifying long messages outside the exception class
(TRY003)
1027-1027: Avoid specifying long messages outside the exception class
(TRY003)
1027-1027: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1041-1043: try-except-continue detected, consider logging the exception
(S112)
1041-1041: Do not catch blind exception: Exception
(BLE001)
1058-1058: Abstract raise to an inner function
(TRY301)
1058-1058: Avoid specifying long messages outside the exception class
(TRY003)
1064-1064: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1101-1101: Avoid specifying long messages outside the exception class
(TRY003)
1103-1103: Avoid specifying long messages outside the exception class
(TRY003)
1162-1162: Do not catch blind exception: Exception
(BLE001)
1192-1192: Avoid specifying long messages outside the exception class
(TRY003)
1206-1206: Do not catch blind exception: Exception
(BLE001)
1261-1261: Avoid specifying long messages outside the exception class
(TRY003)
1301-1301: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
1301-1301: Avoid specifying long messages outside the exception class
(TRY003)
1301-1301: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1315-1315: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
1330-1330: Avoid specifying long messages outside the exception class
(TRY003)
1360-1360: Do not catch blind exception: Exception
(BLE001)
1388-1391: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
1388-1391: Create your own exception
(TRY002)
1388-1391: Avoid specifying long messages outside the exception class
(TRY003)
1394-1397: Create your own exception
(TRY002)
1394-1397: Avoid specifying long messages outside the exception class
(TRY003)
1547-1547: Avoid specifying long messages outside the exception class
(TRY003)
1564-1564: Avoid specifying long messages outside the exception class
(TRY003)
1573-1573: Avoid specifying long messages outside the exception class
(TRY003)
1601-1601: Avoid specifying long messages outside the exception class
(TRY003)
1621-1621: Avoid specifying long messages outside the exception class
(TRY003)
1644-1644: Avoid specifying long messages outside the exception class
(TRY003)
1661-1661: Avoid specifying long messages outside the exception class
(TRY003)
1689-1689: Avoid specifying long messages outside the exception class
(TRY003)
1723-1723: Avoid specifying long messages outside the exception class
(TRY003)
1732-1732: Avoid specifying long messages outside the exception class
(TRY003)
1773-1773: Avoid specifying long messages outside the exception class
(TRY003)
1813-1814: Avoid specifying long messages outside the exception class
(TRY003)
1823-1823: Avoid specifying long messages outside the exception class
(TRY003)
1835-1837: Avoid specifying long messages outside the exception class
(TRY003)
1841-1843: Avoid specifying long messages outside the exception class
(TRY003)
1900-1900: Function definition does not bind loop variable secondary_idx
(B023)
configuration/klippy/beacon_adaptive_heat_soak.py
44-44: Do not catch blind exception: Exception
(BLE001)
70-70: Avoid specifying long messages outside the exception class
(TRY003)
89-89: Avoid specifying long messages outside the exception class
(TRY003)
94-94: Create your own exception
(TRY002)
94-94: Avoid specifying long messages outside the exception class
(TRY003)
179-179: Avoid specifying long messages outside the exception class
(TRY003)
184-184: Avoid specifying long messages outside the exception class
(TRY003)
232-232: Avoid specifying long messages outside the exception class
(TRY003)
366-366: Avoid specifying long messages outside the exception class
(TRY003)
372-372: Avoid specifying long messages outside the exception class
(TRY003)
409-409: Avoid specifying long messages outside the exception class
(TRY003)
415-415: Avoid specifying long messages outside the exception class
(TRY003)
424-424: Avoid specifying long messages outside the exception class
(TRY003)
427-427: Avoid specifying long messages outside the exception class
(TRY003)
498-498: Probable insecure usage of temporary file or directory: "/tmp/heat_soak_"
(S108)
525-525: Avoid specifying long messages outside the exception class
(TRY003)
642-642: Avoid specifying long messages outside the exception class
(TRY003)
645-645: Avoid specifying long messages outside the exception class
(TRY003)
670-670: Avoid specifying long messages outside the exception class
(TRY003)
696-696: Avoid specifying long messages outside the exception class
(TRY003)
699-699: Avoid specifying long messages outside the exception class
(TRY003)
714-714: Avoid specifying long messages outside the exception class
(TRY003)
721-721: Function definition does not bind loop variable samples
(B023)
🔇 Additional comments (79)
configuration/printers/v-core-3-hybrid/macros.cfg (2)
6-6: Clarify the rationale for the HYBRID_INIT delay change.The initial_duration was increased from 0.1 to 0.2 seconds. Please provide context for this timing adjustment—is it addressing a timing issue, improving probe stability, or another concern?
22-22: Verify fastconfig migration consistency.Per the PR objectives, the broader refactoring shifts from
printer.configfile.settingstoprinter.fastconfig.settingsfor beacon-related configuration checks. This line still usesprinter.configfile.settings.beacon. Confirm whether this should be updated to usefastconfigas part of the centralized configuration pattern, or if configfile.settings is intentionally retained here.configuration/printers/v-core-pro/macros.cfg (1)
16-20: Beacon condition correctly migrated tofastconfig; ensure object is always presentSwitching the guard to
printer.fastconfig.settings.beaconkeeps the contact-path behavior intact and aligns this macro with the new fastconfig model. Please just confirm thatprinter.fastconfigand.settingsare guaranteed to exist for this profile at macro-eval time (even when beacon is disabled), so this check never throws due to a missingfastconfigobject.configuration/printers/v-core-3-idex/macros.cfg (2)
14-14: Verify the rationale for doubling the initialization delay.The initial delay was doubled from 0.1 to 0.2 seconds. Please confirm whether this change addresses a specific timing or race condition issue during IDEX initialization, or if it's a preventive measure.
48-48: Verify fastconfig availability and complete migration.The migration from
printer.configfile.settings.beacontoprinter.fastconfig.settings.beaconis part of a broader architectural change. Ensure that:
printer.fastconfigis properly initialized before this macro executes- The migration is complete and consistent across all printer configurations
fastconfig.settings.beaconprovides the same structure and values asconfigfile.settings.beaconconfiguration/scripts/ratos-install.sh (1)
4-16: libopenblas-base addition to PKGLIST looks fineThe extended
PKGLISTkeeps the existing pattern and won’t affect theapt-getcall semantics.configuration/moonraker.conf (1)
113-116: Klipper pinned_commit bump is configuration-onlyChanging the
pinned_commitSHA for[update_manager klipper]is a straightforward version uplift and doesn’t alter Moonraker config semantics here. Just ensure this commit has been validated with the new beacon/mesh workflows.configuration/macros/idex/idex_is.cfg (1)
41-51: Probe point source migration to fastconfig is consistentBoth macros now pull
probe_pointsfromprinter.fastconfig.settings.resonance_tester.probe_points[0], matching the project-wide move offprinter.configfile.settingswithout changing how the coordinates are consumed.Also applies to: 301-309
configuration/printers/v-core-4-hybrid/macros.cfg (1)
5-10: Hybrid init delay and fastconfig-based beacon check look good
- Increasing
_HYBRID_INITinitial_durationto 0.2s should give a bit more safety margin without side effects.- Switching the Z tilt beacon check to
printer.fastconfig.settings.beaconwhile gating onbeacon_contact_z_tilt_adjustmatches the rest of the fastconfig migration and keeps the legacy fallback path intact.Also applies to: 22-26
src/server/gcode-processor/Actions.ts (1)
99-104: PrusaSlicer version gate and message are consistentThe updated
semver.satisfiesexpression now exactly matches the error message (2.8.0,2.8.1, and2.9.0–2.9.2), preserving the “only specific releases” policy while adding 2.9.1 and 2.9.2. If you later broaden support, consider moving to a range (e.g.>=2.8.0 <2.10.0) to avoid having to touch this list for each patch.configuration/macros/parking.cfg (1)
28-35: Guard against potentially undefinedbeacon_contact_start_print_true_zeroThe variable
beacon_contact_start_print_true_zeroused in the condition appears without a local definition in this file. If this variable is not globally injected into the Jinja context by Klipper or the RatOS configuration, the condition could fail or behave unexpectedly. Verify that this variable is reliably available in the Jinja scope, or consider deriving it fromprinter["gcode_macro RatOS"]with a safe default as a more defensive approach.configuration/macros/idex/util.cfg (1)
14-17: LGTM - Consistent migration to fastconfig.The switch from
printer.configfile.settingstoprinter.fastconfig.settingsaligns with the centralized immutable config wrapper pattern introduced in this PR.Also applies to: 40-41
configuration/homing.cfg (5)
81-81: LGTM - Centralized safe home position retrieval.The tuple unpacking from
printer.ratos.safe_home_positionproperly retrieves both X and Y coordinates from the centralized accessor in ratos.py.Also applies to: 124-124
155-156: New beacon configuration variables added.These variables support the beacon true-zero workflow and fuzzy positioning feature. The default values (false/0) ensure backward compatibility.
173-190: Beacon calibration logic looks correct.The conditional branching properly distinguishes between:
beacon_contact_start_print_true_zero=true: Skip multipoint probing here since critical zero probing happens during start print- Otherwise: Perform full calibration including multipoint probing
334-336: Macro renamed to debug-only echo.The macro
_MOVE_TO_SAFE_Z_HOMEwas renamed to__MOVE_TO_SAFE_Z_HOME_ECHO_DEBUGand now only logs parameters. The actual movement is handled by the Python implementationcmd_MOVE_TO_SAFE_Z_HOMEin ratos.py, which calls this macro for debug output via__MOVE_TO_SAFE_Z_HOME_ECHO_DEBUG.
329-330: Verifyratos_homingsection exists in fastconfig.The
_Z_HOPmacro now readsz_hopandz_hop_speedfromprinter.fastconfig.config.ratos_homing. Ensure the[ratos_homing]section (defined at lines 20-23 in this file) is properly captured by the fastconfig module.configuration/macros/idex/toolheads.cfg (2)
496-498: LGTM - Consistent fastconfig migration for beacon checks.Both beacon configuration checks are properly migrated to use
printer.fastconfig.settings.beacon.Also applies to: 563-565
830-834: LGTM - Debug logging helper.The new
_SET_TOOLHEAD_OFFSET_LOG_DEBUGmacro provides useful before/after offset state logging for debugging toolhead offset changes.configuration/klippy/ratos.py (3)
656-686: LGTM - Fuzzy positioning implementation.The fuzzy positioning uses proper uniform distribution within a circle (sqrt of random for radius ensures uniform area distribution). The clamping to beacon probing or printable region is correctly implemented with appropriate warnings when clamping occurs.
Note: Using
random.random()is acceptable here as this is not for cryptographic purposes - it's for distributing probe contact points to reduce bed wear.
803-870: NewBackgroundDisplayStatusProgressHandlerclass.This class provides background progress updates with a spinner for display status during long operations. The implementation looks solid:
- Proper reactor timer registration/unregistration
- Progress clamping between 0.0 and 1.0
- Auto-rate feature for gradual progress updates
- Clean enable/disable lifecycle
630-649: Safe home position validation triggers printer shutdown.The
get_safe_home_positionmethod callsprinter.invoke_shutdown()when the configured safe home is outside the beacon-probable region. This could cause unexpected shutdowns if invoked from frequently-called status update methods.Consider whether a shutdown is the appropriate response here, or if raising an error during command execution would be more appropriate. The current implementation may cause operational issues if triggered repeatedly during normal operation.
configuration/macros.cfg (7)
284-294: Good UX improvement - LED feedback before error.Adding
_LED_START_PRINTING_ERRORbefore raising errors provides visual feedback to users when mandatory parameters are missing.
326-333: Beacon adaptive heat soak configuration.The new configuration variables provide fine-grained control over the adaptive heat soak behavior with sensible defaults:
min_wait: 0 (no minimum)max_wait: 5400 (90 minutes)layer_quality: 3maximum_first_layer_duration: 1800 (30 minutes)
625-639: Beacon adaptive heat soak integration.The implementation properly:
- Moves to safe Z home position
- Lowers Z to 2.5mm for proximity measurements
- Waits for heat soak using beacon measurements
- Supports optional extra wait time after completion
The fallback to traditional time-based soak when beacon adaptive heat soak is disabled maintains backward compatibility.
733-740: Explicit standby flag reset ensures consistent state.Resetting both T0 and T1 standby flags to False before conditionally setting the inactive toolhead to standby prevents stale state from previous prints.
1033-1039: Fuzzy positioning and position storage for bed mesh.The fuzzy radius parameter allows randomizing the true-zero probe position to distribute wear, and the position is stored for later use when setting the mesh zero reference. This is a well-designed integration.
1274-1284: END_PRINT beacon offset cleanup.The migration from inline offset reset to
_BEACON_SUBTRACT_CONTACT_EXPANSION_OFFSETis cleaner and delegates the logic to the appropriate macro.
1055-1059: Position storage macro for bed mesh zero reference.This macro reads
printer.ratos.last_move_to_safe_z_home_positionand stores it in_START_PRINT_BED_MESHvariables. This enables the bed mesh to use the actual true-zero position (which may differ from the configured safe home when fuzzy positioning is used).configuration/printers/v-core-3/macros.cfg (1)
20-24: Beacon check correctly migrated tofastconfigSwitching the beacon presence check to
printer.fastconfig.settings.beaconkeeps behavior while avoidingconfigfiledeep copies. Looks good and consistent with the new fastconfig wrapper.configuration/printers/v-core-4/macros.cfg (1)
16-20: Consistent fastconfig-based beacon guardUsing
printer.fastconfig.settings.beaconhere mirrors the v-core-3 macro and removes repeatedconfigfilesnapshots. No functional regression apparent.configuration/printers/v-core-4-idex/macros.cfg (2)
15-19: Slightly increased_IDEX_INITdelay is reasonableDoubling
initial_durationfrom 0.1s to 0.2s should only improve robustness against startup races and has negligible impact on startup latency.
42-46: Beacon-aware Z-tilt now uses fastconfigThe Z-tilt contact path is now gated on
printer.fastconfig.settings.beacon, aligning with the new immutable config snapshot and matching other macros in this PR. Behavior remains the same when beacon is configured.configuration/macros/idex/vaoc.cfg (3)
117-120: IDEX safe distance now sourced from fastconfigUsing
printer.fastconfig.settings.dual_carriage.safe_distancehere removes the heavyconfigfilestatus copy and stays true to the configured dual_carriage value. Assumes dual_carriage is always present on VAOC-enabled IDEX machines, which matches this file’s target.If there are edge configurations without
[dual_carriage]that still include VAOC, consider a defensive default (e.g.,|default(70)) to avoid undefined-key errors.
304-345: Consistent fastconfig migration for_VAOC_LOAD_TOOLsafe distanceSame as
_START_VAOC, sourcingsafe_distancefromprinter.fastconfig.settings.dual_carriage.safe_distancekeeps behavior while avoiding repeated deep copies. No functional issues spotted.
633-659: Beacon gate for temp-offset calibration updated to fastconfigThe VAOC temp-offset calibration is now guarded by
printer.fastconfig.settings.beacon, in line with other beacon/true-zero flows. This should behave identically to the old configfile-based check while benefitting from the immutable snapshot.configuration/scripts/ratos-common.sh (1)
194-198: Unable to verify this review comment. The repository could not be accessed in the sandbox environment to confirm:
- Whether the extension paths actually exist
- Whether the
expected_extensionsarray follows the claimed pattern- Whether auto-registration logic will properly handle these entries
- Whether config sections use matching extension names
The original review recommends verification but does not provide verification results. To properly assess this comment, access to the codebase is needed to inspect the registration logic, verify file paths, and check config section alignment.
configuration/macros/priming.cfg (4)
32-45: Consistent migration to fastconfig data source.The migration from
printer.configfile.settingstoprinter.fastconfig.settingsis applied consistently across all beacon/bltouch/probe checks in this macro. The logic flow remains unchanged.
105-125: LGTM - Probe offset retrieval updated consistently.The probe offset retrieval logic correctly migrates all three probe types (bltouch, probe, beacon) to use
printer.fastconfig.settings. The error message at line 124 appropriately guides users when no probe is configured.
207-217: LGTM - Beacon detection updated for probe method selection.The beacon presence check for selecting contact vs. standard probing is correctly migrated to fastconfig.
354-356: LGTM - PRIME_BLOB probe checks migrated consistently.All probe availability checks within PRIME_BLOB are consistently updated to use fastconfig.
Also applies to: 379-381, 410-412
configuration/macros/util.cfg (3)
48-61: Good documentation for startup ordering requirements.The added comment clearly explains the ordering dependency and the 0.2-second minimum delay requirement for subsequent init macros. The beacon check migration to fastconfig is correct.
255-262: LGTM - Hybrid inverted check migrated correctly.The migration to
printer.fastconfig.settings.ratos_hybrid_corexymaintains the same logic for detecting the inverted configuration.
383-391: LGTM - Skew profile lookup migrated to fastconfig.config.The change to
printer.fastconfig.configfor looking up skew correction profiles is consistent with the config accessor pattern.configuration/klippy/ratos_z_offset.py (4)
10-29: Well-structured Z-offset manager with Klipper transform compliance.The class correctly implements the gcode_move transform interface with proper position list copying (
[:]) to avoid mutating the original. The event handler registration and gcode command setup follow Klipper conventions.
80-88: Good refactor addressing previous review feedback.The
_validate_and_set_offsethelper method consolidates the duplicated validation logic as suggested in past reviews. The implementation correctly handles zero-value cleanup by removing entries rather than storing zeros.
92-104: Transform implementation correctly applies offset bidirectionally.The
get_positionremoves the offset (for reporting the logical position) whilemoveadds it (to apply physical correction). Both methods properly copy the position list to avoid side effects.
113-116: Unusedeventtimeparameter is intentional.The
eventtimeparameter inget_statusfollows Klipper's standard signature for status methods and should be retained for API compatibility even if unused.configuration/macros/overrides.cfg (5)
95-108: Beacon thermal offset updates properly gated by print state.The
is_printing_gcodecheck ensures nozzle thermal expansion offsets are only updated during active printing, preventing unintended offset changes during preheat or manual temperature commands.
149-154: LGTM - M109 beacon offset handling consistent with M104.The same pattern is correctly applied to M109, updating thermal offsets after the wait completes.
185-191: LGTM - SET_HEATER_TEMPERATURE beacon integration.Correctly applies beacon offset updates only when targeting an extruder heater (
t != -1) and during active printing.
223-247: Improved logging with descriptive sensor/toolhead identification.The new
idvariable provides clearer log messages distinguishing between generic sensors and toolhead extruders. The fallback case at lines 238-244 correctly propagates to the base command to maintain consistent error behavior.
319-354: Comprehensive BED_MESH_CALIBRATE wrapper with proper sequencing.The macro correctly:
- Applies Z_TILT_ADJUST/QUAD_GANTRY_LEVEL if not already applied
- Rehomes Z after leveling adjustments
- Checks active beacon model temperature for proximity probing
- Handles stowable probe deploy/stow
- Applies RatOS bed mesh parameters post-calibration
The
abl_and_home_z_if_requiredvariable allows bypassing the leveling checks when needed.configuration/klippy/beacon_true_zero_correction.py (6)
18-75: Well-structured configuration with sensible defaults and bounds.The configuration options are well-documented with clear explanations of the sampling strategies. The safety defaults (z_rejection_threshold=0.075, max_retries=10) are derived from empirical testing data.
77-108: Correct event handling for offset lifecycle.The offset is properly cleared on both Z-axis homing (
homing:home_rails_end) and motor disable (stepper_enable:motor_off), ensuring stale corrections don't persist across homing cycles.
292-310: Good validation with clear error messaging.The probing region validation correctly guards against
None(addressing past review feedback) and provides clear error messages when the probing region exceeds the configured contact area.
344-382: Robust probing session with retry mechanism.The session correctly:
- Generates points with minimum spacing based on nozzle tip diameter
- Validates the probing region before starting
- Reserves extra points for retries upfront
- Uses
probe.ProbePointsHelperfor standardized probing
384-403: Comprehensive finalization with safety checks.The -0.2mm safety limit is a good protection against bed damage from erroneous corrections. Error messages are clear and actionable.
405-431: Statistical approach is well-implemented.The "take N, keep 3 lowest" strategy effectively filters out early-trigger outliers (values above
z_rejection_threshold) while using the mean of the lowest samples for robustness. The retry mechanism for rejected samples is elegantly handled by pre-generating extra points.configuration/macros/mesh.cfg (4)
15-30: LGTM on the zero reference position sanity checks.The logic correctly validates compatibility between
zero_reference_positionand fuzzy true-zero mode, with appropriate error messaging. The position matching check on line 25 uses rounded values which is appropriate for coordinate comparison.
48-55: LGTM on the new preflight check macro.Clean implementation that resets internal state variables and delegates beacon scan compensation check when beacon is configured.
178-190: LGTM on zero reference position mesh expansion logic.The logic correctly expands the mesh region to include the zero reference position when it falls outside the initial mesh bounds. This ensures
SET_ZERO_REFERENCE_POSITIONcan meaningfully set the reference.
74-78: Theis nonecheck on line 77 will never be triggered—variables are pre-converted to float on lines 47-48.Lines 47-48 convert
params.ACTUAL_TRUE_ZERO_POSITION_Xandparams.ACTUAL_TRUE_ZERO_POSITION_Yto float with a default of 0, meaningactual_true_zero_position_xandactual_true_zero_position_ycan never beNone. The conditional on line 77 checkingif actual_true_zero_position_x is nonewill always evaluate to False, making the fallback logic dead code. If the intent is to support optional parameters where no coordinate is provided, the initial conversion on lines 47-48 should useNoneas the default instead offloat(0), and then theis nonecheck would work correctly.Likely an incorrect or invalid review comment.
configuration/klippy/beacon_adaptive_heat_soak.py (5)
37-61: LGTM on multiprocessing pattern for threshold prediction.The implementation correctly uses a child process with daemon mode, reactor-friendly polling, proper pipe cleanup, and error propagation via the pipe. This avoids blocking the Klipper reactor during expensive GAM prediction.
88-96: Exception chaining is correct.Line 94 properly uses
from efor exception chaining, maintaining the traceback. This was addressed per past review comments.
224-260: LGTM on RunningAverage implementation.Clean circular buffer implementation with efficient O(1) add and get_average operations. The edge case of
size <= 0is properly guarded.
496-507: Verify/tmpusage is acceptable in this context.Static analysis flags
/tmp/heat_soak_{ts}.csvas potentially insecure (S108). In this context, the file is used for diagnostic logging of heat soak data, which is low-sensitivity operational data. The risk is minimal, but consider:
- The file is world-readable by default
- On multi-user systems, another user could potentially read or manipulate it
For a 3D printer environment (typically single-user Raspberry Pi), this is likely acceptable, but verify this aligns with the project's security posture.
619-632: Confirmed: usesis Trueidentity check correctly.Per past review comments, using
is Truerather than truthiness check is intentional here since these variables can be'N/A'(string),True, orFalse. Line 631 now correctly logslevel_2_moving_average_trend_checks_passed(the boolean result). This was fixed per commit 62b6f6f.configuration/z-probe/beacon.cfg (5)
19-26: LGTM on mesh configuration documentation.Clear comments explaining why
mesh_runs: 1andmesh_cluster_size: 0are recommended, helping users understand the rationale behind these defaults.
100-131: LGTM on adaptive heat soak configuration variables.The variables are well-documented with inline comments explaining their purpose and constraints. Per retrieved learnings, the
|default()pattern used when reading these variables elsewhere is correct Jinja2 behavior.
683-738: LGTM on IDEX-aware nozzle expansion offset logic.The logic correctly handles:
- Single mode: applies offset only for the active toolhead
- Copy/Mirror mode: applies offset only for the default toolhead
- Proper calculation of expansion coefficient based on temperature delta
- Debug logging for troubleshooting
The conditional at line 698
(toolhead == 1) == (idex_mode == "primary")correctly determines if toolhead 1 is active when carriage_1 is in primary mode.
1074-1093: LGTM on preflight beacon model check.The logic correctly identifies when a Beacon model is required but not present:
- For true zero calibration when
beacon_contact_calibrate_model_on_printis false- For homing when using proximity method without contact fallback
This provides early, clear error messaging rather than cryptic failures later in the print sequence.
1174-1206: LGTM on runtime offset management.The
_BEACON_SET_RUNTIME_OFFSETmacro correctly:
- Subtracts the applied expansion offset from current gcode offset
- Handles IDEX tool z offset by adding it back (since
_SET_TOOLHEAD_OFFSETapplies negative offset)- Documents the limitation that gcode file offsets cannot be distinguished from babystepping
This enables persistent babystep/z-offset adjustments across prints.
configuration/klippy/beacon_mesh.py (6)
744-754: LGTM on_gaussian_filterimplementation.The indentation issue flagged in past reviews has been fixed. The
returnstatement is now correctly at the module level outside theifblock. The lazy loading ofscipy.ndimageis appropriate.
1895-1918: Loop variablesecondary_idxcaptured in nested function.Static analysis hint B023 flags that
primary_idx_from_line_idxcapturessecondary_idxfrom the enclosing loop. While the function is only called within the same iteration where it's defined, this pattern can be confusing.However, since
primary_idx_from_line_idxis defined fresh each iteration and only used within that iteration, this is safe. No change required.
633-672: LGTM onapply_scan_compensationbed temp ordering.Per past review comment, the
measured_mesh_bed_tempis now correctly read after_validate_extended_parameterssucceeds (line 657), preventingKeyErrorwith legacy meshes. This was fixed per commit 7be6853.
1472-1525: LGTM onCotemporalProbingHelperinitialization.Clean initialization with proper handler registration, faulty region parsing from config, and clear documentation of why
beacon.get_offsets()is not used (due to its limited-circumstance design).
1792-1860: LGTM on offset-aligned probe sequence generation.The algorithm correctly:
- Validates beacon offsets and spacing constraints
- Determines primary/secondary axes based on offset magnitudes
- Calculates appropriate resolution as a divisor of the primary offset
- Handles both beacon-leading and beacon-trailing scenarios per scan direction
This enables cotemporal contact/proximity probing with minimal toolhead movement.
717-742: LGTM on multiprocessing pattern for local-low filter.Consistent with the pattern in
beacon_adaptive_heat_soak.py: daemon child process, reactor-friendly polling, proper pipe cleanup, error propagation. This prevents heavy numpy operations from blocking the Klipper reactor.
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
configuration/klippy/beacon_adaptive_heat_soak.py (1)
494-505: Avoid hard‑coded/home/pipaths in diagnostics (reuse config dir)The adaptive heat‑soak diagnostics still write to fixed paths under
/home/pi/printer_data/config/:
- Z‑rate capture:
fn = f"/tmp/heat_soak_{ts}.csv"(fine as a temp file) but_CAPTURE_Z_RATESwrites summary CSVs to/home/pi/printer_data/config/{filename}.- Beacon sample capture:
filename = f'/home/pi/printer_data/config/beacon_adaptive_heat_soak_beacon_samples_{timestamp}.txt'.This hard‑codes the user and layout (Pi + Moonraker defaults) and will break on other hosts or custom setups. It also reintroduces the issue previously discussed in an earlier review.
Consider deriving these paths from Klipper’s config directory instead:
- fullpath = f'/home/pi/printer_data/config/{filename}' + config_dir = self.printer.get_config_dir() + fullpath = os.path.join(config_dir, filename)and similarly for the beacon‑samples filename.
This keeps diagnostics portable without changing user‑visible behavior.
Also applies to: 646-652, 703-705
🧹 Nitpick comments (3)
configuration/moonraker.conf (1)
113-115: Klipper dev pinned_commit bump looks consistent, but verify compatibility with new features and printer profilesLine 115 updates the Klipper dev
pinned_committo93c8ad8a017c45f4502e73ad1dc174cf7d3c3b90, which matches the existing pattern of tracking specific dev snapshots and is reasonable given the new Beacon/fastconfig-related functionality in this PR. Please double‑check that:
- This commit contains all required Beacon/bed-mesh/RatOS APIs used elsewhere in the PR.
- You’ve smoke‑tested across the main supported printer configs, since a Klipper dev bump can have side effects on kinematics, config parsing, or modules beyond Beacon.
Optionally, consider noting in the PR description (or a brief comment near this section) why this particular commit was chosen (e.g., “first commit with fastconfig support for X/Y”), to simplify future upgrades and debugging.
configuration/klippy/beacon_mesh.py (1)
1895-1918: Consider refactoring inner function to avoid closure ambiguity.The inner function
primary_idx_from_line_idxdefined inside the loop references the loop variablesecondary_idx. While this works correctly in this case (since the function is only called within the same iteration), it's a code pattern that static analysis tools flag and could be clearer.Consider refactoring to make the dependency explicit, for example by passing
secondary_idxas a parameter:for secondary_idx in range(secondary_count): # Determine if the beacon is leading or trailing the nozzle beacon_leading = ( primary_offset > 0 ) == ( secondary_idx % 2 == 0 ) - def primary_idx_from_line_idx(primary_line_idx): - if secondary_idx % 2 == 0: + def primary_idx_from_line_idx(primary_line_idx, sec_idx): + if sec_idx % 2 == 0: return primary_line_idx else: return primary_count - primary_line_idx - 1 # Add any initial probe actions for the first (offset_divisor - 1) points for primary_line_idx in range(offset_divisor - 1): - append_probe_action(not beacon_leading, primary_idx_from_line_idx(primary_line_idx), secondary_idx) + append_probe_action(not beacon_leading, primary_idx_from_line_idx(primary_line_idx, secondary_idx), secondary_idx)configuration/klippy/beacon_true_zero_correction.py (1)
141-207: Tighten diagnostics path: avoid hard‑coded/home/piand unnecessary f‑stringThe diagnostics capture in
cmd_BEACON_TRUE_ZERO_CORRECTION_DIAGNOSTICSworks, but two small issues are worth addressing:
- The CSV path is hard‑coded to
/home/pi/printer_data/config/..., which will break on non‑Pi or differently laid‑out installs. Prefer deriving from Klipper’s config dir, e.g.:- filename = f'/home/pi/printer_data/config/mpp_capture_{timestamp}.csv' + config_dir = self.printer.get_config_dir() + filename = os.path.join(config_dir, f'mpp_capture_{timestamp}.csv')
- The
elsebranch raisesself.gcode.error(f"Unknown action."), which is an f‑string with no interpolation. Dropping thefprefix avoids the Ruff F541 warning:- else: - raise self.gcode.error(f"Unknown action.") + else: + raise self.gcode.error("Unknown action.")Both changes are low‑risk and improve portability and style.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
configuration/klippy/beacon_adaptive_heat_soak_model_training.csvis excluded by!**/*.csv
📒 Files selected for processing (43)
configuration/homing.cfg(8 hunks)configuration/klippy/beacon_adaptive_heat_soak.py(1 hunks)configuration/klippy/beacon_mesh.py(3 hunks)configuration/klippy/beacon_true_zero_correction.py(1 hunks)configuration/klippy/fastconfig.py(1 hunks)configuration/klippy/ratos.py(10 hunks)configuration/klippy/ratos_z_offset.py(1 hunks)configuration/macros.cfg(20 hunks)configuration/macros/idex/idex_is.cfg(2 hunks)configuration/macros/idex/toolheads.cfg(6 hunks)configuration/macros/idex/util.cfg(2 hunks)configuration/macros/idex/vaoc.cfg(5 hunks)configuration/macros/mesh.cfg(9 hunks)configuration/macros/overrides.cfg(8 hunks)configuration/macros/parking.cfg(1 hunks)configuration/macros/priming.cfg(7 hunks)configuration/macros/util.cfg(3 hunks)configuration/moonraker.conf(1 hunks)configuration/printers/base.cfg(1 hunks)configuration/printers/v-core-3-hybrid/macros.cfg(1 hunks)configuration/printers/v-core-3-idex/macros.cfg(2 hunks)configuration/printers/v-core-3/macros.cfg(1 hunks)configuration/printers/v-core-4-hybrid/300.cfg(0 hunks)configuration/printers/v-core-4-hybrid/400.cfg(0 hunks)configuration/printers/v-core-4-hybrid/500.cfg(0 hunks)configuration/printers/v-core-4-hybrid/macros.cfg(2 hunks)configuration/printers/v-core-4-hybrid/v-core-4-hybrid.cfg(1 hunks)configuration/printers/v-core-4-idex/300.cfg(0 hunks)configuration/printers/v-core-4-idex/400.cfg(0 hunks)configuration/printers/v-core-4-idex/500.cfg(0 hunks)configuration/printers/v-core-4-idex/macros.cfg(2 hunks)configuration/printers/v-core-4-idex/v-core-4-idex.cfg(1 hunks)configuration/printers/v-core-4/300.cfg(0 hunks)configuration/printers/v-core-4/400.cfg(0 hunks)configuration/printers/v-core-4/500.cfg(0 hunks)configuration/printers/v-core-4/macros.cfg(1 hunks)configuration/printers/v-core-4/v-core-4.cfg(1 hunks)configuration/printers/v-core-pro/macros.cfg(1 hunks)configuration/scripts/ratos-common.sh(1 hunks)configuration/scripts/ratos-install.sh(1 hunks)configuration/z-probe/beacon.cfg(18 hunks)configuration/z-probe/stowable-probe.cfg(0 hunks)src/server/gcode-processor/Actions.ts(1 hunks)
💤 Files with no reviewable changes (10)
- configuration/printers/v-core-4-idex/400.cfg
- configuration/printers/v-core-4-hybrid/400.cfg
- configuration/printers/v-core-4-idex/300.cfg
- configuration/printers/v-core-4-idex/500.cfg
- configuration/printers/v-core-4/400.cfg
- configuration/printers/v-core-4-hybrid/300.cfg
- configuration/printers/v-core-4/300.cfg
- configuration/printers/v-core-4/500.cfg
- configuration/printers/v-core-4-hybrid/500.cfg
- configuration/z-probe/stowable-probe.cfg
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: tg73
Repo: Rat-OS/RatOS-configurator PR: 101
File: configuration/z-probe/beacon.cfg:259-259
Timestamp: 2025-12-03T11:42:25.554Z
Learning: In beacon_true_zero_correction.py, the BEACON_AUTO_CALIBRATE command is wrapped to add multi-point probing functionality for improved true zero consistency. The wrapper adds a custom parameter SKIP_MULTIPOINT_PROBING (accepts 1, true, or yes) that allows bypassing the multi-point probing and using just the standard Beacon auto-calibration. This is a valid RatOS-specific parameter, not part of upstream Beacon.
Learnt from: miklschmidt
Repo: Rat-OS/RatOS-configurator PR: 101
File: configuration/printers/v-core-4/v-core-4.cfg:7-9
Timestamp: 2025-07-28T19:09:05.023Z
Learning: In Klipper configuration files, duplicate sections (like `[gcode_macro RatOS]`) do not cause errors. Instead, Klipper uses config section merging where later section parameters (chronologically) take precedence over earlier ones. This means multiple definitions of the same section are allowed and the last one processed will override parameters from earlier definitions.
📚 Learning: 2025-12-03T11:42:25.554Z
Learnt from: tg73
Repo: Rat-OS/RatOS-configurator PR: 101
File: configuration/z-probe/beacon.cfg:259-259
Timestamp: 2025-12-03T11:42:25.554Z
Learning: In beacon_true_zero_correction.py, the BEACON_AUTO_CALIBRATE command is wrapped to add multi-point probing functionality for improved true zero consistency. The wrapper adds a custom parameter SKIP_MULTIPOINT_PROBING (accepts 1, true, or yes) that allows bypassing the multi-point probing and using just the standard Beacon auto-calibration. This is a valid RatOS-specific parameter, not part of upstream Beacon.
Applied to files:
configuration/printers/v-core-4/macros.cfgconfiguration/printers/v-core-4-idex/macros.cfgconfiguration/printers/v-core-4-hybrid/macros.cfgconfiguration/macros/priming.cfgconfiguration/printers/v-core-3/macros.cfgconfiguration/printers/v-core-4/v-core-4.cfgconfiguration/printers/v-core-4-hybrid/v-core-4-hybrid.cfgconfiguration/printers/v-core-pro/macros.cfgconfiguration/printers/v-core-4-idex/v-core-4-idex.cfgconfiguration/printers/v-core-3-idex/macros.cfgconfiguration/macros/mesh.cfgconfiguration/homing.cfgconfiguration/macros/overrides.cfgconfiguration/klippy/beacon_true_zero_correction.pyconfiguration/macros/idex/vaoc.cfgconfiguration/klippy/beacon_adaptive_heat_soak.pyconfiguration/macros.cfgconfiguration/klippy/ratos.pyconfiguration/klippy/beacon_mesh.pyconfiguration/z-probe/beacon.cfg
📚 Learning: 2025-06-16T16:44:30.280Z
Learnt from: LucidityCrash
Repo: Rat-OS/RatOS-configurator PR: 89
File: src/templates/v-core-pro.ts:18-20
Timestamp: 2025-06-16T16:44:30.280Z
Learning: In the RatOS configurator project, v-core-pro configuration files are stored in `configuration/printers/v-core-pro/` in the source repository, but are accessed via `RatOS/printers/v-core-pro/` paths in the deployed/installed environment. The include statements in templates should use the runtime paths, not the source repository paths.
Applied to files:
configuration/printers/v-core-4/v-core-4.cfgconfiguration/printers/v-core-4-hybrid/v-core-4-hybrid.cfgconfiguration/printers/v-core-4-idex/v-core-4-idex.cfg
📚 Learning: 2025-07-28T19:09:05.023Z
Learnt from: miklschmidt
Repo: Rat-OS/RatOS-configurator PR: 101
File: configuration/printers/v-core-4/v-core-4.cfg:7-9
Timestamp: 2025-07-28T19:09:05.023Z
Learning: In Klipper configuration files, duplicate sections (like `[gcode_macro RatOS]`) do not cause errors. Instead, Klipper uses config section merging where later section parameters (chronologically) take precedence over earlier ones. This means multiple definitions of the same section are allowed and the last one processed will override parameters from earlier definitions.
Applied to files:
configuration/printers/v-core-4/v-core-4.cfgconfiguration/printers/v-core-4-hybrid/v-core-4-hybrid.cfgconfiguration/printers/v-core-4-idex/v-core-4-idex.cfgconfiguration/macros/util.cfgconfiguration/klippy/ratos_z_offset.pyconfiguration/macros/idex/util.cfgconfiguration/macros/overrides.cfgconfiguration/z-probe/beacon.cfg
📚 Learning: 2025-12-03T11:42:25.554Z
Learnt from: tg73
Repo: Rat-OS/RatOS-configurator PR: 101
File: configuration/z-probe/beacon.cfg:259-259
Timestamp: 2025-12-03T11:42:25.554Z
Learning: In the RatOS codebase, standard Klipper and Beacon G-code commands are often wrapped by custom Python code to add extended functionality. The wrapping pattern involves: (1) calling `self.gcode.register_command(COMMAND_NAME, None)` to retrieve the original command handler and store it (e.g., `self.orig_cmd`), then (2) calling `self.gcode.register_command(COMMAND_NAME, self.custom_handler)` to install the wrapper. The wrapper can add custom parameters and logic, then delegate to the original command when needed.
Applied to files:
configuration/klippy/ratos.pyconfiguration/z-probe/beacon.cfg
📚 Learning: 2025-12-02T18:27:19.189Z
Learnt from: tg73
Repo: Rat-OS/RatOS-configurator PR: 101
File: configuration/z-probe/beacon.cfg:100-131
Timestamp: 2025-12-02T18:27:19.189Z
Learning: In Klipper configuration macros using Jinja2 templates, the `|default(value)` filter provides a fallback value when a variable is undefined or missing. For example, `printer["gcode_macro RatOS"].some_variable|default(0)` will return `0` if `variable_some_variable` is not declared in the `[gcode_macro RatOS]` section. This is a standard pattern for optional or backward-compatible settings and does not cause errors.
Applied to files:
configuration/z-probe/beacon.cfg
🧬 Code graph analysis (6)
src/server/gcode-processor/Actions.ts (2)
src/server/gcode-processor/State.ts (2)
gcodeInfo(79-84)gcodeInfo(86-88)src/server/gcode-processor/errors.ts (1)
SlicerNotSupported(36-36)
configuration/klippy/ratos_z_offset.py (1)
configuration/klippy/fastconfig.py (3)
items(76-77)get(67-68)values(73-74)
configuration/klippy/beacon_true_zero_correction.py (2)
configuration/klippy/ratos_z_offset.py (1)
set_offset(74-78)configuration/klippy/ratos.py (2)
get_beacon_probing_regions(607-628)console_echo(546-572)
configuration/klippy/beacon_adaptive_heat_soak.py (1)
configuration/klippy/ratos.py (6)
BackgroundDisplayStatusProgressHandler(803-870)set_auto_rate(847-853)enable(823-828)progress(840-841)progress(844-845)disable(830-837)
configuration/klippy/ratos.py (1)
configuration/klippy/beacon_mesh.py (1)
get_profiles(323-336)
configuration/klippy/beacon_mesh.py (1)
configuration/klippy/ratos.py (6)
BackgroundDisplayStatusProgressHandler(803-870)get_beacon_probing_regions(607-628)enable(823-828)disable(830-837)progress(840-841)progress(844-845)
🪛 Ruff (0.14.7)
configuration/klippy/ratos_z_offset.py
83-83: Avoid specifying long messages outside the exception class
(TRY003)
113-113: Unused method argument: eventtime
(ARG002)
configuration/klippy/fastconfig.py
37-37: Unused method argument: eventtime
(ARG002)
39-39: Avoid specifying long messages outside the exception class
(TRY003)
configuration/klippy/beacon_true_zero_correction.py
87-87: Avoid specifying long messages outside the exception class
(TRY003)
99-99: Unused method argument: rails
(ARG002)
105-105: Unused method argument: print_time
(ARG002)
207-207: Avoid specifying long messages outside the exception class
(TRY003)
207-207: f-string without any placeholders
Remove extraneous f prefix
(F541)
236-238: Avoid specifying long messages outside the exception class
(TRY003)
297-297: Avoid specifying long messages outside the exception class
(TRY003)
310-310: Avoid specifying long messages outside the exception class
(TRY003)
346-346: Create your own exception
(TRY002)
346-346: Avoid specifying long messages outside the exception class
(TRY003)
390-390: Avoid specifying long messages outside the exception class
(TRY003)
398-398: Avoid specifying long messages outside the exception class
(TRY003)
403-403: Avoid specifying long messages outside the exception class
(TRY003)
configuration/klippy/beacon_adaptive_heat_soak.py
44-44: Do not catch blind exception: Exception
(BLE001)
70-70: Avoid specifying long messages outside the exception class
(TRY003)
89-89: Avoid specifying long messages outside the exception class
(TRY003)
94-94: Create your own exception
(TRY002)
94-94: Avoid specifying long messages outside the exception class
(TRY003)
179-179: Avoid specifying long messages outside the exception class
(TRY003)
184-184: Avoid specifying long messages outside the exception class
(TRY003)
232-232: Avoid specifying long messages outside the exception class
(TRY003)
363-363: Avoid specifying long messages outside the exception class
(TRY003)
369-369: Avoid specifying long messages outside the exception class
(TRY003)
406-406: Avoid specifying long messages outside the exception class
(TRY003)
412-412: Avoid specifying long messages outside the exception class
(TRY003)
421-421: Avoid specifying long messages outside the exception class
(TRY003)
424-424: Avoid specifying long messages outside the exception class
(TRY003)
495-495: Probable insecure usage of temporary file or directory: "/tmp/heat_soak_"
(S108)
522-522: Avoid specifying long messages outside the exception class
(TRY003)
639-639: Avoid specifying long messages outside the exception class
(TRY003)
642-642: Avoid specifying long messages outside the exception class
(TRY003)
667-667: Avoid specifying long messages outside the exception class
(TRY003)
693-693: Avoid specifying long messages outside the exception class
(TRY003)
696-696: Avoid specifying long messages outside the exception class
(TRY003)
711-711: Avoid specifying long messages outside the exception class
(TRY003)
718-718: Function definition does not bind loop variable samples
(B023)
configuration/klippy/ratos.py
249-249: Avoid specifying long messages outside the exception class
(TRY003)
269-269: Do not catch blind exception: Exception
(BLE001)
270-270: Use explicit conversion flag
Replace with conversion flag
(RUF010)
276-276: Do not catch blind exception: Exception
(BLE001)
277-277: Use explicit conversion flag
Replace with conversion flag
(RUF010)
285-285: Avoid specifying long messages outside the exception class
(TRY003)
516-516: Consider moving this statement to an else block
(TRY300)
661-661: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
663-663: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
696-696: Unused method argument: eventtime
(ARG002)
713-713: Unused method argument: gcmd
(ARG002)
configuration/klippy/beacon_mesh.py
205-205: Unused method argument: gcmd
(ARG002)
237-237: Avoid specifying long messages outside the exception class
(TRY003)
299-299: Avoid specifying long messages outside the exception class
(TRY003)
321-321: Avoid specifying long messages outside the exception class
(TRY003)
354-354: Avoid specifying long messages outside the exception class
(TRY003)
388-388: Avoid specifying long messages outside the exception class
(TRY003)
420-420: Avoid specifying long messages outside the exception class
(TRY003)
423-423: Avoid specifying long messages outside the exception class
(TRY003)
446-446: Avoid specifying long messages outside the exception class
(TRY003)
453-453: Avoid specifying long messages outside the exception class
(TRY003)
460-460: Avoid specifying long messages outside the exception class
(TRY003)
463-463: Avoid specifying long messages outside the exception class
(TRY003)
499-499: Avoid specifying long messages outside the exception class
(TRY003)
531-531: Avoid specifying long messages outside the exception class
(TRY003)
541-541: Avoid specifying long messages outside the exception class
(TRY003)
546-546: Consider moving this statement to an else block
(TRY300)
548-548: Avoid specifying long messages outside the exception class
(TRY003)
548-548: Use explicit conversion flag
Replace with conversion flag
(RUF010)
562-562: Avoid specifying long messages outside the exception class
(TRY003)
635-635: Avoid specifying long messages outside the exception class
(TRY003)
711-711: Consider moving this statement to an else block
(TRY300)
725-725: Do not catch blind exception: Exception
(BLE001)
749-752: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
749-752: Create your own exception
(TRY002)
749-752: Avoid specifying long messages outside the exception class
(TRY003)
1027-1027: Avoid specifying long messages outside the exception class
(TRY003)
1027-1027: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1041-1043: try-except-continue detected, consider logging the exception
(S112)
1041-1041: Do not catch blind exception: Exception
(BLE001)
1058-1058: Abstract raise to an inner function
(TRY301)
1058-1058: Avoid specifying long messages outside the exception class
(TRY003)
1064-1064: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1101-1101: Avoid specifying long messages outside the exception class
(TRY003)
1103-1103: Avoid specifying long messages outside the exception class
(TRY003)
1162-1162: Do not catch blind exception: Exception
(BLE001)
1192-1192: Avoid specifying long messages outside the exception class
(TRY003)
1206-1206: Do not catch blind exception: Exception
(BLE001)
1261-1261: Avoid specifying long messages outside the exception class
(TRY003)
1301-1301: Avoid specifying long messages outside the exception class
(TRY003)
1301-1301: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1330-1330: Avoid specifying long messages outside the exception class
(TRY003)
1360-1360: Do not catch blind exception: Exception
(BLE001)
1388-1391: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
1388-1391: Create your own exception
(TRY002)
1388-1391: Avoid specifying long messages outside the exception class
(TRY003)
1394-1397: Create your own exception
(TRY002)
1394-1397: Avoid specifying long messages outside the exception class
(TRY003)
1547-1547: Avoid specifying long messages outside the exception class
(TRY003)
1564-1564: Avoid specifying long messages outside the exception class
(TRY003)
1573-1573: Avoid specifying long messages outside the exception class
(TRY003)
1601-1601: Avoid specifying long messages outside the exception class
(TRY003)
1621-1621: Avoid specifying long messages outside the exception class
(TRY003)
1644-1644: Avoid specifying long messages outside the exception class
(TRY003)
1661-1661: Avoid specifying long messages outside the exception class
(TRY003)
1689-1689: Avoid specifying long messages outside the exception class
(TRY003)
1723-1723: Avoid specifying long messages outside the exception class
(TRY003)
1732-1732: Avoid specifying long messages outside the exception class
(TRY003)
1773-1773: Avoid specifying long messages outside the exception class
(TRY003)
1813-1814: Avoid specifying long messages outside the exception class
(TRY003)
1823-1823: Avoid specifying long messages outside the exception class
(TRY003)
1835-1837: Avoid specifying long messages outside the exception class
(TRY003)
1841-1843: Avoid specifying long messages outside the exception class
(TRY003)
1900-1900: Function definition does not bind loop variable secondary_idx
(B023)
🔇 Additional comments (73)
configuration/printers/v-core-3/macros.cfg (1)
20-20: Verify fastconfig accessibility and equivalent behavior before merge.The change from
printer.configfile.settings.beacontoprinter.fastconfig.settings.beaconrequires confirmation that:
fastconfigis initialized and available when this macro executesfastconfig.settings.beaconprovides the same interface and data asconfigfile.settings.beacon- This migration pattern is consistently applied across related configuration files
configuration/printers/v-core-4-hybrid/v-core-4-hybrid.cfg (2)
10-12: LGTM! Spelling corrected as requested.The printer-specific
[bed_mesh]override withsplit_delta_z: 0.001is correctly configured, and the comment spelling has been fixed from "arfetacts" to "artifacts" as previously requested.
7-9: The printer-specific override of[gcode_macro RatOS]withvariable_beacon_adaptive_heat_soak: Truefollows the correct RatOS pattern. Klipper's config section merging ensures this parameter will override any base definition. This change aligns with the Beacon/first layer improvements objective and follows the documented RatOS override pattern.configuration/printers/v-core-pro/macros.cfg (1)
16-20: Fastconfig-based Beacon check looks correct; confirm fastconfig is always presentSwitching the Beacon presence check to
printer.fastconfig.settings.beaconaligns this macro with the new fastconfig wrapper while preserving the original conditional behavior aroundbeacon_contact_z_tilt_adjust. No logic changes or regressions are apparent here.Please just confirm that
printer.fastconfigis guaranteed to exist for all v-core-pro configurations using this macro (so this file can’t be loaded in an environment without fastconfig); if there’s any chance of mixed environments, you may want a defensive fallback or a clear migration path.configuration/printers/v-core-3-idex/macros.cfg (2)
13-16: Startup delay bump for_IDEX_INITlooks safeIncreasing
initial_durationto 0.2s should only make the IDEX init more robust against startup timing/race issues and doesn’t change logic. No issues from this change.
30-52: Beacon condition viaprinter.fastconfig.settings.beaconlooks correct; confirm config invariantGating the contact-based Z_TILT (
PROBE_METHOD=contact) behind:{% if printer.fastconfig.settings.beacon is defined and beacon_contact_z_tilt_adjust %}is a sensible way to:
- Avoid running beacon-specific logic when no beacon is present.
- Keep the behavior opt‑in via
beacon_contact_z_tilt_adjust.One thing to double‑check: if
fastconfig.settings.beaconcan exist but be explicitly setfalseon some setups, you might want to additionally check its truthiness:{% if printer.fastconfig.settings.beacon is defined and printer.fastconfig.settings.beacon and beacon_contact_z_tilt_adjust %}If, by convention, the key is only defined when a beacon is installed, the current condition is fine.
src/server/gcode-processor/Actions.ts (1)
99-102: PrusaSlicer version extension looks consistent and safeThe expanded semver constraint cleanly adds 2.9.1 and 2.9.2, and the error message correctly reflects the supported set; no behavioural issues spotted here.
configuration/printers/v-core-4-hybrid/macros.cfg (2)
6-6: LGTM: Startup timing adjustment.The increase in
initial_durationfrom 0.1 to 0.2 seconds aligns with similar changes across other printer configurations, likely ensuring proper initialization ordering with the new fastconfig system.
22-22: LGTM: Fastconfig migration.The migration from
printer.configfile.settingstoprinter.fastconfig.settingsis correct and improves performance by avoiding costly deep copies during config access.configuration/klippy/fastconfig.py (3)
20-36: LGTM: Well-designed immutable snapshot pattern.The one-time deep copy at
klippy:connectcreates an immutable snapshot of the configuration, trading a single upfront cost for eliminating repeated expensive deep copies during macro execution. Removing thesave_config_pendingfields from the snapshot is appropriate since this wrapper is read-only.
37-40: LGTM: Proper initialization guard.The
get_statusmethod correctly enforces that the wrapper can only be queried after initialization. Theeventtimeparameter follows Klipper's standard status interface convention.
42-77: LGTM: Singleton-like copy semantics and complete Mapping interface.The copy prevention methods (
__copy__and__deepcopy__returningself) are essential to the performance optimization, ensuring that accessing this object never triggers expensive deep copies. The Mapping interface implementation is complete and correctly delegates to the immutable snapshot.configuration/printers/v-core-4-idex/macros.cfg (1)
15-15: LGTM: Consistent with PR-wide patterns.Both changes align with the broader PR updates:
- The
initial_durationincrease ensures proper initialization ordering- The fastconfig migration improves performance by avoiding repeated deep copies
Also applies to: 42-42
configuration/macros/idex/util.cfg (1)
14-17: LGTM: Fastconfig migration for IDEX utilities.The migration of stepper position and endstop settings from
printer.configfile.settingstoprinter.fastconfig.settingsis correct and consistent with the PR-wide performance improvements.Also applies to: 40-41
configuration/klippy/ratos.py (9)
9-23: LGTM: Well-designed beacon probing regions structure.The
BeaconProbingRegionsnamedtuple provides a clean, typed interface for beacon probe configuration with clear field names and comprehensive documentation.
49-63: LGTM: Clear component and status field organization.The new fields are well-organized with clear comments distinguishing initialization-time components from runtime status fields. These support the expanded RatOS functionality for beacon probing and bed mesh operations.
238-278: LGTM: Useful G-code control flow commands.Both commands provide valuable functionality:
_RAISE_ERRORavoids unhelpful macro name prefixing_TRYimplements proper try/except/finally semantics in G-codeThe broad exception catches in
_TRYare intentional to implement the exception handling pattern correctly.
279-289: LGTM: Clean bed mesh profile validation.The command correctly checks for profile existence and updates the status field for macro access. The error handling appropriately validates that a profile name was provided.
607-649: LGTM: Robust safe home position calculation with beacon region validation.The safe home position calculation correctly:
- Falls back to middle of printable area when not specified
- Validates against beacon probing regions when beacon is configured
- Triggers a shutdown with a clear error message if the safe home position is outside the beacon-probable region, preventing runtime failures
651-694: LGTM: Well-implemented fuzzy home positioning.The fuzzy radius implementation correctly:
- Uses
sqrt(random.random())for uniform distribution within the circle- Constrains the fuzzy position to beacon probing regions or printable area
- Logs warnings when constraints are applied
- Updates status with the actual position moved to
The use of standard pseudo-random is appropriate for position variance in probing (not cryptographic).
696-705: LGTM: Comprehensive status exposure.The updated status dictionary properly exposes all the new runtime state for macro access, including the safe home position calculation and last movement position.
711-801: LGTM: Sophisticated debugging infrastructure.The stack trace functionality provides valuable debugging capabilities for G-code macro execution:
- Crawl markers (
;$text) enable callsite identification- The callback pattern allows frame-specific formatting
- The implementation correctly uses Python's inspect module for stack introspection
803-870: LGTM: Clean progress display handler implementation.The
BackgroundDisplayStatusProgressHandlerprovides a polished user experience with:
- Animated spinner using Unicode Braille characters
- Auto-rate progress increment capability
- Proper timer lifecycle management
- Configurable update interval and message formatting
configuration/homing.cfg (4)
81-81: LGTM: Centralized safe home position calculation.The migration from individual safe_home_x/safe_home_y calculations to the centralized
printer.ratos.safe_home_positionensures consistency and enables beacon-aware validation logic in a single location.Also applies to: 124-124
155-156: LGTM: Flexible beacon calibration flow.The updated HOME_Z logic correctly implements two beacon calibration modes:
- When
beacon_contact_start_print_true_zerois enabled, it skips multi-point probing during homing and defers critical zero probing to start print after heat soaking- Otherwise, it performs full calibration during homing
The conditional logic is clear and the parameters are properly validated. Based on learnings,
SKIP_MULTIPOINT_PROBINGis a valid RatOS-specific parameter.Also applies to: 173-190
236-236: LGTM: Fastconfig migration for sensorless homing.The migration of stepper driver
run_currentlookups fromprinter.configfile.configtoprinter.fastconfig.configis correct and consistent with the PR-wide performance improvements. These values are correctly restored after sensorless homing operations.Also applies to: 240-240, 247-247, 251-251, 302-302, 306-306, 313-313, 317-317
329-330: LGTM: Centralized safe home movement implementation.The fastconfig migration for z_hop settings is correct. The macro rename to
__MOVE_TO_SAFE_Z_HOME_ECHO_DEBUGreflects that the actual movement logic has been centralized inratos.py(cmd_MOVE_TO_SAFE_Z_HOME), while this macro now serves as a debug logging helper called by the Python implementation.Also applies to: 334-336
configuration/klippy/ratos_z_offset.py (5)
7-33: LGTM: Clean Z-offset module initialization.The module correctly:
- Defines clear offset categories (toolhead, true_zero_correction, hotend_thermal_expansion)
- Integrates with Klipper's gcode_move transform chain at connect time
- Registers appropriate G-code commands
37-78: LGTM: Clean command implementation with proper validation.The offset management commands are well-designed:
GET_RATOS_Z_OFFSETprovides clear output including the combined offsetSET_RATOS_Z_OFFSETandCLEAR_RATOS_Z_OFFSETuse the shared_validate_and_set_offsethelper (addressing the past review concern)- The public
set_offsetmethod enables programmatic access for other extensions
80-87: LGTM: Proper validation with clean zero-offset handling.The validation correctly ensures only recognized offset names are used, and removing zero offsets from the dictionary keeps the status clean and efficient.
92-104: LGTM: Correct gcode_move transform implementation.The transform methods correctly implement Klipper's transform chain pattern:
get_positionremoves the offset so G-code sees the intended Z positionmoveapplies the offset to the actual movement, ensuring proper tool height
109-119: LGTM: Efficient status reporting.The status implementation correctly exposes all individual offsets plus the combined offset for macro access. The lazy initialization and caching on change is efficient.
configuration/scripts/ratos-install.sh (1)
4-4: Clarify the purpose and necessity of the libopenblas-base dependency.The
libopenblas-basepackage is being added alongsidepython3-numpy. While OpenBLAS is a linear algebra library that NumPy can use for performance optimization, the review comment speculates about its purpose (beacon mesh calculations) without confirming whether this dependency is actually required for the new changes or if it's optional. Confirm that this package is needed for the functionality being introduced, and if so, consider documenting the rationale in the commit message or code.configuration/printers/v-core-3-hybrid/macros.cfg (1)
5-9: LGTM: Timing adjustment for hybrid initialization.The increase in
initial_durationfrom 0.1 to 0.2 seconds provides additional initialization time for the hybrid CoreXY configuration, which aligns with the broader timing adjustments introduced across the PR for extended startup flows and beacon integration.configuration/macros/parking.cfg (1)
29-29: LGTM: Fastconfig migration for beacon detection.The migration from
printer.configfile.settings.beacontoprinter.fastconfig.settings.beaconis consistent with the PR-wide shift to the immutable fastconfig wrapper introduced in this PR. This change centralizes configuration access and aligns with the new configuration architecture.configuration/macros/idex/idex_is.cfg (2)
46-46: LGTM: Consistent fastconfig migration for resonance testing.The change from
printer.configfile.settings.resonance_tester.probe_pointstoprinter.fastconfig.settings.resonance_tester.probe_pointsaligns with the PR-wide configuration access refactoring. This ensures the IDEX input shaper macros use the centralized immutable configuration wrapper.
306-306: LGTM: Second fastconfig reference for belt tension measurement.Consistent with the fastconfig migration pattern applied throughout the PR, ensuring both shaper calibration and belt tension measurement macros use the same configuration access method.
configuration/printers/base.cfg (1)
45-48: LGTM: Base configuration additions for fastconfig and bed mesh.The addition of the
[bed_mesh]section withsplit_delta_z: 0.01helps reduce visible surface artifacts, and the empty[fastconfig]section establishes the load point for the new immutable configuration wrapper module. These are appropriate foundational settings for the base printer configuration.configuration/printers/v-core-4-idex/v-core-4-idex.cfg (1)
7-11: LGTM: V-Core 4 IDEX beacon and mesh configuration.The addition of
beacon_adaptive_heat_soak: Trueenables the new adaptive heat-soak functionality for this printer model, and the finersplit_delta_z: 0.001(compared to 0.01 in base.cfg) is appropriate for the higher precision expected from the V-Core 4 IDEX platform.configuration/printers/v-core-4/macros.cfg (1)
16-16: LGTM: Fastconfig migration in Z_TILT_ADJUST.The migration to
printer.fastconfig.settings.beaconin the Z_TILT_ADJUST macro is consistent with the PR-wide configuration access refactoring, ensuring beacon detection uses the centralized immutable configuration wrapper.configuration/scripts/ratos-common.sh (1)
194-197: LGTM: Extension registration for new modules.The four new extension entries correctly register the new Klipper modules introduced in this PR:
ratos_z_offset_extensionfor Z-offset managementbeacon_true_zero_correction_extensionfor enhanced beacon calibrationbeacon_adaptive_heatsoak_extensionfor adaptive heat soak functionalityfastconfigfor the immutable configuration wrapperEach entry follows the established pattern with correct realpath resolution.
configuration/printers/v-core-4/v-core-4.cfg (1)
7-11: Configuration additions for Beacon adaptive heat soak look good.The
variable_beacon_adaptive_heat_soak: Trueenables the new adaptive heat soak feature, andsplit_delta_z: 0.001is an appropriate value for reducing visible surface stripe artifacts in bed mesh probing. Based on learnings, Klipper's config section merging allows this duplicate[gcode_macro RatOS]section to override/extend parameters from earlier definitions inbase.cfg.configuration/macros/idex/vaoc.cfg (5)
117-117: Migration to fastconfig for safe_distance looks correct.The change from
printer.configfile.settingstoprinter.fastconfig.settingsis consistent with the broader PR migration pattern.
304-304: Consistent fastconfig usage.
633-633: Fastconfig-based beacon check is appropriate.This aligns with the migration pattern and correctly gates the temp offset calibration on beacon presence.
736-740: Conditional hotend heat soak implementation looks good.The new
hotend_heat_soak_timeknob provides flexibility for thermal expansion compensation. The conditional execution when> 0and conversion to milliseconds (* 1000) for G4 dwell is correct.
882-978: No action required.Klipper's config section merging is the intended behavior for handling duplicate macro definitions. Later definitions override earlier ones without error. If the macros are identical, the duplicate is redundant but harmless. To determine if removal is warranted, verify whether the duplicate definitions are truly identical or if there are intentional differences that should be consolidated into a single definition.
configuration/macros/priming.cfg (7)
32-45: Fastconfig migration for probe result saving is consistent.The migration from
printer.configfile.settingstoprinter.fastconfig.settingsfor beacon, bltouch, and probe detection maintains the same logic flow while using the new centralized config access.
105-122: Fastconfig usage for bed_mesh and probe offsets is correct.The changes properly migrate config access patterns for:
bed_mesh.horizontal_move_zbed_meshconfig object- Probe offset retrieval for bltouch, probe, and beacon
207-217: Beacon detection for probe method selection is properly migrated.
262-262: Nozzle diameter retrieval via fastconfig is correct.
354-356: Probe existence validation properly migrated.
379-381: Consistent with T0 probe validation above.
410-412: Beacon nozzle temp offset integration is correct.configuration/macros/idex/toolheads.cfg (8)
496-498: Fastconfig beacon check in T0 toolchange offset flow is correct.
563-565: Consistent fastconfig usage for T1 toolchange offset flow.
766-766: Timing adjustment coordinates with RATOS_INIT ordering.Increasing
initial_durationfrom 0.1 to 0.2 ensures_INIT_TOOLHEADSruns afterRATOS_INIT(which runs at 0.1s), aligning with the startup ordering comment added inutil.cfg.
779-785: Fastconfig-based safe_distance validation is properly migrated.
791-792: Capturing offset_before for debugging purposes is helpful.The
offset_beforevariable captures the homing origin state before applying offsets, enabling before/after comparison in debug logs.
811-821: Enhanced debug logging with precision formatting.The
.round(6)formatting provides consistent decimal precision in debug output.
825-827: Fastconfig beacon check for nozzle temp offset is consistent.
830-834: New debug logging macro for toolhead offset tracking.The
_SET_TOOLHEAD_OFFSET_LOG_DEBUGmacro provides a clean way to log offset changes with before/after state comparison. Note that this macro readsprinter.gcode_move.homing_originat execution time, sooffset_afterwill reflect the state when the macro runs (after the offset is applied), whileoffset_beforewas captured before theSET_GCODE_OFFSETcommands.configuration/macros/util.cfg (4)
48-61: Startup ordering documentation and fastconfig migration are well-implemented.The comment block clearly documents the initialization order requirement (RATOS_INIT at 0.1s must run first, others at ≥0.2s). The simplified beacon check using
printer.fastconfig.settings.beaconremoves the previous dual condition checking both beacon and zero_reference_position.
255-258: Fastconfig migration for hybrid corexy check is correct.
383-383: Fastconfig usage for skew profile lookup is correct.
397-400: Verify_RAISE_ERRORmacro exists.The
_STOP_AND_RAISE_ERRORmacro calls_RAISE_ERROR, but this macro definition could not be located in the configuration files. If_RAISE_ERRORhas been removed or is not defined, invoking_STOP_AND_RAISE_ERRORwill result in a runtime error.configuration/macros/overrides.cfg (2)
95-107: Beacon nozzle thermal-offset integration in M104/M109/SET_HEATER_TEMPERATURE looks solidThe new Beacon hooks correctly:
- Gate on
printer.fastconfig.settings.beacon is definedandis_printing_gcode, so they don’t affect non‑Beacon or out‑of‑print calls.- Respect IDEX copy/mirror by applying offsets to both toolheads and using the existing RatOS
T*temperature_offset variables.- Reuse the same toolhead index (
t) resolution inSET_HEATER_TEMPERATUREso the behavior matches M104/M109.This wiring looks coherent with the rest of the RatOS/Beacon integration; I don’t see functional issues here.
Also applies to: 146-153, 166-191
203-248: Temperature wait offsets and bed‑mesh wrapper behavior align with Beacon/fastconfig flow
TEMPERATURE_WAITnow:
- Maps
SENSOR=extruder|extruder1to a toolhead index, applies that toolhead’s temperature_offset to MINIMUM/MAXIMUM, and logs against a computedid(“sensor …” vs “toolhead Tn”).- Falls through to
TEMPERATURE_WAIT_BASE SENSOR="{sensor}"when neither bound is provided, preserving Klipper’s native error behavior while adding explicit debug/echo messages.
SKEW_PROFILE’s switch toprinter.fastconfig.settings["skew_correction %s" % params.LOAD]is consistent with the rest of the fastconfig migration and still guards on the key being defined.The new
BED_MESH_CALIBRATEwrapper cleanly:
- Runs Z‑tilt / quad‑gantry leveling first (with rehome of Z where needed),
- Handles stowable probes via DEPLOY/STOW,
- Adds Beacon‑specific model checks and applies RatOS bed mesh parameters only when Beacon is configured.
Overall these changes are coherent and preserve sensible behavior for non‑Beacon setups.
Also applies to: 259-269, 319-354
configuration/macros/mesh.cfg (1)
15-47: Zero‑reference and Beacon sanity checks are well‑designedThe additions around
_BED_MESH_SANITY_CHECKand_START_PRINT_BED_MESHlook robust:
- Validating
bed_mesh.zero_reference_positionagainstprinter.ratos.safe_home_positionand fuzzy true‑zero mode ensures misconfigurations are caught early with clear console errors.- The flow “explicit zero_reference_position from fastconfig, else fall back to last true‑zero position or safe_home” is sensible and keeps behavior deterministic across prints.
- Beacon warning messages for contact bed mesh, automatic scan, and contact Z‑tilt adjust are explicit and actionable.
- Preflight
_START_PRINT_PREFLIGHT_CHECK_AND_RESET_BED_MESHcorrectly resets the internal fuzzy true‑zero coordinates and delegates Beacon scan‑comp validation to the dedicated macro.I don’t see functional issues here; this is a nice tightening of mesh/beacon interactions.
Also applies to: 48-55, 72-79, 98-123
configuration/macros.cfg (2)
320-333: START_PRINT preflight and adaptive heat‑soak wiring is coherentThe updated
START_PRINTflow ties together Beacon and bed‑mesh nicely:
Preflight:
_START_PRINT_PREFLIGHT_CHECK_BEACON_MODELis only called whenprinter.fastconfig.settings.beaconis defined and gives an early, clear failure if a model is required (for homing or true zero) but not present._START_PRINT_PREFLIGHT_CHECK_AND_RESET_BED_MESHcentralizes mesh state reset and Beacon scan‑comp profile validation before heating.Bed heating / heat soak:
- For Beacon +
beacon_adaptive_heat_soak, the sequence_MOVE_TO_SAFE_Z_HOME,G1 Z2.5, andBEACON_WAIT_FOR_PRINTER_HEAT_SOAK(with layer quality, first‑layer duration, min/max wait) matches the new adaptive heat‑soak API.- The legacy
bed_heat_soak_timebranch remains intact as a fallback when adaptive heat soak is disabled or Beacon is absent.The conditional
PARK_TOOLHEADsuppression when Beacon true zero or adaptive heat soak is active avoids unnecessarily moving away from the bed while relying on Beacon measurements.This overall sequencing looks correct and matches the new Python heat‑soak module’s interface.
Also applies to: 359-365, 601-640, 624-639
879-889: Fuzzy true‑zero storage and runtime Z‑offset restoration are wired correctly
_START_PRINT_AFTER_HEATING_CONTACT_WITH_OPTIONAL_WIPE:
- Derives a fuzzy radius from
beacon_contact_start_print_true_zero_fuzzy_positionandbeacon_contact_start_print_true_zero_fuzzy_radius, passes it into_MOVE_TO_SAFE_Z_HOME, and then storesprinter.ratos.last_move_to_safe_z_home_positionvia_START_PRINT_AFTER_HEATING_CONTACT_WITH_OPTIONAL_WIPE_STORE_TRUE_ZERO_POSITION.- This feeds the
actual_true_zero_position_x/yvariables later consumed by_START_PRINT_BED_MESH(viazero_ref_posfallback), so the mesh’s zero reference follows the last true-zero contact point.The true‑zero calibration call correctly distinguishes:
- With
beacon_contact_calibrate_model_on_print:BEACON_AUTO_CALIBRATE(full model+true zero).- Without:
BEACON_AUTO_CALIBRATE SKIP_MODEL_CREATION=1(true zero only).At the end of
START_PRINT, the sequence:
_BEACON_SET_NOZZLE_TEMP_OFFSET RESET=True_BEACON_SET_NOZZLE_TEMP_OFFSET TOOLHEAD={initial_tool}_BEACON_RESTORE_RUNTIME_OFFSET(when contact true zero is enabled)ensures the model‑based contact expansion is reapplied cleanly and the user’s saved runtime Z offset is restored on top of the new true-zero baseline. END_PRINT’s
_BEACON_SUBTRACT_CONTACT_EXPANSION_OFFSET+_BEACON_SET_NOZZLE_TEMP_OFFSET RESET=Truethen correctly unwind that expansion component.This end‑to‑end flow appears internally consistent.
Also applies to: 982-987, 1040-1051, 1055-1060, 787-797, 1273-1284
configuration/z-probe/beacon.cfg (2)
19-27: Beacon calibration/adaptive‑heat‑soak configuration is coherentKey pieces line up well here:
[beacon] tweaks (
mesh_runsdocs andmesh_cluster_size: 0) are consistent with the new Beacon mesh helper’s behavior, avoiding aliasing from clustered sampling.The empty
[beacon_true_zero_correction]and[beacon_adaptive_heat_soak]sections (plus[ratos_z_offset]) correctly activate the corresponding Python extensions without forcing per‑printer overrides.New RatOS variables under
[gcode_macro RatOS]for:
beacon_contact_*(true-zero, wipe, bed mesh, z‑tilt adjust),- scan compensation (
beacon_scan_compensation_*),- adaptive heat soak (
beacon_adaptive_heat_soak_*),
are all consumed via|default(...), so older configs remain compatible.Calibration macros:
BEACON_INITIAL_CALIBRATIONandBEACON_FINAL_CALIBRATIONuseBEACON_AUTO_CALIBRATE SKIP_MULTIPOINT_PROBING=1for their internal contact calibration passes, which is appropriate for setup routines.BEACON_FINAL_CALIBRATIONnow optionally usesBEACON_WAIT_FOR_PRINTER_HEAT_SOAKwith its own min/max wait, quality, and first‑layer duration parameters, gated bybeacon_adaptive_heat_soak, so full Beacon calibration can reuse the same adaptive soak logic as START_PRINT.The
already_heatedflag that flows fromBEACON_RATOS_CALIBRATEintoBEACON_FINAL_CALIBRATIONensures you don’t redo chamber/bed heat soak when scan‑compensation calibration has already brought the machine to temperature.Overall this config side matches the new Python and macro flows cleanly.
Also applies to: 45-46, 55-75, 83-131, 170-215, 276-338
658-747: Nozzle expansion and runtime Z‑offset helpers look internally consistentThe new macros for Beacon contact expansion and runtime Z offset appear sound:
_BEACON_SET_NOZZLE_TEMP_OFFSET:
- Only applies expansion when both
beacon_contact_start_print_true_zeroandbeacon_contact_expansion_compensationare enabled.- Handles IDEX by:
- Applying offsets only when the target toolhead is actually “active/applicable” (default toolhead in copy/mirror; current active tool in single mode).
- Using per‑toolhead expansion coefficients from
save_variableswith a multiplier, and adjusting by the delta from the previously applied expansion (nozzle_expansion_applied_offset).- Uses
SET_GCODE_OFFSET Z_ADJUST=...plusSAVE_VARIABLEto keep the applied expansion offset tracked and reversible, with detailed debug logging via_BEACON_SET_NOZZLE_TEMP_OFFSET_LOG_DEBUG.
_BEACON_SUBTRACT_CONTACT_EXPANSION_OFFSETcorrectly subtracts the saved applied expansion offset at END_PRINT (single‑toolhead path), after which_BEACON_SET_NOZZLE_TEMP_OFFSET RESET=Trueclears the tracking variable.
_BEACON_SET_RUNTIME_OFFSETand_BEACON_RESTORE_RUNTIME_OFFSET:
- Capture
beacon_saved_runtime_offsetas the current gcode Z offset minus the applied expansion compensation (and minus the active IDEX Z‑offset where applicable), so what’s stored is effectively the user’s runtime/babystepped Z offset.- Later restore it via
SET_GCODE_OFFSET Z_ADJUST={runtime_offset}, which is appropriate because it’s applied onto the fresh true‑zero + expansion baseline at START_PRINT.- The
Z_OFFSET_APPLY_PROBEwrapper only switches to this RatOS path when Beacon contact true zero is enabled; otherwise, it falls back to the original Klipper behavior.These pieces fit together with the macros in
configuration/macros.cfgand the true‑zero Python module; I don’t see a correctness hole here, assuming the existingsave_variableskeys are present on IDEX setups.Please double‑check on a real IDEX machine that:
idex_applied_offset/idex_zoffsetare always present insave_variablesbefore_BEACON_SET_RUNTIME_OFFSETcan run, and- The restored runtime offset matches user expectations after a full START_PRINT/END_PRINT cycle with Beacon contact true zero enabled.
Also applies to: 1169-1205, 1207-1228
|
@coderabbitai get_config_dir() appears to be a hallucination, or at least it's not present in the version of klipper we use.
The correct way to get the configuration directory is: |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 569 🏁 Script executed: Length of output: 8972 @tg73 Thank you for the correction! You're absolutely right— Looking at the current code in timestamp = time.strftime("%Y%m%d_%H%M%S")
filename = f'/home/pi/printer_data/config/mpp_capture_{timestamp}.csv'This should be updated to use your suggested approach: config_file = self.printer.get_start_args()['config_file']
config_dir = os.path.dirname(config_file)
filename = os.path.join(config_dir, f'mpp_capture_{timestamp}.csv')I confirmed that ✏️ Learnings added
|
…gurator@topic/first-layer-improvements-pr - This merge was performed while development was taking place away from the main RatOS repos. - Merges upstream PR Rat-OS#101
Summary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.