Sample: CIENG uses the factory OPERATOR group; correct arc and rounding notes

- Group CIENG_OPERATOR dropped (08, 85, load.cmd, README): the live-data Start also works for a
  user in the factory group OPERATOR (tested 2026-10-06 as OPER), so EXECUTE_GENERAL_COMMANDS is
  not needed; 08b_user_df.qli gives CIENG the group OPERATOR
- remove.cmd / README: open CIENG session note reworded
- Generator README / cixml.py: arc angles run clockwise from 3 o'clock on desktop and web (fixed
  and connected; the earlier "mirrored on the desktop" note was wrong); rounding above 1 draws an
  ellipse on both clients
- Tested on CI Server R1.03.00 2026-10-06: CIENG logon (empty password) and Start with group
  OPERATOR; test display with static and connected arcs on both clients

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Clio Liu 2026-10-06 11:16:58 +11:00
parent 0e5a39361c
commit 266e9e3710
8 changed files with 21 additions and 33 deletions

View file

@ -4,19 +4,10 @@ ENGLISH
@VERSION @VERSION
1.03.00 1.03.00
! CI-Eng-Sample authorization groups (IM 36K10C10-01EN 2.4), CI Server R1.03.00: ! CI-Eng-Sample read-only authorization group (IM 36K10C10-01EN 2.4), CI Server R1.03.00
! CIENG_VIEWER read-only; CIENG_OPERATOR for the demo user CIENG (08b_user_df.qli)
! Actions are NAME values from AUTH_ACTION_DF. ! Actions are NAME values from AUTH_ACTION_DF.
@FIELDS @FIELDS
NAME,DESCRIPTION,ACTION_NAME_1,ACTION_NAME_2,ACTION_NAME_3,ACTION_NAME_4 NAME,DESCRIPTION,ACTION_NAME_1,ACTION_NAME_2,ACTION_NAME_3,ACTION_NAME_4
@AUTH_GROUP_DF @AUTH_GROUP_DF
"CIENG_VIEWER","CI-Eng-Sample read-only viewer","ITEM_READ","SECTION_READ","ALARM_CURRENT_READ","ALARM_CHRONO_READ" "CIENG_VIEWER","CI-Eng-Sample read-only viewer","ITEM_READ","SECTION_READ","ALARM_CURRENT_READ","ALARM_CHRONO_READ"
! CIENG_OPERATOR: the actions of the factory group OPERATOR (R1.03.00) plus EXECUTE_GENERAL_COMMANDS,
! needed for the server-side command of the live-data button Start (feed\cieng_feed_start.cmd).
@FIELDS
NAME,DESCRIPTION,ACTION_NAME_1,ACTION_NAME_2,ACTION_NAME_3,ACTION_NAME_4,ACTION_NAME_5,ACTION_NAME_6,ACTION_NAME_7,ACTION_NAME_8,ACTION_NAME_9,ACTION_NAME_10,ACTION_NAME_11,ACTION_NAME_12,ACTION_NAME_13,ACTION_NAME_14,ACTION_NAME_15,ACTION_NAME_16,ACTION_NAME_17,ACTION_NAME_18,ACTION_NAME_19,ACTION_NAME_20,ACTION_NAME_21,ACTION_NAME_22,ACTION_NAME_23,ACTION_NAME_24,ACTION_NAME_25,ACTION_NAME_26,ACTION_NAME_27,ACTION_NAME_28,ACTION_NAME_29,ACTION_NAME_30,ACTION_NAME_31,ACTION_NAME_32,ACTION_NAME_33,ACTION_NAME_34,ACTION_NAME_35,ACTION_NAME_36,ACTION_NAME_37,ACTION_NAME_38,ACTION_NAME_39,ACTION_NAME_40,ACTION_NAME_41,ACTION_NAME_42,ACTION_NAME_43,ACTION_NAME_44,ACTION_NAME_45,ACTION_NAME_46,ACTION_NAME_47,ACTION_NAME_48,ACTION_NAME_49,ACTION_NAME_50,ACTION_NAME_51,ACTION_NAME_52,ACTION_NAME_53,ACTION_NAME_54,ACTION_NAME_55,ACTION_NAME_56,ACTION_NAME_57,ACTION_NAME_58,ACTION_NAME_59,ACTION_NAME_60,ACTION_NAME_61,ACTION_NAME_62,ACTION_NAME_63,ACTION_NAME_64,ACTION_NAME_65,ACTION_NAME_66,ACTION_NAME_67,ACTION_NAME_68,ACTION_NAME_69,ACTION_NAME_70,ACTION_NAME_71,ACTION_NAME_72,ACTION_NAME_73,ACTION_NAME_74,ACTION_NAME_75
@AUTH_GROUP_DF
"CIENG_OPERATOR","CI-Eng-Sample operator (OPERATOR + server commands)","ALARM_ACK_READ","ALARM_AOI_READ","ALARM_ASA_READ","ALARM_CHRONO_READ","ALARM_CURRENT_ACK","ALARM_CURRENT_READ","ALARM_DISPLAY_READ","ALARM_FO_READ","ALARM_FU_READ","ALARM_GROUP_READ","ALARM_NOT_DEST_READ","ALARM_NOT_USR_READ","AUDIT_EVENT_CLAS_READ","AUDIT_SELGRP_READ","AUDIT_TRAIL_READ","AUTH_ACTION_READ","AUTH_GROUP_READ","CLASS_ATTR_VAL_READ","CLASS_INCLUDED_READ","CLASS_READ","CLASS_SIGNALS_READ","DISPLAY_READ","EXTERNAL_ALARM_READ","FOLDER_READ","HIS_GROUP_FORCE_ROLLOVER","HIS_GROUP_READ","HIS_UNITS_READ","INSTALL_BLOCK_UNBLOCK","INSTALL_READ","ITEM_ACK_ALARM","ITEM_HISTORY_READ","ITEM_HIS_READ","ITEM_MODIFY_APPLICATION_FLAG","ITEM_MODIFY_BLOCKED_VALUE","ITEM_MODIFY_DEADBAND","ITEM_MODIFY_HISTORY","ITEM_MODIFY_LIMIT_HIGH","ITEM_MODIFY_LIMIT_HIGH_HIGH","ITEM_MODIFY_LIMIT_LOW","ITEM_MODIFY_LIMIT_LOW_LOW","ITEM_MODIFY_QUALITY_CODE","ITEM_MODIFY_STATUS","ITEM_MODIFY_STRING_VALUE","ITEM_MODIFY_VALUE","ITEM_READ","ITEM_READ_ALARM_TYPE","NODE_HOST_READ","NODE_LOCAL_READ","OBJECT_READ","OBJECT_SIGNALS_READ","OPC_GROUP_READ","REPORT_CANCEL","REPORT_DELETE_GENERATED_REPORT","REPORT_GENERATE_ADHOC","REPORT_MAINTAIN_LOGBOOK","REPORT_PRINT","REPORT_READ","REPORT_READ_GENERATED_REPORT","SCAN_TYPE_READ","SCHEME_READ","SECTION_BLOCK_UNBLOCK","SECTION_READ","SEQUENCE_READ","STATION_ON_OFF_SCAN","STATION_READ","STATUS_READ","SUB_ITEM_READ","SYMBOL_READ","SYS_LOG_READ","TRIGGER_GROUP_READ","UAC_METHOD_MODIFY","UAC_METHOD_READ","UNIT_BLOCK_UNBLOCK","UNIT_READ","EXECUTE_GENERAL_COMMANDS"

View file

@ -4,7 +4,7 @@ ENGLISH
@VERSION @VERSION
1.03.00 1.03.00
! CI-Eng-Sample demo user CIENG (IM 36K10C10-01EN 2.5), CI Server R1.03.00: group CIENG_OPERATOR, ! 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). ! 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 ! 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). ! user has no password set and every logon fails with DSS-E-UNK_USER).
@ -12,4 +12,4 @@ ENGLISH
NAME,DESCRIPTION,AUTH_GROUP,PROCESS_AREAS,LOGOFF_TIMEOUT,LAYOUT,INITIAL_DISPLAY,PASSWORD NAME,DESCRIPTION,AUTH_GROUP,PROCESS_AREAS,LOGOFF_TIMEOUT,LAYOUT,INITIAL_DISPLAY,PASSWORD
@USER_DF @USER_DF
"CIENG","CI-Eng-Sample demo user (no password)","CIENG_OPERATOR","1-999",0,"CIENG_Operator","CIENG_Overview","" "CIENG","CI-Eng-Sample demo user (no password)","OPERATOR","1-999",0,"CIENG_Operator","CIENG_Overview",""

View file

@ -4,8 +4,7 @@ ENGLISH
@VERSION @VERSION
1.03.00 1.03.00
! Remove the CI-Eng-Sample user and authorization groups (the user first: a group with users ! Remove the CI-Eng-Sample user and authorization group (the user first)
! cannot be removed)
@FIELDS @FIELDS
NAME NAME
@ -13,5 +12,4 @@ NAME
"CIENG" "CIENG"
@AUTH_GROUP_DF @AUTH_GROUP_DF
"CIENG_OPERATOR"
"CIENG_VIEWER" "CIENG_VIEWER"

View file

@ -22,10 +22,10 @@ cmd /c "<repo>\examples\CI-Eng-Sample\remove.cmd"
- **Restart CI Server after loading** (stop, then start the CI Service): a new storage group - **Restart CI Server after loading** (stop, then start the CI Service): a new storage group
stores no history until CI Server restarts. stores no history until CI Server restarts.
- `load.cmd` on a system that already has the project reports `Exists` and changes nothing. - `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): a group - Before `remove.cmd`, log out every `CIENG` session (Operator Interface and web): on 2026-10-06
cannot be removed while a session of its user is open (`DSSP-E-NODEL` … `USER_VAL`), and a 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 retry in that state stopped the `DSSSDA03` process (`DUR-F-BAD_SIZE`) until CI Server was
restarted (2026-10-06). restarted.
- `remove.cmd` takes about 1½ minutes: a storage group can only be deleted after its stop time - `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 has passed, so the script sets a stop time one minute ahead and waits. Removing the group
also deletes its history. also deletes its history.
@ -79,8 +79,7 @@ cmd /c "<repo>\examples\CI-Eng-Sample\remove.cmd"
| `CIENG_TANKS` | Area of interest | Label for tank items (`TANK1.LEVEL` `AOI_1`) | | `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_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_VIEWER` | Authorization group | Read-only: `ITEM_READ`, `SECTION_READ`, `ALARM_CURRENT_READ`, `ALARM_CHRONO_READ` |
| `CIENG_OPERATOR` | Authorization group | The actions of the factory group `OPERATOR` plus `EXECUTE_GENERAL_COMMANDS` (server-side command of the live-data button) | | `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` | User | Demo user, **no password**, group `CIENG_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_FILE` | Printer device + destination | FILE output to `%TLS_LST_PATH%\cieng_report.txt` (overwritten by each printed report); destination visible to operators | | `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_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` | | `CIENG_INFLOW_HI` | Report | Generated 5 s after `TANK1.INFLOW` rises above 400; output `CIENG_FILE` |
@ -104,7 +103,7 @@ New items start with status 13 (`NOT INIT`) until a value is written.
| `03_his_group_df.qli` | Item storage groups (`HIS_GROUP_DF`): event, scan, aggregation | | `03_his_group_df.qli` | Item storage groups (`HIS_GROUP_DF`): event, scan, aggregation |
| `04_item_his_df.qli` | Items in the storage group (`ITEM_HIS_DF`, name `<group>:<item>`) | | `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) | | `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 groups (`AUTH_GROUP_DF`) | | `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`) | | `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 | | `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`) | | `12_opc_visible_df.qli` | OPC visible / read flags (loaded with `dssqld -m`) |
@ -224,7 +223,7 @@ and alarms show nothing until values are written. `feed\cieng_feed.ps1` writes t
| `-UntilFlag` | Runs while `DEMO.FEED_ON` = 1 (display buttons *Start* / *Stop*) | | `-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 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; needs a group with `EXECUTE_GENERAL_COMMANDS`), which 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: 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 `%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 values within 5 s). After a CI Server restart the *Live data* lamp can stay green although no feed

View file

@ -32,12 +32,13 @@ back to an estimate and left/right-aligned texts land slightly off.
- Texts and numbers use *keep original size*: the HTML export draws them at their font size centred - 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 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. 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 - Rectangle rounding is stored as a fraction (0..1) of the half size; values above 1 draw an
ellipse in the web client). ellipse (desktop and web).
- The tab displays are designed 1880 x 680 and stretched to 1880 x 760 (`design_h`): panels, bars, - 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. lists and trends grow, texts / controls / round shapes keep their size and only move.
- Ring gauges are symmetric about the horizontal axis (gap on the right, value growing from 9 - Arc angles (desktop and web alike, fixed or connected): degrees **clockwise** from 3 o'clock
o'clock up and down) because the desktop draws arc angles mirrored compared with the web. (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 - 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`). 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 - Trend: `trend(..., web_spares=True)` pads a trend to 50 pens so it also draws on the web; the

View file

@ -378,9 +378,9 @@ class Display:
def ring_gauge(self, cx, cy, rad, item, mn, mx, color='teal', sw=12.0, thresholds=None): 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. """270 degree ring with the gap on the right; the value arc grows from 9 o'clock up and down.
The Operator Interface (desktop) draws arc angles mirrored about the horizontal axis compared Arc angles run clockwise from 3 o'clock on both clients (tested 2026-10-06, fixed and
with the web client, so only shapes symmetric about that axis look the same on both: connected angles): track 45..315 degrees, value arc centred on 180 degrees
track 45..315 degrees, value arc centred on 180 degrees (start = 180 - extent / 2).""" (start = 180 - extent / 2)."""
self.arc(cx, cy, rad, 45, 270, 'track', sw) self.arc(cx, cy, rad, 45, 270, 'track', sw)
acts = [conn('arc.extentAngle', item, transform=tr_linear(mn, mx, 0.5, 270)), 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))] conn('arc.startAngle', item, transform=tr_linear(mn, mx, 179.75, 45))]

View file

@ -17,7 +17,7 @@ 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 05_trigger_df.qli -l 05_trigger_df.qlo
dssqld -i 06_class_df.qli -l 06_class_df.qlo dssqld -i 06_class_df.qli -l 06_class_df.qlo
dssqld -i 07_object_df.qli -l 07_object_df.qlo dssqld -i 07_object_df.qli -l 07_object_df.qlo
rem Authorization: groups CIENG_VIEWER (read-only) and CIENG_OPERATOR (demo user) rem Authorization: read-only group CIENG_VIEWER
dssqld -i 08_auth_group_df.qli -l 08_auth_group_df.qlo 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) rem Demo user CIENG (no password; logs on to the CIENG_Operator layout)
dssqld -i 08b_user_df.qli -l 08b_user_df.qlo dssqld -i 08b_user_df.qli -l 08b_user_df.qlo

View file

@ -1,9 +1,8 @@
@echo off @echo off
rem Remove CI-Eng-Sample from a CI Server R1.03 TEST system (also deletes its history). 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 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): an authorization group cannot rem Log out every CIENG session first (Operator Interface and web): on R1.03.00 an open session kept
rem be removed while a session of its user is open (DSSP-E-NODEL ... in dataset USER_VAL); a retry in that rem its user's authorization group in use (DSSP-E-NODEL ... USER_VAL), and a retry stopped DSSSDA03.
rem state stopped the DSSSDA03 process (DUR-F-BAD_SIZE) on R1.03.00 and needed a CI Server restart.
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 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 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. rem group first gets a stop time one minute ahead; the script waits until it has passed.