# hmi — what CI Server can draw, and the kit we build with

Study of the live CI Server deployment copied to
`99-reference/ciserver-hmi-deployment/`: 53 components, 3130
symbols (177 of them the AOG standard set), 74 displays, 2 layouts.

> **`C:\Users\Public\Yokogawa\tls` is reference only.** Never edit it. Everything
> is authored in this repo and handed over for the user to deploy.

## 1. Components — the primitives a display is made of

| Group | Components |
|---|---|
| Drawing | `Rectangle` `Ellipse` `Arc` `Line` `Polygon` `Spline` `Text` `Icon` |
| Structure | `Display` `GraphicSet` `Symbol` `SymbolInstance` `VisibilityGroup` `VisualizationLayer` `VisualizationParameter` `Link` |
| Data display | `Number` `DataBar` `CircularScale` `RectangularScale` `Radial` `MicroTrend` `Chart` `DtsChart` |
| Input | `JButton` `JToggleButton` `JCheckBox` `JRadioButton` `JComboBox` `JSlider` `JSpinner` `JFormattedNumberField` `JFormattedTextField` `JTextArea` `JDateTimeField` `JList` `JNavigationTree` |
| System | `AlarmOverview` `ShelvedOverview` `BlockedItems` `AlarmSound` `Playback` `Reporting` `MapViewer` `PDFViewer` `DatasetTable` `DatasetForm` `ScriptedFunction` |

So the earlier claim that CI View was "rectangles and text only" was wrong — that
was an artefact of the *Straddle* screens, which happen to use little else.
Ellipses, lines, polygons, trends, gauges and real input widgets are all available.

## 2. AOG — the standard symbol library

`symbols/AOG_*.xml` is Yokogawa's **Advanced Operating Graphics** set: a
high-performance HMI standard in the ISA-101 tradition. Relevant here:

| Purpose | Symbol |
|---|---|
| Analog value | `AOG_ProcessIndicator`, `AOG_NumberIndicator` |
| Typed instrument | `AOG_IndicatorLevel` `AOG_IndicatorFlow` `AOG_IndicatorPressure` `AOG_IndicatorTemperature` |
| Bar / needle | `AOG_VerticalBarIndicator` `AOG_HorizontalBarIndicator` `AOG_*NeedleIndicator` `AOG_RadialNeedleIndicator` |
| Digital state | `AOG_OnOffIndicator` `AOG_AlarmIndicator` `AOG_TextIndicator` `AOG_ManualIndicator` |
| Equipment | `AOG_Pump` `AOG_PumpSimple` `AOG_PumpWithOutlet` `AOG_Motor` `AOG_Tank` `AOG_Vessel` `AOG_AtmosphericTank` |
| Valves | `AOG_CheckValve` `AOG_Horizontal2WayValve` `AOG_VerticalOnOffValve` `AOG_ButterflyValve` `AOG_BlockValveStation` |
| Instrument bubble | `AOG_Instrument` `AOG_Transmitter` |
| Faceplate | `AOG_Faceplate` `AOG_FP_Frame` `AOG_FP_PVValue` `AOG_FP_SVValue` `AOG_FP_Mode` `AOG_FP_Status` `AOG_FP_BarIndicator` |
| Trend | `AOG_Trend` `AOG_TrendIndicator` |
| Screen furniture | `AOG_DisplayTitle` `AOG_SelectionBox` `AOG_NavigationSelectionBox` `AOG_TagNameComponent` |

An `AOG_O*` variant exists for most (`AOG_OPump`, `AOG_ONumberIndicator` …).

### The parameter contract — this is what standardisation means here

Every dynamic AOG symbol takes the same external parameters:

```
item                 the SCADA item to display        (AID.WRPS.STN.LEVEL)
setPointItem         optional companion item
tagName              label, with alwaysShowTagName / neverShowTagName
format               numeric format
showBackground       draw the indicator box
showAlarmIndicator   built-in alarm annunciation
selectable           can the operator click it
displayToActivate    display opened on click  <- this is how faceplates work
```

Two consequences worth stating plainly:

1. **Analog values are consistent by construction.** Every one is an
   `AOG_ProcessIndicator`; nothing is hand-drawn, so nothing can drift.
2. **Faceplates are separate displays**, not overlays. A symbol names one in
   `displayToActivate`. `AOG_ItemFaceplate` and `AOG_ObjectFacePlate` already
   exist and can be used as-is, or copied and specialised for a pump.

### Ready-made displays

`displays/AOG_displays/` includes `AOG_DisplayTemplate` (start a new display from
it), `AOG_Style` (the colour tokens), `AOG_ItemFaceplate`, `AOG_ItemTuningPanel`,
`AOG_AlarmBanner`, `AOG_AlarmCurrent`, `AOG_MenuMain`, `AOG_SetNumberPV/SV/SH/SL`
(the standard numeric-entry popups — use these for setpoint writes rather than
building an entry field).

## 3. Two styles exist on this system — pick one

| | AOG standard | Site style (Straddle screens) |
|---|---|---|
| Ground | `#E3E3E3` light grey | `#171B22` near-black |
| Panels | `#F0F0F0` / `#F2F2F2` | `#262D38` / `#333B47` |
| Text | `#404040` / `#6D6D6D` | `#C8D0DA` |
| Accent | none — colour is reserved | `#5FB8D0` cyan |
| Alarm | `#FF0000` `#FFA500` `#FFFF00` | `#D65B5B` |
| Built from | AOG symbols | hand-drawn rectangles + text |

The AOG palette follows the high-performance HMI convention: a grey plant, and
**colour only where something is abnormal**. The site's own Straddle screens are a
custom dark theme that does not use the AOG library at all — no display in the
deployment instantiates a single `AOG_*` symbol.

**Recommendation: AOG.** It is the product standard, it brings the faceplate
machinery and alarm annunciation for free, and its parameter contract is what
keeps every indicator identical. The cost is that the demo will not match the
Straddle screens an operator may already know.

## 4. Decision: our own kit, AOG as reference only

Settled 2026-08-14 with the user:

- **Build our own components**, not AOG instances — only what this project needs.
  AOG's *parameter contract* is the thing worth copying, not its artwork.
- **Light theme, but not AOG's.** The customer reads AOG as dated; the cause is
  the bevelled 3D symbols and mid-grey ground, so the kit is flat, square, hairline
  bordered, white on cool neutral.
- **16:9**, and **operators may write** setpoint, command and simulation items.

The kit is specified in `component-kit.md`. The table below is superseded by it
and kept only to show which AOG symbol each of our components was modelled on.

## 5. AOG reference for each component we built

What each element of the display is built from, so the same thing always looks the
same:

| Element | Component | Bound to |
|---|---|---|
| Title bar | `AOG_DisplayTitle` | — |
| Wet well | `AOG_Tank` + `AOG_VerticalBarIndicator` | `STN.LEVEL` |
| Level, flows, pressures, speed | `AOG_ProcessIndicator` | `STN.*`, `PU30x.*` |
| Level switches, run/avail/trip | `AOG_OnOffIndicator` | `PU30x.*`, `STN.*` |
| Pumps | `AOG_Pump`, `displayToActivate` = pump faceplate | `PU30x.RUNNING` |
| Check / isolation valves | `AOG_CheckValve`, `AOG_Horizontal2WayValve` | static |
| Instrument bubbles | `AOG_Instrument` | tag text |
| Setpoint entry | `AOG_SetNumberSV` popup | `SP.*` |
| Pump faceplate | copy of `AOG_ItemFaceplate` | `PU30x.*` |
| Buttons (mode, commands, simulation) | `AOG_SelectionBox` / `JButton` | `SP.MODE`, `SP.CMD_WORD`, `SIM.*` |

## Scripts in this directory

| Command | What it does |
|---|---|
| `python build_display.py` | Builds the three displays into `out/`. **Refuses to build if the item ids cannot be proven current.** |
| `python build_display.py --harvest <saved.xml>` | Re-calibrates the item ids from a display CI View saved, and records provenance |
| `python build_display.py --verify <saved.xml>` | Compares CI Server's own ids against what the build emits; exit 1 on any mismatch |
| `python build_tagtest.py` | Builds the diagnostic display that lists every item |
| `python check_layout.py` | Reports text that collides with other text; exit 1 on any collision |

The two `--` modes exist because of the failure that keeps recurring: an item
id that no longer matches CI Server binds silently to nothing, and the screen
looks fine. `DEPLOY.md` has the ritual.

## Status

Study complete; nothing built yet. The layout is under review as a mockup — see
the preview link in the conversation, and `04-scada/hmi/` will hold the display
XML once the style question above is settled.
