From 90058ffdefbd0107c1d343071e84fd9f1ab9def6 Mon Sep 17 00:00:00 2001 From: cliu Date: Wed, 30 Sep 2026 17:22:58 +1000 Subject: [PATCH] Add equipment skill and Modbus loopback station to CI-Eng-Sample - New skill equipment with task modbus-station: line, station, scan type, points and connected items by quick load, tested against CI Server's own Modbus slave mirror (eqpmdcmem + eqpmdcslvtcp) - CI-Eng-Sample: section PLC1, station CIENG_PLC with write/read-back items, load/remove steps and mirror start/stop scripts - ISS-024: the TCP slave answers Open Modbus/TCP, not RTU (closed) Co-Authored-By: Claude Opus 5.5 --- .claude/skills/equipment/SKILL.md | 34 +++++ .../skills/equipment/tasks/modbus-station.md | 119 ++++++++++++++++++ examples/CI-Eng-Sample/01_section_df.qli | 1 + examples/CI-Eng-Sample/02_item_df.qli | 1 + examples/CI-Eng-Sample/09_modbus_line_df.qli | 14 +++ .../CI-Eng-Sample/10_modbus_station_df.qli | 30 +++++ examples/CI-Eng-Sample/11_item_eqp_df.qli | 15 +++ .../CI-Eng-Sample/80_remove_item_eqp_df.qli | 15 +++ .../81_remove_modbus_station_df.qli | 21 ++++ .../82_remove_modbus_line_df.qli | 12 ++ examples/CI-Eng-Sample/91_remove_item_df.qli | 1 + .../CI-Eng-Sample/92_remove_section_df.qli | 1 + examples/CI-Eng-Sample/README.md | 29 ++++- .../equipment/eqpciengslv_start.cmd | 5 + .../equipment/eqpciengslv_stop.cmd | 4 + examples/CI-Eng-Sample/load.cmd | 7 ++ examples/CI-Eng-Sample/remove.cmd | 3 + knowledge/issues.md | 1 + knowledge/manuals/IM36K10L41-01EN.md | 4 +- knowledge/progress.md | 3 +- 20 files changed, 316 insertions(+), 4 deletions(-) create mode 100644 .claude/skills/equipment/SKILL.md create mode 100644 .claude/skills/equipment/tasks/modbus-station.md create mode 100644 examples/CI-Eng-Sample/09_modbus_line_df.qli create mode 100644 examples/CI-Eng-Sample/10_modbus_station_df.qli create mode 100644 examples/CI-Eng-Sample/11_item_eqp_df.qli create mode 100644 examples/CI-Eng-Sample/80_remove_item_eqp_df.qli create mode 100644 examples/CI-Eng-Sample/81_remove_modbus_station_df.qli create mode 100644 examples/CI-Eng-Sample/82_remove_modbus_line_df.qli create mode 100644 examples/CI-Eng-Sample/equipment/eqpciengslv_start.cmd create mode 100644 examples/CI-Eng-Sample/equipment/eqpciengslv_stop.cmd diff --git a/.claude/skills/equipment/SKILL.md b/.claude/skills/equipment/SKILL.md new file mode 100644 index 0000000..0a86fe7 --- /dev/null +++ b/.claude/skills/equipment/SKILL.md @@ -0,0 +1,34 @@ +--- +name: equipment +description: >- + CI Server R1.03 EQUIPMENT Service: lines, stations, scan types, I/O points and conversion + types. Use when the user wants to connect CI Server to a PLC, RTU or other device (Modbus + TCP/RTU, STARDOM FCX, FA-M3, DNP3, IEC 60870-5-104, IEC 61850, MQTT, OPC …), define or + remove a line, station, scan type or point, connect an item to an I/O address, set a station + off-scan or suppress outputs, add a station communication status item, run CI Server as a + Modbus slave, force a faster scan (eqpfrcscn), check equipment statistics or use the + equipment debugger (eqpdbg). Sources IM 36K10L40-01EN, IM 36K10L41-01EN, IM 36K10C10-01EN §4.1. +--- + +# Equipment (R1.03) + +Background: `knowledge/manuals/IM36K10L41-01EN.md` (line types, station parameters, +conversion types, Modbus, driver table), `IM36K10L40-01EN.md` (forced scan, statistics, +`eqpdbg`), `IM36K10C10-01EN.md` §4.1 (Engineering Module forms). + +Rules: +- Run the `system-check` skill first; follow the user's chosen way of working. +- Loading a line creates files in `tls\com` and `tls\sup` and starts an equipment manager; + removing it stops the manager and deletes them. Only do this on test systems or with the + user's approval. +- Outputs write to real devices: never write to a production station's output points without + the user's explicit approval. +- `eqpdbg`: only the read-only actions (see L40 summary) unless the user approves. + +| Task | File | Status | +|---|---|---| +| Modbus TCP station by quick load: line, station, scan type, points, connected items; test, off-scan, remove | `tasks/modbus-station.md` | verified | +| CI Server as Modbus slave (mirror `eqpmdcmem` + `eqpmdcslvtcp`) | `tasks/modbus-station.md` §1 | verified (started by hand; start file see task) | +| Read-only equipment manager status with `eqpdbg` | `system-management` task `tuning-checks.md` | verified | +| Forced scan (`eqpfrcscn`), hourly statistics (`eqpiostat`) | L40 summary | from docs (statistics empty, ISS-021) | +| Other protocols | L41 summary §3.8–3.40 | from docs (no hardware) | diff --git a/.claude/skills/equipment/tasks/modbus-station.md b/.claude/skills/equipment/tasks/modbus-station.md new file mode 100644 index 0000000..f7fb1fa --- /dev/null +++ b/.claude/skills/equipment/tasks/modbus-station.md @@ -0,0 +1,119 @@ +--- +task: Modbus TCP station by quick load (line, station, scan type, points, items) +version: R1.03 +source: IM 36K10L41-01EN §2, §3.1–3.2, §3.6–3.7; IM 36K10C10-01EN §4.1; practiced on CI-Eng-Sample 2026-09-30 +status: verified +--- + +# Modbus TCP station by quick load + +Uses the CI-Eng-Sample loopback station `CIENG_PLC` as the worked example (files in +`examples/CI-Eng-Sample/`: `09_modbus_line_df.qli`, `10_modbus_station_df.qli`, +`11_item_eqp_df.qli`, removal `80_`–`82_`). For a real device, replace the address, unit id, +points and conversion settings. Works from a normal prompt while CI Server is running; use +short relative file names. + +## 1. (Test only) CI Server as its own Modbus slave + +CI Server ships a Modbus slave "mirror" that needs no hardware: +- `eqpmdcmem -n EQPMDCMEM`: slave memory (64K registers, 64K bits per unit id; input and + holding registers are the same memory, as are coils and input bits). The name must be + `EQPMDCMEM`: the TCP slave looks for it. +- `eqpmdcslvtcp -n EQPMDCSLVTCP -p 5020`: Modbus TCP listener (default port 502). + +Started by hand from a normal prompt they run until logoff or CI Server restart. To start +them with CI Server, an administrator copies `examples/CI-Eng-Sample/equipment/ +eqpciengslv_start.cmd` and `_stop.cmd` to `%TLS_ROOT_PATH%\tls\com`: `equipment_start.cmd` +runs every `eqp*start.cmd` there. + +## 2. Line (`MODBUS_LINE_DF`) + +``` +@FIELDS +NAME,DESCRIPTION,LINE_TYPE,EQUIPMENT_MAN,HEART_BEAT,TIMEOUT,DEAD_TIME,REPEAT_CONNECTION_DELAY + +@MODBUS_LINE_DF +"CIENG_MB_LINE","CI-Eng-Sample Modbus loopback line","TCP/IP","EQPCIENG",100,3000,30,10 +``` + +- `EQUIPMENT_MAN` = equipment manager process name, must start with `EQP`, ≤ 12 characters. +- Leave `EQUIPMENT_NODE` out: it defaults to the local node (keeps files portable). +- Loading it **creates** `tls\com\eqpcieng_start.cmd`, `eqpcieng_stop.cmd` and + `tls\sup\eqpcieng.sup` (written by the CI Service, no admin rights needed) and **starts** + `eqpmdc -n EQPCIENG` a few seconds later. Wait ~15 s before loading stations. + +## 3. Station, scan type, points (`MODBUS_STATION_DF`, `MODBUS_SCAN_TYPE_DF`, `MODBUS_POINT_DF`) + +``` +@FIELDS +NAME,DESCRIPTION,LINE,PROTOCOL,LINE_1_DEVICE,SUB_STATION_ID,OUTPUT_METHOD,STATUS_ITEM,ON_SCAN + +@MODBUS_STATION_DF +"CIENG_PLC","Loopback to CI Server Modbus slave (port 5020)","CIENG_MB_LINE","Open Modbus/TCP","localhost:5020",1,"On change and connect","CI-Eng-Sample.PLC1.COMM_OK",1 + +@FIELDS +NAME,DESCRIPTION,SCAN_INTERVAL + +@MODBUS_SCAN_TYPE_DF +"CIENG_SCAN1S","CI-Eng-Sample 1 s scan",1000 + +@FIELDS +NAME,STATION,POINT,DESCRIPTION,IO_ADDRESS,EXTERNAL_RELATION,SCAN_TYPE,CONV_TYPE,BITS + +@MODBUS_POINT_DF +"CIENG_PLC:SP","CIENG_PLC","SP","Setpoint, holding register 1","RO:1","Output","CIENG_SCAN1S","Binary",16 +"CIENG_PLC:PV","CIENG_PLC","PV","Read-back, input register 1","RI:1","Input","CIENG_SCAN1S","Binary",16 +``` + +- `PROTOCOL`: `Open Modbus/TCP`, `RTU` or `Ascii`. The CI Server TCP slave only answered + **Open Modbus/TCP** (with `RTU` every request timed out, `EQP-E-TCPRCVTMO`; ISS-024). +- `LINE_1_DEVICE` `[:]`, default port 502. `SUB_STATION_ID` = Modbus unit id. +- `STATUS_ITEM`: an existing Boolean item; 1 = communication good, 0 = bad, status 22 + OFFSCAN when off-scan. Load it before the station. +- Points need `NAME` = `:` as well as `STATION` and `POINT` + (without it: `DSS-E-PIDX_FST`). +- Addresses: `DO:n` coil, `DI:n` input bit, `RO:n[,bit]` holding register, `RI:n[,bit]` input + register (numbers from 1, not 40001/30001). `EXTERNAL_RELATION`: `Input`, `Output`, + `Input + Output`. `CONV_TYPE`: `Binary`, `Linear` (with `ELEC_LOW/HIGH`, `PHYS_LOW/HIGH`), + `Float` (`FLOAT_TYPE` Intel, swap words), `Digital`, … (L41 summary §3.3). + +## 4. Connect items (`ITEM_DF.STATION`, `POINT`) + +``` +@FIELDS +NAME,DESCRIPTION,ITEM_REP,VALUE_FORMAT,STATION,POINT + +@ITEM_DF +"CI-Eng-Sample.PLC1.SETPOINT","Setpoint written to holding register 1","Integer","99999","CIENG_PLC","SP" +"CI-Eng-Sample.PLC1.READBACK","Read back from input register 1","Integer","99999","CIENG_PLC","PV" +``` + +## 5. Test + +``` +itmval -p -n CI-Eng-Sample.PLC1.SETPOINT -v 1234 +itmval -g -n CI-Eng-Sample.PLC1.READBACK +itmval -g -n CI-Eng-Sample.PLC1.COMM_OK +printf '3\n1\n-1\n' | eqpdbg 0 EQPCIENG # slave 1: scan status, line status, request statistics +``` + +Before the first good scan input items show `off` (offline) and status 13 NOT INIT. + +**Off-scan / on-scan** (`dssqld -m` with `NAME,ON_SCAN` = 0 or 1): off-scan sets the status +item to 0 / status 22 OFFSCAN and freezes input items at their last value with the `off` +flag; a value written to an output while off-scan reached the device after going back +on-scan (output method *On change and connect*). + +## 6. Remove (reverse order) + +1. Items connected to points (`ITEM_DF` names). +2. Points, then station, then scan type (one file, in that order). +3. Line: this **stops** the equipment manager and deletes its start/stop scripts, setup file + and `tls\sav` files. +4. The status item and section with the other items. + +## Test system (2026-09-30) + +Full cycle on CI-Eng-Sample: loaded, `SETPOINT` 1234/4321/2468 and `CMD` 1/0 read back +through Modbus on `READBACK`/`FEEDBACK`, off-scan/on-scan checked, removed (manager stopped, +files deleted), reloaded from the sample files and re-tested: all 0 errors. diff --git a/examples/CI-Eng-Sample/01_section_df.qli b/examples/CI-Eng-Sample/01_section_df.qli index eafc087..bd48bdd 100644 --- a/examples/CI-Eng-Sample/01_section_df.qli +++ b/examples/CI-Eng-Sample/01_section_df.qli @@ -14,3 +14,4 @@ NAME,SECTION_PATH,SECTION_NAME,DESCRIPTION "CI-Eng-Sample.PUMP1","CI-Eng-Sample","PUMP1","Sample pump 1" "CI-Eng-Sample.SYSTEM","CI-Eng-Sample","SYSTEM","Sample system monitoring" "CI-Eng-Sample.DEMO","CI-Eng-Sample","DEMO","Tutorial examples (class/object)" +"CI-Eng-Sample.PLC1","CI-Eng-Sample","PLC1","Modbus loopback station CIENG_PLC" diff --git a/examples/CI-Eng-Sample/02_item_df.qli b/examples/CI-Eng-Sample/02_item_df.qli index 61cc540..8ff1a91 100644 --- a/examples/CI-Eng-Sample/02_item_df.qli +++ b/examples/CI-Eng-Sample/02_item_df.qli @@ -19,3 +19,4 @@ 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.PLC1.COMM_OK","Station CIENG_PLC communication (1 = good), status item","Boolean","",0,0,0,0,0,0 diff --git a/examples/CI-Eng-Sample/09_modbus_line_df.qli b/examples/CI-Eng-Sample/09_modbus_line_df.qli new file mode 100644 index 0000000..0f9cb0b --- /dev/null +++ b/examples/CI-Eng-Sample/09_modbus_line_df.qli @@ -0,0 +1,14 @@ +@LANGUAGE +ENGLISH + +@VERSION +1.03.00 + +! CI-Eng-Sample Modbus line (IM 36K10L41-01EN 3.6.1), CI Server R1.03.00 +! Loading it creates tls\com\eqpcieng_start.cmd, _stop.cmd and tls\sup\eqpcieng.sup and +! starts equipment manager EQPCIENG (eqpmdc) after a few seconds. EQUIPMENT_NODE blank = local node. +@FIELDS +NAME,DESCRIPTION,LINE_TYPE,EQUIPMENT_MAN,HEART_BEAT,TIMEOUT,DEAD_TIME,REPEAT_CONNECTION_DELAY + +@MODBUS_LINE_DF +"CIENG_MB_LINE","CI-Eng-Sample Modbus loopback line","TCP/IP","EQPCIENG",100,3000,30,10 diff --git a/examples/CI-Eng-Sample/10_modbus_station_df.qli b/examples/CI-Eng-Sample/10_modbus_station_df.qli new file mode 100644 index 0000000..5e8c910 --- /dev/null +++ b/examples/CI-Eng-Sample/10_modbus_station_df.qli @@ -0,0 +1,30 @@ +@LANGUAGE +ENGLISH + +@VERSION +1.03.00 + +! CI-Eng-Sample Modbus station, scan type and points (IM 36K10L41-01EN 3.6.3-3.6.5), CI Server R1.03.00 +! The station talks to CI Server's own Modbus slave mirror (eqpmdcmem + eqpmdcslvtcp on port 5020, +! started by equipment/eqpciengslv_start.cmd). Protocol must be Open Modbus/TCP (RTU does not answer). +! Input and holding registers share memory in the mirror (RI:1 = RO:1), as do inputs and coils (DI:1 = DO:1). +@FIELDS +NAME,DESCRIPTION,LINE,PROTOCOL,LINE_1_DEVICE,SUB_STATION_ID,OUTPUT_METHOD,STATUS_ITEM,ON_SCAN + +@MODBUS_STATION_DF +"CIENG_PLC","Loopback to CI Server Modbus slave (port 5020)","CIENG_MB_LINE","Open Modbus/TCP","localhost:5020",1,"On change and connect","CI-Eng-Sample.PLC1.COMM_OK",1 + +@FIELDS +NAME,DESCRIPTION,SCAN_INTERVAL + +@MODBUS_SCAN_TYPE_DF +"CIENG_SCAN1S","CI-Eng-Sample 1 s scan",1000 + +@FIELDS +NAME,STATION,POINT,DESCRIPTION,IO_ADDRESS,EXTERNAL_RELATION,SCAN_TYPE,CONV_TYPE,BITS + +@MODBUS_POINT_DF +"CIENG_PLC:SP","CIENG_PLC","SP","Setpoint, holding register 1","RO:1","Output","CIENG_SCAN1S","Binary",16 +"CIENG_PLC:PV","CIENG_PLC","PV","Read-back, input register 1 (same memory)","RI:1","Input","CIENG_SCAN1S","Binary",16 +"CIENG_PLC:CMD","CIENG_PLC","CMD","Command, coil 1","DO:1","Output","CIENG_SCAN1S","Digital",1 +"CIENG_PLC:FB","CIENG_PLC","FB","Feedback, input bit 1 (same memory)","DI:1","Input","CIENG_SCAN1S","Digital",1 diff --git a/examples/CI-Eng-Sample/11_item_eqp_df.qli b/examples/CI-Eng-Sample/11_item_eqp_df.qli new file mode 100644 index 0000000..2261e16 --- /dev/null +++ b/examples/CI-Eng-Sample/11_item_eqp_df.qli @@ -0,0 +1,15 @@ +@LANGUAGE +ENGLISH + +@VERSION +1.03.00 + +! CI-Eng-Sample items connected to Modbus points (ITEM_DF STATION + POINT), CI Server R1.03.00 +@FIELDS +NAME,DESCRIPTION,ITEM_REP,VALUE_FORMAT,STATION,POINT + +@ITEM_DF +"CI-Eng-Sample.PLC1.SETPOINT","Setpoint written to holding register 1","Integer","99999","CIENG_PLC","SP" +"CI-Eng-Sample.PLC1.READBACK","Read back from input register 1","Integer","99999","CIENG_PLC","PV" +"CI-Eng-Sample.PLC1.CMD","Command written to coil 1","Boolean","","CIENG_PLC","CMD" +"CI-Eng-Sample.PLC1.FEEDBACK","Feedback read from input bit 1","Boolean","","CIENG_PLC","FB" diff --git a/examples/CI-Eng-Sample/80_remove_item_eqp_df.qli b/examples/CI-Eng-Sample/80_remove_item_eqp_df.qli new file mode 100644 index 0000000..cc9ec6b --- /dev/null +++ b/examples/CI-Eng-Sample/80_remove_item_eqp_df.qli @@ -0,0 +1,15 @@ +@LANGUAGE +ENGLISH + +@VERSION +1.03.00 + +! Remove the CI-Eng-Sample items connected to Modbus points +@FIELDS +NAME + +@ITEM_DF +"CI-Eng-Sample.PLC1.SETPOINT" +"CI-Eng-Sample.PLC1.READBACK" +"CI-Eng-Sample.PLC1.CMD" +"CI-Eng-Sample.PLC1.FEEDBACK" diff --git a/examples/CI-Eng-Sample/81_remove_modbus_station_df.qli b/examples/CI-Eng-Sample/81_remove_modbus_station_df.qli new file mode 100644 index 0000000..c5ff8ca --- /dev/null +++ b/examples/CI-Eng-Sample/81_remove_modbus_station_df.qli @@ -0,0 +1,21 @@ +@LANGUAGE +ENGLISH + +@VERSION +1.03.00 + +! Remove CI-Eng-Sample Modbus points, scan type and station (points first) +@FIELDS +NAME + +@MODBUS_POINT_DF +"CIENG_PLC:SP" +"CIENG_PLC:PV" +"CIENG_PLC:CMD" +"CIENG_PLC:FB" + +@MODBUS_STATION_DF +"CIENG_PLC" + +@MODBUS_SCAN_TYPE_DF +"CIENG_SCAN1S" diff --git a/examples/CI-Eng-Sample/82_remove_modbus_line_df.qli b/examples/CI-Eng-Sample/82_remove_modbus_line_df.qli new file mode 100644 index 0000000..d0a2ab8 --- /dev/null +++ b/examples/CI-Eng-Sample/82_remove_modbus_line_df.qli @@ -0,0 +1,12 @@ +@LANGUAGE +ENGLISH + +@VERSION +1.03.00 + +! Remove the CI-Eng-Sample Modbus line (after its stations) +@FIELDS +NAME + +@MODBUS_LINE_DF +"CIENG_MB_LINE" diff --git a/examples/CI-Eng-Sample/91_remove_item_df.qli b/examples/CI-Eng-Sample/91_remove_item_df.qli index d91a425..f67e82b 100644 --- a/examples/CI-Eng-Sample/91_remove_item_df.qli +++ b/examples/CI-Eng-Sample/91_remove_item_df.qli @@ -18,3 +18,4 @@ NAME "CI-Eng-Sample.SYSTEM.PING_LOCALHOST" "CI-Eng-Sample.SYSTEM.PROC_ALM" "CI-Eng-Sample.DEMO.COUNTER" +"CI-Eng-Sample.PLC1.COMM_OK" diff --git a/examples/CI-Eng-Sample/92_remove_section_df.qli b/examples/CI-Eng-Sample/92_remove_section_df.qli index d57a8e8..62fed29 100644 --- a/examples/CI-Eng-Sample/92_remove_section_df.qli +++ b/examples/CI-Eng-Sample/92_remove_section_df.qli @@ -12,5 +12,6 @@ NAME "CI-Eng-Sample.TANK1" "CI-Eng-Sample.PUMP1" "CI-Eng-Sample.SYSTEM" +"CI-Eng-Sample.PLC1" "CI-Eng-Sample.DEMO" "CI-Eng-Sample" diff --git a/examples/CI-Eng-Sample/README.md b/examples/CI-Eng-Sample/README.md index 5b9d274..5212346 100644 --- a/examples/CI-Eng-Sample/README.md +++ b/examples/CI-Eng-Sample/README.md @@ -47,9 +47,16 @@ cmd /c "\examples\CI-Eng-Sample\remove.cmd" | `CIENG_INCR` | Class (traditional) | Increments `DEMO.COUNTER`, wraps at 100; compiled on load | | `CI-Eng-Sample.DEMO.INCR1` | Object | Instance of `CIENG_INCR` | | `CIENG_EVENT` | Item storage group | Event/Item, lifetime 1 week, rollover 1 day | +| `CI-Eng-Sample.PLC1` | Section | Modbus loopback station | +| `CI-Eng-Sample.PLC1.COMM_OK` | Item, Boolean | Status item of station `CIENG_PLC` (1 = communicating, status 22 when off-scan) | +| `CI-Eng-Sample.PLC1.SETPOINT` / `.READBACK` | Items, Integer | Written to holding register 1 (`RO:1`) / read from input register 1 (`RI:1`), same memory | +| `CI-Eng-Sample.PLC1.CMD` / `.FEEDBACK` | Items, Boolean | Written to coil 1 (`DO:1`) / read from input bit 1 (`DI:1`), same memory | +| `CIENG_MB_LINE` | Modbus line (TCP/IP) | Equipment manager `EQPCIENG` (created and started by loading the line) | +| `CIENG_PLC` | Modbus station | Open Modbus/TCP to `localhost:5020`, unit 1, output method *On change and connect* | +| `CIENG_SCAN1S` | Modbus scan type | 1000 ms | | `CIENG_VIEWER` | Authorization group | Read-only: `ITEM_READ`, `SECTION_READ`, `ALARM_CURRENT_READ`, `ALARM_CHRONO_READ`. No users are created by the sample. | -All items are internal (no station), so the project works without any PLC or simulator. +All items except `PLC1.*` are internal (no station). The `PLC1` station talks to CI Server's own Modbus slave mirror (see below), so no PLC is needed either. New items start with status 13 (`NOT INIT`) until a value is written. ## Files @@ -63,10 +70,28 @@ 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 `:`) | | `05_trigger_df.qli`, `06_class_df.qli`, `07_object_df.qli` | Trigger group, class (source in the `METHOD` memo, `@"` … `"@`, `COMPILE` 1), object | | `08_auth_group_df.qli` | Authorization group (`AUTH_GROUP_DF`) | -| `85_`…`92_remove_*.qli` | Names to delete, in reverse order | +| `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 | +| `equipment/eqpciengslv_start.cmd`, `_stop.cmd` | Start/stop the Modbus slave mirror (copy to `tls\com`) | +| `80_`…`92_remove_*.qli` | Names to delete, in reverse order | | `load.cmd`, `remove.cmd` | Run the steps in the right order | | `monitoring/*.sup.txt` | Setup-file lines for the monitoring processes (not applied by `load.cmd`) | +## Modbus slave mirror (for station CIENG_PLC) + +`CIENG_PLC` reads and writes CI Server's own Modbus slave: `eqpmdcmem` (slave memory) and +`eqpmdcslvtcp` (Modbus TCP on port 5020). Without them the station reports bad communication +(`COMM_OK` = 0) but everything loads. To start them with CI Server, an administrator copies +`equipment/eqpciengslv_start.cmd` and `eqpciengslv_stop.cmd` to `%TLS_ROOT_PATH%\tls\com`; +for a quick test they can also be started by hand from a normal prompt: + +``` +start eqpmdcmem -n EQPMDCMEM +start eqpmdcslvtcp -n EQPMDCSLVTCP -p 5020 +``` + +Remove the two files from `tls\com` when the sample is removed. See skill `equipment`, task +`modbus-station.md`. + ## Monitoring processes (optional) `monitoring/` holds the lines to add to the setup files in `%TLS_ROOT_PATH%\tls\sup\` so that diff --git a/examples/CI-Eng-Sample/equipment/eqpciengslv_start.cmd b/examples/CI-Eng-Sample/equipment/eqpciengslv_start.cmd new file mode 100644 index 0000000..a334d51 --- /dev/null +++ b/examples/CI-Eng-Sample/equipment/eqpciengslv_start.cmd @@ -0,0 +1,5 @@ +@echo off +REM CI-Eng-Sample: start the Modbus slave mirror used by station CIENG_PLC. +REM Copy to %TLS_ROOT_PATH%\tls\com (administrator); equipment_start.cmd calls every eqp*start.cmd there. +start /B /NORMAL %TLS_ROOT_PATH%\tls\exe\eqpmdcmem.exe -n EQPMDCMEM +start /B /NORMAL %TLS_ROOT_PATH%\tls\exe\eqpmdcslvtcp.exe -n EQPMDCSLVTCP -p 5020 diff --git a/examples/CI-Eng-Sample/equipment/eqpciengslv_stop.cmd b/examples/CI-Eng-Sample/equipment/eqpciengslv_stop.cmd new file mode 100644 index 0000000..06ec4d9 --- /dev/null +++ b/examples/CI-Eng-Sample/equipment/eqpciengslv_stop.cmd @@ -0,0 +1,4 @@ +@echo off +REM CI-Eng-Sample: stop the Modbus slave mirror. +%TLS_ROOT_PATH%\tls\exe\durstp.exe -msk -t 10 -p EQPMDCSLVTCP +%TLS_ROOT_PATH%\tls\exe\durstp.exe -msk -t 10 -p EQPMDCMEM diff --git a/examples/CI-Eng-Sample/load.cmd b/examples/CI-Eng-Sample/load.cmd index 13b91e8..bfa4197 100644 --- a/examples/CI-Eng-Sample/load.cmd +++ b/examples/CI-Eng-Sample/load.cmd @@ -17,3 +17,10 @@ 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 (no users are created by the sample) dssqld -i 08_auth_group_df.qli -l 08_auth_group_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 +echo Waiting 15 seconds for equipment manager EQPCIENG to start... +powershell -NoProfile -Command "Start-Sleep -Seconds 15" +dssqld -i 10_modbus_station_df.qli -l 10_modbus_station_df.qlo +dssqld -i 11_item_eqp_df.qli -l 11_item_eqp_df.qlo diff --git a/examples/CI-Eng-Sample/remove.cmd b/examples/CI-Eng-Sample/remove.cmd index b85f7f6..c354c05 100644 --- a/examples/CI-Eng-Sample/remove.cmd +++ b/examples/CI-Eng-Sample/remove.cmd @@ -5,6 +5,9 @@ rem Order: object, class, trigger group, storage links, stop + delete storage gr 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. cd /d "%~dp0" +dssqld -r 80_remove_item_eqp_df.qli -l 80_remove_item_eqp_df.qlo +dssqld -r 81_remove_modbus_station_df.qli -l 81_remove_modbus_station_df.qlo +dssqld -r 82_remove_modbus_line_df.qli -l 82_remove_modbus_line_df.qlo dssqld -r 85_remove_auth_group_df.qli -l 85_remove_auth_group_df.qlo dssqld -r 86_remove_object_df.qli -l 86_remove_object_df.qlo dssqld -r 87_remove_class_df.qli -l 87_remove_class_df.qlo diff --git a/knowledge/issues.md b/knowledge/issues.md index cfc5e1d..03b91ac 100644 --- a/knowledge/issues.md +++ b/knowledge/issues.md @@ -43,3 +43,4 @@ development system (see "Test system" in `progress.md`); they do not exist on ot | ISS-021 | 2026-09-30 | EQUIPMENT (`eqpiostat`) | IM 36K10L40 §2 says `eqpiostat` stores hourly I/O statistics per station line in "history group STATION_STAT". On the test system `eqpiostat` runs (started by `equipment_start.cmd` on the host node) and `STATION_STAT` is a dataset, but `dssqld -e` returned 0 records, also with filters on `TIME_STAMP` and `STATION` (AID Modbus stations, which send requests). | open | Check whether records appear after a full hour with a communicating station, or whether the dataset is read another way (e.g. Engineering Module, report). | `knowledge/manuals/IM36K10L40-01EN.md` §2 | | ISS-022 | 2026-09-30 | ITEM (`itmval -f`) | `itmval -f vs -n CI-Eng-Sample.TANK1.LEVEL` (IM 36K10L36 §1.4, write a restore command) crashes with a segmentation fault (bash) / access violation 0xC0000005 (PowerShell) and writes no file; also with `-l`. The manual's space-separated form `-n ` is rejected with `FSL-E-NARG_ALL`. `itmval -g`/`-p` work. | open | Workaround: build restore lines from `itmval -g` output. Report to Yokogawa support if needed. | `knowledge/manuals/IM36K10L36-01EN.md` §3; `.claude/skills/system-management/tasks/read-write-item.md` | | ISS-023 | 2026-09-30 | ITEM / ITH (manual vs install) | Installed ITEM Service differs from IM 36K10L35/L36: `item_start.cmd` starts `itheix` (EVENT/ITEM storage, not described), aggregation `ithsag`/`ithrag`, two instances of each retrieve process, and `itmtim 100 1000 1 200 1` (five arguments, three documented); `itm.sup` item pool is 650000 KB (manual default 50000) and has `not_regained` (not described); `itheix.sup` has `max_sample_delay`, `max_samples_queued`, `max_open_files`. | closed | Closed 2026-09-30 (user decision: the installed software is the reference). Summaries describe the installed values. | `knowledge/manuals/IM36K10L35-01EN.md`; `knowledge/manuals/IM36K10L36-01EN.md` | +| ISS-024 | 2026-09-30 | EQUIPMENT (Modbus slave) | IM 36K10L41 §3.7 says `EQPMDCSLVTCP` waits for "MODBUS RTU requests via TCP/IP" and the CI Server master should use "MODBUS RTU via TCP/IP". A Modbus master station with `PROTOCOL = RTU` to `eqpmdcslvtcp` (port 5020) got no answer (`EQP-E-TCPRCVTMO`, 4 requests, 0 valid); with `Open Modbus/TCP` it worked at once. | closed | Closed 2026-09-30 (user decision: installed software is the reference). Use `Open Modbus/TCP` towards `eqpmdcslvtcp`. | `knowledge/manuals/IM36K10L41-01EN.md` §3.7; `.claude/skills/equipment/tasks/modbus-station.md` | diff --git a/knowledge/manuals/IM36K10L41-01EN.md b/knowledge/manuals/IM36K10L41-01EN.md index 8dd5b8f..adea046 100644 --- a/knowledge/manuals/IM36K10L41-01EN.md +++ b/knowledge/manuals/IM36K10L41-01EN.md @@ -147,7 +147,9 @@ CI Server can serve third-party Modbus masters through a "mirror": and stations in CI Server pointing at the slave's address** (output method *On change and connect*). CI Server items then read and write the same registers the third party sees. Installed on the test system: `eqpmdcmem.exe`, `eqpmdcslvser.exe`, `eqpmdcslvtcp.exe`; none -running. On R1.03 `equipment_start.cmd` runs every `tls\com\eqp*start.cmd`, so a separate +running. **Verified** 2026-09-30 with CI-Eng-Sample station `CIENG_PLC`: the TCP slave answered only with +station protocol **Open Modbus/TCP**, not RTU as the manual says (ISS-024); skill `equipment`, task +`modbus-station.md`. On R1.03 `equipment_start.cmd` runs every `tls\com\eqp*start.cmd`, so a separate start file is enough (see L40 summary). ## 3.8–3.40 Other drivers diff --git a/knowledge/progress.md b/knowledge/progress.md index 8d8ce8e..63b5fb4 100644 --- a/knowledge/progress.md +++ b/knowledge/progress.md @@ -104,7 +104,8 @@ now come before classes and objects (phase 6), and the other interfaces follow a | C10 | String items: length 1–200, holds length − 1 characters ([task](../.claude/skills/item-engineering/tasks/string-items.md)) | passed | passed | Tested with temporary `CI-Eng-Sample.DEMO.STR*` items (removed): 201 rejected; too-long writes cut, status 12 OVERRANGED ([ISS-019](issues.md)). | | C10 | Integrator time unit: integration granule `itm_int_secs` in `itm.sup` ([task](../.claude/skills/item-engineering/tasks/sub-items.md)) | passed | passed | 60 → `RUN_SECONDS` +1 per minute; restored to 1 (file identical to backup), +1 per second again ([ISS-010](issues.md)). Elevated restarts run by the user. | | G10 | Displays, symbols, Operator Interface test | not practiced | pending | GUI (Edit Module); phase 10. | -| G10 | Lines / stations / points, alarms, reports, audit, RDBMS, history | not practiced | pending | Covered in their own phases (5–12). | +| L41/C10 | Modbus TCP line, station, scan type, points, connected items by quick load ([task](../.claude/skills/equipment/tasks/modbus-station.md)) | passed | passed | Loopback to CI Server's own Modbus slave (`eqpmdcmem` + `eqpmdcslvtcp` on 5020, started by hand). Line load created and started `EQPCIENG`; removal stopped it and deleted its files. Write/read-back, off-scan/on-scan checked; full remove/reload from sample files. Protocol must be Open Modbus/TCP ([ISS-024](issues.md)). Mirror start file in `tls\com` not yet tested (needs admin). | +| G10 | Alarms, reports, audit, RDBMS, history | not practiced | pending | Covered in their own phases (7–12). | | R10/R20 | Read a setup file: active settings and keyword help ([task](../.claude/skills/portal-setup/tasks/read-setup-file.md)) | passed | n/a | Read-only. Compared with the Setup File Editor GUI for `wfla_display.sup`, `wflgdi.sup` and all 9 tabs of `jwuiisg.sup`: fields and values identical. Manual differences logged as ISS-012 to ISS-017 (installed software taken as the reference). | | R10 | Check web access for CI View: ports, Remote Connect page, `DEPLOY` folder ([task](../.claude/skills/portal-setup/tasks/check-web-access.md)) | passed | n/a | 8080/8443 listening, page 200, six `DEPLOY` folders. | | R10/R20 | Change a setup file safely ([task](../.claude/skills/portal-setup/tasks/change-setup-file.md)) | passed | n/a | `jwuiisg.sup` HTTP port 8080 → 8081 (text edit, elevated restart): 8081 served the page, 8080 refused; restored, hash identical to backup. Editor: *OK* writes at once, *Reset Field* restores the default (ISS-016). |