The old 05-scada/, restructured around the distinction its README never
drew: configuration is deployed with dssqld, displays are deployed by
file copy. Conflating the two is what made the folder confusing.
modbus_points/ the tag database - named for the protocol,
since CI Server configures others differently
modbus_points/historian/ 3 groups, 49 bindings - HAND-MADE, no
generator, and drifted from the server
hmi/ displays and their generator
ciserver-backup-2026-08/ outdated exports, evidence only, never import
QUICKLOAD.md dssqld export/import, the 5 classes, the import
order, and why an item import kills every display
README.md the chain end to end, and the not-updating triage
Verified during the move - the whole chain is reproducible:
scada-points.csv and all three .qli regenerate byte-identically
all six displays build clean
Removed the K offset machinery from build_display.py, item-ids.meta.json
and DEPLOY.md. K was a consistency check on measured ids, not a source of
them, and diagnosing a dead screen by arithmetic is wasted effort when
validating the display in CI Server's Editor Module fixes it outright.
The guidance now leads with that one action.
Recorded, not fixed: the repo's historian config disagrees with the
2026-08 CI Server export - WRPS_THIRTY_SEC and a FIVE_SECONDS group exist
on the server and not here. cicore1 was unreachable during this audit, so
which is correct is unknown.
Not carried across: __pycache__, out/*.xml, and the top-level
WRPS_Overview.xml that was tracked despite .gitignore declaring the
display XMLs to be build output.
115 lines
5 KiB
Markdown
115 lines
5 KiB
Markdown
# 04-scada — the CI Server side
|
|
|
|
Everything that lives on `yau-poc-cicore1` (`10.0.0.21`): the tag database that
|
|
reads the PLC, and the displays an operator looks at.
|
|
|
|
## Two halves, two deployment mechanisms
|
|
|
|
This is the distinction to get straight before anything else. Conflating them is
|
|
what makes this folder confusing.
|
|
|
|
| | **Configuration** | **Displays** |
|
|
|---|---|---|
|
|
| What | sections, items, Modbus points, historian groups | the `.xml` screens |
|
|
| Lives in | `modbus_points/` | `hmi/` |
|
|
| **Deployed by** | **`dssqld`** — the quickload utility | **file copy** into the displays directory |
|
|
| Generated from | `03-plc/register-map.csv` | `build_display.py` |
|
|
| Binds by | `NSID` / `ID_NUMBER` | **itemId** — healed by name on import |
|
|
|
|
`dssqld` is for configuration only. It has nothing to do with displays. See
|
|
`QUICKLOAD.md`.
|
|
|
|
## The chain
|
|
|
|
Everything derives from the PLC. The PLC side leads, always.
|
|
|
|
```
|
|
03-plc/src/*.st
|
|
│ build.py
|
|
▼
|
|
03-plc/register-map.csv the contract - 69 points
|
|
│ gen_scada_points.py
|
|
▼
|
|
modbus_points/scada-points.csv the SCADA view - 49 points, poll groups, units
|
|
│ gen_ciserver_qli.py
|
|
▼
|
|
modbus_points/*.qli 6 sections · 49 Modbus points · 49 items
|
|
│ dssqld -i
|
|
▼
|
|
CI SERVER ◄──── Modbus TCP ──── the PLC on 10.0.0.17:502
|
|
▲
|
|
│ file copy
|
|
│
|
|
hmi/out/*.xml 6 displays
|
|
▲ build_display.py
|
|
│
|
|
hmi/item-ids.csv 49 itemIds, MEASURED from CI Server
|
|
```
|
|
|
|
**Nothing in this chain is hand-edited.** Change a register in `03-plc/build.py`,
|
|
rebuild, then re-run both generators. If CI Server needs a field the generators do
|
|
not emit, it goes in the generator.
|
|
|
|
**One exception:** the historian has no generator. See
|
|
`modbus_points/historian/README.md`.
|
|
|
|
## Layout
|
|
|
|
```
|
|
QUICKLOAD.md dssqld - export and import configuration
|
|
modbus_points/ the tag database (named for the protocol: CI Server
|
|
configures other protocols differently)
|
|
historian/ collection groups and item bindings - HAND-MADE
|
|
hmi/ displays, and the generator that builds them
|
|
ciserver-backup-2026-08/ ⚠️ outdated exports, evidence only - never import
|
|
```
|
|
|
|
## ⚠️ "The values on my display are not updating"
|
|
|
|
**First, and before any other investigation:**
|
|
|
|
> **Open the display in CI Server's Editor Module and validate it.
|
|
> Then report what happened.**
|
|
|
|
Validation resolves every connection by name and repairs the file. It fixes the
|
|
overwhelmingly common cause in seconds — an itemId that no longer matches, which
|
|
happens **every time the items are re-imported**. CI Server recreates items on
|
|
import rather than updating them in place, so every id in every display moves at
|
|
once, and every value goes dead together.
|
|
|
|
That simultaneity is the signature: everything dying at the same moment is ids,
|
|
not communications.
|
|
|
|
**Only once validation has been ruled out**, work down these:
|
|
|
|
| Symptom | Cause |
|
|
|---|---|
|
|
| Some values dead, others fine | Those items were never measured. Harvest the ids — see `hmi/DEPLOY.md`. |
|
|
| Every analogue reads 0, always | You are polling `%IW`/`%IX` (FC04/FC02). Those are **field** inputs; in the simulation build nothing writes them. Live values are in the `%QW` block (FC03). |
|
|
| Values frozen at a plausible number | Communications stopped. Is the container up? Is a **program running**? The runtime opens its Modbus slave only while a program runs — a stopped program means port 502 refuses. |
|
|
| Values moving but wrong | Addressing. `%MW` starts at holding register **1024**, not 0. A wrong-by-1024 read succeeds and returns plausible nonsense. |
|
|
| Alarm word goes negative | `%QW17` must be read **unsigned**. Bit 15 does not fit a signed INT. |
|
|
|
|
**What this repo cannot tell you:** whether CI Server's own poll groups are
|
|
actually scanning. That lives on `cicore1`. If the PLC polls correctly with
|
|
`05-tests/verify_modbus.py` and the ids are good, that is the remaining place to
|
|
look.
|
|
|
|
## Status
|
|
|
|
| | |
|
|
|---|---|
|
|
| Points and items | **Imported and reading live PLC values** (2026-08-14), verified against a direct Modbus read |
|
|
| Generators | Verified reproducible 2026-09-02 — `scada-points.csv` and all three `.qli` regenerate byte-identically |
|
|
| Displays | Six built; `build_display.py` runs clean |
|
|
| Historian | 3 groups, 49 bindings — **hand-made, and drifted from the server** |
|
|
| CI Server state | ⚠️ **Unverified.** No access to `cicore1` during this audit. Everything here is what the repo believes, not what the server holds. |
|
|
|
|
### Two things left for you
|
|
|
|
- **Alarm and trend limits.** Every item imports with alarming off and limits at 0.
|
|
Which points alarm, at what threshold and priority, is engineering judgement
|
|
about the plant — not something to derive from a register map.
|
|
- **Re-export the configuration from `cicore1`** and diff it against this folder.
|
|
Until then, `ciserver-backup-2026-08/` is the only record of the server's own
|
|
state, and it is known to disagree with `modbus_points/historian/`.
|