wrps-demo-kit/03-plc/VERSIONS.md
Clio Liu 5be48b6bbb fix: CI Server on cicore1 is R1.05, not R1.03
Corrected in README.md, CLAUDE.md, 02-environment/README.md and
03-plc/VERSIONS.md.

The @VERSION 1.03.00 header inside the .qli files is the quickload FILE
FORMAT version, not the CI Server release. Left alone.

This also sharpens a caveat that was previously stated wrongly. The
EQP-E-DUP_ITEM rejection - an item import fails if two items share an
IO_ADDRESS - was observed on 2026-08-14 on the DEVELOPMENT machine, which
ran R1.03. Production runs R1.05, where it has never been tested. The
design still works around it by publishing level and speed in % only, and
that workaround costs nothing; but anyone wanting a second unit for a
measurement should try it on R1.05 before assuming they need a second PLC
register to carry it.
2026-09-02 17:34:58 +10:00

79 lines
3.8 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.

# Software and versions
Everything below was **read from the running system on 2026-09-02**, not taken
from documentation. Where a version matters — where a different one behaves
differently — that is said explicitly.
## The PLC
| Component | Version | Where it runs | How to check |
|---|---|---|---|
| **OpenPLC Runtime** | **v4.1.10** | `openplc-runtime` container on `yau-sls-poc-lin001` | `docker exec openplc-runtime cat /workdir/VERSION` |
| Docker image | `openplc-runtime-migrated:v4.1.10` | local to the host, **not in any registry** | `docker images` |
| Base OS in container | Debian 12 (bookworm) | | `docker exec openplc-runtime cat /etc/os-release` |
| Python (runtime + plugins) | 3.11.2 | | `docker exec openplc-runtime python3 --version` |
| g++ | 12.2.0 | used to build the PLC program | `docker exec openplc-runtime g++ --version` |
| GNU Make | 4.3 | drives `scripts/Makefile.strucpp` | |
| pymodbus (in the slave plugin) | 3.11.2 | | `docker exec openplc-runtime ./venvs/modbus_slave/bin/pip list` |
### Runtime plugins
`/workdir/plugins.conf` — the third field is enabled (1) / disabled (0):
| Plugin | Enabled | Note |
|---|---|---|
| `modbus_slave` | **1** | This is the one that matters. It is what makes the PLC a Modbus **server** on 502. |
| `modbus_master` | 0 | Correct — the PLC must not poll anyone. |
| `opcua` | 0 | |
| `s7comm` | 0 | |
| `ethercat` | **1** | ⚠️ Enabled for no reason. It came from an `ethercat.json` the Editor project emits by default (the file is 0 bytes). Harmless so far, but it is a plugin running with nothing to do. |
## The toolchain
| Component | Version | Notes |
|---|---|---|
| **OpenPLC Editor** | **v4.2.11** (AppImage) | Needs `--no-sandbox` (Electron) and `libfuse2t64`. ⚠️ **Not currently installed anywhere** — see `DEPLOY.md` §0. |
| **STruC++** | **v0.6.2** | The ST → C++ compiler. **Ships only inside the Editor AppImage**; there is no standalone binary. This is the single reason the Editor is unavoidable. |
## The SCADA
| Component | Version | Where |
|---|---|---|
| **Yokogawa CI Server** | R1.05 | `yau-poc-cicore1` (`10.0.0.21`) |
## Versions that actually matter
**OpenPLC Runtime v3 → v4 is a breaking change, and most guidance you'll find
online is for v3.**
| | v3 | **v4 (what we run)** |
|---|---|---|
| ST compiler | MatIEC | **STruC++** |
| Accepts a flat `.st` upload | yes | **no**`scripts/compile.sh` explicitly rejects MatIEC files (`Config0.c`, `glueVars.c`) |
| Web UI on the runtime | yes | **no** — REST API only, port 8443, JWT |
| Editor project format | one file | **a folder**`project.json` + one file per POU |
| `%MW` Modbus mapping | starts at HR 0 | **starts at HR 1024** (`%QW` occupies 01023) |
That last row is the one that silently produces wrong data rather than an error.
See `register-map.csv`, which carries resolved addresses.
**The Modbus buffer layout is configuration, not a constant.** From
`core/generated/conf/modbus_slave.json` in the running container:
```json
"holding_registers": { "qw_count": 1024, "mw_count": 1024, ... }
```
`qw_count: 1024` is *why* `%MW0` is holding register 1024. Change that file and
every SCADA address moves.
**One CI Server behaviour is load-bearing, and it was observed on a different
release.** An item import is rejected if two items share an `IO_ADDRESS`
(`EQP-E-DUP_ITEM`). The SCADA design works around it by publishing one unit per
register — level and speed in % only, not in both % and engineering units.
That rejection was seen on **2026-08-14 on the development machine, which ran
R1.03**. Production `yau-poc-cicore1` runs **R1.05**, where the constraint has
never been tested. The workaround is harmless either way, but if you need a second
unit for a measurement, try it on R1.05 before assuming you need a second PLC
register for it.