Implemented epics read/write

This commit is contained in:
Martino Ferrari
2026-04-27 12:42:10 +02:00
parent b76b7f0ba8
commit 1bda25454b
32 changed files with 1553 additions and 281 deletions
+224
View File
@@ -0,0 +1,224 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
uopi EPICS test panel
Covers: textview · gauge · barh · barv · led · multiled · setvalue · button ×3 modes · plot ×4 types
Signals: epics (UOPI:*) · synthetic (temp_moving_avg, temp_derivative, noise_lowpass, etc.)
Canvas: 1380 × 720
-->
<interface id="epics_test" name="EPICS Test Panel" version="1" width="1380" height="720">
<!-- ════════════════════════ SECTION LABELS ════════════════════════════ -->
<widget type="textlabel" id="lbl_monitor" x="10" y="6" w="160" h="22">
<option key="label" value="PROCESS VALUES"/>
<option key="fontSize" value="11"/>
<option key="color" value="#64748b"/>
</widget>
<widget type="textlabel" id="lbl_controls" x="10" y="302" w="120" h="22">
<option key="label" value="CONTROLS"/>
<option key="fontSize" value="11"/>
<option key="color" value="#64748b"/>
</widget>
<widget type="textlabel" id="lbl_trends" x="10" y="392" w="120" h="22">
<option key="label" value="TRENDS &amp; ANALYSIS"/>
<option key="fontSize" value="11"/>
<option key="color" value="#64748b"/>
</widget>
<!-- ════════════════════════ TEXT VIEWS ══════════════════════════════ -->
<!-- textview: quality dot, live value, unit from EPICS metadata -->
<!-- Temperature: analog float, alarm chain LOW/HIGH/LOLO/HIHI -->
<widget type="textview" id="tv_temp" x="10" y="28" w="220" h="58">
<signal ds="epics" name="UOPI:TEMP"/>
<option key="label" value="Temperature"/>
</widget>
<!-- Pressure: sawtooth, different unit (bar) -->
<widget type="textview" id="tv_pressure" x="244" y="28" w="210" h="58">
<signal ds="epics" name="UOPI:PRESSURE"/>
<option key="label" value="Pressure"/>
</widget>
<!-- Flow: noisy signal, 5 Hz update -->
<widget type="textview" id="tv_flow" x="468" y="28" w="210" h="58">
<signal ds="epics" name="UOPI:FLOW"/>
<option key="label" value="Flow Rate"/>
</widget>
<!-- Counter: monotonically increasing integer -->
<widget type="textview" id="tv_counter" x="692" y="28" w="200" h="58">
<signal ds="epics" name="UOPI:COUNTER"/>
<option key="label" value="Event Counter"/>
<option key="unit" value="none"/>
</widget>
<!-- Message: string PV — tests string display and write -->
<widget type="textview" id="tv_message" x="906" y="28" w="320" h="58">
<signal ds="epics" name="UOPI:MESSAGE"/>
<option key="label" value="Operator Msg"/>
</widget>
<!-- ════════════════════════ GAUGES ══════════════════════════════════ -->
<!-- gauge: SVG arc, displays LOPR/HOPR range, alarm colour zones -->
<!-- Temperature gauge: full alarm chain visible as colour zones -->
<widget type="gauge" id="g_temp" x="10" y="100" w="170" h="170">
<signal ds="epics" name="UOPI:TEMP"/>
<option key="label" value="Temperature"/>
<option key="min" value="0"/>
<option key="max" value="100"/>
<option key="thresholdHigh" value="78"/>
<option key="thresholdLow" value="20"/>
</widget>
<!-- Pressure gauge -->
<widget type="gauge" id="g_pressure" x="194" y="100" w="150" h="150">
<signal ds="epics" name="UOPI:PRESSURE"/>
<option key="label" value="Pressure"/>
<option key="min" value="0"/>
<option key="max" value="10"/>
<option key="thresholdHigh" value="8"/>
</widget>
<!-- ════════════════════════ BAR WIDGETS ═════════════════════════════ -->
<!-- Temperature horizontal bar: full-range with setpoint reference -->
<widget type="barh" id="bh_temp" x="360" y="100" w="300" h="52">
<signal ds="epics" name="UOPI:TEMP"/>
<option key="label" value="Temperature"/>
<option key="min" value="0"/>
<option key="max" value="100"/>
</widget>
<!-- Deviation from setpoint: symmetric range, can go negative -->
<widget type="barh" id="bh_dev" x="360" y="166" w="300" h="52">
<signal ds="epics" name="UOPI:TEMP_DEVIATION"/>
<option key="label" value="ΔT from SP"/>
<option key="min" value="-60"/>
<option key="max" value="60"/>
</widget>
<!-- Flow vertical bar -->
<widget type="barv" id="bv_flow" x="360" y="232" w="50" h="56">
<signal ds="epics" name="UOPI:FLOW"/>
<option key="label" value="Flow"/>
<option key="min" value="0"/>
<option key="max" value="100"/>
</widget>
<!-- ════════════════════════ LED INDICATORS ══════════════════════════ -->
<!-- Beam On/Off LED — binary bo PV, tests ZNAM/ONAM string display -->
<widget type="led" id="led_beam" x="676" y="100" w="90" h="90">
<signal ds="epics" name="UOPI:BEAM_ON"/>
<option key="label" value="Beam On"/>
<option key="condition" value="value>0"/>
</widget>
<!-- Interlock LED — computed calc, MAJOR alarm when fired -->
<widget type="led" id="led_ilck" x="780" y="100" w="90" h="90">
<signal ds="epics" name="UOPI:INTERLOCK"/>
<option key="label" value="Interlock"/>
<option key="condition" value="value>0"/>
</widget>
<!-- ════════════════════════ MULTI-LED ═══════════════════════════════ -->
<!-- multiled: bitset display — STATUS_BITS is an 8-bit rotating word -->
<widget type="multiled" id="ml_status" x="676" y="204" w="360" h="64">
<signal ds="epics" name="UOPI:STATUS_BITS"/>
<option key="label" value="Status Bits"/>
<option key="bits" value="8"/>
</widget>
<!-- ════════════════════════ CONTROLS ════════════════════════════════ -->
<!-- Setpoint: ao PV, numeric write, unit from EPICS metadata -->
<widget type="setvalue" id="sv_sp" x="10" y="324" w="240" h="56">
<signal ds="epics" name="UOPI:SETPOINT"/>
<option key="label" value="Temp Setpoint"/>
</widget>
<!-- Mode selector: mbbo enum, write 0=Idle 1=Running 2=Fault 3=Maint -->
<widget type="setvalue" id="sv_mode" x="264" y="324" w="220" h="56">
<signal ds="epics" name="UOPI:MODE"/>
<option key="label" value="Mode (03)"/>
<option key="unit" value="none"/>
</widget>
<!-- String write: stringout PV, freeform text -->
<widget type="setvalue" id="sv_msg" x="498" y="324" w="280" h="56">
<signal ds="epics" name="UOPI:MESSAGE"/>
<option key="label" value="Operator Message"/>
<option key="unit" value="none"/>
</widget>
<!-- Button ONE-SHOT: writes 1 to RESET_CMD; IOC auto-resets after 1 s -->
<widget type="button" id="btn_reset" x="794" y="324" w="160" h="56">
<signal ds="epics" name="UOPI:RESET_CMD"/>
<option key="label" value="Reset"/>
<option key="value" value="1"/>
<option key="mode" value="oneshot"/>
</widget>
<!-- Button SET-RESET: writes 1, then uopi reverts to 0 after 2 s -->
<widget type="button" id="btn_latch" x="968" y="324" w="200" h="56">
<signal ds="epics" name="UOPI:LATCH"/>
<option key="label" value="Latch (2 s)"/>
<option key="value" value="1"/>
<option key="resetValue" value="0"/>
<option key="resetTime" value="2"/>
<option key="mode" value="setReset"/>
</widget>
<!-- Button PERSISTENT: toggles BEAM_ON; stays pressed while value=1 -->
<widget type="button" id="btn_beam" x="1182" y="324" w="186" h="56">
<signal ds="epics" name="UOPI:BEAM_ON"/>
<option key="label" value="Beam Enable"/>
<option key="value" value="1"/>
<option key="resetValue" value="0"/>
<option key="mode" value="persistent"/>
</widget>
<!-- ════════════════════════ PLOTS ═══════════════════════════════════ -->
<!-- Timeseries: TEMP + moving average + derivative (3 signals, synthetic) -->
<widget type="plot" id="plot_temp" x="10" y="414" w="480" h="290">
<signal ds="epics" name="UOPI:TEMP"/>
<signal ds="synthetic" name="temp_moving_avg"/>
<signal ds="synthetic" name="temp_derivative"/>
<option key="plotType" value="timeseries"/>
<option key="timeWindow" value="120"/>
<option key="yMin" value="auto"/>
<option key="yMax" value="auto"/>
<option key="legend" value="bottom"/>
</widget>
<!-- Histogram: noise distribution (expect uniform 01) -->
<widget type="plot" id="plot_hist" x="504" y="414" w="290" h="290">
<signal ds="epics" name="UOPI:NOISE"/>
<option key="plotType" value="histogram"/>
<option key="legend" value="none"/>
</widget>
<!-- Timeseries: raw noise vs lowpass filtered (synthetic) -->
<widget type="plot" id="plot_noise" x="808" y="414" w="380" h="290">
<signal ds="epics" name="UOPI:NOISE"/>
<signal ds="synthetic" name="noise_lowpass"/>
<option key="plotType" value="timeseries"/>
<option key="timeWindow" value="30"/>
<option key="legend" value="bottom"/>
</widget>
<!-- Pressure sawtooth — bar chart (latest value per signal) -->
<widget type="plot" id="plot_bar" x="1202" y="414" w="166" h="290">
<signal ds="epics" name="UOPI:PRESSURE"/>
<signal ds="epics" name="UOPI:FLOW"/>
<option key="plotType" value="bar"/>
<option key="legend" value="bottom"/>
</widget>
</interface>