Files
hla_framework_bd/qt/A_BD_ServiceManager_inc.ui
T
Benjamin LabrecqueandClaude Opus 5 cfd3ecad6c refactor: centralize deploy-time substitutions (steps 1-2)
Deploy-time placeholders were spread across four independent
implementations: sed in the Gitea deploy script, ansible.builtin.replace
in two playbooks, a hardcoded suffix in bin/sls_hla_launch_gui.sh, and
another in agebd/pv.py. Each defined its own values, so nothing kept them
in sync and a missed substitution failed silently.

Step 1 -- one source of truth:

  * config/environments.yml declares every deploy-time token, its value
    per environment, and where tokens are allowed to live. An environment
    that is missing a token, or defines an undeclared one, is a load-time
    error.
  * agebd.subs loads it and renders. Rendering is a strict regex over
    declared token names rather than a template engine: the rendered
    files are EPICS db/substitution files and Qt XML, and an unknown
    token must raise rather than survive into the output.
  * scripts/ci/check_subs.py enforces the contract in CI: tokens in a
    rendered path are declared, declared tokens only appear where they
    are rendered or generated, and no pre-migration delimiters survive.

Step 2 -- separate the two substitution stages by delimiter:

  * Creation-time (copier, once per new service) keeps {{ token }}.
    Deploy-time (every deploy, per environment) becomes @@token@@.
  * This drops the {{ '{{ token }}' }} escaping from templates/, which
    existed only because one Jinja pass had to emit syntax for a second.
  * Angle brackets were tried first and rejected: << >> is not
    well-formed XML, and cli parses qt/*.ui with ElementTree.
  * The existing sed and ansible consumers are repointed at the new
    delimiters so this stays behaviour-preserving. Routing them through
    agebd.subs is step 3.

Also fixes, as a side effect of having one implementation:

  * The sed pattern '{{ *agebd_env_suffix_upper* }}' quantified 'r'
    rather than the space, so it only matched one exact spacing.
  * agebd.subs.read_ioc_port compares service names case-insensitively;
    ansible/tasks/utils/get-ioc-port.yml still compares CamelCase
    registry names against a lowercase input and never matches.

qt/*.ui is declared as a render path but nothing renders it yet -- the
Qt deploy step is still a plain rsync. Wiring that up is step 4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 11:26:49 +02:00

755 lines
19 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1319</width>
<height>30</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="caLed" name="caled_51">
<property name="geometry">
<rect>
<x>8</x>
<y>0</y>
<width>30</width>
<height>30</height>
</rect>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="rectangular">
<bool>true</bool>
</property>
<property name="gradientEnabled">
<bool>false</bool>
</property>
<property name="ledWidth">
<number>28</number>
</property>
<property name="ledHeight">
<number>28</number>
</property>
<property name="linearGradient">
<bool>true</bool>
</property>
<property name="scaleContents">
<bool>false</bool>
</property>
<property name="channel" stdset="0">
<string notr="true">$(IOC):STATUS</string>
</property>
<property name="colorMode">
<enum>caLed::Alarm</enum>
</property>
</widget>
<widget class="caRelatedDisplay" name="carelateddisplay_26">
<property name="geometry">
<rect>
<x>43</x>
<y>0</y>
<width>30</width>
<height>30</height>
</rect>
</property>
<property name="background">
<color>
<red>183</red>
<green>157</green>
<blue>92</blue>
</color>
</property>
<property name="labels">
<string>P</string>
</property>
<property name="files">
<string>/ioc/modules/qt/iocStats.ui</string>
</property>
<property name="args">
<string>IOC=$(IOC)</string>
</property>
</widget>
<widget class="caFrame" name="caframe">
<property name="geometry">
<rect>
<x>1200</x>
<y>0</y>
<width>110</width>
<height>40</height>
</rect>
</property>
<property name="visibility">
<enum>caFrame::Calc</enum>
</property>
<property name="visibilityMode">
<enum>caFrame::All</enum>
</property>
<property name="visibilityCalc">
<string notr="true">$(panel)</string>
</property>
<property name="channel" stdset="0">
<string notr="true"/>
</property>
<property name="channelB">
<string notr="true"/>
</property>
<widget class="caRelatedDisplay" name="carelateddisplay_23">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>30</width>
<height>30</height>
</rect>
</property>
<property name="background">
<color>
<red>183</red>
<green>157</green>
<blue>92</blue>
</color>
</property>
<property name="labels">
<string>P</string>
</property>
<property name="files">
<string>$(panelcmd)</string>
</property>
<property name="args">
<string>$(macro)</string>
</property>
</widget>
</widget>
<widget class="caFrame" name="caframe_2">
<property name="geometry">
<rect>
<x>277</x>
<y>0</y>
<width>900</width>
<height>120</height>
</rect>
</property>
<property name="visibility">
<enum>caFrame::Calc</enum>
</property>
<property name="visibilityCalc">
<string notr="true">$(svc_exist)</string>
</property>
<widget class="caLineEdit" name="calineedit_73">
<property name="geometry">
<rect>
<x>800</x>
<y>0</y>
<width>100</width>
<height>30</height>
</rect>
</property>
<property name="channel" stdset="0">
<string notr="true">AGEBD-ALH@@agebd_env_suffix_upper@@:$(service)-STATUS</string>
</property>
<property name="colorMode">
<enum>caLineEdit::Default</enum>
</property>
<property name="alarmHandling">
<enum>caLineEdit::onBackground</enum>
</property>
<property name="precisionMode">
<enum>caLineEdit::User</enum>
</property>
</widget>
<widget class="caMessageButton" name="camessagebutton_88">
<property name="geometry">
<rect>
<x>220</x>
<y>0</y>
<width>60</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Restart</string>
</property>
<property name="fontScaleMode">
<enum>EPushButton::None</enum>
</property>
<property name="channel" stdset="0">
<string notr="true">AGEBD-MASTER@@agebd_env_suffix_upper@@:$(service)-RESTART-REQ</string>
</property>
<property name="label">
<string notr="true">Restart</string>
</property>
<property name="background">
<color>
<red>160</red>
<green>160</green>
<blue>160</blue>
</color>
</property>
<property name="disableChannel" stdset="0">
<string>CONTROL-ONOFF</string>
</property>
<property name="releaseMessage">
<string notr="true"/>
</property>
<property name="pressMessage">
<string notr="true">1</string>
</property>
</widget>
<widget class="caLineEdit" name="calineedit_81">
<property name="geometry">
<rect>
<x>690</x>
<y>0</y>
<width>100</width>
<height>30</height>
</rect>
</property>
<property name="channel" stdset="0">
<string notr="true">AGEBD-ALH@@agebd_env_suffix_upper@@:$(service)-VERSION</string>
</property>
<property name="colorMode">
<enum>caLineEdit::Default</enum>
</property>
<property name="alarmHandling">
<enum>caLineEdit::onBackground</enum>
</property>
<property name="precisionMode">
<enum>caLineEdit::User</enum>
</property>
</widget>
<widget class="caChoice" name="cachoice_18">
<property name="geometry">
<rect>
<x>340</x>
<y>0</y>
<width>100</width>
<height>30</height>
</rect>
</property>
<property name="channel" stdset="0">
<string notr="true">AGEBD-ALH@@agebd_env_suffix_upper@@:$(service)-ONOFF</string>
</property>
<property name="stackingMode" stdset="0">
<enum>caChoice::Column</enum>
</property>
<property name="endBit">
<number>1</number>
</property>
</widget>
<widget class="caLineEdit" name="calineedit_87">
<property name="geometry">
<rect>
<x>500</x>
<y>0</y>
<width>180</width>
<height>30</height>
</rect>
</property>
<property name="channel" stdset="0">
<string notr="true">AGEBD-ALH@@agebd_env_suffix_upper@@:$(service)-STARTTIME</string>
</property>
<property name="colorMode">
<enum>caLineEdit::Default</enum>
</property>
<property name="alarmHandling">
<enum>caLineEdit::onBackground</enum>
</property>
<property name="precisionMode">
<enum>caLineEdit::User</enum>
</property>
</widget>
<widget class="caLed" name="caled_55">
<property name="geometry">
<rect>
<x>300</x>
<y>0</y>
<width>30</width>
<height>30</height>
</rect>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="rectangular">
<bool>true</bool>
</property>
<property name="gradientEnabled">
<bool>false</bool>
</property>
<property name="ledWidth">
<number>28</number>
</property>
<property name="ledHeight">
<number>28</number>
</property>
<property name="linearGradient">
<bool>true</bool>
</property>
<property name="scaleContents">
<bool>false</bool>
</property>
<property name="channel" stdset="0">
<string notr="true">AGEBD-ALH@@agebd_env_suffix_upper@@:$(service)-ALIVE</string>
</property>
<property name="colorMode">
<enum>caLed::Alarm</enum>
</property>
</widget>
<widget class="caMessageButton" name="camessagebutton_79">
<property name="geometry">
<rect>
<x>170</x>
<y>0</y>
<width>40</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Logs</string>
</property>
<property name="fontScaleMode">
<enum>EPushButton::None</enum>
</property>
<property name="channel" stdset="0">
<string notr="true">AGEBD-MASTER@@agebd_env_suffix_upper@@:$(service)-LOGS-REQ</string>
</property>
<property name="label">
<string notr="true">Logs</string>
</property>
<property name="background">
<color>
<red>160</red>
<green>160</green>
<blue>160</blue>
</color>
</property>
<property name="disableChannel" stdset="0">
<string>CONTROL-ONOFF</string>
</property>
<property name="releaseMessage">
<string notr="true"/>
</property>
<property name="pressMessage">
<string notr="true">1</string>
</property>
</widget>
<widget class="caLed" name="caled_58">
<property name="geometry">
<rect>
<x>450</x>
<y>0</y>
<width>30</width>
<height>30</height>
</rect>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="rectangular">
<bool>true</bool>
</property>
<property name="gradientEnabled">
<bool>false</bool>
</property>
<property name="ledWidth">
<number>28</number>
</property>
<property name="ledHeight">
<number>28</number>
</property>
<property name="linearGradient">
<bool>true</bool>
</property>
<property name="scaleContents">
<bool>false</bool>
</property>
<property name="channel" stdset="0">
<string notr="true">AGEBD-ALH@@agebd_env_suffix_upper@@:$(service)-ONOFF-RB</string>
</property>
<property name="colorMode">
<enum>caLed::Alarm</enum>
</property>
</widget>
<widget class="Line" name="line_20">
<property name="geometry">
<rect>
<x>481</x>
<y>0</y>
<width>20</width>
<height>30</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</widget>
<widget class="caLabel" name="calabel_47">
<property name="geometry">
<rect>
<x>130</x>
<y>0</y>
<width>201</width>
<height>30</height>
</rect>
</property>
<property name="text">
<string>$(name)</string>
</property>
<property name="textFormat">
<enum>Qt::MarkdownText</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="Line" name="line_17">
<property name="geometry">
<rect>
<x>108</x>
<y>0</y>
<width>20</width>
<height>30</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
<widget class="Line" name="line_18">
<property name="geometry">
<rect>
<x>328</x>
<y>0</y>
<width>20</width>
<height>30</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
<widget class="Line" name="line_19">
<property name="geometry">
<rect>
<x>558</x>
<y>0</y>
<width>20</width>
<height>30</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
<widget class="Line" name="line_21">
<property name="geometry">
<rect>
<x>1178</x>
<y>0</y>
<width>20</width>
<height>30</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
<widget class="caFrame" name="caframe_3">
<property name="geometry">
<rect>
<x>340</x>
<y>0</y>
<width>101</width>
<height>40</height>
</rect>
</property>
<property name="visibility">
<enum>caFrame::IfZero</enum>
</property>
<property name="channel" stdset="0">
<string notr="true">Expert-Mode</string>
</property>
<widget class="caMessageButton" name="camessagebutton_136">
<property name="geometry">
<rect>
<x>60</x>
<y>0</y>
<width>40</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Start</string>
</property>
<property name="fontScaleMode">
<enum>EPushButton::None</enum>
</property>
<property name="channel" stdset="0">
<string notr="true">AGEBD-MASTER@@agebd_env_suffix_upper@@:$(service)-START-REQ</string>
</property>
<property name="label">
<string notr="true">Start</string>
</property>
<property name="background">
<color>
<red>160</red>
<green>160</green>
<blue>160</blue>
</color>
</property>
<property name="disableChannel" stdset="0">
<string>CONTROL-ONOFF</string>
</property>
<property name="releaseMessage">
<string notr="true"/>
</property>
<property name="pressMessage">
<string notr="true">1</string>
</property>
</widget>
<widget class="caMessageButton" name="camessagebutton_91">
<property name="geometry">
<rect>
<x>10</x>
<y>0</y>
<width>40</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>KILL</string>
</property>
<property name="fontScaleMode">
<enum>EPushButton::None</enum>
</property>
<property name="channel" stdset="0">
<string notr="true">AGEBD-MASTER@@agebd_env_suffix_upper@@:$(service)-ABORT-REQ</string>
</property>
<property name="label">
<string notr="true">KILL</string>
</property>
<property name="background">
<color>
<red>148</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="disableChannel" stdset="0">
<string>CONTROL-ONOFF</string>
</property>
<property name="releaseMessage">
<string notr="true"/>
</property>
<property name="pressMessage">
<string notr="true">1</string>
</property>
</widget>
</widget>
<widget class="caFrame" name="caframe_4">
<property name="geometry">
<rect>
<x>80</x>
<y>0</y>
<width>41</width>
<height>30</height>
</rect>
</property>
<property name="visibility">
<enum>caFrame::IfZero</enum>
</property>
<property name="channel" stdset="0">
<string notr="true">Expert-Mode</string>
</property>
<widget class="caMessageButton" name="camessagebutton_123">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>30</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
</font>
</property>
<property name="text">
<string>↺</string>
</property>
<property name="fontScaleMode">
<enum>EPushButton::None</enum>
</property>
<property name="channel" stdset="0">
<string notr="true">$(IOC):RESTART</string>
</property>
<property name="label">
<string notr="true">↺</string>
</property>
<property name="background">
<color>
<red>160</red>
<green>160</green>
<blue>160</blue>
</color>
</property>
<property name="disableChannel" stdset="0">
<string/>
</property>
<property name="releaseMessage">
<string notr="true"/>
</property>
<property name="pressMessage">
<string notr="true">1</string>
</property>
</widget>
</widget>
<widget class="caFrame" name="caframe_5">
<property name="geometry">
<rect>
<x>1240</x>
<y>0</y>
<width>71</width>
<height>40</height>
</rect>
</property>
<property name="visibility">
<enum>caFrame::IfZero</enum>
</property>
<property name="channel" stdset="0">
<string notr="true">Expert-Mode</string>
</property>
<widget class="caMessageButton" name="camessagebutton_96">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>70</width>
<height>30</height>
</rect>
</property>
<property name="channel" stdset="0">
<string notr="true">AGEBD-ALH@@agebd_env_suffix_upper@@:$(service)-GUIRELOAD</string>
</property>
<property name="label">
<string notr="true">Reload</string>
</property>
<property name="background">
<color>
<red>160</red>
<green>160</green>
<blue>160</blue>
</color>
</property>
<property name="disableChannel" stdset="0">
<string/>
</property>
<property name="releaseMessage">
<string notr="true"/>
</property>
<property name="pressMessage">
<string notr="true">1</string>
</property>
</widget>
</widget>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>caChoice</class>
<extends>QWidget</extends>
<header>caChoice</header>
</customwidget>
<customwidget>
<class>caRelatedDisplay</class>
<extends>QWidget</extends>
<header>caRelatedDisplay</header>
</customwidget>
<customwidget>
<class>caMessageButton</class>
<extends>QPushButton</extends>
<header>caMessageButton</header>
</customwidget>
<customwidget>
<class>caFrame</class>
<extends>QFrame</extends>
<header>caFrame</header>
<container>1</container>
</customwidget>
<customwidget>
<class>caLabel</class>
<extends>QLabel</extends>
<header>caLabel</header>
</customwidget>
<customwidget>
<class>caLed</class>
<extends>QWidget</extends>
<header>caLed</header>
</customwidget>
<customwidget>
<class>caLineEdit</class>
<extends>QLineEdit</extends>
<header>caLineEdit</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>