wrps-demo-kit/04-scada/hmi/README.md
Clio Liu 947f632d7f feat(scada): CI Server tag database, historian, displays
The old 05-scada/, restructured around the distinction its README never
drew: configuration is deployed with dssqld, displays are deployed by
file copy. Conflating the two is what made the folder confusing.

  modbus_points/          the tag database - named for the protocol,
                          since CI Server configures others differently
  modbus_points/historian/  3 groups, 49 bindings - HAND-MADE, no
                          generator, and drifted from the server
  hmi/                    displays and their generator
  ciserver-backup-2026-08/  outdated exports, evidence only, never import
  QUICKLOAD.md            dssqld export/import, the 5 classes, the import
                          order, and why an item import kills every display
  README.md               the chain end to end, and the not-updating triage

Verified during the move - the whole chain is reproducible:
  scada-points.csv and all three .qli regenerate byte-identically
  all six displays build clean

Removed the K offset machinery from build_display.py, item-ids.meta.json
and DEPLOY.md. K was a consistency check on measured ids, not a source of
them, and diagnosing a dead screen by arithmetic is wasted effort when
validating the display in CI Server's Editor Module fixes it outright.
The guidance now leads with that one action.

Recorded, not fixed: the repo's historian config disagrees with the
2026-08 CI Server export - WRPS_THIRTY_SEC and a FIVE_SECONDS group exist
on the server and not here. cicore1 was unreachable during this audit, so
which is correct is unknown.

Not carried across: __pycache__, out/*.xml, and the top-level
WRPS_Overview.xml that was tracked despite .gitignore declaring the
display XMLs to be build output.
2026-09-02 17:16:18 +10:00

146 lines
7.6 KiB
Markdown

# 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.