fix(scada): PS_* placeholder tags out, CI Server item names in

scada-points.csv led with a scada_tag column of PS_* names derived from
the PLC register map - PS_STN_WET_WELL_LEVEL and the like. CI Server never
adopted them. They named nothing that exists, nothing in this repo read
them, and read as if authoritative they have already caused a real defect
in a downstream project.

Replaced with ci-server-points.csv, the as-built delivery from the CI
Server side (copied from yau-plant-assistant, not re-derived). It is keyed
on the CI Server item, with the station and point name beside it:

    ci_item,ci_station,ci_point,description,poll_group,...

gen_scada_points.py now reproduces that file byte-identically, taking the
names from the LEAF table in gen_ciserver_qli.py so the CSV and the .qli
cannot disagree. tag_for() is gone. Verified: the CSV and all three .qli
regenerate unchanged, and all six displays still build.

The four poll groups keep their PS_ names - PS_STATUS_BITS, PS_PUBLISHED,
PS_SETPOINTS, PS_SIM_CONTROL. Those are live configuration, and are the
only legitimate PS_ names.

modbus_points/README.md gains a 'four namespaces' section - instrument tag,
PLC address, CI Server point, CI Server item - since confusing them is what
produced the placeholder column in the first place.

Also settles the historian drift left open in the previous commit. The
live export is the authority: the server runs WRPS_ONE_SEC at 5 SECONDS,
not 1, and WRPS_THIRTY_SEC at 30 seconds rather than a 60 second
WRPS_ONE_MIN. Code assuming 60 s was wrong by twelvefold. Recorded in
historian/README.md with a caution never to hardcode a sample interval.

Every .qli in the delivery was byte-identical to ours - only the CSV
differed.
This commit is contained in:
Clio Liu 2026-09-02 17:21:57 +10:00
parent 947f632d7f
commit 0927323e13
11 changed files with 169 additions and 102 deletions

View file

@ -30,7 +30,7 @@ Everything derives from the PLC. The PLC side leads, always.
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
modbus_points/ci-server-points.csv the SCADA view - 49 points, poll groups, units
│ gen_ciserver_qli.py
modbus_points/*.qli 6 sections · 49 Modbus points · 49 items
@ -100,9 +100,9 @@ look.
| | |
|---|---|
| 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 |
| Generators | Verified reproducible 2026-09-02 — `ci-server-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** |
| Historian | 3 groups, 49 bindings — **hand-made, and the live rates differ from these files.** The server runs `WRPS_ONE_SEC` at 5 s and `WRPS_THIRTY_SEC` at 30 s. See `modbus_points/historian/README.md`. |
| 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

View file

@ -21,9 +21,11 @@ as opposed to what the repo believes was configured.
An export holds **every** record of its class, not only this project's. Filter on
`AID.WRPS` when comparing.
## The drift they revealed
## The drift they revealed — and settled
Comparing these against `../modbus_points/historian/` shows the two do not agree:
Comparing these against `../modbus_points/historian/` shows the two do not agree.
**These exports are the authority**: they record what the running server actually
did, whereas `his_group.qli` records what the source project intended.
| In this export | In the repo's source |
|---|---|
@ -34,6 +36,11 @@ Comparing these against `../modbus_points/historian/` shows the two do not agree
That is the whole reason this folder exists rather than being deleted.
**The rates matter more than the names.** The live `WRPS_ONE_SEC` runs at **5
seconds**, not 1, and the second group is `WRPS_THIRTY_SEC` at **30 seconds**, not
a 60 second `WRPS_ONE_MIN`. Code that assumed 60 seconds was wrong by twelvefold.
Never hardcode a sample interval — read it from the item.
## Replacing it
When `cicore1` is reachable, re-export the five classes (`../../QUICKLOAD.md`),

View file

@ -252,7 +252,7 @@ of the spill weir resolves to 0.017% because the register underneath is mm, and
a flow in m³/h to 0.1 — so both get one decimal, and a second would be invented
precision. Integer registers get none. `point_format.check()` fails the build if
a new item has no mask, and the masks are cross-checked against `format_mask` in
`04-scada/modbus_points/scada-points.csv`, which is what CI Server imports as
`04-scada/modbus_points/ci-server-points.csv`, which is what CI Server imports as
`VALUE_FORMAT`.
Element order matters to match what CI View saves: `<htmlId>`, `<format>`,

View file

@ -35,7 +35,7 @@ decimal is honest and two would not be; a flow in m3/h resolves to 0.1.
Integer registers get no decimal at all - a decimal place there would be
invented precision.
**These masks must agree with `format_mask` in `04-scada/modbus_points/scada-points.csv`,**
**These masks must agree with `format_mask` in `04-scada/modbus_points/ci-server-points.csv`,**
which is what the item export carries into CI Server as `VALUE_FORMAT`. The
units and their gains are defined once, in `gen_scada_points.py`.
"""

View file

@ -42,7 +42,7 @@ from pathlib import Path
HERE = Path(__file__).resolve().parent
OUT = HERE / "out"
POINTS = HERE.parent / "modbus_points" / "scada-points.csv"
POINTS = HERE.parent / "modbus_points" / "ci-server-points.csv"
QLI_GEN = HERE.parent / "modbus_points" / "gen_ciserver_qli.py"
PLC_HOST, PLC_PORT, PLC_UNIT = "192.168.153.192", 502, 1

View file

@ -7,20 +7,55 @@ Three kinds of file live here, and only the first two are generated:
| | |
|---|---|
| **Generated** | `scada-points.csv` and the three `wrps_*.qli` |
| **Generated** | `ci-server-points.csv` and the three `wrps_*.qli` |
| **Generators** | `gen_scada_points.py`, `gen_ciserver_qli.py` |
| **Hand-made** | `historian/` — no generator, and it has drifted. See its README. |
Deployed with `dssqld`, not by file copy — see `../QUICKLOAD.md`.
## Four namespaces, and which one is which
Getting these confused is the single most common mistake in this folder.
```
LIT-101 instrument tag the field device
%QW0 PLC symbol/address the register the PLC writes
WRPS_PLC:STN_LEVEL CI Server point Modbus station : point name
AID.WRPS.STN.LEVEL CI Server item what displays bind to, and what
the historian is keyed on
```
`ci-server-points.csv` carries all four, one row per point: `ci_item`,
`ci_station`, `ci_point`, `iec_address` and `plc_tag`.
**The historian is keyed on the item, and only the item.** Modbus carries register
numbers, not names, so the point layer and the item layer are free to differ — and
they do.
> [!WARNING]
> **`PS_*` is not one of these namespaces.**
> An earlier version of this file carried a `scada_tag` column with names like
> `PS_STN_WET_WELL_LEVEL`, derived from the PLC register map. **CI Server never
> adopted them.** They named nothing that exists, and they caused a real defect
> downstream when read as if they did.
>
> The **only** legitimate `PS_` names are the four Modbus **poll groups** in the
> `poll_group` column — `PS_STATUS_BITS`, `PS_PUBLISHED`, `PS_SETPOINTS`,
> `PS_SIM_CONTROL`. Those are live configuration.
>
> `ci-server-points.csv` is the as-built delivery from the CI Server side.
> `gen_scada_points.py` reproduces it byte-identically, taking the item names from
> the `LEAF` table in `gen_ciserver_qli.py` so the CSV and the `.qli` cannot
> disagree.
```bash
python gen_scada_points.py # register-map.csv -> scada-points.csv
python gen_ciserver_qli.py # scada-points.csv -> the two .qli files
python gen_scada_points.py # register-map.csv -> ci-server-points.csv
python gen_ciserver_qli.py # ci-server-points.csv -> the two .qli files
```
| File | What |
|---|---|
| `scada-points.csv` | The point list, for reading and for configuring by hand |
| `ci-server-points.csv` | The point list, keyed on the **CI Server item** each point feeds |
| `historian/` | Collection groups and 49 item bindings — **hand-made**, see its README |
| `wrps_section_df.qli` | `@SECTION_DF` — the six `AID.WRPS.*` sections |
| `wrps_modbus_point_df.qli` | `@MODBUS_POINT_DF` — 49 Modbus point definitions, station `WRPS_PLC` |
@ -29,7 +64,7 @@ python gen_ciserver_qli.py # scada-points.csv -> the two .qli files
**Import in that order.** CI Server derives its hierarchy from the dots in a name,
and a section must exist before an item can be created inside it.
The chain is ST sources → `03-plc/register-map.csv``scada-points.csv` → `.qli`,
The chain is ST sources → `03-plc/register-map.csv``ci-server-points.csv` → `.qli`,
so a register change propagates by re-running the scripts. **Nothing here is
hand-edited**; if CI Server needs a field the generators do not emit, it goes in
the generator.
@ -90,7 +125,7 @@ presentation choice, made here, as a pure gain on the raw register:
| `SP.MIN_SPEED` | % | 0.2 | same scale as `STN.SPEED`; **entered in %** |
The gains live in one place — `UNITS` in `gen_scada_points.py`. Change a unit
there and it propagates to `scada-points.csv`, to both `.qli` files and to the
there and it propagates to `ci-server-points.csv`, to both `.qli` files and to the
HMI masks.
> [!IMPORTANT]
@ -128,7 +163,7 @@ unsigned; see below.
## The point list
`gen_scada_points.py` reads `03-plc/register-map.csv` (the PLC-side list, itself
generated from the ST sources) and rewrites `scada-points.csv`. Re-run it after any
generated from the ST sources) and rewrites `ci-server-points.csv`. Re-run it after any
register change so the two sides cannot drift — that is the §3 invariant. Anything
changed by hand here is lost on the next run; if CI Server needs a field the script
does not emit, it goes in the generator.

View file

@ -0,0 +1,50 @@
ci_item,ci_station,ci_point,description,poll_group,function_code,modbus_address,data_type,access,eng_units,raw_to_eng,eng_gain,format_mask,iec_address,plc_tag,notes
AID.WRPS.PU301.RUN_CMD,WRPS_PLC,PU301_RUN_CMD,Run command,PS_STATUS_BITS,FC01,0,Boolean,Read,,value,1.0,99999,%QX0.0,PU-301,
AID.WRPS.PU302.RUN_CMD,WRPS_PLC,PU302_RUN_CMD,Run command,PS_STATUS_BITS,FC01,1,Boolean,Read,,value,1.0,99999,%QX0.1,PU-302,
AID.WRPS.PU303.RUN_CMD,WRPS_PLC,PU303_RUN_CMD,Run command,PS_STATUS_BITS,FC01,2,Boolean,Read,,value,1.0,99999,%QX0.2,PU-303,
AID.WRPS.PU301.RUNNING,WRPS_PLC,PU301_RUNNING,Running,PS_STATUS_BITS,FC01,3,Boolean,Read,,value,1.0,99999,%QX0.3,PU-301,
AID.WRPS.PU302.RUNNING,WRPS_PLC,PU302_RUNNING,Running,PS_STATUS_BITS,FC01,4,Boolean,Read,,value,1.0,99999,%QX0.4,PU-302,
AID.WRPS.PU303.RUNNING,WRPS_PLC,PU303_RUNNING,Running,PS_STATUS_BITS,FC01,5,Boolean,Read,,value,1.0,99999,%QX0.5,PU-303,
AID.WRPS.PU301.AVAILABLE,WRPS_PLC,PU301_AVAILABLE,Available,PS_STATUS_BITS,FC01,6,Boolean,Read,,value,1.0,99999,%QX0.6,PU-301,
AID.WRPS.PU302.AVAILABLE,WRPS_PLC,PU302_AVAILABLE,Available,PS_STATUS_BITS,FC01,7,Boolean,Read,,value,1.0,99999,%QX0.7,PU-302,
AID.WRPS.PU303.AVAILABLE,WRPS_PLC,PU303_AVAILABLE,Available,PS_STATUS_BITS,FC01,8,Boolean,Read,,value,1.0,99999,%QX1.0,PU-303,
AID.WRPS.STN.IN_AUTO,WRPS_PLC,STN_IN_AUTO,Station in auto,PS_STATUS_BITS,FC01,9,Boolean,Read,,value,1.0,99999,%QX1.1,STN,
AID.WRPS.STN.HIGH_LEVEL,WRPS_PLC,STN_HIGH_LEVEL,High level alarm,PS_STATUS_BITS,FC01,10,Boolean,Read,,value,1.0,99999,%QX1.2,STN,
AID.WRPS.STN.SPILL_ACTIVE,WRPS_PLC,STN_SPILL_ACTIVE,Spill active,PS_STATUS_BITS,FC01,11,Boolean,Read,,value,1.0,99999,%QX1.3,STN,
AID.WRPS.PU301.TRIPPED,WRPS_PLC,PU301_TRIPPED,Tripped,PS_STATUS_BITS,FC01,12,Boolean,Read,,value,1.0,99999,%QX1.4,PU-301,
AID.WRPS.PU302.TRIPPED,WRPS_PLC,PU302_TRIPPED,Tripped,PS_STATUS_BITS,FC01,13,Boolean,Read,,value,1.0,99999,%QX1.5,PU-302,
AID.WRPS.PU303.TRIPPED,WRPS_PLC,PU303_TRIPPED,Tripped,PS_STATUS_BITS,FC01,14,Boolean,Read,,value,1.0,99999,%QX1.6,PU-303,
AID.WRPS.STN.LEVEL,WRPS_PLC,STN_LEVEL,Wet well level,PS_PUBLISHED,FC03,0,Signed 16-bit,Read,%,value / 60,0.016666666666666666,999.9,%QW0,STN,
AID.WRPS.STN.INFLOW,WRPS_PLC,STN_INFLOW,Inflow,PS_PUBLISHED,FC03,1,Signed 16-bit,Read,m3/h,value * 0.36,0.36,9999.9,%QW1,STN,
AID.WRPS.STN.DISCHARGE,WRPS_PLC,STN_DISCHARGE,Total discharge flow,PS_PUBLISHED,FC03,2,Signed 16-bit,Read,m3/h,value * 0.36,0.36,9999.9,%QW2,STN,
AID.WRPS.STN.PUMPS_RUNNING,WRPS_PLC,STN_PUMPS_RUNNING,Pumps running,PS_PUBLISHED,FC03,3,Signed 16-bit,Read,count,value,1.0,9,%QW3,STN,
AID.WRPS.STN.SPEED,WRPS_PLC,STN_SPEED,Common drive speed,PS_PUBLISHED,FC03,4,Signed 16-bit,Read,%,value * 0.2,0.2,999.9,%QW4,STN,
AID.WRPS.STN.TIME_TO_SPILL,WRPS_PLC,STN_TIME_TO_SPILL,Time to spill weir (32767 = drawing down),PS_PUBLISHED,FC03,5,Signed 16-bit,Read,s,value,1.0,99999,%QW5,STN,
AID.WRPS.STN.TIME_TO_LSHH,WRPS_PLC,STN_TIME_TO_LSHH,Time to LSHH (32767 = drawing down),PS_PUBLISHED,FC03,6,Signed 16-bit,Read,s,value,1.0,99999,%QW6,STN,
AID.WRPS.STN.NET_ACCUM,WRPS_PLC,STN_NET_ACCUM,Net accumulation (signed),PS_PUBLISHED,FC03,7,Signed 16-bit,Read,m3/h,value * 0.36,0.36,9999.9,%QW7,STN,
AID.WRPS.PU301.RUN_HOURS,WRPS_PLC,PU301_RUN_HOURS,Run hours,PS_PUBLISHED,FC03,8,Signed 16-bit,Read,h,value,1.0,99999,%QW8,PU-301,
AID.WRPS.PU302.RUN_HOURS,WRPS_PLC,PU302_RUN_HOURS,Run hours,PS_PUBLISHED,FC03,9,Signed 16-bit,Read,h,value,1.0,99999,%QW9,PU-302,
AID.WRPS.PU303.RUN_HOURS,WRPS_PLC,PU303_RUN_HOURS,Run hours,PS_PUBLISHED,FC03,10,Signed 16-bit,Read,h,value,1.0,99999,%QW10,PU-303,
AID.WRPS.STN.VOL_TO_SPILL,WRPS_PLC,STN_VOL_TO_SPILL,Volume remaining to spill,PS_PUBLISHED,FC03,11,Signed 16-bit,Read,m3,value,1.0,9999,%QW11,STN,
AID.WRPS.STN.STATE,WRPS_PLC,STN_STATE,Station state (enum 3.1),PS_PUBLISHED,FC03,12,Signed 16-bit,Read,,value,1.0,9,%QW12,STN,
AID.WRPS.PU301.STATE,WRPS_PLC,PU301_STATE,Pump state (enum 3.2),PS_PUBLISHED,FC03,13,Signed 16-bit,Read,,value,1.0,9,%QW13,PU-301,
AID.WRPS.PU302.STATE,WRPS_PLC,PU302_STATE,Pump state (enum 3.2),PS_PUBLISHED,FC03,14,Signed 16-bit,Read,,value,1.0,9,%QW14,PU-302,
AID.WRPS.PU303.STATE,WRPS_PLC,PU303_STATE,Pump state (enum 3.2),PS_PUBLISHED,FC03,15,Signed 16-bit,Read,,value,1.0,9,%QW15,PU-303,
AID.WRPS.STN.DUTY_PUMP,WRPS_PLC,STN_DUTY_PUMP,"Current duty pump (0 = none, 1-3)",PS_PUBLISHED,FC03,16,Signed 16-bit,Read,,value,1.0,9,%QW16,STN,
AID.WRPS.STN.ALARM_WORD,WRPS_PLC,STN_ALARM_WORD,Alarm bitmask (section 6) - READ AS UNSIGNED,PS_PUBLISHED,FC03,17,Unsigned 16-bit,Read,,value,1.0,99999,%QW17,STN,
AID.WRPS.STN.CMD_ACK,WRPS_PLC,STN_CMD_ACK,Command acknowledge (echoes %MW1),PS_PUBLISHED,FC03,20,Signed 16-bit,Read,,value,1.0,99,%QW20,STN,
AID.WRPS.SP.MODE,WRPS_PLC,SP_MODE,"Station mode: 1 = auto, 2 = off",PS_SETPOINTS,FC03/FC06,1024,Signed 16-bit,Read/Write,,value,1.0,9,%MW0,STN,
AID.WRPS.SP.CMD_WORD,WRPS_PLC,SP_CMD_WORD,Command word (section 3.3),PS_SETPOINTS,FC03/FC06,1025,Signed 16-bit,Read/Write,,value,1.0,99,%MW1,STN,
AID.WRPS.SP.CMD_PARAM,WRPS_PLC,SP_CMD_PARAM,Command parameter (pump number),PS_SETPOINTS,FC03/FC06,1026,Signed 16-bit,Read/Write,,value,1.0,9,%MW2,STN,
AID.WRPS.SP.LEVEL_SP,WRPS_PLC,SP_LEVEL_SP,Level control setpoint,PS_SETPOINTS,FC03/FC06,1027,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW3,STN,
AID.WRPS.SP.START_DUTY,WRPS_PLC,SP_START_DUTY,Start duty level,PS_SETPOINTS,FC03/FC06,1028,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW4,STN,
AID.WRPS.SP.START_P2,WRPS_PLC,SP_START_P2,Start pump 2 level,PS_SETPOINTS,FC03/FC06,1029,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW5,STN,
AID.WRPS.SP.START_P3,WRPS_PLC,SP_START_P3,Start pump 3 level,PS_SETPOINTS,FC03/FC06,1030,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW6,STN,
AID.WRPS.SP.STOP_ALL,WRPS_PLC,SP_STOP_ALL,Stop all level,PS_SETPOINTS,FC03/FC06,1031,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW7,STN,
AID.WRPS.SP.HIGH_ALARM,WRPS_PLC,SP_HIGH_ALARM,High level alarm,PS_SETPOINTS,FC03/FC06,1032,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW8,STN,
AID.WRPS.SP.MIN_SPEED,WRPS_PLC,SP_MIN_SPEED,Minimum drive speed,PS_SETPOINTS,FC03/FC06,1033,Signed 16-bit,Read/Write,%,value * 0.2,0.2,999.9,%MW9,STN,
AID.WRPS.SP.SERVICE_HRS,WRPS_PLC,SP_SERVICE_HRS,Service interval,PS_SETPOINTS,FC03/FC06,1034,Signed 16-bit,Read/Write,h,value,1.0,99999,%MW10,STN,
AID.WRPS.SIM.INFLOW,WRPS_PLC,SIM_INFLOW,manual inflow (mode 0),PS_SIM_CONTROL,FC03/FC06,1044,Signed 16-bit,Read/Write,m3/h,value * 0.36,0.36,9999.9,%MW20,SIM,SIMULATION CONTROL - simulation build only
AID.WRPS.SIM.SCENARIO,WRPS_PLC,SIM_SCENARIO,scenario 0=man 1=diurnal 2=wet 3=ref,PS_SIM_CONTROL,FC03/FC06,1045,Signed 16-bit,Read/Write,,value,1.0,9,%MW21,SIM,SIMULATION CONTROL - simulation build only
AID.WRPS.SIM.RESET,WRPS_PLC,SIM_RESET,"write 1 to reset scenario, self-clearing",PS_SIM_CONTROL,FC03/FC06,1046,Signed 16-bit,Read/Write,,value,1.0,9,%MW22,SIM,SIMULATION CONTROL - simulation build only
AID.WRPS.SIM.TIME_SCALE,WRPS_PLC,SIM_TIME_SCALE,time scale 1-120,PS_SIM_CONTROL,FC03/FC06,1047,Signed 16-bit,Read/Write,x,value,1.0,999,%MW23,SIM,SIMULATION CONTROL - simulation build only
1 ci_item ci_station ci_point description poll_group function_code modbus_address data_type access eng_units raw_to_eng eng_gain format_mask iec_address plc_tag notes
2 AID.WRPS.PU301.RUN_CMD WRPS_PLC PU301_RUN_CMD Run command PS_STATUS_BITS FC01 0 Boolean Read value 1.0 99999 %QX0.0 PU-301
3 AID.WRPS.PU302.RUN_CMD WRPS_PLC PU302_RUN_CMD Run command PS_STATUS_BITS FC01 1 Boolean Read value 1.0 99999 %QX0.1 PU-302
4 AID.WRPS.PU303.RUN_CMD WRPS_PLC PU303_RUN_CMD Run command PS_STATUS_BITS FC01 2 Boolean Read value 1.0 99999 %QX0.2 PU-303
5 AID.WRPS.PU301.RUNNING WRPS_PLC PU301_RUNNING Running PS_STATUS_BITS FC01 3 Boolean Read value 1.0 99999 %QX0.3 PU-301
6 AID.WRPS.PU302.RUNNING WRPS_PLC PU302_RUNNING Running PS_STATUS_BITS FC01 4 Boolean Read value 1.0 99999 %QX0.4 PU-302
7 AID.WRPS.PU303.RUNNING WRPS_PLC PU303_RUNNING Running PS_STATUS_BITS FC01 5 Boolean Read value 1.0 99999 %QX0.5 PU-303
8 AID.WRPS.PU301.AVAILABLE WRPS_PLC PU301_AVAILABLE Available PS_STATUS_BITS FC01 6 Boolean Read value 1.0 99999 %QX0.6 PU-301
9 AID.WRPS.PU302.AVAILABLE WRPS_PLC PU302_AVAILABLE Available PS_STATUS_BITS FC01 7 Boolean Read value 1.0 99999 %QX0.7 PU-302
10 AID.WRPS.PU303.AVAILABLE WRPS_PLC PU303_AVAILABLE Available PS_STATUS_BITS FC01 8 Boolean Read value 1.0 99999 %QX1.0 PU-303
11 AID.WRPS.STN.IN_AUTO WRPS_PLC STN_IN_AUTO Station in auto PS_STATUS_BITS FC01 9 Boolean Read value 1.0 99999 %QX1.1 STN
12 AID.WRPS.STN.HIGH_LEVEL WRPS_PLC STN_HIGH_LEVEL High level alarm PS_STATUS_BITS FC01 10 Boolean Read value 1.0 99999 %QX1.2 STN
13 AID.WRPS.STN.SPILL_ACTIVE WRPS_PLC STN_SPILL_ACTIVE Spill active PS_STATUS_BITS FC01 11 Boolean Read value 1.0 99999 %QX1.3 STN
14 AID.WRPS.PU301.TRIPPED WRPS_PLC PU301_TRIPPED Tripped PS_STATUS_BITS FC01 12 Boolean Read value 1.0 99999 %QX1.4 PU-301
15 AID.WRPS.PU302.TRIPPED WRPS_PLC PU302_TRIPPED Tripped PS_STATUS_BITS FC01 13 Boolean Read value 1.0 99999 %QX1.5 PU-302
16 AID.WRPS.PU303.TRIPPED WRPS_PLC PU303_TRIPPED Tripped PS_STATUS_BITS FC01 14 Boolean Read value 1.0 99999 %QX1.6 PU-303
17 AID.WRPS.STN.LEVEL WRPS_PLC STN_LEVEL Wet well level PS_PUBLISHED FC03 0 Signed 16-bit Read % value / 60 0.016666666666666666 999.9 %QW0 STN
18 AID.WRPS.STN.INFLOW WRPS_PLC STN_INFLOW Inflow PS_PUBLISHED FC03 1 Signed 16-bit Read m3/h value * 0.36 0.36 9999.9 %QW1 STN
19 AID.WRPS.STN.DISCHARGE WRPS_PLC STN_DISCHARGE Total discharge flow PS_PUBLISHED FC03 2 Signed 16-bit Read m3/h value * 0.36 0.36 9999.9 %QW2 STN
20 AID.WRPS.STN.PUMPS_RUNNING WRPS_PLC STN_PUMPS_RUNNING Pumps running PS_PUBLISHED FC03 3 Signed 16-bit Read count value 1.0 9 %QW3 STN
21 AID.WRPS.STN.SPEED WRPS_PLC STN_SPEED Common drive speed PS_PUBLISHED FC03 4 Signed 16-bit Read % value * 0.2 0.2 999.9 %QW4 STN
22 AID.WRPS.STN.TIME_TO_SPILL WRPS_PLC STN_TIME_TO_SPILL Time to spill weir (32767 = drawing down) PS_PUBLISHED FC03 5 Signed 16-bit Read s value 1.0 99999 %QW5 STN
23 AID.WRPS.STN.TIME_TO_LSHH WRPS_PLC STN_TIME_TO_LSHH Time to LSHH (32767 = drawing down) PS_PUBLISHED FC03 6 Signed 16-bit Read s value 1.0 99999 %QW6 STN
24 AID.WRPS.STN.NET_ACCUM WRPS_PLC STN_NET_ACCUM Net accumulation (signed) PS_PUBLISHED FC03 7 Signed 16-bit Read m3/h value * 0.36 0.36 9999.9 %QW7 STN
25 AID.WRPS.PU301.RUN_HOURS WRPS_PLC PU301_RUN_HOURS Run hours PS_PUBLISHED FC03 8 Signed 16-bit Read h value 1.0 99999 %QW8 PU-301
26 AID.WRPS.PU302.RUN_HOURS WRPS_PLC PU302_RUN_HOURS Run hours PS_PUBLISHED FC03 9 Signed 16-bit Read h value 1.0 99999 %QW9 PU-302
27 AID.WRPS.PU303.RUN_HOURS WRPS_PLC PU303_RUN_HOURS Run hours PS_PUBLISHED FC03 10 Signed 16-bit Read h value 1.0 99999 %QW10 PU-303
28 AID.WRPS.STN.VOL_TO_SPILL WRPS_PLC STN_VOL_TO_SPILL Volume remaining to spill PS_PUBLISHED FC03 11 Signed 16-bit Read m3 value 1.0 9999 %QW11 STN
29 AID.WRPS.STN.STATE WRPS_PLC STN_STATE Station state (enum 3.1) PS_PUBLISHED FC03 12 Signed 16-bit Read value 1.0 9 %QW12 STN
30 AID.WRPS.PU301.STATE WRPS_PLC PU301_STATE Pump state (enum 3.2) PS_PUBLISHED FC03 13 Signed 16-bit Read value 1.0 9 %QW13 PU-301
31 AID.WRPS.PU302.STATE WRPS_PLC PU302_STATE Pump state (enum 3.2) PS_PUBLISHED FC03 14 Signed 16-bit Read value 1.0 9 %QW14 PU-302
32 AID.WRPS.PU303.STATE WRPS_PLC PU303_STATE Pump state (enum 3.2) PS_PUBLISHED FC03 15 Signed 16-bit Read value 1.0 9 %QW15 PU-303
33 AID.WRPS.STN.DUTY_PUMP WRPS_PLC STN_DUTY_PUMP Current duty pump (0 = none, 1-3) PS_PUBLISHED FC03 16 Signed 16-bit Read value 1.0 9 %QW16 STN
34 AID.WRPS.STN.ALARM_WORD WRPS_PLC STN_ALARM_WORD Alarm bitmask (section 6) - READ AS UNSIGNED PS_PUBLISHED FC03 17 Unsigned 16-bit Read value 1.0 99999 %QW17 STN
35 AID.WRPS.STN.CMD_ACK WRPS_PLC STN_CMD_ACK Command acknowledge (echoes %MW1) PS_PUBLISHED FC03 20 Signed 16-bit Read value 1.0 99 %QW20 STN
36 AID.WRPS.SP.MODE WRPS_PLC SP_MODE Station mode: 1 = auto, 2 = off PS_SETPOINTS FC03/FC06 1024 Signed 16-bit Read/Write value 1.0 9 %MW0 STN
37 AID.WRPS.SP.CMD_WORD WRPS_PLC SP_CMD_WORD Command word (section 3.3) PS_SETPOINTS FC03/FC06 1025 Signed 16-bit Read/Write value 1.0 99 %MW1 STN
38 AID.WRPS.SP.CMD_PARAM WRPS_PLC SP_CMD_PARAM Command parameter (pump number) PS_SETPOINTS FC03/FC06 1026 Signed 16-bit Read/Write value 1.0 9 %MW2 STN
39 AID.WRPS.SP.LEVEL_SP WRPS_PLC SP_LEVEL_SP Level control setpoint PS_SETPOINTS FC03/FC06 1027 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW3 STN
40 AID.WRPS.SP.START_DUTY WRPS_PLC SP_START_DUTY Start duty level PS_SETPOINTS FC03/FC06 1028 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW4 STN
41 AID.WRPS.SP.START_P2 WRPS_PLC SP_START_P2 Start pump 2 level PS_SETPOINTS FC03/FC06 1029 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW5 STN
42 AID.WRPS.SP.START_P3 WRPS_PLC SP_START_P3 Start pump 3 level PS_SETPOINTS FC03/FC06 1030 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW6 STN
43 AID.WRPS.SP.STOP_ALL WRPS_PLC SP_STOP_ALL Stop all level PS_SETPOINTS FC03/FC06 1031 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW7 STN
44 AID.WRPS.SP.HIGH_ALARM WRPS_PLC SP_HIGH_ALARM High level alarm PS_SETPOINTS FC03/FC06 1032 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW8 STN
45 AID.WRPS.SP.MIN_SPEED WRPS_PLC SP_MIN_SPEED Minimum drive speed PS_SETPOINTS FC03/FC06 1033 Signed 16-bit Read/Write % value * 0.2 0.2 999.9 %MW9 STN
46 AID.WRPS.SP.SERVICE_HRS WRPS_PLC SP_SERVICE_HRS Service interval PS_SETPOINTS FC03/FC06 1034 Signed 16-bit Read/Write h value 1.0 99999 %MW10 STN
47 AID.WRPS.SIM.INFLOW WRPS_PLC SIM_INFLOW manual inflow (mode 0) PS_SIM_CONTROL FC03/FC06 1044 Signed 16-bit Read/Write m3/h value * 0.36 0.36 9999.9 %MW20 SIM SIMULATION CONTROL - simulation build only
48 AID.WRPS.SIM.SCENARIO WRPS_PLC SIM_SCENARIO scenario 0=man 1=diurnal 2=wet 3=ref PS_SIM_CONTROL FC03/FC06 1045 Signed 16-bit Read/Write value 1.0 9 %MW21 SIM SIMULATION CONTROL - simulation build only
49 AID.WRPS.SIM.RESET WRPS_PLC SIM_RESET write 1 to reset scenario, self-clearing PS_SIM_CONTROL FC03/FC06 1046 Signed 16-bit Read/Write value 1.0 9 %MW22 SIM SIMULATION CONTROL - simulation build only
50 AID.WRPS.SIM.TIME_SCALE WRPS_PLC SIM_TIME_SCALE time scale 1-120 PS_SIM_CONTROL FC03/FC06 1047 Signed 16-bit Read/Write x value 1.0 999 %MW23 SIM SIMULATION CONTROL - simulation build only

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""Emit CI Server .qli imports for the WRPS points.
python gen_scada_points.py # first: refresh scada-points.csv
python gen_scada_points.py # first: refresh ci-server-points.csv
python gen_ciserver_qli.py
Writes, alongside this script:
@ -13,7 +13,7 @@ Writes, alongside this script:
Import them in that order: CI Server derives its hierarchy from the dots
in a name, and a section must exist before an item can be created in it.
The chain is ST sources -> 03-plc/register-map.csv -> scada-points.csv ->
The chain is ST sources -> 03-plc/register-map.csv -> ci-server-points.csv ->
these files, so a register change propagates by re-running the three
scripts rather than by hand-editing anything.
@ -48,7 +48,7 @@ import sys
from pathlib import Path
HERE = Path(__file__).resolve().parent
POINTS = HERE / "scada-points.csv"
POINTS = HERE / "ci-server-points.csv"
STATION = "WRPS_PLC"
ROOT = "AID.WRPS"
@ -331,7 +331,7 @@ def main():
args = ap.parse_args()
if not POINTS.is_file():
sys.exit("missing scada-points.csv - run gen_scada_points.py first")
sys.exit("missing ci-server-points.csv - run gen_scada_points.py first")
pinned = {}
for spec in args.section_nsid:

View file

@ -4,7 +4,7 @@
python gen_scada_points.py
Reads ../../03-plc/register-map.csv (PLC side, generated by build.py)
Writes ./scada-points.csv (SCADA side, for CI Server config)
Writes ./ci-server-points.csv (SCADA side, for CI Server config)
CLAUDE.md section 3: the two sides are two views of the same points, and
the PLC side leads. This script makes the SCADA view reproducible
@ -48,7 +48,7 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
SRC_MAP = ROOT / "03-plc" / "register-map.csv"
OUT = Path(__file__).resolve().parent / "scada-points.csv"
OUT = Path(__file__).resolve().parent / "ci-server-points.csv"
# Modbus object -> (function code, poll group name)
#
@ -165,17 +165,31 @@ def gain_expr(gain):
return "value * %g" % gain
def tag_for(row, description):
"""Tag name per CLAUDE.md section 8: PS_<EQUIP><NN>_<MEAS>.
# The CI Server naming, imported from the .qli generator so the two files
# cannot disagree. LEAF is keyed on IEC address and is the single place
# section/leaf names are defined.
#
# An earlier version of this script emitted a `scada_tag` column holding
# names like PS_STN_WET_WELL_LEVEL, derived from the PLC register map.
# **CI Server never adopted them.** They named nothing that exists, and
# they caused a real defect downstream when read as if they did. The only
# legitimate PS_ names are the four Modbus POLL GROUPS below, which are
# live configuration.
sys.path.insert(0, str(Path(__file__).resolve().parent))
from gen_ciserver_qli import LEAF, ROOT, STATION
Built from the cleaned description, so the "SIM ONLY:" marker does
not end up inside the tag name.
def ci_names(iec):
"""(item, station, point) - the three CI Server namespaces.
AID.WRPS.STN.LEVEL item what the historian is keyed on
WRPS_PLC station the Modbus station
STN_LEVEL point the Modbus point on that station
"""
equip = row["tag"].replace("-", "")
meas = description.split("(")[0].split(",")[0].strip()
meas = "".join(ch if ch.isalnum() else "_" for ch in meas)
meas = "_".join(p for p in meas.split("_") if p)[:28].upper()
return f"PS_{equip}_{meas}".upper()
if iec not in LEAF:
sys.exit(f"no leaf name defined for {iec} - add it to LEAF in gen_ciserver_qli.py")
section, leaf = LEAF[iec]
return (f"{ROOT}.{section}.{leaf}", STATION, ("%s_%s" % (section, leaf))[:24])
def main():
@ -225,7 +239,9 @@ def main():
out_rows.append(
{
"scada_tag": tag_for(r, description),
"ci_item": ci_names(iec)[0],
"ci_station": ci_names(iec)[1],
"ci_point": ci_names(iec)[2],
"description": description,
"poll_group": group,
"function_code": fc,

View file

@ -9,12 +9,30 @@ not, and that is the reason they have drifted from the server.
| `his_group.qli` | `@HIS_GROUP_DF` | 3 collection groups |
| `item_his.qli` | `@ITEM_HIS_DF` | 49 item → group bindings |
## The three groups
## ⚠️ These files are the INTENDED rates. The server runs different ones.
| Group | Items | Collection |
> **Resolved 2026-09-02.** The question of which was correct is now answered:
> `../../ciserver-backup-2026-08/export_his_group.qli`, taken from the running
> server, is what the historian actually did. **The live export wins.**
| | `his_group.qli` says | The running server does |
|---|---|---|
| `WRPS_ONE_SEC` | 5 | 1 s scan — the fast analogues: level, inflow, discharge |
| `WRPS_ONE_MIN` | 4 | 1 min scan — slower trends |
| Fast group | `WRPS_ONE_SEC` at **1 second** | `WRPS_ONE_SEC` at **5 seconds** |
| Second group | `WRPS_ONE_MIN` at **60 seconds** | `WRPS_THIRTY_SEC` at **30 seconds** |
| Event group | `WRPS_EVENT`, on change | `WRPS_EVENT`, on change ✅ |
> [!CAUTION]
> **Never hardcode a sample interval from these files.** Anything assuming
> `WRPS_ONE_MIN` at 60 seconds is wrong by **twelvefold** against a group that is
> actually running at 5 seconds. This has already produced a real defect in a
> downstream project. Read the interval from the item's own configuration.
## The three groups as written here (intended, not live)
| Group | Items | Intended collection |
|---|---|---|
| `WRPS_ONE_SEC` | 5 | 1 s — the fast analogues: level, inflow, discharge |
| `WRPS_ONE_MIN` | 4 | 1 min — slower trends |
| `WRPS_EVENT` | 40 | on change — states, commands, alarms, trips |
Written 2026-08-21.
@ -31,25 +49,16 @@ and headroom — works from live values alone. The push-back that earns trust do
not. **Without these two files there is no historian, and the demo loses the layer
it was designed around.**
## ⚠️ These files disagree with the server
## Why they disagree
`ciserver-backup-2026-08/export_his_group.qli`, exported from CI Server around
2026-08-20, contains groups that `his_group.qli` does not define:
These files are the *source project's* intent. The server was tuned afterwards and
nobody brought the change back. That is the predictable cost of the one link in
this chain with no generator: the points and items cannot drift because they are
regenerated; the historian can, and did.
| In the CI Server export | In `his_group.qli` |
|---|---|
| `WRPS_EVENT` | ✅ |
| `WRPS_ONE_SEC` | ✅ |
| `WRPS_THIRTY_SEC` | ❌ not defined here |
| `WRPS_ONE_MIN` | — not in the export |
| `FIVE_SECONDS` (binding `STN.LEVEL`, `STN.INFLOW`) | ❌ not a WRPS group at all |
**Nobody currently knows which is right.** The export is dated a day before these
files, but contains groups they do not. Resolve it by exporting from `cicore1` and
comparing — see `../../QUICKLOAD.md`.
Until then: **do not import these files onto a working server** without checking
what is already there. You may remove a group something depends on.
Before importing these onto a working server, **export what is there first**
(`../../QUICKLOAD.md`) and compare. Importing blind may remove a group something
depends on.
## Worth doing: generate these too

View file

@ -1,50 +0,0 @@
scada_tag,description,poll_group,function_code,modbus_address,data_type,access,eng_units,raw_to_eng,eng_gain,format_mask,iec_address,plc_tag,notes
PS_PU301_RUN_COMMAND,Run command,PS_STATUS_BITS,FC01,0,Boolean,Read,,value,1.0,99999,%QX0.0,PU-301,
PS_PU302_RUN_COMMAND,Run command,PS_STATUS_BITS,FC01,1,Boolean,Read,,value,1.0,99999,%QX0.1,PU-302,
PS_PU303_RUN_COMMAND,Run command,PS_STATUS_BITS,FC01,2,Boolean,Read,,value,1.0,99999,%QX0.2,PU-303,
PS_PU301_RUNNING,Running,PS_STATUS_BITS,FC01,3,Boolean,Read,,value,1.0,99999,%QX0.3,PU-301,
PS_PU302_RUNNING,Running,PS_STATUS_BITS,FC01,4,Boolean,Read,,value,1.0,99999,%QX0.4,PU-302,
PS_PU303_RUNNING,Running,PS_STATUS_BITS,FC01,5,Boolean,Read,,value,1.0,99999,%QX0.5,PU-303,
PS_PU301_AVAILABLE,Available,PS_STATUS_BITS,FC01,6,Boolean,Read,,value,1.0,99999,%QX0.6,PU-301,
PS_PU302_AVAILABLE,Available,PS_STATUS_BITS,FC01,7,Boolean,Read,,value,1.0,99999,%QX0.7,PU-302,
PS_PU303_AVAILABLE,Available,PS_STATUS_BITS,FC01,8,Boolean,Read,,value,1.0,99999,%QX1.0,PU-303,
PS_STN_STATION_IN_AUTO,Station in auto,PS_STATUS_BITS,FC01,9,Boolean,Read,,value,1.0,99999,%QX1.1,STN,
PS_STN_HIGH_LEVEL_ALARM,High level alarm,PS_STATUS_BITS,FC01,10,Boolean,Read,,value,1.0,99999,%QX1.2,STN,
PS_STN_SPILL_ACTIVE,Spill active,PS_STATUS_BITS,FC01,11,Boolean,Read,,value,1.0,99999,%QX1.3,STN,
PS_PU301_TRIPPED,Tripped,PS_STATUS_BITS,FC01,12,Boolean,Read,,value,1.0,99999,%QX1.4,PU-301,
PS_PU302_TRIPPED,Tripped,PS_STATUS_BITS,FC01,13,Boolean,Read,,value,1.0,99999,%QX1.5,PU-302,
PS_PU303_TRIPPED,Tripped,PS_STATUS_BITS,FC01,14,Boolean,Read,,value,1.0,99999,%QX1.6,PU-303,
PS_STN_WET_WELL_LEVEL,Wet well level,PS_PUBLISHED,FC03,0,Signed 16-bit,Read,%,value / 60,0.016666666666666666,999.9,%QW0,STN,
PS_STN_INFLOW,Inflow,PS_PUBLISHED,FC03,1,Signed 16-bit,Read,m3/h,value * 0.36,0.36,9999.9,%QW1,STN,
PS_STN_TOTAL_DISCHARGE_FLOW,Total discharge flow,PS_PUBLISHED,FC03,2,Signed 16-bit,Read,m3/h,value * 0.36,0.36,9999.9,%QW2,STN,
PS_STN_PUMPS_RUNNING,Pumps running,PS_PUBLISHED,FC03,3,Signed 16-bit,Read,count,value,1.0,9,%QW3,STN,
PS_STN_COMMON_DRIVE_SPEED,Common drive speed,PS_PUBLISHED,FC03,4,Signed 16-bit,Read,%,value * 0.2,0.2,999.9,%QW4,STN,
PS_STN_TIME_TO_SPILL_WEIR,Time to spill weir (32767 = drawing down),PS_PUBLISHED,FC03,5,Signed 16-bit,Read,s,value,1.0,99999,%QW5,STN,
PS_STN_TIME_TO_LSHH,Time to LSHH (32767 = drawing down),PS_PUBLISHED,FC03,6,Signed 16-bit,Read,s,value,1.0,99999,%QW6,STN,
PS_STN_NET_ACCUMULATION,Net accumulation (signed),PS_PUBLISHED,FC03,7,Signed 16-bit,Read,m3/h,value * 0.36,0.36,9999.9,%QW7,STN,
PS_PU301_RUN_HOURS,Run hours,PS_PUBLISHED,FC03,8,Signed 16-bit,Read,h,value,1.0,99999,%QW8,PU-301,
PS_PU302_RUN_HOURS,Run hours,PS_PUBLISHED,FC03,9,Signed 16-bit,Read,h,value,1.0,99999,%QW9,PU-302,
PS_PU303_RUN_HOURS,Run hours,PS_PUBLISHED,FC03,10,Signed 16-bit,Read,h,value,1.0,99999,%QW10,PU-303,
PS_STN_VOLUME_REMAINING_TO_SPILL,Volume remaining to spill,PS_PUBLISHED,FC03,11,Signed 16-bit,Read,m3,value,1.0,9999,%QW11,STN,
PS_STN_STATION_STATE,Station state (enum 3.1),PS_PUBLISHED,FC03,12,Signed 16-bit,Read,,value,1.0,9,%QW12,STN,
PS_PU301_PUMP_STATE,Pump state (enum 3.2),PS_PUBLISHED,FC03,13,Signed 16-bit,Read,,value,1.0,9,%QW13,PU-301,
PS_PU302_PUMP_STATE,Pump state (enum 3.2),PS_PUBLISHED,FC03,14,Signed 16-bit,Read,,value,1.0,9,%QW14,PU-302,
PS_PU303_PUMP_STATE,Pump state (enum 3.2),PS_PUBLISHED,FC03,15,Signed 16-bit,Read,,value,1.0,9,%QW15,PU-303,
PS_STN_CURRENT_DUTY_PUMP,"Current duty pump (0 = none, 1-3)",PS_PUBLISHED,FC03,16,Signed 16-bit,Read,,value,1.0,9,%QW16,STN,
PS_STN_ALARM_BITMASK,Alarm bitmask (section 6) - READ AS UNSIGNED,PS_PUBLISHED,FC03,17,Unsigned 16-bit,Read,,value,1.0,99999,%QW17,STN,
PS_STN_COMMAND_ACKNOWLEDGE,Command acknowledge (echoes %MW1),PS_PUBLISHED,FC03,20,Signed 16-bit,Read,,value,1.0,99,%QW20,STN,
PS_STN_STATION_MODE_1_AUTO,"Station mode: 1 = auto, 2 = off",PS_SETPOINTS,FC03/FC06,1024,Signed 16-bit,Read/Write,,value,1.0,9,%MW0,STN,
PS_STN_COMMAND_WORD,Command word (section 3.3),PS_SETPOINTS,FC03/FC06,1025,Signed 16-bit,Read/Write,,value,1.0,99,%MW1,STN,
PS_STN_COMMAND_PARAMETER,Command parameter (pump number),PS_SETPOINTS,FC03/FC06,1026,Signed 16-bit,Read/Write,,value,1.0,9,%MW2,STN,
PS_STN_LEVEL_CONTROL_SETPOINT,Level control setpoint,PS_SETPOINTS,FC03/FC06,1027,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW3,STN,
PS_STN_START_DUTY_LEVEL,Start duty level,PS_SETPOINTS,FC03/FC06,1028,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW4,STN,
PS_STN_START_PUMP_2_LEVEL,Start pump 2 level,PS_SETPOINTS,FC03/FC06,1029,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW5,STN,
PS_STN_START_PUMP_3_LEVEL,Start pump 3 level,PS_SETPOINTS,FC03/FC06,1030,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW6,STN,
PS_STN_STOP_ALL_LEVEL,Stop all level,PS_SETPOINTS,FC03/FC06,1031,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW7,STN,
PS_STN_HIGH_LEVEL_ALARM,High level alarm,PS_SETPOINTS,FC03/FC06,1032,Signed 16-bit,Read/Write,%,value / 60,0.016666666666666666,999.9,%MW8,STN,
PS_STN_MINIMUM_DRIVE_SPEED,Minimum drive speed,PS_SETPOINTS,FC03/FC06,1033,Signed 16-bit,Read/Write,%,value * 0.2,0.2,999.9,%MW9,STN,
PS_STN_SERVICE_INTERVAL,Service interval,PS_SETPOINTS,FC03/FC06,1034,Signed 16-bit,Read/Write,h,value,1.0,99999,%MW10,STN,
PS_SIM_MANUAL_INFLOW,manual inflow (mode 0),PS_SIM_CONTROL,FC03/FC06,1044,Signed 16-bit,Read/Write,m3/h,value * 0.36,0.36,9999.9,%MW20,SIM,SIMULATION CONTROL - simulation build only
PS_SIM_SCENARIO_0_MAN_1_DIURNAL_2_W,scenario 0=man 1=diurnal 2=wet 3=ref,PS_SIM_CONTROL,FC03/FC06,1045,Signed 16-bit,Read/Write,,value,1.0,9,%MW21,SIM,SIMULATION CONTROL - simulation build only
PS_SIM_WRITE_1_TO_RESET_SCENARIO,"write 1 to reset scenario, self-clearing",PS_SIM_CONTROL,FC03/FC06,1046,Signed 16-bit,Read/Write,,value,1.0,9,%MW22,SIM,SIMULATION CONTROL - simulation build only
PS_SIM_TIME_SCALE_1_120,time scale 1-120,PS_SIM_CONTROL,FC03/FC06,1047,Signed 16-bit,Read/Write,x,value,1.0,999,%MW23,SIM,SIMULATION CONTROL - simulation build only
1 scada_tag description poll_group function_code modbus_address data_type access eng_units raw_to_eng eng_gain format_mask iec_address plc_tag notes
2 PS_PU301_RUN_COMMAND Run command PS_STATUS_BITS FC01 0 Boolean Read value 1.0 99999 %QX0.0 PU-301
3 PS_PU302_RUN_COMMAND Run command PS_STATUS_BITS FC01 1 Boolean Read value 1.0 99999 %QX0.1 PU-302
4 PS_PU303_RUN_COMMAND Run command PS_STATUS_BITS FC01 2 Boolean Read value 1.0 99999 %QX0.2 PU-303
5 PS_PU301_RUNNING Running PS_STATUS_BITS FC01 3 Boolean Read value 1.0 99999 %QX0.3 PU-301
6 PS_PU302_RUNNING Running PS_STATUS_BITS FC01 4 Boolean Read value 1.0 99999 %QX0.4 PU-302
7 PS_PU303_RUNNING Running PS_STATUS_BITS FC01 5 Boolean Read value 1.0 99999 %QX0.5 PU-303
8 PS_PU301_AVAILABLE Available PS_STATUS_BITS FC01 6 Boolean Read value 1.0 99999 %QX0.6 PU-301
9 PS_PU302_AVAILABLE Available PS_STATUS_BITS FC01 7 Boolean Read value 1.0 99999 %QX0.7 PU-302
10 PS_PU303_AVAILABLE Available PS_STATUS_BITS FC01 8 Boolean Read value 1.0 99999 %QX1.0 PU-303
11 PS_STN_STATION_IN_AUTO Station in auto PS_STATUS_BITS FC01 9 Boolean Read value 1.0 99999 %QX1.1 STN
12 PS_STN_HIGH_LEVEL_ALARM High level alarm PS_STATUS_BITS FC01 10 Boolean Read value 1.0 99999 %QX1.2 STN
13 PS_STN_SPILL_ACTIVE Spill active PS_STATUS_BITS FC01 11 Boolean Read value 1.0 99999 %QX1.3 STN
14 PS_PU301_TRIPPED Tripped PS_STATUS_BITS FC01 12 Boolean Read value 1.0 99999 %QX1.4 PU-301
15 PS_PU302_TRIPPED Tripped PS_STATUS_BITS FC01 13 Boolean Read value 1.0 99999 %QX1.5 PU-302
16 PS_PU303_TRIPPED Tripped PS_STATUS_BITS FC01 14 Boolean Read value 1.0 99999 %QX1.6 PU-303
17 PS_STN_WET_WELL_LEVEL Wet well level PS_PUBLISHED FC03 0 Signed 16-bit Read % value / 60 0.016666666666666666 999.9 %QW0 STN
18 PS_STN_INFLOW Inflow PS_PUBLISHED FC03 1 Signed 16-bit Read m3/h value * 0.36 0.36 9999.9 %QW1 STN
19 PS_STN_TOTAL_DISCHARGE_FLOW Total discharge flow PS_PUBLISHED FC03 2 Signed 16-bit Read m3/h value * 0.36 0.36 9999.9 %QW2 STN
20 PS_STN_PUMPS_RUNNING Pumps running PS_PUBLISHED FC03 3 Signed 16-bit Read count value 1.0 9 %QW3 STN
21 PS_STN_COMMON_DRIVE_SPEED Common drive speed PS_PUBLISHED FC03 4 Signed 16-bit Read % value * 0.2 0.2 999.9 %QW4 STN
22 PS_STN_TIME_TO_SPILL_WEIR Time to spill weir (32767 = drawing down) PS_PUBLISHED FC03 5 Signed 16-bit Read s value 1.0 99999 %QW5 STN
23 PS_STN_TIME_TO_LSHH Time to LSHH (32767 = drawing down) PS_PUBLISHED FC03 6 Signed 16-bit Read s value 1.0 99999 %QW6 STN
24 PS_STN_NET_ACCUMULATION Net accumulation (signed) PS_PUBLISHED FC03 7 Signed 16-bit Read m3/h value * 0.36 0.36 9999.9 %QW7 STN
25 PS_PU301_RUN_HOURS Run hours PS_PUBLISHED FC03 8 Signed 16-bit Read h value 1.0 99999 %QW8 PU-301
26 PS_PU302_RUN_HOURS Run hours PS_PUBLISHED FC03 9 Signed 16-bit Read h value 1.0 99999 %QW9 PU-302
27 PS_PU303_RUN_HOURS Run hours PS_PUBLISHED FC03 10 Signed 16-bit Read h value 1.0 99999 %QW10 PU-303
28 PS_STN_VOLUME_REMAINING_TO_SPILL Volume remaining to spill PS_PUBLISHED FC03 11 Signed 16-bit Read m3 value 1.0 9999 %QW11 STN
29 PS_STN_STATION_STATE Station state (enum 3.1) PS_PUBLISHED FC03 12 Signed 16-bit Read value 1.0 9 %QW12 STN
30 PS_PU301_PUMP_STATE Pump state (enum 3.2) PS_PUBLISHED FC03 13 Signed 16-bit Read value 1.0 9 %QW13 PU-301
31 PS_PU302_PUMP_STATE Pump state (enum 3.2) PS_PUBLISHED FC03 14 Signed 16-bit Read value 1.0 9 %QW14 PU-302
32 PS_PU303_PUMP_STATE Pump state (enum 3.2) PS_PUBLISHED FC03 15 Signed 16-bit Read value 1.0 9 %QW15 PU-303
33 PS_STN_CURRENT_DUTY_PUMP Current duty pump (0 = none, 1-3) PS_PUBLISHED FC03 16 Signed 16-bit Read value 1.0 9 %QW16 STN
34 PS_STN_ALARM_BITMASK Alarm bitmask (section 6) - READ AS UNSIGNED PS_PUBLISHED FC03 17 Unsigned 16-bit Read value 1.0 99999 %QW17 STN
35 PS_STN_COMMAND_ACKNOWLEDGE Command acknowledge (echoes %MW1) PS_PUBLISHED FC03 20 Signed 16-bit Read value 1.0 99 %QW20 STN
36 PS_STN_STATION_MODE_1_AUTO Station mode: 1 = auto, 2 = off PS_SETPOINTS FC03/FC06 1024 Signed 16-bit Read/Write value 1.0 9 %MW0 STN
37 PS_STN_COMMAND_WORD Command word (section 3.3) PS_SETPOINTS FC03/FC06 1025 Signed 16-bit Read/Write value 1.0 99 %MW1 STN
38 PS_STN_COMMAND_PARAMETER Command parameter (pump number) PS_SETPOINTS FC03/FC06 1026 Signed 16-bit Read/Write value 1.0 9 %MW2 STN
39 PS_STN_LEVEL_CONTROL_SETPOINT Level control setpoint PS_SETPOINTS FC03/FC06 1027 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW3 STN
40 PS_STN_START_DUTY_LEVEL Start duty level PS_SETPOINTS FC03/FC06 1028 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW4 STN
41 PS_STN_START_PUMP_2_LEVEL Start pump 2 level PS_SETPOINTS FC03/FC06 1029 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW5 STN
42 PS_STN_START_PUMP_3_LEVEL Start pump 3 level PS_SETPOINTS FC03/FC06 1030 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW6 STN
43 PS_STN_STOP_ALL_LEVEL Stop all level PS_SETPOINTS FC03/FC06 1031 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW7 STN
44 PS_STN_HIGH_LEVEL_ALARM High level alarm PS_SETPOINTS FC03/FC06 1032 Signed 16-bit Read/Write % value / 60 0.016666666666666666 999.9 %MW8 STN
45 PS_STN_MINIMUM_DRIVE_SPEED Minimum drive speed PS_SETPOINTS FC03/FC06 1033 Signed 16-bit Read/Write % value * 0.2 0.2 999.9 %MW9 STN
46 PS_STN_SERVICE_INTERVAL Service interval PS_SETPOINTS FC03/FC06 1034 Signed 16-bit Read/Write h value 1.0 99999 %MW10 STN
47 PS_SIM_MANUAL_INFLOW manual inflow (mode 0) PS_SIM_CONTROL FC03/FC06 1044 Signed 16-bit Read/Write m3/h value * 0.36 0.36 9999.9 %MW20 SIM SIMULATION CONTROL - simulation build only
48 PS_SIM_SCENARIO_0_MAN_1_DIURNAL_2_W scenario 0=man 1=diurnal 2=wet 3=ref PS_SIM_CONTROL FC03/FC06 1045 Signed 16-bit Read/Write value 1.0 9 %MW21 SIM SIMULATION CONTROL - simulation build only
49 PS_SIM_WRITE_1_TO_RESET_SCENARIO write 1 to reset scenario, self-clearing PS_SIM_CONTROL FC03/FC06 1046 Signed 16-bit Read/Write value 1.0 9 %MW22 SIM SIMULATION CONTROL - simulation build only
50 PS_SIM_TIME_SCALE_1_120 time scale 1-120 PS_SIM_CONTROL FC03/FC06 1047 Signed 16-bit Read/Write x value 1.0 999 %MW23 SIM SIMULATION CONTROL - simulation build only