performance_loss
performance_loss ¤
Performance/speed loss tracking.
Track when machine runs slower than ideal/target speed: - Identify slow periods vs target cycle time - Calculate performance loss in minutes and parts - Performance trend over time
PerformanceLossEvents ¤
PerformanceLossEvents(
dataframe: DataFrame,
*,
time_column: str = "systime",
shift_definitions: (
dict[str, tuple[str, str]] | None
) = None,
event_uuid: str = "prod:performance_loss"
)
Bases: Base
Track performance and speed losses against target cycle times.
Identifies hidden losses where the machine is running but slower than it should be. Typically 10-20% of production time is lost to speed losses.
Each method takes one signal: - cycle_uuid: cycle trigger or production counter
All methods compare against a single target_cycle_time; there are no
per-part targets.
Definitions follow ISO 22400-2: actual_parts is the produced
quantity (the sum of reset-aware counter increments, so a counter that
steps by 2 counts 2 parts; for a trigger signal one part per row),
run_seconds is the running time the parts were made in (the summed
intervals between producing readings, minus any dropped by
max_cycle_gap), avg_cycle_time_seconds = run_seconds /
actual_parts and performance_pct = target_cycle_time x actual_parts
/ run_seconds x 100. The speed loss is run_seconds - actual_parts x
target_cycle_time. Durations are in seconds (*_seconds);
loss_minutes and the *_s cycle time columns are kept as a
convenience. For a line that runs several part numbers, filter the data
to one part (or one product run) per call.
Merge keys: [date, shift] for shift-level, [period] for trend data.
Pipeline example::
perf = PerformanceLossEvents(df)
shift_perf = perf.performance_by_shift('cycle', target_cycle_time=45)
# → merge with DowntimeEvents.downtime_by_shift() on [date, shift]
# → merge with QualityEvents.nok_by_shift() on [date, shift]
# → feed into ShiftHandoverEvents.from_shift_data()
Example usage
tracker = PerformanceLossEvents(df)
Performance by shift¤
perf = tracker.performance_by_shift( cycle_uuid='cycle_trigger', target_cycle_time=45.0, )
Identify slow periods¤
slow = tracker.slow_periods( cycle_uuid='cycle_trigger', target_cycle_time=45.0, threshold_pct=90, )
Initialize the performance-loss tracker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataframe
|
DataFrame
|
Input DataFrame with timeseries data. |
required |
time_column
|
str
|
Name of timestamp column (default: 'systime'). |
'systime'
|
shift_definitions
|
dict[str, tuple[str, str]] | None
|
Mapping of shift name to (start, end) times. Default: 3-shift operation (06:00-14:00, 14:00-22:00, 22:00-06:00). |
None
|
event_uuid
|
str
|
UUID tagged on derived interval events (the |
'prod:performance_loss'
|
performance_by_shift ¤
performance_by_shift(
cycle_uuid: str,
target_cycle_time: float,
*,
value_column: str = "value_integer",
max_cycle_gap: str | None = None,
production_day: bool = True
) -> pd.DataFrame
Calculate performance percentage per shift.
Performance = (target_cycle_time * actual_parts) / run_seconds, with
actual_parts the produced quantity (counter increments).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cycle_uuid
|
str
|
UUID of cycle trigger or counter signal. |
required |
target_cycle_time
|
float
|
Target (ideal) cycle time in seconds. |
required |
value_column
|
str
|
Column with counter values. |
'value_integer'
|
max_cycle_gap
|
str | None
|
Optional cap (e.g. "5min"). Intervals longer than this are treated as stoppages and excluded, so a break or downtime is not counted as slow-running time (which would otherwise report a large, spurious speed loss). |
None
|
production_day
|
bool
|
Attribute an overnight shift's post-midnight
readings to the shift's start date, so a night shift is one
|
True
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
are convenience duplicates of the |
slow_periods ¤
slow_periods(
cycle_uuid: str,
target_cycle_time: float,
*,
threshold_pct: float = 90.0,
window: str = "1h",
value_column: str = "value_integer",
max_cycle_gap: str | None = None
) -> pd.DataFrame
Identify time windows where performance is below threshold.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cycle_uuid
|
str
|
UUID of cycle trigger or counter signal. |
required |
target_cycle_time
|
float
|
Target cycle time in seconds. |
required |
threshold_pct
|
float
|
Performance must be below this to flag (default 90%). |
90.0
|
window
|
str
|
Fixed time window per row (default '1h'). |
'1h'
|
value_column
|
str
|
Column with counter values. |
'value_integer'
|
max_cycle_gap
|
str | None
|
Optional cap (e.g. "5min"). Cycle intervals longer than it are dropped as stops instead of counted as slow cycles. None keeps every interval. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: |
DataFrame
|
|
DataFrame
|
|
performance_trend ¤
performance_trend(
cycle_uuid: str,
target_cycle_time: float,
*,
window: str = "1D",
value_column: str = "value_integer",
max_cycle_gap: str | None = None
) -> pd.DataFrame
Track performance trend over time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cycle_uuid
|
str
|
UUID of cycle trigger or counter signal. |
required |
target_cycle_time
|
float
|
Target cycle time in seconds. |
required |
window
|
str
|
Time window for aggregation (default '1D'). |
'1D'
|
value_column
|
str
|
Column with counter values. |
'value_integer'
|
max_cycle_gap
|
str | None
|
Optional cap (e.g. "5min"). Cycle intervals longer than it are dropped as stops instead of counted as slow cycles. None keeps every interval. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|