Skip to content

Refactor basic filament button logic - #297

Merged
gmmcosta15 merged 5 commits into
devfrom
refactor/button-logic
Sep 24, 2026
Merged

gmmcosta15 merged 5 commits into
devfrom
refactor/button-logic

Conversation

@Robert0Mart

Copy link
Copy Markdown
Collaborator

Description

  • refactor

BlocksScreen/lib/panels/widgets/basicFilamentPanel.py

  • updated button logic (now using with filament map position)

@Robert0Mart
Robert0Mart requested a review from HugoCLSC August 5, 2026 08:51
@Robert0Mart
Robert0Mart marked this pull request as ready for review August 5, 2026 09:44
@Robert0Mart
Robert0Mart force-pushed the refactor/button-logic branch from 28090bb to 579b2af Compare August 5, 2026 10:26

@gmmcosta15 gmmcosta15 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's good

  • Moves off the filament string onto the typed filament_pos enum.
  • status != GateStatus.EMPTY has the right polarity: UNKNOWN stays permissive instead of locking the user out.
  • current_gate_info already bounds-checks the gate, so the None guard covers bypass/no selection.
  • Loading the real devices.amu in the widgets conftest instead of stubbing the enums is the right call, the comparisons need real IntEnum values.

1. basicFilamentPanel.py:260-266: FilamentPos.UNKNOWN now resolves to LOADED
UNKNOWN = -1, UNLOADED = 0, and the else branch takes everything that isn't exactly UNLOADED. The old string was tri-state and "Unknown" landed in UNLOADED. Now a freshly booted AMU, or one after MMU_MOTORS_OFF, shows Load disabled and Unload enabled. With no encoder, an eject from an unknown position is the one case worth blocking. FilamentStates.UNKNOWN already exists:

if mmu_state.filament_pos == FilamentPos.UNKNOWN:
    self.filament_state = self.FilamentStates.UNKNOWN
elif mmu_state.filament_pos == FilamentPos.UNLOADED:
    self.filament_state = self.FilamentStates.UNLOADED
else:
    self.filament_state = self.FilamentStates.LOADED

2. basicFilamentPanel.py:264: the empty-gate lockout is undone by the next update
setEnabled(status != GateStatus.EMPTY) runs outside the setter, and the setter writes filament_page_load_btn.setEnabled(True) on every UNLOADED transition. on_filament_sensor_update (:145) sets filament_state with no knowledge of the gate, so the next filament_detected=False re-enables Load on an empty gate. Let the setter apply it:

_loaded = update is self.FilamentStates.LOADED
self.filament_page_unload_btn.setEnabled(_loaded or update is self.FilamentStates.UNKNOWN)
self.filament_page_load_btn.setEnabled(not _loaded and self._gate_has_filament)

3. basicFilamentPanel.py:265: every intermediate position counts as fully loaded
HOMED_GATE through IN_EXTRUDER (1-9) are mid-move states. Treating them as LOADED makes Unload live while Happy Hare is still driving the gear, and an MMU_EJECT then collides with a move already in progress. Gate the buttons on the MMU being idle too:

_busy = bool(mmu_state.operation) or mmu_state.action not in ("", "Idle")
self.filament_page_unload_btn.setEnabled(not _busy and _loaded)

4. tests/widgets/conftest.py:16-24: the eviction list stops one level short
devices and devices.amu are popped but devices.amu.models, the module basicFilamentPanel imports, is not. tests/panels/conftest.py installs fakes with no teardown, so in a shared xdist worker FilamentPos/GateStatus come back as MagicMocks:

"devices", "devices.amu", "devices.amu.models",

Minor

    1. basicFilamentPanel.py:261-264: the gate lookup reads better as a property next to filament_state, and item 2 needs it (store mmu_state as self._mmu_state):
@property
def _gate_has_filament(self) -> bool:
    _gate = self._mmu_state.current_gate_info if self._mmu_state else None
    return _gate is None or _gate.status != GateStatus.EMPTY
    1. tests/widgets/conftest.py:26-39: three near-identical module shims, a loop keeps the next one from being a fourth:
for _name, _parts in (("lib", ("lib",)), ("devices", ("devices",)), ("devices.amu", ("devices", "amu"))):
    _m = types.ModuleType(_name)
    _m.__path__ = [str(_project_root.joinpath("BlocksScreen", *_parts))]
    _m.__package__ = _name
    sys.modules[_name] = _m

@gmmcosta15
gmmcosta15 merged commit 0c97cb7 into dev Sep 24, 2026
8 checks passed
@gmmcosta15
gmmcosta15 deleted the refactor/button-logic branch September 24, 2026 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants