Skip to content

Feature/BCON lite - Beam Control without deflection#88

Merged
bwalkerMIR merged 135 commits intodevelopfrom
feature/BCON-lite
Apr 30, 2026
Merged

Feature/BCON lite - Beam Control without deflection#88
bwalkerMIR merged 135 commits intodevelopfrom
feature/BCON-lite

Conversation

@sbasu107
Copy link
Copy Markdown
Contributor

@sbasu107 sbasu107 commented Mar 7, 2026

PR Review Checklist

  • Check merging to correct branch
  • Confirm latest develop branch has been merged into PR
  • Confirm any merge conflicts are resolved
  • Confirm you have written (using AI) code logic and hardware tests and drafted clear test results so less human final review needed. Your PR should say where the test document is with results so final review can examine.
  • Run new branch code and confirm works when attached to real hardware, document results in a test document for the final reviewer
  • In VSCode with Codex/Claude extension make sure you are not committing white space changes:
    • Make sure this branch doesn't have white space, EOL, etc. so that the diff only shows true logic changes and not lines that otherwise look identical apart from white space or hidden characters. Preserve existing line endings and formatting in this file. Do not change LF/CRLF line endings.
  • In VSCode with Codex/Claude extension review your own branch with multiple prompts similar to:
    • "I want your assessment if this code is good to go. Tell me if the code is ready to merge into the develop branch. Is there anything critical that needs to change before merging? Will it break develop in any way? What do the changes in the new code do and are they good changes? Point out any critical errors, in particular logic errors or anything that might break the dashboard. Make sure you do a diff of this branch relative to develop."
  • Run @codex review from PR
  • Look through questions asked in the conversation and resolve any code questions (highlighting from files changed as needed) or comment why you're not addressing a question
  • Review Checks to confirm CI tests pass
  • Review entire "Files Changed" manually aided by AI:
    • Confirm that .gitignore files were not committed
    • Confirm that no unnecessary development comments were committed
    • Confirm only changes within the scope of this PR were committed
    • Confirm no non-functional unnecessary changes were committed (e.g. needlessly adding extra space or something like that that just pollutes the PR review)
    • Confirm new functional code makes sense
    • Confirm hardware test
  • Let the final reviewer know ready for final review

GitHub Copilot Generated Summary

This pull request introduces the new Beam Pulse (BCON) subsystem to the project, providing both hardware driver and GUI control for beam pulsing via RS-485 serial communication. It includes comprehensive documentation for both the backend driver (instrumentctl/BCON) and the frontend GUI subsystem (subsystem/beam_pulse), adds a full test suite for cathode heating beam-off logic, and updates the dashboard's main module to include the new subsystem.

image

Major new features and documentation:

  • BCON driver and documentation:

    • Added instrumentctl/BCON/README.md with detailed documentation for the BCON (Beam Controller) driver, including hardware interface, command set, telemetry format, API reference, error handling, and usage examples.
    • Created instrumentctl/BCON/__init__.py to expose the BCON driver, enums, utility functions, and hardware register constants for external use.
  • Beam Pulse GUI subsystem and documentation:

    • Added subsystem/beam_pulse/README.md describing the new BeamPulseSubsystem, its GUI features, hardware communication, API, integration, and troubleshooting. This subsystem provides a Tkinter-based interface for controlling beam pulse hardware via the BCON driver.

Testing and workflow changes:

  • Automated tests:
    • Added citestfiles/CathodeHeating/beams_off_test.py, a comprehensive unittest suite for the cathode heating subsystem's beam-off logic, covering success, failure, exception handling, idempotency, and UI update scenarios.

Dashboard integration:

  • Subsystem registration:
    • Registered the new BeamPulse subsystem in the dashboard's main subsystem list in main.py to enable its use in the application.

Johnson and others added 30 commits September 3, 2025 14:09
@sbasu107
Copy link
Copy Markdown
Contributor Author

Result of Asking Codex in VSCode the question "I want your assessment if this code is good to go. Tell me if the code is ready to merge into the develop branch. Is there anything critical that needs to change before merging? Will it break develop in any way? What do the changes in the new code do and are they good changes? Point out any critical errors, in particular logic errors or anything that might break the dashboard. Make sure you do a diff of this branch relative to develop.":

It said that this won't break develop. It pointed out two issues, the second one we were aware of:

Findings (ordered by severity)

High: Beam arming can report success even when no BCON hardware/connection exists.

  • In beam_pulse.py:1447, arm_beams returns True and sets armed status even when bcon_driver is missing.
  • Dashboard then enables controls based on that status in dashboard.py:602.

Risk: operator sees system armed while hardware is absent/disconnected, which is a safety/UX mismatch.
Recommendation before merge: make arm_beams fail (return False) unless driver exists and is connected, and gate dashboard arming on connection state.

Medium: Full test suite passes but still emits thread warnings in unrelated interlock test code.

  • Warning source appears in G9 communication threads (StopIteration in mocked serial read), not BCON-lite files.
  • This does not block merge of this branch by itself, but it is a residual risk area for CI noise/flakiness.

@ColeMov
Copy link
Copy Markdown
Contributor

ColeMov commented Apr 21, 2026

High: Beam arming can report success even when no BCON hardware/connection exists.

* In beam_pulse.py:1447, arm_beams returns True and sets armed status even when bcon_driver is missing.

* Dashboard then enables controls based on that status in dashboard.py:602.

Risk: operator sees system armed while hardware is absent/disconnected, which is a safety/UX mismatch. Recommendation before merge: make arm_beams fail (return False) unless driver exists and is connected, and gate dashboard arming on connection state.

In response to the first finding, is it necessary for the Arm Beams toggle to have a hardware connection. I initially considered this a software interlock however we should recheck its current behavior with the bcon_driver

@sbasu107
Copy link
Copy Markdown
Contributor Author

High: Beam arming can report success even when no BCON hardware/connection exists.

* In beam_pulse.py:1447, arm_beams returns True and sets armed status even when bcon_driver is missing.

* Dashboard then enables controls based on that status in dashboard.py:602.

Risk: operator sees system armed while hardware is absent/disconnected, which is a safety/UX mismatch. Recommendation before merge: make arm_beams fail (return False) unless driver exists and is connected, and gate dashboard arming on connection state.

In response to the first finding, is it necessary for the Arm Beams toggle to have a hardware connection. I initially considered this a software interlock however we should recheck its current behavior with the bcon_driver

@ColeMov and I discussed, we are going to keep arm beams software-only as it was originally intended.

@sbasu107
Copy link
Copy Markdown
Contributor Author

Arm beams is now software only and toggle still works in frontend.

@sbasu107 sbasu107 marked this pull request as ready for review April 21, 2026 20:07
@ColeMov
Copy link
Copy Markdown
Contributor

ColeMov commented Apr 23, 2026

Most recent version was largely successful and tested as documented in BCON-BTEST-010: Firmware and Dashboard Integration Test https://docs.google.com/document/d/11xRWqmwaAlp3FNkDllFCPtVAfsml8pKOYc3Xju00kMQ/edit?usp=sharing

Copilot AI pushed a commit that referenced this pull request Apr 28, 2026
Resolved conflicts in:
- main.py: kept both 'KnobBox' and 'BeamPulse' in SUBSYSTEMS list
- dashboard.py: kept ports_after_id from #105 + toggle images and BeamPulse subsystem init from BCON-lite
- subsystem/cathode_heating/cathode_heating.py: kept HEAD's LUT-based logic (from #90) plus BCON-lite's turn_off_all_beams and set_target_current additions

Co-authored-by: sbasu107 <40325803+sbasu107@users.noreply.github.com>
@sbasu107
Copy link
Copy Markdown
Contributor Author

sbasu107 commented Apr 30, 2026

Tomorrow, I can take a look at the merge conflicts from cathode heating created by merging PR #90. This should be resolved quickly.

@sbasu107 sbasu107 marked this pull request as draft April 30, 2026 00:49
@sbasu107 sbasu107 marked this pull request as ready for review April 30, 2026 16:58
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 23dc141d7b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1463 to +1467
def disarm_beams(self) -> bool:
self.beams_armed_status = False
self.set_all_beams_status(False)
if self.bcon_driver:
self.bcon_driver.stop_all()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Stop CSV worker when beams are disarmed

Disarming beams does not stop an in-flight CSV sequence thread, so if an operator disarms (or triggers E-STOP, which calls disarm_beams) during a run, _sequence_worker can continue issuing sync_start commands on later steps and re-drive channels after the stop action. This is a safety regression because software disarm is expected to halt further pulse commands immediately.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator

@bwalkerMIR bwalkerMIR Apr 30, 2026

Choose a reason for hiding this comment

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

@sbasu107 @ColeMov @chott24 what is your assessment of this one?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would consider this fine for now and should not block the merge. We do not currently have plans to operate using a CSV sequence at this time. We should note this as a future issue and either target the thread to stop when calling disarm_beams or remove the feature entirely.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Addressed in 5d48f4e

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.

@ColeMov fixed issue #110 in 5d48f4e

Comment on lines +601 to +605
self._connected = ok
self._poll_errors = 0
self._reset_cached_state()

if ok:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Close serial handle when connect validation fails

When the post-open validation read fails (e.g., device not ready after settle), connect() sets ok=False and reports failure, but it never closes self._serial on that path. That leaves the COM port open while the driver is marked disconnected, which can block external recovery tools and creates inconsistent connection state until a later reconnect/disconnect happens to close it.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Addressed in commit 0c8a972. On post connection validation failure the COM port will be closed to match connection state.

@bwalkerMIR
Copy link
Copy Markdown
Collaborator

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0c8a9729b5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread dashboard.py
self.subsystems['Beam Pulse'] = beam_pulse_subsystem
else:
# placeholder if module not importable
container = self.frames.get('Beam Steering/Pulse', self.frames['Process Monitor'])
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Render BeamPulse import fallback in the Beam Pulse frame

When BeamPulseSubsystem cannot be imported, this fallback writes the placeholder label into Process Monitor instead of the Beam Pulse pane, because it looks up 'Beam Steering/Pulse' and then falls back to self.frames['Process Monitor']. In that failure mode, users get a misleading Process Monitor panel while the Beam Pulse frame stays empty; the fallback should target the Beam Pulse frame directly.

Useful? React with 👍 / 👎.

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.

Not addressing at the moment, but saved as issue #111

Comment thread dashboard.py
frame = ttk.Frame(self.com_port_menu)
frame.pack(fill=tk.X, padx=5, pady=2)
ttk.Label(frame, text="Beam Pulse:").pack(side=tk.LEFT)
port_var = tk.StringVar(value=self.com_ports.get('Beam Pulse', ''))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Initialize Beam Pulse COM selector from the persisted key

The new COM-port field is initialized from self.com_ports.get('Beam Pulse', ''), but this commit registers the subsystem key as BeamPulse in main.py (SUBSYSTEMS). As a result, the Beam Pulse dropdown appears blank even when a port is already configured, and pressing Apply can overwrite the in-memory config with an empty value. Read both aliases (or the canonical key) when initializing this control.

Useful? React with 👍 / 👎.

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.

Not fixing at the moment, but tracked as issue #112

Copy link
Copy Markdown
Collaborator

@bwalkerMIR bwalkerMIR left a comment

Choose a reason for hiding this comment

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

This is a big PR for introducing BCON to the dashboard, was well tested by the team, and looks good. Codex found some bugs that were fixed over the last day, and others were low priority so made to issues. Approved.

@bwalkerMIR bwalkerMIR merged commit a87841c into develop Apr 30, 2026
1 check passed
@bwalkerMIR bwalkerMIR deleted the feature/BCON-lite branch April 30, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stop active CSV sequence worker when beams are disarmed or software E-STOP is pressed

8 participants