Skip to content

Maintenance¤

How to watch an asset wear out and plan the intervention: trends and health scores from condition signals, the time left until a limit, and MTBF, MTTR and Weibull statistics from the failure history. The classes live in ts_shape.events.maintenance.

Example data¤

A press bearing over three days, one sample every 10 minutes: vibration that rises steadily, a temperature that stays put.

import pandas as pd
import ts_shape

kw = dict(n_points=432, freq="10min", start="2024-03-01")
df = pd.concat([
    ts_shape.make_timeseries(["press:vibration"], baseline=2.0, noise=0.05, drift=3.0, **kw),
    ts_shape.make_timeseries(["press:bearing_temp"], baseline=55.0, noise=0.3, **kw),
], ignore_index=True)

Is the signal degrading?¤

DegradationDetectionEvents compares one signal with its own opening period: trends, growing variance, level shifts and a 0-100 health score.

from ts_shape.events.maintenance.degradation_detection import DegradationDetectionEvents

vib = DegradationDetectionEvents(df, "press:vibration")
trend = vib.detect_trend_degradation(window="6h", min_slope=0.0, direction="increasing")
health = vib.health_score(window="6h", baseline_window="12h")
print(health[["systime", "health_score"]].iloc[[0, -1]])

The baseline is the start of the data, so start at a known-good period (after a repair or a calibration).

One score for the asset¤

AssetHealthIndexEvents fuses several signals, each with the failure mode it watches and a weight, into one score per window and projects when it reaches a critical level:

from ts_shape.events.maintenance.asset_health_index import AssetHealthIndexEvents

asset = AssetHealthIndexEvents(
    df, asset_id="press-01",
    signals={"press:vibration": "bearing", "press:bearing_temp": "thermal"},
)
index = asset.health_index(window="6h", baseline_window="12h")
forecast = asset.maintenance_forecast(window="6h", baseline_window="12h", critical_threshold=60.0)
print(forecast[["current_health", "decline_per_day", "recommended_maintenance_days"]].round(1))

How long until the limit?¤

FailurePredictionEvents extrapolates the signal itself to a failure threshold you know from the data sheet or from experience:

from ts_shape.events.maintenance.failure_prediction import FailurePredictionEvents

fp = FailurePredictionEvents(df, "press:vibration")
tte = fp.time_to_threshold(6.0, direction="increasing")
print(tte[["systime", "current_value", "estimated_time_seconds"]].tail(1))

For vibration spectra (RMS, peak, crest factor, bearing frequencies) see Vibration analysis.

Failure history¤

ReliabilityEvents reads a status signal with run and failure states and reports MTBF, MTTR and availability, a Weibull fit of the times between failures, and the probability of surviving the next hours:

import numpy as np
from ts_shape.events.maintenance.reliability import ReliabilityEvents

rng = np.random.default_rng(3)
up_h, down_h = rng.weibull(2.0, 12) * 150, rng.uniform(1, 6, 12)  # 12 run/repair cycles
starts = np.cumsum(np.column_stack([up_h, down_h]).ravel())
status = pd.DataFrame({
    "systime": pd.Timestamp("2024-01-01") + pd.to_timedelta(np.r_[0, starts[:-1]], unit="h"),
    "uuid": "press:status", "value_string": ["RUN", "BREAKDOWN"] * 12,
})
rel = ReliabilityEvents(status, "press:status", failure_states=("BREAKDOWN",),
                        value_column="value_string", max_gap="30D")
print(rel.mtbf_mttr()[["failures", "mtbf_hours", "mttr_hours", "availability_pct"]].round(1))
fit = rel.weibull_fit()   # beta > 1 ("wear_out"): failures increase with age

Which class answers which question¤

Question Class Page
Is one signal trending, getting noisier or shifting? DegradationDetectionEvents Degradation detection
One health score from several signals, and when to intervene? AssetHealthIndexEvents Asset health index
How long until a failure threshold? FailurePredictionEvents Failure prediction
Vibration levels and bearing defect frequencies? VibrationAnalysisEvents Vibration analysis
MTBF, MTTR, Weibull, survival probability? ReliabilityEvents Reliability
Which signal moved before the breakdowns? RootCauseCorrelationEvents Root cause correlation
Hours since service, starts per day? RuntimeAccountingEvents Runtime accounting