| list_signalsA | List signal files on disk or signals loaded in the repository. scope='disk' (default): files under data/signals/ that load_signal can
open — use before loading. scope='memory': signals currently cached in
the in-memory repository with their metadata (signal_id, sampling_rate,
declared unit) — use to see which signal_ids are available for analysis.
Args:
ctx: MCP context.
scope: 'disk' for loadable files, 'memory' for loaded signal_ids.
Returns:
Dict with scope, count, and either 'files' (relative paths, disk)
or 'signals' (StoredSignalInfo entries, memory).
|
| generate_test_signalA | Generate a synthetic test signal, save it, and load it into the repository. The signal is written to data/signals/ with a timestamped filename and a
companion _metadata.json declaring sampling_rate and signal_unit='g'
(synthetic acceleration), then auto-registered in the repository — the
returned signal_id is immediately usable by every analysis, diagnosis,
and ISO severity tool with no manual steps.
Signal content: 'bearing_fault' = 10 Hz impacts modulating a 1 kHz
carrier; 'gear_fault' = 200 Hz mesh tone + harmonics; 'imbalance' =
25 Hz (1500 RPM) tone; 'normal' = broadband noise.
Args:
signal_type: Synthetic fault pattern to generate.
duration: Signal duration in seconds (10 s gives 0.1 Hz resolution).
sampling_rate: Sampling frequency in Hz.
noise_level: Additive white-noise amplitude.
random_seed: Seed for reproducible noise (None = non-deterministic).
ctx: MCP context.
Returns:
StoredSignalInfo of the auto-loaded signal (signal_id, declared
sampling_rate and unit 'g').
|
| load_signalA | Load one signal — or a batch — into the in-memory repository. Once loaded, reference the signal by its signal_id in every analysis,
diagnosis, report, and prognostics tool (the load -> analyze ->
diagnose -> report flow uses signal_id as the single handle).
Batch form: pass a LIST of file paths (e.g. for training sets). The
batch is fail-fast and atomic — all paths and derived ids are
validated up front, and on the first problem ONE error names the
offending entries and nothing is loaded. One declared sampling_rate/
signal_unit applies to all files; per-file metadata wins only when
the parameter is omitted. Custom signal_id is not allowed for a
batch (ids derive from each file's relative path).
signal_id default: the path relative to data/signals/ with separators
replaced by underscores — 'real_train/baseline_1.csv' loads as
'real_train_baseline_1', so same-named files in different folders
never collide silently. Re-loading a path whose id already exists is
an explicit error unless overwrite=True.
Signal unit discipline: ISO 20816-3 severity verdicts require a
DECLARED unit — either via this parameter or a 'signal_unit' field in
the companion _metadata.json (explicit parameter wins). Units are
never guessed from signal amplitude; without a declared unit the ISO
severity block is refused with a structured reason and remedy.
Args:
filepath: Filename relative to data/signals/ or absolute path —
or a list of such paths for an atomic batch load.
signal_id: Custom ID (single-file loads only; default derives
from the relative path).
sampling_rate: Sampling rate in Hz (overrides metadata file).
signal_unit: Declared signal unit — 'g' or 'm/s2' (acceleration),
'mm/s' or 'm/s' (velocity). Overrides the metadata file.
overwrite: Replace existing entries on signal_id collision
instead of raising.
Returns:
StoredSignalInfo for a single load; a list of StoredSignalInfo
(input order) for a batch.
Raises:
ValueError: If signal_unit is invalid, the signal data cannot be
loaded, a signal_id collides without overwrite=True, or a
batch contains any invalid entry (nothing is loaded).
|
| get_signal_infoA | Get metadata for a stored signal without loading the full array. Includes the COMPLETE companion-metadata dict (source_metadata: rpm/
shaft_speed, reference frequencies, ...) alongside the repository
fields (sampling_rate, declared signal_unit, shape, timestamps).
Args:
ctx: MCP context.
signal_id: ID of a signal previously loaded via load_signal.
Returns:
StoredSignalInfo with source_metadata populated from the companion
_metadata.json (empty dict when the file has none).
Raises:
ValueError: If the signal_id is not in the repository.
|
| clear_signalsA | Remove one signal — or all signals — from the in-memory repository. Args:
ctx: MCP context.
signal_id: ID to remove; None (default) clears the whole cache.
Returns:
Dict with cleared_count, plus signal_id and status ('removed' or
'not_found') for single-signal calls.
|
| analyze_fftA | Perform FFT (Fast Fourier Transform) analysis on a stored signal.
FFT analysis converts the signal from time domain to frequency domain,
allowing identification of harmonic components and faults that manifest
at specific frequencies. Requires the signal loaded via load_signal()
first; the sampling rate comes from the stored signal metadata.
By default analyzes the LEADING 1.0-second segment (deterministic:
two identical calls return identical results). Set
segment_duration=None to analyze the entire signal, or pass
random_seed to sample a seeded random segment position instead.
Args:
ctx: MCP context for user communication
signal_id: ID of the stored signal (from load_signal).
max_frequency: Maximum frequency to analyze (default: Nyquist frequency)
segment_duration: Duration in seconds to analyze (default: leading
1.0 s). Set to None to analyze the full signal.
random_seed: Seed for random segment position (default: None =
deterministic leading segment).
Returns:
FFTResult with top peaks, dominant peak, and spectrum stats.
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate.
|
| analyze_envelopeA | Envelope-spectrum analysis of a stored signal (bearing fault screening).
THE unified envelope tool: bandpass filter -> Hilbert
envelope -> mean subtraction + Hann window -> FFT -> top peaks.
The mean subtraction/window step is an intentional U9 fix: the
envelope's DC leakage used to bury the low-frequency FTF zone.
Requires the signal loaded via load_signal() first; the sampling
rate comes from the stored signal metadata.
The requested band must fit the signal: an invalid band (low <= 0,
low >= high, high > Nyquist) raises a ValueError — it is NEVER
silently clamped. The band used is echoed in the result.
By default analyzes the LEADING 1.0-second segment (deterministic:
two identical calls return identical results). Set
segment_duration=None to analyze the entire signal, or pass
random_seed to sample a seeded random segment position instead.
No reference bearing frequencies are assumed: compare the returned
peaks against frequencies computed for the actual bearing and
shaft speed (check_bearing_faults or
calculate_bearing_characteristic_frequencies).
Args:
ctx: MCP context for user communication
signal_id: ID of the stored signal (from load_signal).
filter_low: Bandpass low edge in Hz (default: 500).
filter_high: Bandpass high edge in Hz (default: 5000). Must
not exceed the signal's Nyquist frequency.
num_peaks: Number of top peaks to return (default: 5).
segment_duration: Duration in seconds to analyze (default:
leading 1.0 s). None analyzes the full signal.
random_seed: Seed for random segment position (default: None =
deterministic leading segment).
Returns:
EnvelopeResult with the band actually used, top peaks, and
comparison guidance.
Raises:
ValueError: If the signal_id is not loaded, the stored signal
has no sampling rate, or the band is invalid vs Nyquist.
|
| analyze_statisticsA | Calculate statistical parameters of a stored signal for diagnostics.
Statistical parameters are key indicators for diagnostics:
- RMS: Effective value, correlated to signal energy
- Crest Factor: Indicates presence of impulses (high = possible faults)
- Kurtosis: Measures impulsiveness (excess kurtosis; >0 = non-Gaussian, >3 = strong impulses)
- Peak-to-Peak: Signal range
Requires the signal loaded via load_signal() first. Statistical
parameters are screening indicators, not definitive diagnostics —
combine with frequency-domain evidence.
**Signal units:** all values are in the signal's native unit. The unit
is reported only when DECLARED — load_signal(signal_unit=...) or the
companion _metadata.json — and never guessed from signal amplitude.
ISO 20816-3 severity tools refuse to produce a verdict until the unit
is declared.
Args:
signal_id: ID of the stored signal (from load_signal).
Returns:
StatisticalResult with all statistical parameters
Raises:
ValueError: If the signal_id is not loaded.
|
| extract_features_from_signalA | Extract time-domain features from a stored signal using sliding windows.
Segments the signal into overlapping windows and extracts 17 statistical features
from each segment. Features include: mean, std, RMS, kurtosis, crest factor, entropy, etc.
Requires the signal loaded via load_signal() first; the sampling rate
comes from the stored signal metadata. Returns an in-memory summary
only — no CSV is written to data/signals/.
Args:
signal_id: ID of the stored signal (from load_signal).
segment_duration: Duration of each segment in seconds (default: 0.1)
overlap_ratio: Overlap between segments, 0-1 (default: 0.5 = 50%)
ctx: MCP context for progress/logging
Returns:
FeatureExtractionResult with features matrix and metadata
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate.
Example:
extract_features_from_signal(
"healthy_motor",
segment_duration=0.2,
overlap_ratio=0.5
)
|
| compute_power_spectral_densityA | Compute Power Spectral Density (Welch method) for a stored signal. Requires signal loaded via load_signal() first.
Args:
signal_id: ID of the stored signal.
nperseg: Samples per FFT segment (default 256).
noverlap: Overlap between segments (default 128).
window: Window function (default 'hann').
|
| compute_spectrogram_stftA | Compute STFT spectrogram for a stored signal. Returns time-frequency summary (no full 2D array). Use for detecting
time-varying frequency content (transient faults, speed changes).
Args:
signal_id: ID of the stored signal.
nperseg: Samples per STFT segment (default 256).
noverlap: Overlap between segments (default 128).
window: Window function (default 'hann').
|
| assess_severityA | Assess vibration severity (ISO 20816-3 zones A-D) and alert level. THE unified severity tool: ISO zone assessment and alert
classification in one call. Zone boundary values are those of
ISO 10816-3:2009 (ISO 20816-3:2022 merges zones A/B — provenance is
noted in the result). Scope: machines rated above 15 kW; a declared
machine_power_kw below 15 kW is refused.
Input routes (exactly ONE required):
- signal_id: a stored signal (load_signal first). Sampling rate AND
declared unit come from the stored metadata; an undeclared unit is
refused, never guessed from amplitude.
- rms_velocity_mm_s: a direct broadband RMS velocity reading in mm/s
(e.g. from a portable instrument) — no unit declaration needed.
Args:
ctx: MCP context.
signal_id: ID of the stored signal (mutually exclusive with
rms_velocity_mm_s).
rms_velocity_mm_s: Direct broadband RMS velocity in mm/s
(mutually exclusive with signal_id).
machine_group: 1 (large, >300 kW) or 2 (medium, 15-300 kW).
Ignored when custom thresholds are given. Default 2.
support_type: 'rigid' or 'flexible'. Ignored when custom
thresholds are given. Default 'rigid'.
thresholds: Optional custom zone boundaries {'warning': A/B,
'alarm': B/C, 'danger': C/D} in mm/s, strictly increasing —
replaces the ISO table for this call.
machine_power_kw: Rated machine power, if known. Declared values
below 15 kW are refused (out of ISO scope); None means
unknown and is not refused.
rpm: Operating speed in RPM (signal route only: selects the 2 Hz
band lower edge below 600 RPM).
Returns:
VibrationSeverityResult (status='assessed') with zone, severity,
boundaries, derived alert_level/exceeded_threshold, and threshold
provenance.
Raises:
ValueError: On route misuse (both/neither inputs), undeclared
signal unit, missing sampling rate, Nyquist below the ISO
band, declared power below 15 kW, negative RMS, or invalid
custom thresholds.
|
| train_anomaly_modelA | Train ML-based anomaly detection model on healthy data (UNSUPERVISED/SEMI-SUPERVISED).
All signals are referenced by signal_id: load them first with
load_signal — its batch form accepts a list of file paths, e.g.
load_signal(filepath=["real_train/baseline_1.csv", ...]). Each
signal's sampling rate comes from its stored metadata.
Complete pipeline:
1. Extract features from healthy signals (segmentation + time-domain features)
2. Standardize features (StandardScaler - fitted on training data only)
3. Dimensionality reduction (PCA with specified variance explained)
4. Train novelty detection model (OneClassSVM or LocalOutlierFactor) on HEALTHY DATA ONLY
5. Optional hyperparameter tuning using validation data (semi-supervised)
6. Save model, scaler, and PCA transformer
**Training Mode:**
- UNSUPERVISED: Train only on healthy data with automatic hyperparameters
- SEMI-SUPERVISED: Train on healthy data, tune hyperparameters using validation set (healthy + fault)
**Note:** This is NOT supervised learning. OneClassSVM/LOF are trained ONLY on healthy data.
Fault data (if provided) is used ONLY for hyperparameter tuning after training.
**Validation Strategy:**
- If healthy_validation_ids provided: Use those explicitly (no split)
- If healthy_validation_ids NOT provided: Automatic 80/20 split of training data
- If fault_signal_ids provided: Enable semi-supervised mode (hyperparameter tuning)
Args:
healthy_signal_ids: Stored signal IDs with healthy machine data (for training)
segment_duration: Segment duration in seconds (default: 0.1)
overlap_ratio: Overlap ratio 0-1 (default: 0.5)
model_type: 'OneClassSVM' or 'LocalOutlierFactor' (default: 'OneClassSVM')
pca_variance: Cumulative variance to explain with PCA (default: 0.95)
fault_signal_ids: Optional stored signal IDs for HYPERPARAMETER TUNING (semi-supervised)
healthy_validation_ids: Optional stored healthy signal IDs for validation (specificity check).
If not provided, 20% of training data will be used.
model_name: Name for saved model files (default: 'anomaly_model')
ctx: MCP context for progress/logging
Returns:
AnomalyModelResult with model paths and performance metrics
Raises:
ValueError: If a signal_id is not loaded or has no sampling rate,
or model_name/model_type is invalid.
|
| predict_anomaliesA | Predict anomalies in a stored signal using a trained model.
Requires the signal loaded via load_signal() first and a model
trained via train_anomaly_model (its result echoes the model_name
to pass here). Pipeline: segment -> features -> scaler -> PCA ->
predict -> aggregate.
Output is BOUNDED: counts, anomaly ratio, score percentiles, and
up to 10 worst segments — never per-segment arrays, regardless of
signal length.
Args:
signal_id: ID of the stored signal to analyze (from load_signal)
model_name: Name of trained model (default: 'anomaly_model')
ctx: MCP context for progress/logging
Returns:
AnomalyPredictionResult with aggregate statistics and health
assessment.
Raises:
FileNotFoundError: If the model does not exist (the message
lists the models actually on disk).
ValueError: If the signal_id is not loaded, or no sampling rate
is available for segmentation.
|
| list_machine_manualsA | List all machine manuals in resources/machine_manuals/ (PDF/TXT).
Use before read_manual_excerpt / extract_manual_specs, and pass the
returned filenames exactly as-is.
Returns:
List of dicts with filename, size_mb, modified, and path.
|
| extract_manual_specsA | Extract machine specifications from an equipment manual (PDF).
Extracts bearing designations (e.g. SKF 6205), operating speeds
(RPM), power ratings (kW/HP/MW), and a text excerpt. Results are
cached. If a bearing's geometry is not in the manual, follow up
with search_bearing_catalog(bearing_id=...); if it is not in the
catalog either, ask the user for the geometry — never invent it.
Args:
file_name: Manual filename in resources/machine_manuals/
use_cache: Use cached extraction if available (default: True)
ctx: MCP context
Returns:
Dictionary with extracted specifications and text excerpt.
Raises:
FileNotFoundError: If the manual does not exist (the message
lists the available manuals).
|
| calculate_bearing_characteristic_frequenciesA | Calculate bearing characteristic frequencies from geometry.
Standard rolling-element kinematic formulas (Randall & Antoni 2011,
"Rolling element bearing diagnostics — A tutorial", MSSP 25(2)).
Requires the EXACT geometry — from the manual, the catalog
(search_bearing_catalog), or the user; never guessed. Deep-groove
ball bearings have contact_angle_deg = 0.
Args:
num_balls: Number of rolling elements (Z)
ball_diameter_mm: Ball/roller diameter (Bd) in mm
pitch_diameter_mm: Pitch circle diameter (Pd) in mm
contact_angle_deg: Contact angle (alpha) in degrees
rpm: Shaft rotation speed in RPM
ctx: MCP context
Returns:
Dictionary with BPFO, BPFI, BSF, FTF in Hz.
Example:
>>> # 6205 geometry (CWRU Bearing Data Center) at 1797 RPM
>>> freqs = calculate_bearing_characteristic_frequencies(
... num_balls=9, ball_diameter_mm=7.94,
... pitch_diameter_mm=39.04, rpm=1797
... )
>>> round(freqs['BPFO'], 2)
107.36
|
| read_manual_excerptA | Read a text excerpt from a machine manual (PDF or TXT).
Use for consecutive-page reading; for targeted questions prefer
search_documentation. Start with max_pages=10 and increase only if
needed (pages consume tokens).
Args:
file_name: Manual filename in resources/machine_manuals/
(PDF or TXT)
max_pages: Maximum pages to extract (ignored for TXT files)
ctx: MCP context
Returns:
Extracted text from the manual.
Raises:
FileNotFoundError: If the manual does not exist.
|
| search_bearing_catalogA | Search for bearing specifications in the local verified catalog.
Fallback for when the machine manual names a bearing but not its
geometry. The catalog is small BY DESIGN: only entries whose
geometry is traceable to a public source (mandatory `source`
citation). A miss is a legitimate negative outcome — ask the user
for the geometry; never guess it.
Args:
bearing_id: Bearing designation (e.g. "6205", "SKF 6205-2RS")
ctx: MCP context
Returns:
Dictionary with bearing specifications if found, or a
BearingCatalogMiss (status='not_found', suggestion,
catalog_contains) when the bearing is not in the catalog.
Raises:
Exception: If the catalog itself cannot be read (missing or
malformed common_bearings_catalog.json).
|
| search_documentationA | Semantic search across all machine manuals and bearing catalogs.
Uses vector retrieval (RAG) to find the most relevant passages from
PDFs, text files, and JSON catalogs in resources/.
Backends (chosen automatically):
- FAISS + sentence-transformers (pip install predictive-maintenance-mcp[vector-search])
- TF-IDF keyword search (default, zero extra deps)
The index is built lazily on first call and cached on disk. It is
automatically rebuilt when source files change.
Args:
query: Natural-language question or keywords
(e.g. "bearing 6205 geometry", "maintenance interval pump")
top_k: Number of passages to return (default: 5)
force_reindex: Rebuild the index even if cache is fresh (default: False)
ctx: MCP context
Returns:
Dictionary with ranked results, each containing text passage, source
file, relevance score, and chunk index.
|
| check_bearing_faultsA | Check expected fault frequencies in a stored signal's envelope spectrum. THE unified bearing-check tool: catalog lookup, explicit
frequencies, or explicit geometry in one call. Requires the signal
loaded via load_signal() first.
Expected-frequency routes (exactly ONE required):
- bearing_id: catalog lookup (verified entries only) — BPFO/BPFI/BSF/
FTF computed from the catalog geometry; the entry's source citation
is echoed in the result.
- frequencies: explicit {label: hz} dict — for bearings not in the
catalog or non-bearing checks such as a gearbox GMF
(e.g. {"GMF": 350.0}). Labels BPFO/BPFI/BSF/FTF map to the
canonical fault vocabulary; other labels have no canonical form.
- explicit geometry: num_balls + ball_diameter_mm + pitch_diameter_mm
(+ contact_angle_deg) — frequencies computed from user-provided
geometry (out-of-catalog path).
Each check reports fault_type_canonical (outer_race / inner_race /
ball / cage) alongside the acronym.
Args:
ctx: MCP context.
signal_id: ID of the stored signal.
rpm: Shaft speed in RPM.
bearing_id: Bearing designation (e.g. '6205', 'SKF 6205-2RS').
frequencies: Explicit expected frequencies {label: hz}, all > 0.
num_balls: Number of rolling elements (explicit-geometry route).
ball_diameter_mm: Ball/roller diameter Bd in mm.
pitch_diameter_mm: Pitch circle diameter Pd in mm.
contact_angle_deg: Contact angle in degrees (default 0.0).
tolerance_pct: Frequency matching tolerance in percent (default 5).
Returns:
BearingFaultsSummary with one check per expected frequency,
overall assessment, most likely fault (+ canonical form), and the
provenance of the expected frequencies (`source`).
Raises:
ValueError: If the signal is not loaded / has no sampling rate, if
not exactly one route is given, if the geometry is incomplete,
if the bearing is not in the catalog, or if frequencies is
empty / non-positive.
|
| diagnose_vibrationA | Full integrated diagnosis: FFT + PSD + STFT + bearing faults + ISO severity. Comprehensive vibration diagnostic pipeline. Loads signal from repository,
runs all analyses, and synthesizes results into an actionable report.
The ISO severity block uses ISO 20816-3 machine group/support type
(zone boundaries from ISO 10816-3:2009, provenance noted in output).
The diagnosis DEGRADES instead of failing when the ISO verdict cannot
be produced honestly: if the stored signal has no declared unit (or
the sampling rate cannot cover the ISO evaluation band), the
iso_severity block is a structured refusal (status='refused' with
reason and remedy) while the spectral, bearing, and anomaly blocks
still run. Units are never guessed from amplitude — declare them via
load_signal(signal_unit=...) or the companion _metadata.json.
Args:
signal_id: ID of the stored signal.
rpm: Machine operating speed in RPM.
bearing_id: Bearing designation for fault detection (optional).
machine_group: 1 (large, >300 kW) or 2 (medium, 15-300 kW).
Default 2.
support_type: 'rigid' or 'flexible'. Default 'rigid'.
Raises:
ValueError: If the stored signal has no sampling rate.
|
| generate_diagnostic_report_docxA | Generate a structured Word (.docx) diagnostic report for a stored signal.
Requires: ``pip install predictive-maintenance-mcp[docx]``
``sections`` is a dict whose keys define what to include (all optional):
- statistics: dict (RMS, Kurtosis, Crest Factor …)
- fft_peaks: list [{frequency, magnitude_db, note}, …]
- envelope_peaks: list [{frequency, magnitude_db, match}, …]
- bearing_frequencies: dict {BPFO, BPFI, BSF, FTF}
- iso: dict (mapped from assess_severity output)
- diagnosis: str (free-text diagnostic summary)
Args:
signal_id: ID of the stored signal (from load_signal); used for
the report title / filename.
sections: Content sections to include (see above)
title: Optional custom report title
ctx: MCP context
Returns:
Dictionary with file_path, file_name, and per-section summary.
Raises:
ValueError: If the signal_id is not loaded, or python-docx is
not installed.
|
| plot_signalA | Generate interactive time-domain plot for a stored signal.
Creates an interactive HTML plot showing the signal in the time domain.
Useful for inspecting signal quality, identifying anomalies, and
visualizing transients. Requires the signal loaded via load_signal()
first; the sampling rate comes from the stored signal metadata.
Args:
signal_id: ID of the stored signal (from load_signal).
time_range: [start_time, end_time] in seconds to zoom on a portion (optional)
show_statistics: Show RMS, peak levels as horizontal lines (default: True)
title: Custom plot title (optional)
ctx: MCP context for progress/logging
Returns:
Path to generated HTML file
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate.
Example:
plot_signal(
"bearing_signal",
time_range=[0.1, 0.3], # Zoom on 100-300 ms
show_statistics=True
)
|
| generate_fft_reportA | Generate an interactive FFT spectrum report (HTML) for a stored signal.
Saves a self-contained Plotly HTML report (spectrum in dB, automatic
peak detection, harmonic labels) to the reports/ directory with a
timestamped filename — consecutive runs produce distinct files.
Requires the signal loaded via load_signal() first; the sampling
rate comes from the stored signal metadata.
Args:
signal_id: ID of the stored signal (from load_signal).
max_freq: Maximum frequency to display (Hz). Default 5000 Hz
num_peaks: Number of peaks to detect and label. Default 15
rpm: Optional shaft speed in RPM — peaks at integer multiples
of rpm/60 Hz are labeled as 1x/2x/... harmonics.
ctx: MCP context
Returns:
Dictionary with file path, metadata, and summary (NO HTML content)
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate.
|
| generate_envelope_reportA | Generate professional envelope analysis report (HTML) for a stored signal.
Generates a professional HTML report file instead of inline content.
Saves to reports/ directory. Requires the signal loaded via
load_signal() first; the sampling rate comes from the stored signal
metadata. Reference bearing frequencies (BPFO/BPFI/BSF/FTF) can be
passed explicitly or, if omitted, are read from the source file's
companion _metadata.json when present.
Args:
signal_id: ID of the stored signal (from load_signal).
filter_low: Bandpass filter low cutoff (Hz). Default 500 Hz
filter_high: Bandpass filter high cutoff (Hz). Default (None)
adapts to the signal: min(5000, Nyquist-1). An explicit value
above Nyquist is rejected, never clamped.
max_freq: Max envelope spectrum frequency to display. Default 500 Hz
num_peaks: Number of peaks to detect. Default 15
bearing_freqs: Optional dict with BPFO, BPFI, BSF, FTF
ctx: MCP context
Returns:
Dictionary with file path, metadata, and summary (NO HTML content)
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate.
Example:
>>> # Bearing frequencies computed for YOUR bearing/rpm (here: 6205
>>> # per CWRU geometry at 1797 RPM)
>>> result = generate_envelope_report(
... "real_train_OuterRaceFault_1",
... bearing_freqs={"BPFO": 107.36, "BPFI": 162.19, "BSF": 70.58, "FTF": 11.93}
... )
|
| generate_iso_reportA | Generate an ISO 20816-3 evaluation report (HTML) for a stored signal.
Saves a self-contained Plotly HTML report (color-coded A-D zone
chart with the measured RMS marker, boundaries, severity text) to
the reports/ directory with a timestamped filename. The evaluation
itself is delegated to assess_severity — requires the signal loaded
via load_signal() first with sampling rate AND a declared unit
(units are never guessed).
Args:
signal_id: ID of the stored signal (from load_signal).
machine_group: 1 (large, >300 kW) or 2 (medium, 15-300 kW)
support_type: 'rigid' or 'flexible'
rpm: Operating speed in RPM (optional; selects the ISO band's
lower edge below 600 RPM)
ctx: MCP context
Returns:
Dictionary with file path, metadata, and summary (NO HTML content)
Raises:
ValueError: If the signal_id is not loaded, or the stored signal
has no sampling rate or no declared unit.
|
| list_html_reportsA | List HTML reports, or get one report's embedded metadata.
Without file_name: lists every report in reports/ with file name,
type, signal, and size. With file_name: returns that report's
embedded metadata block (absorbed get_report_info). Never returns
HTML content — metadata only, to avoid token consumption.
Args:
file_name: Optional report filename inside reports/ — returns
its metadata instead of the listing.
Returns:
List of report summaries (no file_name), or a dict with the
single report's metadata (file_name given).
Raises:
ValueError: If file_name escapes the reports directory, does
not exist, or carries no metadata block.
|
| generate_pca_visualization_reportA | Generate PCA visualization HTML report showing test data in 2D PCA space.
Creates interactive scatter plot with:
- Test/prediction data (green = predicted healthy, red = predicted anomaly)
- PC1 vs PC2 axes with variance explained
- Hover information showing segment details and prediction status
**IMPORTANT**: Labels show MODEL PREDICTIONS, not ground truth. Use `true_labels`
parameter to provide actual labels for validation visualization.
Requires the test signals loaded via load_signal() first; each
signal's sampling rate comes from its stored metadata.
Args:
model_name: Name of trained model (e.g., 'bearing_health_model')
test_signal_ids: Optional list of stored signal IDs to predict and visualize
true_labels: Optional dict mapping signal_ids to true labels.
Format: {"real_test_baseline_3": "healthy",
"real_test_InnerRaceFault_vload_6": "faulty"}
When provided, legend shows both true and predicted labels for validation.
segment_duration: Segment duration in seconds (default: 0.1s for ML)
overlap_ratio: Overlap ratio 0-1 (default: 0.5)
ctx: MCP context
Returns:
Dictionary with file path, metadata, and summary (includes validation metrics if true_labels provided)
Raises:
FileNotFoundError: If the model does not exist.
ValueError: If a signal_id is not loaded or has no sampling rate.
Example (with validation):
>>> generate_pca_visualization_report(
... model_name="bearing_health_model",
... test_signal_ids=["real_test_baseline_3", "real_test_InnerRaceFault_vload_6"],
... true_labels={"real_test_baseline_3": "healthy",
... "real_test_InnerRaceFault_vload_6": "faulty"}
... )
|
| generate_feature_comparison_reportA | Generate feature comparison report with violin plots comparing time-domain features.
Creates interactive HTML report with violin plots showing distribution of 17
time-domain features across different signal groups (e.g., Healthy vs Faulty).
Requires every signal loaded via load_signal() first; each signal's
sampling rate comes from its stored metadata.
**Strategy**: Same HTML report approach as other reports. Useful for understanding
which features are most discriminative for fault detection.
Args:
signal_groups: Dictionary mapping group names to lists of stored
signal IDs.
Example: {"Healthy": ["real_train_baseline_1"],
"Faulty": ["real_train_OuterRaceFault_1"]}
segment_duration: Segment duration in seconds (default: 0.1s for ML)
overlap_ratio: Overlap ratio 0-1 (default: 0.5)
features_to_plot: List of feature names to plot (default: all 17 features)
ctx: MCP context
Returns:
Dictionary with file path, metadata, and summary
Raises:
ValueError: If a signal_id is not loaded or has no sampling rate.
Example:
>>> generate_feature_comparison_report(
... signal_groups={
... "Healthy": ["real_train_baseline_1", "real_train_baseline_2"],
... "Inner Fault": ["real_train_InnerRaceFault_vload_1"],
... "Outer Fault": ["real_train_OuterRaceFault_1"]
... }
... )
|
| estimate_rulA | Estimate Remaining Useful Life from repeated measurements over time. RUL is only physically meaningful when fitted on a degradation trend
across MULTIPLE measurements of the same machine taken at different
times (days/weeks/months apart). This tool refuses a single
recording or single point — for within-recording screening use
analyze_signal_trend instead.
Two mutually exclusive input routes (both need `timestamps`, one
entry per measurement, strictly increasing, in `time_unit`):
1. `feature_values`: the degradation indicator already measured
externally (e.g. RMS velocity trended by a data collector).
2. `signal_ids`: one stored signal per measurement session (loaded
via load_signal); each recording is reduced to a single
`feature_name` value.
The degradation indicator is assumed to RISE toward
`failure_threshold`. A statistically significant increasing trend
(slope p-value < 0.05) is required before any RUL is computed; a
flat/insignificant series returns status 'no_degradation_trend'
with no RUL number.
Args:
ctx: MCP context for user communication.
failure_threshold: Indicator value considered as failure, in the
same units as the feature values. No universal default is
imposed — but when the indicator is broadband VELOCITY RMS
in mm/s, the standard choice is the ISO 10816-3:2009 zone
C/D boundary that assess_severity / get_zone_boundaries()
reports for the machine's group and support (single source
of truth — no boundaries restated here).
timestamps: Measurement times in `time_unit`, strictly
increasing (e.g. hours since first measurement).
feature_values: Indicator values, one per measurement
(mutually exclusive with signal_ids).
signal_ids: Stored signal IDs, one per measurement session
(mutually exclusive with feature_values).
feature_name: Time-domain feature used to reduce each signal
(default: "rms"). Ignored for feature_values input.
method: "linear" (default), "exponential", or "kalman"
(kalman needs approximately uniform measurement spacing).
time_unit: Label for the time axis; RUL and
observation_horizon are expressed in this unit.
Returns:
RULEstimationResult with status, rul (only when estimated),
fit_r_squared (goodness of fit — NOT a confidence),
observation_horizon, and a plain-language message.
|
| analyze_signal_trendA | Within-recording screening: feature trend + degradation onset. THE unified screening tool: feature trend AND degradation
onset in one call. Segments a single recording
(seconds of data), extracts the requested feature per segment,
tests whether the per-segment values show a statistically
significant trend (slope p < 0.05), and detects the first segment
AFTER the baseline window (first half of the series) whose value
exceeds baseline mean + onset_threshold_sigma standard deviations.
Onset inside the baseline window cannot be detected (the baseline
defines "normal"). Requires the signal loaded via load_signal()
first; the sampling rate comes from the stored signal metadata.
This is a SCREENING tool, not a prognosis: a trend inside seconds
of signal says whether the recording is stationary, not how long
the machine will live. For Remaining Useful Life, collect repeated
measurements over days/weeks (one recording per session) and pass
them to estimate_rul — this tool returns the per-segment feature
series so each recording can be reduced to one measurement point.
Args:
ctx: MCP context for user communication.
signal_id: ID of the stored signal (from load_signal).
feature_name: Time-domain feature to analyze (default: "rms").
segment_duration: Duration of each segment in seconds.
overlap_ratio: Overlap between segments (0-1).
onset_threshold_sigma: Baseline standard deviations above the
baseline mean that trigger onset detection (default: 3.0).
Returns:
TrendAnalysisResult with slope, direction (p-value based),
fit quality, the (truncated) per-segment feature series, and
the onset-detection outcome (onset_detected,
onset_segment_index, onset_time_s, baseline_segments).
Raises:
ValueError: If the signal_id is not loaded, or the stored
signal has no sampling rate.
|
| generate_maintenance_recommendationsA | Generate maintenance recommendations based on severity and detected faults. Combines ISO zone-based urgency with fault-specific maintenance
actions. This tool intentionally does NOT accept a confidence
value: any number supplied by the caller would be echoed into
advisory output without evidential basis.
Args:
ctx: MCP context for user communication.
severity_zone: ISO zone letter — "A", "B", "C", or "D".
fault_types: Detected fault types from the closed canonical
vocabulary — outer_race/inner_race/ball/cage for bearings
(NOT the BPFO/BPFI/BSF/FTF acronyms) plus misalignment/
unbalance/looseness. None for zone-only advice.
Returns:
Formatted string listing all maintenance recommendations.
Raises:
ValueError: If any fault type is outside the canonical
vocabulary (the message lists the allowed values —
unknown values are never dropped silently).
|