# Display generator (CI-Eng-Sample operator HMI) A small Python tool that **writes the CI-Eng-Sample display files** (`..\CIENG_*.xml`) instead of drawing them in the Edit Module. The XML is the same format the Edit Module saves (display definition 1.3.0.0, *HTML display* on), so the files run in the Operator Interface (desktop) and in the HTML display (web), and they can still be opened and changed in the Edit Module afterwards (but a later generator run overwrites such changes). Built and tested with CI Server R1.03.00, Python 3.12 and Pillow, 2026-10-06. ## Files | File | Purpose | |---|---| | `cixml.py` | Library: a `Display` class with one method per component (rectangle, text, number, number/text/date-time field, button, toggle, check box, slider, spinner, combo box, data bar, scales, arc / ring gauge, lamp, alarm overview, report, micro trend, trend), item connections, linear and threshold transformations, actions (open / close display, set item value, execute command) and the dark colour theme | | `build.py` | The eight sample displays: `CIENG_Header`, `CIENG_Overview`, `CIENG_Control`, `CIENG_Trends`, `CIENG_Alarms`, `CIENG_System`, `CIENG_AlarmBanner` (layout `CIENG_Operator`) and `CIENG_TankFaceplate` (layout `CIENG_Popup`) | ## Use ``` python build.py (writes ..\CIENG_*.xml) python build.py (writes into another folder) ``` Then deploy with `..\deploy_displays.cmd`. Requirements: Python 3, Pillow (`pip install pillow`; used to measure text widths with the Windows fonts Segoe UI and Consolas). Without Pillow it falls back to an estimate and left/right-aligned texts land slightly off. ## How it works (rules learned on R1.03.00) - Positions are boxes (left, top, width, height); the file stores the centre plus half sizes. - Texts and numbers use *keep original size*: the HTML export draws them at their font size centred on the box (otherwise the text is stretched to the box). The box is therefore shrunk to the measured text width for left / right alignment. - Rectangle rounding is stored as a fraction (0..1) of the half size (values above 1 draw an ellipse in the web client). - The tab displays are designed 1880 x 680 and stretched to 1880 x 760 (`design_h`): panels, bars, lists and trends grow, texts / controls / round shapes keep their size and only move. - Ring gauges are symmetric about the horizontal axis (gap on the right, value growing from 9 o'clock up and down) because the desktop draws arc angles mirrored compared with the web. - The live-data button runs `C:\Users\Public\CI-Eng-Sample\feed\cieng_feed_start.cmd` on the server (`FEED_START` in `build.py`; installed by `..\..\feed\install_feed.ps1`). - Trend: `trend(..., web_spares=True)` pads a trend to 50 pens so it also draws on the web; the sample trend uses `web_spares=False` (2 pens, clean desktop hairline, no line on the web).