← Projelerim
PM
TEI ELD Predictive Maintenance Dashboard
21 Motor › Filo Sağlığı
Backend Connected
DU

SAP Fiori Elements (Analytical List Page) · ABAP OOP · CDS Analitik View'lar · Klasik SEGW OData V2

Bir parça arızalanmadan önce, veri bunu kaç ay önceden söyleyebilir?

21 gerçek motorluk bir filonun kullanım loglarını okuyup her kritik parça için kalan ömrü (LLP çevrim limiti) ve her motor için EGT marjini düşüş trendini hesaplayan; bulguları borescope muayene geçmişiyle birlikte tek bir Object Page'de toplayan bir kestirimci bakım dashboard'u. Proje 2'nin gerçek 6 motor ailesi ve BOM verisi üzerine kuruldu — üç proje boyunca entegre bir mini-ERP anlatısının parçası.

21
Gerçek Motor
5.883
Kullanım Kaydı
2
Kestirimci ABAP Sınıfı
10/10
ABAP Unit Test
01

Riski parça listesinde değil, trendde gör

Bir uçak motorunun parçaları aniden değil, aşama aşama bozulur — dönen kritik parçalar (LLP) çevrim biriktirir, egzoz gaz sıcaklığı (EGT) marjini yavaşça düşer. Bu proje, 21 gerçek motorluk bir filonun kullanım loglarını okuyup bu iki eğrinin nereye gittiğini hesaplayan uçtan uca bir SAP sistemi kuruyor: analitik CDS view katmanı, iki kestirimci ABAP OOP sınıfı ve bulguları tek ekranda toplayan bir Fiori Elements Analytical List Page.

Temel Soru

Filodaki hangi parça ne zaman devreden çıkacak — ve bunu kaç ay önceden söyleyebiliriz?

Analytical List Page — filo genel bakışı, grafik + tablo bir arada
Filo Sağlığı — grafik + tablo bir arada, en riskli motor en üstte
02

Neler kuruldu

  • Katmanlı analitik CDS view mimarisi

    Dört view birbirinin üstüne kuruluyor: motor seviyesinde ZTEI_I_ELD_FLEET_HEALTH → parça kullanım oranını hesaplayan ZTEI_I_ELD_PART_USAGE → risk bandına çeviren ZTEI_I_ELD_PART_RISK → hepsini motor bazında birleştiren ZTEI_C_ELD_DASHBOARD.

  • Sunucu tarafı filtre, sıralama ve sayfalama

    Klasik SEGW GetEntitySet'te hiçbiri otomatik gelmiyor — IT_FILTER_SELECT_OPTIONS, IT_ORDER ve IS_PAGING elle okunup işlendi.

  • Object Page'de dört facet

    Kritik Parçalar (renkli risk göstergesi), Muayene Bulguları, Ömür Tahmini ve EGT Trend Tahmini — her biri kendi navigation property'siyle bağlı.

  • Türkçe durum ve risk metinleri

    Ham kodlar (A/R/Y) yerine Common.Text + UI.TextArrangement ile "Aktif"/"Kırmızı"/"Sarı" gösteriliyor — hem property hem entity seviyesinde annotasyon şart olduğu ortaya çıktı.

  • ALP grafik çökmesine framework seviyesinde düzeltme

    Analitik olmayan bir servise bağlı grafik, SAP'nin kendi getDrillStack() null-kontrolündeki boşluğu açığa çıkardı — Component.js'te beş satırlık bir guard ile giderildi.

  • Proje 2'nin filosuyla gerçek entegrasyon

    Yeni motor kayıtları uydurma bir filo değil, proje 2'nin gerçek 6 motor ailesi ve BOM verisine BOM_ID/NODE_ID üzerinden bağlı.

Grafik görünümü büyütülmüş — üs, motor modeli ve duruma göre gruplanmış
Grafik görünümü — üs, motor modeli ve duruma göre gruplanmış
Tablo görünümü büyütülmüş — tahmin kolonunda 10+ yıl ve Veri Yok etiketleri
Tablo görünümü — tahmin kolonunda "10+ yıl" / "Veri Yok" etiketleri
03

Loglardan tahmine: iki ABAP sınıfının kalbi

ZCL_TEI_ELD_FORECAST her kritik (LLP) parça için kalan çevrim ömrünü, ZCL_TEI_ELD_EGT_TREND ise her motorun EGT marjininin ne zaman Hot Section Inspection eşiğini geçeceğini hesaplıyor. İkisi de aynı temel mantığı izliyor: geçmiş kullanım logundan bir tüketim hızı çıkar, limitle arasındaki farkı bu hıza böl.

1

Kullanım logları toplanır

ZTEI_ELD_USAGE_L'daki uçuş/çevrim kayıtları düğüm bazında toplanıp güncel çevrim/saat ve ortalama günlük kullanım hızı çıkarılıyor.

2

Limite göre kalan gün hesaplanır

LLP çevrim limitinden (veya EGT eşiğinden) mevcut değer çıkarılıp günlük tüketim hızına bölünüyor — estimated_days_left.

3

Sonuç okunur bir etikete dönüşür

SAĞLIKLI

Genç filo için hesaplanan gün sayısı 10 yılı aşıyorsa "10+ yıl" etiketiyle kısaltılır.

KRİTİK

Gün sayısı negatifse parça zaten limitini aşmıştır — "AŞILDI" gösterilir.

Üçüncü bir durum daha var: pistonlu PD170 motorunda dönen kritik parça (LLP) ve EGT marjini kavramının kendisi geçersiz — bu motorlar için tahmin sütunu bilinçli olarak "Veri Yok" gösteriyor.

Ömür Tahmini facet'i — negatif gün değerleriyle
Ömür Tahmini — negatif gün = parça zaten limitini aştı
EGT Trend Tahmini facet'i
EGT Trend Tahmini — marjinin eşiğe ulaşma tarihi

Bu iki ileriye dönük tahmin, Object Page'de iki tamamlayıcı görünümle destekleniyor: parçaların anlık risk bandı ve motorun geçmiş muayene bulguları.

Kritik Parçalar facet'i — renkli risk göstergesi
Kritik Parçalar — anlık risk bandı (kırmızı/sarı)
Muayene Bulguları facet'i
Muayene Bulguları — borescope geçmişi
04

Dört tablo, proje 2'nin filosuna bağlı

Yeni tablolar fiziksel, seri numaralı motor örneklerini modelliyor; ama uydurma bir filo değiller — BOM_ID ve NODE_ID üzerinden proje 2'nin gerçek ZTEI_BOM_HEAD/ZTEI_BOM_ITEM verisine bağlanıyorlar.

ZTEI_ELD_ENGINE
  • ENGINE_SN (key)
  • BOM_ID → (proje 2'nin filosu)
  • BASE_CODE · BASE_NAME · STATUS
  • TOTAL_FLIGHT_HOURS · TOTAL_CYCLES
↑ 1 : N
ZTEI_ELD_PART_LI
  • ENGINE_SN · NODE_ID(proje 2'nin BOM'u)
  • CYCLE_LIMIT · CURRENT_CYCLES
N : 1 ↓
ZTEI_ELD_USAGE_L
  • ENGINE_SN · LOG_DATE
  • FLIGHT_HOURS · CYCLES · EGT_MARGIN
ZTEI_ELD_BORESCO
  • ENGINE_SN · FINDING_ID (key)
  • SUBSYSTEM · SEVERITY · FINDING_TEXT
SE16'da ZTEI_ELD_ENGINE tablosunun gerçek verisi
SE16 — ZTEI_ELD_ENGINE, gerçek Türkçe üretilmiş veriyle
05

Mock'ta görünmeyen hatalar, gerçek backend'de yakalandı

Bu proje bilinçli olarak diğer ikisinden daha fazla test içeriyor. Sebep basit: klasik SEGW'de GetEntitySet'i redefine ettiğinde OData'nın gönderdiği filtre, sıralama ve sayfalamayı elle işlemek zorundasın — mock sunucu (@sap-ux/ui5-middleware-fe-mockserver) bunların hepsini kendisi yaptığı için, eksik kalan kısım sadece gerçek backend'e bağlanınca ortaya çıkıyor. Filtre uygulanınca tüm tablo hücreleri boşalıyor, grafikte [object Object] beliriyordu — kök neden, sunucunun sayfalama toplam sayısını ($inlinecount) hiç bildirmemesiydi.

Ayrı bir katmanda, Forecast/EgtTrend entity'leri ilk kez bir UI'ya bağlandığında üç ayrı, birbirini gizleyen hata art arda çıktı: ABAP sınıfının snake_case alan adları (engine_sn) OData'nın PascalCase alanlarıyla (EngineSn) CORRESPONDING #( ) ile eşleşmediği için satırlar sessizce boş kalıyordu — hata yoktu, sadece "kayıt yok" görünüyordu. Bu üç hata sınıfını bir daha kaçırmamak için 10 ABAP Unit testi yazıldı.

Eclipse ADT'de ABAP Unit test sonucu — yeşil onay işaretleri
ABAP Unit — tahmin sınıfı için 6/6 yeşil (EGT-trend sınıfının kendi 4/4 koşusu ayrıca var)

Aynı disiplin filtre tarafında da geçerli: ALP'nin tablo seviyesindeki View Settings filtresi uygulanmadan önce ve sonra.

View Settings filtre diyaloğu — Motor Modeli seçiliyor
1. Motor Modeli filtresi giriliyor
sonra
Filtre tabloya uygulanmış hâli
2. Filtre tabloya uygulanmış hâli
06

Denedik ve vazgeçtik: native analitik

İlk plan, gerçek sunucu-tarafı analitik toplama içindi: bir @Analytics.dataCategory: #CUBE + @Analytics.query: true CDS view çifti, Fiori Elements AnalyticalTable'a bağlanacaktı. İki gerçek deneme yapıldı — cube+query view'ı temiz aktive oldu ama otomatik üretilen OData servisinin $metadata'sı sürekli boş EntityContainer döndü; SEGW'nin "Redefine → ODP Extraction" yolu ise ODP arama diyaloğunda isimle arama olmadığı için tıkandı. İkisi de bu NPL deneme sisteminin native OData-V2-üzerinden-embedded-analytics yolunun uçtan uca açık olmadığına işaret ediyordu. Zaman kaybetmek yerine düz bir GridTable + istemci tarafı grafik toplamaya geçildi — çalışan, dürüst bir çözüm. Terk edilen CDS view'ları sistemden silindi ama kaynak kodu burada:

ZTEI_I_ELD_CUBE.ddls.asddlsCDS
@Analytics.dataCategory: #CUBE
define view ZTEI_I_ELD_CUBE
  as select from ZTEI_C_ELD_DASHBOARD as Engine
{
  key Engine.EngineSn             as EngineSn,
      Engine.BomId                 as BomId,
      …

      @DefaultAggregation: #SUM
      Engine.TotalFlightHours      as TotalFlightHours,

      // Kucuk sayi = daha kotu (1=Kirmizi...3=Yesil), yani
      // bir grubun "en kotu" riskini bulmak icin MIN gerekir, MAX degil.
      @DefaultAggregation: #MIN
      Engine.WorstPartRiskRank     as WorstPartRiskRank
}
07

Neyle inşa edildi

Backend
KalemBileşenDetay
B-01SAP Gateway servisiOData V2, klasik SEGW — ZTEI_ELD_PM_SRV_SRV
B-02Analitik CDS view katmanı4 view: FLEET_HEALTH → PART_USAGE → PART_RISK → DASHBOARD
B-03Kestirimci ABAP sınıflarıZCL_TEI_ELD_FORECAST, ZCL_TEI_ELD_EGT_TREND
B-04Test kapsamı10 ABAP Unit testi, gerçek bulunan hataları regresyona kilitliyor
Frontend
KalemBileşenDetay
F-01UI frameworkSAP Fiori Elements — Analytical List Page + Object Page
F-02Tablo tipiGridTable — native analitik denemesi sonrası bilinçli tercih
F-03RuntimeSAPUI5 / OpenUI5 1.150.1
F-04MimariTamamen annotation-driven — Component.js'teki 5 satırlık framework guard'ı dışında özel controller kodu yok
08

Neyin gerçek, neyin gösterimsel olduğu

LLP çevrim limitleri ve EGT marjini eşikleri gerçek TEI rakamları değildir. Kamuya açık referans noktalarından (FAA AC 33.70-1, tipik EGT marjini aralıkları) türetilmiş, endüstri-tipik gösterimsel değerlerdir.
Bazı üs/lokasyon verileri için kamuya açık kaynak bulunamadı. Gösterimsel olarak işaretlenmiştir.
ALP'nin varsayılan filtresi (UI.SelectionPresentationVariant) bu sistemde uygulanmıyor. Annotasyon metamodele doğru şekilde ulaşıyor ama sayfa açılışında otomatik uygulanmıyor — saf annotasyon-tabanlı mimariyi bozmamak için controller extension'a geçilmedi, dürüstçe çözülmemiş bir platform sınırı olarak bırakıldı.
Native OData V2 analitik toplama bu sistemde uçtan uca çalışmadı. Ayrıntı için yukarıdaki "Denedik ve vazgeçtik" bölümüne bakın.

Uygulamalı bir SAP Fiori Elements · ABAP OOP · CDS öğrenme ve portföy projesi olarak geliştirilmiştir.