Index
maintenance ¤
Maintenance Events
Detectors for maintenance-related patterns: degradation trends, failure prediction, reliability (MTBF / MTTR / Weibull) and vibration analysis for predictive maintenance on manufacturing/industrial IoT time series data.
- AssetHealthIndexEvents: Fuse several degradation signals into one asset health index, weighted by failure-mode criticality.
- health_index: Weighted 0-100 asset score per evaluation window.
- health_events: Point events on warning/critical threshold crossings.
- signal_contributions: Per-signal share of the asset's health loss.
-
maintenance_forecast: Days until the index reaches a critical level.
-
DegradationDetectionEvents: Detect trend degradation, variance increases, level shifts, and compute composite health scores.
- detect_trend_degradation: Rolling linear regression slope detection.
- detect_variance_increase: Rolling variance vs baseline comparison.
- detect_level_shift: CUSUM-like permanent mean shift detection.
-
health_score: Composite 0-100 score from drift, variance, and trend.
-
FailurePredictionEvents: Predict remaining useful life and escalating failure patterns.
- remaining_useful_life: Linear extrapolation to failure threshold.
- detect_exceedance_pattern: Rolling threshold exceedance frequency.
-
time_to_threshold: Rate-of-change based threshold ETA.
-
ReliabilityEvents: Reliability KPIs from a failure-state signal.
- failure_events: One interval per failure with repair and operating time.
- mtbf_mttr: MTBF (common and ISO 22400), MTTR, availability, failure rate.
- weibull_fit: Censored Weibull life model (beta, eta, MTTF, B10).
-
reliability_at: Reliability and hazard ahead, optionally given the age.
-
VibrationAnalysisEvents: Vibration signal analysis for rotating equipment.
- detect_rms_exceedance: Rolling RMS vs baseline threshold.
- detect_amplitude_growth: Peak-to-peak amplitude tracking.
- bearing_health_indicators: Kurtosis and crest factor per window.
AssetHealthIndexEvents ¤
AssetHealthIndexEvents(
dataframe: DataFrame,
asset_id: str,
signals: Mapping[str, str | Mapping[str, Any]],
*,
event_uuid: str = "maint:asset_health",
value_column: str = "value_double",
time_column: str = "systime",
uuid_column: str = "uuid"
)
Bases: Base
Maintenance: multi-signal asset health fusion.
Each asset is described by a mapping of signal UUID to a failure mode (and optionally a weight)::
AssetHealthIndexEvents(
df,
asset_id="press-01",
signals={
"vib:press-01": "bearing",
"temp:press-01": {"failure_mode": "thermal", "weight": 2.0},
"curr:press-01": {"failure_mode": "electrical"},
},
)
A bare string is shorthand for {"failure_mode": <str>, "weight": 1.0}.
Weights express failure-mode criticality: a thermal runaway that scraps
the tool should outweigh a slow bearing drift.
Methods: - health_index: fused 0-100 asset score per window. - health_events: point events when the index crosses warning/critical. - signal_contributions: per-signal breakdown of the health loss. - maintenance_forecast: days until the index reaches a critical level.
Initialize the asset health index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataframe
|
DataFrame
|
Timeseries frame holding every configured signal. |
required |
asset_id
|
str
|
Identifier of the asset the signals belong to. It is
emitted as |
required |
signals
|
Mapping[str, str | Mapping[str, Any]]
|
Mapping of signal UUID to failure mode (string) or to a
|
required |
event_uuid
|
str
|
UUID stamped on emitted events. |
'maint:asset_health'
|
value_column
|
str
|
Column holding the numeric readings. |
'value_double'
|
time_column
|
str
|
Timestamp column. |
'systime'
|
uuid_column
|
str
|
Column identifying the signal. |
'uuid'
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
health_index ¤
health_index(
*, window: str = "1h", baseline_window: str = "24h"
) -> pd.DataFrame
Fuse the configured signals into one asset health score per window.
A signal with no data in a window is skipped rather than scored as
zero; confidence_level reports the share of the configured weight
that was actually available, so a score computed from one of four
signals is visibly weaker evidence than a score from all four.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
window
|
str
|
Evaluation window (e.g. |
'1h'
|
baseline_window
|
str
|
Opening period of each signal used as its healthy reference for drift and variance. |
'24h'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Summary-shape DataFrame: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
health_events ¤
health_events(
*,
window: str = "1h",
baseline_window: str = "24h",
warning_threshold: float = 70.0,
critical_threshold: float = 50.0,
only_crossings: bool = True
) -> pd.DataFrame
Emit an event when the fused index falls to warning or critical.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
window
|
str
|
Evaluation window passed to :meth: |
'1h'
|
baseline_window
|
str
|
Baseline period passed to :meth: |
'24h'
|
warning_threshold
|
float
|
Score at or below which a |
70.0
|
critical_threshold
|
float
|
Score at or below which a |
50.0
|
only_crossings
|
bool
|
When |
True
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Point-shape DataFrame: |
DataFrame
|
|
DataFrame
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
signal_contributions ¤
signal_contributions(
*, window: str = "1h", baseline_window: str = "24h"
) -> pd.DataFrame
Rank the configured signals by how much health they cost the asset.
The contribution of a signal is its mean weighted health deficit
(100 - health) * weight over the evaluated windows, expressed as a
share of the total deficit. A perfectly healthy asset has no deficit
to distribute and every contribution is 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
window
|
str
|
Evaluation window passed to the per-signal scorer. |
'1h'
|
baseline_window
|
str
|
Baseline period passed to the per-signal scorer. |
'24h'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Static-shape DataFrame: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
maintenance_forecast ¤
maintenance_forecast(
*,
window: str = "1h",
baseline_window: str = "24h",
critical_threshold: float = 50.0,
min_confidence: float = 0.5
) -> pd.DataFrame
Project when the asset index reaches critical_threshold.
Fits a least-squares line through the fused index and extrapolates it
to the threshold. confidence is the fit's R²: a flat but noisy
index nearly always slopes slightly one way, so a fit below
min_confidence reports its slope and confidence but no horizon,
rather than handing out a maintenance date the data cannot support.
An index that is flat or improving likewise yields NaN for the
horizon columns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
window
|
str
|
Evaluation window passed to :meth: |
'1h'
|
baseline_window
|
str
|
Baseline period passed to :meth: |
'24h'
|
critical_threshold
|
float
|
Score treated as "intervention required". |
50.0
|
min_confidence
|
float
|
Minimum R² of the trend fit before a horizon is
projected. Pass |
0.5
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Summary-shape DataFrame with a single row: |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DegradationDetectionEvents ¤
DegradationDetectionEvents(
dataframe: DataFrame,
signal_uuid: str,
*,
event_uuid: str = "maint:degradation",
value_column: str = "value_double",
time_column: str = "systime"
)
Bases: Base
Detect degradation patterns in time series signals: trend degradation, variance increases, level shifts, and composite health scores.
Designed for predictive maintenance on manufacturing/industrial IoT data.
detect_trend_degradation ¤
detect_trend_degradation(
window: str = "1h",
min_slope: float = 0.0,
direction: str = "decreasing",
*,
interval_end: str = "next_change"
) -> pd.DataFrame
Detect intervals where a rolling linear regression slope exceeds min_slope in the given direction, indicating trend-based degradation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
window
|
str
|
Rolling window size (e.g. '1h', '30min'). |
'1h'
|
min_slope
|
float
|
Minimum absolute slope to consider degradation. |
0.0
|
direction
|
str
|
'decreasing' (negative slope) or 'increasing' (positive slope). |
'decreasing'
|
interval_end
|
str
|
|
'next_change'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end, uuid, source_uuid, is_delta, |
DataFrame
|
avg_slope, total_change, duration_seconds. |
DataFrame
|
analyzed signal. |
detect_variance_increase ¤
detect_variance_increase(
window: str = "1h",
threshold_factor: float = 2.0,
*,
interval_end: str = "next_change"
) -> pd.DataFrame
Compare rolling variance against a baseline (first window) and flag intervals where the ratio exceeds threshold_factor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
window
|
str
|
Rolling window size. |
'1h'
|
threshold_factor
|
float
|
Minimum variance ratio to flag. |
2.0
|
interval_end
|
str
|
|
'next_change'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end, uuid, source_uuid, is_delta, |
DataFrame
|
baseline_variance, current_variance, ratio, duration_seconds |
DataFrame
|
(float seconds from start to end). |
detect_level_shift ¤
detect_level_shift(
min_shift: float, hold: str = "5min"
) -> pd.DataFrame
CUSUM-like detection for permanent mean shifts in the signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_shift
|
float
|
Minimum absolute shift magnitude to detect. |
required |
hold
|
str
|
Minimum duration the new level must persist. |
'5min'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: systime, uuid, source_uuid, is_delta, |
DataFrame
|
shift_magnitude, prev_mean, new_mean. |
health_score ¤
health_score(
window: str = "1h", baseline_window: str = "24h"
) -> pd.DataFrame
Composite 0-100 health score based on mean drift, variance change, and trend slope, computed over rolling windows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
window
|
str
|
Rolling window for current metrics. |
'1h'
|
baseline_window
|
str
|
Initial period used to establish baseline behavior. |
'24h'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: systime, uuid, source_uuid, is_delta, |
DataFrame
|
health_score, mean_drift_pct, variance_ratio, trend_slope. |
FailurePredictionEvents ¤
FailurePredictionEvents(
dataframe: DataFrame,
signal_uuid: str,
*,
event_uuid: str = "maint:failure_pred",
value_column: str = "value_double",
time_column: str = "systime"
)
Bases: Base
Predict remaining useful life and detect escalating failure patterns in time series signals from manufacturing/industrial IoT systems.
remaining_useful_life ¤
remaining_useful_life(
degradation_rate: float, failure_threshold: float
) -> pd.DataFrame
Estimate remaining useful life (RUL) at each point via linear extrapolation from the recent trend to a failure threshold.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
degradation_rate
|
float
|
Expected rate of change per second (used as fallback if local slope cannot be computed). |
required |
failure_threshold
|
float
|
The signal level that represents failure.
The sign of |
required |
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: systime, uuid, source_uuid, is_delta, |
DataFrame
|
current_value, rul_seconds, rul_hours, confidence. |
DataFrame
|
threshold is reached or passed, and None when no failure is |
DataFrame
|
projected (flat trend, or a trend moving away from the threshold). |
detect_exceedance_pattern ¤
detect_exceedance_pattern(
warning_threshold: float,
critical_threshold: float,
window: str = "1h",
) -> pd.DataFrame
Track frequency of threshold exceedances in rolling windows and flag escalating patterns (increasing exceedance counts).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
warning_threshold
|
float
|
Warning level (absolute value comparison). |
required |
critical_threshold
|
float
|
Critical level (absolute value comparison). |
required |
window
|
str
|
Rolling window size. |
'1h'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end, duration_seconds, uuid, |
DataFrame
|
source_uuid, is_delta, warning_count, critical_count, |
DataFrame
|
escalation_detected. |
time_to_threshold ¤
time_to_threshold(
threshold: float, direction: str = "increasing"
) -> pd.DataFrame
Estimate time to reach a threshold based on recent rate of change.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
threshold
|
float
|
Target threshold value. |
required |
direction
|
str
|
'increasing' or 'decreasing'. |
'increasing'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: systime, uuid, source_uuid, is_delta, |
DataFrame
|
current_value, rate_of_change, estimated_time_seconds. |
ReliabilityEvents ¤
ReliabilityEvents(
dataframe: DataFrame,
run_state_uuid: str,
*,
failure_states: Sequence[object] = (True,),
value_column: str = "value_bool",
max_gap: str | Timedelta | None = None,
data_end: str | Timestamp | None = None,
event_uuid: str = "maint:reliability",
time_column: str = "systime"
)
Bases: Base
Maintenance: reliability KPIs from a failure-state signal.
- failure_events: One interval per failure, with its repair time and the operating time before it.
- mtbf_mttr: MTBF, MTTR, availability and failure rate, overall or per calendar window.
- weibull_fit: Weibull life model of the times between failures, with
right censoring; shape
betatells infant mortality / random / wear-out. - reliability_at: Reliability and hazard at given operating times from the fitted model, optionally conditional on the current age.
Example
import pandas as pd, ts_shape t = pd.date_range("2025-01-01", periods=8, freq="1h") df = pd.DataFrame({"systime": t, "uuid": "fault", "value_bool": ... [False, False, True, False, False, False, True, False]}) kpi = ts_shape.ReliabilityEvents(df, "fault").mtbf_mttr() kpi[["failures", "mtbf_hours", "mttr_hours", "availability_pct"]].round(1) failures mtbf_hours mttr_hours availability_pct 0 2 2.5 1.0 71.4
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataframe
|
DataFrame
|
Long-format data. |
required |
run_state_uuid
|
str
|
The failure-state signal. |
required |
failure_states
|
Sequence[object]
|
Values meaning "failed / down for repair". The
default |
(True,)
|
value_column
|
str
|
Column holding the state. |
'value_bool'
|
max_gap
|
str | Timedelta | None
|
Longest time a state is held; longer gaps are no data. Default None: every state is held until the next sample, however long the gap. |
None
|
data_end
|
str | Timestamp | None
|
End of the observation (e.g. "now"); the last state holds until then. Default: the last sample. |
None
|
event_uuid
|
str
|
|
'maint:reliability'
|
time_column
|
str
|
Timestamp column. |
'systime'
|
failure_events ¤
failure_events() -> pd.DataFrame
One interval per failure.
Returns:
| Type | Description |
|---|---|
DataFrame
|
Intervals |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
repair) and |
DataFrame
|
began before the data did, so its length is a lower bound). |
mtbf_mttr ¤
mtbf_mttr(
window: str | None = None, tz: str | None = None
) -> pd.DataFrame
MTBF, MTTR, availability and failure rate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
window
|
str | None
|
Calendar window (e.g. |
None
|
tz
|
str | None
|
Timezone for the window grid (DST-correct day lengths). Default: the data's timezone. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Summary rows ( |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
|
DataFrame
|
known time) are NaN. |
weibull_fit ¤
weibull_fit(include_initial: bool = False) -> pd.DataFrame
Two-parameter Weibull model of the times between failures.
Fitted by maximum likelihood (scipy.stats.weibull_min, location
fixed at 0). The operating period still running at the end of the
data is right-censored.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
include_initial
|
bool
|
Also use the operating time before the first failure as a complete observation. Off by default: that period started before the data did, so the asset's age at the first failure is unknown. |
False
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
One row: |
DataFrame
|
failed by then), |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
for beta < 0.9, |
DataFrame
|
Empty when fewer than two failure intervals are available. |
DataFrame
|
When the times between failures (almost) all have the same |
DataFrame
|
length, the model has no finite fit: the parameters are NaN, |
DataFrame
|
|
DataFrame
|
class: |
reliability_at ¤
reliability_at(
hours: Sequence[float],
age_hours: float = 0.0,
include_initial: bool = False,
) -> pd.DataFrame
Reliability and hazard from the fitted Weibull model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hours
|
Sequence[float]
|
Operating hours ahead to evaluate. |
required |
age_hours
|
float
|
Operating hours already survived since the last
repair. Reliability is then conditional:
|
0.0
|
include_initial
|
bool
|
Passed to :meth: |
False
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
One row per value of |
DataFrame
|
|
DataFrame
|
|
DataFrame
|
Empty when there are too few failures to fit; NaN values when |
DataFrame
|
the fit is degenerate (see :meth: |
VibrationAnalysisEvents ¤
VibrationAnalysisEvents(
dataframe: DataFrame,
signal_uuid: str,
*,
event_uuid: str = "maint:vibration",
value_column: str = "value_double",
time_column: str = "systime"
)
Bases: Base
Analyze vibration signals from industrial equipment: RMS exceedance, amplitude growth, and bearing health indicators (kurtosis, crest factor).
detect_rms_exceedance ¤
detect_rms_exceedance(
baseline_rms: float,
threshold_factor: float = 1.5,
window: str = "1min",
*,
interval_end: str = "next_change"
) -> pd.DataFrame
Compute rolling RMS and flag intervals exceeding baseline_rms * threshold_factor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
baseline_rms
|
float
|
Known baseline RMS value for healthy equipment. |
required |
threshold_factor
|
float
|
Multiplier above baseline to trigger alarm. |
1.5
|
window
|
str
|
Rolling window size. |
'1min'
|
interval_end
|
str
|
|
'next_change'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end, uuid, source_uuid, is_delta, |
DataFrame
|
rms_value, baseline_rms, ratio, duration_seconds. |
detect_amplitude_growth ¤
detect_amplitude_growth(
window: str = "1h", growth_threshold: float = 0.1
) -> pd.DataFrame
Track peak-to-peak amplitude in non-overlapping windows and flag windows where amplitude grows beyond growth_threshold relative to baseline.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
window
|
str
|
Window size for amplitude measurement. |
'1h'
|
growth_threshold
|
float
|
Minimum fractional growth (e.g. 0.1 = 10%) to flag. |
0.1
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end, duration_seconds, uuid, |
DataFrame
|
source_uuid, is_delta, amplitude, baseline_amplitude, growth_pct. |
DataFrame
|
|
bearing_health_indicators ¤
bearing_health_indicators(
window: str = "5min",
) -> pd.DataFrame
Compute bearing health indicators per window: RMS, peak value, crest factor (peak/RMS), and kurtosis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
window
|
str
|
Window size for indicator computation. |
'5min'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with columns: start, end, duration_seconds, uuid, |
DataFrame
|
source_uuid, is_delta, rms, peak, crest_factor, kurtosis. |
DataFrame
|
|