Skip to content

rework_tracking

rework_tracking ¤

Rework tracking for parts requiring re-processing.

Track rework events and their impact: - Rework count by shift - Rework by reason code - Rework rate as percentage of production - Rework cost estimation - Rework trends over time

ReworkEvents ¤

ReworkEvents(
    dataframe: DataFrame,
    *,
    time_column: str = "systime",
    shift_definitions: (
        dict[str, tuple[str, str]] | None
    ) = None
)

Bases: Base

Track parts that require rework (re-processing through a station).

Each UUID represents one signal: - rework_uuid: rework event counter (monotonic integer) - reason_uuid: rework reason code signal (optional) - total_production_uuid: total production counter (optional) - part_id_uuid: part number / product type signal (optional)

Merge keys: [date, shift] for shift-level, [period] for trend, [reason] for reason-level, [part_number] for part-level.

Pipeline example::

rework = ReworkEvents(df)
shift_rework = rework.rework_by_shift('rework_counter')
# → merge with ShiftReportEvents.shift_production() on [date, shift]
# → merge with QualityEvents.nok_by_shift() on [date, shift]
rate = rework.rework_rate('rework_counter', 'total_counter')
# → merge with ShiftReportEvents.shift_production() on [date, shift]
Example usage

tracker = ReworkEvents(df)

Rework per shift¤

shift_rework = tracker.rework_by_shift(rework_uuid='rework_counter')

Rework rate¤

rate = tracker.rework_rate( rework_uuid='rework_counter', total_production_uuid='total_counter', )

rework_by_shift ¤

rework_by_shift(
    rework_uuid: str,
    *,
    value_column: str = "value_integer",
    handle_resets: bool = True,
    production_day: bool = True
) -> pd.DataFrame

Rework count per shift.

Parameters:

Name Type Description Default
rework_uuid str

UUID for rework event counter signal.

required
value_column str

Column containing counter values.

'value_integer'
handle_resets bool

When True (default), treat a decreasing counter as a reset and count the rework accumulated after the reset instead of losing it. The increments are computed once over the whole signal and booked to the shift of the reading that reports them, so the shifts add up to the signal total. The result gains a resets column with the number of resets observed in each shift. When False, the quantity is max(0, last - first) of the shift's own readings: a shift containing a reset reports too little (often 0) and the production between two shifts' readings is lost.

True
production_day bool

When True, an overnight shift's post-midnight readings are attributed to the shift's start date, so a night shift is one contiguous (date, shift) group. Default True; False groups by raw calendar date, which splits a night shift across two rows. Only affects overnight schedules.

True

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • start, end, duration_seconds: the shift window from shift_definitions (date at the shift start time, tz-aware in the data's tz; an overnight shift ends on the next day)
DataFrame
  • date, shift, rework_count
DataFrame
  • resets: Number of counter resets in the shift (only when handle_resets=True)

rework_by_reason ¤

rework_by_reason(
    rework_uuid: str,
    reason_uuid: str,
    *,
    value_column_rework: str = "value_integer",
    value_column_reason: str = "value_string",
    handle_resets: bool = True
) -> pd.DataFrame

Rework quantity by reason code.

Parameters:

Name Type Description Default
rework_uuid str

UUID for rework counter signal.

required
reason_uuid str

UUID for rework reason code signal.

required
value_column_rework str

Column containing rework counter values.

'value_integer'
value_column_reason str

Column containing reason codes.

'value_string'
handle_resets bool

When True (default), treat a decreasing counter as a reset and count the rework accumulated after the reset. The reason is attached to a single global counter, so the reset-aware quantity is the sum of per-reading increments over the full time-sorted series, grouped by reason -- this also corrects the over-count that last - first produces when reasons alternate over a non-contiguous group. The result gains a resets column with the number of resets attributed to each reason. When False, the quantity is max(0, last - first) per reason group and a reset is lost.

True

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • reason, rework_count, pct_of_total
DataFrame
  • resets: Number of counter resets for the reason (only when handle_resets=True)
DataFrame

Canonical twin columns: share_of_total_pct (after pct_of_total); each

DataFrame

holds the same values as the deprecated column right before it, which is

DataFrame

removed in the next major release.

rework_rate ¤

rework_rate(
    rework_uuid: str,
    total_production_uuid: str,
    *,
    value_column_rework: str = "value_integer",
    value_column_production: str = "value_integer",
    handle_resets: bool = True,
    production_day: bool = True
) -> pd.DataFrame

Rework rate as percentage of total production per shift.

Parameters:

Name Type Description Default
rework_uuid str

UUID for rework counter signal.

required
total_production_uuid str

UUID for total production counter signal.

required
value_column_rework str

Column containing rework counter values.

'value_integer'
value_column_production str

Column containing production counter values.

'value_integer'
handle_resets bool

When True (default), treat a decreasing counter as a reset and count the production/rework accumulated after the reset, for both the numerator (rework) and denominator (total produced). Both are computed once over the whole signal and booked to the shift of the reading that reports them, so the shifts add up to the signal totals. The result gains rework_resets, production_resets and resets (their sum) columns with the number of resets observed in each shift. When False, both use max(0, last - first) per shift and a reset is lost.

True
production_day bool

When True, an overnight shift's post-midnight readings are attributed to the shift's start date. Default True; False groups by raw calendar date, which splits a night shift across two rows. Only affects overnight schedules.

True

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • start, end, duration_seconds: the shift window from shift_definitions (date at the shift start time, tz-aware in the data's tz; an overnight shift ends on the next day)
DataFrame
  • date, shift, total_produced, rework_count, rework_rate_pct
DataFrame
  • rework_resets, production_resets, resets: Number of counter resets of the rework counter, the production counter, and both together in the shift (only when handle_resets=True)

rework_cost ¤

rework_cost(
    rework_uuid: str,
    part_id_uuid: str,
    rework_costs: dict[str, float],
    *,
    value_column_rework: str = "value_integer",
    value_column_part: str = "value_string",
    handle_resets: bool = True
) -> pd.DataFrame

Convert rework counts to monetary cost by part number.

Parameters:

Name Type Description Default
rework_uuid str

UUID for rework counter signal.

required
part_id_uuid str

UUID for part number / product type signal.

required
rework_costs dict[str, float]

Dict mapping part numbers to cost per rework.

required
value_column_rework str

Column containing rework counter values.

'value_integer'
value_column_part str

Column containing part number values.

'value_string'
handle_resets bool

When True (default), treat a decreasing counter as a reset and count the rework accumulated after the reset. The increments are computed once over the whole signal and booked to the part of the reading that reports them, so the parts add up to the signal total (also when parts alternate). The result gains a resets column with the number of resets observed for each part. When False, the quantity is max(0, last - first) per part and a reset is lost.

True

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • part_number, rework_count, cost_per_rework, total_cost
DataFrame
  • resets: Number of counter resets for the part (only when handle_resets=True)

rework_trend ¤

rework_trend(
    rework_uuid: str,
    *,
    value_column: str = "value_integer",
    window: str = "1D",
    handle_resets: bool = True
) -> pd.DataFrame

Track rework count trend over time.

Parameters:

Name Type Description Default
rework_uuid str

UUID for rework counter signal.

required
value_column str

Column containing counter values.

'value_integer'
window str

Time window for aggregation (default '1D').

'1D'
handle_resets bool

When True (default), treat a decreasing counter as a reset and count the rework accumulated after the reset. The increments are computed once over the whole signal and booked to the period of the reading that reports them, so the periods add up to the signal total. The result gains a resets column with the number of resets observed in each period. When False, the quantity is max(0, last - first) of the period's own readings: a reset and the production between two periods' readings are lost.

True

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • start, end (start + window), duration_seconds
DataFrame
  • period, rework_count
DataFrame
  • resets: Number of counter resets in the period (only when handle_resets=True)