Skip to main content

Aerospace — fleet predictive maintenance

The problem. An airline operates a fleet of aircraft, each a deep hierarchy of systems and components, each component streaming sensor data every second of every flight. When one part starts trending toward failure, two questions follow immediately: is this part about to fail, and which other aircraft carry the same part and are therefore at the same risk? The second question is a graph question — and answering it fast is the difference between scheduled maintenance and a grounding.

This scenario leans on the knowledge graph: model the fleet down to the component, and when one component looks suspect, walk the graph to its whole blast radius.

Set up demo data

New workspace? Run this once (Python) to create three aircraft whose pumps are all the same part type — so the blast-radius walk in step 2 returns the whole affected fleet. Safe to re-run.

import datahub_sdk

client = datahub_sdk.DataHubClient.from_env()

nodes = [datahub_sdk.Resource(external_id="part_type_hp_47", name="Hydraulic pump type HP-47", labels=["part_type_hp_47"])]
edges = []
for ac in ["ln_312", "ln_318", "ln_401"]:
nodes += [datahub_sdk.Resource(external_id=f"aircraft_{ac}", name=f"Aircraft {ac}", labels=[f"aircraft_{ac}"]),
datahub_sdk.Resource(external_id=f"hyd_pump_{ac}_1", name=f"Pump {ac}", labels=[f"hyd_pump_{ac}_1"])]
edges += [datahub_sdk.RelForm.by_external_ids(f"aircraft_{ac}", f"hyd_pump_{ac}_1", "contains"),
datahub_sdk.RelForm.by_external_ids(f"hyd_pump_{ac}_1", "part_type_hp_47", "is_part_type")]
client.resources.create(nodes, edges)

1. Model the fleet to the component

A fleet contains aircraft, an aircraft contains systems, a system contains components. Components of the same part type also link to a shared part_type node — that shared node is what makes fleet-wide correlation possible.

ResourceForm aircraft = new ResourceForm();
aircraft.setExternalId("aircraft_ln_312");
aircraft.setName("Aircraft LN-312");
aircraft.setLabels(List.of("aircraft_ln_312"));

ResourceForm pump = new ResourceForm();
pump.setExternalId("hyd_pump_ln_312_1");
pump.setName("Hydraulic pump #1");
pump.setLabels(List.of("hyd_pump_ln_312_1"));

// the component is an instance of a shared part type
RelForm installed = new RelForm();
installed.setName("contains");
installed.setFromExternalId("aircraft_ln_312");
installed.setToExternalId("hyd_pump_ln_312_1");

RelForm isType = new RelForm();
isType.setName("is_part_type");
isType.setFromExternalId("hyd_pump_ln_312_1");
isType.setToExternalId("part_type_hp_47");

client.resources().create(List.of(aircraft, pump), List.of(installed, isType));

Each component streams series — hyd_pump_ln_312_1_vibration_mm_s, hyd_pump_ln_312_1_temp_cingested at fleet scale.

2. A part looks suspect — find the blast radius

Rising vibration on one pump suggests a part-type defect. Walk the graph out from the shared part_type_hp_47 node: every component is_part_type of it, and every aircraft that contains one, is the blast radius — the list maintenance needs to inspect.

ResourceNetwork affected = client.resources().fetchRelated("part_type_hp_47", 3);

// every aircraft in the returned sub-graph carries this part type
affected.nodes().stream()
.filter(n -> n.getExternalId().startsWith("aircraft_"))
.forEach(a -> System.out.println("inspect: " + a.getExternalId()));

One traversal turns a single suspect reading into a precise, fleet-wide inspection list. See Correlate alarms with the graph for the pattern.

3. Record the finding

Raise a component_anomaly event per affected component so the maintenance system schedules the work and keeps an auditable trail.

See the result

Walking out from the suspect part type returns every aircraft to inspect:

inspect: aircraft_ln_312
inspect: aircraft_ln_318
inspect: aircraft_ln_401

See also