# ============================================================================= # equipment.yml — alias resolution at equipment and tag level. # # SOURCE: pg-ai public.equipment and public.tags. These live in pg-ai whatever # happens to imh, so this file does not change at Phase 4. # # WHY IT IS IN CUBE AT ALL: so that a question about "Pump 02" can be answered # without the caller knowing that its data is on AID.WRPS.PU302.RUNNING, # AID.WRPS.PU302.TRIPPED and AID.WRPS.PU302.RUN_HOURS. Without equipment-level joins every # equipment question fails, because no historian point is called "Pump 02". # # Alias matching itself is done in the API (api/tools/equipment.py) against the # GIN-indexed alias arrays, not here - Cube is the aggregation layer, not the # entity resolver. What Cube provides is the join, so that once the API has # resolved "Pump 02" to PU-302 the measures in the other cubes can be filtered # by equipment rather than by a list of tags the model would have to hardcode. # ============================================================================= cubes: - name: equipment sql: > SELECT equipment_id, display_name, equipment_type, unit_name, description, array_to_string(aliases, ' | ') AS alias_list FROM public.equipment description: > Plant equipment at the Waterloo Road Pump Station - the station itself, the wet well, three pumps, the discharge manifold, the spill weir and the switchboard. dimensions: - name: equipment_id sql: equipment_id type: string primary_key: true description: Canonical identifier - PU-302, WW-101, STN-001. - name: display_name sql: display_name type: string description: What to call it in an answer - "Pump 02", not "PU-302". - name: equipment_type sql: equipment_type type: string - name: unit_name sql: unit_name type: string - name: alias_list sql: alias_list type: string description: > Pipe-separated aliases, for display and debugging. Resolution happens in the API against the array column with a GIN index; this string is for showing an operator why "pump2" was understood as PU-302. - name: description sql: description type: string measures: - name: count type: count - name: tags sql_table: public.tags description: > Historian points and field instruments, their units, ranges and setpoints. Read the description column before interpreting any value - it records the historian-versus-PLC unit conversion and, critically, whether the tag is historised at all. joins: - name: equipment sql: "{CUBE}.equipment_id = {equipment}.equipment_id" relationship: many_to_one dimensions: - name: tag_id sql: tag_id type: string primary_key: true - name: equipment_id sql: equipment_id type: string - name: display_name sql: display_name type: string - name: signal_type sql: signal_type type: string description: level, flow, pressure, vibration, status, state, speed, hours. - name: engineering_unit sql: engineering_unit type: string description: > The unit the HISTORIAN stores, which is not always the unit the PLC works in. Wet well level is historised as percent of the spill weir crest (raw mm / 60). Always report the unit with the number. - name: range_low sql: range_low type: number - name: range_high sql: range_high type: number - name: alarm_setpoint_hi sql: alarm_setpoint_hi type: number description: > The configured alarm setpoint at the time this reference data was loaded. Setpoints are writable from SCADA - if a question compares two periods, check AID.WRPS.SP.HIGH_ALARM for a change before attributing a difference in alarm counts to the process. - name: alarm_setpoint_lo sql: alarm_setpoint_lo type: number - name: trip_setpoint sql: trip_setpoint type: number - name: description sql: description type: string measures: - name: count type: count # --------------------------------------------------------------------------- # historian_items — the CI Server item dictionary. # # WHY IT IS A CUBE AT ALL: so "what is AID.WRPS.STN.LEVEL" and "which item # holds the wet well level" are both answerable, and so an engineer checking # a number can walk from the answer back through item -> point -> PLC address # without leaving the assistant. Four namespaces name the same measurement # and this table is the only place all four appear together. # # It is also where an item's SAMPLE RATE and RETENTION come from, both taken # from the live CI Server historisation groups rather than assumed. # --------------------------------------------------------------------------- - name: historian_items sql_table: public.historian_items description: > CI Server items - what the historian is actually keyed on - and how each maps to a tag, a SCADA point and a PLC register. joins: - name: tags sql: "{CUBE}.tag_id = {tags}.tag_id" relationship: many_to_one dimensions: - name: item_name sql: item_name type: string primary_key: true description: AID.WRPS.STN.LEVEL. The historian's own key. - name: tag_id sql: tag_id type: string description: > NULL only for items deliberately excluded from answering - see exclusion_reason. A NULL here with no reason is a build failure. - name: exclusion_reason sql: exclusion_reason type: string description: > Why this item cannot be asked about. Present it verbatim rather than reporting "no records found" - the two mean very different things. - name: section sql: section type: string description: > CI Server's own grouping - STN, PU301, PU302, PU303, SP, SIM. It is COARSER than plant equipment: there is no wet well, weir, manifold or switchboard section. Use equipment for the plant view, not this. - name: attribute sql: attribute type: string - name: description sql: description type: string - name: eng_unit sql: eng_unit type: string description: The unit CI Server presents, which is not the PLC's unit. - name: raw_to_eng sql: raw_to_eng type: string description: > How the raw register becomes the engineering value, as written in the SCADA point list - "value / 60" for level. Quote this when explaining why a level reads 70.3 and not 4217. - name: his_group sql: his_group type: string description: WRPS_ONE_SEC (5 s), WRPS_THIRTY_SEC (30 s), WRPS_EVENT (on change). - name: scan_interval_seconds sql: scan_interval_seconds type: number - name: life_time sql: life_time type: string description: > Retention on the item's history group - "1 weeks" on every WRPS group. This is the answer to "why can it not tell me about last month". - name: ci_point sql: ci_point type: string - name: iec_address sql: iec_address type: string description: The PLC address, %QW0. Field inputs (%IW/%IX) are not historised. measures: - name: count type: count views: - name: item_reference description: > The CI Server item dictionary joined to the tag and equipment each item belongs to. This is the lookup behind "which item holds the wet well level", "how often is it sampled" and "how far back does it go". cubes: - join_path: historian_items includes: - item_name - tag_id - exclusion_reason - section - attribute - description - eng_unit - raw_to_eng - his_group - scan_interval_seconds - life_time - ci_point - iec_address - count - join_path: historian_items.tags prefix: true includes: - display_name - signal_type - engineering_unit - join_path: historian_items.tags.equipment prefix: true includes: - equipment_id - display_name - equipment_type - name: equipment_reference description: > Equipment joined to its tags - the lookup behind "what does the PVHI alarm on the wet well mean" and "which pump is PU-302". cubes: - join_path: tags includes: - tag_id - display_name - signal_type - engineering_unit - range_low - range_high - alarm_setpoint_hi - alarm_setpoint_lo - trip_setpoint - description - join_path: tags.equipment prefix: true includes: - equipment_id - display_name - equipment_type - alias_list