📌 4.1.3 Production Run Monitoring
📌

4.1.3 Production Run Monitoring

1. Overview

The Production Run Monitoring view provides real-time visibility into the current Production Run for a specific Line.

It displays up-to-date run context, production KPIs, OEE indicators, cycle-time behavior, hourly production trends, and operator actions (waste input, downtime categorization, run stop).

This view is data-driven entirely through UDT tags:

  • Realtime tags (5 seconds) from Line Runtime UDTs

  • Database aggregate tags (1 minute) delivered via SQL Query Tags inside the UI_RunMonitor UDT

  • Lookup tags provide human-readable wording (e.g., downtime reasons, product descriptions)

  • Command Tags (write-only) are used by Perspective to trigger run actions through the Dispatch UDT.

Perspective does not perform any direct SQL.

All database access is encapsulated inside the UI_RunMonitor UDT.

2. UDT Architecture

1. UDT Name & Purpose

UDT Name: UI_RunMonitor

One instance per Line, e.g.:

  • [default]UI/RunMonitor/Line01

  • [default]UI/RunMonitor/Line02

Purpose:

Provide a single tag interface for the Production Run Monitoring view:

  • Realtime machine + counter tags (≈ 5s)

  • Aggregated MES data from DB (≈ 60s, via SQL Query Tags)

  • UI-friendly scalar tags (strings, numbers) parsed from the datasets

Perspective only binds to this UDT. No direct SQL from the UI.

2. UDT Parameters

Might work UDT


Parameter Type Example value Used for
LineId Int4 1 DB queries (run, schedule, etc.)
LineName String LINE_01 For display / logging
LinePath String [default]Runtime/Line01 Path to Line-runtime UDT
DbConn String MES_Core DB connection for SQL Query Tags

3. Members – Realtime (5s)

These are Reference tags into your existing Runtime/Line UDTs.

Adjust the LinePath mapping to your actual structure.

Folder: Realtime

Tag Name Type Source (where to get it from) Notes
StateCode Int4 Reference: {LinePath}/State/Code Current machine state
StateDuration Int4/Int8 Reference: {LinePath}/State/Duration Seconds in current state
GoodCountLive Int8 Reference: {LinePath}/OEE/OutfeedCount or /Outfeed/Count Live good count
WasteCountLive Int8 Reference: {LinePath}/OEE/WasteCount or /Waste/Count Live waste count
RunId Int8 Reference: {LinePath}/OEE/RunId or /Run/Id Active run ID
MachineName String Expression: {LineName} or ref from runtime UDT For header display

Scan class / rate:

  • Use your existing 5 s (or faster) scan class.

4. Members – DB (SQL Query Tags, 60s)

These are SQL Query Tags that go to the MES DB via connection {DbConn}.

Execution mode: Run every 60000 ms.

Folder: DB

4.1 RunHeaderData (Dataset)

Type: Query Tag (Dataset)

Rate: 60000 ms

DB Connection: {DbConn}

Parameter(s): :line_id = {LineId}

Purpose:

One-row dataset with all info for:

  • Work Order, Product, target qty

  • Actual good/reject/total

  • Remaining, progress %

  • Expected good (based on idealcycletime & runtime)

  • OEE (A, P, Q, OEE)

SQL (simplified from previous):

WITH active_run AS (
    SELECT
        r.id               AS run_id,
        r.schedule_id,
        r.total_count,
        r.good_count,
        r.waste_count,
        r.availability,
        r.performance,
        r.quality,
        r.oee,
        r.runtime,
        r.run_start_datetime,
        s.line_id,
        s.schedule_start_datetime,
        s.schedule_finish_datetime,
        s.quantity         AS target_qty,
        wo.id              AS work_order_id,
        wo.work_order      AS work_order_no,
        pc.product_code,
        pc.description     AS product_description,
        pcl.idealcycletime AS ideal_cycle_time_s
    FROM run r
    JOIN schedule       s   ON r.schedule_id      = s.id
    JOIN work_order     wo  ON s.work_order_id    = wo.id
    JOIN product_code   pc  ON wo.product_code_id = pc.id
    LEFT JOIN product_code_line pcl
           ON pcl.product_code_id = pc.id
          AND pcl.line_id         = s.line_id
    WHERE s.line_id = :line_id
      AND r.closed = FALSE
    ORDER BY r.run_start_datetime DESC
    LIMIT 1
)
SELECT * FROM active_run;

4.2 Last5CyclesData (Dataset)

Type: Query Tag (Dataset)

Rate: 60000 ms

Parameter: :run_id = {Realtime/RunId}

Source table: run_cycle_time

SELECT
    cycle_index,
    cycle_end_time,
    cycle_time_s
FROM run_cycle_time
WHERE run_id = :run_id
ORDER BY cycle_index DESC
LIMIT 5;

Used by the “Last 5 cycles” bar list.

4.3 PartsByHourData (Dataset)

Type: Query Tag (Dataset)

Rate: 60000 ms

Parameter: :run_id = {Realtime/RunId}

Source table: run_count_by_interval (or equivalent aggregation view)

SELECT
    bucket_start,
    bucket_end,
    good_count,
    waste_count,
    total_count
FROM run_count_by_interval
WHERE run_id = :run_id
ORDER BY bucket_start;

Used by the “Parts made – by hour” chart.

4.4 DowntimeDictionary (Dataset)

Type: Query Tag (Dataset)

Rate: 60000 ms

Source table: downtime_reason

SELECT
    code,
    short_text,
    long_text
FROM downtime_reason;

Used to turn a downtime code into wording text.

5. Members – UI / Parsed Values (Expression Tags)

These are scalar tags parsed from the datasets.

This is what Perspective typically binds to for labels, KPIs, etc.

Folder: UI/Header

Tag Name Type Expression (where it reads from) Purpose
RunIdActive Int8 {Realtime/RunId} Convenience alias Used by KPI expressions, OEE tiles, and chart queries when parsing DB results.
WorkOrderNo String lookup("work_order_no", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, "") Header
ProductCode String lookup("product_code", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, "") Header
ProductDescription String lookup("product_description", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, "") Header
TargetQty Int8 lookup("target_qty", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, 0) KPIs
RuntimeSeconds Int8 lookup("runtime", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, 0) For expected calc
IdealCycleTime Float8 lookup("ideal_cycle_time_s", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, 0) For expected calc
ScheduleStartDT DateTime lookup("schedule_start_datetime", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, now()) Display
ScheduleFinishDT DateTime lookup("schedule_finish_datetime", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, now()) Display

Folder: UI/KPI

Tag Name Type Expression
ActualGood Int8 lookup("good_count", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, 0)
ActualReject Int8 lookup("waste_count", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, 0)
ActualTotal Int8 {UI/KPI/ActualGood} + {UI/KPI/ActualReject}
RemainingQty Int8 lookup("target_qty", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, 0) - {UI/KPI/ActualGood}
ProgressPct Float8 if({UI/KPI/TargetQty} > 0, 100.0 * {UI/KPI/ActualGood} / {UI/KPI/TargetQty}, 0)
ExpectedGood Int8 if({UI/Header/IdealCycleTime} > 0, floor({UI/Header/RuntimeSeconds} / {UI/Header/IdealCycleTime}), 0)

(You can also lookup pre-calculated expected_good_count if you store it directly in the SQL.)

Folder: UI/OEE

Tag Name Type Expression
Availability Float8 lookup("availability", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, 0)
Performance Float8 lookup("performance", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, 0)
Quality Float8 lookup("quality", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, 0)
OEE Float8 lookup("oee", "run_id", {Realtime/RunId}, {DB/RunHeaderData}, 0)

Folder: UI/Downtime

Tag Name Type Source / Expression
CurrentCode Int4 {Realtime/StateCode}
CurrentTextShort String lookup("short_text", "code", {UI/Downtime/CurrentCode}, {DB/DowntimeDictionary}, "")
CurrentTextLong String lookup("long_text", "code", {UI/Downtime/CurrentCode}, {DB/DowntimeDictionary}, "")

Folder: UI/Charts

For charts and lists, you use the dataset tags directly:

Tag Name Type Source Note
CyclesLast5 Dataset {DB/Last5CyclesData} Bind to repeater / flex repeater
PartsByHour Dataset {DB/PartsByHourData} Bind to chart (X = bucket_start)

No parsing needed here; just use the full dataset.

6. How Perspective Uses This UDT

  • Header bar

    • Binds to UI/Header/* and UI/Downtime/* tags.

  • KPI row

    • Binds to UI/KPI/*.

  • OEE strip

    • Binds to UI/OEE/*.

  • Last 5 cycles

    • Repeater data source = UI/Charts/CyclesLast5.

  • Parts made – by hour

    • Chart data source = UI/Charts/PartsByHour.

  • Action buttons / popups

    • Use {Realtime/RunId}, {LineId}, {LineName} as parameters to Gateway scripts / Named Queries.


3. Page Structure and Workflow

The View binds exclusively to tags under:

[default]UI/RunMonitor/{Line}

3.1 Header Bar (Live Run Context)

Shows Work Order, Product, State, Machine Name, Downtime wording, Run Start Time.

Bindings:

  • Work Order No → WorkOrderNo

  • Product Code & Description → ProductCode, ProductDescription

  • Machine State → StateCode, StateDuration

  • Downtime wording → DowntimeText

  • Scheduled Start/End → lookup from RunHeaderData

Refresh behavior:

  • State code & duration: every 5s

  • Context info: every 60s

3.2 Production KPI Row

Contains the following tiles:

(A) You Have Made

  • Good → ActualGood

  • Reject → ActualReject

  • Total = (Good + Reject)

(B) Progress

  • Remaining Qty → RemainingQty

  • Progress % → ProgressPct

(C) Expected to Have Made

  • Expected Good → ExpectedGood

Refresh behavior:

From RunHeaderData → 60s

3.3 OEE Strip

Mobile responsive view

Tiles: Availability / Performance / Quality / OEE

All values → lookup from RunHeaderData (Expression Tags).

Refresh rate: 60s

3.4 Cycle Time – Last 5 Cycles

Horizontal bar chart.

Bind repeater to:

Last5CyclesData

Refresh: 60s

For each cycle row:

  • Actual cycle time: {cycle_time_s}

  • Ideal cycle: from lookup {ideal_cycle_time_s}

  • Percentage bar width computed in Perspective transform:

min(100, 100 * cycle_time_s / ideal_cycle_time_s)

3.5 Hourly Parts Made Chart

Bind chart directly to:

PartsByHourData

Refresh: 60s

Columns:

  • bucket_start (X-axis)

  • good_count (bar height)

  • Optional: waste_count, total_count

3.6 Action Buttons

Buttons trigger Perspective popup views and write to Command Tags in the UI_RunMonitor UDT. Dispatch UDT scripts handle all database writes and run-state transitions.

Updated Action Button table:

ActionBehaviour
Add WasteOpens popup → writes values to UI_RunMonitor.Commands.Waste* tags → Dispatch UDT handles the DB insert + counter update
Downtime CategorizationOpens popup → writes values to UI_RunMonitor.Commands.Dt* tags → Dispatch UDT handles downtime logging
Stop RunOpens popup → sets UI_RunMonitor.Commands.EndRunTrigger → Dispatch UDT closes run & writes final DB summary
Operator LoginSame operator login popup as 4.1.1 (handled by Security/Login UDT)

This is the only correction needed for functional correctness.

UDT values (RunId, LineId) may be referenced by Dispatch UDT scripts. Perspective does not pass parameters to gateway scripts.

4. Command Tag Integration with Dispatch UDT

These Query Tags are strictly read-only and are used only to retrieve MES data for the UI.

All write operations (waste, downtime, end run) are handled by the Dispatch UDT

Perspective popups do not write to the database.

They only write to command tags in the UI_RunMonitor UDT, which are mapped 1:1 to the existing Dispatch UDT command tags.

The existing Dispatch scripts are responsible for updating the Run UDT and the MES database.

4.1 Command Tag Mapping Structure (Required)

To make the documentation complete, explicitly declare the command tags:

Command Tags Inside UI_RunMonitor (Reference → Dispatch)

Inside the Commands folder:

UI TagTypeSource / Mapping
Commands/WasteQtyIntReference → {LinePath}/Dispatch/CmdWasteQty
Commands/WasteReasonStringReference → {LinePath}/Dispatch/CmdWasteReason
Commands/WasteCommentStringReference → {LinePath}/Dispatch/CmdWasteComment
Commands/WasteTriggerBoolReference → {LinePath}/Dispatch/CmdWasteTrigger
Commands/DtCategoryStringReference → {LinePath}/Dispatch/CmdDtCategory
Commands/DtReasonStringReference → {LinePath}/Dispatch/CmdDtReason
Commands/DtCommentStringReference → {LinePath}/Dispatch/CmdDtComment
Commands/DtTriggerBoolReference → {LinePath}/Dispatch/CmdDtTrigger
Commands/EndRunOperatorIdStringReference → {LinePath}/Dispatch/CmdEndRunOperatorId
Commands/EndRunTriggerBoolReference → {LinePath}/Dispatch/CmdEndRunTrigger

All commands in the Production Run Monitoring view are executed by writing values into these tags.

The Dispatch UDT monitors these tags and performs:

  • MES database writes

  • Run state transitions

  • Waste/downtime capture

  • End Run finalisation

5. Ignition Implementation Requirements

UDTs

  • UI_RunMonitor (new)

  • Existing runtime UDT (Line) referenced via LinePath

Tag Types

Type Frequency Purpose
Reference Tags 5s Machine state + live counters
SQL Query Tags 60s Run summary, OEE, cycles, hourly data
Lookup Tags 5s–60s Human-readable mappings

Perspective Bindings

  • Entire view binds only to UDT tag paths

  • No Named Query bindings

  • Charts and repeaters receive dataset tags

6. Summary

The Production Run Monitoring view is implemented using a hybrid tag-driven model:

  • Realtime behaviour comes from runtime UDTs (5s)

  • Aggregated MES data comes from SQL Query Tags (60s)

  • No direct DB calls from Perspective

  • The view becomes completely tag-driven, easy to maintain, consistent, and high performance