Compare commits

..

No commits in common. "ecf1f226f2da38222cb8feede0b0689974bf2cd6" and "a298fdebc16ccaeea813c9ebf97e435b3ee728aa" have entirely different histories.

43 changed files with 5585 additions and 1952 deletions

View file

@ -35,8 +35,7 @@ switching anything off.
`ITEM_DF` / `SUB_ITEM_DF` / `EXTERNAL_ALARM_DF` field `AUDIT_INFO` (default 0). It switches the
`ITEM.*` / `SUB-ITEM.*` events raised by ITEM Service for **operator writes**. Verified on
`CI-Eng-Sample.PUMP1.MODE` with the buttons on display `CIENG_Tank` (2026-10-01; re-checked
2026-10-06 with *Manual* / *Auto* on `CIENG_Control`: same events, user and old / new value):
`CI-Eng-Sample.PUMP1.MODE` with the buttons on display `CIENG_Tank`:
- `AUDIT_INFO` 1: a button write 0 → 1 stored `ITEM` `VALUE` `MODIFY` `OPER-INTERFACE`, user
`ADMIN`, old 0 / new 1, plus `ITEM` `STATUS` `MODIFY` (13 → 9).
- `AUDIT_INFO` 0: the write 1 → 0 left **no** audit record.

View file

@ -41,11 +41,8 @@ NAME,DESCRIPTION,ACTION_NAME_1,ACTION_NAME_2,ACTION_NAME_3,ACTION_NAME_4
Required: `NAME` (≤ 32) and `AUTH_GROUP` (an existing group). Optional: `DESCRIPTION`,
`PROCESS_AREAS` (e.g. `"1-999"`), `LOGOFF_TIMEOUT` (minutes, 0–999), `INITIAL_DISPLAY`,
`LOCALE`, `ENTERPRISE`, `LAYOUT`, playback fields. Password: without a `PASSWORD` field the user
is created **without any password set** and every logon fails with *DSS-E-UNK_USER Unknown user
name/password combination*; set the password in the Engineering Module (the user does this, not
Claude). A user with an **empty** password is created by giving `PASSWORD ""` explicitly
(tested 2026-10-06, sample user `CIENG`: logon on desktop and web). Template:
`LOCALE`, `ENTERPRISE`, playback fields. A password is **not** required on import; set it in
the Engineering Module (the user does this, not Claude). Template:
```
@FIELDS
@ -84,20 +81,6 @@ NAME
## Test system (2026-09-30)
Group `CIENG_VIEWER` and user `CIENG_TEST` (no `PASSWORD` field, logoff 15 min) loaded with 0
errors, exported back as defined, then removed (1 + 1 removed, 0 errors). Logon was not tried;
such a user cannot log on (see *User*). The group is part of CI-Eng-Sample.
## Sample user (2026-10-06)
`examples/CI-Eng-Sample/08b_user_df.qli`: user `CIENG`, `PASSWORD ""`, factory group `OPERATOR`,
`LAYOUT` `CIENG_Operator`, `INITIAL_DISPLAY` `CIENG_Overview`; logs on to that layout on the desktop
and on the web (no `?l=` needed). Removal (`85_remove_auth_group_df.qli`) removes the user before
the group.
**Log out all sessions of a user before removing its group**: while a session is open the group
is still referenced in `USER_VAL` and `dssqld -r` fails with *DSSP-E-NODEL … in dataset
USER_VAL*; logging out did not free it at once, and a retry in that state stopped the process
`DSSSDA03` (*DUR-F-BAD_SIZE, Negative size not allowed*; later requests failed with
*DUR-F-UNKNOWN_ATT*) until CI Server was restarted (2026-10-06, ISS-073). After a restart the
group was removed without error. `USER_VAL` exports only its header (no way to list sessions).
Group `CIENG_VIEWER` and user `CIENG_TEST` (no password, logoff 15 min) loaded with 0 errors,
exported back as defined, then removed (1 + 1 removed, 0 errors). The group is part of
CI-Eng-Sample; the sample creates no users.

View file

@ -38,11 +38,10 @@ Rules:
| Task | File | Status |
|---|---|---|
| Build a display in the Edit Module (text, number field, alarm overview, trend) and check the saved XML | `tasks/create-display.md` | verified |
| Write display XML directly / with the sample generator (text size, rounding, arc angles, item attributes for the web, server-side command, alarm overview columns) | `tasks/create-display.md` (*Writing display XML directly*), `examples/CI-Eng-Sample/displays/generator/` | verified 2026-10-06 |
| Deploy / remove display files, export HTML, validate and search with `jwuiutl` | `tasks/deploy-displays.md` | verified |
| Trend: pen sources (history group, aggregates), every pen and chart setting, desktop vs HTML display, 50-pen web workaround (`add_trend_spares.ps1`), Micro Trend | `tasks/trend.md` | verified (desktop); web workaround verified; Micro Trend open (ISS-055) |
| Open and check a display in the browser (HTML display / Mobile Operator) | `tasks/deploy-displays.md` §4 | verified |
| Operator layouts (`Layouts.xml`): windows, menus, toolbars, frames, popups, kiosk screens; open displays in frames and layouts; every parameter and command, desktop vs web (§6) | `tasks/layouts.md` | verified (per-user layout 2026-10-06; dual screen from docs) |
| Operator layouts (`Layouts.xml`): windows, menus, toolbars, frames, popups, kiosk screens; open displays in frames and layouts; every parameter and command, desktop vs web (§6) | `tasks/layouts.md` | verified (dual screen, per-user layout from docs) |
| Dataset forms (`*Dia.xml`) and the form description language | R30 summary §3 | from docs |
| Symbols, parameters, actions, localisation, record/playback | C50 summary §1, §4, §5 | from docs |
| AOG library (styles, symbols, faceplates, templates) | C60 summary | from docs |

View file

@ -1,15 +1,14 @@
---
task: Build a display in the Edit Module and check the saved file
version: R1.03
source: IM 36K10C50-01EN §1.2, §1.7, §2, §4.8.1; practiced on CI-Eng-Sample (display CIENG_Tank) 2026-10-01; display XML written by the sample generator and checked on desktop and web 2026-10-02 to 2026-10-06 (installed web client code, component definitions in DEPLOY\components)
source: IM 36K10C50-01EN §1.2, §1.7, §2, §4.8.1; practiced on CI-Eng-Sample (display CIENG_Tank) 2026-10-01
status: verified
---
# Build a display (Edit Module)
The user draws; Claude gives the steps and checks the result. The sample displays
`examples/CI-Eng-Sample/displays/CIENG_*.xml` are not drawn but written by a generator
(`displays/generator/`); *Writing display XML directly* lists the rules they follow.
The user draws; Claude gives the steps and checks the result. Example = the sample display
`examples/CI-Eng-Sample/displays/CIENG_Tank.xml`.
## Steps for the user
@ -39,8 +38,8 @@ grep -n "<html>\|<width>\|<height>\|itemName\|itemId\|<source" <DisplayName>.xml
- `<html>true</html>` = HTML mode; `<width>`/`<height>` must be set for the HTML display.
- Item connections: `<itemName>` + `<itemId>` (node.group.number…); trend pens:
`<source type="sourceID" uri="ci:/item/<item>"/>` (`uri=""` = empty pen).
- Write a fixed value with a button (verified in the HTML display, buttons *Manual* / *Auto* on
the former `CIENG_Tank` and, since 2026-10-06, on `CIENG_Control`): `<button>` › `<data>` › `<action type="actionSetItemAttribute">` with
- Write a fixed value with a button (verified in the HTML display, `CIENG_Tank` *Manual (0)* /
*Auto (1)*): `<button>` › `<data>` › `<action type="actionSetItemAttribute">` with
`<event type="event" event="On action"/>`, `<filter type="filter"><value>1.0</value></filter>`
and a `<connection>` with `<direction>2</direction>`, `<itemName>`, `<itemAttribute>ItemValue`
(the factory popups use `ItemValueOW`, presumably the overwrite variant like `itmval -o`; not tested). The factory popup `AOG_SetNumberPV` uses the
@ -52,25 +51,6 @@ grep -n "<html>\|<width>\|<height>\|itemName\|itemId\|<source" <DisplayName>.xml
Sample displays therefore carry no `<itemId>`; for displays made in the Edit Module, reconnect
or remove the ids after reloading items (ISS-052).
## Writing display XML directly (verified 2026-10-02 to 2026-10-06)
The Edit Module stores one element per component (`<text>`, `<number>`, `<rectangle>`, `<arc>`,
`<button>`, `<slider>` …, names as in `DEPLOY\components\*.xml`), its position as centre plus half
sizes, and the connections in `<data>`. Files written by hand or by a script load in the Edit
Module, the Operator Interface and the HTML display, if these rules are kept (sample generator:
`examples/CI-Eng-Sample/displays/generator/`):
| Topic | Rule (R1.03.00) |
|---|---|
| Text / number size | With `<keepOriginalSize>false` the HTML export **scales the text to its box** (e.g. `scale(0.98, 3.80)` in a 40 px box); with `true` it is drawn at its font size, centred on the box (tested 2026-10-06) |
| Rectangle rounding | `roundingX` / `roundingY` are a **fraction 0..1** of the half width / height; values above 1 draw an ellipse, on the desktop and on the web (tested 2026-10-06) |
| Arc angles | `startAngle` / `extentAngle` in degrees **clockwise** from 3 o'clock (screen y down), negative values allowed; the same on both clients, fixed or connected (tested 2026-10-06: 0/90 = lower-right quarter) |
| Click on a shape | event `Clicked b1` (buttons: `On action`), e.g. an *Open display* action on a rectangle (2026-10-02) |
| Item attributes for the web | `ItemValue`, `ItemDesc`, `ItemStatusMnemonic`, `ItemUpdTime` (epoch seconds), `ItemHHL` / `ItemHL` / `ItemLL` / `ItemLLL` (limits), `ItemName` (micro trend pens), list in the web client code; `ItemDescription` does not exist (sample faceplate and Control tab, 2026-10-06) |
| Showing a time | number field with `<asDateTime>true` connected to `ItemUpdTime`; a `dateTimeField` shows the value on the web only when editable (2026-10-02/06) |
| Server-side command | `<action type="actionExecuteCommand">` with `<command>` and `<onServer>true</onServer>` runs on the CI Server node as the service account `CIX_PROCESS`, also from the web; a user in the factory group `OPERATOR` may use it (tested 2026-10-06, sample live-data *Start*) |
| Alarm overview | `autoFit` true in a tab that is hidden while loading squeezes all columns to ~0 px on the web: set `autoFit` false and give `column<Name>Width`; `column…Visible` for `AlarmAttribute` is an array property (a plain value fails the HTML export with `ClassCastException`); the empty part of the list stays **white** on both clients (no property; web: `jquery.dataTables.css` forces it); web rows are 20 px at a 14 px font (2026-10-02/06) |
## Verified (CIENG_Tank, 2026-10-01)
Text `CI-Eng-Sample Tank 1`, number field on `TANK1.LEVEL` (live: 72 → 61), alarm overview
@ -78,6 +58,4 @@ Text `CI-Eng-Sample Tank 1`, number field on `TANK1.LEVEL` (live: 72 → 61), al
`CI-Eng-Sample.TANK1.LEVEL [CIENG_SCAN10S]` = highest-priority storage group). In the HTML
display the trend drew no line: a trend needs 50 visible pens to draw on the web (ISS-041;
workaround and all trend settings in `trend.md`). The sample file is now padded with
`add_trend_spares.ps1` (49 spares) and draws in the browser too. `CIENG_Tank` was replaced by the
generated `CIENG_*` displays on 2026-10-06; they carry no `<itemId>` and found the recreated items
after a full `remove.cmd` / `load.cmd` cycle in a fresh session (2026-10-06).
`add_trend_spares.ps1` (49 spares) and draws in the browser too.

View file

@ -1,7 +1,7 @@
---
task: Deploy, remove, export, validate and search displays; open them in the browser
version: R1.03
source: IM 36K10C50-01EN §1.5; IM 36K10R30-01EN §1.1, §4; practiced on CI-Eng-Sample 2026-10-01; sample operator HMI (8 displays) and validate test 2026-10-06
source: IM 36K10C50-01EN §1.5; IM 36K10R30-01EN §1.1, §4; practiced on CI-Eng-Sample 2026-10-01
status: verified
---
@ -12,19 +12,17 @@ No admin rights needed (`C:\Users\Public\Yokogawa\tls\wap`). `jwuiutl.cmd` is in
## 1. Deploy / remove (sample scripts)
`examples/CI-Eng-Sample/displays/deploy_displays.cmd`: copies the 8 sample displays
(`CIENG_Header`, `CIENG_Overview`, … `CIENG_TankFaceplate`) to
`examples/CI-Eng-Sample/displays/deploy_displays.cmd`: copies `CIENG_Tank.xml` to
`%TLS_WAP_PATH%\cfg\operatorInterfaces\DEPLOY\displays\` and runs
`jwuiutl.cmd -e HTML -i -f DEPLOY <name>` for each (HTML into
`jwuiutl.cmd -e HTML -i -f DEPLOY CIENG_Tank` (HTML into
`%TLS_WAP_PATH%\mobileoperator\operatorInterfaces\DEPLOY\displays\`).
`remove_displays.cmd` deletes both files of each (close the displays in the Edit Module first).
Deploy after `load.cmd` so the items exist. Verified 2026-10-06: remove → 0 sample files left,
deploy → exactly the 8 XML + 8 HTML files.
`remove_displays.cmd` deletes both files (close the display in the Edit Module first).
Deploy after `load.cmd` so the items exist.
For another display: copy `<name>.xml` into `DEPLOY\displays` and export it the same way.
Displays with symbols also need the symbol files in `DEPLOY\symbols`.
## 2. Validate (re-saves the validated files)
## 2. Validate (report only)
```
cmd /c "jwuiutl.cmd -d -v -i -l <scratch>\validate.txt"
@ -35,13 +33,6 @@ display <name>:` with `Problem: <component>: Connected item is not found (<item>
`*** Display locked <name>` (open in the Edit Module or a stale `.lck`; `-u` unlocks — with
approval), displays saved by a newer version. `-vf` re-saves all displays — only with approval.
**`-v` also re-saves** (tested 2026-10-06: `jwuiutl -d -v -i -l … CIENG_Test` reported *No problems
found* and rewrote the file, 9 618 → 11 191 bytes: default values dropped, positions moved into
attributes - same content). Run it on copies, or redeploy the source files afterwards. On
2026-10-02 a validation of eight displays once hung on one of them and left `<name>.lck` and
`<name>.xml.tmp` (stop the `java` process, delete both files); not reproduced on 2026-10-06
(ISS-075).
## 3. Search
```

View file

@ -1,7 +1,7 @@
---
task: Configure operator layouts (Layouts.xml): windows, menus, toolbars, frames, popups; open displays in frames and layouts
version: R1.03
source: Layouts.readme (installed, %TLS_WAP_PATH%\cfg\operatorInterfaces\DEPLOY\layouts); IM 36K10R30-01EN §1, §4.7; IM 36K10C50-01EN §4.12; practiced with CI-Eng-Sample (layout CIENG_Operator) in the Operator Interface (desktop) and the HTML display 2026-10-01; parameter-by-parameter test (§6) on both clients 2026-10-02, web behaviour also read from the installed web client code (mobileoperator fasttools.min.js); sample operator HMI (layouts CIENG_Operator with a tab set and CIENG_Popup, user CIENG) and test layouts on both clients 2026-10-06
source: Layouts.readme (installed, %TLS_WAP_PATH%\cfg\operatorInterfaces\DEPLOY\layouts); IM 36K10R30-01EN §1, §4.7; IM 36K10C50-01EN §4.12; practiced with CI-Eng-Sample (layout CIENG_Operator) in the Operator Interface (desktop) and the HTML display 2026-10-01; parameter-by-parameter test (§6) on both clients 2026-10-02, web behaviour also read from the installed web client code (mobileoperator fasttools.min.js)
status: verified (parameters tested on desktop and web 2026-10-02 except print orientation/margins, playback, multi-screen positions and the maximumTabs limit for new tabs)
---
@ -27,8 +27,7 @@ reference is `Layouts.readme` in the same folder; `Layouts-original.xml` is the
toolbar commands) open their targets in a frame called `default`. At login the user profile's
*Initial display* replaces the `initialDisplay` of frame `default` (desktop; web: `?d=`).
- Layouts used by **both** clients must have the web-compatible shape (§6.1): per frame set at
most one `n*` division, and at most one nested frame set, placed in that `n*` slot. A `<tab>`
set must be the **last** child of its frame set (§6.6). Always
most one `n*` division, and at most one nested frame set, placed in that `n*` slot. Always
set `title` and `drawBorder`.
- Menu items whose command has an on/off state (`toolbar`, `statusline`, `playback record`)
**must** be `type="check"`: otherwise the Operator Interface fails at start
@ -90,11 +89,11 @@ reference is `Layouts.readme` in the same folder; `Layouts-original.xml` is the
|---|---|
| Button / component (Edit Module, *Actions* sheet → *Open display*) | Display, **Layout** (empty = current window), **Frame**, parameters; stored as `<action type="actionActivateDisplay">` with `<type … value="ActivateSpecific"/>`, `<display>`, `<layout>`, `<layoutFrame>` |
| Menu / toolbar | `navigate to <frame> <display>` (current window only) |
| Login | User profile *Layout* and *Initial display* (Engineering Module, Authorization > Users, or `USER_DF` `LAYOUT` / `INITIAL_DISPLAY`); empty layout = `default`. Verified 2026-10-06 with the sample user `CIENG` (layout `CIENG_Operator`, display `CIENG_Overview`): applied on the desktop **and** at web logon without `?l=` |
| Login | User profile *Layout* and *Initial display* (Engineering Module, Authorization > Users); empty layout = `default` (from docs; not changed on the test system) |
| HTML display | URL `?d=<display>&l=<layout>` |
| Script on a component | *Execute command* (client side) with `ACTION <layout command>`, e.g. `ACTION toggleSize 50,50,710x520`. Desktop only: the web client ignores it (2026-10-02). **One command at a time**: a second `ACTION` while the first runs fails with *IllegalStateException: A command is already being executed* (desktop, tested 2026-10-06 with two `ACTION reload all` on one button) |
| Script on a component | *Execute command* with `ACTION <layout command>`, e.g. `ACTION toggleSize 50,50,710x520` |
Verified behaviour (desktop, 2026-10-01, with the former sample layout `CIENG_Operator`): a button with that layout opened a **second window**
Verified behaviour (desktop): a button with layout `CIENG_Operator` opened a **second window**
(1600 × 900, own menu/toolbar/frames); buttons without layout opened their display in the main
frame of the current window; **Back** returned. A button with layout `popup` opened a separate
window: always on top, only a close button, sized to the display (`fitFrames`), and minimised
@ -120,10 +119,8 @@ setpoint dialogs).
The browser window is the main layout (its size and window options are ignored); other layouts
open as windows inside the page; print, look-and-feel and the debug key are not supported; pick
the layout with `&l=`, or let the user profile choose it (§3). Verified 2026-10-06:
`?l=CIENG_Operator` (and a plain logon as `CIENG`) showed the sample menu, navigation toolbar,
header, tab set and banner. The web client does not zoom displays (§6.1), so size them for the
browser window.
the layout with `&l=`. Verified: `?d=CIENG_Tank&l=CIENG_Operator` showed the sample menu,
toolbar, navigation frame and banner.
## 6. Parameter reference: desktop vs web (tested 2026-10-02)
@ -142,7 +139,7 @@ browser and in the web client code. "n/a" = the browser window is the main layou
| `n*` fractions (`2*,1*`) | **not honoured** (sizes follow the displays, e.g. 800:88 px) | every `n*` becomes the *main* panel; two `n*` overwrite each other, only the last display shows |
| Divisions per frame set | any | first = top/left, last = bottom/right, `n*` = main; more do not fit |
| Nested `frame-set` | anywhere, several | **always placed in the parent's main panel**; two nested sets, or one in an edge position, break the page (stays on *Loading…*) |
| Frame `zoom` (`fitDisplay`, `stretchDisplay`, `n%`) | applied, **except for frames inside a `<tab>`** (shown at 100 %; use `navigate to <frame> <display> fitDisplay|stretchDisplay`, tested 2026-10-06) | ignored (always 100 %) |
| Frame `zoom` (`fitDisplay`, `stretchDisplay`, `n%`) | applied | ignored (always 100 %) |
| `borderStyle` | drawn | only with `drawBorder="true"`; every value except `none` becomes a 1 px line |
| `stackSize` | honoured | honoured; default when missing = 1 |
| `zoomingAllowed="false"` | `zoom` commands on that frame do nothing | zoom not supported at all |
@ -175,7 +172,7 @@ browser and in the web client code. "n/a" = the browser window is the main layou
| Toolbar `left` / `right` | shown | **not shown** |
| Toolbar `bottom` | **not shown** (two layouts tried) | not shown |
| Toolbar item `combo`, `editableCombo`, `dropdownList` | shown | shown |
| Status line, all 8 types | shown | 7 shown; **`connectionState` breaks the layout**: at login `createStatusline` fails (*Cannot read properties of undefined (reading 'split')*) and no frame is created (tested 2026-10-06, ISS-068) |
| Status line, all 8 types | shown | shown |
### 6.4 Commands
@ -224,10 +221,7 @@ Factory pattern (works on both clients): a `<tab name="default">` holding frames
| Parameter | Desktop | Web |
|---|---|---|
| Tab labels | display title (the profile's initial display goes into the first tab) | display **title** (`_` until the display is loaded; verified 2026-10-06 with the sample tabs) |
| Frame `zoom` on a tab frame or on `<tab>` | ignored (100 %); `navigate to <tab frame> <display> stretchDisplay` applies it (sample: toolbar, menu and an *On entry* `ACTION` of the banner) | not supported |
| Active tab after login | the profile's initial display tab | the **last** tab whose display loaded; the sample banner (loaded after the tab set) opens `CIENG_Overview` in its tab with an *On entry* action to bring Overview to the front |
| Position of `<tab>` in its frame set | any | must be the **last** child: the tab click handler uses the last panel created in the frame set; tab set first (banner after it): labels stay `_`, *Unable to switch/load requested display*, tab clicks fail, the banner frame is missing (tested 2026-10-06, ISS-069) |
| Tab labels | display title (the profile's initial display goes into the first tab) | display name |
| `tabPosition` `bottom` / `left` | applied | **ignored** (always top) |
| `navigate to <tab set name> <display>` | replaces the display in the **active** tab; no new tab | — |
| `navigate to <tab frame name> <display>` | shows it in that tab | — |
@ -245,10 +239,3 @@ Interface restart required before the layout was found; desktop and web windows
above; F11 (`toggleSize fullScreen`) worked within the taskbar limits; after restarting the
Operator Interface the main window still used the factory `default` layout (Admin profile
unchanged).
2026-10-06 (sample operator HMI): `layout.ps1` add / remove / add with `CIENG_Operator` (tab set
in a nested frame set, last child) and `CIENG_Popup`; removal restored `Layouts.xml` byte for
byte. User `CIENG` lands in `CIENG_Operator` on Overview on both clients; ADMIN keeps the
default layout. Test layouts (removed again): tab set first in its frame set (web broken),
`maximumTabs` 8 with 2 tab frames (no extra tab on the web), status line with `connectionState`
(web broken).

View file

@ -1,25 +1,22 @@
---
task: Configure a trend (chart) component; what each setting does on the desktop and in the HTML display
version: R1.03
source: IM 36K10C50-01EN §2.27 (Trend, Tables 2.27-10…28), §2.29 (Micro Trend); IM 36K10R30-01EN §4.8.7; installed web client code (`%TLS_WAP_PATH%\mobileoperator\src\fasttools\ui\components\implementation\charts\`); practiced on CI-Eng-Sample (display CIENG_TrendLab, removed 2026-10-06) 2026-10-02; sample trends CIENG_Trends / CIENG_TankFaceplate and a test display on both clients 2026-10-06
source: IM 36K10C50-01EN §2.27 (Trend, Tables 2.27-10…28), §2.29 (Micro Trend); IM 36K10R30-01EN §4.8.7; installed web client code (`%TLS_WAP_PATH%\mobileoperator\src\fasttools\ui\components\implementation\charts\`); practiced on CI-Eng-Sample (display CIENG_TrendLab) 2026-10-02
status: verified (desktop Operator Interface: every row marked ✅/❌ below; HTML display: §6)
---
# Trend settings (desktop and web)
The settings below were tested on the sample display `CIENG_TrendLab` (removed from the sample
on 2026-10-06). Method used: change one XML value in the display, deploy, *View > Reload* in the
client, compare. Current sample: `CIENG_Trends` (trend with 2 pens and micro trends) and the
micro trends on `CIENG_Overview` and `CIENG_TankFaceplate`.
Example: `examples/CI-Eng-Sample/displays/CIENG_TrendLab.xml` (deployed by
`deploy_displays.cmd`). Method used: change one XML value in the display, deploy, *View >
Reload* in the client, compare.
## 1. Before you start
- **Data**: the trend draws history. `TANK1.LEVEL` / `TANK1.INFLOW` are internal items: after a
CI Server start they are `NOT INIT` (value 0) until something writes them, and the trend then
shows nothing (or a bold black line at 0 with status drawing). For tests run
`feed/cieng_feed.ps1` (writes sine waves with `itmval` every 5 s; `-Seconds` = run time,
default 3600; it replaced `displays/trend_feed.ps1` on 2026-10-06), or the sample displays'
live-data button *Start*.
`displays/trend_feed.ps1` (writes sine waves with `itmval` every 5 s; `-Seconds` = run time).
- **Reload**: changes in the display file show after *View > Reload*. A reload within a few
seconds of the deploy can still show the old file — reload again.
- The **Trend properties** dialog (right-click the trend) and the trend toolbar change the trend
@ -123,13 +120,7 @@ rotation, zoom. Outputs (⇨): *Hairline value[n]*, *Time range begin/end*, *Upd
in the legend background colour
(the web legend ignores *Show in legend*, ISS-056). Run it again after editing the trend; do
not keep hidden real pens: one hidden real pen (49 visible) and nothing draws again (checked).
Cost: 50 history requests per trend. **Desktop side effect**: the hairline box lists every
visible pen, so it shows 50 values (the user found this unusable); `hairlineVisible` false does
not help, as the hairline can still be switched on from the trend toolbar. The sample trend
`CIENG_Trends` therefore keeps its 2 pens and draws no line on the web (2026-10-06).
- Component level (outside `<chartPanel>`): `<opaque>true` with `<backgroundColor>` turned the
frame around the plot **light** on the desktop instead of dark (2026-10-06, reverted);
`backgroundPaint` in the chart panel has no effect (ISS-056).
Cost: 50 history requests per trend.
- **Web check of the settings** (2026-10-02, padded scratch copy of `CIENG_TrendLab`, checked in
the browser; supported-property lists: IM 36K10C50 Table 2.27-28, IM 36K10R30 §4.8.7):
@ -143,8 +134,6 @@ rotation, zoom. Outputs (⇨): *Hairline value[n]*, *Time range begin/end*, *Upd
time, then stayed blank on several later opens (ISS-055). Cause: *Number of pens* resets all
pen sources, so fixed item names can be lost during load. **Connect** `microTrend.itemName[n]`
to the item with attribute `ItemName` instead (`<action type="actionConnectTo">`, `<direction>1`,
`<itemAttribute>ItemName`; samples `CIENG_Overview`, `CIENG_Trends`): both pens then drew on every open; the
`<itemAttribute>ItemName`; sample `CIENG_TrendLab`): both pens then drew on every open; the
history fill still failed at times on the web and on the desktop (only the live part drew;
ISS-055 open). `fillWithHistory` true on an item that is in **no** storage group (e.g.
`SYSTEM.CPU_LOAD`) gives the message *Record not found* when the display opens, on the desktop
and on the web (tested 2026-10-06): set it false for such items.
ISS-055 open).

View file

@ -20,6 +20,5 @@ LOW_LOW_LIMIT,LOW_LIMIT,HIGH_LIMIT,HIGH_HIGH_LIMIT,SCALE_LOW_LIMIT,SCALE_HIGH_LI
"CI-Eng-Sample.SYSTEM.PING_LOCALHOST","localhost reachable, from inttcpmon","Integer","9",0,0,0,0,0,1
"CI-Eng-Sample.SYSTEM.PROC_ALM","ALARM process (alm) running, from intmon","Integer","9",0,0,0,0,0,1
"CI-Eng-Sample.DEMO.COUNTER","Counter 1..100 driven by object DEMO.INCR1","Integer","999",0,0,0,0,0,100
"CI-Eng-Sample.DEMO.FEED_ON","Live-data feed running (1 = on), written by feed\cieng_feed.ps1","Boolean","",0,0,0,0,0,0
"CI-Eng-Sample.PLC1.COMM_OK","Station CIENG_PLC communication (1 = good), status item","Boolean","",0,0,0,0,0,0
"CI-Eng-Sample.UA.COMM_OK","Station CIENG_UA communication (1 = good), status item","Boolean","",0,0,0,0,0,0

View file

@ -1,15 +0,0 @@
@LANGUAGE
ENGLISH
@VERSION
1.03.00
! CI-Eng-Sample demo user CIENG (IM 36K10C10-01EN 2.5), CI Server R1.03.00: factory group OPERATOR,
! logs on to layout CIENG_Operator with display CIENG_Overview (Operator Interface and web).
! Empty password: PASSWORD "" must be given explicitly (tested 2026-10-06: without the field the
! user has no password set and every logon fails with DSS-E-UNK_USER).
@FIELDS
NAME,DESCRIPTION,AUTH_GROUP,PROCESS_AREAS,LOGOFF_TIMEOUT,LAYOUT,INITIAL_DISPLAY,PASSWORD
@USER_DF
"CIENG","CI-Eng-Sample demo user (no password)","OPERATOR","1-999",0,"CIENG_Operator","CIENG_Overview",""

View file

@ -5,7 +5,7 @@ ENGLISH
1.03.00
! CI-Eng-Sample: switch on "Audit trailing wanted" (AUDIT_INFO) for PUMP1.MODE (loaded with
! dssqld -m). Operator writes from a display (buttons Manual / Auto on CIENG_Control) are
! dssqld -m). Operator writes from a display (buttons Manual (0) / Auto (1) on CIENG_Tank) are
! then stored as ITEM.VALUE.MODIFY.OPER-INTERFACE with old and new value; with AUDIT_INFO 0 they
! are not audited at all. Changes through DSS (dssqld, Engineering Module) are audited anyway.
@FIELDS

View file

@ -4,12 +4,9 @@ ENGLISH
@VERSION
1.03.00
! Remove the CI-Eng-Sample user and authorization group (the user first)
! Remove the CI-Eng-Sample authorization group (remove its users first)
@FIELDS
NAME
@USER_DF
"CIENG"
@AUTH_GROUP_DF
"CIENG_VIEWER"

View file

@ -18,7 +18,6 @@ NAME
"CI-Eng-Sample.SYSTEM.PING_LOCALHOST"
"CI-Eng-Sample.SYSTEM.PROC_ALM"
"CI-Eng-Sample.DEMO.COUNTER"
"CI-Eng-Sample.DEMO.FEED_ON"
"CI-Eng-Sample.PLC1.COMM_OK"
"CI-Eng-Sample.UA.COMM_OK"
"CI-Eng-Sample.TEMPLATES.TPL_REAL"

View file

@ -4,8 +4,7 @@ A small, invented sample project that anyone with this repo can load into a CI S
**R1.03** test system. Skills use its names in their examples, and every skill task is
re-tested against it so that no other project is needed.
Built and tested on CI Server R1.03.00 (unlicensed test system), 2026-09-30; operator HMI, demo
user and live-data feed added 2026-10-06.
Built and tested on CI Server R1.03.00 (unlicensed test system), 2026-09-30.
## Load and remove
@ -22,10 +21,6 @@ cmd /c "<repo>\examples\CI-Eng-Sample\remove.cmd"
- **Restart CI Server after loading** (stop, then start the CI Service): a new storage group
stores no history until CI Server restarts.
- `load.cmd` on a system that already has the project reports `Exists` and changes nothing.
- Before `remove.cmd`, log out every `CIENG` session (Operator Interface and web): on 2026-10-06
an open session kept its user's authorization group in use (`DSSP-E-NODEL` … `USER_VAL`), and a
retry in that state stopped the `DSSSDA03` process (`DUR-F-BAD_SIZE`) until CI Server was
restarted.
- `remove.cmd` takes about 1½ minutes: a storage group can only be deleted after its stop time
has passed, so the script sets a stop time one minute ahead and waits. Removing the group
also deletes its history.
@ -48,7 +43,6 @@ cmd /c "<repo>\examples\CI-Eng-Sample\remove.cmd"
| `CI-Eng-Sample.TANK1.LEVEL.MAX` | Sub-item, Min-Max | Highest level seen |
| `CI-Eng-Sample.DEMO` | Section | Tutorial examples |
| `CI-Eng-Sample.DEMO.COUNTER` | Item, Integer | Counts 1…100, one step per second, written by `DEMO.INCR1` |
| `CI-Eng-Sample.DEMO.FEED_ON` | Item, Boolean | 1 while the live-data feed runs in display mode (`feed\cieng_feed.ps1 -UntilFlag`); the display button *Stop* writes 0 |
| `CIENG_1S` | Trigger group | Every second |
| `CIENG_INCR` | Class (traditional) | Increments `DEMO.COUNTER`, wraps at 100; compiled on load |
| `CI-Eng-Sample.DEMO.INCR1` | Object | Instance of `CIENG_INCR` |
@ -78,8 +72,7 @@ cmd /c "<repo>\examples\CI-Eng-Sample\remove.cmd"
| `CIENG_ACK` | Acknowledgement type | Every alarm needs an acknowledgement; return to normal automatic only if the alarm was acknowledged (same matrix as `MANUAL`) |
| `CIENG_TANKS` | Area of interest | Label for tank items (`TANK1.LEVEL` `AOI_1`) |
| `CIENG_TANK1` | Alarm selection area | `SECTION = "CI-Eng-Sample.TANK1"`, compiled on load |
| `CIENG_VIEWER` | Authorization group | Read-only: `ITEM_READ`, `SECTION_READ`, `ALARM_CURRENT_READ`, `ALARM_CHRONO_READ` |
| `CIENG` | User | Demo user, **no password**, factory group `OPERATOR`; logs on to layout `CIENG_Operator` with display `CIENG_Overview` (desktop and web). The only user the sample creates; `ADMIN` is not changed. |
| `CIENG_VIEWER` | Authorization group | Read-only: `ITEM_READ`, `SECTION_READ`, `ALARM_CURRENT_READ`, `ALARM_CHRONO_READ`. No users are created by the sample. |
| `CIENG_FILE` | Printer device + destination | FILE output to `%TLS_LST_PATH%\cieng_report.txt` (overwritten by each printed report); destination visible to operators |
| `CIENG_TANK1` | Report | Values of the `TANK1` items + last-hour statistics of one item (ad-hoc parameter chosen in an item browser, default `LEVEL`); daily 06:00 local time and ad hoc; output `CIENG_FILE`; lifetime 1 week |
| `CIENG_INFLOW_HI` | Report | Generated 5 s after `TANK1.INFLOW` rises above 400; output `CIENG_FILE` |
@ -104,7 +97,6 @@ New items start with status 13 (`NOT INIT`) until a value is written.
| `04_item_his_df.qli` | Items in the storage group (`ITEM_HIS_DF`, name `<group>:<item>`) |
| `05_trigger_df.qli`, `06_class_df.qli`, `07_object_df.qli` | Trigger group; classes (source in the `METHOD` memo, `@"` … `"@`, `COMPILE` 1; Traditional and Java); objects (`ATTR_VALUE_1` = prompt answer) |
| `08_auth_group_df.qli` | Authorization group (`AUTH_GROUP_DF`) |
| `08b_user_df.qli` | Demo user `CIENG` (`USER_DF`); `PASSWORD ""` given explicitly - without the field the user has no password set and every logon fails (`DSS-E-UNK_USER`) |
| `09_modbus_line_df.qli`, `10_modbus_station_df.qli`, `11_item_eqp_df.qli` | Modbus line; station, scan type, points; items connected to points |
| `12_opc_visible_df.qli` | OPC visible / read flags (loaded with `dssqld -m`) |
| `13_opcua_line_df.qli`, `14_opcua_station_df.qli`, `15_item_opcua_df.qli` | OPC UA client line; station, subscription, points; connected items |
@ -118,13 +110,14 @@ New items start with status 13 (`NOT INIT`) until a value is written.
| `equipment/eqpciengslv_start.cmd`, `_stop.cmd` | Start/stop the Modbus slave mirror (copy to `tls\com`) |
| `76_`…`93_remove_*.qli` | Names to delete, in reverse order (audit `79`, reports and printer `83`/`84` first, alarm definitions last, `93`) |
| `load.cmd`, `remove.cmd` | Run the steps in the right order |
| `displays/CIENG_Tank.xml` | Display (HTML mode): title, number field on `TANK1.LEVEL`, `PUMP1.MODE` field with buttons *Manual (0)* / *Auto (1)* (write the item), alarm overview, trend of `TANK1.LEVEL` (padded with 49 spare pens so it also draws in the browser), button *Operator layout* |
| `19b_audit_item_df.qli` | *Audit trailing wanted* for `PUMP1.MODE` (loaded with `dssqld -m`) |
| `displays/CIENG_*.xml` | The operator HMI: 8 displays in HTML mode (desktop and web), see *Displays and layout* |
| `displays/generator/` | `build.py` + `cixml.py` write the `CIENG_*.xml` files (Python 3 + Pillow); `README.md` there describes the tool |
| `layouts/CIENG_Operator.xml`, `layouts/layout.ps1` | Layout block (`CIENG_Operator`, `CIENG_Popup`) and the script that adds/removes it in `Layouts.xml` |
| `displays/add_trend_spares.ps1` | Pads every trend in a display file to 50 visible pens (web workaround, ISS-041); safe to run again. Kept as a tool; the sample trend is not padded |
| `displays/CIENG_Menu.xml` | Navigation display (200 x 700): *Tank 1*, *Current Alarm* (main frame), *Tank 1 popup* (layout `popup`) |
| `layouts/CIENG_Operator.xml`, `layouts/layout.ps1` | Operator layout block and the script that adds/removes it in `Layouts.xml` |
| `displays/CIENG_TrendLab.xml` | Trend lab (1000 x 860, HTML mode): trend of `TANK1.LEVEL` (no history group, value axis) and `TANK1.INFLOW` (`CIENG_EVENT`), live, last hour, padded with 48 spare pens so it draws in the browser; Micro Trend of both items (ISS-055) |
| `displays/add_trend_spares.ps1` | Pads every trend in a display file to 50 visible pens (web workaround, ISS-041); safe to run again |
| `displays/trend_feed.ps1` | Writes sine-wave test values to `TANK1.LEVEL` / `TANK1.INFLOW` every 5 s (`-Seconds`, default 3600) |
| `displays/deploy_displays.cmd`, `remove_displays.cmd` | Copy the displays into the operator interface and export their HTML versions / delete them |
| `feed/cieng_feed.ps1`, `cieng_feed_start.cmd`, `install_feed.ps1` | Live-data feed (test values for the tank, pump and system items), its start wrapper for the display button, and the installer into `C:\Users\Public\CI-Eng-Sample\feed` |
| `monitoring/*.sup.txt` | Setup-file lines for the monitoring processes (not applied by `load.cmd`) |
## Modbus slave mirror (for station CIENG_PLC)
@ -169,72 +162,35 @@ priority 1). To try it on a test system: `itmval -p -n CI-Eng-Sample.TANK1.LEVEL
## Displays and layout (optional)
A dark dashboard-style operator HMI with its own layout (no AOG displays). All displays are in
HTML mode, so the same files run in the Operator Interface (desktop) and in the browser (web).
No admin rights needed. After `load.cmd`:
1. `displays\deploy_displays.cmd` copies the 8 displays into the operator interface and creates
their HTML versions.
2. `powershell -ExecutionPolicy Bypass -File layouts\layout.ps1` adds the layouts
`CIENG_Operator` and `CIENG_Popup` to `Layouts.xml` (first run saves
`Layouts-before-CIENG.xml`). **Restart the Operator Interface** afterwards: it reads the
layouts only at start.
3. `powershell -ExecutionPolicy Bypass -File feed\install_feed.ps1` installs the live-data feed
(see *Live data*).
4. Log in as **`CIENG`** (no password): Operator Interface, or the web at
`http://localhost:8080/mobileoperator/`. Other users: `?l=CIENG_Operator` (web) or
`jwuipoi.cmd -layout CIENG_Operator` (desktop).
1. `displays\deploy_displays.cmd` copies `CIENG_Tank`, `CIENG_Menu` and `CIENG_TrendLab` into
the operator interface and creates their HTML versions.
2. `powershell -ExecutionPolicy Bypass -File layouts\layout.ps1` adds the layout
`CIENG_Operator` to `Layouts.xml` (first run saves `Layouts-before-CIENG.xml`).
**Restart the Operator Interface** afterwards: it reads the layouts only at start.
3. Operator Interface (desktop): open `CIENG_Tank` from the display box and click
**Operator layout** - a second window opens with the sample menu (File / View / Displays),
toolbar, `CIENG_Menu` on the left, `CIENG_Tank` in the main frame `default` and the alarm
banner. HTML display (web): `http://localhost:8080/mobileoperator/?d=CIENG_Tank&l=CIENG_Operator`
(CI Server login).
| Display | Where | Shows |
|---|---|---|
| `CIENG_Header` | top frame | KPIs (level coloured by its limits, inflow, volume, pump, PLC / OPC UA communication), live data *Start* / *Stop* with lamp, *Tank 1* faceplate button, last update |
| `CIENG_Overview` | tab *Overview* | Tank 1 mimic (inflow pipe, level fill coloured by limits, limit marks, pump, outlet pipes), volume / flow / maximum / counter / run time, three ring gauges, micro trend; click the tank for the faceplate |
| `CIENG_Control` | tab *Process control* | Slider, spinner and input field on `PLC1.SETPOINT` with Modbus readback; toggle and *Set ON / OFF* on `PLC1.CMD` with `FEEDBACK` lamp; pump mode combo box and *Manual* / *Auto* buttons (audited), run check box; level test slider and buttons LL / L / Normal / H / HH |
| `CIENG_Trends` | tab *Trends* | Trend of level and inflow (10 min, 2 pens) and micro trends for level, inflow and CPU |
| `CIENG_Alarms` | tab *Alarms* | Current alarms and alarm history of `CIENG_TANK1` |
| `CIENG_System` | tab *System* | CPU and disk gauges, communication and process lamps with status, OPC UA loopback, report component |
| `CIENG_AlarmBanner` | bottom frame | Tank 1 alarm lamp, *Alarm list* button, 4-row alarm banner |
| `CIENG_TankFaceplate` | layout `CIENG_Popup` | Level, status, limits, maximum, last update, micro trend, *Trends* / *Alarms* / *Close* |
Trends: `TANK1.LEVEL` and `TANK1.INFLOW` are internal items and stay `NOT INIT` after a CI
Server start, so trends stay empty. `powershell -ExecutionPolicy Bypass -File
displays\trend_feed.ps1 -Seconds 3600` writes test values every 5 s. `CIENG_TrendLab` (also
in the browser: `?d=CIENG_TrendLab`) shows the trend padded to 50 pens, which the HTML display
needs to draw (ISS-041); `CIENG_Tank`'s trend is padded the same way (1 real pen + 49 spares).
Screen sizes: designed for 1920 x 1080. The desktop opens the tabs with `stretchDisplay`, so they
fill any monitor (slightly stretched where the ratio differs); maximise the window, it opens over
the taskbar. The web client does not zoom displays: use full screen (F11) and the browser zoom
(estimates, not tested: about 100 % at 1920 x 1080, 80 % at 1536 x 864, 70 % at 1366 x 768).
Known limits (R1.03.00): the trend draws no line in the browser (a web trend needs 50 pens,
ISS-041; the 2-pen trend keeps the desktop hairline box readable); the empty part of the alarm
lists stays white; a tab opened by clicking the tab strip itself keeps its zoom until it is opened
once from the toolbar, menu or F1–F6.
Remove: `layouts\layout.ps1 -Remove` (restores the file exactly), `displays\remove_displays.cmd`
and `feed\install_feed.ps1 -Remove`. Close the displays in the Edit Module first. See skill
Remove: `layouts\layout.ps1 -Remove` (restores the file exactly) and
`displays\remove_displays.cmd`. Close the displays in the Edit Module first. See skill
`graphics`.
## Live data
The sample items are internal: after a CI Server start they stay `NOT INIT`, so displays, trends
and alarms show nothing until values are written. `feed\cieng_feed.ps1` writes them every 5 s:
| Option | Effect |
|---|---|
| (none) | Runs `-Seconds` (default 3600): `TANK1.LEVEL` 50 ± 25 % (inside the limits), `TANK1.INFLOW` 250 ± 150 m3/h; `PUMP1.RUNNING` follows the inflow in auto mode |
| `-Alarms` | `TANK1.LEVEL` 50 ± 33 %: crosses L 20 and H 80, so alarms appear (manual acknowledgement) |
| `-System` | Also writes `SYSTEM.CPU_LOAD` / `DISK_C` / `PING_LOCALHOST` / `PROC_ALM` with this PC's values; skipped while the monitoring processes run (they write the same items) |
| `-UntilFlag` | Runs while `DEMO.FEED_ON` = 1 (display buttons *Start* / *Stop*) |
The header button *Start* runs `C:\Users\Public\CI-Eng-Sample\feed\cieng_feed_start.cmd` on the
server (as the CI Server service account `CIX_PROCESS`; the factory group `OPERATOR` is enough), which
starts the feed with `-UntilFlag -Alarms -System`. Only one copy runs at a time. Log:
`%TLS_LST_PATH%\cieng_feed.log`. Stop the feed before manual tests with `itmval` (it overwrites the
values within 5 s). After a CI Server restart the *Live data* lamp can stay green although no feed
runs: click *Start*.
## Monitoring processes (optional)
`monitoring/` holds the lines to add to the setup files in `%TLS_ROOT_PATH%\tls\sup\` so that
`intcpumon`, `intdskmon`, `inttcpmon`, `intmon` and `intspawn` write into the `SYSTEM` items.
These change the system's own setup files: back the files up first and restore them after
testing. While they run, the live-data feed leaves the `SYSTEM` items alone (`-System` is skipped). See the `system-management` skill, task `monitoring-processes.md`.
testing. See the `system-management` skill, task `monitoring-processes.md`.
## Reports
@ -259,7 +215,7 @@ Engineering Module is in the audit trail (skill `audit-trail`):
- Generate `CIENG_AUDIT` (ad hoc, like the other reports) to list the last hour of changes on
`CI-Eng-Sample.*`: time, dataset, field, action, source, user, old and new value.
- Operator writes: with the displays deployed, click *Manual* / *Auto* on `CIENG_Control`;
- Operator writes: with the displays deployed, click *Manual (0)* / *Auto (1)* on `CIENG_Tank`;
each click is stored as `ITEM.VALUE.MODIFY.OPER-INTERFACE` because `PUMP1.MODE` has *Audit
trailing wanted* (`19b_audit_item_df.qli`).
- Export: `dssqld -e audit.qlo -d AUDIT_TRAIL` (whole trail) or a qli with `@SELECT` (keep `NAME`
@ -275,7 +231,7 @@ selection group.
| Phase | Adds |
|---|---|
| 10 | A symbol (the faceplate popup `CIENG_TankFaceplate` exists since 2026-10-06) |
| 10 | A symbol and a faceplate popup (displays and the operator layout exist) |
## Rules

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,96 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<visualization protocolVersion="1.3.0.0">
<globalSection/>
<coreObjectDefinition type="displayDefinition">
<version type="version" value="1.3.0.0"/>
<title>Process control</title>
<html>true</html>
<width>1880</width>
<height>760</height>
<referenceCheck>72</referenceCheck>
<backgroundColor type="colorSet" r="13" g="17" b="23"/>
<backgroundColorOn>true</backgroundColorOn>
<defaultBgColor type="colorSet" r="13" g="17" b="23"/>
<defaultFgColor type="colorSet" r="230" g="237" b="243"/>
<defaultFont type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/>
<defaultStroke type="stroke" width="1.0"/>
<grid type="grid" gridVisible="true" snappingActive="true" verticalSnapInterval="4" horizontalSnapInterval="4" onTop="false"><color type="colorSet" r="51" g="59" b="71"/></grid>
<revisionHistory type="revisionHistory"><revision type="revision" who="ADMIN" when="2026.10.02 12:00:00.000 AEST" what="Generated by displays/generator/build.py" where="localhost"/></revisionHistory>
<blinkDelay>500</blinkDelay>
<blinkEnabled>true</blinkEnabled>
<mousePassThrough>false</mousePassThrough>
<visibilityGroup type="componentData"><htmlId>2</htmlId><name>Overview</name><description>Always shown</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>10.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>3</htmlId><name>Rough</name><description>Shown when viewing viewing a large area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>25.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>4</htmlId><name>Standard</name><description>Shown when using the default view setting</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>100.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>5</htmlId><name>Detail</name><description>Shown only when viewing a small area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>400.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>6</htmlId><name>Intricacies</name><description>Shown only when viewing a very small area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>1000.0</minimumZoomFactor></visibilityGroup>
<visualizationLayer type="componentData"><htmlId>1</htmlId><name>Layer1</name></visualizationLayer>
<componentCountHint>66</componentCountHint>
<rectangle type="componentData"><htmlId>7</htmlId><x>940.0</x><y>380.0</y><top>380.0</top><bottom>380.0</bottom><left>940.0</left><right>940.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="13" g="17" b="23"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>8</htmlId><roundingX>0.0216</roundingX><roundingY>0.0551</roundingY><x>472.5</x><y>192.8</y><top>181.6</top><bottom>181.6</bottom><left>462.5</left><right>462.5</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>9</htmlId><value>SETPOINT -&gt; PLC1 (MODBUS LOOPBACK)</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>134.8</x><y>36.9</y><top>11.0</top><bottom>11.0</bottom><left>104.8</left><right>104.8</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>10</htmlId><value>Slider, spinner and input field write PLC1.SETPOINT; READBACK returns through Modbus</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="88" g="100" b="116"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>218.2</x><y>59.2</y><top>9.0</top><bottom>9.0</bottom><left>188.2</left><right>188.2</right><rotation>0.0</rotation><shear>0.0</shear></text>
<slider type="componentData" x="340.0" y="114.0" top="32.0" bottom="32.0" left="300.0" right="300.0" rotation="0.0" shear="0.0"><htmlId>11</htmlId><maximum>100.0</maximum><minimum>0.0</minimum><value>0.0</value><majorTickSpacing>10.0</majorTickSpacing><minorTickSpacing>5.0</minorTickSpacing><paintLabels>true</paintLabels><paintTicks>true</paintTicks><trackDrag>false</trackDrag><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><opaque>false</opaque><foregroundColor type="colorSet" r="139" g="152" b="168"/><data type="data"><action type="actionConnectTo"><property type="property" name="slider.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><itemName>CI-Eng-Sample.PLC1.SETPOINT</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></slider>
<text type="componentData"><htmlId>12</htmlId><value>SPINNER</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>61.0</x><y>176.6</y><top>8.0</top><bottom>8.0</bottom><left>21.0</left><right>21.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<spinner type="componentData" x="110.0" y="210.1" top="18.0" bottom="18.0" left="70.0" right="70.0" rotation="0.0" shear="0.0"><htmlId>13</htmlId><editable>true</editable><step>5.0</step><minimum>0.0</minimum><maximum>100.0</maximum><font type="font" name="Consolas" bold="true" size="14" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><zoomEnabled>false</zoomEnabled><data type="data"><action type="actionConnectTo"><property type="property" name="spinner.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><itemName>CI-Eng-Sample.PLC1.SETPOINT</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></spinner>
<text type="componentData"><htmlId>14</htmlId><value>INPUT FIELD</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>228.3</x><y>176.6</y><top>8.0</top><bottom>8.0</bottom><left>28.3</left><right>28.3</right><rotation>0.0</rotation><shear>0.0</shear></text>
<numberField type="componentData" x="270.0" y="210.1" top="18.0" bottom="18.0" left="70.0" right="70.0" rotation="0.0" shear="0.0"><htmlId>15</htmlId><font type="font" name="Consolas" bold="true" size="16" underline="false" strikethrough="false"/><format>999</format><editable>true</editable><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><justification type="jTextJustification" value="TextJustificationRight"/><data type="data"><action type="actionConnectTo"><property type="property" name="numberField.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><itemName>CI-Eng-Sample.PLC1.SETPOINT</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></numberField>
<text type="componentData"><htmlId>16</htmlId><value>SETPOINT</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>383.4</x><y>176.6</y><top>8.0</top><bottom>8.0</bottom><left>23.4</left><right>23.4</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>17</htmlId><value>0.0</value><format>999</format><font type="font" name="Consolas" bold="true" size="28" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="59" g="130" b="246"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>381.9</x><y>210.1</y><top>20.0</top><bottom>20.0</bottom><left>21.9</left><right>21.9</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.SETPOINT</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>18</htmlId><value>READBACK (data bar + scale)</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>105.8</x><y>261.5</y><top>8.0</top><bottom>8.0</bottom><left>65.8</left><right>65.8</right><rotation>0.0</rotation><shear>0.0</shear></text>
<dataBar type="componentData" x="340.0" y="287.2" top="9.0" bottom="9.0" left="300.0" right="300.0" rotation="0.0" shear="0.0"><htmlId>19</htmlId><fillOn>true</fillOn><background type="paint"><paint type="colorSet" r="40" g="50" b="64"/></background><foreground type="paint"><paint type="colorSet" r="59" g="130" b="246"/></foreground><borderColor type="paint"><paint type="colorSet" r="40" g="50" b="64"/></borderColor><foregroundBorderColor type="paint"><paint type="colorSet" r="59" g="130" b="246"/></foregroundBorderColor><lowLimit>0.0</lowLimit><highLimit>100.0</highLimit><growthDirection type="growthDirection" value="GrowthDirectionRight"/><data type="data"><action type="actionConnectTo"><property type="property" name="dataBar.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.READBACK</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></dataBar>
<rectangularScale type="componentData" x="340.0" y="319.6" top="18.0" bottom="18.0" left="300.0" right="300.0" rotation="0.0" shear="0.0"><htmlId>20</htmlId><maximum>100.0</maximum><minimum>0.0</minimum><majorTickSpacing>10.0</majorTickSpacing><minorTickSpacing>5.0</minorTickSpacing><format>999</format><vertical>false</vertical><color type="colorSet" r="139" g="152" b="168"/><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/></rectangularScale>
<arc type="componentData"><htmlId>21</htmlId><startAngle>45.0</startAngle><extentAngle>270.0</extentAngle><closed>false</closed><x>790.0</x><y>195.6</y><top>95.0</top><bottom>95.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="40" g="50" b="64"/></strokePaint><fillOn>false</fillOn></arc>
<arc type="componentData"><htmlId>22</htmlId><startAngle>179.8</startAngle><extentAngle>0.5</extentAngle><closed>false</closed><x>790.0</x><y>195.6</y><top>95.0</top><bottom>95.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="59" g="130" b="246"/></strokePaint><fillOn>false</fillOn><data type="data"><action type="actionConnectTo"><property type="property" name="arc.extentAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>100.0</inputValueEnd><outputValueStart>0.5</outputValueStart><outputValueEnd>270.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.READBACK</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="arc.startAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>100.0</inputValueEnd><outputValueStart>179.75</outputValueStart><outputValueEnd>45.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.READBACK</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></arc>
<number type="componentData"><htmlId>23</htmlId><value>0.0</value><format>999</format><font type="font" name="Consolas" bold="true" size="26" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>790.0</x><y>191.1</y><top>18.0</top><bottom>18.0</bottom><left>81.0</left><right>81.0</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.READBACK</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>24</htmlId><value></value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>790.0</x><y>223.5</y><top>9.0</top><bottom>9.0</bottom><left>40.0</left><right>40.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>25</htmlId><value>Readback</value><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>790.0</x><y>306.2</y><top>10.0</top><bottom>10.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<ellipse type="componentData"><htmlId>26</htmlId><x>706.0</x><y>40.2</y><top>6.0</top><bottom>6.0</bottom><left>6.0</left><right>6.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>true</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.COMM_OK</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>27</htmlId><value>station CIENG_PLC</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>762.9</x><y>39.1</y><top>9.0</top><bottom>9.0</bottom><left>44.9</left><right>44.9</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>28</htmlId><roundingX>0.0216</roundingX><roundingY>0.0551</roundingY><x>1407.5</x><y>192.8</y><top>181.6</top><bottom>181.6</bottom><left>462.5</left><right>462.5</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>29</htmlId><value>DIGITAL COMMAND -&gt; PLC1.CMD</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1052.8</x><y>36.9</y><top>11.0</top><bottom>11.0</bottom><left>87.8</left><right>87.8</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>30</htmlId><value>Toggle and push buttons write the coil; FEEDBACK is read back from the input bit</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="88" g="100" b="116"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1139.0</x><y>59.2</y><top>9.0</top><bottom>9.0</bottom><left>174.0</left><right>174.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<toggleButton type="componentData" x="1075.0" y="116.2" top="24.0" bottom="24.0" left="100.0" right="100.0" rotation="0.0" shear="0.0"><htmlId>31</htmlId><label>CMD (toggle)</label><font type="font" name="Segoe UI" bold="true" size="14" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><data type="data"><action type="actionConnectTo"><property type="property" name="toggleButton.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><itemName>CI-Eng-Sample.PLC1.CMD</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></toggleButton>
<button type="componentData" x="1022.5" y="190.0" top="20.0" bottom="20.0" left="47.5" right="47.5" rotation="0.0" shear="0.0"><htmlId>32</htmlId><label>Set ON</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="255" g="255" b="255"/><backgroundColor type="colorSet" r="34" g="197" b="94"/><data type="data"><action type="actionSetItemAttribute"><event type="event" event="On action"/><filter type="filter"><value>1.0</value></filter><connection type="connection"><direction>2</direction><location type="nodeName" node="$default$"/><itemName>CI-Eng-Sample.PLC1.CMD</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></button>
<button type="componentData" x="1127.5" y="190.0" top="20.0" bottom="20.0" left="47.5" right="47.5" rotation="0.0" shear="0.0"><htmlId>33</htmlId><label>Set OFF</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><data type="data"><action type="actionSetItemAttribute"><event type="event" event="On action"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>2</direction><location type="nodeName" node="$default$"/><itemName>CI-Eng-Sample.PLC1.CMD</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></button>
<ellipse type="componentData"><htmlId>34</htmlId><x>1360.0</x><y>156.5</y><top>60.0</top><bottom>60.0</bottom><left>60.0</left><right>60.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="3.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="71" g="85" b="105"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="71" g="85" b="105"/></thresholdOut><thresholdIn>true</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.FEEDBACK</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>35</htmlId><value>FEEDBACK</value><font type="font" name="Segoe UI" bold="true" size="13" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="255" g="255" b="255"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1360.0</x><y>156.5</y><top>12.0</top><bottom>12.0</bottom><left>60.0</left><right>60.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>36</htmlId><value>LAST CHANGE OF FEEDBACK</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1525.3</x><y>109.5</y><top>8.0</top><bottom>8.0</bottom><left>65.3</left><right>65.3</right><rotation>0.0</rotation><shear>0.0</shear></text>
<dateTimeField type="componentData" x="1610.0" y="141.9" top="15.0" bottom="15.0" left="150.0" right="150.0" rotation="0.0" shear="0.0"><htmlId>37</htmlId><font type="font" name="Segoe UI" size="13" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="230" g="237" b="243"/><editable>true</editable><secondsVisible>true</secondsVisible><backgroundColor type="colorSet" r="36" g="45" b="57"/><data type="data"><action type="actionConnectTo"><property type="property" name="dateTimeField.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.FEEDBACK</itemName><itemAttribute>ItemUpdTime</itemAttribute></connection></action></data></dateTimeField>
<text type="componentData"><htmlId>38</htmlId><value>STATUS</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1478.5</x><y>187.8</y><top>8.0</top><bottom>8.0</bottom><left>18.5</left><right>18.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>39</htmlId><value>NORMAL</value><font type="font" name="Segoe UI" bold="true" size="16" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1493.6</x><y>214.6</y><top>12.0</top><bottom>12.0</bottom><left>33.6</left><right>33.6</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.FEEDBACK</itemName><itemAttribute>ItemStatusMnemonic</itemAttribute></connection></action></data></text>
<rectangle type="componentData"><htmlId>40</htmlId><roundingX>0.0216</roundingX><roundingY>0.0551</roundingY><x>472.5</x><y>567.2</y><top>181.6</top><bottom>181.6</bottom><left>462.5</left><right>462.5</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>41</htmlId><value>PUMP 1</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>50.5</x><y>411.3</y><top>11.0</top><bottom>11.0</bottom><left>20.5</left><right>20.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>42</htmlId><value>Combo box, buttons and check box write PUMP1.MODE / PUMP1.RUNNING (mode changes are audited)</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="88" g="100" b="116"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>257.7</x><y>433.6</y><top>9.0</top><bottom>9.0</bottom><left>227.7</left><right>227.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>43</htmlId><value>MODE (COMBO BOX)</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>90.2</x><y>456.0</y><top>8.0</top><bottom>8.0</bottom><left>50.2</left><right>50.2</right><rotation>0.0</rotation><shear>0.0</shear></text>
<comboBox type="componentData" x="140.0" y="488.4" top="17.0" bottom="17.0" left="100.0" right="100.0" rotation="0.0" shear="0.0"><htmlId>44</htmlId><label>0;Manual;1;Auto</label><font type="font" name="Segoe UI" size="14" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="230" g="237" b="243"/><data type="data"><action type="actionConnectTo"><property type="property" name="comboBox.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><itemName>CI-Eng-Sample.PUMP1.MODE</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></comboBox>
<button type="componentData" x="315.0" y="488.4" top="17.0" bottom="17.0" left="55.0" right="55.0" rotation="0.0" shear="0.0"><htmlId>45</htmlId><label>Manual</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><data type="data"><action type="actionSetItemAttribute"><event type="event" event="On action"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>2</direction><location type="nodeName" node="$default$"/><itemName>CI-Eng-Sample.PUMP1.MODE</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></button>
<button type="componentData" x="435.0" y="488.4" top="17.0" bottom="17.0" left="55.0" right="55.0" rotation="0.0" shear="0.0"><htmlId>46</htmlId><label>Auto</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="255" g="255" b="255"/><backgroundColor type="colorSet" r="59" g="130" b="246"/><data type="data"><action type="actionSetItemAttribute"><event type="event" event="On action"/><filter type="filter"><value>1.0</value></filter><connection type="connection"><direction>2</direction><location type="nodeName" node="$default$"/><itemName>CI-Eng-Sample.PUMP1.MODE</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></button>
<text type="componentData"><htmlId>47</htmlId><value>RUN COMMAND (CHECK BOX, MANUAL MODE)</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>152.1</x><y>543.2</y><top>8.0</top><bottom>8.0</bottom><left>112.1</left><right>112.1</right><rotation>0.0</rotation><shear>0.0</shear></text>
<checkBox type="componentData" x="160.0" y="574.5" top="16.0" bottom="16.0" left="120.0" right="120.0" rotation="0.0" shear="0.0"><htmlId>48</htmlId><label>Pump running</label><font type="font" name="Segoe UI" size="14" underline="false" strikethrough="false"/><opaque>false</opaque><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="28" g="35" b="45"/><data type="data"><action type="actionConnectTo"><property type="property" name="checkBox.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><itemName>CI-Eng-Sample.PUMP1.RUNNING</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></checkBox>
<text type="componentData"><htmlId>49</htmlId><value>DESCRIPTION (TEXT FIELD)</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>102.4</x><y>625.9</y><top>8.0</top><bottom>8.0</bottom><left>62.4</left><right>62.4</right><rotation>0.0</rotation><shear>0.0</shear></text>
<textField type="componentData" x="265.0" y="656.1" top="15.0" bottom="15.0" left="225.0" right="225.0" rotation="0.0" shear="0.0"><htmlId>50</htmlId><font type="font" name="Segoe UI" size="13" underline="false" strikethrough="false"/><editable>false</editable><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><data type="data"><action type="actionConnectTo"><property type="property" name="textField.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.MODE</itemName><itemAttribute>ItemDesc</itemAttribute></connection></action></data></textField>
<ellipse type="componentData"><htmlId>51</htmlId><x>655.0</x><y>530.9</y><top>55.0</top><bottom>55.0</bottom><left>55.0</left><right>55.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="3.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="71" g="85" b="105"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="71" g="85" b="105"/></thresholdOut><thresholdIn>true</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.RUNNING</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>52</htmlId><value>P1</value><font type="font" name="Segoe UI" bold="true" size="18" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="255" g="255" b="255"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>655.0</x><y>529.8</y><top>12.0</top><bottom>12.0</bottom><left>55.0</left><right>55.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>53</htmlId><value>RUN TIME (INTEGRATOR)</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>670.0</x><y>621.4</y><top>8.0</top><bottom>8.0</bottom><left>110.0</left><right>110.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>54</htmlId><value>0.0</value><format>9999999</format><font type="font" name="Consolas" bold="true" size="24" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>705.6</x><y>651.6</y><top>17.0</top><bottom>17.0</bottom><left>44.4</left><right>44.4</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.RUNNING.RUN_SECONDS</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>55</htmlId><value>s</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>756.4</x><y>653.8</y><top>9.0</top><bottom>9.0</bottom><left>2.4</left><right>2.4</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>56</htmlId><roundingX>0.0216</roundingX><roundingY>0.0551</roundingY><x>1407.5</x><y>567.2</y><top>181.6</top><bottom>181.6</bottom><left>462.5</left><right>462.5</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>57</htmlId><value>TANK 1 - ALARM TEST</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1021.5</x><y>411.3</y><top>11.0</top><bottom>11.0</bottom><left>56.5</left><right>56.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>58</htmlId><value>Stop live data first, then drive TANK1.LEVEL across its limits (H 80 / HH 90 / L 20 / LL 10)</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="88" g="100" b="116"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1150.2</x><y>433.6</y><top>9.0</top><bottom>9.0</bottom><left>185.2</left><right>185.2</right><rotation>0.0</rotation><shear>0.0</shear></text>
<slider type="componentData" x="1255.0" y="494.0" top="32.0" bottom="32.0" left="280.0" right="280.0" rotation="0.0" shear="0.0"><htmlId>59</htmlId><maximum>100.0</maximum><minimum>0.0</minimum><value>0.0</value><majorTickSpacing>10.0</majorTickSpacing><minorTickSpacing>5.0</minorTickSpacing><paintLabels>true</paintLabels><paintTicks>true</paintTicks><trackDrag>false</trackDrag><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><opaque>false</opaque><foregroundColor type="colorSet" r="139" g="152" b="168"/><data type="data"><action type="actionConnectTo"><property type="property" name="slider.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></slider>
<button type="componentData" x="1028.0" y="580.1" top="19.0" bottom="19.0" left="53.0" right="53.0" rotation="0.0" shear="0.0"><htmlId>60</htmlId><label>Low-Low 5</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="255" g="255" b="255"/><backgroundColor type="colorSet" r="239" g="68" b="68"/><data type="data"><action type="actionSetItemAttribute"><event type="event" event="On action"/><filter type="filter"><value>5.0</value></filter><connection type="connection"><direction>2</direction><location type="nodeName" node="$default$"/><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></button>
<button type="componentData" x="1142.0" y="580.1" top="19.0" bottom="19.0" left="53.0" right="53.0" rotation="0.0" shear="0.0"><htmlId>61</htmlId><label>Low 15</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="255" g="255" b="255"/><backgroundColor type="colorSet" r="245" g="158" b="11"/><data type="data"><action type="actionSetItemAttribute"><event type="event" event="On action"/><filter type="filter"><value>15.0</value></filter><connection type="connection"><direction>2</direction><location type="nodeName" node="$default$"/><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></button>
<button type="componentData" x="1256.0" y="580.1" top="19.0" bottom="19.0" left="53.0" right="53.0" rotation="0.0" shear="0.0"><htmlId>62</htmlId><label>Normal 50</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="255" g="255" b="255"/><backgroundColor type="colorSet" r="20" g="184" b="166"/><data type="data"><action type="actionSetItemAttribute"><event type="event" event="On action"/><filter type="filter"><value>50.0</value></filter><connection type="connection"><direction>2</direction><location type="nodeName" node="$default$"/><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></button>
<button type="componentData" x="1370.0" y="580.1" top="19.0" bottom="19.0" left="53.0" right="53.0" rotation="0.0" shear="0.0"><htmlId>63</htmlId><label>High 85</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="255" g="255" b="255"/><backgroundColor type="colorSet" r="245" g="158" b="11"/><data type="data"><action type="actionSetItemAttribute"><event type="event" event="On action"/><filter type="filter"><value>85.0</value></filter><connection type="connection"><direction>2</direction><location type="nodeName" node="$default$"/><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></button>
<button type="componentData" x="1484.0" y="580.1" top="19.0" bottom="19.0" left="53.0" right="53.0" rotation="0.0" shear="0.0"><htmlId>64</htmlId><label>High-High 95</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="255" g="255" b="255"/><backgroundColor type="colorSet" r="239" g="68" b="68"/><data type="data"><action type="actionSetItemAttribute"><event type="event" event="On action"/><filter type="filter"><value>95.0</value></filter><connection type="connection"><direction>2</direction><location type="nodeName" node="$default$"/><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></button>
<text type="componentData"><htmlId>65</htmlId><value>LEVEL</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>988.2</x><y>641.5</y><top>8.0</top><bottom>8.0</bottom><left>13.2</left><right>13.2</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>66</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="38" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1026.2</x><y>680.6</y><top>25.0</top><bottom>25.0</bottom><left>51.2</left><right>51.2</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="number.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>10.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>20.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="20" g="184" b="166"/></thresholdOut><thresholdIn>80.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>90.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>67</htmlId><value>ITEM STATUS</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1211.7</x><y>641.5</y><top>8.0</top><bottom>8.0</bottom><left>31.7</left><right>31.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>68</htmlId><value>NORMAL</value><font type="font" name="Segoe UI" bold="true" size="22" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1226.3</x><y>678.4</y><top>17.0</top><bottom>17.0</bottom><left>46.3</left><right>46.3</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemStatusMnemonic</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="text.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>10.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>20.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="20" g="184" b="166"/></thresholdOut><thresholdIn>80.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>90.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></text>
<arc type="componentData"><htmlId>69</htmlId><startAngle>45.0</startAngle><extentAngle>270.0</extentAngle><closed>false</closed><x>1720.0</x><y>581.2</y><top>90.0</top><bottom>90.0</bottom><left>90.0</left><right>90.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="14.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="40" g="50" b="64"/></strokePaint><fillOn>false</fillOn></arc>
<arc type="componentData"><htmlId>70</htmlId><startAngle>179.8</startAngle><extentAngle>0.5</extentAngle><closed>false</closed><x>1720.0</x><y>581.2</y><top>90.0</top><bottom>90.0</bottom><left>90.0</left><right>90.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="14.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="20" g="184" b="166"/></strokePaint><fillOn>false</fillOn><data type="data"><action type="actionConnectTo"><property type="property" name="arc.extentAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>100.0</inputValueEnd><outputValueStart>0.5</outputValueStart><outputValueEnd>270.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="arc.startAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>100.0</inputValueEnd><outputValueStart>179.75</outputValueStart><outputValueEnd>45.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="arc.strokePaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>10.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>20.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="20" g="184" b="166"/></thresholdOut><thresholdIn>80.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>90.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></arc>
<circularScale type="componentData" x="1720.0" y="581.2" top="120.0" bottom="120.0" left="120.0" right="120.0" rotation="0.0" shear="0.0"><htmlId>71</htmlId><maximum>100.0</maximum><minimum>0.0</minimum><majorTickSpacing>20.0</majorTickSpacing><minorTickSpacing>5.0</minorTickSpacing><format>999</format><startAngle>225.0</startAngle><extentAngle>-270.0</extentAngle><color type="colorSet" r="139" g="152" b="168"/><font type="font" name="Segoe UI" size="9" underline="false" strikethrough="false"/></circularScale>
<number type="componentData"><htmlId>72</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="26" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1720.0</x><y>581.2</y><top>20.0</top><bottom>20.0</bottom><left>60.0</left><right>60.0</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
</coreObjectDefinition>
</visualization>

View file

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<visualization protocolVersion="1.3.0.0">
<globalSection/>
<coreObjectDefinition type="displayDefinition">
<version type="version" value="1.3.0.0"/>
<title>Header</title>
<html>true</html>
<width>1920</width>
<height>96</height>
<referenceCheck>43</referenceCheck>
<backgroundColor type="colorSet" r="22" g="27" b="34"/>
<backgroundColorOn>true</backgroundColorOn>
<defaultBgColor type="colorSet" r="22" g="27" b="34"/>
<defaultFgColor type="colorSet" r="230" g="237" b="243"/>
<defaultFont type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/>
<defaultStroke type="stroke" width="1.0"/>
<grid type="grid" gridVisible="true" snappingActive="true" verticalSnapInterval="4" horizontalSnapInterval="4" onTop="false"><color type="colorSet" r="51" g="59" b="71"/></grid>
<revisionHistory type="revisionHistory"><revision type="revision" who="ADMIN" when="2026.10.02 12:00:00.000 AEST" what="Generated by displays/generator/build.py" where="localhost"/></revisionHistory>
<blinkDelay>500</blinkDelay>
<blinkEnabled>true</blinkEnabled>
<mousePassThrough>false</mousePassThrough>
<visibilityGroup type="componentData"><htmlId>2</htmlId><name>Overview</name><description>Always shown</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>10.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>3</htmlId><name>Rough</name><description>Shown when viewing viewing a large area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>25.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>4</htmlId><name>Standard</name><description>Shown when using the default view setting</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>100.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>5</htmlId><name>Detail</name><description>Shown only when viewing a small area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>400.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>6</htmlId><name>Intricacies</name><description>Shown only when viewing a very small area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>1000.0</minimumZoomFactor></visibilityGroup>
<visualizationLayer type="componentData"><htmlId>1</htmlId><name>Layer1</name></visualizationLayer>
<componentCountHint>37</componentCountHint>
<rectangle type="componentData"><htmlId>7</htmlId><x>960.0</x><y>48.0</y><top>48.0</top><bottom>48.0</bottom><left>960.0</left><right>960.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>8</htmlId><x>960.0</x><y>95.0</y><top>0.5</top><bottom>0.5</bottom><left>960.0</left><right>960.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>9</htmlId><roundingX>0.4667</roundingX><roundingY>0.4667</roundingY><x>50.0</x><y>48.0</y><top>30.0</top><bottom>30.0</bottom><left>30.0</left><right>30.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="59" g="130" b="246"/></fillPaint></rectangle>
<text type="componentData"><htmlId>10</htmlId><value>CI</value><font type="font" name="Segoe UI" bold="true" size="22" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="255" g="255" b="255"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>50.0</x><y>48.0</y><top>14.0</top><bottom>14.0</bottom><left>30.0</left><right>30.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>11</htmlId><value>CI-Eng-Sample</value><font type="font" name="Segoe UI" bold="true" size="22" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>171.1</x><y>33.0</y><top>15.0</top><bottom>15.0</bottom><left>75.1</left><right>75.1</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>12</htmlId><value>Operations dashboard | Tank farm demo</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>201.8</x><y>62.0</y><top>10.0</top><bottom>10.0</bottom><left>105.8</left><right>105.8</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>13</htmlId><roundingX>0.0952</roundingX><roundingY>0.2353</roundingY><x>604.0</x><y>48.0</y><top>34.0</top><bottom>34.0</bottom><left>84.0</left><right>84.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>14</htmlId><value>TANK LEVEL</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>561.8</x><y>30.0</y><top>8.0</top><bottom>8.0</bottom><left>27.8</left><right>27.8</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>15</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="22" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>563.2</x><y>56.0</y><top>16.0</top><bottom>16.0</bottom><left>29.2</left><right>29.2</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="number.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>10.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>20.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="20" g="184" b="166"/></thresholdOut><thresholdIn>80.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>90.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>16</htmlId><value>%</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>642.4</x><y>59.0</y><top>9.0</top><bottom>9.0</bottom><left>4.4</left><right>4.4</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>17</htmlId><roundingX>0.0952</roundingX><roundingY>0.2353</roundingY><x>784.0</x><y>48.0</y><top>34.0</top><bottom>34.0</bottom><left>84.0</left><right>84.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>18</htmlId><value>INFLOW</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>733.0</x><y>30.0</y><top>8.0</top><bottom>8.0</bottom><left>19.0</left><right>19.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>19</htmlId><value>0.0</value><format>9999.9</format><font type="font" name="Consolas" bold="true" size="22" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>749.1</x><y>56.0</y><top>16.0</top><bottom>16.0</bottom><left>35.1</left><right>35.1</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.INFLOW</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>20</htmlId><value>m3/h</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>830.2</x><y>59.0</y><top>9.0</top><bottom>9.0</bottom><left>12.2</left><right>12.2</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>21</htmlId><roundingX>0.0952</roundingX><roundingY>0.2353</roundingY><x>964.0</x><y>48.0</y><top>34.0</top><bottom>34.0</bottom><left>84.0</left><right>84.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>22</htmlId><value>VOLUME</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>914.5</x><y>30.0</y><top>8.0</top><bottom>8.0</bottom><left>20.5</left><right>20.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>23</htmlId><value>0.0</value><format>9999.9</format><font type="font" name="Consolas" bold="true" size="22" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>929.1</x><y>56.0</y><top>16.0</top><bottom>16.0</bottom><left>35.1</left><right>35.1</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.CALC.VOLUME</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>24</htmlId><value>m3</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1005.3</x><y>59.0</y><top>9.0</top><bottom>9.0</bottom><left>7.3</left><right>7.3</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>25</htmlId><roundingX>0.0952</roundingX><roundingY>0.2353</roundingY><x>1144.0</x><y>48.0</y><top>34.0</top><bottom>34.0</bottom><left>84.0</left><right>84.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>26</htmlId><value>PUMP 1</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1092.5</x><y>30.0</y><top>8.0</top><bottom>8.0</bottom><left>18.5</left><right>18.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<ellipse type="componentData"><htmlId>27</htmlId><x>1083.0</x><y>57.0</y><top>9.0</top><bottom>9.0</bottom><left>9.0</left><right>9.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="71" g="85" b="105"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="71" g="85" b="105"/></thresholdOut><thresholdIn>true</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.RUNNING</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>28</htmlId><value>RUNNING</value><font type="font" name="Segoe UI" bold="true" size="14" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="34" g="197" b="94"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1132.2</x><y>56.0</y><top>12.0</top><bottom>12.0</bottom><left>32.2</left><right>32.2</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.visible"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>java.lang.Boolean</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut>false</thresholdOut><thresholdIn>true</thresholdIn><thresholdOut>true</thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.RUNNING</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></text>
<text type="componentData"><htmlId>29</htmlId><value>STOPPED</value><font type="font" name="Segoe UI" bold="true" size="14" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1130.2</x><y>56.0</y><top>12.0</top><bottom>12.0</bottom><left>30.2</left><right>30.2</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.visible"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>java.lang.Boolean</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut>true</thresholdOut><thresholdIn>true</thresholdIn><thresholdOut>false</thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.RUNNING</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></text>
<rectangle type="componentData"><htmlId>30</htmlId><roundingX>0.0952</roundingX><roundingY>0.2353</roundingY><x>1324.0</x><y>48.0</y><top>34.0</top><bottom>34.0</bottom><left>84.0</left><right>84.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>31</htmlId><value>COMMUNICATION</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1297.9</x><y>30.0</y><top>8.0</top><bottom>8.0</bottom><left>43.9</left><right>43.9</right><rotation>0.0</rotation><shear>0.0</shear></text>
<ellipse type="componentData"><htmlId>32</htmlId><x>1261.0</x><y>57.0</y><top>7.0</top><bottom>7.0</bottom><left>7.0</left><right>7.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>true</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.COMM_OK</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>33</htmlId><value>PLC1</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1286.7</x><y>56.0</y><top>10.0</top><bottom>10.0</bottom><left>12.7</left><right>12.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<ellipse type="componentData"><htmlId>34</htmlId><x>1337.0</x><y>57.0</y><top>7.0</top><bottom>7.0</bottom><left>7.0</left><right>7.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>true</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.UA.COMM_OK</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>35</htmlId><value>OPC UA</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1370.5</x><y>56.0</y><top>10.0</top><bottom>10.0</bottom><left>20.5</left><right>20.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>36</htmlId><roundingX>0.0640</roundingX><roundingY>0.2353</roundingY><x>1549.0</x><y>48.0</y><top>34.0</top><bottom>34.0</bottom><left>125.0</left><right>125.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>37</htmlId><value>LIVE DATA</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1462.4</x><y>30.0</y><top>8.0</top><bottom>8.0</bottom><left>24.4</left><right>24.4</right><rotation>0.0</rotation><shear>0.0</shear></text>
<ellipse type="componentData"><htmlId>38</htmlId><x>1542.0</x><y>29.0</y><top>6.0</top><bottom>6.0</bottom><left>6.0</left><right>6.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="71" g="85" b="105"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="71" g="85" b="105"/></thresholdOut><thresholdIn>true</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.DEMO.FEED_ON</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<button type="componentData" x="1490.0" y="59.0" top="15.0" bottom="15.0" left="52.0" right="52.0" rotation="0.0" shear="0.0"><htmlId>39</htmlId><toolTipText>Start the live-data feed (cieng_feed.ps1) on the server</toolTipText><label>Start</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="255" g="255" b="255"/><backgroundColor type="colorSet" r="34" g="197" b="94"/><data type="data"><action type="actionSetItemAttribute"><event type="event" event="On action"/><filter type="filter"><value>1.0</value></filter><connection type="connection"><direction>2</direction><location type="nodeName" node="$default$"/><itemName>CI-Eng-Sample.DEMO.FEED_ON</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionExecuteCommand"><event type="event" event="On action"/><command>cmd /c "C:\Users\Public\CI-Eng-Sample\feed\cieng_feed_start.cmd"</command><onServer>true</onServer></action></data></button>
<button type="componentData" x="1606.0" y="59.0" top="15.0" bottom="15.0" left="52.0" right="52.0" rotation="0.0" shear="0.0"><htmlId>40</htmlId><toolTipText>Stop the feed (ends within 5 s)</toolTipText><label>Stop</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><data type="data"><action type="actionSetItemAttribute"><event type="event" event="On action"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>2</direction><location type="nodeName" node="$default$"/><itemName>CI-Eng-Sample.DEMO.FEED_ON</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></button>
<button type="componentData" x="1734.0" y="48.0" top="34.0" bottom="34.0" left="46.0" right="46.0" rotation="0.0" shear="0.0"><htmlId>41</htmlId><toolTipText>Open the Tank 1 faceplate popup</toolTipText><label>Tank 1</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="255" g="255" b="255"/><backgroundColor type="colorSet" r="59" g="130" b="246"/><data type="data"><action type="actionActivateDisplay"><event type="event" event="On action"/><type type="displayActivationType" value="ActivateSpecific"/><display>CIENG_TankFaceplate</display><layout>CIENG_Popup</layout><layoutFrame>default</layoutFrame></action></data></button>
<text type="componentData"><htmlId>42</htmlId><value>LAST UPDATE</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1823.7</x><y>30.0</y><top>8.0</top><bottom>8.0</bottom><left>31.7</left><right>31.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<numberField type="componentData" x="1853.0" y="58.0" top="14.0" bottom="14.0" left="61.0" right="61.0" rotation="0.0" shear="0.0"><htmlId>43</htmlId><font type="font" name="Consolas" bold="true" size="9" underline="false" strikethrough="false"/><format></format><editable>false</editable><asDateTime>true</asDateTime><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><justification type="jTextJustification" value="TextJustificationRight"/><data type="data"><action type="actionConnectTo"><property type="property" name="numberField.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.DEMO.COUNTER</itemName><itemAttribute>ItemUpdTime</itemAttribute></connection></action></data></numberField>
</coreObjectDefinition>
</visualization>

View file

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8" ?>
<visualization protocolVersion="1.3.0.0">
<globalSection/>
<coreObjectDefinition type="displayDefinition">
<version type="version" value="1.3.0.0"/>
<html>true</html>
<width>200</width>
<height>700</height>
<referenceCheck>2</referenceCheck>
<defaultBgColor type="colorSet" r="255" g="255" b="255"/>
<defaultFgColor type="colorSet" r="0" g="0" b="0"/>
<defaultFont type="font" name="Tahoma" size="11" underline="false" strikethrough="false"/>
<defaultStroke type="stroke" width="1.0"/>
<grid type="grid" gridVisible="true" snappingActive="true" verticalSnapInterval="8" horizontalSnapInterval="8" onTop="false">
<color type="colorSet" r="0" g="0" b="0"/>
</grid>
<revisionHistory type="revisionHistory">
<revision type="revision" who="ADMIN" when="2026.10.01 15:05:12.398 AEST" what="Created" where="PXiSEDev"/>
</revisionHistory>
<blinkDelay>500</blinkDelay>
<blinkEnabled>true</blinkEnabled>
<mousePassThrough>false</mousePassThrough>
<visibilityGroup type="componentData">
<htmlId>2</htmlId>
<name>Overview</name>
<description>Always shown</description>
<minimumZoomEnabled>true</minimumZoomEnabled>
<minimumZoomFactor>10.0</minimumZoomFactor>
</visibilityGroup>
<visibilityGroup type="componentData">
<htmlId>3</htmlId>
<name>Rough</name>
<description>Shown when viewing viewing a large area</description>
<minimumZoomEnabled>true</minimumZoomEnabled>
<minimumZoomFactor>25.0</minimumZoomFactor>
</visibilityGroup>
<visibilityGroup type="componentData">
<htmlId>4</htmlId>
<name>Standard</name>
<description>Shown when using the default view setting</description>
<minimumZoomEnabled>true</minimumZoomEnabled>
<minimumZoomFactor>100.0</minimumZoomFactor>
</visibilityGroup>
<visibilityGroup type="componentData">
<htmlId>5</htmlId>
<name>Detail</name>
<description>Shown only when viewing a small area</description>
<minimumZoomEnabled>true</minimumZoomEnabled>
<minimumZoomFactor>400.0</minimumZoomFactor>
</visibilityGroup>
<visibilityGroup type="componentData">
<htmlId>6</htmlId>
<name>Intricacies</name>
<description>Shown only when viewing a very small area</description>
<minimumZoomEnabled>true</minimumZoomEnabled>
<minimumZoomFactor>1000.0</minimumZoomFactor>
</visibilityGroup>
<visualizationLayer type="componentData">
<htmlId>1</htmlId>
<name>Layer1</name>
</visualizationLayer>
<componentCountHint>3</componentCountHint>
<button type="componentData" x="100.0" y="44.0" top="20.0" bottom="20.0" left="84.0" right="84.0" rotation="0.0" shear="0.0">
<htmlId>7</htmlId>
<label>Tank 1</label>
<data type="data">
<action type="actionActivateDisplay">
<event type="event" event="On action"/>
<display>CIENG_Tank</display>
</action>
</data>
</button>
<button type="componentData" x="100.0" y="108.0" top="20.0" bottom="20.0" left="84.0" right="84.0" rotation="0.0" shear="0.0">
<htmlId>8</htmlId>
<label>Current Alarm</label>
<data type="data">
<action type="actionActivateDisplay">
<event type="event" event="On action"/>
<display>AOG_AlarmCurrent</display>
</action>
</data>
</button>
<button type="componentData" x="100.0" y="180.0" top="20.0" bottom="20.0" left="84.0" right="84.0" rotation="0.0" shear="0.0">
<htmlId>9</htmlId>
<label>Tank 1 popup</label>
<data type="data">
<action type="actionActivateDisplay">
<event type="event" event="On action"/>
<type type="displayActivationType" value="ActivateSpecific"/>
<display>CIENG_Tank</display>
<layout>popup</layout>
<layoutFrame>default</layoutFrame>
</action>
</data>
</button>
</coreObjectDefinition>
</visualization>

View file

@ -1,100 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<visualization protocolVersion="1.3.0.0">
<globalSection/>
<coreObjectDefinition type="displayDefinition">
<version type="version" value="1.3.0.0"/>
<title>Overview</title>
<html>true</html>
<width>1880</width>
<height>760</height>
<referenceCheck>76</referenceCheck>
<backgroundColor type="colorSet" r="13" g="17" b="23"/>
<backgroundColorOn>true</backgroundColorOn>
<defaultBgColor type="colorSet" r="13" g="17" b="23"/>
<defaultFgColor type="colorSet" r="230" g="237" b="243"/>
<defaultFont type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/>
<defaultStroke type="stroke" width="1.0"/>
<grid type="grid" gridVisible="true" snappingActive="true" verticalSnapInterval="4" horizontalSnapInterval="4" onTop="false"><color type="colorSet" r="51" g="59" b="71"/></grid>
<revisionHistory type="revisionHistory"><revision type="revision" who="ADMIN" when="2026.10.02 12:00:00.000 AEST" what="Generated by displays/generator/build.py" where="localhost"/></revisionHistory>
<blinkDelay>500</blinkDelay>
<blinkEnabled>true</blinkEnabled>
<mousePassThrough>false</mousePassThrough>
<visibilityGroup type="componentData"><htmlId>2</htmlId><name>Overview</name><description>Always shown</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>10.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>3</htmlId><name>Rough</name><description>Shown when viewing viewing a large area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>25.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>4</htmlId><name>Standard</name><description>Shown when using the default view setting</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>100.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>5</htmlId><name>Detail</name><description>Shown only when viewing a small area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>400.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>6</htmlId><name>Intricacies</name><description>Shown only when viewing a very small area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>1000.0</minimumZoomFactor></visibilityGroup>
<visualizationLayer type="componentData"><htmlId>1</htmlId><name>Layer1</name></visualizationLayer>
<componentCountHint>70</componentCountHint>
<rectangle type="componentData"><htmlId>7</htmlId><x>940.0</x><y>380.0</y><top>380.0</top><bottom>380.0</bottom><left>940.0</left><right>940.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="13" g="17" b="23"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>8</htmlId><roundingX>0.0180</roundingX><roundingY>0.0271</roundingY><x>565.0</x><y>380.0</y><top>368.8</top><bottom>368.8</bottom><left>555.0</left><right>555.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>9</htmlId><value>PROCESS - TANK 1</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>76.8</x><y>36.9</y><top>11.0</top><bottom>11.0</bottom><left>46.8</left><right>46.8</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>10</htmlId><value>Click the tank for its faceplate</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="88" g="100" b="116"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>92.4</x><y>59.2</y><top>9.0</top><bottom>9.0</bottom><left>62.4</left><right>62.4</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>11</htmlId><x>250.0</x><y>377.8</y><top>8.0</top><bottom>8.0</bottom><left>190.0</left><right>190.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="40" g="50" b="64"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>12</htmlId><x>250.0</x><y>377.8</y><top>5.0</top><bottom>5.0</bottom><left>190.0</left><right>190.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="20" g="184" b="166"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="rectangle.visible"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>java.lang.Boolean</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut>false</thresholdOut><thresholdIn>5.0</thresholdIn><thresholdOut>true</thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.INFLOW</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></rectangle>
<text type="componentData"><htmlId>13</htmlId><value>INFLOW</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>79.0</x><y>288.4</y><top>8.0</top><bottom>8.0</bottom><left>19.0</left><right>19.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>14</htmlId><value>0.0</value><format>9999.9</format><font type="font" name="Consolas" bold="true" size="30" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>109.7</x><y>321.9</y><top>20.0</top><bottom>20.0</bottom><left>49.7</left><right>49.7</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.INFLOW</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>15</htmlId><value>m3/h</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>227.7</x><y>326.4</y><top>10.0</top><bottom>10.0</bottom><left>13.7</left><right>13.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>16</htmlId><toolTipText>Tank 1 - click for the faceplate</toolTipText><roundingX>0.1500</roundingX><roundingY>0.0671</roundingY><x>560.0</x><y>380.0</y><top>268.2</top><bottom>268.2</bottom><left>120.0</left><right>120.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="2.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint><data type="data"><action type="actionActivateDisplay"><event type="event" event="Clicked b1"/><type type="displayActivationType" value="ActivateSpecific"/><display>CIENG_TankFaceplate</display><layout>CIENG_Popup</layout><layoutFrame>default</layoutFrame></action></data></rectangle>
<rectangle type="componentData"><htmlId>17</htmlId><roundingX>0.1091</roundingX><roundingY>0.0467</roundingY><x>560.0</x><y>380.0</y><top>257.1</top><bottom>257.1</bottom><left>110.0</left><right>110.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="59" g="130" b="246"/></fillPaint><fillAmount>0.5</fillAmount><fillDirection type="fillDirection" value="FillDirectionUp"/><data type="data"><action type="actionConnectTo"><property type="property" name="rectangle.fillAmount"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>100.0</inputValueEnd><outputValueStart>0.0</outputValueStart><outputValueEnd>1.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="rectangle.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="185" g="28" b="28"/></thresholdOut><thresholdIn>10.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="180" g="83" b="9"/></thresholdOut><thresholdIn>20.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="37" g="99" b="235"/></thresholdOut><thresholdIn>80.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="180" g="83" b="9"/></thresholdOut><thresholdIn>90.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="185" g="28" b="28"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionActivateDisplay"><event type="event" event="Clicked b1"/><type type="displayActivationType" value="ActivateSpecific"/><display>CIENG_TankFaceplate</display><layout>CIENG_Popup</layout><layoutFrame>default</layoutFrame></action></data></rectangle>
<text type="componentData"><htmlId>18</htmlId><value>TANK 1</value><font type="font" name="Segoe UI" bold="true" size="16" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>560.0</x><y>82.7</y><top>14.0</top><bottom>14.0</bottom><left>110.0</left><right>110.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>19</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="40" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="255" g="255" b="255"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>560.0</x><y>363.2</y><top>25.0</top><bottom>25.0</bottom><left>100.0</left><right>100.0</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>20</htmlId><value>% level</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>560.0</x><y>404.6</y><top>10.0</top><bottom>10.0</bottom><left>100.0</left><right>100.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>21</htmlId><x>691.0</x><y>174.4</y><top>1.0</top><bottom>1.0</bottom><left>9.0</left><right>9.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint></rectangle>
<text type="componentData"><htmlId>22</htmlId><value>HH 90</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>721.1</x><y>174.4</y><top>9.0</top><bottom>9.0</bottom><left>15.1</left><right>15.1</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>23</htmlId><x>691.0</x><y>225.8</y><top>1.0</top><bottom>1.0</bottom><left>9.0</left><right>9.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="245" g="158" b="11"/></fillPaint></rectangle>
<text type="componentData"><htmlId>24</htmlId><value>H 80</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="245" g="158" b="11"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>717.2</x><y>225.8</y><top>9.0</top><bottom>9.0</bottom><left>11.2</left><right>11.2</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>25</htmlId><x>691.0</x><y>534.2</y><top>1.0</top><bottom>1.0</bottom><left>9.0</left><right>9.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="245" g="158" b="11"/></fillPaint></rectangle>
<text type="componentData"><htmlId>26</htmlId><value>L 20</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="245" g="158" b="11"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>715.8</x><y>534.2</y><top>9.0</top><bottom>9.0</bottom><left>9.8</left><right>9.8</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>27</htmlId><x>691.0</x><y>585.6</y><top>1.0</top><bottom>1.0</bottom><left>9.0</left><right>9.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint></rectangle>
<text type="componentData"><htmlId>28</htmlId><value>LL 10</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>718.2</x><y>585.6</y><top>9.0</top><bottom>9.0</bottom><left>12.2</left><right>12.2</right><rotation>0.0</rotation><shear>0.0</shear></text>
<button type="componentData" x="560.0" y="681.8" top="16.0" bottom="16.0" left="90.0" right="90.0" rotation="0.0" shear="0.0"><htmlId>29</htmlId><label>Open faceplate</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="255" g="255" b="255"/><backgroundColor type="colorSet" r="59" g="130" b="246"/><data type="data"><action type="actionActivateDisplay"><event type="event" event="On action"/><type type="displayActivationType" value="ActivateSpecific"/><display>CIENG_TankFaceplate</display><layout>CIENG_Popup</layout><layoutFrame>default</layoutFrame></action></data></button>
<rectangle type="componentData"><htmlId>30</htmlId><x>755.0</x><y>603.5</y><top>8.0</top><bottom>8.0</bottom><left>75.0</left><right>75.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="40" g="50" b="64"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>31</htmlId><x>755.0</x><y>603.5</y><top>5.0</top><bottom>5.0</bottom><left>75.0</left><right>75.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="20" g="184" b="166"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="rectangle.visible"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.RUNNING</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></rectangle>
<ellipse type="componentData"><htmlId>32</htmlId><x>875.0</x><y>603.5</y><top>45.0</top><bottom>45.0</bottom><left>45.0</left><right>45.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="2.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="71" g="85" b="105"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="71" g="85" b="105"/></thresholdOut><thresholdIn>true</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.RUNNING</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>33</htmlId><value>P1</value><font type="font" name="Segoe UI" bold="true" size="16" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="255" g="255" b="255"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>875.0</x><y>603.5</y><top>12.0</top><bottom>12.0</bottom><left>45.0</left><right>45.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>34</htmlId><x>1005.0</x><y>603.5</y><top>8.0</top><bottom>8.0</bottom><left>85.0</left><right>85.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="40" g="50" b="64"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>35</htmlId><x>1005.0</x><y>603.5</y><top>5.0</top><bottom>5.0</bottom><left>85.0</left><right>85.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="20" g="184" b="166"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="rectangle.visible"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.RUNNING</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></rectangle>
<text type="componentData"><htmlId>36</htmlId><value>PUMP 1</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>875.0</x><y>680.6</y><top>9.0</top><bottom>9.0</bottom><left>75.0</left><right>75.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>37</htmlId><value>AUTO</value><font type="font" name="Segoe UI" bold="true" size="13" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="20" g="184" b="166"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>875.0</x><y>704.1</y><top>10.0</top><bottom>10.0</bottom><left>75.0</left><right>75.0</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.visible"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>java.lang.Boolean</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut>false</thresholdOut><thresholdIn>1.0</thresholdIn><thresholdOut>true</thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.MODE</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></text>
<text type="componentData"><htmlId>38</htmlId><value>MANUAL</value><font type="font" name="Segoe UI" bold="true" size="13" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="245" g="158" b="11"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>875.0</x><y>704.1</y><top>10.0</top><bottom>10.0</bottom><left>75.0</left><right>75.0</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.visible"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>java.lang.Boolean</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut>true</thresholdOut><thresholdIn>1.0</thresholdIn><thresholdOut>false</thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.MODE</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></text>
<rectangle type="componentData"><htmlId>39</htmlId><roundingX>0.0696</roundingX><roundingY>0.0434</roundingY><x>975.0</x><y>285.0</y><top>184.4</top><bottom>184.4</bottom><left>115.0</left><right>115.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint></rectangle>
<text type="componentData"><htmlId>40</htmlId><value>VOLUME (TANK1.CALC)</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>926.2</x><y>125.2</y><top>8.0</top><bottom>8.0</bottom><left>50.2</left><right>50.2</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>41</htmlId><value>0.0</value><format>9999.9</format><font type="font" name="Consolas" bold="true" size="22" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>911.1</x><y>153.1</y><top>15.0</top><bottom>15.0</bottom><left>35.1</left><right>35.1</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.CALC.VOLUME</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>42</htmlId><value>m3</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1035.3</x><y>155.4</y><top>9.0</top><bottom>9.0</bottom><left>7.3</left><right>7.3</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>43</htmlId><value>FLOW PER SECOND (JFLOW)</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>938.4</x><y>196.7</y><top>8.0</top><bottom>8.0</bottom><left>62.4</left><right>62.4</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>44</htmlId><value>0.0</value><format>999.99</format><font type="font" name="Consolas" bold="true" size="22" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>911.1</x><y>224.6</y><top>15.0</top><bottom>15.0</bottom><left>35.1</left><right>35.1</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.JFLOW.sPerMin</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>45</htmlId><value>m3/s</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1039.7</x><y>226.9</y><top>9.0</top><bottom>9.0</bottom><left>11.7</left><right>11.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>46</htmlId><value>LEVEL MAXIMUM</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>914.0</x><y>268.2</y><top>8.0</top><bottom>8.0</bottom><left>38.0</left><right>38.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>47</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="22" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>905.2</x><y>296.2</y><top>15.0</top><bottom>15.0</bottom><left>29.2</left><right>29.2</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL.MAX</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>48</htmlId><value>%</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1032.4</x><y>298.4</y><top>9.0</top><bottom>9.0</bottom><left>4.4</left><right>4.4</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>49</htmlId><value>COUNTER (DEMO.INCR1)</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>930.1</x><y>339.8</y><top>8.0</top><bottom>8.0</bottom><left>54.1</left><right>54.1</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>50</htmlId><value>0.0</value><format>999</format><font type="font" name="Consolas" bold="true" size="22" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>893.5</x><y>367.7</y><top>15.0</top><bottom>15.0</bottom><left>17.6</left><right>17.6</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.DEMO.COUNTER</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>51</htmlId><value></value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1030.0</x><y>369.9</y><top>9.0</top><bottom>9.0</bottom><left>2.0</left><right>2.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<dataBar type="componentData" x="975.0" y="399.0" top="5.0" bottom="5.0" left="99.0" right="99.0" rotation="0.0" shear="0.0"><htmlId>52</htmlId><fillOn>true</fillOn><background type="paint"><paint type="colorSet" r="40" g="50" b="64"/></background><foreground type="paint"><paint type="colorSet" r="139" g="92" b="246"/></foreground><borderColor type="paint"><paint type="colorSet" r="40" g="50" b="64"/></borderColor><foregroundBorderColor type="paint"><paint type="colorSet" r="139" g="92" b="246"/></foregroundBorderColor><lowLimit>0.0</lowLimit><highLimit>100.0</highLimit><growthDirection type="growthDirection" value="GrowthDirectionRight"/><data type="data"><action type="actionConnectTo"><property type="property" name="dataBar.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.DEMO.COUNTER</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></dataBar>
<text type="componentData"><htmlId>53</htmlId><value>PUMP RUN TIME</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>913.0</x><y>429.2</y><top>8.0</top><bottom>8.0</bottom><left>37.0</left><right>37.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>54</htmlId><value>0.0</value><format>9999999</format><font type="font" name="Consolas" bold="true" size="16" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>906.7</x><y>451.5</y><top>12.0</top><bottom>12.0</bottom><left>30.7</left><right>30.7</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PUMP1.RUNNING.RUN_SECONDS</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>55</htmlId><value>s</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1032.4</x><y>452.6</y><top>9.0</top><bottom>9.0</bottom><left>2.4</left><right>2.4</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>56</htmlId><roundingX>0.0270</roundingX><roundingY>0.0542</roundingY><x>1500.0</x><y>195.6</y><top>184.4</top><bottom>184.4</bottom><left>370.0</left><right>370.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>57</htmlId><value>KEY FIGURES</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1182.7</x><y>36.9</y><top>11.0</top><bottom>11.0</bottom><left>32.7</left><right>32.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<arc type="componentData"><htmlId>58</htmlId><startAngle>45.0</startAngle><extentAngle>270.0</extentAngle><closed>false</closed><x>1255.0</x><y>195.6</y><top>95.0</top><bottom>95.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="40" g="50" b="64"/></strokePaint><fillOn>false</fillOn></arc>
<arc type="componentData"><htmlId>59</htmlId><startAngle>179.8</startAngle><extentAngle>0.5</extentAngle><closed>false</closed><x>1255.0</x><y>195.6</y><top>95.0</top><bottom>95.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="20" g="184" b="166"/></strokePaint><fillOn>false</fillOn><data type="data"><action type="actionConnectTo"><property type="property" name="arc.extentAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>100.0</inputValueEnd><outputValueStart>0.5</outputValueStart><outputValueEnd>270.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="arc.startAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>100.0</inputValueEnd><outputValueStart>179.75</outputValueStart><outputValueEnd>45.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="arc.strokePaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>10.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>20.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="20" g="184" b="166"/></thresholdOut><thresholdIn>80.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>90.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></arc>
<number type="componentData"><htmlId>60</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="26" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1255.0</x><y>191.1</y><top>18.0</top><bottom>18.0</bottom><left>81.0</left><right>81.0</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="number.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>10.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>20.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="20" g="184" b="166"/></thresholdOut><thresholdIn>80.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>90.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>61</htmlId><value>%</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1255.0</x><y>223.5</y><top>9.0</top><bottom>9.0</bottom><left>40.0</left><right>40.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>62</htmlId><value>Level</value><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1255.0</x><y>306.2</y><top>10.0</top><bottom>10.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<arc type="componentData"><htmlId>63</htmlId><startAngle>45.0</startAngle><extentAngle>270.0</extentAngle><closed>false</closed><x>1500.0</x><y>195.6</y><top>95.0</top><bottom>95.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="40" g="50" b="64"/></strokePaint><fillOn>false</fillOn></arc>
<arc type="componentData"><htmlId>64</htmlId><startAngle>179.8</startAngle><extentAngle>0.5</extentAngle><closed>false</closed><x>1500.0</x><y>195.6</y><top>95.0</top><bottom>95.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="139" g="92" b="246"/></strokePaint><fillOn>false</fillOn><data type="data"><action type="actionConnectTo"><property type="property" name="arc.extentAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>500.0</inputValueEnd><outputValueStart>0.5</outputValueStart><outputValueEnd>270.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.INFLOW</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="arc.startAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>500.0</inputValueEnd><outputValueStart>179.75</outputValueStart><outputValueEnd>45.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.INFLOW</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></arc>
<number type="componentData"><htmlId>65</htmlId><value>0.0</value><format>9999</format><font type="font" name="Consolas" bold="true" size="26" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1500.0</x><y>191.1</y><top>18.0</top><bottom>18.0</bottom><left>81.0</left><right>81.0</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.INFLOW</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>66</htmlId><value>m3/h</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1500.0</x><y>223.5</y><top>9.0</top><bottom>9.0</bottom><left>40.0</left><right>40.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>67</htmlId><value>Inflow</value><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1500.0</x><y>306.2</y><top>10.0</top><bottom>10.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<arc type="componentData"><htmlId>68</htmlId><startAngle>45.0</startAngle><extentAngle>270.0</extentAngle><closed>false</closed><x>1745.0</x><y>195.6</y><top>95.0</top><bottom>95.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="40" g="50" b="64"/></strokePaint><fillOn>false</fillOn></arc>
<arc type="componentData"><htmlId>69</htmlId><startAngle>179.8</startAngle><extentAngle>0.5</extentAngle><closed>false</closed><x>1745.0</x><y>195.6</y><top>95.0</top><bottom>95.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="59" g="130" b="246"/></strokePaint><fillOn>false</fillOn><data type="data"><action type="actionConnectTo"><property type="property" name="arc.extentAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>200.0</inputValueEnd><outputValueStart>0.5</outputValueStart><outputValueEnd>270.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.CALC.VOLUME</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="arc.startAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>200.0</inputValueEnd><outputValueStart>179.75</outputValueStart><outputValueEnd>45.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.CALC.VOLUME</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></arc>
<number type="componentData"><htmlId>70</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="26" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1745.0</x><y>191.1</y><top>18.0</top><bottom>18.0</bottom><left>81.0</left><right>81.0</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.CALC.VOLUME</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>71</htmlId><value>m3</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1745.0</x><y>223.5</y><top>9.0</top><bottom>9.0</bottom><left>40.0</left><right>40.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>72</htmlId><value>Volume</value><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1745.0</x><y>306.2</y><top>10.0</top><bottom>10.0</bottom><left>95.0</left><right>95.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>73</htmlId><roundingX>0.0270</roundingX><roundingY>0.0559</roundingY><x>1500.0</x><y>570.0</y><top>178.8</top><bottom>178.8</bottom><left>370.0</left><right>370.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>74</htmlId><value>LAST 10 MINUTES</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1195.3</x><y>416.9</y><top>11.0</top><bottom>11.0</bottom><left>45.3</left><right>45.3</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>75</htmlId><value>Micro trend: level (teal, 0-100 %) and inflow (violet, 0-500 m3/h)</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="88" g="100" b="116"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1284.5</x><y>439.2</y><top>9.0</top><bottom>9.0</bottom><left>134.5</left><right>134.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<microTrend type="componentData" x="1500.0" y="592.4" top="134.1" bottom="134.1" left="350.0" right="350.0" rotation="0.0" shear="0.0"><htmlId>76</htmlId><numberOfPens>2</numberOfPens><realTime>true</realTime><fillWithHistory>true</fillWithHistory><microTrendBackgroundFillOn>true</microTrendBackgroundFillOn><lowHighFillOn>false</lowHighFillOn><microTrendBackgroundFillColor type="colorSet" r="22" g="27" b="34"/><microTrendBackgroundColor type="colorSet" r="48" g="61" b="77"/><property type="componentProperty"><name>itemName[0]</name><value/></property><property type="componentProperty"><name>scaleMin[0]</name><value>0.0</value></property><property type="componentProperty"><name>scaleMax[0]</name><value>100.0</value></property><property type="componentProperty"><name>color[0]</name><value type="colorSet" r="20" g="184" b="166"/></property><property type="componentProperty"><name>stroke[0]</name><value type="stroke" width="2.0"/></property><property type="componentProperty"><name>itemName[1]</name><value/></property><property type="componentProperty"><name>scaleMin[1]</name><value>0.0</value></property><property type="componentProperty"><name>scaleMax[1]</name><value>500.0</value></property><property type="componentProperty"><name>color[1]</name><value type="colorSet" r="139" g="92" b="246"/></property><property type="componentProperty"><name>stroke[1]</name><value type="stroke" width="2.0"/></property><data type="data"><action type="actionInternalServiced"/><action type="actionConnectTo"><property type="property" name="microTrend.itemName[0]"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemName</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="microTrend.itemName[1]"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.INFLOW</itemName><itemAttribute>ItemName</itemAttribute></connection></action></data></microTrend>
</coreObjectDefinition>
</visualization>

View file

@ -1,84 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<visualization protocolVersion="1.3.0.0">
<globalSection/>
<coreObjectDefinition type="displayDefinition">
<version type="version" value="1.3.0.0"/>
<title>System</title>
<html>true</html>
<width>1880</width>
<height>760</height>
<referenceCheck>60</referenceCheck>
<backgroundColor type="colorSet" r="13" g="17" b="23"/>
<backgroundColorOn>true</backgroundColorOn>
<defaultBgColor type="colorSet" r="13" g="17" b="23"/>
<defaultFgColor type="colorSet" r="230" g="237" b="243"/>
<defaultFont type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/>
<defaultStroke type="stroke" width="1.0"/>
<grid type="grid" gridVisible="true" snappingActive="true" verticalSnapInterval="4" horizontalSnapInterval="4" onTop="false"><color type="colorSet" r="51" g="59" b="71"/></grid>
<revisionHistory type="revisionHistory"><revision type="revision" who="ADMIN" when="2026.10.02 12:00:00.000 AEST" what="Generated by displays/generator/build.py" where="localhost"/></revisionHistory>
<blinkDelay>500</blinkDelay>
<blinkEnabled>true</blinkEnabled>
<mousePassThrough>false</mousePassThrough>
<visibilityGroup type="componentData"><htmlId>2</htmlId><name>Overview</name><description>Always shown</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>10.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>3</htmlId><name>Rough</name><description>Shown when viewing viewing a large area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>25.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>4</htmlId><name>Standard</name><description>Shown when using the default view setting</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>100.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>5</htmlId><name>Detail</name><description>Shown only when viewing a small area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>400.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>6</htmlId><name>Intricacies</name><description>Shown only when viewing a very small area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>1000.0</minimumZoomFactor></visibilityGroup>
<visualizationLayer type="componentData"><htmlId>1</htmlId><name>Layer1</name></visualizationLayer>
<componentCountHint>54</componentCountHint>
<rectangle type="componentData"><htmlId>7</htmlId><x>940.0</x><y>380.0</y><top>380.0</top><bottom>380.0</bottom><left>940.0</left><right>940.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="13" g="17" b="23"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>8</htmlId><roundingX>0.0333</roundingX><roundingY>0.0559</roundingY><x>310.0</x><y>190.0</y><top>178.8</top><bottom>178.8</bottom><left>300.0</left><right>300.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>9</htmlId><value>SERVER HEALTH</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>70.9</x><y>36.9</y><top>11.0</top><bottom>11.0</bottom><left>40.9</left><right>40.9</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>10</htmlId><value>Real values of this PC, written by the live-data feed</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="88" g="100" b="116"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>137.2</x><y>59.2</y><top>9.0</top><bottom>9.0</bottom><left>107.2</left><right>107.2</right><rotation>0.0</rotation><shear>0.0</shear></text>
<arc type="componentData"><htmlId>11</htmlId><startAngle>45.0</startAngle><extentAngle>270.0</extentAngle><closed>false</closed><x>160.0</x><y>201.2</y><top>100.0</top><bottom>100.0</bottom><left>100.0</left><right>100.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="40" g="50" b="64"/></strokePaint><fillOn>false</fillOn></arc>
<arc type="componentData"><htmlId>12</htmlId><startAngle>179.8</startAngle><extentAngle>0.5</extentAngle><closed>false</closed><x>160.0</x><y>201.2</y><top>100.0</top><bottom>100.0</bottom><left>100.0</left><right>100.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="20" g="184" b="166"/></strokePaint><fillOn>false</fillOn><data type="data"><action type="actionConnectTo"><property type="property" name="arc.extentAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>100.0</inputValueEnd><outputValueStart>0.5</outputValueStart><outputValueEnd>270.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.CPU_LOAD</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="arc.startAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>100.0</inputValueEnd><outputValueStart>179.75</outputValueStart><outputValueEnd>45.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.CPU_LOAD</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="arc.strokePaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="20" g="184" b="166"/></thresholdOut><thresholdIn>80.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>90.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.CPU_LOAD</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></arc>
<number type="componentData"><htmlId>13</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="26" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>160.0</x><y>196.7</y><top>18.0</top><bottom>18.0</bottom><left>86.0</left><right>86.0</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.CPU_LOAD</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>14</htmlId><value>%</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>160.0</x><y>229.1</y><top>9.0</top><bottom>9.0</bottom><left>40.0</left><right>40.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>15</htmlId><value>CPU load</value><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>160.0</x><y>317.4</y><top>10.0</top><bottom>10.0</bottom><left>100.0</left><right>100.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<arc type="componentData"><htmlId>16</htmlId><startAngle>45.0</startAngle><extentAngle>270.0</extentAngle><closed>false</closed><x>450.0</x><y>201.2</y><top>100.0</top><bottom>100.0</bottom><left>100.0</left><right>100.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="40" g="50" b="64"/></strokePaint><fillOn>false</fillOn></arc>
<arc type="componentData"><htmlId>17</htmlId><startAngle>179.8</startAngle><extentAngle>0.5</extentAngle><closed>false</closed><x>450.0</x><y>201.2</y><top>100.0</top><bottom>100.0</bottom><left>100.0</left><right>100.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="12.0" endCap="butt"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="59" g="130" b="246"/></strokePaint><fillOn>false</fillOn><data type="data"><action type="actionConnectTo"><property type="property" name="arc.extentAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>100.0</inputValueEnd><outputValueStart>0.5</outputValueStart><outputValueEnd>270.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.DISK_C</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="arc.startAngle"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationLinear"><inputType>java.lang.Double</inputType><outputType>java.lang.Double</outputType><inputValueStart>0.0</inputValueStart><inputValueEnd>100.0</inputValueEnd><outputValueStart>179.75</outputValueStart><outputValueEnd>45.0</outputValueEnd></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.DISK_C</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="arc.strokePaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="20" g="184" b="166"/></thresholdOut><thresholdIn>80.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>90.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.DISK_C</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></arc>
<number type="componentData"><htmlId>18</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="26" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>450.0</x><y>196.7</y><top>18.0</top><bottom>18.0</bottom><left>86.0</left><right>86.0</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.DISK_C</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>19</htmlId><value>%</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>450.0</x><y>229.1</y><top>9.0</top><bottom>9.0</bottom><left>40.0</left><right>40.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>20</htmlId><value>Disk C: used</value><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>450.0</x><y>317.4</y><top>10.0</top><bottom>10.0</bottom><left>100.0</left><right>100.0</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>21</htmlId><roundingX>0.0333</roundingX><roundingY>0.0559</roundingY><x>920.0</x><y>190.0</y><top>178.8</top><bottom>178.8</bottom><left>300.0</left><right>300.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>22</htmlId><value>COMMUNICATION AND PROCESSES</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>731.6</x><y>36.9</y><top>11.0</top><bottom>11.0</bottom><left>91.6</left><right>91.6</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>23</htmlId><roundingX>0.0214</roundingX><roundingY>0.2440</roundingY><x>920.0</x><y>91.6</y><top>24.6</top><bottom>24.6</bottom><left>280.0</left><right>280.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint></rectangle>
<ellipse type="componentData"><htmlId>24</htmlId><x>665.0</x><y>91.6</y><top>9.0</top><bottom>9.0</bottom><left>9.0</left><right>9.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>true</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.COMM_OK</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>25</htmlId><value>Modbus station CIENG_PLC</value><font type="font" name="Segoe UI" size="13" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>765.5</x><y>91.6</y><top>10.0</top><bottom>10.0</bottom><left>77.5</left><right>77.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>26</htmlId><value>NORMAL</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1165.6</x><y>91.6</y><top>10.0</top><bottom>10.0</bottom><left>24.4</left><right>24.4</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.PLC1.COMM_OK</itemName><itemAttribute>ItemStatusMnemonic</itemAttribute></connection></action></data></text>
<rectangle type="componentData"><htmlId>27</htmlId><roundingX>0.0214</roundingX><roundingY>0.2440</roundingY><x>920.0</x><y>149.8</y><top>24.6</top><bottom>24.6</bottom><left>280.0</left><right>280.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint></rectangle>
<ellipse type="componentData"><htmlId>28</htmlId><x>665.0</x><y>149.8</y><top>9.0</top><bottom>9.0</bottom><left>9.0</left><right>9.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Boolean</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>false</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>true</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.UA.COMM_OK</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>29</htmlId><value>OPC UA client station CIENG_UA</value><font type="font" name="Segoe UI" size="13" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>778.7</x><y>149.8</y><top>10.0</top><bottom>10.0</bottom><left>90.7</left><right>90.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>30</htmlId><value>NORMAL</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1165.6</x><y>149.8</y><top>10.0</top><bottom>10.0</bottom><left>24.4</left><right>24.4</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.UA.COMM_OK</itemName><itemAttribute>ItemStatusMnemonic</itemAttribute></connection></action></data></text>
<rectangle type="componentData"><htmlId>31</htmlId><roundingX>0.0214</roundingX><roundingY>0.2440</roundingY><x>920.0</x><y>207.9</y><top>24.6</top><bottom>24.6</bottom><left>280.0</left><right>280.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint></rectangle>
<ellipse type="componentData"><htmlId>32</htmlId><x>665.0</x><y>207.9</y><top>9.0</top><bottom>9.0</bottom><left>9.0</left><right>9.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="71" g="85" b="105"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut><thresholdIn>0.5</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.UA.SRV_STATE</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>33</htmlId><value>OPC UA server state (0 = running)</value><font type="font" name="Segoe UI" size="13" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>784.5</x><y>207.9</y><top>10.0</top><bottom>10.0</bottom><left>96.5</left><right>96.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>34</htmlId><value>NORMAL</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1165.6</x><y>207.9</y><top>10.0</top><bottom>10.0</bottom><left>24.4</left><right>24.4</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.UA.SRV_STATE</itemName><itemAttribute>ItemStatusMnemonic</itemAttribute></connection></action></data></text>
<rectangle type="componentData"><htmlId>35</htmlId><roundingX>0.0214</roundingX><roundingY>0.2440</roundingY><x>920.0</x><y>266.0</y><top>24.6</top><bottom>24.6</bottom><left>280.0</left><right>280.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint></rectangle>
<ellipse type="componentData"><htmlId>36</htmlId><x>665.0</x><y>266.0</y><top>9.0</top><bottom>9.0</bottom><left>9.0</left><right>9.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="71" g="85" b="105"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>0.5</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.PING_LOCALHOST</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>37</htmlId><value>localhost reachable</value><font type="font" name="Segoe UI" size="13" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>743.1</x><y>266.0</y><top>10.0</top><bottom>10.0</bottom><left>55.1</left><right>55.1</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>38</htmlId><value>NORMAL</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1165.6</x><y>266.0</y><top>10.0</top><bottom>10.0</bottom><left>24.4</left><right>24.4</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.PING_LOCALHOST</itemName><itemAttribute>ItemStatusMnemonic</itemAttribute></connection></action></data></text>
<rectangle type="componentData"><htmlId>39</htmlId><roundingX>0.0214</roundingX><roundingY>0.2440</roundingY><x>920.0</x><y>324.1</y><top>24.6</top><bottom>24.6</bottom><left>280.0</left><right>280.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint></rectangle>
<ellipse type="componentData"><htmlId>40</htmlId><x>665.0</x><y>324.1</y><top>9.0</top><bottom>9.0</bottom><left>9.0</left><right>9.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="71" g="85" b="105"/></fillPaint><data type="data"><action type="actionConnectTo"><property type="property" name="ellipse.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>0.5</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="34" g="197" b="94"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.PROC_ALM</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></ellipse>
<text type="componentData"><htmlId>41</htmlId><value>ALARM process (alm) running</value><font type="font" name="Segoe UI" size="13" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>772.3</x><y>324.1</y><top>10.0</top><bottom>10.0</bottom><left>84.3</left><right>84.3</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>42</htmlId><value>NORMAL</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1165.6</x><y>324.1</y><top>10.0</top><bottom>10.0</bottom><left>24.4</left><right>24.4</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.SYSTEM.PROC_ALM</itemName><itemAttribute>ItemStatusMnemonic</itemAttribute></connection></action></data></text>
<rectangle type="componentData"><htmlId>43</htmlId><roundingX>0.0312</roundingX><roundingY>0.0559</roundingY><x>1550.0</x><y>190.0</y><top>178.8</top><bottom>178.8</bottom><left>320.0</left><right>320.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>44</htmlId><value>OPC UA LOOPBACK</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1299.7</x><y>36.9</y><top>11.0</top><bottom>11.0</bottom><left>49.7</left><right>49.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>45</htmlId><value>TANK1.LEVEL read back through CI Server's own OPC UA server</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="88" g="100" b="116"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1385.5</x><y>59.2</y><top>9.0</top><bottom>9.0</bottom><left>135.5</left><right>135.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>46</htmlId><value>TANK1.LEVEL</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1290.7</x><y>87.2</y><top>8.0</top><bottom>8.0</bottom><left>30.7</left><right>30.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>47</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="32" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="20" g="184" b="166"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1303.9</x><y>125.2</y><top>22.0</top><bottom>22.0</bottom><left>43.9</left><right>43.9</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<dataBar type="componentData" x="1390.0" y="177.7" top="9.0" bottom="9.0" left="130.0" right="130.0" rotation="0.0" shear="0.0"><htmlId>48</htmlId><fillOn>true</fillOn><background type="paint"><paint type="colorSet" r="40" g="50" b="64"/></background><foreground type="paint"><paint type="colorSet" r="20" g="184" b="166"/></foreground><borderColor type="paint"><paint type="colorSet" r="40" g="50" b="64"/></borderColor><foregroundBorderColor type="paint"><paint type="colorSet" r="20" g="184" b="166"/></foregroundBorderColor><lowLimit>0.0</lowLimit><highLimit>100.0</highLimit><growthDirection type="growthDirection" value="GrowthDirectionRight"/><data type="data"><action type="actionConnectTo"><property type="property" name="dataBar.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></dataBar>
<text type="componentData"><htmlId>49</htmlId><value>LAST UPDATE</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1291.7</x><y>212.4</y><top>8.0</top><bottom>8.0</bottom><left>31.7</left><right>31.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<numberField type="componentData" x="1390.0" y="241.4" top="14.0" bottom="14.0" left="130.0" right="130.0" rotation="0.0" shear="0.0"><htmlId>50</htmlId><font type="font" name="Consolas" bold="true" size="13" underline="false" strikethrough="false"/><format></format><editable>false</editable><asDateTime>true</asDateTime><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><justification type="jTextJustification" value="TextJustificationRight"/><data type="data"><action type="actionConnectTo"><property type="property" name="numberField.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemUpdTime</itemAttribute></connection></action></data></numberField>
<text type="componentData"><htmlId>51</htmlId><value>UA.LEVEL_COPY</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1596.1</x><y>87.2</y><top>8.0</top><bottom>8.0</bottom><left>36.1</left><right>36.1</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>52</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="32" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="59" g="130" b="246"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1603.9</x><y>125.2</y><top>22.0</top><bottom>22.0</bottom><left>43.9</left><right>43.9</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.UA.LEVEL_COPY</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<dataBar type="componentData" x="1690.0" y="177.7" top="9.0" bottom="9.0" left="130.0" right="130.0" rotation="0.0" shear="0.0"><htmlId>53</htmlId><fillOn>true</fillOn><background type="paint"><paint type="colorSet" r="40" g="50" b="64"/></background><foreground type="paint"><paint type="colorSet" r="59" g="130" b="246"/></foreground><borderColor type="paint"><paint type="colorSet" r="40" g="50" b="64"/></borderColor><foregroundBorderColor type="paint"><paint type="colorSet" r="59" g="130" b="246"/></foregroundBorderColor><lowLimit>0.0</lowLimit><highLimit>100.0</highLimit><growthDirection type="growthDirection" value="GrowthDirectionRight"/><data type="data"><action type="actionConnectTo"><property type="property" name="dataBar.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.UA.LEVEL_COPY</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></dataBar>
<text type="componentData"><htmlId>54</htmlId><value>LAST UPDATE</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>1591.7</x><y>212.4</y><top>8.0</top><bottom>8.0</bottom><left>31.7</left><right>31.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<numberField type="componentData" x="1690.0" y="241.4" top="14.0" bottom="14.0" left="130.0" right="130.0" rotation="0.0" shear="0.0"><htmlId>55</htmlId><font type="font" name="Consolas" bold="true" size="13" underline="false" strikethrough="false"/><format></format><editable>false</editable><asDateTime>true</asDateTime><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><justification type="jTextJustification" value="TextJustificationRight"/><data type="data"><action type="actionConnectTo"><property type="property" name="numberField.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.UA.LEVEL_COPY</itemName><itemAttribute>ItemUpdTime</itemAttribute></connection></action></data></numberField>
<rectangularScale type="componentData" x="1540.0" y="298.4" top="17.0" bottom="17.0" left="280.0" right="280.0" rotation="0.0" shear="0.0"><htmlId>56</htmlId><maximum>100.0</maximum><minimum>0.0</minimum><majorTickSpacing>10.0</majorTickSpacing><minorTickSpacing>5.0</minorTickSpacing><format>999</format><vertical>false</vertical><color type="colorSet" r="139" g="152" b="168"/><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/></rectangularScale>
<rectangle type="componentData"><htmlId>57</htmlId><roundingX>0.0108</roundingX><roundingY>0.0542</roundingY><x>940.0</x><y>564.4</y><top>184.4</top><bottom>184.4</bottom><left>930.0</left><right>930.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>true</strokeOn><strokePaint type="paint"><paint type="colorSet" r="48" g="61" b="77"/></strokePaint><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<text type="componentData"><htmlId>58</htmlId><value>REPORTS</value><font type="font" name="Segoe UI" bold="true" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>52.9</x><y>405.7</y><top>11.0</top><bottom>11.0</bottom><left>22.9</left><right>22.9</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>59</htmlId><value>Report component: select CIENG_TANK1 or CIENG_HTML, generate and view</value><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="88" g="100" b="116"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>193.3</x><y>428.1</y><top>9.0</top><bottom>9.0</bottom><left>163.3</left><right>163.3</right><rotation>0.0</rotation><shear>0.0</shear></text>
<reporting type="componentData" x="940.0" y="586.8" top="150.9" bottom="150.9" left="920.0" right="920.0" rotation="0.0" shear="0.0"><htmlId>60</htmlId><data type="data"><action type="actionInternalServiced"/></data></reporting>
</coreObjectDefinition>
</visualization>

File diff suppressed because it is too large Load diff

View file

@ -1,66 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<visualization protocolVersion="1.3.0.0">
<globalSection/>
<coreObjectDefinition type="displayDefinition">
<version type="version" value="1.3.0.0"/>
<title>Tank 1 faceplate</title>
<html>true</html>
<width>420</width>
<height>600</height>
<referenceCheck>42</referenceCheck>
<backgroundColor type="colorSet" r="28" g="35" b="45"/>
<backgroundColorOn>true</backgroundColorOn>
<defaultBgColor type="colorSet" r="28" g="35" b="45"/>
<defaultFgColor type="colorSet" r="230" g="237" b="243"/>
<defaultFont type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/>
<defaultStroke type="stroke" width="1.0"/>
<grid type="grid" gridVisible="true" snappingActive="true" verticalSnapInterval="4" horizontalSnapInterval="4" onTop="false"><color type="colorSet" r="51" g="59" b="71"/></grid>
<revisionHistory type="revisionHistory"><revision type="revision" who="ADMIN" when="2026.10.02 12:00:00.000 AEST" what="Generated by displays/generator/build.py" where="localhost"/></revisionHistory>
<blinkDelay>500</blinkDelay>
<blinkEnabled>true</blinkEnabled>
<mousePassThrough>false</mousePassThrough>
<visibilityGroup type="componentData"><htmlId>2</htmlId><name>Overview</name><description>Always shown</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>10.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>3</htmlId><name>Rough</name><description>Shown when viewing viewing a large area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>25.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>4</htmlId><name>Standard</name><description>Shown when using the default view setting</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>100.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>5</htmlId><name>Detail</name><description>Shown only when viewing a small area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>400.0</minimumZoomFactor></visibilityGroup>
<visibilityGroup type="componentData"><htmlId>6</htmlId><name>Intricacies</name><description>Shown only when viewing a very small area</description><minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>1000.0</minimumZoomFactor></visibilityGroup>
<visualizationLayer type="componentData"><htmlId>1</htmlId><name>Layer1</name></visualizationLayer>
<componentCountHint>36</componentCountHint>
<rectangle type="componentData"><htmlId>7</htmlId><x>210.0</x><y>300.0</y><top>300.0</top><bottom>300.0</bottom><left>210.0</left><right>210.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="28" g="35" b="45"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>8</htmlId><x>210.0</x><y>26.0</y><top>26.0</top><bottom>26.0</bottom><left>210.0</left><right>210.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="36" g="45" b="57"/></fillPaint></rectangle>
<text type="componentData"><htmlId>9</htmlId><value>TANK 1 | LEVEL</value><font type="font" name="Segoe UI" bold="true" size="15" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>77.5</x><y>26.0</y><top>12.0</top><bottom>12.0</bottom><left>57.5</left><right>57.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<button type="componentData" x="388.0" y="26.0" top="16.0" bottom="16.0" left="18.0" right="18.0" rotation="0.0" shear="0.0"><htmlId>10</htmlId><toolTipText>Close</toolTipText><label>X</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="28" g="35" b="45"/><data type="data"><action type="actionExitDisplay"><event type="event" event="On action"/></action></data></button>
<text type="componentData"><htmlId>11</htmlId><value>Tank 1 level (%)</value><font type="font" name="Segoe UI" size="11" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>57.0</x><y>73.0</y><top>9.0</top><bottom>9.0</bottom><left>37.0</left><right>37.0</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemDesc</itemAttribute></connection></action></data></text>
<number type="componentData"><htmlId>12</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="44" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>78.5</x><y>114.0</y><top>28.0</top><bottom>28.0</bottom><left>58.5</left><right>58.5</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="number.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>10.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>20.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="20" g="184" b="166"/></thresholdOut><thresholdIn>80.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>90.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>13</htmlId><value>%</value><font type="font" name="Segoe UI" size="16" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>230.3</x><y>118.0</y><top>12.0</top><bottom>12.0</bottom><left>6.3</left><right>6.3</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>14</htmlId><value>STATUS</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>381.5</x><y>100.0</y><top>8.0</top><bottom>8.0</bottom><left>18.5</left><right>18.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<text type="componentData"><htmlId>15</htmlId><value>NORMAL</value><font type="font" name="Segoe UI" bold="true" size="16" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>366.4</x><y>123.0</y><top>13.0</top><bottom>13.0</bottom><left>33.6</left><right>33.6</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="text.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemStatusMnemonic</itemAttribute></connection></action><action type="actionConnectTo"><property type="property" name="text.fillPaint"/><filter type="filter"><value>0.0</value></filter><transformation type="transformationThreshold"><inputType>java.lang.Double</inputType><outputType>fasttools.jwui.common.property.paint.PaintSet</outputType><thresholdTable type="thresholdTable"><thresholdIn>0.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut><thresholdIn>10.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>20.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="20" g="184" b="166"/></thresholdOut><thresholdIn>80.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="245" g="158" b="11"/></thresholdOut><thresholdIn>90.0</thresholdIn><thresholdOut type="paint"><paint type="colorSet" r="239" g="68" b="68"/></thresholdOut></thresholdTable></transformation><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></text>
<dataBar type="componentData" x="70.0" y="300.0" top="140.0" bottom="140.0" left="30.0" right="30.0" rotation="0.0" shear="0.0"><htmlId>16</htmlId><fillOn>true</fillOn><background type="paint"><paint type="colorSet" r="40" g="50" b="64"/></background><foreground type="paint"><paint type="colorSet" r="59" g="130" b="246"/></foreground><borderColor type="paint"><paint type="colorSet" r="40" g="50" b="64"/></borderColor><foregroundBorderColor type="paint"><paint type="colorSet" r="59" g="130" b="246"/></foregroundBorderColor><lowLimit>0.0</lowLimit><highLimit>100.0</highLimit><growthDirection type="growthDirection" value="GrowthDirectionUp"/><data type="data"><action type="actionConnectTo"><property type="property" name="dataBar.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></dataBar>
<rectangularScale type="componentData" x="126.0" y="300.0" top="140.0" bottom="140.0" left="22.0" right="22.0" rotation="0.0" shear="0.0"><htmlId>17</htmlId><maximum>100.0</maximum><minimum>0.0</minimum><majorTickSpacing>20.0</majorTickSpacing><minorTickSpacing>5.0</minorTickSpacing><format>999</format><vertical>true</vertical><color type="colorSet" r="139" g="152" b="168"/><font type="font" name="Segoe UI" size="10" underline="false" strikethrough="false"/></rectangularScale>
<text type="componentData"><htmlId>18</htmlId><value>ALARM LIMITS</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>225.1</x><y>168.0</y><top>8.0</top><bottom>8.0</bottom><left>35.1</left><right>35.1</right><rotation>0.0</rotation><shear>0.0</shear></text>
<rectangle type="componentData"><htmlId>19</htmlId><roundingX>0.0571</roundingX><roundingY>0.3529</roundingY><x>295.0</x><y>203.0</y><top>17.0</top><bottom>17.0</bottom><left>105.0</left><right>105.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>20</htmlId><x>193.0</x><y>203.0</y><top>17.0</top><bottom>17.0</bottom><left>3.0</left><right>3.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint></rectangle>
<text type="componentData"><htmlId>21</htmlId><value>High-High</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>233.8</x><y>203.0</y><top>9.0</top><bottom>9.0</bottom><left>27.8</left><right>27.8</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>22</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="16" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>368.1</x><y>203.0</y><top>13.0</top><bottom>13.0</bottom><left>21.9</left><right>21.9</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemHHL</itemAttribute></connection></action></data></number>
<rectangle type="componentData"><htmlId>23</htmlId><roundingX>0.0571</roundingX><roundingY>0.3529</roundingY><x>295.0</x><y>243.0</y><top>17.0</top><bottom>17.0</bottom><left>105.0</left><right>105.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>24</htmlId><x>193.0</x><y>243.0</y><top>17.0</top><bottom>17.0</bottom><left>3.0</left><right>3.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="245" g="158" b="11"/></fillPaint></rectangle>
<text type="componentData"><htmlId>25</htmlId><value>High</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>218.7</x><y>243.0</y><top>9.0</top><bottom>9.0</bottom><left>12.7</left><right>12.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>26</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="16" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="245" g="158" b="11"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>368.1</x><y>243.0</y><top>13.0</top><bottom>13.0</bottom><left>21.9</left><right>21.9</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemHL</itemAttribute></connection></action></data></number>
<rectangle type="componentData"><htmlId>27</htmlId><roundingX>0.0571</roundingX><roundingY>0.3529</roundingY><x>295.0</x><y>283.0</y><top>17.0</top><bottom>17.0</bottom><left>105.0</left><right>105.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>28</htmlId><x>193.0</x><y>283.0</y><top>17.0</top><bottom>17.0</bottom><left>3.0</left><right>3.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="245" g="158" b="11"/></fillPaint></rectangle>
<text type="componentData"><htmlId>29</htmlId><value>Low</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>216.7</x><y>283.0</y><top>9.0</top><bottom>9.0</bottom><left>10.7</left><right>10.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>30</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="16" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="245" g="158" b="11"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>368.1</x><y>283.0</y><top>13.0</top><bottom>13.0</bottom><left>21.9</left><right>21.9</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemLL</itemAttribute></connection></action></data></number>
<rectangle type="componentData"><htmlId>31</htmlId><roundingX>0.0571</roundingX><roundingY>0.3529</roundingY><x>295.0</x><y>323.0</y><top>17.0</top><bottom>17.0</bottom><left>105.0</left><right>105.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="22" g="27" b="34"/></fillPaint></rectangle>
<rectangle type="componentData"><htmlId>32</htmlId><x>193.0</x><y>323.0</y><top>17.0</top><bottom>17.0</bottom><left>3.0</left><right>3.0</right><rotation>0.0</rotation><shear>0.0</shear><stroke type="stroke" width="1.0"/><strokeOn>false</strokeOn><fillOn>true</fillOn><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint></rectangle>
<text type="componentData"><htmlId>33</htmlId><value>Low-Low</value><font type="font" name="Segoe UI" size="12" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>229.9</x><y>323.0</y><top>9.0</top><bottom>9.0</bottom><left>23.9</left><right>23.9</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>34</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="16" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="239" g="68" b="68"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>368.1</x><y>323.0</y><top>13.0</top><bottom>13.0</bottom><left>21.9</left><right>21.9</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemLLL</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>35</htmlId><value>MAXIMUM SEEN</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>229.5</x><y>360.0</y><top>8.0</top><bottom>8.0</bottom><left>39.5</left><right>39.5</right><rotation>0.0</rotation><shear>0.0</shear></text>
<number type="componentData"><htmlId>36</htmlId><value>0.0</value><format>999.9</format><font type="font" name="Consolas" bold="true" size="22" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="230" g="237" b="243"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>219.2</x><y>386.0</y><top>16.0</top><bottom>16.0</bottom><left>29.2</left><right>29.2</right><rotation>0.0</rotation><shear>0.0</shear><data type="data"><action type="actionConnectTo"><property type="property" name="number.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL.MAX</itemName><itemAttribute>ItemValue</itemAttribute></connection></action></data></number>
<text type="componentData"><htmlId>37</htmlId><value>LAST UPDATE</value><font type="font" name="Segoe UI" bold="true" size="10" underline="false" strikethrough="false"/><fillPaint type="paint"><paint type="colorSet" r="139" g="152" b="168"/></fillPaint><justification type="textJustification" value="TextJustificationCenter"/><stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize><x>221.7</x><y>420.0</y><top>8.0</top><bottom>8.0</bottom><left>31.7</left><right>31.7</right><rotation>0.0</rotation><shear>0.0</shear></text>
<numberField type="componentData" x="295.0" y="442.0" top="12.0" bottom="12.0" left="105.0" right="105.0" rotation="0.0" shear="0.0"><htmlId>38</htmlId><font type="font" name="Consolas" bold="true" size="11" underline="false" strikethrough="false"/><format></format><editable>false</editable><asDateTime>true</asDateTime><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><justification type="jTextJustification" value="TextJustificationRight"/><data type="data"><action type="actionConnectTo"><property type="property" name="numberField.value"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemUpdTime</itemAttribute></connection></action></data></numberField>
<microTrend type="componentData" x="210.0" y="500.0" top="40.0" bottom="40.0" left="190.0" right="190.0" rotation="0.0" shear="0.0"><htmlId>39</htmlId><numberOfPens>1</numberOfPens><realTime>true</realTime><fillWithHistory>true</fillWithHistory><microTrendBackgroundFillOn>true</microTrendBackgroundFillOn><lowHighFillOn>false</lowHighFillOn><microTrendBackgroundFillColor type="colorSet" r="22" g="27" b="34"/><microTrendBackgroundColor type="colorSet" r="48" g="61" b="77"/><property type="componentProperty"><name>itemName[0]</name><value/></property><property type="componentProperty"><name>scaleMin[0]</name><value>0.0</value></property><property type="componentProperty"><name>scaleMax[0]</name><value>100.0</value></property><property type="componentProperty"><name>color[0]</name><value type="colorSet" r="20" g="184" b="166"/></property><property type="componentProperty"><name>stroke[0]</name><value type="stroke" width="2.0"/></property><data type="data"><action type="actionInternalServiced"/><action type="actionConnectTo"><property type="property" name="microTrend.itemName[0]"/><filter type="filter"><value>0.0</value></filter><connection type="connection"><direction>1</direction><itemName>CI-Eng-Sample.TANK1.LEVEL</itemName><itemAttribute>ItemName</itemAttribute></connection></action></data></microTrend>
<button type="componentData" x="80.0" y="569.0" top="17.0" bottom="17.0" left="60.0" right="60.0" rotation="0.0" shear="0.0"><htmlId>40</htmlId><label>Trends</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><data type="data"><action type="actionActivateDisplay"><event type="event" event="On action"/><type type="displayActivationType" value="ActivateSpecific"/><display>CIENG_Trends</display><layout>CIENG_Operator</layout><layoutFrame>trd</layoutFrame></action></data></button>
<button type="componentData" x="210.0" y="569.0" top="17.0" bottom="17.0" left="60.0" right="60.0" rotation="0.0" shear="0.0"><htmlId>41</htmlId><label>Alarms</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="230" g="237" b="243"/><backgroundColor type="colorSet" r="36" g="45" b="57"/><data type="data"><action type="actionActivateDisplay"><event type="event" event="On action"/><type type="displayActivationType" value="ActivateSpecific"/><display>CIENG_Alarms</display><layout>CIENG_Operator</layout><layoutFrame>alm</layoutFrame></action></data></button>
<button type="componentData" x="340.0" y="569.0" top="17.0" bottom="17.0" left="60.0" right="60.0" rotation="0.0" shear="0.0"><htmlId>42</htmlId><label>Close</label><font type="font" name="Segoe UI" bold="true" size="12" underline="false" strikethrough="false"/><foregroundColor type="colorSet" r="255" g="255" b="255"/><backgroundColor type="colorSet" r="59" g="130" b="246"/><data type="data"><action type="actionExitDisplay"><event type="event" event="On action"/></action></data></button>
</coreObjectDefinition>
</visualization>

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -3,11 +3,12 @@ rem Deploy the CI-Eng-Sample displays into the operator interface (deployment DE
rem CI Server R1.03.00. Load the sample (load.cmd) first; no admin rights needed.
rem Copies the display XML, then creates the HTML (Mobile Operator) version with jwuiutl;
rem without -o the HTML goes to %TLS_WAP_PATH%\mobileoperator\operatorInterfaces\DEPLOY.
rem The files are generated by generator\build.py (already in this folder; rerun only after changes).
cd /d "%~dp0"
set WAP=%TLS_WAP_PATH%
if not defined TLS_WAP_PATH set WAP=C:\Users\Public\Yokogawa\tls\wap
for %%d in (CIENG_Header CIENG_Overview CIENG_Control CIENG_Trends CIENG_Alarms CIENG_System CIENG_AlarmBanner CIENG_TankFaceplate) do (
copy /y %%d.xml "%WAP%\cfg\operatorInterfaces\DEPLOY\displays\" > nul
call jwuiutl.cmd -e HTML -i -f DEPLOY %%d
)
copy /y CIENG_Tank.xml "%WAP%\cfg\operatorInterfaces\DEPLOY\displays\"
copy /y CIENG_Menu.xml "%WAP%\cfg\operatorInterfaces\DEPLOY\displays\"
copy /y CIENG_TrendLab.xml "%WAP%\cfg\operatorInterfaces\DEPLOY\displays\"
call jwuiutl.cmd -e HTML -i -f DEPLOY CIENG_Tank
call jwuiutl.cmd -e HTML -i -f DEPLOY CIENG_Menu
call jwuiutl.cmd -e HTML -i -f DEPLOY CIENG_TrendLab

View file

@ -1 +0,0 @@
__pycache__/

View file

@ -1,45 +0,0 @@
# 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 <folder> (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 (desktop and web).
- 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.
- Arc angles (desktop and web alike, fixed or connected): degrees **clockwise** from 3 o'clock
(screen y points down), negative values allowed - not the counter-clockwise maths convention.
The ring gauges have the gap on the right and the value growing from 9 o'clock up and down.
- 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).

View file

@ -1,351 +0,0 @@
"""Build the CI-Eng-Sample demo displays (CI Server R1.03.00, HTML mode = desktop + web).
python build.py [<output folder>] (default: the displays folder, ..)
See README.md in this folder.
Displays: CIENG_Header, CIENG_Overview, CIENG_Control, CIENG_Trends, CIENG_Alarms, CIENG_System,
CIENG_AlarmBanner (frames of layout CIENG_Operator) and CIENG_TankFaceplate (layout CIENG_Popup).
"""
import os, sys
sys.path.insert(0, os.path.dirname(__file__))
from cixml import *
S = 'CI-Eng-Sample.'
LEVEL, INFLOW, VOLUME = S + 'TANK1.LEVEL', S + 'TANK1.INFLOW', S + 'TANK1.CALC.VOLUME'
LVL_COLORS = [(0, 'red'), (10, 'amber'), (20, 'teal'), (80, 'amber'), (90, 'red')] # LL/L/normal/H/HH
# live-data feed, installed by feed\install_feed.ps1 into a fixed folder outside CI Server
FEED_START = r'cmd /c "C:\Users\Public\CI-Eng-Sample\feed\cieng_feed_start.cmd"'
W, H, HD = 1880, 760, 680 # content displays (tab frames): 1880 x 760 (about 2.5:1, between the
# 16:9 and 16:10 content areas); coordinates below are designed for 680 high
FACEPLATE = act_open('CIENG_TankFaceplate', 'CIENG_Popup', 'default')
FACEPLATE_CLICK = act_open('CIENG_TankFaceplate', 'CIENG_Popup', 'default', event='Clicked b1')
def card(d, l, t, w, h, title, sub=None):
d.rect(l, t, w, h, fill='card', stroke='line', r=10)
d.text(l + 20, t + 12, w - 40, 22, title.upper(), 11, 'muted', bold=True)
if sub:
d.text(l + 20, t + 34, w - 40, 18, sub, 10, 'dim')
def kv(d, l, t, w, label, item, fmt, unit, size=22, color='text', extra=()):
d.text(l, t, w, 16, label, 10, 'muted')
d.number(l, t + 18, w - 50, 30, item, fmt, size, color, align='Left', extra=extra)
d.text(l + w - 48, t + 26, 48, 18, unit, 11, 'muted')
def level_color(prop='number.fillPaint'):
return conn(prop, LEVEL, transform=tr_threshold(LVL_COLORS))
def gauge(d, cx, cy, r, item, mn, mx, fmt, unit, label, color='teal', thresholds=None, extra=()):
d.ring_gauge(cx, cy, r, item, mn, mx, color, 12, thresholds)
d.number(cx - r + 14, cy - 22, 2 * r - 28, 36, item, fmt, 26, align='Center', extra=extra)
d.text(cx - 40, cy + 16, 80, 18, unit, 11, 'muted', align='Center')
d.text(cx - r, cy + r - 6, 2 * r, 20, label, 12, 'text', bold=True, align='Center')
def build_header():
d = Display('CIENG_Header', 1920, 96, 'Header', bg='panel')
d.rect(0, 0, 1920, 96, fill='panel')
d.line(0, 95, 1920, 95, 'line', 1)
d.rect(20, 18, 60, 60, fill='blue', r=14)
d.text(20, 34, 60, 28, 'CI', 22, 'white', bold=True, align='Center')
d.text(96, 18, 380, 30, 'CI-Eng-Sample', 22, 'text', bold=True)
d.text(96, 52, 400, 20, 'Operations dashboard | Tank farm demo', 12, 'muted')
# KPI chips
chips = [(520, 'TANK LEVEL', LEVEL, '999.9', '%', [level_color()]),
(700, 'INFLOW', INFLOW, '9999.9', 'm3/h', []),
(880, 'VOLUME', VOLUME, '9999.9', 'm3', [])]
for x, label, item, fmt, unit, extra in chips:
d.rect(x, 14, 168, 68, fill='card', stroke='line', r=8)
d.text(x + 14, 22, 140, 16, label, 10, 'muted', bold=True)
d.number(x + 14, 40, 100, 32, item, fmt, 22, align='Left', extra=extra)
d.text(x + 118, 50, 46, 18, unit, 11, 'muted')
x = 1060
d.rect(x, 14, 168, 68, fill='card', stroke='line', r=8)
d.text(x + 14, 22, 140, 16, 'PUMP 1', 10, 'muted', bold=True)
d.lamp(x + 14, 48, 18, S + 'PUMP1.RUNNING')
for txt, col, on in (('RUNNING', 'green', True), ('STOPPED', 'muted', False)):
d.text(x + 40, 44, 120, 24, txt, 14, col, bold=True)
d.parts[-1] = d.parts[-1].replace('</text>', data([conn('text.visible', S + 'PUMP1.RUNNING',
transform=tr_threshold([(False, not on), (True, on)], 'Boolean', 'Boolean'))]) + '</text>')
x = 1240
d.rect(x, 14, 168, 68, fill='card', stroke='line', r=8)
d.text(x + 14, 22, 140, 16, 'COMMUNICATION', 10, 'muted', bold=True)
d.lamp(x + 14, 50, 14, S + 'PLC1.COMM_OK', off='red')
d.text(x + 34, 46, 50, 20, 'PLC1', 12, 'text')
d.lamp(x + 90, 50, 14, S + 'UA.COMM_OK', off='red')
d.text(x + 110, 46, 50, 20, 'OPC UA', 12, 'text')
# live data start/stop
x = 1424
d.rect(x, 14, 250, 68, fill='card', stroke='line', r=8)
d.text(x + 14, 22, 120, 16, 'LIVE DATA', 10, 'muted', bold=True)
d.lamp(x + 112, 23, 12, S + 'DEMO.FEED_ON')
d.button(x + 14, 44, 104, 30, 'Start', [act_set(S + 'DEMO.FEED_ON', 1), act_cmd(FEED_START)], fg='white', bg='green',
tip='Start the live-data feed (cieng_feed.ps1) on the server')
d.button(x + 130, 44, 104, 30, 'Stop', [act_set(S + 'DEMO.FEED_ON', 0)], fg='text', bg='card2',
tip='Stop the feed (ends within 5 s)')
# faceplate + clock
d.button(1688, 14, 92, 68, 'Tank 1', [FACEPLATE], fg='white', bg='blue', tip='Open the Tank 1 faceplate popup')
d.text(1792, 22, 120, 16, 'LAST UPDATE', 10, 'muted', bold=True)
d.time_text(1792, 44, 122, 28, S + 'DEMO.COUNTER', 9)
return d
def build_overview():
d = Display('CIENG_Overview', W, H, 'Overview', design_h=HD)
d.rect(0, 0, W, HD, fill='bg')
card(d, 10, 10, 1110, 660, 'Process - Tank 1', 'Click the tank for its faceplate')
# inflow pipe + flow indicator
d.rect(60, 330, 380, 16, fill='track')
d.rect(60, 333, 380, 10, fill='teal', actions=[conn('rectangle.visible', INFLOW,
transform=tr_threshold([(0, False), (5, True)], 'Double', 'Boolean'))])
d.text(60, 250, 200, 16, 'INFLOW', 10, 'muted', bold=True)
d.number(60, 268, 150, 40, INFLOW, '9999.9', 30, align='Left')
d.text(214, 282, 60, 20, 'm3/h', 12, 'muted')
# tank
d.rect(440, 100, 240, 480, fill='panel', stroke='line', sw=2, r=18, actions=[FACEPLATE_CLICK],
tip='Tank 1 - click for the faceplate')
d.rect(450, 110, 220, 460, fill='blue', r=12, fill_amount=0.5, fill_dir='FillDirectionUp',
actions=[conn('rectangle.fillAmount', LEVEL, transform=tr_linear(0, 100, 0, 1)),
conn('rectangle.fillPaint', LEVEL, transform=tr_threshold(
[(0, (185, 28, 28)), (10, (180, 83, 9)), (20, (37, 99, 235)), (80, (180, 83, 9)), (90, (185, 28, 28))])),
FACEPLATE_CLICK])
d.text(450, 60, 220, 28, 'TANK 1', 16, 'text', bold=True, align='Center')
d.number(460, 300, 200, 50, LEVEL, '999.9', 40, 'white', align='Center')
d.text(460, 352, 200, 20, '% level', 12, 'text', align='Center')
for pct, lab, col in ((90, 'HH 90', 'red'), (80, 'H 80', 'amber'), (20, 'L 20', 'amber'), (10, 'LL 10', 'red')):
y = 570 - pct * 4.6
d.line(682, y, 700, y, col, 2)
d.text(706, y - 9, 60, 18, lab, 10, col, bold=True)
d.button(470, 594, 180, 32, 'Open faceplate', [FACEPLATE], fg='white', bg='blue')
# outlet pipe + pump
d.rect(680, 532, 150, 16, fill='track')
d.rect(680, 535, 150, 10, fill='teal', actions=[conn('rectangle.visible', S + 'PUMP1.RUNNING')])
d.ellipse(830, 495, 90, 90, fill='off', stroke='line', sw=2, actions=[
conn('ellipse.fillPaint', S + 'PUMP1.RUNNING', transform=tr_threshold([(False, 'off'), (True, 'green')], 'Boolean'))])
d.text(830, 528, 90, 24, 'P1', 16, 'white', bold=True, align='Center')
d.rect(920, 532, 170, 16, fill='track')
d.rect(920, 535, 170, 10, fill='teal', actions=[conn('rectangle.visible', S + 'PUMP1.RUNNING')])
d.text(800, 600, 150, 18, 'PUMP 1', 11, 'muted', bold=True, align='Center')
for txt, col, val in (('AUTO', 'teal', 1), ('MANUAL', 'amber', 0)):
d.text(800, 620, 150, 20, txt, 13, col, bold=True, align='Center')
d.parts[-1] = d.parts[-1].replace('</text>', data([conn('text.visible', S + 'PUMP1.MODE', transform=tr_threshold(
[(0, val == 0), (1, val == 1)], 'Double', 'Boolean'))]) + '</text>')
# info column
x = 860
d.rect(x, 90, 230, 330, fill='panel', stroke='line', r=8)
kv(d, x + 16, 104, 200, 'VOLUME (TANK1.CALC)', VOLUME, '9999.9', 'm3')
kv(d, x + 16, 168, 200, 'FLOW PER SECOND (JFLOW)', S + 'TANK1.JFLOW.sPerMin', '999.99', 'm3/s')
kv(d, x + 16, 232, 200, 'LEVEL MAXIMUM', S + 'TANK1.LEVEL.MAX', '999.9', '%')
kv(d, x + 16, 296, 200, 'COUNTER (DEMO.INCR1)', S + 'DEMO.COUNTER', '999', '')
d.databar(x + 16, 352, 198, 10, S + 'DEMO.COUNTER', 0, 100, 'violet', 'track', 'Right')
d.text(x + 16, 376, 200, 16, 'PUMP RUN TIME', 10, 'muted')
d.number(x + 16, 392, 150, 24, S + 'PUMP1.RUNNING.RUN_SECONDS', '9999999', 16, align='Left')
d.text(x + 170, 396, 40, 18, 's', 11, 'muted')
# gauges
card(d, 1130, 10, 740, 330, 'Key figures')
gauge(d, 1255, 175, 95, LEVEL, 0, 100, '999.9', '%', 'Level', thresholds=LVL_COLORS, extra=[level_color()])
gauge(d, 1500, 175, 95, INFLOW, 0, 500, '9999', 'm3/h', 'Inflow', 'violet')
gauge(d, 1745, 175, 95, VOLUME, 0, 200, '999.9', 'm3', 'Volume', 'blue')
card(d, 1130, 350, 740, 320, 'Last 10 minutes', 'Micro trend: level (teal, 0-100 %) and inflow (violet, 0-500 m3/h)')
d.micro_trend(1150, 410, 700, 240, [(LEVEL, 0, 100, 'teal'), (INFLOW, 0, 500, 'violet')])
return d
def build_control():
d = Display('CIENG_Control', W, H, 'Process control', design_h=HD)
d.rect(0, 0, W, HD, fill='bg')
# setpoint -> Modbus loopback
card(d, 10, 10, 925, 325, 'Setpoint -> PLC1 (Modbus loopback)', 'Slider, spinner and input field write PLC1.SETPOINT; READBACK returns through Modbus')
d.slider(40, 70, 600, 64, S + 'PLC1.SETPOINT', 0, 100, 10, 5)
d.text(40, 150, 140, 16, 'SPINNER', 10, 'muted', bold=True)
d.spinner(40, 170, 140, 36, S + 'PLC1.SETPOINT', 0, 100, 5)
d.text(200, 150, 140, 16, 'INPUT FIELD', 10, 'muted', bold=True)
d.number_field(200, 170, 140, 36, S + 'PLC1.SETPOINT', '999', 16)
d.text(360, 150, 160, 16, 'SETPOINT', 10, 'muted', bold=True)
d.number(360, 168, 120, 40, S + 'PLC1.SETPOINT', '999', 28, 'blue', align='Left')
d.text(40, 226, 300, 16, 'READBACK (data bar + scale)', 10, 'muted', bold=True)
d.databar(40, 248, 600, 18, S + 'PLC1.READBACK', 0, 100, 'blue', 'track', 'Right')
d.rect_scale(40, 268, 600, 36, 0, 100, 10, 5, vertical=False)
gauge(d, 790, 175, 95, S + 'PLC1.READBACK', 0, 100, '999', '', 'Readback', 'blue')
d.lamp(700, 30, 12, S + 'PLC1.COMM_OK', off='red')
d.text(718, 26, 200, 18, 'station CIENG_PLC', 11, 'muted')
# digital command
card(d, 945, 10, 925, 325, 'Digital command -> PLC1.CMD', 'Toggle and push buttons write the coil; FEEDBACK is read back from the input bit')
d.toggle(975, 80, 200, 48, 'CMD (toggle)', S + 'PLC1.CMD', 14)
d.button(975, 150, 95, 40, 'Set ON', [act_set(S + 'PLC1.CMD', 1)], fg='white', bg='green')
d.button(1080, 150, 95, 40, 'Set OFF', [act_set(S + 'PLC1.CMD', 0)], fg='text', bg='card2')
d.ellipse(1300, 80, 120, 120, fill='off', stroke='line', sw=3, actions=[
conn('ellipse.fillPaint', S + 'PLC1.FEEDBACK', transform=tr_threshold([(False, 'off'), (True, 'green')], 'Boolean'))])
d.text(1300, 128, 120, 24, 'FEEDBACK', 13, 'white', bold=True, align='Center')
d.text(1460, 90, 380, 16, 'LAST CHANGE OF FEEDBACK', 10, 'muted', bold=True)
d.datetime_field(1460, 112, 300, 30, S + 'PLC1.FEEDBACK', 'ItemUpdTime', 13) # date/time field (editable on the web)
d.text(1460, 160, 380, 16, 'STATUS', 10, 'muted', bold=True)
d.text(1460, 180, 380, 24, 'NORMAL', 16, 'text', bold=True)
d.parts[-1] = d.parts[-1].replace('</text>', data([conn('text.value', S + 'PLC1.FEEDBACK', 'ItemStatusMnemonic')]) + '</text>')
# pump
card(d, 10, 345, 925, 325, 'Pump 1', 'Combo box, buttons and check box write PUMP1.MODE / PUMP1.RUNNING (mode changes are audited)')
d.text(40, 400, 160, 16, 'MODE (COMBO BOX)', 10, 'muted', bold=True)
d.combo(40, 420, 200, 34, S + 'PUMP1.MODE', '0;Manual;1;Auto', 14)
d.button(260, 420, 110, 34, 'Manual', [act_set(S + 'PUMP1.MODE', 0)], fg='text', bg='card2')
d.button(380, 420, 110, 34, 'Auto', [act_set(S + 'PUMP1.MODE', 1)], fg='white', bg='blue')
d.text(40, 478, 300, 16, 'RUN COMMAND (CHECK BOX, MANUAL MODE)', 10, 'muted', bold=True)
d.checkbox(40, 498, 240, 32, 'Pump running', S + 'PUMP1.RUNNING', 14)
d.text(40, 552, 300, 16, 'DESCRIPTION (TEXT FIELD)', 10, 'muted', bold=True)
d.text_field(40, 572, 450, 30, S + 'PUMP1.MODE', 'ItemDesc', 13)
d.ellipse(600, 420, 110, 110, fill='off', stroke='line', sw=3, actions=[
conn('ellipse.fillPaint', S + 'PUMP1.RUNNING', transform=tr_threshold([(False, 'off'), (True, 'green')], 'Boolean'))])
d.text(600, 462, 110, 24, 'P1', 18, 'white', bold=True, align='Center')
d.text(560, 548, 220, 16, 'RUN TIME (INTEGRATOR)', 10, 'muted', bold=True, align='Center')
d.number(560, 566, 190, 34, S + 'PUMP1.RUNNING.RUN_SECONDS', '9999999', 24, align='Right')
d.text(754, 576, 30, 18, 's', 12, 'muted')
# alarm test
card(d, 945, 345, 925, 325, 'Tank 1 - alarm test', 'Stop live data first, then drive TANK1.LEVEL across its limits (H 80 / HH 90 / L 20 / LL 10)')
d.slider(975, 410, 560, 64, LEVEL, 0, 100, 10, 5)
for i, (lab, v, col, fg) in enumerate((('Low-Low 5', 5, 'red', 'white'), ('Low 15', 15, 'amber', 'white'),
('Normal 50', 50, 'teal', 'white'), ('High 85', 85, 'amber', 'white'),
('High-High 95', 95, 'red', 'white'))):
d.button(975 + i * 114, 500, 106, 38, lab, [act_set(LEVEL, v)], fg=fg, bg=col)
d.text(975, 566, 200, 16, 'LEVEL', 10, 'muted', bold=True)
d.number(975, 584, 160, 50, LEVEL, '999.9', 38, align='Left', extra=[level_color()])
d.text(1180, 566, 300, 16, 'ITEM STATUS', 10, 'muted', bold=True)
d.text(1180, 590, 300, 34, 'NORMAL', 22, 'text', bold=True)
d.parts[-1] = d.parts[-1].replace('</text>', data([conn('text.value', LEVEL, 'ItemStatusMnemonic'),
conn('text.fillPaint', LEVEL, transform=tr_threshold(LVL_COLORS))]) + '</text>')
d.ring_gauge(1720, 520, 90, LEVEL, 0, 100, 'teal', 14, LVL_COLORS)
d.circ_scale(1720, 520, 120, 0, 100, 20, 5)
d.number(1660, 500, 120, 40, LEVEL, '999.9', 26, align='Center')
return d
def build_trends():
d = Display('CIENG_Trends', W, H, 'Trends', design_h=HD)
d.rect(0, 0, W, HD, fill='bg')
d.rect(10, 10, 1380, 660, fill='panel', stroke='line', r=10)
d.trend(20, 20, 1360, 640, [(LEVEL, 'teal', 0, 100, 'Tank 1 level (%)'),
(INFLOW, 'violet', 0, 500, 'Tank 1 inflow (m3/h)')], 10, 'Tank 1 - level and inflow',
web_spares=False) # user choice: hairline shows 2 values; the web main trend then draws no line
for i, (title, item, mn, mx, col, fmt, unit) in enumerate((
('Level', LEVEL, 0, 100, 'teal', '999.9', '%'), ('Inflow', INFLOW, 0, 500, 'violet', '9999.9', 'm3/h'),
('CPU load', S + 'SYSTEM.CPU_LOAD', 0, 100, 'blue', '999.9', '%'))):
t = 10 + i * 223
card(d, 1400, t, 470, 213, title)
d.number(1660, t + 8, 150, 30, item, fmt, 20, col, align='Right')
d.text(1814, t + 14, 50, 18, unit, 11, 'muted')
d.micro_trend(1420, t + 48, 430, 150, [(item, mn, mx, col)], history=(i < 2)) # CPU_LOAD has no history
return d
def build_alarms():
d = Display('CIENG_Alarms', W, H, 'Alarms', design_h=HD)
d.rect(0, 0, W, HD, fill='bg')
card(d, 10, 10, 1860, 390, 'Current alarms', 'All areas - acknowledge with the check box or right-click')
d.alarm_overview(20, 60, 1840, 330, size=13)
card(d, 10, 410, 1860, 260, 'Alarm history - Tank 1', 'Historical overview filtered on alarm selection area CIENG_TANK1')
d.alarm_overview(20, 460, 1840, 200, 'HistoricalAlarms', asa='CIENG_TANK1', size=13)
return d
def build_system():
d = Display('CIENG_System', W, H, 'System', design_h=HD)
d.rect(0, 0, W, HD, fill='bg')
card(d, 10, 10, 600, 320, 'Server health', 'Real values of this PC, written by the live-data feed')
th = [(0, 'teal'), (80, 'amber'), (90, 'red')]
gauge(d, 160, 180, 100, S + 'SYSTEM.CPU_LOAD', 0, 100, '999.9', '%', 'CPU load', thresholds=th)
gauge(d, 450, 180, 100, S + 'SYSTEM.DISK_C', 0, 100, '999.9', '%', 'Disk C: used', 'blue', thresholds=th)
card(d, 620, 10, 600, 320, 'Communication and processes')
rows = ((S + 'PLC1.COMM_OK', 'Modbus station CIENG_PLC', 'Boolean', None),
(S + 'UA.COMM_OK', 'OPC UA client station CIENG_UA', 'Boolean', None),
(S + 'UA.SRV_STATE', 'OPC UA server state (0 = running)', 'Double', [(0, 'green'), (0.5, 'red')]),
(S + 'SYSTEM.PING_LOCALHOST', 'localhost reachable', 'Double', [(0, 'red'), (0.5, 'green')]),
(S + 'SYSTEM.PROC_ALM', 'ALARM process (alm) running', 'Double', [(0, 'red'), (0.5, 'green')]))
for i, (item, lab, inp, tbl) in enumerate(rows):
y = 60 + i * 52
d.rect(640, y, 560, 44, fill='panel', r=6)
if inp == 'Boolean':
d.lamp(656, y + 13, 18, item, off='red')
else:
d.lamp(656, y + 13, 18, item, inp='Double', table=tbl)
d.text(688, y + 12, 340, 20, lab, 13, 'text')
d.text(1040, y + 12, 150, 20, 'NORMAL', 12, 'muted', align='Right')
d.parts[-1] = d.parts[-1].replace('</text>', data([conn('text.value', item, 'ItemStatusMnemonic')]) + '</text>')
card(d, 1230, 10, 640, 320, 'OPC UA loopback', 'TANK1.LEVEL read back through CI Server\'s own OPC UA server')
for i, (lab, item, col) in enumerate((('TANK1.LEVEL', LEVEL, 'teal'), ('UA.LEVEL_COPY', S + 'UA.LEVEL_COPY', 'blue'))):
x = 1260 + i * 300
d.text(x, 70, 260, 16, lab, 10, 'muted', bold=True)
d.number(x, 90, 200, 44, item, '999.9', 32, col, align='Left')
d.databar(x, 150, 260, 18, item, 0, 100, col, 'track', 'Right')
d.text(x, 182, 260, 16, 'LAST UPDATE', 10, 'muted', bold=True)
d.time_text(x, 202, 260, 28, item, 13)
d.rect_scale(1260, 250, 560, 34, 0, 100, 10, 5, vertical=False)
card(d, 10, 340, 1860, 330, 'Reports', 'Report component: select CIENG_TANK1 or CIENG_HTML, generate and view')
d.report(20, 390, 1840, 270)
return d
def build_banner():
d = Display('CIENG_AlarmBanner', 1920, 96, 'Alarm banner', bg='panel')
# Desktop: frames inside a <tab> ignore their zoom attribute; the layout command with a zoom argument
# applies it. Only ONE command can run at a time (more give "IllegalStateException: A command is
# already being executed"), so only the Overview tab is fitted here; the toolbar / menu / F-keys
# open the other tabs with fitDisplay. Web: the plain open action (web ignores ACTION commands).
d.rect(0, 0, 1920, 96, fill='panel', actions=[
act_open('CIENG_Overview', 'CIENG_Operator', 'ovw', event='On entry'),
act_cmd('ACTION navigate to ovw CIENG_Overview stretchDisplay', server=False, event='On entry')])
d.line(0, 0, 1920, 0, 'line', 1)
d.rect(10, 7, 170, 82, fill='card', stroke='line', r=8)
d.text(24, 13, 70, 18, 'ALARMS', 12, 'muted', bold=True)
d.ellipse(96, 14, 16, 16, fill='off', actions=[conn('ellipse.fillPaint', LEVEL, transform=tr_threshold(
[(0, 'red'), (10, 'amber'), (20, 'green'), (80, 'amber'), (90, 'red')]))])
d.text(118, 13, 60, 18, 'Tank 1', 12, 'text')
d.button(24, 44, 142, 34, 'Alarm list', [act_open('CIENG_Alarms', 'CIENG_Operator', 'alm')], fg='white', bg='blue', size=13)
# 4 rows of 20 px (14 px font, web) + border: no empty white area below the rows when 4+ alarms
d.alarm_overview(190, 7, 1722, 82, size=14, banner=True)
return d
def build_faceplate():
d = Display('CIENG_TankFaceplate', 420, 600, 'Tank 1 faceplate', bg='card')
d.rect(0, 0, 420, 600, fill='card')
d.rect(0, 0, 420, 52, fill='card2')
d.text(20, 14, 300, 24, 'TANK 1 | LEVEL', 15, 'text', bold=True)
d.button(370, 10, 36, 32, 'X', [act_close()], fg='text', bg='card', tip='Close')
d.text(20, 64, 380, 18, 'Tank 1 level (%)', 11, 'muted')
d.parts[-1] = d.parts[-1].replace('</text>', data([conn('text.value', LEVEL, 'ItemDesc')]) + '</text>')
d.number(20, 86, 200, 56, LEVEL, '999.9', 44, align='Left', extra=[level_color()])
d.text(224, 106, 30, 24, '%', 16, 'muted')
d.text(270, 92, 130, 16, 'STATUS', 10, 'muted', bold=True, align='Right')
d.text(250, 110, 150, 26, 'NORMAL', 16, 'text', bold=True, align='Right')
d.parts[-1] = d.parts[-1].replace('</text>', data([conn('text.value', LEVEL, 'ItemStatusMnemonic'),
conn('text.fillPaint', LEVEL, transform=tr_threshold(LVL_COLORS))]) + '</text>')
d.databar(40, 160, 60, 280, LEVEL, 0, 100, 'blue', 'track', 'Up')
d.rect_scale(104, 160, 44, 280, 0, 100, 20, 5)
d.text(190, 160, 210, 16, 'ALARM LIMITS', 10, 'muted', bold=True)
for i, (lab, attr, col) in enumerate((('High-High', 'ItemHHL', 'red'), ('High', 'ItemHL', 'amber'),
('Low', 'ItemLL', 'amber'), ('Low-Low', 'ItemLLL', 'red'))):
y = 186 + i * 40
d.rect(190, y, 210, 34, fill='panel', r=6)
d.rect(190, y, 6, 34, fill=col)
d.text(206, y + 8, 100, 18, lab, 12, 'text')
d.number(300, y + 4, 90, 26, LEVEL, '999.9', 16, col, attr=attr)
d.text(190, 352, 210, 16, 'MAXIMUM SEEN', 10, 'muted', bold=True)
d.number(190, 370, 140, 32, S + 'TANK1.LEVEL.MAX', '999.9', 22, align='Left')
d.text(190, 412, 210, 16, 'LAST UPDATE', 10, 'muted', bold=True)
d.time_text(190, 430, 210, 24, LEVEL, 11)
d.micro_trend(20, 460, 380, 80, [(LEVEL, 0, 100, 'teal')])
d.button(20, 552, 120, 34, 'Trends', [act_open('CIENG_Trends', 'CIENG_Operator', 'trd')], fg='text', bg='card2')
d.button(150, 552, 120, 34, 'Alarms', [act_open('CIENG_Alarms', 'CIENG_Operator', 'alm')], fg='text', bg='card2')
d.button(280, 552, 120, 34, 'Close', [act_close()], fg='white', bg='blue')
return d
if __name__ == '__main__':
out = sys.argv[1] if len(sys.argv) > 1 else os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
for b in (build_header, build_overview, build_control, build_trends, build_alarms, build_system, build_banner,
build_faceplate):
disp = b()
disp.save(out)
print(disp.name, len(disp.parts), 'components')

View file

@ -1,583 +0,0 @@
"""Small XML writer for CI Server R1.03 display files (Edit Module format 1.3.0.0).
Positions are given as boxes (left, top, width, height) in display pixels; CI Server stores a
component as its centre (x, y) plus half sizes (top, bottom, left, right).
Element and property names follow the installed component definitions
(%TLS_WAP_PATH%\\cfg\\operatorInterfaces\\DEPLOY\\components\\*.xml) and factory displays.
"""
from xml.sax.saxutils import escape
# ---------------------------------------------------------------- theme (dark dashboard)
C = {
'bg': (13, 17, 23), 'panel': (22, 27, 34), 'card': (28, 35, 45), 'card2': (36, 45, 57),
'line': (48, 61, 77), 'text': (230, 237, 243), 'muted': (139, 152, 168), 'dim': (88, 100, 116),
'blue': (59, 130, 246), 'teal': (20, 184, 166), 'green': (34, 197, 94), 'amber': (245, 158, 11),
'red': (239, 68, 68), 'violet': (139, 92, 246), 'off': (71, 85, 105), 'white': (255, 255, 255),
'track': (40, 50, 64),
}
FONT_UI = 'Segoe UI'
FONT_NUM = 'Consolas'
def rgb(c):
c = C.get(c, c) if isinstance(c, str) else c
return 'r="%d" g="%d" b="%d"' % tuple(c)
def colorset(tag, c):
return '<%s type="colorSet" %s/>' % (tag, rgb(c))
def paint(tag, c):
return '<%s type="paint"><paint type="colorSet" %s/></%s>' % (tag, rgb(c), tag)
def font(size, bold=False, name=FONT_UI, tag='font'):
b = ' bold="true"' if bold else ''
return '<%s type="font" name="%s"%s size="%d" underline="false" strikethrough="false"/>' % (tag, name, b, size)
def esc(s):
return escape(str(s))
def box_attrs(l, t, w, h):
return 'x="%.1f" y="%.1f" top="%.1f" bottom="%.1f" left="%.1f" right="%.1f" rotation="0.0" shear="0.0"' % (
l + w / 2.0, t + h / 2.0, h / 2.0, h / 2.0, w / 2.0, w / 2.0)
def box_elems(l, t, w, h):
return ('<x>%.1f</x><y>%.1f</y><top>%.1f</top><bottom>%.1f</bottom><left>%.1f</left><right>%.1f</right>'
'<rotation>0.0</rotation><shear>0.0</shear>') % (l + w / 2.0, t + h / 2.0, h / 2.0, h / 2.0, w / 2.0, w / 2.0)
_FONTS = {}
def text_width(s, size, bold=False, name=FONT_UI):
"""Width in display pixels, measured with the Windows font (matches the HTML export within ~3 %)."""
try:
from PIL import ImageFont
fn = {(FONT_UI, False): 'segoeui.ttf', (FONT_UI, True): 'segoeuib.ttf',
(FONT_NUM, False): 'consola.ttf', (FONT_NUM, True): 'consolab.ttf'}[(name, bool(bold))]
key = (fn, size)
if key not in _FONTS:
_FONTS[key] = ImageFont.truetype(r'C:\Windows\Fonts\%s' % fn, size)
return _FONTS[key].getlength(s) * 0.975
except Exception:
return len(s) * size * 0.55
def fit(l, w, s, size, align, bold=False, name=FONT_UI):
"""Text and numbers are exported with keepOriginalSize: drawn at natural size, centred on the box.
Shrink the box to the measured text width so 'Left' / 'Right' alignment still lands right."""
est = min(w, max(4.0, text_width(s, size, bold, name)))
if align == 'Left':
return l, est
if align == 'Right':
return l + w - est, est
return l, w
# ---------------------------------------------------------------- data connections
def tr_linear(i0, i1, o0, o1):
return ('<transformation type="transformationLinear"><inputType>java.lang.Double</inputType>'
'<outputType>java.lang.Double</outputType><inputValueStart>%s</inputValueStart>'
'<inputValueEnd>%s</inputValueEnd><outputValueStart>%s</outputValueStart>'
'<outputValueEnd>%s</outputValueEnd></transformation>') % (float(i0), float(i1), float(o0), float(o1))
def tr_threshold(table, inp='Double', out='Paint'):
"""table: list of (input, output). Output for Paint = colour key/tuple, Boolean = bool."""
itype = {'Double': 'java.lang.Double', 'Boolean': 'java.lang.Boolean'}[inp]
otype = {'Paint': 'fasttools.jwui.common.property.paint.PaintSet', 'Boolean': 'java.lang.Boolean',
'Color': 'fasttools.jtools.common.property.color.ColorSet'}[out]
rows = []
for i, o in table:
iv = ('true' if i else 'false') if inp == 'Boolean' else repr(float(i))
if out == 'Paint':
ov = '<thresholdOut type="paint"><paint type="colorSet" %s/></thresholdOut>' % rgb(o)
elif out == 'Color':
ov = '<thresholdOut type="colorSet" %s/>' % rgb(o)
else:
ov = '<thresholdOut>%s</thresholdOut>' % ('true' if o else 'false')
rows.append('<thresholdIn>%s</thresholdIn>%s' % (iv, ov))
return ('<transformation type="transformationThreshold"><inputType>%s</inputType><outputType>%s</outputType>'
'<thresholdTable type="thresholdTable">%s</thresholdTable></transformation>') % (itype, otype, ''.join(rows))
def conn(prop, item, attr='ItemValue', direction=1, transform=''):
"""Connect component property <prop> (e.g. 'number.value') to an item attribute.
direction 1 = read, 2 = write, None = read and write (as the factory toggle buttons)."""
d = '' if direction is None else '<direction>%d</direction>' % direction
return ('<action type="actionConnectTo"><property type="property" name="%s"/>'
'<filter type="filter"><value>0.0</value></filter>%s<connection type="connection">%s'
'<itemName>%s</itemName><itemAttribute>%s</itemAttribute></connection></action>') % (
prop, transform, d, esc(item), attr)
def act_set(item, value):
return ('<action type="actionSetItemAttribute"><event type="event" event="On action"/>'
'<filter type="filter"><value>%s</value></filter><connection type="connection"><direction>2</direction>'
'<location type="nodeName" node="$default$"/><itemName>%s</itemName><itemAttribute>ItemValue</itemAttribute>'
'</connection></action>') % (float(value), esc(item))
def act_open(display, layout=None, frame=None, event='On action'):
lay = ''
if layout or frame:
lay = ('<type type="displayActivationType" value="ActivateSpecific"/><display>%s</display>'
'<layout>%s</layout><layoutFrame>%s</layoutFrame>') % (display, layout or '', frame or '')
return '<action type="actionActivateDisplay"><event type="event" event="%s"/>%s</action>' % (event, lay)
return ('<action type="actionActivateDisplay"><event type="event" event="%s"/><display>%s</display>'
'</action>') % (event, display)
def act_close(event='On action'):
return '<action type="actionExitDisplay"><event type="event" event="%s"/></action>' % event
def act_cmd(command, server=True, event='On action'):
return ('<action type="actionExecuteCommand"><event type="event" event="%s"/><command>%s</command>'
'<onServer>%s</onServer></action>') % (event, esc(command), 'true' if server else 'false')
def data(actions):
return '<data type="data">%s</data>' % ''.join(actions) if actions else ''
# ---------------------------------------------------------------- display builder
class Display:
def __init__(self, name, width, height, title, bg='bg', design_h=None):
self.name, self.w, self.h, self.title, self.bg = name, width, height, title, bg
# Coordinates are written for a display design_h high and stretched vertically to height:
# panels, bars and lists grow, text / controls / round shapes keep their size and only move.
self.sy = float(height) / design_h if design_h else 1.0
self.parts = []
self.hid = 6 # 1 = layer, 2..6 = visibility groups
def _b(self, l, t, w, h, stretch):
if self.sy == 1.0:
return l, t, w, h
if stretch:
return l, t * self.sy, w, h * self.sy
return l, (t + h / 2.0) * self.sy - h / 2.0, w, h
def _id(self):
self.hid += 1
return '<htmlId>%d</htmlId>' % self.hid
def add(self, s):
self.parts.append(s)
# ----- shapes
def rect(self, l, t, w, h, fill='card', stroke=None, sw=1.0, r=0, actions=(), tip=None, fill_amount=None,
fill_dir=None, visible=True):
l, t, w, h = self._b(l, t, w, h, h > 40)
s = '<rectangle type="componentData">' + self._id()
if tip:
s += '<toolTipText>%s</toolTipText>' % esc(tip)
if r:
# stored as a fraction (0..1) of the half width / half height (web client
# ExtendedRectangle: rx = width / 2 * roundingX); pixel values > 1 draw an ellipse
s += '<roundingX>%.4f</roundingX><roundingY>%.4f</roundingY>' % (min(1.0, 2.0 * r / w), min(1.0, 2.0 * r / h))
s += box_elems(l, t, w, h)
s += '<stroke type="stroke" width="%.1f"/>' % sw
if stroke:
s += '<strokeOn>true</strokeOn>' + paint('strokePaint', stroke)
else:
s += '<strokeOn>false</strokeOn>'
if fill:
s += '<fillOn>true</fillOn>' + paint('fillPaint', fill)
else:
s += '<fillOn>false</fillOn>'
if fill_amount is not None:
s += '<fillAmount>%s</fillAmount>' % fill_amount
if fill_dir:
s += '<fillDirection type="fillDirection" value="%s"/>' % fill_dir
if not visible:
s += '<visible>false</visible>'
s += data(actions) + '</rectangle>'
self.add(s)
def ellipse(self, l, t, w, h, fill='green', stroke=None, sw=1.0, actions=(), tip=None):
l, t, w, h = self._b(l, t, w, h, False)
s = '<ellipse type="componentData">' + self._id()
if tip:
s += '<toolTipText>%s</toolTipText>' % esc(tip)
s += box_elems(l, t, w, h) + '<stroke type="stroke" width="%.1f"/>' % sw
s += ('<strokeOn>true</strokeOn>' + paint('strokePaint', stroke)) if stroke else '<strokeOn>false</strokeOn>'
s += ('<fillOn>true</fillOn>' + paint('fillPaint', fill)) if fill else '<fillOn>false</fillOn>'
s += data(actions) + '</ellipse>'
self.add(s)
def arc(self, cx, cy, rad, start, extent, color='blue', sw=10.0, actions=()):
cy = cy * self.sy
s = '<arc type="componentData">' + self._id()
s += '<startAngle>%.1f</startAngle><extentAngle>%.1f</extentAngle><closed>false</closed>' % (start, extent)
s += box_elems(cx - rad, cy - rad, 2 * rad, 2 * rad)
s += '<stroke type="stroke" width="%.1f" endCap="butt"/><strokeOn>true</strokeOn>' % sw
s += paint('strokePaint', color) + '<fillOn>false</fillOn>'
s += data(actions) + '</arc>'
self.add(s)
def line(self, x1, y1, x2, y2, color='line', sw=2.0, actions=()):
# a line is stored by its bounding box; direction by the sign of the extents is not available,
# so only horizontal / vertical lines are used here
l, t = min(x1, x2), min(y1, y2)
w, h = abs(x2 - x1), abs(y2 - y1)
# drawn as a thin filled rectangle: a <line> without curve points is placed wrongly on the web
if h < w:
self.rect(l, t - sw / 2.0, max(w, 1), sw, fill=color, actions=actions)
else:
self.rect(l - sw / 2.0, t, sw, max(h, 1), fill=color, actions=actions)
# ----- text and numbers
def text(self, l, t, w, h, value, size=12, color='text', bold=False, align='Left', actions=(), name=FONT_UI,
bgfill=None):
l, t, w, h = self._b(l, t, w, h, False)
s = '<text type="componentData">' + self._id() + '<value>%s</value>' % esc(value)
s += font(size, bold, name) + paint('fillPaint', color)
l, w = fit(l, w, str(value), size, align, bold, name)
s += '<justification type="textJustification" value="TextJustificationCenter"/>'
if bgfill:
s += '<backgroundOn>true</backgroundOn>' + paint('backgroundPaint', bgfill)
s += '<stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize>'
s += box_elems(l, t, w, h) + data(actions) + '</text>'
self.add(s)
def number(self, l, t, w, h, item, fmt='999.9', size=22, color='text', bold=True, align='Right', attr='ItemValue',
extra=()):
l, t, w, h = self._b(l, t, w, h, False)
s = '<number type="componentData">' + self._id() + '<value>0.0</value><format>%s</format>' % fmt
s += font(size, bold, FONT_NUM) + paint('fillPaint', color)
l, w = fit(l, w, fmt.replace('9', '0'), size, align, bold, FONT_NUM)
s += '<justification type="textJustification" value="TextJustificationCenter"/>'
s += '<stroke type="stroke" width="1.0"/><keepOriginalSize>true</keepOriginalSize>'
s += box_elems(l, t, w, h) + data([conn('number.value', item, attr)] + list(extra)) + '</number>'
self.add(s)
def number_field(self, l, t, w, h, item, fmt='9999', size=14, editable=True, attr='ItemValue', as_datetime=False):
l, t, w, h = self._b(l, t, w, h, False)
s = '<numberField type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += font(size, True, FONT_NUM) + '<format>%s</format>' % fmt
s += '<editable>%s</editable>' % ('true' if editable else 'false')
if as_datetime:
s += '<asDateTime>true</asDateTime>'
s += colorset('foregroundColor', 'text') + colorset('backgroundColor', 'card2')
s += '<justification type="jTextJustification" value="TextJustificationRight"/>'
s += data([conn('numberField.value', item, attr, direction=None if editable else 1)]) + '</numberField>'
self.add(s)
def text_field(self, l, t, w, h, item, attr='ItemDescription', size=12):
l, t, w, h = self._b(l, t, w, h, False)
s = '<textField type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += font(size) + '<editable>false</editable>'
s += colorset('foregroundColor', 'text') + colorset('backgroundColor', 'card2')
s += data([conn('textField.value', item, attr)]) + '</textField>'
self.add(s)
def time_text(self, l, t, w, h, item, size=12, color='text', align='Left'):
"""Last update time of an item: number field with asDateTime (epoch seconds -> local date and time).\n The web dateTimeField only shows a value when editable (white input boxes)."""
self.number_field(l, t, w, h, item, '', size, editable=False, attr='ItemUpdTime', as_datetime=True)
def datetime_field(self, l, t, w, h, item, attr='ItemUpdTime', size=12, editable=True):
l, t, w, h = self._b(l, t, w, h, False)
s = '<dateTimeField type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += font(size) + colorset('foregroundColor', 'text')
s += '<editable>%s</editable><secondsVisible>true</secondsVisible>' % ('true' if editable else 'false')
s += colorset('backgroundColor', 'card2')
s += data([conn('dateTimeField.value', item, attr)]) + '</dateTimeField>'
self.add(s)
# ----- controls
def button(self, l, t, w, h, label, actions, fg='text', bg='card2', size=12, bold=True, tip=None, extra=()):
l, t, w, h = self._b(l, t, w, h, False)
s = '<button type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
if tip:
s += '<toolTipText>%s</toolTipText>' % esc(tip)
s += '<label>%s</label>' % esc(label) + font(size, bold)
s += colorset('foregroundColor', fg) + colorset('backgroundColor', bg)
s += data(list(actions) + list(extra)) + '</button>'
self.add(s)
def toggle(self, l, t, w, h, label, item, size=12):
l, t, w, h = self._b(l, t, w, h, False)
s = '<toggleButton type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += '<label>%s</label>' % esc(label) + font(size, True)
s += colorset('foregroundColor', 'text') + colorset('backgroundColor', 'card2')
s += data([conn('toggleButton.value', item, direction=None)]) + '</toggleButton>'
self.add(s)
def checkbox(self, l, t, w, h, label, item, size=12):
l, t, w, h = self._b(l, t, w, h, False)
s = '<checkBox type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += '<label>%s</label>' % esc(label) + font(size)
s += '<opaque>false</opaque>' + colorset('foregroundColor', 'text') + colorset('backgroundColor', 'card')
s += data([conn('checkBox.value', item, direction=None)]) + '</checkBox>'
self.add(s)
def slider(self, l, t, w, h, item, mn, mx, major, minor=None, size=10):
l, t, w, h = self._b(l, t, w, h, False)
s = '<slider type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += '<maximum>%s</maximum><minimum>%s</minimum><value>%s</value>' % (float(mx), float(mn), float(mn))
s += '<majorTickSpacing>%s</majorTickSpacing><minorTickSpacing>%s</minorTickSpacing>' % (
float(major), float(minor or major))
s += '<paintLabels>true</paintLabels><paintTicks>true</paintTicks><trackDrag>false</trackDrag>'
s += font(size) + '<opaque>false</opaque>' + colorset('foregroundColor', 'muted')
s += data([conn('slider.value', item, direction=None)]) + '</slider>'
self.add(s)
def spinner(self, l, t, w, h, item, mn, mx, step=1, size=14):
l, t, w, h = self._b(l, t, w, h, False)
s = '<spinner type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += '<editable>true</editable><step>%s</step><minimum>%s</minimum><maximum>%s</maximum>' % (
float(step), float(mn), float(mx))
s += font(size, True, FONT_NUM) + colorset('foregroundColor', 'text') + colorset('backgroundColor', 'card2')
s += '<zoomEnabled>false</zoomEnabled>'
s += data([conn('spinner.value', item, direction=None)]) + '</spinner>'
self.add(s)
def combo(self, l, t, w, h, item, options, size=12):
l, t, w, h = self._b(l, t, w, h, False)
"""options: 'value;Text;value;Text' (web client format)."""
s = '<comboBox type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += '<label>%s</label>' % esc(options) + font(size) + colorset('foregroundColor', 'text')
s += data([conn('comboBox.value', item, direction=None)]) + '</comboBox>'
self.add(s)
# ----- indicators
def databar(self, l, t, w, h, item, lo=0, hi=100, fg='blue', bg='track', direction='Up', border=None):
l, t, w, h = self._b(l, t, w, h, h > w)
s = '<dataBar type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += '<fillOn>true</fillOn>' + paint('background', bg) + paint('foreground', fg)
s += paint('borderColor', border or bg) + paint('foregroundBorderColor', fg)
s += '<lowLimit>%s</lowLimit><highLimit>%s</highLimit>' % (float(lo), float(hi))
s += '<growthDirection type="growthDirection" value="GrowthDirection%s"/>' % direction
s += data([conn('dataBar.value', item)]) + '</dataBar>'
self.add(s)
def rect_scale(self, l, t, w, h, mn, mx, major, minor, vertical=True, fmt='999', size=10):
l, t, w, h = self._b(l, t, w, h, h > w)
s = '<rectangularScale type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += '<maximum>%s</maximum><minimum>%s</minimum><majorTickSpacing>%s</majorTickSpacing>' % (
float(mx), float(mn), float(major))
s += '<minorTickSpacing>%s</minorTickSpacing><format>%s</format><vertical>%s</vertical>' % (
float(minor), fmt, 'true' if vertical else 'false')
s += colorset('color', 'muted') + font(size) + '</rectangularScale>'
self.add(s)
def circ_scale(self, cx, cy, rad, mn, mx, major, minor, start=225, extent=-270, fmt='999', size=9):
cy = cy * self.sy
s = '<circularScale type="componentData" %s>' % box_attrs(cx - rad, cy - rad, 2 * rad, 2 * rad) + self._id()
s += '<maximum>%s</maximum><minimum>%s</minimum><majorTickSpacing>%s</majorTickSpacing>' % (
float(mx), float(mn), float(major))
s += '<minorTickSpacing>%s</minorTickSpacing><format>%s</format>' % (float(minor), fmt)
s += '<startAngle>%s</startAngle><extentAngle>%s</extentAngle>' % (float(start), float(extent))
s += colorset('color', 'muted') + font(size) + '</circularScale>'
self.add(s)
def ring_gauge(self, cx, cy, rad, item, mn, mx, color='teal', sw=12.0, thresholds=None):
"""270 degree ring with the gap on the right; the value arc grows from 9 o'clock up and down.
Arc angles run clockwise from 3 o'clock on both clients (tested 2026-10-06, fixed and
connected angles): track 45..315 degrees, value arc centred on 180 degrees
(start = 180 - extent / 2)."""
self.arc(cx, cy, rad, 45, 270, 'track', sw)
acts = [conn('arc.extentAngle', item, transform=tr_linear(mn, mx, 0.5, 270)),
conn('arc.startAngle', item, transform=tr_linear(mn, mx, 179.75, 45))]
if thresholds:
acts.append(conn('arc.strokePaint', item, transform=tr_threshold(thresholds)))
self.arc(cx, cy, rad, 179.75, 0.5, color, sw, acts)
def lamp(self, l, t, d, item, on='green', off='off', inp='Boolean', table=None):
tbl = table or [(False, off), (True, on)]
self.ellipse(l, t, d, d, fill=off, actions=[conn('ellipse.fillPaint', item,
transform=tr_threshold(tbl, inp))])
# ----- complex components
def alarm_overview(self, l, t, w, h, overview='CurrentAlarms', asa=None, size=12, banner=False):
l, t, w, h = self._b(l, t, w, h, True)
s = '<alarmOverview type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += '<zoomEnabled>false</zoomEnabled>'
s += '<overviewType type="alarmOverview" value="%s"/>' % overview
# dark rows: background, unacknowledged / acknowledged row colour per priority, text colours
s += '<opaque>true</opaque>' + colorset('backgroundColor', 'panel')
for c, col in (('Alarm', (248, 113, 113)), ('Normal', 'text'), ('Ackn', 'muted'), ('Info', 'muted'),
('Diag', 'amber'), ('Deactive', 'muted'), ('Recover', 'green')):
s += colorset('eventType%sAckColor' % c, col) + colorset('eventType%sNackColor' % c, col)
for p in range(0, 16):
s += ('<property type="componentProperty"><name>priorityNackColor[%02d]</name><value type="colorSet" %s/></property>'
'<property type="componentProperty"><name>priorityAckColor[%02d]</name><value type="colorSet" %s/></property>'
) % (p, rgb((64, 24, 30) if p <= 3 else (36, 45, 57)), p, rgb('card'))
s += font(size) + font(size, False, FONT_UI, 'alarmLineFont') + font(size - 1, True, FONT_UI, 'buttonFont')
# explicit columns: order and widths spread over the whole component width (autoFit off)
cols = [('AlarmTime', 200), ('Priority', 70), ('Section', 300), ('Tag', 170), ('ItemDesciption', 320),
('Text', 300), ('AlarmType', 120), ('Value', 110), ('Acknowledged', 110)]
scale = (w - 24.0) / sum(c[1] for c in cols)
for i, (c, cw) in enumerate(cols):
s += '<column%sVisible>true</column%sVisible><column%sPosition>%d</column%sPosition>' % (c, c, c, i + 1, c)
s += '<column%sWidth>%d</column%sWidth>' % (c, int(cw * scale), c)
hide = ['CEventActor', 'CEventCat', 'CEventCondition', 'CEventSource', 'CEventSubCond', 'EventActor',
'EventCat', 'EventCondition', 'EventSource', 'EventSubCond', 'Installation', 'ItemName',
'OriginalTime', 'Quality', 'Unit', 'User', 'Sub', 'EngUnits', 'Location', 'InstallationDescription',
'UnitDescription', 'SectionDescription', 'AlarmCollection', 'EventID', 'ConditionID', 'BranchID',
'PriorityText'] # AlarmAttribute is an array property
for c in hide:
s += '<column%sVisible>false</column%sVisible>' % (c, c)
if banner:
s += ('<statusLineVisible>false</statusLineVisible><autoFit>false</autoFit><stopMoreVisible>false'
'</stopMoreVisible><headingVisible>false</headingVisible><dateTimeSelectorVisible>false'
'</dateTimeSelectorVisible><filterSelectorVisible>false</filterSelectorVisible>')
else:
# autoFit in a tab that is hidden while loading squeezes all columns to nothing (web)
s += '<autoFit>false</autoFit>'
s += '<highAlarmPriorityRange>1-1</highAlarmPriorityRange><mediumAlarmPriorityRange>2-2</mediumAlarmPriorityRange>'
s += '<lowAlarmPriorityRange>3-3</lowAlarmPriorityRange><diagnosticAlarmPriorityRange>0-0,4-15</diagnosticAlarmPriorityRange>'
if asa:
s += ('<userDataFilterType type="alarmUserFilter" value="UserDataFilterASA"/>'
'<userDataFilterValue>%s</userDataFilterValue>'
'<dataFilterType type="alarmDataFilter" value="DataFilterUserFiler"/>') % asa
s += '<data type="data"><action type="actionInternalServiced"/></data></alarmOverview>'
self.add(s)
def report(self, l, t, w, h, report=None):
l, t, w, h = self._b(l, t, w, h, True)
s = '<reporting type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
if report:
s += '<reportSelected>%s</reportSelected>' % esc(report)
s += '<data type="data"><action type="actionInternalServiced"/></data></reporting>'
self.add(s)
def micro_trend(self, l, t, w, h, pens, time_range=600, history=True):
l, t, w, h = self._b(l, t, w, h, True)
"""pens: list of (item, min, max, colour)."""
s = '<microTrend type="componentData" %s>' % box_attrs(l, t, w, h) + self._id()
s += '<numberOfPens>%d</numberOfPens><realTime>true</realTime><fillWithHistory>%s</fillWithHistory>' % (len(pens), 'true' if history else 'false')
s += '<microTrendBackgroundFillOn>true</microTrendBackgroundFillOn><lowHighFillOn>false</lowHighFillOn>'
s += colorset('microTrendBackgroundFillColor', 'panel') + colorset('microTrendBackgroundColor', 'line')
acts = ['<action type="actionInternalServiced"/>']
for i, (item, mn, mx, col) in enumerate(pens):
s += ('<property type="componentProperty"><name>itemName[%d]</name><value/></property>'
'<property type="componentProperty"><name>scaleMin[%d]</name><value>%s</value></property>'
'<property type="componentProperty"><name>scaleMax[%d]</name><value>%s</value></property>'
'<property type="componentProperty"><name>color[%d]</name><value type="colorSet" %s/></property>'
'<property type="componentProperty"><name>stroke[%d]</name><value type="stroke" width="2.0"/></property>'
) % (i, i, float(mn), i, float(mx), i, rgb(col), i)
acts.append(conn('microTrend.itemName[%d]' % i, item, 'ItemName'))
s += data(acts) + '</microTrend>'
self.add(s)
def trend(self, l, t, w, h, pens, minutes=10, title='', web_spares=True):
l, t, w, h = self._b(l, t, w, h, True)
"""pens: list of (item, colour, min, max, description). Padded to 50 visible pens (ISS-041)."""
def pen(item, col, mn, mx, desc, spare=0):
if spare:
col_x = colorset('color', 'panel')
stroke, legend, vis_leg, rng, mn_s, mx_s, typ = '0.0', ' ' * spare, 'false', 1, '1.0E30', '2.0E30', 1
desc = ''
else:
col_x = colorset('color', col)
stroke, legend, vis_leg, rng, mn_s, mx_s, typ = '2.0', '', 'true', 1, repr(float(mn)), repr(float(mx)), 0
return ('<pen type="pen"><type>%d</type>%s<stroke type="stroke" width="%s"/><paint>@NULL</paint>'
'<visible>true</visible><visibleLegend>%s</visibleLegend>'
'<source type="sourceID" uri="ci:/item/%s"/><axisVisible>%s</axisVisible><axisPosition>0</axisPosition>'
'<labelVisible>true</labelVisible><majorTickVisible>true</majorTickVisible><minorTickVisible>true</minorTickVisible>'
'<axisColor>@NULL</axisColor><labelColor>@NULL</labelColor><scaleRangeType>%d</scaleRangeType>'
'<minimum>%s</minimum><maximum>%s</maximum><procentual>false</procentual><title/>'
'<description>%s</description><legendText>%s</legendText><titlePlacement>0</titlePlacement>'
'<titleRotation>0</titleRotation><labelRotation>0</labelRotation><majorGridVisible>false</majorGridVisible>'
'<minorGridVisible>false</minorGridVisible><lowHighLimitGridVisible>false</lowHighLimitGridVisible>'
'<lowHighLimitGridAreaVisible>false</lowHighLimitGridAreaVisible>'
'<lowLowHighHighLimitGridVisible>false</lowLowHighHighLimitGridVisible><majorGridColor>@NULL</majorGridColor>'
'<minorGridColor>@NULL</minorGridColor><lowHighLimitGridColor>@NULL</lowHighLimitGridColor>'
'<lowHighLimitGridAreaColor>@NULL</lowHighLimitGridAreaColor>'
'<lowLowHighHighLimiGridColor>@NULL</lowLowHighHighLimiGridColor>'
'<majorGridStroke type="stroke" width="0.1"/><minorGridStroke type="stroke" width="0.1"/>'
'<lowHighLimitGridStroke type="stroke" width="0.1"/><lowLowHighHighLimiGridStroke type="stroke" width="0.1"/>'
'<annotationVisible>false</annotationVisible><timeShift>0</timeShift></pen>') % (
typ, col_x, stroke, vis_leg, esc(item), 'true' if (not spare and pens and item == pens[0][0]) else 'false',
rng, mn_s, mx_s, esc(desc), legend)
body = ''.join(pen(*p) for p in pens)
if web_spares: # the web trend draws only with 50 visible pens (ISS-041); the desktop hairline then lists 50 values
body += ''.join(pen(pens[0][0], None, 0, 0, '', i) for i in range(1, 51 - len(pens)))
s = ('<chart type="componentData">' + self._id() +
'<config type="graphicInfo"><version type="version" value="1.3.0.0"/>'
'<backgroundBorder type="border" value="BorderEmpty"/><penPanelVisible>false</penPanelVisible>'
'<penPanelHeight>-1</penPanelHeight><toolbarVisible>true</toolbarVisible>'
'<toolbarPosition type="borderLayoutPosition" value="PositionNorth"/><shiftOffset>0</shiftOffset>'
'<shiftLength>0</shiftLength><enterpriseGroupLocation type="nodeName" node="$display$"/>'
'<chartPanel><name/><author/><version type="version" value="1.3.0.0"/><description/>'
'<forAllUsers>false</forAllUsers><template>false</template><group>@NULL</group><XyMode>false</XyMode>'
'<x>0</x><y>0</y><width>%d</width><heigth>%d</heigth><iconized>false</iconized>'
'<backgroundBorder type="border" value="BorderEmpty"/>%s'
'<backgroundPaint type="paint"><paint type="colorSet" %s/></backgroundPaint>'
'<plotAreaBorder type="border" value="BorderEmpty"/><plotAreaTransparent>false</plotAreaTransparent>'
'<plotAreaIcon>@NULL</plotAreaIcon><plotAreaPaint type="paint"><paint type="colorSet" %s/></plotAreaPaint>'
'%s<hairlineVisible>false</hairlineVisible><antialiasingText>true</antialiasingText>'
'<antialiasingData>true</antialiasingData><renderMode type="chartRendering" value="Rendering2d"/>'
'<timeNavigatorVisible>true</timeNavigatorVisible><timeRangeControlVisible>true</timeRangeControlVisible>'
'<autoUpdateInterval>false</autoUpdateInterval><legendVisible>true</legendVisible><legendTitle/>'
'<legendHeading/>%s%s%s<legendTransparancy>0.0</legendTransparancy>'
'<legendBorderType type="border" value="BorderEmpty"/><legendPositionType type="position" value="PositionNorthEast"/>'
'<timeSliderVisible>true</timeSliderVisible><timeSliderAbove>false</timeSliderAbove>'
'<valueSliderVisible>false</valueSliderVisible><valueSliderLeft>false</valueSliderLeft>'
'<xAxisReversed>false</xAxisReversed><yAxisReversed>false</yAxisReversed><projectorReversed>false</projectorReversed>'
'<scalingFonts>false</scalingFonts><maximumPens>50</maximumPens><pensPerPack>0</pensPerPack>'
'<triggerPen>0</triggerPen><timeAxisVisible>true</timeAxisVisible><timeAxisMajorTickVisible>true</timeAxisMajorTickVisible>'
'<timeAxisMinorTickVisible>false</timeAxisMinorTickVisible>%s%s%s'
'<timeAxisLabelVisible>true</timeAxisLabelVisible><timeAxisLongLabelVisible>false</timeAxisLongLabelVisible>'
'<timeAxisLabelRotation>0</timeAxisLabelRotation><timeAxisTitle/><timeAxisTitleRotation>0</timeAxisTitleRotation>'
'<timeAxisTitlePlacement>50</timeAxisTitlePlacement><timeAxisMajorGridVisible>true</timeAxisMajorGridVisible>'
'%s<timeAxisMajorGridStroke type="stroke" width="1.0" endCap="butt" lineJoin="bevel"/>'
'<timeAxisMinorGridVisible>false</timeAxisMinorGridVisible>%s'
'<timeAxisMinorGridStroke type="stroke" width="1.0" endCap="butt" lineJoin="bevel"/>'
'<headerText>%s</headerText>%s%s<headerJustification type="jTextJustification" value="TextJustificationLeft"/>'
'<footerText/>%s%s<footerJustification type="jTextJustification" value="TextJustificationLeft"/>'
'<enterprisePrimarySourceLocation type="nodeName" node="$default$"/>'
'<enterpriseSecondarySourceLocation type="nodeName" node="$default$"/>'
'<enterprisePrimaryHistoryLocation type="nodeName" node="$default$"/>'
'<enterpriseSecondaryHistoryLocation type="nodeName" node="$default$"/>'
'<updateFromHistory>true</updateFromHistory><useSampleInterval>true</useSampleInterval>'
'<sampleInterval>0</sampleInterval><optimised>true</optimised>%s'
'<timeRange type="timeRangeLast" count="%d"><type type="timeUnit" value="TimeUnitMinute"/></timeRange>'
'<updateInterval>5</updateInterval><fillHistory>true</fillHistory><updating>true</updating>'
'</chartPanel></config>%s<data type="data"><action type="actionInternalServiced"/></data></chart>') % (
w, h, colorset('foregroundColor', 'muted'), rgb('panel'), rgb('panel'), colorset('hairlineColor', 'muted'),
colorset('legendColor', 'text'), colorset('legendBackgroundColor', 'panel'), font(11, False, FONT_UI, 'legendFont'),
colorset('timeAxisColor', 'muted'), font(11, False, FONT_UI, 'timeAxisFont'), colorset('timeAxisLabelColor', 'muted'),
colorset('timeAxisMajorGridColor', 'line'), colorset('timeAxisMinorGridColor', 'line'),
esc(title), colorset('headerColor', 'text'), font(12, True, FONT_UI, 'headerFont'),
colorset('footerColor', 'muted'), font(11, False, FONT_UI, 'footerFont'), body, minutes, box_elems(l, t, w, h))
self.add(s)
# ----- output
def xml(self):
vg = ''
for i, (n, d, z) in enumerate([('Overview', 'Always shown', 10.0), ('Rough', 'Shown when viewing viewing a large area', 25.0),
('Standard', 'Shown when using the default view setting', 100.0),
('Detail', 'Shown only when viewing a small area', 400.0),
('Intricacies', 'Shown only when viewing a very small area', 1000.0)]):
vg += ('<visibilityGroup type="componentData"><htmlId>%d</htmlId><name>%s</name><description>%s</description>'
'<minimumZoomEnabled>true</minimumZoomEnabled><minimumZoomFactor>%s</minimumZoomFactor>'
'</visibilityGroup>\n') % (i + 2, n, d, z)
head = ('<?xml version="1.0" encoding="utf-8" ?>\n<visualization protocolVersion="1.3.0.0">\n <globalSection/>\n'
' <coreObjectDefinition type="displayDefinition">\n<version type="version" value="1.3.0.0"/>\n'
'<title>%s</title>\n<html>true</html>\n<width>%d</width>\n<height>%d</height>\n'
'<referenceCheck>%d</referenceCheck>\n'
'%s\n<backgroundColorOn>true</backgroundColorOn>\n%s\n%s\n%s\n<defaultStroke type="stroke" width="1.0"/>\n'
'<grid type="grid" gridVisible="true" snappingActive="true" verticalSnapInterval="4" horizontalSnapInterval="4" onTop="false">'
'<color type="colorSet" r="51" g="59" b="71"/></grid>\n'
'<revisionHistory type="revisionHistory"><revision type="revision" who="ADMIN" when="2026.10.02 12:00:00.000 AEST" '
'what="Generated by displays/generator/build.py" where="localhost"/></revisionHistory>\n'
'<blinkDelay>500</blinkDelay>\n<blinkEnabled>true</blinkEnabled>\n<mousePassThrough>false</mousePassThrough>\n'
) % (esc(self.title), self.w, self.h, self.hid, colorset('backgroundColor', self.bg),
colorset('defaultBgColor', self.bg), colorset('defaultFgColor', 'text'), font(12, False, FONT_UI, 'defaultFont'))
layer = '<visualizationLayer type="componentData"><htmlId>1</htmlId><name>Layer1</name></visualizationLayer>\n'
body = '<componentCountHint>%d</componentCountHint>\n' % len(self.parts)
# full-size background rectangle first (the web client ignores the display background colour on some frames)
return (head + vg + layer + body + '\n'.join(self.parts) +
'\n </coreObjectDefinition>\n</visualization>\n')
def save(self, folder):
import os
with open(os.path.join(folder, self.name + '.xml'), 'w', encoding='utf-8', newline='\r\n') as f:
f.write(self.xml())

View file

@ -1,9 +1,11 @@
@echo off
rem Remove the CI-Eng-Sample displays (operator interface and HTML version). CI Server R1.03.00.
rem Close them in the Edit Module first.
rem Close CIENG_Tank, CIENG_Menu and CIENG_TrendLab in the Edit Module first.
set WAP=%TLS_WAP_PATH%
if not defined TLS_WAP_PATH set WAP=C:\Users\Public\Yokogawa\tls\wap
for %%d in (CIENG_Header CIENG_Overview CIENG_Control CIENG_Trends CIENG_Alarms CIENG_System CIENG_AlarmBanner CIENG_TankFaceplate) do (
if exist "%WAP%\cfg\operatorInterfaces\DEPLOY\displays\%%d.xml" del /q "%WAP%\cfg\operatorInterfaces\DEPLOY\displays\%%d.xml"
if exist "%WAP%\mobileoperator\operatorInterfaces\DEPLOY\displays\%%d.html" del /q "%WAP%\mobileoperator\operatorInterfaces\DEPLOY\displays\%%d.html"
)
del /q "%WAP%\cfg\operatorInterfaces\DEPLOY\displays\CIENG_Tank.xml"
del /q "%WAP%\mobileoperator\operatorInterfaces\DEPLOY\displays\CIENG_Tank.html"
del /q "%WAP%\cfg\operatorInterfaces\DEPLOY\displays\CIENG_Menu.xml"
del /q "%WAP%\mobileoperator\operatorInterfaces\DEPLOY\displays\CIENG_Menu.html"
del /q "%WAP%\cfg\operatorInterfaces\DEPLOY\displays\CIENG_TrendLab.xml"
del /q "%WAP%\mobileoperator\operatorInterfaces\DEPLOY\displays\CIENG_TrendLab.html"

View file

@ -0,0 +1,16 @@
# Feed test values into the CI-Eng-Sample tank items so trends have a moving line.
# CI Server R1.03.00. TANK1.LEVEL and TANK1.INFLOW are internal items: after a restart they
# stay NOT INIT until something writes them. Writes every 5 s with itmval; stop with Ctrl+C.
# LEVEL = 50 +/- 25 % (period 10 min, stays inside the L 20 / H 80 alarm limits)
# INFLOW = 250 +/- 150 m3/h (period 4 min)
param([int]$Seconds = 3600)
$end = (Get-Date).AddSeconds($Seconds)
while ((Get-Date) -lt $end) {
$t = [double]((Get-Date) - (Get-Date).Date).TotalSeconds
$level = [math]::Round(50 + 25 * [math]::Sin(2 * [math]::PI * $t / 600), 1)
$inflow = [math]::Round(250 + 150 * [math]::Sin(2 * [math]::PI * $t / 240), 1)
itmval -p -n CI-Eng-Sample.TANK1.LEVEL -v $level > $null
itmval -p -n CI-Eng-Sample.TANK1.INFLOW -v $inflow > $null
Start-Sleep -Seconds 5
}

View file

@ -1,79 +0,0 @@
# CI-Eng-Sample live data: writes test values into the sample items so displays, trends and alarms
# move (internal items stay NOT INIT after a CI Server start). CI Server R1.03.00. Replaces
# displays\trend_feed.ps1. Not part of the CI Server package: installed with install_feed.ps1 into
# C:\Users\Public\CI-Eng-Sample\feed, from where the display button "Start" runs it.
#
# Usage: powershell -ExecutionPolicy Bypass -File cieng_feed.ps1 [-Seconds 3600] [-UntilFlag] [-Alarms] [-System] [-Cycle 5]
# (default) run for -Seconds (3600)
# -UntilFlag run while CI-Eng-Sample.DEMO.FEED_ON = 1 (display buttons Start / Stop); sets it to 1
# at start and 0 at the end
# -Alarms LEVEL 50 +/- 33 % (crosses L 20 and H 80: alarms that need an acknowledgement);
# without it 50 +/- 25 % (stays inside the limits)
# -System also write SYSTEM.CPU_LOAD / DISK_C / PING_LOCALHOST / PROC_ALM with this PC's real
# values - skipped automatically while the monitoring processes (intcpumon, intdskmon,
# inttcpmon, intmon; see ..\monitoring) are running, so they do not overwrite each other
# Every cycle (default 5 s): TANK1.LEVEL (sine, 10 min), TANK1.INFLOW (250 +/- 150 m3/h, 4 min);
# PUMP1.RUNNING = 1 while INFLOW > 250, only in auto mode (PUMP1.MODE = 1).
# Only one copy runs at a time; log: %TLS_LST_PATH%\cieng_feed.log (start / stop lines).
param([int]$Seconds = 3600, [switch]$UntilFlag, [switch]$Alarms, [switch]$System, [int]$Cycle = 5)
$itmval = 'itmval'
if ($env:TLS_ROOT_PATH) {
$exe = Join-Path $env:TLS_ROOT_PATH 'tls\exe\itmval.exe'
if (Test-Path $exe) { $itmval = $exe }
}
$S = 'CI-Eng-Sample.'
$logDir = $env:TLS_LST_PATH
if (-not $logDir) { $logDir = $PSScriptRoot }
$log = Join-Path $logDir 'cieng_feed.log'
function Get-Val([string]$name) {
$out = & $itmval -g -n ($S + $name) 2>$null
foreach ($l in $out) { if ($l -match '^Value\s*=\s*(.+)$') { return $Matches[1].Trim() } }
return $null
}
function Put([string]$name, $value) { & $itmval -p -n ($S + $name) -v $value > $null 2>&1 }
function Write-Log([string]$text) {
try { Add-Content -Path $log -Value ('{0} {1}' -f (Get-Date -Format s), $text) } catch { }
}
$created = $false
$mutex = New-Object Threading.Mutex($true, 'Global\CIENG_FEED', [ref]$created)
if (-not $created) { Write-Log 'already running - this copy exits'; exit 0 }
$amp = 25
if ($Alarms) { $amp = 33 }
$monitors = @('intcpumon', 'intdskmon', 'inttcpmon', 'intmon')
$mode = 'seconds=' + $Seconds
if ($UntilFlag) { $mode = 'until FEED_ON = 0' }
$end = (Get-Date).AddSeconds($Seconds)
try {
Write-Log ('start ({0}, alarms={1}, system={2}, user {3})' -f $mode, [bool]$Alarms, [bool]$System, [Environment]::UserName)
if ($UntilFlag) { Put 'DEMO.FEED_ON' 1 }
while ($true) {
if ($UntilFlag) { if ((Get-Val 'DEMO.FEED_ON') -ne '1') { break } }
elseif ((Get-Date) -ge $end) { break }
$t = [double]((Get-Date) - (Get-Date).Date).TotalSeconds
$level = [math]::Round(50 + $amp * [math]::Sin(2 * [math]::PI * $t / 600), 1)
$inflow = [math]::Round(250 + 150 * [math]::Sin(2 * [math]::PI * $t / 240), 1)
Put 'TANK1.LEVEL' $level
Put 'TANK1.INFLOW' $inflow
if ((Get-Val 'PUMP1.MODE') -eq '1') { Put 'PUMP1.RUNNING' ([int]($inflow -gt 250)) }
if ($System -and -not (Get-Process -Name $monitors -ErrorAction SilentlyContinue)) {
try {
$cpus = @(Get-CimInstance Win32_Processor)
$cpu = 0; foreach ($c in $cpus) { $cpu += $c.LoadPercentage }; $cpu = $cpu / [math]::Max(1, $cpus.Count)
Put 'SYSTEM.CPU_LOAD' ([math]::Round($cpu, 1))
$d = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='C:'"
Put 'SYSTEM.DISK_C' ([math]::Round(100 * ($d.Size - $d.FreeSpace) / $d.Size, 1))
Put 'SYSTEM.PING_LOCALHOST' ([int](Test-Connection -ComputerName localhost -Count 1 -Quiet))
Put 'SYSTEM.PROC_ALM' ([int]([bool](Get-Process alm -ErrorAction SilentlyContinue)))
} catch { }
}
Start-Sleep -Seconds $Cycle
}
} finally {
if ($UntilFlag) { Put 'DEMO.FEED_ON' 0 }
Write-Log 'stop'
$mutex.ReleaseMutex()
}

View file

@ -1,6 +0,0 @@
@echo off
rem Starts cieng_feed.ps1 in the background (CI Server R1.03.00). Called by the display button
rem "Start" (server-side command, runs as the CI Server service account CIX_PROCESS) from the
rem fixed install folder C:\Users\Public\CI-Eng-Sample\feed (install_feed.ps1). Returns at once;
rem the feed runs until the button "Stop" writes CI-Eng-Sample.DEMO.FEED_ON = 0.
start "" /b powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "%~dp0cieng_feed.ps1" -UntilFlag -Alarms -System

View file

@ -1,18 +0,0 @@
# Install or remove the CI-Eng-Sample live-data feed (CI Server R1.03.00).
# Copies cieng_feed.ps1 and cieng_feed_start.cmd to C:\Users\Public\CI-Eng-Sample\feed: a fixed folder
# outside the CI Server installation (the feed is not part of the CI Server package) that the CI
# Server service account can read. The display button "Start" calls the .cmd there.
# No admin rights needed. Usage: powershell -ExecutionPolicy Bypass -File install_feed.ps1 [-Remove]
param([switch]$Remove)
$dest = 'C:\Users\Public\CI-Eng-Sample\feed'
if ($Remove) {
if (Test-Path $dest) { Remove-Item -LiteralPath $dest -Recurse -Force }
$parent = Split-Path $dest
if ((Test-Path $parent) -and -not (Get-ChildItem -LiteralPath $parent -Force)) { Remove-Item -LiteralPath $parent -Force }
'Feed removed from ' + $dest
return
}
New-Item -ItemType Directory -Force -Path $dest > $null
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'cieng_feed.ps1') -Destination $dest -Force
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'cieng_feed_start.cmd') -Destination $dest -Force
'Feed installed in ' + $dest

View file

@ -1,13 +1,11 @@
<!-- CIENG-SAMPLE-BEGIN: CI-Eng-Sample operator layouts (CI Server R1.03.00).
<!-- CIENG-SAMPLE-BEGIN: CI-Eng-Sample operator layout (CI Server R1.03.00).
Added and removed by examples\CI-Eng-Sample\layouts\layout.ps1; do not edit inside Layouts.xml.
CIENG_Operator: menu, navigation toolbar, header frame "hdr" (CIENG_Header), tab set "default"
with frames ovw / ctl / trd / alm / sys, alarm banner frame (CIENG_AlarmBanner), status line.
CIENG_Popup: faceplate window (CIENG_TankFaceplate). No AOG displays are used.
Desktop: frames inside a <tab> ignore their zoom attribute; the navigate commands carry
stretchDisplay instead (and CIENG_AlarmBanner opens the Overview tab that way at logon). -->
Window: menu, toolbar, navigation frame "nav" (left), main frame "default" (right),
alarm banner frame (bottom), status line. The main frame is called "default" because the
AOG displays (alarm lists, faceplates) open their targets in a frame named "default". -->
<layout
name="CIENG_Operator"
title="CI-Eng-Sample Demo"
title="CI-Eng-Sample - $default"
icon="poi.png"
drawBorder="true"
sizingAllowed="true"
@ -17,90 +15,170 @@
initialPosition="centreScreen"
initialPositionX="0"
initialPositionY="0"
initialSize="desktopSize"
initialSizeWidth="1920"
initialSizeHeight="1040"
initialSize="pixels"
initialSizeWidth="1600"
initialSizeHeight="900"
maximumOpen="1">
<menu>
<menu-item name="cieng.menu.file" label="File" mnemonic="f">
<menu-item name="cieng.menu.file.print" label="Print..." mnemonic="p" tooltip="Print the current tab" command="print frameWithSetup"/>
<menu-item
name="cieng.menu.file"
label="File"
mnemonic="f">
<menu-item
name="cieng.menu.file.print"
label="Print..."
mnemonic="p"
tooltip="Print $"
command="print frameWithSetup"/>
<menu-separator/>
<menu-item name="cieng.menu.file.logout" label="Log out" mnemonic="l" tooltip="Log out" command="logout"/>
<menu-item name="cieng.menu.file.exit" label="Exit" mnemonic="x" tooltip="Close this window" command="exit"/>
<menu-item
name="cieng.menu.file.exit"
label="Exit"
mnemonic="x"
tooltip="Close this window"
command="exit"/>
</menu-item>
<menu-item name="cieng.menu.view" label="View" mnemonic="v">
<menu-item name="cieng.menu.view.reload" label="Reload all" mnemonic="r" accelerator="F5" tooltip="Reload all displays" command="reload all"/>
<menu-item name="cieng.menu.view.fullscreen" label="Full screen" mnemonic="u" accelerator="F11" tooltip="Toggle full screen" command="toggleSize fullScreen"/>
<menu-item
name="cieng.menu.view"
label="View"
mnemonic="v">
<menu-item
name="cieng.menu.view.reload"
label="Reload"
mnemonic="r"
accelerator="F5"
tooltip="Reload $"
command="reload default"/>
<menu-item
name="cieng.menu.view.reload.all"
label="Reload All"
mnemonic="a"
tooltip="Reload all displays"
command="reload all"/>
<menu-separator/>
<menu-item name="cieng.menu.view.toolbar" label="Toolbar" mnemonic="t" type="check" tooltip="Show or hide the toolbar" command="toolbar"/>
<menu-item name="cieng.menu.view.status" label="Status line" mnemonic="s" type="check" tooltip="Show or hide the status line" command="statusline"/>
<menu-item
name="cieng.menu.view.fullscreen"
label="Full screen"
mnemonic="u"
accelerator="F11"
tooltip="Toggle full screen"
command="toggleSize fullScreen"/>
</menu-item>
<menu-item name="cieng.menu.displays" label="Displays" mnemonic="d">
<menu-item name="cieng.menu.displays.ovw" label="Overview" mnemonic="o" accelerator="F1" command="navigate to ovw CIENG_Overview stretchDisplay"/>
<menu-item name="cieng.menu.displays.ctl" label="Process control" mnemonic="p" accelerator="F2" command="navigate to ctl CIENG_Control stretchDisplay"/>
<menu-item name="cieng.menu.displays.trd" label="Trends" mnemonic="t" accelerator="F3" command="navigate to trd CIENG_Trends stretchDisplay"/>
<menu-item name="cieng.menu.displays.alm" label="Alarms" mnemonic="a" accelerator="F4" command="navigate to alm CIENG_Alarms stretchDisplay"/>
<menu-item name="cieng.menu.displays.sys" label="System" mnemonic="s" accelerator="F6" command="navigate to sys CIENG_System stretchDisplay"/>
<menu-item
name="cieng.menu.displays"
label="Displays"
mnemonic="d">
<menu-item
name="cieng.menu.displays.tank"
label="Tank 1"
mnemonic="t"
tooltip="Tank 1 overview"
command="navigate to default CIENG_Tank fitDisplay"/>
<menu-separator/>
<menu-item
name="cieng.menu.displays.alarmCurrent"
label="Current alarms"
mnemonic="c"
tooltip="Current alarm list"
command="navigate to default AOG_AlarmCurrent"/>
<menu-item
name="cieng.menu.displays.alarmHistory"
label="Alarm history"
mnemonic="h"
tooltip="Historical alarm list"
command="navigate to default AOG_AlarmHistory"/>
<menu-item
name="cieng.menu.displays.trend"
label="Trend"
mnemonic="r"
tooltip="Trend display"
command="navigate to default AOG_TrendOpen"/>
</menu-item>
</menu>
<toolbar name="cieng.toolbar" label="Navigation" floatable="false" position="top">
<toolbar-item name="cieng.toolbar.back" icon="ciNavLeft32.png" label="" tooltip="Back to $" command="navigate back ovw"/>
<toolbar-item name="cieng.toolbar.forward" icon="ciNavRight32.png" label="" tooltip="Forward to $" command="navigate forward ovw"/>
<toolbar-item name="cieng.toolbar.home" icon="ciOverview32.png" label="" tooltip="Home: Overview" command="navigate home ovw"/>
<toolbar
name="cieng.toolbar"
label="CI-Eng-Sample"
floatable="false"
position="top">
<toolbar-item
name="cieng.toolbar.back"
icon="ciNavLeft32.png"
label=""
tooltip="Back to $"
command="navigate back default"/>
<toolbar-item
name="cieng.toolbar.forward"
icon="ciNavRight32.png"
label=""
tooltip="Forward to $"
command="navigate forward default"/>
<toolbar-item
name="cieng.toolbar.home"
icon="ciOverview32.png"
label=""
tooltip="Home to $"
command="navigate home default"/>
<toolbar-item
name="cieng.toolbar.history"
tooltip="History"
label="History"
type="editableCombo"
command="navigate history default"/>
<toolbar-separator/>
<toolbar-item name="cieng.toolbar.ovw" label="Overview" tooltip="Overview (F1)" command="navigate to ovw CIENG_Overview stretchDisplay"/>
<toolbar-item name="cieng.toolbar.ctl" label="Process control" tooltip="Process control (F2)" command="navigate to ctl CIENG_Control stretchDisplay"/>
<toolbar-item name="cieng.toolbar.trd" label="Trends" tooltip="Trends (F3)" command="navigate to trd CIENG_Trends stretchDisplay"/>
<toolbar-item name="cieng.toolbar.alm" icon="ciProAlar32.png" label="Alarms" tooltip="Alarms (F4)" command="navigate to alm CIENG_Alarms stretchDisplay"/>
<toolbar-item name="cieng.toolbar.sys" label="System" tooltip="System (F6)" command="navigate to sys CIENG_System stretchDisplay"/>
<toolbar-separator/>
<toolbar-item name="cieng.toolbar.reload" label="Reload" tooltip="Reload all displays" command="reload all"/>
<toolbar-item name="cieng.toolbar.full" icon="ciZoomFull32.png" label="" tooltip="Full screen" command="toggleSize fullScreen"/>
<toolbar-item
name="cieng.toolbar.alarmCurrent"
icon="ciProAlar32.png"
label=""
tooltip="Current alarm list"
command="navigate to default AOG_AlarmCurrent"/>
<toolbar-item
name="cieng.toolbar.zoomFit"
icon="ciZoomFull32.png"
label=""
tooltip="Fit display"
command="zoom 0 default"/>
</toolbar>
<!-- The tab set must be the LAST child of its frame-set: the web client (R1.03) binds the tab
click handler to the last panel created in the frame-set. -->
<frame-set rows="1*,fitDisplay" borderStyle="none">
<frame-set rows="fitDisplay,1*" borderStyle="none">
<frame name="hdr" stackSize="1" zoomingAllowed="false" scrollingAllowed="false" initialDisplay="CIENG_Header" borderStyle="none" zoom="stretchDisplay"/>
<tab stackSize="10" name="default" zoomingAllowed="true" scrollingAllowed="true" zoom="stretchDisplay" closeTabAllowed="false" borderStyle="none" tabPosition="top" maximumTabs="5">
<frame name="ovw" stackSize="10" zoomingAllowed="true" scrollingAllowed="true" initialDisplay="CIENG_Overview" closeTabAllowed="false" borderStyle="none" zoom="stretchDisplay"/>
<frame name="ctl" stackSize="10" zoomingAllowed="true" scrollingAllowed="true" initialDisplay="CIENG_Control" closeTabAllowed="false" borderStyle="none" zoom="stretchDisplay"/>
<frame name="trd" stackSize="10" zoomingAllowed="true" scrollingAllowed="true" initialDisplay="CIENG_Trends" closeTabAllowed="false" borderStyle="none" zoom="stretchDisplay"/>
<frame name="alm" stackSize="10" zoomingAllowed="true" scrollingAllowed="true" initialDisplay="CIENG_Alarms" closeTabAllowed="false" borderStyle="none" zoom="stretchDisplay"/>
<frame name="sys" stackSize="10" zoomingAllowed="true" scrollingAllowed="true" initialDisplay="CIENG_System" closeTabAllowed="false" borderStyle="none" zoom="stretchDisplay"/>
</tab>
<frame-set
rows="1*,fitDisplay"
borderStyle="none">
<frame-set
cols="fitDisplay,1*"
borderStyle="none">
<frame
name="nav"
stackSize="1"
zoomingAllowed="false"
scrollingAllowed="false"
initialDisplay="CIENG_Menu"
borderStyle="none"/>
<frame
name="default"
stackSize="10"
zoomingAllowed="true"
scrollingAllowed="true"
initialDisplay="CIENG_Tank"
borderStyle="line"
zoom="fitDisplay"/>
</frame-set>
<frame name="alarmBannerFrame" stackSize="1" zoomingAllowed="false" scrollingAllowed="false" initialDisplay="CIENG_AlarmBanner" borderStyle="none" zoom="stretchDisplay"/>
<frame
name="alarmBannerFrame"
zoomingAllowed="false"
initialDisplay="AOG_AlarmBanner"
borderStyle="none"
zoom="stretchDisplay"/>
</frame-set>
<status-line>
<status-line-item type="statusText"/>
<status-line-item
type="statusText"/>
<status-line-separator/>
<status-line-item type="displayName"/>
<status-line-item
type="displayName"/>
<status-line-separator/>
<status-line-item type="userName"/>
<status-line-item
type="userName"/>
<status-line-separator/>
<status-line-item type="dateTime"/>
<status-line-item
type="dateTime"/>
</status-line>
</layout>
<layout
name="CIENG_Popup"
title="$default"
icon="poi.png"
drawBorder="true"
sizingAllowed="false"
minimizingAllowed="false"
closingAllowed="true"
alwaysOnTop="true"
modal="false"
initialPosition="atCursor"
initialPositionX="0"
initialPositionY="0"
initialSize="fitFrames"
initialSizeWidth="420"
initialSizeHeight="600"
maximumOpen="3">
<frame-set rows="1*">
<frame name="default" stackSize="1" zoomingAllowed="false" scrollingAllowed="false" initialDisplay="CIENG_TankFaceplate" borderStyle="none"/>
</frame-set>
</layout>
<!-- CIENG-SAMPLE-END -->

View file

@ -31,4 +31,4 @@ if (-not $Remove) {
# Check that the result is still well-formed XML before writing it.
[xml]$null = $text
[IO.File]::WriteAllText($file, $text, (New-Object Text.UTF8Encoding($false)))
if ($Remove) { 'CIENG_Operator / CIENG_Popup layouts removed' } else { 'CIENG_Operator / CIENG_Popup layouts added' }
if ($Remove) { 'CIENG_Operator layout removed' } else { 'CIENG_Operator layout added' }

View file

@ -17,10 +17,8 @@ rem Processing: trigger group, class (compiled on load via COMPILE = 1), object
dssqld -i 05_trigger_df.qli -l 05_trigger_df.qlo
dssqld -i 06_class_df.qli -l 06_class_df.qlo
dssqld -i 07_object_df.qli -l 07_object_df.qlo
rem Authorization: read-only group CIENG_VIEWER
rem Authorization: read-only group (no users are created by the sample)
dssqld -i 08_auth_group_df.qli -l 08_auth_group_df.qlo
rem Demo user CIENG (no password; logs on to the CIENG_Operator layout)
dssqld -i 08b_user_df.qli -l 08b_user_df.qlo
rem Equipment: Modbus loopback line, station, scan type, points, connected items.
rem The station needs the Modbus slave mirror (equipment\eqpciengslv_start.cmd, see README).
dssqld -i 09_modbus_line_df.qli -l 09_modbus_line_df.qlo

View file

@ -1,8 +1,6 @@
@echo off
rem Remove CI-Eng-Sample from a CI Server R1.03 TEST system (also deletes its history).
rem Run in an elevated prompt while CI Server is running; call this script by full path.
rem Log out every CIENG session first (Operator Interface and web): on R1.03.00 an open session kept
rem its user's authorization group in use (DSSP-E-NODEL ... USER_VAL), and a retry stopped DSSSDA03.
rem Order: audit report + selection group, reports, printer, OPC UA, Modbus, auth group, object, class, trigger group, storage links, stop + delete storage groups, items, sections (children first).
rem A storage group with an active unit cannot be deleted (HIS-E-GROUPHASUNT), so the
rem group first gets a stop time one minute ahead; the script waits until it has passed.

View file

@ -74,7 +74,7 @@ development system (see "Test system" in `progress.md`); they do not exist on ot
| ISS-052 | 2026-10-01 | GRAPHICS (stale item id) | The HTML display `CIENG_Tank` showed **0** in its number field on `CI-Eng-Sample.TANK1.LEVEL` (live value 50) and the popup `ITM-E-NO_MAIN, No main item found`, in a fresh session after a CI Server restart. The display XML stores `<itemName>` **and** `<itemId>1.1.268.0.0.1.1.7</itemId>` from when it was built; after today's sample reloads the item has `ID_NUMBER` 357. Phase 10 had seen live values after a reload, so the id is not always used, but here it broke the field. | closed | Fixed in the sample: removed the `<itemId>` line from `displays/CIENG_Tank.xml`, redeployed; the field shows 50 and the popup is gone (binding by name). Documented in `create-display.md`. Close when the user confirms. Closed 2026-10-01 (confirmed by user). | `examples/CI-Eng-Sample/displays/CIENG_Tank.xml`; `.claude/skills/graphics/tasks/create-display.md`; `.claude/skills/graphics/tasks/deploy-displays.md` |
| ISS-053 | 2026-10-01 | HAC (manual vs installed) | IM 36K10J20 vs the installed `hac.sup`/scripts: (1) *Start in manual mode*: §1.3 says HAC starts in manual by default, §1.5 and the `hac.sup` help say automatic; the installed template sets `START_MANUAL = YES`. (2) `MAXOPNDB` default: help 500, manual 50 (§1.5) and 5 (§4.8). (3) `QUESIZE` default: help 100 K, manual 2000 K (file sets 2000). (4) §4.5 says `tls\com` and `tls\exe` cannot be mirrored, but the template mirrors `12 COM` (excluding `ci_command.cmd`). (5) §4.4 says the critical processes are already in the queue/CPU check lists; the installed file has no `MAX_QUEUE`/`MAX_CPU`/`INACTIVE` lines. (6) `hacw_standby` uses `TLS_LST_PATH` when `TLS_BACKUP_PATH` is unset (manual: `TLS_ALLUSERS_PATH`). (7) The template `IP_DEVICE` is `localhost` (priority 0), which §1.3 says to remove after testing. (8) HMI properties have `communicationInterval`/`Timeout`/`RetryCount`, not in the manual. | closed | Installed software is the reference (standing user decision); documented in the J20 summary §5 and the `high-availability` skill. Not testable on one server. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10J20-01EN.md`; `.claude/skills/high-availability/tasks/*.md` |
| ISS-054 | 2026-10-01 | AD (manual vs installed) | IM 36K10J40 vs the installed `dssana.sup`: the *Active Directory* tab has keywords the manual does not describe — `AD_SERVER`, `AD_SERVER_BACKUP` (host[:port], 389/636), `AD_SECURE` (LDAPS; installed `NO`, help says default yes), `AD_ACCESS_USER`/`AD_ACCESS_PASSWORD` (blank = the CI Server service account). The manual's *Profile priority* is `USER_DF.MERGE_PRIORITY`; *Directory group* is `DIRECTORY_GROUP` (68 characters). The SSO keytab path is given as `%TLS_WAP_PATH%\webapps\auth\WEB-INF` (§2.5.1) and `%TLS_ALLUSERS_PATH%\wap\webapps\auth\WEB-INF` (§3.4.3) — the same folder on the test system. | closed | Installed software is the reference; documented in the J40 summary §5 and `authorization/tasks/active-directory.md`. Not testable without a domain. Closed 2026-10-01 (confirmed by user). | `knowledge/manuals/IM36K10J40-01EN.md`; `.claude/skills/authorization/tasks/active-directory.md` |
| ISS-055 | 2026-10-02 | GRAPHICS (Micro Trend) | A Micro Trend written into `CIENG_TrendLab` (`itemName[0..1]` = `TANK1.LEVEL`/`INFLOW`, `numberOfPens` 2, `realTime`, `fillWithHistory`) drew both pens on the desktop and in the browser the first time (about 13:33), then stayed **blank** on every later open on both clients: with and without the 48 spare trend pens, and with explicit `timeRange` 600 / `sampleCount` 60. No console error; CI Server running. Code: `MicroTrend.js` only starts when all properties are set (`startTrendIfAllPropertiesAreSet`; it also compares `scaleMax[i]` with `scaleMin[1]`). | open | Later 2026-10-02 the clean sample file (no explicit `timeRange`/`sampleCount`, 48 spare trend pens) drew both pens on the desktop and in the browser after a fresh login; after a *View > Reload* in the browser only LEVEL showed fully, INFLOW only a short piece: the behaviour is intermittent. **Cause 1 found 2026-10-02**: `setNumberOfPens()` calls `updatePenSource()`, which replaces every pen source with an empty one, so fixed `itemName[n]` values are lost when *Number of pens* is applied after them during load (order varies). Fix in the sample: connect `microTrend.itemName[n]` to the item with attribute `ItemName` (as the factory/test displays do); both pens then drew on 3 of 3 opens. **Remaining**: on 1 of 3 opens only the live part drew (no history fill); every property set calls `startTrend()` again, so history requests are repeated and can cancel each other (web-client code, not fixable in the display). The Operator Interface (desktop) showed the same: both pens live, no history fill on the next open, so the fill problem is not web-only. After a CI Server restart (14:30): web first open of a copy of the display drew both pens with history; the next opens (another copy, and the same display again) showed only the live part; the desktop drew history on one display and only the live part on the custom-range copy. No pattern found yet. Earlier note: still to try: build the Micro Trend in the Edit Module (compare the XML), connect `itemName[n]` instead of a fixed value (as in factory/test displays), a display with only the Micro Trend, a CI Server restart. | `.claude/skills/graphics/tasks/trend.md` §6; `examples/CI-Eng-Sample/displays/CIENG_TrendLab.xml` (removed 2026-10-06; micro trends now on `CIENG_Overview`, `CIENG_Trends`, `CIENG_TankFaceplate`) |
| ISS-055 | 2026-10-02 | GRAPHICS (Micro Trend) | A Micro Trend written into `CIENG_TrendLab` (`itemName[0..1]` = `TANK1.LEVEL`/`INFLOW`, `numberOfPens` 2, `realTime`, `fillWithHistory`) drew both pens on the desktop and in the browser the first time (about 13:33), then stayed **blank** on every later open on both clients: with and without the 48 spare trend pens, and with explicit `timeRange` 600 / `sampleCount` 60. No console error; CI Server running. Code: `MicroTrend.js` only starts when all properties are set (`startTrendIfAllPropertiesAreSet`; it also compares `scaleMax[i]` with `scaleMin[1]`). | open | Later 2026-10-02 the clean sample file (no explicit `timeRange`/`sampleCount`, 48 spare trend pens) drew both pens on the desktop and in the browser after a fresh login; after a *View > Reload* in the browser only LEVEL showed fully, INFLOW only a short piece: the behaviour is intermittent. **Cause 1 found 2026-10-02**: `setNumberOfPens()` calls `updatePenSource()`, which replaces every pen source with an empty one, so fixed `itemName[n]` values are lost when *Number of pens* is applied after them during load (order varies). Fix in the sample: connect `microTrend.itemName[n]` to the item with attribute `ItemName` (as the factory/test displays do); both pens then drew on 3 of 3 opens. **Remaining**: on 1 of 3 opens only the live part drew (no history fill); every property set calls `startTrend()` again, so history requests are repeated and can cancel each other (web-client code, not fixable in the display). The Operator Interface (desktop) showed the same: both pens live, no history fill on the next open, so the fill problem is not web-only. After a CI Server restart (14:30): web first open of a copy of the display drew both pens with history; the next opens (another copy, and the same display again) showed only the live part; the desktop drew history on one display and only the live part on the custom-range copy. No pattern found yet. Earlier note: still to try: build the Micro Trend in the Edit Module (compare the XML), connect `itemName[n]` instead of a fixed value (as in factory/test displays), a display with only the Micro Trend, a CI Server restart. | `.claude/skills/graphics/tasks/trend.md` §6; `examples/CI-Eng-Sample/displays/CIENG_TrendLab.xml` |
| ISS-056 | 2026-10-02 | GRAPHICS (trend, manual vs installed) | (1) IM 36K10C50 Table 2.27-28 lists *Appearance - Show in Legend* as supported in the HTML display, but the web legend listed pens with `visibleLegend` false (the desktop hides them). (2) The legend position (`PositionSouthWest`) was not applied in the browser (not supported per the table). (3) The manual says a trend has up to 20 pens; the component property sheet has 20 slots, but the web code reserves 50 and `maximumPens` 50 works on the desktop. (4) Desktop: pen `title`/`titlePlacement`, pen limit values `lowLimit`… and chart `backgroundPaint` had no visible effect; time-axis minor ticks/grid showed nothing at a 10-minute range. | closed | Documented in `trend.md`; installed software is the reference. Close when the user confirms. Closed 2026-10-02 (confirmed by user). | `.claude/skills/graphics/tasks/trend.md` |
| ISS-057 | 2026-10-02 | DATA EXPOSURE (filter, manual vs installed) | IM 36K10G10 §10.1 gives the filter example `"NAME" like "ABC*"` (quoted field name). On R1.05 a `DATA_EXPOSURE_DF` record with `RECORDS` = `"NAME" LIKE "<Section>*"` made `DBCSND` log `DSS-E-FLT_SYN_ERR` (+ `DSSF-E-CMP_NO_SUCC`, `DBC-E-DSS_SUB`, `DBC-E-SUB_DAT`, `DBC-E-DAT_HND`) and exit (`DUR-W-REM_PROC`), stopping **all** exposures. Tested on the user's R1.05 system (AID.WRPS items, exposure `WRPS-ITEM-VAL`). | closed | Closed 2026-10-02 (confirmed by user; user decision: installed software is the reference): the unquoted form `NAME LIKE "<Section>*"` compiles and data flows. Tested in R1.05 only. | `.claude/skills/data-access/tasks/rdbms-exposure.md` (done); `knowledge/manuals/IM36K10G10-01EN.md` (done); `knowledge/manuals/IM36K10L45-01EN.md` §8 (done) |
| ISS-058 | 2026-10-02 | DATA EXPOSURE (ITEM_HISTORY, manual vs installed) | IM 36K10G10 ch. 10 lists `ITEM_HISTORY` as an exposure source (filter required). The installed `dbc.sup` (R1.03 and R1.05, identical) has the change-log line `PCL Aug-19 e12150 Refactor to support MS-SQL/ODBC, remove ITM history support`. An `ITEM_HISTORY` record (all fields, quoted filter, ISS-057) on the user's R1.05 system never created its table; it was disabled and then deleted, so whether ITEM_HISTORY works with a correct filter is **not tested**. | open | Treat ITEM_HISTORY exposure as unsupported and use `ITEM_VALUES` with `AGG_INTERVAL`. To close: on an R1.05 system, create an `ITEM_HISTORY` record with an unquoted filter and check whether `DBCSND` stays up and the table is created. | `.claude/skills/data-access/tasks/rdbms-exposure.md`; `knowledge/manuals/IM36K10G10-01EN.md`; `knowledge/manuals/IM36K10L45-01EN.md` §8 |
@ -87,11 +87,3 @@ development system (see "Test system" in `progress.md`); they do not exist on ot
| ISS-065 | 2026-10-02 | GRAPHICS (layouts, web) | The web client (HTML display) supports only part of `Layouts.xml`: nested frame sets only in the parent's main (`n*`) slot (other placements hang on *Loading…*), frame `zoom` and navigate zoom ignored, `zoom`/`print`/`login`/`toolbar`/`statusline`/`lookfeel`/`playback` not supported, menu `sub`/`check`/`radio` items and left/right/bottom toolbars not shown, a layout without `title` shows *undefined*. Not described in the readme or IM 36K10R30. | open | Documented in the task (§6, tested and read from the web client code). Close when the user confirms. | `.claude/skills/graphics/tasks/layouts.md` §6 (done) |
| ISS-066 | 2026-10-02 | GRAPHICS (layouts) | Readme options that do not work as described in R1.03: a toolbar with `position="bottom"` is not shown (desktop and web; left/right work on the desktop); `initialPosition="centreFrame"` opens the window at 0,0 on the desktop; translations are used only for the exact locale (no fallback from `en_AU` to `en`). | open | Documented in the task. Close when the user confirms. | `.claude/skills/graphics/tasks/layouts.md` §6 (done) |
| ISS-067 | 2026-10-02 | GRAPHICS (layouts, tabs) | Readme: `<tab>` provides defaults (`closeTabAllowed`, `stackSize`, …) for its frames, and `maximumTabs`, `minimumTabLabelWidth`, `tabButtonGap`, `tabPosition` control the tabs. Observed: defaults on `<tab>` are not inherited (close buttons only with `closeTabAllowed` on each frame); `maximumTabs` does not limit the initial tabs; label width and gap show no effect on the desktop; the web client ignores `tabPosition` (always top) and hangs when the tab set sits next to the nav frame at the top level (factory shape with a nested frame set works). | open | Documented in the task; use the factory pattern. Close when the user confirms. | `.claude/skills/graphics/tasks/layouts.md` §6.6 (done) |
| ISS-068 | 2026-10-06 | GRAPHICS (layouts, web) | `layouts.md` §6.3 (2026-10-02) lists all 8 status line types as shown on the web. A layout whose status line contains `connectionState` (a type listed in `Layouts.readme`) does not start in the HTML display: at login `createStatusline` fails with *Cannot read properties of undefined (reading 'split')* and no frame is created (menu and toolbar only). Seen with the demo layout and reproduced with test layout `LT_ConnState` 2026-10-06. The desktop was not re-tested. | open | Documented in `layouts.md` §6.3 (web: 7 types shown). Close when the user confirms. | `.claude/skills/graphics/tasks/layouts.md` §6.3 (done) |
| ISS-069 | 2026-10-06 | GRAPHICS (layouts, tabs, web) | In the HTML display a `<tab>` set works only as the **last** child of its frame set: the tab click handler (`LayoutWindow.js`) uses the last panel created in the frame set. With the tab set first (banner frame after it, test layout `LT_TabFirst` 2026-10-06) the tab labels stay `_`, the console shows *Unable to switch/load requested display* and *Cannot set properties of undefined (setting 'active')*, tab clicks fail and the banner frame is missing. Not in `Layouts.readme` or IM 36K10R30. | open | Rule added (`layouts.md` §1, §6.6); sample `CIENG_Operator` uses the factory shape. Close when the user confirms. | `.claude/skills/graphics/tasks/layouts.md` §1, §6.6 (done) |
| ISS-070 | 2026-10-06 | GRAPHICS (layouts, tabs, desktop) | The Operator Interface ignores `zoom` (`fitDisplay`, `stretchDisplay`) on frames inside a `<tab>` and on the `<tab>` element: the displays are shown at 100 % (cropped on a small, unused space on a large monitor; F5 *Reload all* did not change it). The layout command `navigate to <tab frame> <display> fitDisplay|stretchDisplay` does apply the zoom (sample: toolbar, menu and an *On entry* `ACTION` of `CIENG_AlarmBanner`, 2026-10-03/06). A tab opened by clicking the tab strip keeps the zoom it had. | open | Documented in `layouts.md` §6.1 / §6.6. Close when the user confirms. | `.claude/skills/graphics/tasks/layouts.md` §6.1, §6.6 (done) |
| ISS-071 | 2026-10-06 | GRAPHICS (layout commands, desktop) | Only one layout command can run at a time: five *Execute command* `ACTION navigate …` actions in one *On entry* gave *IllegalStateException: A command is already being executed* (2026-10-03); reproduced 2026-10-06 with two `ACTION reload all` on one button (test display `CIENG_Test`). Layout commands cannot be chained (`Layouts.readme` has no separator). | open | Documented in `layouts.md` §3. Close when the user confirms. | `.claude/skills/graphics/tasks/layouts.md` §3 (done) |
| ISS-072 | 2026-10-06 | AUTH (users, quick load) | A user loaded with `dssqld` without a `PASSWORD` field (as `users-groups.md` advised: "a password is not required on import") has **no** password set: every logon fails with *DSS-E-UNK_USER Unknown user name/password combination*, also with an empty password; clearing the password in the Engineering Module made it work. With `PASSWORD ""` given explicitly the user logs on with an empty password on the desktop and the web (sample user `CIENG`, 2026-10-06). | closed | Answered by test 2026-10-06; `users-groups.md` corrected, sample `08b_user_df.qli` uses `PASSWORD ""`. Close when the user confirms. | `.claude/skills/authorization/tasks/users-groups.md` (done); `examples/CI-Eng-Sample/08b_user_df.qli` (done) |
| ISS-073 | 2026-10-06 | DSS (remove group / DSSSDA) | Removing an authorization group while a session of one of its users is open fails with *DSSP-E-NODEL … in dataset USER_VAL*; after logging out the session was still referenced, and a retry stopped the process `DSSSDA03` (*DUR-F-BAD_SIZE, Negative size not allowed*; `DUR-W-REM_PROC … exited unexpectedly`); following DSS requests failed with *DUR-F-UNKNOWN_ATT … DSSSDA03* until CI Server was restarted (2026-10-06). After the restart the group was removed without error. `USER_VAL` exports only its header, so open sessions cannot be listed. | open | Workaround: log out the user's sessions and restart CI Server before removing the group; noted in the sample `remove.cmd` / README and `users-groups.md`. Not repeated on purpose (it stops a CI Server process). Report to Yokogawa. | `.claude/skills/authorization/tasks/users-groups.md` (done); `examples/CI-Eng-Sample/remove.cmd`, `README.md` (done) |
| ISS-074 | 2026-10-06 | GRAPHICS (HTML display login) | IM 36K10R30 §4 lists the user profile fields used by the HTML display login as "… initial display, locale (layout not)". On R1.03.00 the profile's *Layout* is used too: a logon as `CIENG` (layout `CIENG_Operator`) at `/mobileoperator/` without `?l=` opened `CIENG_Operator` (2026-10-02 with ADMIN, 2026-10-06 with `CIENG`). | open | Installed software is the reference; R30 summary and `layouts.md` §3 updated. Close when the user confirms. | `knowledge/manuals/IM36K10R30-01EN.md` (done); `.claude/skills/graphics/tasks/layouts.md` §3, §5 (done) |
| ISS-075 | 2026-10-06 | GRAPHICS (`jwuiutl -v`) | `deploy-displays.md` called `jwuiutl -v` "report only", but `jwuiutl -d -v -i -l <log> <display>` re-saves the validated display (normalised XML: defaults dropped, positions as attributes; 9 618 → 11 191 bytes for `CIENG_Test`, 2026-10-06). On 2026-10-02 a validation of eight displays hung on one and left `<name>.lck` and `<name>.xml.tmp`; not reproduced on 2026-10-06. | open | Documented in `deploy-displays.md` §2 and the C50 summary. Close when the user confirms. | `.claude/skills/graphics/tasks/deploy-displays.md` §2 (done); `knowledge/manuals/IM36K10C50-01EN.md` (done) |

View file

@ -3,7 +3,7 @@ manual: IM 36K10C50-01EN
title: Edit Module
edition: 3rd Edition, Sep. 2023
version: R1.03
status: display CIENG_Tank built by the user in the Edit Module (text, number field, alarm overview, trend) and checked as XML and HTML 2026-10-01; jwuiutl search, validate and HTML export verified; trend settings (§2.27) tested one by one on CIENG_TrendLab 2026-10-02 (skill graphics, tasks/trend.md); generated sample displays (CIENG_*, most components: shapes, arc, text, number/text/date-time fields, buttons, toggle, check box, slider, spinner, combo box, data bar, scales, alarm overview, report, micro trend, trend) checked on desktop and web 2026-10-06; symbols, other actions and the tutorial from docs
status: display CIENG_Tank built by the user in the Edit Module (text, number field, alarm overview, trend) and checked as XML and HTML 2026-10-01; jwuiutl search, validate and HTML export verified; trend settings (§2.27) tested one by one on CIENG_TrendLab 2026-10-02 (skill graphics, tasks/trend.md); other components, symbols, actions and the tutorial from docs
---
# Edit Module (R1.03)
@ -46,9 +46,7 @@ display. Displays are XML files (`IM36K10R30-01EN.md` §1). Section numbers refe
**Verified on the test system:** `-d -m TANK1` and `-d -v -i -l` ran without errors; locked
displays and displays saved by a newer version are skipped (`*** Display locked <name>`,
`… created with a newer version of CI Server (R1.04.0.0)`); `-e HTML -i -f DEPLOY CIENG_Tank`
wrote `mobileoperator\operatorInterfaces\DEPLOY\displays\CIENG_Tank.html`. 2026-10-06: `-v` with
a display name also **re-saved** that display (normalised XML, same content; skill `graphics`,
`tasks/deploy-displays.md` §2).
wrote `mobileoperator\operatorInterfaces\DEPLOY\displays\CIENG_Tank.html`.
## 3. Components (§2)
@ -89,7 +87,7 @@ Symbols* and *Validate all Displays* (with all tabs closed); a symbol can be lin
PROCESS Service class so each instance shows one object; data location (display, operator's
CI Portal, display's server, enterprise, node).
## 6. What the display file stores (verified with CIENG_Tank, removed from the sample 2026-10-06)
## 6. What the display file stores (verified with CIENG_Tank)
- `<coreObjectDefinition type="displayDefinition">` with `<html>true</html>`, `<width>`,
`<height>`, grid, revision history, visibility groups, layers.
@ -101,9 +99,6 @@ CI Portal, display's server, enterprise, node).
reported *No problems found*, and a newly opened session showed the live value — the name is
what counts. Sessions that were already open kept the old binding (value frozen) until the
display was opened in a new session.
- Rules for writing display XML directly (text size, rounding, arc angles, item attributes for
the web, server-side commands, alarm overview columns): skill `graphics`,
`tasks/create-display.md`, verified 2026-10-06 with the generated `CIENG_*` displays.
## 7. Tutorial (§6)

View file

@ -83,8 +83,7 @@ as *dataset* events — `SUBJECT_GROUP` = dataset name (`ITEM_DF`, `ITEM_VAL`, `
`AUDIT_INFO` (*Audit trailing wanted*, default 0; also on `SUB_ITEM_DF`, `EXTERNAL_ALARM_DF`) made
no difference for these tools; it switches the `ITEM.*` events of **operator writes**: a button on
display `CIENG_Tank` stored `ITEM.VALUE.MODIFY.OPER-INTERFACE` (old/new, user) with
`AUDIT_INFO` 1 and nothing with 0 (verified, ISS-049; the same events from *Manual* / *Auto* on
`CIENG_Control`, 2026-10-06). A changed `STORAGE` flag takes effect only after the notifying process
`AUDIT_INFO` 1 and nothing with 0 (verified, ISS-049). A changed `STORAGE` flag takes effect only after the notifying process
re-reads it (`ECL_REFRESH`, up to 30 minutes, both directions; verified, ISS-050).
## 4. Setup files (§4.2)

View file

@ -3,7 +3,7 @@ manual: IM 36K10R30-01EN
title: Graphic Display Setup
edition: 3rd Edition, Sep. 2023
version: R1.03
status: HTML display (Mobile Operator) and a project layout (CIENG_Operator) verified in the Operator Interface (desktop) and the HTML display 2026-10-01; sample operator HMI with tab set, popup layout and per-user layout verified on both clients 2026-10-06; dataset forms, form language and dual screen from docs
status: HTML display (Mobile Operator) and a project layout (CIENG_Operator) verified in the Operator Interface (desktop) and the HTML display 2026-10-01; dataset forms, form language and dual screen from docs
---
# Graphic Display Setup (R1.03)
@ -38,16 +38,13 @@ empty = `deploy`).
- Menu items (§1.5, e.g. `menu.file.login`, `menu.view.reload`), toolbar (§1.6), status line
items (§1.7, e.g. graphics queue level), frames and tabs (§1.8), translations (§1.9).
- Which layout opens: *In layout* of an *Open display* action (Edit Module), or the user's
*Layout* field (Engineering Module, Authorization > Users); empty = `default`. Verified
2026-10-06 with the sample user `CIENG` on the desktop and in the HTML display.
*Layout* field (Engineering Module, Authorization > Users); empty = `default`.
- Dual screen (§1.10): copy the layout and the banner display as `<name>_1` / `<name>_2` and let
each banner open its main display in its own layout.
- **Verified (2026-10-01, former sample layout)**: sample layout `CIENG_Operator` (skill `graphics`, task `layouts.md`):
- **Verified (2026-10-01)**: sample layout `CIENG_Operator` (skill `graphics`, task `layouts.md`):
second window from an *Open display* action, own menu/toolbar/frames, `$default` title, popup
layout, F11; the Operator Interface reads `Layouts.xml` only at start. The installed
`Layouts.readme` is the full reference for options and commands. Since 2026-10-06
`CIENG_Operator` is the sample operator HMI (header frame, tab set, banner) with the popup
layout `CIENG_Popup`; web and desktop findings for tab sets in `layouts.md` §6.6.
`Layouts.readme` is the full reference for options and commands.
- **Installed layouts**: `mobile`, `default`, `sxga1f/r`, `uxga1f/r`, `wxga1f/r`, `wsxga1f/r`,
`wsxgap1f/r`, `wuxga1f/r`, `ResizablePopup`, `FixedPopup`, `popup`, `Splash`, `tuningpanel`,
`faceplate`, `SelectMode`, `Setpoint`, `mapviewer` (`f` fixed / `r` resizable per screen
@ -75,10 +72,8 @@ property files and language codes (§3.5).
*Mobile Operator* on the Remote Connect page. Login with a CI Server user (manual, or SSO via
`https://<host>:8443/auth/mbl`); user profile fields used: password, authorization group, ASA,
shelving group, process areas, logoff timeout, deployment, initial display, locale (layout
not, per this manual). **Installed software**: the profile's *Layout* is used as well - a
logon as `CIENG` without `?l=` opened `CIENG_Operator` (2026-10-06, ISS-074). Login control:
`dssana.sup` interface *mobile operator*.
- **Verified (2026-10-01)**: `http://localhost:8080/mobileoperator/?d=CIENG_Tank` showed the operator
not). Login control: `dssana.sup` interface *mobile operator*.
- **Verified**: `http://localhost:8080/mobileoperator/?d=CIENG_Tank` showed the operator
frame (menu, navigation buttons, alarm banner, status line) and the display; the number field
updated live; the alarm overview listed the sample's alarms. **Reloading the browser page ends
the session** (login again); use the display's own menu *View > Reload* instead (keeps the
@ -89,7 +84,7 @@ property files and language codes (§3.5).
no enterprise displays. Components supported (§4.8): alarm overview, display, group, symbol,
trend, visibility group/layer, parameters, web browser (with listed properties).
- Full screen F11, Chrome shortcuts or `chrome.exe --app=http://<host>:<port>`.
- **Test system**: the HTML trend of `CIENG_Tank` (removed from the sample 2026-10-06) drew no line although history existed; browser
- **Test system**: the HTML trend of `CIENG_Tank` drew no line although history existed; browser
console `Mismatch between number of labels … and number of columns in array (51)` (ISS-041).
Cause (2026-10-02): the web trend code always builds 50 data columns, so a trend draws only
with 50 visible pens; workaround `add_trend_spares.ps1`, details and web/desktop differences in

View file

@ -139,9 +139,6 @@ now come before classes and objects (phase 6), and the other interfaces follow a
| C50/R30 | HTML trend: cause of the empty web trend and 50-pen workaround (`add_trend_spares.ps1`); Micro Trend ([task](../.claude/skills/graphics/tasks/trend.md) §6) | passed (workaround) | passed | Web code always builds 50 columns (ISS-041). Padded `CIENG_TrendLab` draws in the browser with a clean legend; web ignores *Show in legend* (ISS-056). Micro Trend drew once, then blank (ISS-055). |
| C50/R30 | Web check of each trend setting (4 batches on a padded scratch copy, checked in the browser by Claude) ([task](../.claude/skills/graphics/tasks/trend.md) §6) | passed | passed | 2026-10-02. Works / ignored / different table in the task; matches IM 36K10C50 Table 2.27-28 except `timeShift` (error message) and *Show in legend* (ISS-056). A hidden real pen breaks the 50-pen workaround (confirmed). |
| C50 | Remaining trend settings: custom time range, `Rendering3dOrt`, `RenderingCSS` ([task](../.claude/skills/graphics/tasks/trend.md) §4) | passed | passed | 2026-10-02. Custom range on desktop and web (desktop: no live update); 3dOrt draws black lines; CSS mode makes the display unloadable. |
| R30/C50 | Sample operator HMI: 8 generated `CIENG_*` displays, layouts `CIENG_Operator` (header, tab set, banner) and `CIENG_Popup`, live-data feed with server-side *Start* / *Stop* ([sample README](../examples/CI-Eng-Sample/README.md), [layouts](../.claude/skills/graphics/tasks/layouts.md) §6.6) | passed | passed | 2026-10-06 on desktop and web. Replaces `CIENG_Tank`, `CIENG_Menu`, `CIENG_TrendLab`. Tab sets: last child of the frame set (ISS-069), desktop zoom via `navigate … stretchDisplay` (ISS-070), one layout command at a time (ISS-071), `connectionState` breaks the web layout (ISS-068). |
| C50 | Writing display XML directly: text size, rounding, arc angles, web item attributes, server-side command, alarm overview columns ([task](../.claude/skills/graphics/tasks/create-display.md)) | passed | passed | 2026-10-06, test display `CIENG_Test` (removed) on both clients; arc angles clockwise from 3 o'clock on both clients (an earlier note on mirrored angles was wrong); `jwuiutl -v` re-saves (ISS-075). |
| C10 | Sample user `CIENG` with empty password via quick load, profile layout and initial display ([task](../.claude/skills/authorization/tasks/users-groups.md)) | passed | passed | 2026-10-06: `PASSWORD ""` needed (ISS-072); web logon uses the profile layout (ISS-074); group removal with an open session stopped `DSSSDA03` (ISS-073). Factory group `OPERATOR` is enough for the server-side *Start*. |
| J10/C50 | Restart CI Server with the Edit Module open | observed | n/a | Start aborted: `JWUIGED<pid>` still attached to the BUS Service (`ci_start.log`); closing the Edit Module fixed it (skill `system-check`). |
| R30/C50/C60 | Dataset forms, symbols, AOG library, dual screen, per-user layouts | not practiced | n/a | GUI work; user profiles not changed. |
| R40/C30 | REPORT Service checks: processes, set-up files (`rptman.sup`, `rptge1.rpt`, `rptgen.rpt`), system reports, `rptstp` ([task](../.claude/skills/reporting/tasks/report-checks.md)) | passed | n/a | Read-only plus one cancel: `rptstp rptge1` stopped the endless-loop test report `CIENG_LOOP` (removed). 28 system reports; two names differ from the manual (ISS-043). |