Skip to content

reliability

reliability ¤

Reliability: MTBF, MTTR and Weibull life analysis from a failure-state signal.

Input is one held state signal whose value says whether the asset is failed (down for repair) -- a fault bit, a breakdown status code, a maintenance mode. The timeline is built with :func:ts_shape.signals.primitives.intervals, so each state holds until the next change and a logging gap longer than max_gap is "no data": it counts as neither operating nor repair time.

Definitions (hours throughout):

  • operating time -- time in a non-failed state.
  • repair time (TTR) -- time in a failed state. Consecutive failed intervals separated only by a data gap are one failure.
  • TBF -- operating time between the end of one repair and the next failure.
  • mtbf_hours = operating time / failures (the common definition).
  • mtbf_iso22400_hours = operating time / (failures + 1): ISO 22400-2 averages over the FE + 1 operating periods, including the one still running at the end of the window.
  • mttr_hours = repair time / failures.
  • availability_pct = operating / (operating + repair): inherent availability, the share of known time the asset was not failed.

The Weibull fit treats the operating period still running at the end of the data as right-censored (it has not failed yet), which is what keeps the life estimate from being biased low.

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 beta tells 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,) fits a fault bit; for a status code pass e.g. ("BREAKDOWN", "REPAIR").

(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

uuid of the emitted events.

'maint:reliability'
time_column str

Timestamp column.

'systime'

failure_events ¤

failure_events() -> pd.DataFrame

One interval per failure.

Returns:

Type Description
DataFrame

Intervals start (failure) to end (back in service) with

DataFrame

repair_hours (known failed time; data gaps excluded),

DataFrame

operating_hours_before (operating time since the previous

DataFrame

repair) and first_observed (True when that operating period

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. "1D", "7D", "MS"); None = one row over the whole observation. A failure belongs to the window it starts in; operating and repair time are split exactly at window boundaries.

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 (start, end, duration_seconds, uuid,

DataFrame

source_uuid) with

DataFrame

operating_hours, repair_hours, no_data_hours,

DataFrame

failures, mtbf_hours, mtbf_iso22400_hours,

DataFrame

mttr_hours, availability_pct and

DataFrame

failure_rate_per_hour. Ratios with no failures (or no

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: beta (shape), eta_hours (scale: 63.2 % have

DataFrame

failed by then), mttf_hours (eta * Gamma(1 + 1/beta)),

DataFrame

b10_hours (10 % have failed by then), n_failures,

DataFrame

n_censored and failure_pattern (infant_mortality

DataFrame

for beta < 0.9, random up to 1.1, else wear_out).

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

failure_pattern is "unknown" and a

DataFrame

class:~ts_shape.errors.DataQualityWarning is emitted.

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: R(age + t) / R(age) -- "given it has run 200 h, how likely is it to run another 100 h?".

0.0
include_initial bool

Passed to :meth:weibull_fit.

False

Returns:

Type Description
DataFrame

One row per value of hours: hours, age_hours,

DataFrame

reliability, failure_probability and

DataFrame

hazard_per_hour (instantaneous failure rate at age + t).

DataFrame

Empty when there are too few failures to fit; NaN values when

DataFrame

the fit is degenerate (see :meth:weibull_fit).