Skip to content

routing_traceability

routing_traceability ¤

Routing-based traceability using ID + state/handover signals.

In this pattern a single UUID carries the current item identifier (serial code, order number, etc.) and a separate UUID carries a state / routing signal whose value encodes which process step or station the item is at.

The state_map parameter defines the mapping from signal values to station/step names. This is required because the signal values alone don't tell the module what they mean — they could be PLC step numbers, recipe phases, station codes, or anything else.

Example::

State signal value 10 → "Heating"
State signal value 20 → "Holding"
State signal value 30 → "Cooling"

Or::

State signal value 1 → "Welding"
State signal value 2 → "Painting"
State signal value 3 → "Assembly"

This module correlates both signals to reconstruct the full routing path.

RoutingTraceabilityEvents ¤

RoutingTraceabilityEvents(
    dataframe: DataFrame,
    id_uuid: str,
    routing_uuid: str,
    *,
    state_map: Optional[
        Dict[Union[int, float, str], str]
    ] = None,
    station_map: Optional[
        Dict[Union[int, float, str], str]
    ] = None,
    event_uuid: str = "prod:routing_trace",
    id_value_column: str = "value_string",
    routing_value_column: str = "value_integer",
    time_column: str = "systime"
)

Bases: Base

Trace item routing using an ID signal paired with a state/routing signal.

Two UUIDs work together: - id_uuid: string signal carrying the current identifier (serial number, order ID, batch code, etc.). - routing_uuid: signal whose value encodes the current process step or station.

A state_map translates signal values to human-readable station or step names. Without it, raw values are used as labels.

Example usage::

# PLC step numbers mapped to process steps
trace = RoutingTraceabilityEvents(
    df,
    id_uuid='serial_code_signal',
    routing_uuid='step_chain_signal',
    state_map={
        10: 'Heating',
        20: 'Holding',
        30: 'Cooling',
        40: 'Discharge',
    },
)

# Station handover signal mapped to stations
trace = RoutingTraceabilityEvents(
    df,
    id_uuid='serial_code_signal',
    routing_uuid='handover_signal',
    state_map={1: 'Welding', 2: 'Painting', 3: 'Assembly'},
)

timeline = trace.build_routing_timeline()
lead = trace.lead_time()
stats = trace.station_statistics()
paths = trace.routing_paths()

Initialize routing traceability.

Parameters:

Name Type Description Default
dataframe DataFrame

Input DataFrame with timeseries data.

required
id_uuid str

UUID of the signal carrying item identifiers.

required
routing_uuid str

UUID of the state/routing signal.

required
state_map Optional[Dict[Union[int, float, str], str]]

Mapping from signal value to station/step name. e.g. {10: 'Heating', 20: 'Holding', 30: 'Cooling'} or {1: 'Welding', 2: 'Painting', 3: 'Assembly'} Values can be int, float, or str keys. If not provided, raw signal values are used as labels.

None
station_map Optional[Dict[Union[int, float, str], str]]

Deprecated alias for state_map (for backwards compatibility). Use state_map instead.

None
event_uuid str

UUID to tag derived events with.

'prod:routing_trace'
id_value_column str

Column holding the item ID string.

'value_string'
routing_value_column str

Column holding the state/routing value.

'value_integer'
time_column str

Name of timestamp column.

'systime'

build_routing_timeline ¤

build_routing_timeline() -> pd.DataFrame

Correlate the ID signal with the state/routing signal to build a timeline.

For each sample of the routing signal, the current item ID is determined via backward-fill merge (most recent ID at that timestamp). Contiguous intervals where the same (item_id, state) pair holds are grouped into single events.

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • item_id: Identifier string.
DataFrame
  • routing_value: Raw signal value.
DataFrame
  • station_name: Resolved station/step name from state_map.
DataFrame
  • start: First timestamp of interval.
DataFrame
  • end: Last timestamp of interval.
DataFrame
  • duration_seconds: Time at this state.
DataFrame
  • sample_count: Number of routing samples in interval.
DataFrame
  • station_sequence: Visit order per item (1-based).
DataFrame
  • uuid: Event UUID.

lead_time ¤

lead_time() -> pd.DataFrame

Compute end-to-end lead time per item.

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • item_id
DataFrame
  • first_station: Name of first station/step visited.
DataFrame
  • last_station: Name of last station/step visited.
DataFrame
  • first_seen: Earliest timestamp.
DataFrame
  • last_seen: Latest timestamp.
DataFrame
  • lead_time_seconds: Total elapsed time.
DataFrame
  • stations_visited: Number of distinct stations/steps.
DataFrame
  • routing_path: Ordered station names joined by " -> ".
DataFrame
  • uuid: Event UUID.

station_statistics ¤

station_statistics() -> pd.DataFrame

Compute dwell-time statistics per station/step across all items.

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • station_name
DataFrame
  • routing_value
DataFrame
  • item_count: Number of distinct items seen.
DataFrame
  • min_dwell_seconds
DataFrame
  • avg_dwell_seconds
DataFrame
  • max_dwell_seconds
DataFrame
  • total_dwell_seconds

routing_paths ¤

routing_paths() -> pd.DataFrame

Analyze routing path frequencies -- which station sequences are most common.

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • routing_path: Ordered station names joined by " -> ".
DataFrame
  • item_count: Number of items that followed this path.
DataFrame
  • avg_lead_time_seconds: Average lead time for items on this path.
DataFrame
  • min_lead_time_seconds
DataFrame
  • max_lead_time_seconds