Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
d17cea5
Added method to turn off/disable all cathode heaters at once.
Sep 3, 2025
af7f8c8
testing remote push
MathomJohnson Sep 4, 2025
3c15a1a
this is a test commit
MathomJohnson Sep 5, 2025
d551c60
Implemented method to turn all beams off at once
MathomJohnson Sep 5, 2025
240f723
Added beams off button to GUI
MathomJohnson Sep 5, 2025
b937e59
Added more error checking for all beams off logic
Sep 5, 2025
55ccf04
Updated command param for tk button
Sep 5, 2025
2cc83dc
change button styling
MathomJohnson Sep 7, 2025
e12e283
Merge branch 'feature/beams-off-button' of https://github.com/uw-loci…
MathomJohnson Sep 7, 2025
093ab58
Updating beams off logic
MathomJohnson Sep 7, 2025
403d291
Added basic unit tests for beams off button/logic
MathomJohnson Sep 7, 2025
9d5b781
Moved beams off button to 'main control' window
Sep 8, 2025
9bb29d4
Made beams off button callable from Main Control, removed old button …
MathomJohnson Sep 8, 2025
41ab1c1
Added more unit tests
MathomJohnson Sep 8, 2025
16d0940
testing remote push
danielegelhoff13 Sep 9, 2025
55644d6
Added method to turn off/disable all cathode heaters at once.
Sep 3, 2025
a4222b3
Updated command param for tk button
Sep 5, 2025
6d4c309
Updating beams off logic
MathomJohnson Sep 7, 2025
a6c9819
Added basic unit tests for beams off button/logic
MathomJohnson Sep 7, 2025
e7cec94
Moved beams off button to 'main control' window
Sep 8, 2025
97f80c3
Made beams off button callable from Main Control, removed old button …
MathomJohnson Sep 8, 2025
9d2d612
Added more unit tests
MathomJohnson Sep 8, 2025
9dbce6f
testing remote push
danielegelhoff13 Sep 9, 2025
9d73334
Merge branch 'feature/beams-off-button' of https://github.com/uw-loci…
MathomJohnson Sep 9, 2025
0f509b7
Removed unused button style
MathomJohnson Sep 9, 2025
2e10224
Added BCON driver
theoreotically Sep 22, 2025
d75985a
Minor dashboard updates based on discussions
theoreotically Sep 22, 2025
5980d04
Added some safety features
theoreotically Sep 22, 2025
9ade1e6
Reduced frame size
theoreotically Oct 2, 2025
4b7d8db
First BCOM UI concept inplemented on Dashboard
sbasu107 Oct 10, 2025
8e77dde
Added Config Menu, BCON connected indicator, and made Wave Type dropd…
sbasu107 Oct 13, 2025
2a6ed13
Removed BOP Amp plot, expected current setting and solenioid temp ind…
sbasu107 Oct 15, 2025
52605b8
Adjusted units in config menu, adjusted graphs
sbasu107 Oct 16, 2025
4f2705e
GUI updates
theoreotically Oct 16, 2025
9cb9949
Modified print bed graph scaling
sbasu107 Oct 17, 2025
03053fb
Merge branch 'feature/beams-off-button' into feature/BCON-driver
sbasu107 Oct 17, 2025
dce7aa9
Added Beams Ready button
sbasu107 Oct 17, 2025
6866045
Fished 'Arm Beams' implementation, individual beam on toggle in the m…
sbasu107 Oct 20, 2025
dc5aaf9
Added Beam Pusle Duration setting for each beam, renamed beam on butt…
sbasu107 Oct 21, 2025
dcc00f1
Implemented beam on feature for duration of set value in pulse mode.
sbasu107 Oct 23, 2025
f5d1f43
Started working on graphs
sbasu107 Oct 24, 2025
acc0c96
small changes
theoreotically Oct 24, 2025
0787ee7
Merge branch 'feature/BCON-driver' of https://github.com/uw-loci/EBEA…
theoreotically Oct 24, 2025
d09252a
Minor GUI updates
theoreotically Oct 24, 2025
6cf88f0
Fixed GUI some more
theoreotically Oct 24, 2025
31b3051
Spell fix
theoreotically Oct 24, 2025
3525aaa
Removed deprecated SafetyMonitor
theoreotically Oct 27, 2025
eeada16
Refactored GUI quite a bit
theoreotically Oct 27, 2025
3fb92ee
Updated defualts for 1920x1080
theoreotically Oct 27, 2025
86bcf20
Added Lookup Table Settings in Config menu for the mapping of deflect…
sbasu107 Oct 28, 2025
8d232e9
Added 'Clear Graph' button
sbasu107 Oct 28, 2025
46c8a35
Fixed 'Show All/Clear Graph' button
sbasu107 Oct 29, 2025
7f8b912
Merge branch 'feature/BCON-driver' of https://github.com/uw-loci/EBEA…
theoreotically Oct 29, 2025
dfc2c6c
Added Beam Deflection functionality
sbasu107 Oct 30, 2025
0e7f65c
Lookup table configuration and delfection stats calculation
sbasu107 Nov 3, 2025
646c62d
Merge branch 'feature/BCON-driver' of https://github.com/uw-loci/EBEA…
theoreotically Nov 10, 2025
452d58b
Added deflection stats table format and corresponding Beam energy to …
sbasu107 Nov 10, 2025
264801b
Implemented B-field estimation calculations per beam using linear app…
sbasu107 Nov 10, 2025
4fa8f83
Added support for multiple lookup tables and switching bewteen the on…
sbasu107 Nov 11, 2025
60b85bb
Added derived power equation and handled negative wave/current amplit…
sbasu107 Nov 13, 2025
63474f5
Migrated driver related code to separate file
sbasu107 Nov 13, 2025
885bb27
Improved formatting for readability & to be in compliance with Google…
sbasu107 Nov 14, 2025
14716f2
Fixed LUT Datasets
sbasu107 Nov 17, 2025
523960f
Added pulse mode Beam On duration status bars
sbasu107 Nov 19, 2025
946f281
Added pulsing behavior dropdoen and fixed beam on duration animations
sbasu107 Nov 20, 2025
cb79a09
Added Hour Functionality to timers
sbasu107 Dec 3, 2025
3289586
reduced spacing between beam duration features and deleted 30KV dataset
sbasu107 Dec 3, 2025
34b4623
Beams off Button also disarms beams
sbasu107 Dec 4, 2025
b5989ed
Dashes show for values not existent in lookup table
sbasu107 Dec 8, 2025
54ec6f5
Added more datapoints to mock beam deflection data
sbasu107 Dec 10, 2025
b20f974
Added legend for print bed graphs
Dec 10, 2025
e101e18
Fixed broken debug messages
Dec 11, 2025
4c004d4
refactor: remove BCON_modbus wrapper, use E5CNModbus directly
Dec 11, 2025
c90c39e
Performed refactoring to match the beam pulse README specification fo…
Dec 11, 2025
3283284
Added EBEAM_dashboard_LUT repo as submodule
Jan 20, 2026
cce938b
Updated LUT Submodule
sbasu107 Jan 21, 2026
4532ec6
Moved Beam control LUT Datasets to submodule
sbasu107 Jan 22, 2026
c96d70c
Added warning pop up for switching DC to pulsed mode while beams are on
sbasu107 Jan 22, 2026
af430a8
Fixed Beam control button animation to go off when switching from DC …
sbasu107 Jan 22, 2026
ded34e9
Made separeate buttons for Clear Graph/Show all
sbasu107 Jan 23, 2026
dd01356
Refactor beam plot storage: dictionary-based step history with real-t…
sbasu107 Jan 31, 2026
32a6261
Set default amplitude to 0
sbasu107 Feb 3, 2026
7a8151a
Added Projected and Historical step toggles and moved Pulsing Mode dr…
sbasu107 Feb 6, 2026
1e4efca
Updated graphing behavior for preview
sbasu107 Feb 6, 2026
347d232
Moved deflect beam to main control panel and added loading bar; renam…
sbasu107 Feb 11, 2026
1f0d3da
Added 'deflect beam' holdown button, removed preview deplendency on a…
sbasu107 Feb 11, 2026
79bccac
Changed deflectand arm beam buttons to toggles in main menu
sbasu107 Feb 17, 2026
0eeee4d
Initial update of README
sbasu107 Feb 17, 2026
6c099b8
Updated Python version for tests to 3.11
sbasu107 Feb 17, 2026
1714d9b
Abridged BCON subsystem for lite version
sbasu107 Feb 17, 2026
adbbde4
Added pulse status inducators
sbasu107 Feb 17, 2026
ed2034f
Added new drivers and intgrated backend with it
sbasu107 Feb 18, 2026
8fb9af1
Preliminary integration of standalone app with dashboard
sbasu107 Feb 24, 2026
29f1662
removed pulse status inducators
sbasu107 Feb 24, 2026
002a88e
Added Beam Pulse dropdown for COM post selection
sbasu107 Feb 24, 2026
49824f8
Fixed connection calling on the BCON driver
sbasu107 Feb 24, 2026
0204bf9
Removed pulse train buttons, telemetry setting and state display
sbasu107 Feb 24, 2026
043904d
Moved enable buttons to main control panel
sbasu107 Feb 24, 2026
ef78c1b
Refactor BCOn channel for dashboard integration
sbasu107 Feb 25, 2026
4e9fb80
attempt to fix register overrite mode bug for other channels
sbasu107 Feb 25, 2026
f7688cb
fix: blur out duration and count in off setting for sync control tab
sbasu107 Feb 25, 2026
ff80afc
feat: integrate external control buttons for Sync Control and CSV Seq…
TianruiBai Feb 25, 2026
d68c617
feat: implement tab-aware action buttons for Main Control panel in Be…
TianruiBai Feb 25, 2026
99cb4f0
feat: enhance manual control panel with beam ON/OFF and channel enabl…
TianruiBai Feb 25, 2026
eec6462
feat: add beams armed check to prevent actions when beams are not armed
TianruiBai Feb 25, 2026
41ed317
feat: implement armed state management for control buttons in BeamPul…
TianruiBai Feb 25, 2026
91a96bd
feat: add CSV sequence control buttons and channel status update for …
TianruiBai Feb 25, 2026
c711576
feat: enhance BeamPulseSubsystem with tab-aware control button visibi…
TianruiBai Feb 25, 2026
6fd3eb7
feat: add channel enable getter to BeamPulseSubsystem for hardware-en…
TianruiBai Feb 25, 2026
c09a636
feat: enhance BeamPulseSubsystem with default watchdog value and impr…
TianruiBai Feb 25, 2026
b9043d0
feat: refactor parameter validation in BeamPulseSubsystem for improve…
TianruiBai Feb 25, 2026
f1cc8f4
feat: add input validation for duration and count fields in BeamPulse…
TianruiBai Feb 25, 2026
a2b0f77
Refactor code structure for improved readability and maintainability
TianruiBai Feb 26, 2026
67f4188
fix(bcon): optimize connection handshake and settle timing for BCON d…
sbasu107 Mar 4, 2026
4019357
Moved away from Pymodbus
sbasu107 Mar 6, 2026
d05c2bc
Add .venv to .gitignore that was added to develop already
bwalkerMIR Mar 26, 2026
bfc7b60
First pass refactor for updating bcon_driver to operate with new firm…
Apr 14, 2026
1d568a6
Updated beam enable UI state to follow successful hardware writes and…
ColeMov Apr 16, 2026
65090eb
Updated watchdog behavior on close to ensure output disable
ColeMov Apr 16, 2026
14e6854
Remove Docs
sbasu107 Apr 16, 2026
04887ba
Merge branch 'develop' into feature/BCON-lite
sbasu107 Apr 17, 2026
f6c115d
Fixed merge regression
sbasu107 Apr 17, 2026
a5bfeda
Fixed whitespace issues
sbasu107 Apr 17, 2026
9da6307
Stop tracking citestfiles/_tmp artifacts
sbasu107 Apr 17, 2026
d8b5f78
removed LUT submodules
sbasu107 Apr 17, 2026
0c05eaa
Added back missing frontend cell border logic
sbasu107 Apr 17, 2026
e336a1d
Revert Python version change - out of scope for this PR
sbasu107 Apr 18, 2026
b4f49d8
Remove unnecessary whitespace changes in cathode_heating.py and yaml …
sbasu107 Apr 18, 2026
729fef3
Make beam arming software-only and remove unused driver ARM APIs
sbasu107 Apr 21, 2026
a9deed6
Completed removal of fault latch and arm beams hardware signal from d…
ColeMov Apr 23, 2026
77c8560
Updated Beam Pulse and Main Control to label each beam channel as ABC
ColeMov Apr 23, 2026
23dc141
Merge branch 'develop' into feature/BCON-lite
sbasu107 Apr 30, 2026
0c8a972
Close COM port on failed post-open validation path
Apr 30, 2026
5d48f4e
Updated stop flag checks in CSV sequence worker to be triggered by di…
Apr 30, 2026
1f076a3
Remove unnecessary whitespace EOL changes
bwalkerMIR Apr 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions citestfiles/CathodeHeating/beams_off_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import sys, os, unittest
from unittest.mock import MagicMock

sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))

from subsystem.cathode_heating.cathode_heating import CathodeHeatingSubsystem
from utils import LogLevel

class TestBeamsOff(unittest.TestCase):
def setUp(self):
# Bypass __init__ to avoid Tk and image loading
self.subsys = object.__new__(CathodeHeatingSubsystem)
# Inject only what turn_off_all_beams uses
self.subsys.power_supplies_initialized = True
self.subsys.power_supplies = [MagicMock(), None, MagicMock()]
self.subsys.power_supply_status = [True, False, True]
self.subsys.toggle_states = [True, True, True]
self.subsys.toggle_off_image = object()
self.subsys.toggle_buttons = [MagicMock(), MagicMock(), MagicMock()]
# Simple logger hook
self.subsys.logger = MagicMock()
self.subsys.log = lambda msg, lvl=LogLevel.INFO: None

# Alias method under test (name in your file)
self.turn_off_all_beams = self.subsys.turn_off_all_beams

def test_turns_off_only_initialized_ps_and_updates_ui_on_success(self):
# First and third supply return True; middle is uninitialized
self.subsys.power_supplies[0].set_output.return_value = True
self.subsys.power_supplies[2].set_output.return_value = True

self.turn_off_all_beams()

self.subsys.power_supplies[0].set_output.assert_called_once_with("0")
self.subsys.power_supplies[2].set_output.assert_called_once_with("0")
self.assertFalse(self.subsys.toggle_states[0])
self.assertFalse(self.subsys.toggle_states[2])
self.subsys.toggle_buttons[0].config.assert_called_once()
self.subsys.toggle_buttons[2].config.assert_called_once()
# Uninitialized index 1 untouched
self.subsys.toggle_buttons[1].config.assert_not_called()

def test_does_not_update_ui_when_off_fails(self):
# Simulate failure on index 0, success on index 2
self.subsys.power_supplies[0].set_output.return_value = False
self.subsys.power_supplies[2].set_output.return_value = True

self.turn_off_all_beams()

# UI should not change for failed OFF
self.assertTrue(self.subsys.toggle_states[0])
self.subsys.toggle_buttons[0].config.assert_not_called()

# UI should change for successful OFF
self.assertFalse(self.subsys.toggle_states[2])
self.subsys.toggle_buttons[2].config.assert_called_once()

def test_exceptions_are_caught_and_others_continue(self):
self.subsys.power_supplies[0].set_output.side_effect = RuntimeError("boom")
self.subsys.power_supplies[2].set_output.return_value = True

# Should not raise
self.turn_off_all_beams()

self.subsys.power_supplies[2].set_output.assert_called_once_with("0")
self.assertFalse(self.subsys.toggle_states[2])

def test_returns_early_when_not_initialized(self):
# Arrange: pretend subsystem not initialized
self.subsys.power_supplies_initialized = False
# Keep mocks to detect accidental calls
self.subsys.power_supplies = [MagicMock(), MagicMock(), MagicMock()]
self.subsys.power_supply_status = [True, True, True]

# Act
self.turn_off_all_beams()

# Assert: no calls made
for ps in self.subsys.power_supplies:
ps.set_output.assert_not_called()
for btn in self.subsys.toggle_buttons:
btn.config.assert_not_called()

def test_skips_when_status_false_even_if_ps_present(self):
# Arrange: ps exists but status is False
self.subsys.power_supplies = [MagicMock(), MagicMock(), MagicMock()]
self.subsys.power_supply_status = [True, False, True]
self.subsys.power_supplies[0].set_output.return_value = True
self.subsys.power_supplies[2].set_output.return_value = True

# Act
self.turn_off_all_beams()

# Assert
self.subsys.power_supplies[1].set_output.assert_not_called()

def test_updates_button_with_correct_image_on_success(self):
# Arrange
self.subsys.power_supplies[0].set_output.return_value = True
self.subsys.power_supplies[2].set_output.return_value = True

# Act
self.turn_off_all_beams()

# Assert exact image argument used
self.subsys.toggle_buttons[0].config.assert_called_once_with(image=self.subsys.toggle_off_image)
self.subsys.toggle_buttons[2].config.assert_called_once_with(image=self.subsys.toggle_off_image)

def test_true_status_but_none_power_supply_is_safely_skipped(self):
# Arrange: ps None but status True for index 1
self.subsys.power_supplies = [MagicMock(), None, MagicMock()]
self.subsys.power_supply_status = [True, True, True]
self.subsys.power_supplies[0].set_output.return_value = True
self.subsys.power_supplies[2].set_output.return_value = True

# Act (should not raise)
self.turn_off_all_beams()

# Assert: others still called, middle skipped
self.subsys.power_supplies[0].set_output.assert_called_once_with("0")
self.subsys.power_supplies[2].set_output.assert_called_once_with("0")

# Button 1 should not be touched since ps is None
self.subsys.toggle_buttons[1].config.assert_not_called()

def test_second_call_is_idempotent_and_keeps_off_state(self):
# Arrange first call success
self.subsys.power_supplies[0].set_output.return_value = True
self.subsys.power_supplies[2].set_output.return_value = True

# Act: call twice
self.turn_off_all_beams()
self.turn_off_all_beams()

# Assert: set_output called twice for active channels
self.assertEqual(self.subsys.power_supplies[0].set_output.call_count, 2)
self.assertEqual(self.subsys.power_supplies[2].set_output.call_count, 2)
# State remains off
self.assertFalse(self.subsys.toggle_states[0])
self.assertFalse(self.subsys.toggle_states[2])

if __name__ == '__main__':
unittest.main()
Loading
Loading