The point list handed over in August named the points PS_STN_WET_WELL_LEVEL
and the like. Those were never CI Server names. They came from
gen_scada_points.py on the PLC side, which describes its own output as "a
starting point for CI Server configuration, not a CI Server import file",
and the CI Server generator ignored them entirely - it names points from
its own address-keyed table. The names appear in no .qli export, and
nowhere else in the WRPS project at all.
This is the corrected delivery. ci-server-points.csv is keyed on the CI
Server ITEM each point feeds, with the Modbus station and the point name
beside it, so all four namespaces are visible in one row:
LIT-101 instrument tag
%QW0 PLC symbol and address
WRPS_PLC:STN_LEVEL CI Server point - station, colon, point name
AID.WRPS.STN.LEVEL CI Server item - what the historian is keyed on
The 49 rows were joined onto the .qli exports by function code and Modbus
address: 49 matched, 0 unmatched. The item and point names are read from
the exports, not invented here.
The six .qli files come too, unchanged. gen_historian_items.py needs them,
and until now they existed only on one laptop behind a --wrps path - so
the one file the rules say must never be hand-edited could be regenerated
by exactly one person. 84 KB buys the team that back.
These are uncontrolled documents: no revision, no effective date, no
approval. The README says so, says how to ask for a fresh set, and records
the two things that bite - that PS_ survives legitimately as four poll
group names, and that his_group.qli and the live export disagree about the
sample rates, with the live one winning.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The three open Phase 5 findings were one defect: the stand-in was keyed on
CI Server POINT names (PS_STN_WET_WELL_LEVEL) when the historian is keyed on
CI Server ITEM names (AID.WRPS.STN.LEVEL). Modbus carries register numbers,
not names, so those two layers are free to differ - and do. Reconciling
against the register map, as planned, would only have proved the first three
namespaces agreed with each other.
Rebuilt from WRPS/05-scada/modbus, so item names, sample rates, retention and
timestamp semantics come from the machine rather than from a guess.
(a) Level tag does not join. PS_STN_WET_WELL_LEVEL becomes a tag row in its
own right; LIT-101 is marked NOT HISTORISED - a field input on %IW0 that
never reaches SCADA. It was the only seed row carrying two addresses.
public.historian_items holds the item-to-tag mapping, generated by
scripts/gen_historian_items.py and enforced non-empty at generate, at
deploy and at verify.
(b) first_alarm/last_alarm returned UTC. Converted inside the measure, so it
stays in Cube and happens once. Aggregate first, convert after - the other
order picks the wrong row across a DST fall-back. Returned as a formatted
string with a companion site_timezone measure. Storage being UTC is now
confirmed, not assumed: all 49 points carry TIME_ZONE "Date+time GMT" and
every history group CORRECT_DAYLIGHT=0. This answers Phase 4 task 4.
(c) High level alarm filed against the wrong equipment. Both sides were right
about different things; the defect was asserting equipment twice. The
history now carries no equipment column at all - faithful, since CI
Server's section tree stops at the station and three pumps. Equipment is
reached bit -> tag -> equipment via public.alarm_bits.
Alarms are derived, not stored: CI Server's ALARM_HISTORY group is empty
because every item imports with alarming off. Decomposing the alarm word needs
no configuration that does not exist.
Three things the SCADA config changed that were never filed as faults:
- retention is 7 days, not 30. The advisory path was reporting a month of
evidence drawn from a week of data
- the analogue rate is 5 s, not 60. Two measures multiplied sample counts by
a hardcoded 60 - a twelvefold overstatement that read as plausible
- the deadband warning in process_values.yml was wrong and was steering
people away from the correct measure
db/002_fixtures.sql now asserts its own counts at load and cross-checks the
alarm derivation against two independent signals. Those prove the pipeline,
not the plant.
db/README-standin-historian.md documents removal: the seam between generation
and contract, and twelve assumptions about imh that are NOT confirmed. Two of
them fail silently.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Build spec and host brief carried in from C:\Claude and WRPS/02-env; the
plant model (equipment, tags, alarm bitmask, enums, unit conversions) is
derived from WRPS/04-plc/register-map.csv, WRPS/05-scada/modbus/scada-points.csv
and WRPS-CTL-003.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>