part_tracking
part_tracking ¤
Production tracking by part number.
Simple, practical module for daily production reporting: - How many parts were produced? - Production by part number and time window - Daily summaries
Counters are assumed to be monotonically increasing during normal
operation. Many real-world counters reset back to zero (or to a lower
value) - for example at a shift change, a part change, or a controller
restart. A naive last - first calculation silently loses all of the
production that happened in a window where a reset occurred. Pass
handle_resets=True to account for these resets, and use
:meth:PartProductionTracking.detect_resets to inspect when they happened.
PartProductionTracking ¤
PartProductionTracking(
dataframe: DataFrame, *, time_column: str = "systime"
)
Bases: Base
Track production quantities by part number.
Each UUID represents one signal: - part_id_uuid: string signal with current part number - counter_uuid: monotonic counter for production count
The counter is expected to increase as parts are produced. If the
counter is reset during operation (back to zero or a lower value),
enable handle_resets so the reset is treated as new production
instead of being discarded.
Example usage
tracker = PartProductionTracking(df)
Hourly production by part, accounting for counter resets¤
hourly = tracker.production_by_part( part_id_uuid='part_number_signal', counter_uuid='counter_signal', window='1h', handle_resets=True, )
Daily summary¤
daily = tracker.daily_production_summary( part_id_uuid='part_number_signal', counter_uuid='counter_signal', handle_resets=True, )
When did the counter reset?¤
resets = tracker.detect_resets( part_id_uuid='part_number_signal', counter_uuid='counter_signal', )
Initialize part production tracker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataframe
|
DataFrame
|
Input DataFrame with timeseries data |
required |
time_column
|
str
|
Name of timestamp column (default: 'systime') |
'systime'
|
production_by_part ¤
production_by_part(
part_id_uuid: str,
counter_uuid: str,
*,
window: str = "1h",
value_column_part: str = "value_string",
value_column_counter: str = "value_integer",
handle_resets: bool = False
) -> pd.DataFrame
Calculate production quantity per part number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
part_id_uuid
|
str
|
UUID for part number signal |
required |
counter_uuid
|
str
|
UUID for production counter |
required |
window
|
str
|
Time window for aggregation (e.g., '1h', '8h', '1d') |
'1h'
|
value_column_part
|
str
|
Column containing part numbers |
'value_string'
|
value_column_counter
|
str
|
Column containing counter values |
'value_integer'
|
handle_resets
|
bool
|
When True, treat a decreasing counter as a reset
and count the production after the reset instead of losing
it. The result gains a |
False
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
Example
production_by_part('part_id', 'counter', window='1h') start part_number quantity first_count last_count 0 2024-01-01 08:00:00 PART_A 150 1000 1150 1 2024-01-01 09:00:00 PART_A 145 1150 1295 2 2024-01-01 10:00:00 PART_B 98 1295 1393
With handle_resets=True, a window where the counter drops
from 432 to 61 reports a quantity of 61 (and resets=1)
instead of 0.
detect_resets ¤
detect_resets(
part_id_uuid: str,
counter_uuid: str,
*,
value_column_part: str = "value_string",
value_column_counter: str = "value_integer"
) -> pd.DataFrame
Find the points in time where the counter was reset.
A reset is any reading where the counter value is lower than the previous reading.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
part_id_uuid
|
str
|
UUID for part number signal |
required |
counter_uuid
|
str
|
UUID for production counter |
required |
value_column_part
|
str
|
Column containing part numbers |
'value_string'
|
value_column_counter
|
str
|
Column containing counter values |
'value_integer'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with one row per reset and columns: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
Example
detect_resets('part_id', 'counter') systime part_number count_before count_after drop 0 2026-06-15 17:00:00 8842580 432 61 371 1 2026-06-16 19:00:00 9423376 854 0 854
daily_production_summary ¤
daily_production_summary(
part_id_uuid: str,
counter_uuid: str,
*,
value_column_part: str = "value_string",
value_column_counter: str = "value_integer",
handle_resets: bool = False
) -> pd.DataFrame
Daily production summary by part number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
part_id_uuid
|
str
|
UUID for part number signal |
required |
counter_uuid
|
str
|
UUID for production counter |
required |
value_column_part
|
str
|
Column containing part numbers |
'value_string'
|
value_column_counter
|
str
|
Column containing counter values |
'value_integer'
|
handle_resets
|
bool
|
Account for counter resets (see
:meth: |
False
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
Example
daily_production_summary('part_id', 'counter') date part_number total_quantity hours_active 0 2024-01-01 PART_A 1200 8 1 2024-01-01 PART_B 850 6 2 2024-01-02 PART_A 1150 8
production_totals ¤
production_totals(
part_id_uuid: str,
counter_uuid: str,
*,
start_date: str | None = None,
end_date: str | None = None,
value_column_part: str = "value_string",
value_column_counter: str = "value_integer",
handle_resets: bool = False
) -> pd.DataFrame
Total production by part number for a date range.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
part_id_uuid
|
str
|
UUID for part number signal |
required |
counter_uuid
|
str
|
UUID for production counter |
required |
start_date
|
str | None
|
Start date 'YYYY-MM-DD' (optional) |
None
|
end_date
|
str | None
|
End date 'YYYY-MM-DD' (optional) |
None
|
value_column_part
|
str
|
Column containing part numbers |
'value_string'
|
value_column_counter
|
str
|
Column containing counter values |
'value_integer'
|
handle_resets
|
bool
|
Account for counter resets (see
:meth: |
False
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with total production per part |
Example
production_totals('part_id', 'counter', ... start_date='2024-01-01', end_date='2024-01-07') part_number total_quantity days_produced 0 PART_A 8450 5 1 PART_B 6200 4