<?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 (0–3)"/>
    <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 0–1) -->
  <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>
