ci-server-engineer/.claude/skills/equipment/tasks/modbus-station.md
cliu 516729ff24 R1.05 findings from a user project (tested only)
Tested on the R1.05 test server 2026-10-09..12 with a user project (own
objects only); not yet on CI-Eng-Sample (ISS-188). Only results that
were tested are included; inferences, code-only and manual-only points
and the untested sample layout change were left out.
- layouts: 'logout' is a secondary logout, always disabled on the R1.05
  web client; 'exit' closes the window and ends the session (ISS-182).
- create-display: R1.05 web client table (String items in text vs
  textField, fixed text alignment, start-hidden limits ISS-183, two
  visibility conditions, On entry display actions, rectangle blinking,
  verified connections, first load).
- java-class 4a: signal arrays at scale, write on change, attribute
  arrays, offline javac/javap check; change-reset-class: new signals need
  the object recreated, attributes lost (ISS-185); opcdbg reset in cmd,
  TRIGGER_1 via dssqld -m.
- string-items (ISS-187), users-groups, modbus-station (400 registers,
  comm loss), export-dataset (NAME range filter), item-alarming.
- new task system-management/package-project.md; tools/ModbusSim.java
  (tested on R1.05: FC03/04/06/16, exceptions, modes); AMSI (ISS-186).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:57:08 +11:00

139 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
task: Modbus TCP station by quick load (line, station, scan type, points, items)
version: R1.05 (first written for 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 on R1.03 (2026-09-30); on R1.05 the datasets, setup files and start scripts were checked identical (2026-10-08, read-only), re-tested on R1.05 2026-10-08 with the reduced sample load on the shared test server (setpoint 1234 read back, COMM_OK 1, eqpdbg slave GOOD; mirror started for the test only; everything removed afterwards)
---
# 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. On R1.05 (checked 2026-10-08) it also runs `eqt*start.cmd`
and, on the host node, every `?*_equipment_start.cmd` (with `?*_equipment_stop.cmd` called
from `equipment_stop.cmd`), which is a cleaner hook for such extensions.
## 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` `<host>[:<port>]`, 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` = `<station>:<point>` 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 (R1.03, 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. With
`eqpciengslv_start.cmd`/`_stop.cmd` copied to `tls\com` and CI Server restarted, the mirror and
`EQPCIENG` started under the CI Service, `COMM_OK` = 1, and the saved setpoint (2468) was
re-sent to the freshly zeroed slave memory on connect (output method *On change and connect*).
## R1.05: a 400-register device (2026-10-12, user project on the R1.05 test server, 2026-10-09 to 10-12)
- Own line and equipment manager (`EQUIPMENT_MAN` e.g. `EQP<NAME>`) next to another project's
line: loaded, removed and loaded again with 0 errors; removing the line stopped only its manager.
- 400 holding registers as points `RO:1`–`RO:400`, `CONV_TYPE` `Linear` with `HAS_SIGN` 1,
`ELEC_LOW,ELEC_HIGH` = `-32768,32767` and `PHYS_LOW,PHYS_HIGH` = `-327.68,327.67` (raw ÷ 100):
all 400 items read the expected signed values (test pattern from a simulator, quality 0,
status 9).
- Communication loss: status item 0 (status 4), inputs keep their last value with the `off` option;
values and status item recover on the next scan after the device answers again.
- Test without the device: `tools/ModbusSim.java` (Java, runs with CI Server's own JDK; holding
registers with read and write, scenarios through a mode file). A PowerShell script that opens a
TCP listener was blocked by Windows antivirus (AMSI) as malicious content on the engineering PC
(Windows 10).