Skip to content

Feature: CCS and Beams Shutoffs from VTRX Pressure - #180

Open
chott24 wants to merge 28 commits into
bugfix/CCS-connection-statusfrom
feature/pressure-shutoffs
Open

Feature: CCS and Beams Shutoffs from VTRX Pressure#180
chott24 wants to merge 28 commits into
bugfix/CCS-connection-statusfrom
feature/pressure-shutoffs

Conversation

@chott24

@chott24 chott24 commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

This PR expanded in scope from just adding pressure shutoffs. This PR now covers changes in all automatic shutoff features in the dashboard, as well as Predicted Emission LUT fallback with the Richardson-Dushman equation.

Main Areas of Change:

VTRX

  • Added VTRX pressure freshness tracking for each VTRX poll
  • Changed VTRX serial error handling
  • Added firmware_error variable that gets sent to Main Control

Beam Energy

  • Moved the +20kV Beams E-stop current limit out of Beam Energy config and into Main Control config.

Main Control

  • Added CCS Pressure shutoff setting.
    • When enabled and CCS output is on, if pressure goes above 1e-5 mbar, a shutdown timer will begin. If pressure stays above 1e-5 for a configurable amount of time (default 30s) then CCS outputs will shut off.
    • When enabled it prevents CCS outputs from going on if pressure is above 1e-5
    • If vtrx stops communicating for 3s the timer will begin
  • Added BCON Pressure shutoff setting.
    • When enabled if pressure goes above 1e-5 mbar BCON will shut off
    • When enabled it prevents BCON from being enabled or channels turning on if pressure is above 1e-5
    • If vtrx stops communicating for 3s BCON's disable_all_beams() is called
  • Added enable/disable checkboxes for the 20kV Bertan E-Stop current limit, as well as the two new pressure settings
  • Reworked Main Control config json. Saves all user set values to a json, and loads that json on dashboard startup. Resets to defaults if the json does not exist or is invali

Beam Pulse

  • Changed invalid emission-current predictions so that they block output (previously no difference between 0.0 and none)

Cathode Heating

  • Added Richardson-Dushman fallback emission prediction when above LUT domain
  • Removed obsolete Cathode Heating set_target_current() path and outdated cathode model initialization.

This PR is based off of bugfix/CCS-connection-status (#173) This branch should only be reviewed and merged once that PR has been merged into develop.

… be set to 'None' rather than '0.0'. Emission limit checks for a finite emission prediction value >= 0 and treats 'None' as invalid
@chott24 chott24 linked an issue Jun 29, 2026 that may be closed by this pull request
@chott24

chott24 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

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

Copy link
Copy Markdown

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: a0a06e2fc8

ℹ️ 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 subsystem/vtrx/vtrx.py
pass
finally:
self.flush_queued_logs()
self._update_main_control()

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 Schedule pressure callbacks when serial open fails

When the VTRX COM port fails to open at startup, start_serial_thread() is not called, so process_queue() is never scheduled; because the Main Control pressure callback is only invoked from this finally block, Main Control never receives the stale/unavailable-pressure updates that should start the CCS shutdown timer and beam-disable path. This affects systems booted with the VTRX unplugged or misconfigured while outputs are already active, which is exactly the stale-reading case the new guard is intended to handle.

Useful? React with 👍 / 👎.

@chott24 chott24 Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Since the process queue can handle empty serial just fine, it can be started independently of the serial start.

Fixed in b9a46ad

In the situation where a VTRX COM port fails to open, and the process queue was independently started (like it is in b9a46ad, then Machine Status would be updated with invalid VTRX data and then would start the CCS timer and/or turn beams off

@chott24

chott24 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

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

Copy link
Copy Markdown

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: b9a46ad2d3

ℹ️ 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 subsystem/main_control/main_control.py Outdated
Comment on lines +221 to +223
cathode.vtrx_ccs_pressure_allows_output = (
self._vtrx_ccs_pressure_output_status
)

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 Wire CCS pressure guard without depending on Beam Pulse

When Beam Pulse fails to initialize or is omitted, Dashboard never calls wire_beam_pulse() (it is only invoked after the BCON subsystem is constructed), so this block is the only place that gives Cathode Heating its VTRX pressure guard. In that context, if the BCON-disconnect guard is disabled, CathodeHeating.toggle_power_supply() sees vtrx_ccs_pressure_allows_output as None and skips the new high/stale-pressure block, allowing CCS output even though the VTRX CCS shutdown setting is enabled. Move this wiring to a Cathode/VTRX wiring path that runs whenever Cathode Heating is present.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is a good catch. Very unlikely that the whole Beam Pulse subpanel does not initialize, but the fix is simple and easy, and the code being referenced should likely be moved anyway.

Fixed in ca4f73c

@chott24

chott24 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

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

Copy link
Copy Markdown

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: ca4f73c5be

ℹ️ 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 +87 to +88
# Treat startup as already disabled until VTRX reports a safe pressure.
self._vtrx_pressure_beam_disable_latched = True

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 Do not ignore initial unsafe VTRX pressure

When the dashboard starts while BCON channels are already active, or the first VTRX updates are stale/high before any fresh safe sample arrives, this startup latch stays True and _handle_vtrx_bcon_pressure_update() returns without calling disable_all_beams() until a safe pressure clears it. In that scenario the new VTRX beam shutoff only blocks future beam starts and leaves currently active beams running under unsafe/unknown pressure; initialize this unlatched or explicitly disable active beams on the first unsafe update.

Useful? React with 👍 / 👎.

@chott24 chott24 Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was initially added so that Critical Logs, CCS and BCON shutdown were not triggered on dashboard startup. The failure scenario here is unrealistic in my opinion. Codex is neglecting the 1500ms BCON firmware watchdog.

The following situation has to happen in order for this issue to materialize:

T0: Beams are on and the dashboard crashes. The BCON firmware watchdog's last read is at 
worst at 0ms at this point. The dashboard must crash for this scenario to work. Any normal 
dashboard close down attempts a bcon disconnect.

T1: VTRX Pressure readings raise above 1e-5 mbar. This must happen after the dashboard 
crashes, because if the pressure readings raised above that threshold while the dashboard 
was active, it would attempt a BCON shutoff, and beams would not be on. 

T2: The user manages to get to respond to the crash and immediately run py ./main.py and 
click through the COM port config menu and relaunch the dashboard.

T3: The dashboard opens and the user clicks the manual BCON connect button. (The dashboard 
normally waits 4.5s until init is complete before connecting to BCON

T4: The dashboard successfully connects to BCON before the 1500ms watchdog expires and 
shuts beams off.

If everything through T4 completes, then yes, the dashboard would be running with beams on with vtrx pressure above 1e-5mbar.

@chott24

chott24 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

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

Copy link
Copy Markdown

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: 8bfd411adc

ℹ️ 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".

self.disable_ccs_output_on_bcon_disconnect = True
self.disable_beams_on_vtrx_pressure_exceeded = True
# Treat startup as already disabled until VTRX reports a safe pressure.
self._vtrx_pressure_beam_disable_latched = True

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 Do not latch the startup VTRX beam shutoff

With this initialized as already latched, _handle_vtrx_bcon_pressure_update() returns without calling disable_all_beams() for every unsafe or stale VTRX update until a fresh safe pressure is seen. If the dashboard restarts while BCON channels are already active, or if the first VTRX reading after startup is high/stale, the new pressure shutoff never sends the stop command and the channels can keep running in the unsafe state. Initialize unlatched or retry the shutoff once Beam Pulse is available instead of suppressing the first unsafe condition.

Useful? React with 👍 / 👎.

@chott24 chott24 Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

See above comment.


def load_beams_estop_current_limit_ma(filepath=CONFIG_FILE, logger=None):
"""Load the persisted +20kV Beams E-STOP current limit."""
return _load_field(BEAMS_ESTOP_CURRENT_LIMIT_FIELD, filepath=filepath, logger=logger)

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 Migrate the legacy 20 kV E-stop limit before defaulting

When upgrading an existing machine that has the old pos20kv.beams_estop_current_ma saved in usr/usr_data/beam_energy_warning_limits.json but no new Main Control config yet, this loader goes straight to _load_field() and writes the 0.7 mA default. The Beam Energy normalizer now drops the old key, so the operator's previously configured E-stop threshold is silently lost on first startup. Please read and migrate the legacy Beam Energy field before falling back to the new default.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Part of the melt pre-procedure will be to set and configure dashboard defaults. I don't think its worth supporting legacy JSON versions, especially because this setting is quite new and its probably only my development computer, the lab computer, and brandon's computer that have a saved json at all.

@chott24
chott24 marked this pull request as ready for review July 8, 2026 22:11

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

Copy link
Copy Markdown

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: 8bfd411adc

ℹ️ 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 subsystem/vtrx/vtrx.py
Comment on lines +388 to +389
self.last_successful_read_time = time.time()
self.last_valid_pressure_value = pressure_value

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 Update pressure cache before warning-state branch

When a VTRX frame has a valid pressure plus a warning/error segment (for example 972b ERR:16:UNSAFE FOR HV WARNING), line 379 sets self.error_state = True, so this new cache update is skipped. _update_main_control() then keeps publishing the previous last_valid_pressure_value as fresh until PRESSURE_READING_FRESH_SECONDS expires, so a transition from safe pressure to unsafe-with-warning can leave beam/CCS pressure guards seeing the old safe reading instead of tripping immediately; cache the parsed pressure/time before branching on the VTRX warning state or pass the parsed value directly to the callback.

Useful? React with 👍 / 👎.

@chott24 chott24 Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

VTRX now passes a firmware_error variable to Main Control. last_successful_read_time and last_valid_pressure_value functionality remained the same, but Main Control now responds to an explicit VTRX firmware error.

See e92c96d

@chott24

chott24 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

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

Copy link
Copy Markdown

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: fc0403ce63

ℹ️ 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 +87 to +88
# Treat startup as already disabled until VTRX reports a safe pressure.
self._vtrx_pressure_beam_disable_latched = True

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 Shut off active beams on the first unsafe VTRX update

Initializing the beam pressure latch as already set means the first high-pressure, stale, or firmware-error VTRX update after dashboard startup hits the latched return in _handle_vtrx_bcon_pressure_update, so disable_all_beams() is not called. If BCON outputs are already active when the dashboard restarts or reconnects, this guard only blocks future starts and leaves the existing beams on until a safe reading arrives and a later unsafe transition occurs.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines +720 to +722
allowed, error_message = self._vtrx_pressure_allows_output(action, log_failure)
if not allowed:
return False, error_message

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 Apply the VTRX guard before enabling BCON channels

The new pressure guard is only invoked from _emission_limit_allows_output, which covers mode/sync/sequence output commands; the Main Control CH A/B/C buttons call toggle_channel_enable() and that path writes set_channel_enable() directly without this helper. When the VTRX pressure is stale or above the limit, an operator can still enable a BCON channel even though the pressure guard is enabled, so the guard does not cover the channel-enable path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Previously, Main Control checks for enabling output were only done on a button click that would enable output. Emission Limit Allows Output should definitely not be called when enabling channels, since it relies using enabled channels to determine if it allows output of beams. (So that several cathodes can be heated to allow output if they are each individually below the limit, and beams can then only be turned on if the sum of enabled channels cathodes would be below the limit). So this behavior was essentially copied for the VTRX check. However, there is really no reason why an enable channel attempt can't check this.

I am going to add it in, since its a small change, and does not hurt anything.

See d63e9e9

@chott24

chott24 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

chatgpt-codex-connector[bot]

This comment was marked as duplicate.

@chott24

chott24 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

This PR has been thoroughly tested on the lab laptop.

Items tested:

  • Main Control settings user control, buttons work, log responds with info, jsons get properly updated and saved
  • VTRX allows Beams and CCS when pressure is below limit (i changed it to 1e+5 locally in code when testing the success case for this test)
  • Stale VTRX values shut beams off. Stale values and too high pressure values block beams from turning on
  • Stale VTRX values start CCS turn off countdown sequence, regaining vtrx disables shutdown sequence. If VTRX remains stale or pressure is too high CCS does not turn on
  • CCS cannot enable when the CCS countdown sequence is going
  • Both CCS and VTRX pressure values do not apply when setting is disabled
  • Beams are not allowed of the corresponding CCS channel does not have a predicted emission current
  • Emission blocking works as intended from its previous PR.
  • Emission current prediction above 6.03A and .82V are derived from the Richardson-Dushman equation, the log gives a warning that it is out of range of the LUT.
  • 20kV current limit seems to have migrated to Main Control correctly, still works as expected
  • Beam channels cannot be enabled if VTRX does not have a valid, below-threshold reading

@chott24

chott24 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@bwalkerMIR This PR is ready for review and merge.

This PR is quite long, and covers all automatic shutoffs, not just the new pressure shutoff. Around half of the added code is unit test code, it can be discarded if it gets in the way or is not necessary. bugfix/CCS-connection-status should be merged into develop before this PR is reviewed and merged. Once that branch is in, this PR should switch to target develop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing LUT emission prediction can bypass the beam-current guard

2 participants