Implementation of predictive equipment maintenance (Predictive Maintenance)
Predictive maintenance is a shift from calendar-based (once every N months) to condition-based (when equipment is actually needed). An ML system analyzes sensor data in real time and predicts failures days or weeks in advance, allowing time for scheduled replacements without requiring an emergency shutdown.
Task context
CMMS Maturity Model:
- Level 1: Reactive (repair after failure)
- Level 2: Scheduled (by calendar)
- Level 3: Condition-Based (based on the state of sensors)
- Level 4: Predictive (failure prediction)
- Level 5: Prescriptive (recommendation of optimal timing and type of intervention)
Most industrial enterprises are at levels 2-3. The ML system implements levels 4-5.
ROI:
- Cost of unplanned stop: $5,000-$50,000/hour (depending on production)
- Reduction of emergency stops by 30-50%: significant savings
- Reduction of unnecessary scheduled maintenance: 10-20% savings on spare parts
Data architecture
Multi-level data pyramid:
Уровень 4 (Бизнес): ROI, MTBF, OEE
↑
Уровень 3 (KPI): Health Index, RUL, риск-скор
↑
Уровень 2 (Признаки): FFT, статистики, трендовые фичи
↑
Уровень 1 (Сырые данные): вибрация (5-20 кГц), температура, ток, давление
Sensor stack:
sensor_config = {
# Вибрация — основной диагностический параметр
'vibration': {
'type': 'accelerometer_triaxial',
'sampling_rate': 25600, # Hz (для подшипниковых дефектов нужно 10+ кГц)
'vendors': ['PCB Piezotronics', 'Brüel & Kjær', 'IMC'],
'mounting': 'hard_mount_on_bearing_housing'
},
# Температура — косвенный, но надёжный
'temperature': {
'type': 'PT100 / thermocouple',
'sampling_rate': 1, # Hz достаточно
'typical_fault_signal': 'gradual_rise > 10°C above baseline'
},
# Ток электродвигателя (MCSA — Motor Current Signature Analysis)
'motor_current': {
'type': 'current_transformer',
'sampling_rate': 10000,
'fault_frequency': 'rotor_bar_frequency, eccentricity'
},
# Ультразвук — ранняя детекция подшипниковых дефектов
'ultrasound': {
'type': 'acoustic_emission',
'frequency_range': '20-100 kHz',
'advantage': 'detects lubrication issues earliest'
}
}
Feature Engineering for Predictive Maintenance
Temporary signs from vibration:
import numpy as np
from scipy.stats import kurtosis, skew
from scipy.fft import fft, fftfreq
def extract_vibration_features(vibration_signal, sampling_rate):
"""
Стандартный набор признаков из вибрационного сигнала
"""
n = len(vibration_signal)
# Временная область
time_features = {
'rms': np.sqrt(np.mean(vibration_signal**2)),
'peak': np.max(np.abs(vibration_signal)),
'peak_to_peak': np.ptp(vibration_signal),
'crest_factor': np.max(np.abs(vibration_signal)) / np.sqrt(np.mean(vibration_signal**2)),
'kurtosis': kurtosis(vibration_signal), # > 3 указывает на дефект подшипника
'skewness': skew(vibration_signal),
'shape_factor': np.sqrt(np.mean(vibration_signal**2)) / np.mean(np.abs(vibration_signal))
}
# Частотная область (FFT)
freq = fftfreq(n, 1/sampling_rate)[:n//2]
magnitude = np.abs(fft(vibration_signal))[:n//2]
spectral_features = {
'dominant_frequency': freq[np.argmax(magnitude)],
'spectral_centroid': np.sum(freq * magnitude) / np.sum(magnitude),
'band_power_0_500': np.sum(magnitude[(freq > 0) & (freq < 500)]),
'band_power_500_2000': np.sum(magnitude[(freq >= 500) & (freq < 2000)]),
'band_power_2000_10000': np.sum(magnitude[(freq >= 2000) & (freq < 10000)])
}
# Envelope analysis (для подшипниковых дефектов)
from scipy.signal import hilbert
analytic = hilbert(vibration_signal)
envelope = np.abs(analytic)
env_fft = np.abs(fft(envelope))[:n//2]
envelope_features = {
'envelope_rms': np.sqrt(np.mean(envelope**2)),
'envelope_peak': np.max(envelope),
'envelope_kurtosis': kurtosis(envelope)
}
return {**time_features, **spectral_features, **envelope_features}
BPFO/BPFI tracking:
def track_bearing_defect_frequencies(fft_magnitude, fft_freq, shaft_rpm,
bearing_geometry):
"""
Мониторинг характерных дефектных частот подшипника
Рост амплитуды на этих частотах = развивающийся дефект
"""
bpfo, bpfi, bsf, ftf = calculate_bearing_frequencies(shaft_rpm, bearing_geometry)
results = {}
for name, freq in [('bpfo', bpfo), ('bpfi', bpfi), ('bsf', bsf)]:
freq_idx = np.argmin(np.abs(fft_freq - freq))
# Амплитуда в окне ±5% от целевой частоты
band = fft_magnitude[max(0, freq_idx-5):freq_idx+5]
results[f'{name}_amplitude'] = np.max(band)
# Первые 3 гармоники (характерно для развитых дефектов)
for h in range(2, 4):
harmonic_idx = np.argmin(np.abs(fft_freq - freq * h))
harmonic_band = fft_magnitude[max(0, harmonic_idx-5):harmonic_idx+5]
results[f'{name}_harmonic_{h}'] = np.max(harmonic_band)
return results
ML models for PdM
Multi-class condition classification:
from lightgbm import LGBMClassifier
health_states = {
0: 'normal',
1: 'minor_degradation',
2: 'significant_degradation',
3: 'critical_near_failure'
}
health_classifier = LGBMClassifier(
n_estimators=300,
num_leaves=31,
class_weight='balanced' # имбаланс: class 3 редкий
)
health_classifier.fit(X_labeled, y_health_state)
RUL regression (Remaining Useful Life):
import torch
import torch.nn as nn
class MultiScaleCNNLSTM(nn.Module):
"""
Multi-scale CNN: разные масштабы паттернов деградации
LSTM: временные зависимости
"""
def __init__(self, input_size, hidden_size=128):
super().__init__()
# Мультимасштабный CNN
self.conv1 = nn.Conv1d(input_size, 64, kernel_size=3, padding=1)
self.conv2 = nn.Conv1d(input_size, 64, kernel_size=7, padding=3)
self.conv3 = nn.Conv1d(input_size, 64, kernel_size=15, padding=7)
# LSTM объединяет выходы CNN
self.lstm = nn.LSTM(192, hidden_size, num_layers=2, batch_first=True)
self.fc = nn.Linear(hidden_size, 1) # RUL (нормализованный)
def forward(self, x):
# x: (batch, time, features) → нужно (batch, features, time) для Conv1d
x_t = x.transpose(1, 2)
c1 = torch.relu(self.conv1(x_t))
c2 = torch.relu(self.conv2(x_t))
c3 = torch.relu(self.conv3(x_t))
multi_scale = torch.cat([c1, c2, c3], dim=1).transpose(1, 2)
lstm_out, _ = self.lstm(multi_scale)
return self.fc(lstm_out[:, -1, :])
Training at NASA CMAPSS/PRONOSTIA: Public datasets for validating PdM methods before applying them to real plant data.
Implementation and integration
OPC-UA / OSIsoft PI → Feature Pipeline:
from opcua import Client
def collect_opc_data(server_url, node_ids, sampling_interval_ms=100):
client = Client(server_url)
client.connect()
values = {}
for node_id in node_ids:
node = client.get_node(node_id)
values[node_id] = node.get_value()
return values
# Feature pipeline: каждые 5 минут → агрегация → inference
SAP PM / Maximo work orders: If health score < threshold → automatic creation of a Work Order with the recommended type of intervention.
Reliability Engineer Workflow:
- The system publishes the Health Index on the Grafana dashboard
- In case of a critical state → notification in Slack + CMMS Work Order
- The engineer verifies and sets a maintenance date
- After maintenance: feedback to the model (confirmed / false positive)
Quality metrics
| Metrics | Target |
|---|---|
| AUC-ROC (7-day failure) | > 0.80 |
| False Alarm Rate | < 10% |
| Detection Rate | > 70% bounce rate within 3+ days |
| RMSE RUL | <20% of real RUL |
Deadlines: OPC-UA collector, vibration features, Isolation Forest health score, dashboard — 5-6 weeks. CNN-LSTM RUL model, multi-sensor fusion, CMMS integration, automated work orders — 4-5 months.







