wrps-demo-kit/04-scada/hmi
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
..
build_display.py feat(scada): CI Server tag database, historian, displays 2026-09-02 17:16:18 +10:00
build_tagtest.py feat(scada): CI Server tag database, historian, displays 2026-09-02 17:16:18 +10:00
check_layout.py feat(scada): CI Server tag database, historian, displays 2026-09-02 17:16:18 +10:00
component-kit.md feat(scada): CI Server tag database, historian, displays 2026-09-02 17:16:18 +10:00
DEPLOY.md feat(scada): CI Server tag database, historian, displays 2026-09-02 17:16:18 +10:00
item-ids.csv feat(scada): CI Server tag database, historian, displays 2026-09-02 17:16:18 +10:00
item-ids.meta.json feat(scada): CI Server tag database, historian, displays 2026-09-02 17:16:18 +10:00
point_format.py feat(scada): CI Server tag database, historian, displays 2026-09-02 17:16:18 +10:00
README.md feat(scada): CI Server tag database, historian, displays 2026-09-02 17:16:18 +10:00
render_preview.py feat(scada): CI Server tag database, historian, displays 2026-09-02 17:16:18 +10:00

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.