End-to-end pipeline that captures main engine telemetry, classifies cylinder uniformity, scores SFOC variance and overhaul exposure, and produces a TSI-grade expert review.
The main engine is the single most expensive equipment item on a vessel and the single largest fuel consumer. A 5% SFOC drift means several hundred dollars per day at sea — at scale, hundreds of thousands per year per vessel. A late cylinder overhaul means an engine failure at sea — usually the most expensive recovery a fleet ever sees. A misbalanced cylinder means an asymmetrically worn liner — eventually a major overhaul that should have been a top-end.The Main Engine Performance pipeline turns the existing data — ERP monthly performance reports, telemetry exports, the engine register — into something a Technical Superintendent can act on without reading every monthly file. It captures a six-month rolling window of every monitored parameter, computes deviations against the maker’s design and against the rest of the fleet, and routes anything that crosses an operating threshold to the right person.
ERP records the structured engine register and monthly reports; performance forms are vessel-side submissions; the microapp adds the visual evidence layer for owner / charterer correspondence. The pipeline supports two collectors with the same downstream contract:
Standard collector
Microapp collector (with visuals)
Pulls the latest performance entry from the ERP telemetry feed for one vessel at a time. Output is a single structured record covering the most recent reporting period.
Drives the ME Performance microapp via a headless browser, captures the API responses for performance, baseline polynomials, and shop-trial data, and bundles a screenshot of every dashboard tab. Used when the senior review will reference the live microapp visuals — typical for charterer or owner submissions.
Even cylinder loading is the single most important indicator of engine health. A cylinder running hotter than its neighbours points to a fuel-injector defect, a stuck exhaust valve, or piston-ring blow-by — usually weeks before the engine itself flags an alarm.The analyzer computes deviation per cylinder:ΔTi=Ti−Tˉ,Tˉ=N1i=1∑NTiVerdict:
Severity
Threshold
OK
∣ΔTi∣≤30°C
WARNING
30°C<∣ΔTi∣≤50°C
CRITICAL
∣ΔTi∣>50°C
The same deviation maths runs on Pmax and Pcomp. A cylinder that is hot and has low Pmax is the classic exhaust-valve signature; a cylinder that is hot and has high Pmax usually points to fuel-injector overdelivery.
Specific Fuel Oil Consumption is load-dependent — comparing raw values across operating points produces nonsense. The analyzer always normalises to the maker’s design SFOC at the current load:Variance %=SFOCdesign(P)SFOCactual−SFOCdesign(P)×100A 3-point moving average smooths month-to-month noise; persistent variance above 5% is flagged, above 8% triggers escalation.
Trend matters more than spot values. The analyzer builds a rolling six-month grid of every monitored parameter — per cylinder per month — and surfaces parameters whose mean is drifting. Missing months are surfaced too: a vessel that hasn’t filed a performance report for three consecutive months is itself a red flag.
The dashboard logic that drives the rollup, condensed:
# Build a six-month grid keyed by (cylinder, month), values from performance reportsfor unit in sorted(all_units): unit_row = {"units": unit} for month_date, month_label in zip(six_months_dates, six_months_labels): performance = performance_data.get(month_date) if performance == "No Data Available": current = (month_date.month == datetime.utcnow().month and month_date.year == datetime.utcnow().year) unit_row[month_label] = "Report yet to be submitted" if current \ else "Missing Report" continue unit_data = next( (u for u in performance["data"]["parameter"] if u.get("ENGPERTRANSLINENO") == unit), None ) unit_row[month_label] = ( round(unit_data[parameter_key], 2) if unit_data and unit_data.get(parameter_key) is not None else "No Data Available" )
Two pieces of nuance matter: the analyzer distinguishes “report yet to be submitted” (current month — expected gap) from “missing report” (past month — actual gap). The first is a forms problem; the second is a compliance problem.
Peak combustion pressure, mean indicated pressure, and scavenge pressure are checked against the maker’s spec for the operating point. The analyzer maps deviations to specific failure modes:
Pattern
Likely cause
Pmax low + Pcomp normal
Fuel injector overdelivery / late timing
Pmax high + Pcomp high
Excessive compression — piston ring overhaul candidate
Turbocharger boost low and exhaust back-pressure high is the textbook turbo-fouling signature. The analyzer computes:ηtc=Pexhaust_backPboostA falling ηtc across three reports is flagged for cleaning regardless of whether either pressure is individually outside spec.
Six-month parameter rollup — every parameter per cylinder per month, gaps surfaced
Pressure analysis — deviation per cylinder, mapped to failure mode
Turbocharger assessment — ηtc trend
Overhaul plan — urgent / upcoming, port-call coordination
Recommendations — prioritised actions with timeline and cost
Escalation decision — auto-routed to TSI when triggered
When microapp collection is used, the deliverable also embeds the captured screenshots so the review references the same visual the operator sees in production.
Cylinder-deviation maths, SFOC-curve normalisation, and pressure-spec lookups all live in deterministic Python templates. The model interprets results into narrative; it doesn’t recompute. That means a review of POSUN this month and the same review next month produce identical numbers given identical inputs — which is the only way an audit trail holds up.
The microapp collector and the standard collector produce the same downstream record. The choice is operational: when a review will be referenced by a charterer or in a Class dispute, use the microapp collector so the screenshots travel with the numbers.