Production Performance Calculations¶
This document describes how GET /api/v1/production-performance derives its metrics. API usage: Production Performance API.
Data sources¶
| Source | Collection / location | Used for |
|---|---|---|
| Project structure | projects |
Scope resolution, embedded production_stage_operation events |
| Tenant machines | machines |
Machine ID guard for alarm queries |
| Alarm timeline | alarms |
Net/stop duration intervals |
All reads are scoped to the resolved tenant. Alarm queries additionally restrict to tenant machine IDs.
Time window¶
When start_time and end_time are supplied:
- Both must be valid RFC 3339 timestamps (offsets accepted, normalized to UTC)
start_timemust be strictly beforeend_time- The window is
[effective_start_time, effective_end_time)— events ateffective_end_timeare excluded
When omitted:
effective_end_time= current UTC time at request processingeffective_start_timeis resolved in order:- Project
start_datewhen present - Earliest embedded operation event timestamp for the active scope
- Earliest alarm timestamp for the active scope and tenant machines
- Fallback to
effective_end_timewhen no earlier signal exists
Scope and independent metrics¶
Metrics are calculated separately for each returned level:
| Level | Events included |
|---|---|
| Project | All productions and stages under the project |
| Production | Only the selected production |
| Production stage | Only the selected stage |
Operation events are flattened from embedded production_stage_operation arrays on matching stages. Alarm events are loaded for the scope with a tenant machine $in guard.
Duration truncation¶
All duration outputs are int64 seconds. Conversion uses:
text
int64(duration / time.Second)
Fractional sub-second remainders are truncated toward zero. Clipped interval math applies the same rule after intersecting segments with the active window.
Operation time (total_operation_time_seconds)¶
Source: embedded production_stage_operation records (event_case, event_time, machine identity).
Per machine group (by machine ID, else normalized machine name):
| Event case | Effect |
|---|---|
operation_start |
Opens an active interval when none is open |
operation_break |
Closes the active interval |
operation_end |
Closes the active interval |
Rules:
- Only one active interval per machine at a time; a second
operation_startwhile already active is ignored - Intervals open at request time remain open until
operation_break,operation_end, or the window end - Each closed segment is clipped to the window before summation
total_operation_time_seconds is the sum across all machine groups.
Alarm durations¶
Source: alarms documents (event_type, type_code, timestamp, machine identity).
Events are grouped per machine, sorted by (timestamp ASC, _id ASC). The calculator also loads the latest alarm before effective_start_time per machine to establish initial state inside the window.
State transitions¶
event_type |
Resulting state | Notes |
|---|---|---|
start |
Net operation | |
stop |
Stop | type_code classifies planned / unplanned / failure |
reconnecting |
No active state | Contributes zero duration. Legacy aliases (reconnect, re-connect, re_connect, any case) normalize to this canonical value. |
| Other / unknown | No active state |
Stop classification uses normalized type_code:
Canonical type_code |
Bucket |
|---|---|
planned |
planned_stop_time_seconds |
unplanned |
unplanned_stop_time_seconds |
failure |
failure_stop_time_seconds |
Between consecutive in-window events (and from window start through window end), elapsed time in each state is clipped to the window and added to:
net_operation_time_secondsstop_time_seconds(total)- The matching planned/unplanned/failure subset
reconnecting clears the previous start or stop interval at its own timestamp without adding time to net or stop totals.
Product metrics (product_metrics)¶
Source: product_operations entries attached to in-window operation events.
For each product key (prefer product_id, else product_code):
| Counter | Source field |
|---|---|
successful_count |
success_count |
revised_count |
revise_count |
scrap_count |
fire_count |
total_count |
Sum of the three counters |
Negative source values are treated as zero. Results are sorted by product_code, then product_id.
When no in-window product operations exist, product_metrics is an empty array.
Zero-data behavior¶
When a project exists but the window contains no qualifying operation or alarm events:
- HTTP 200
- All duration fields return
0 product_metricsreturns[]
404 responses apply only when the project, production, or stage entity cannot be found for the tenant.
Normalization¶
event_type, type_code, and operation event_case values pass through the shared normalizer (internal/outbound/normalize):
- Trim, lowercase, spaces/hyphens → underscores
- Known aliases map to canonical snake_case forms
- Alarm
event_typecanonical values are onlystart,stop, andreconnecting(reconnect variants map toreconnecting)
This keeps calculation and API output consistent regardless of source casing.
Related indexes¶
Alarm read performance relies on migration-managed non-unique indexes:
ix_alarms_machine_timestamp_id_descix_alarms_project_production_stage_machine_timestamp_id
These are created by the migration CLI, not during API requests.