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.
Filodaki hangi parça ne zaman devreden çıkacak — ve bunu kaç ay önceden söyleyebiliriz?
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ı hesaplayanZTEI_I_ELD_PART_USAGE→ risk bandına çevirenZTEI_I_ELD_PART_RISK→ hepsini motor bazında birleştirenZTEI_C_ELD_DASHBOARD. -
Sunucu tarafı filtre, sıralama ve sayfalama
Klasik SEGW
GetEntitySet'te hiçbiri otomatik gelmiyor —IT_FILTER_SELECT_OPTIONS,IT_ORDERveIS_PAGINGelle 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) yerineCommon.Text+UI.TextArrangementile "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ı.
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.
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.
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.
Sonuç okunur bir etikete dönüşür
Genç filo için hesaplanan gün sayısı 10 yılı aşıyorsa "10+ yıl" etiketiyle kısaltılır.
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.
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ı.
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.
- ENGINE_SN (key)
- BOM_ID → (proje 2'nin filosu)
- BASE_CODE · BASE_NAME · STATUS
- TOTAL_FLIGHT_HOURS · TOTAL_CYCLES
- ENGINE_SN · NODE_ID → (proje 2'nin BOM'u)
- CYCLE_LIMIT · CURRENT_CYCLES
- ENGINE_SN · LOG_DATE
- FLIGHT_HOURS · CYCLES · EGT_MARGIN
- ENGINE_SN · FINDING_ID (key)
- SUBSYSTEM · SEVERITY · FINDING_TEXT
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ı.
Aynı disiplin filtre tarafında da geçerli: ALP'nin tablo seviyesindeki View Settings filtresi uygulanmadan önce ve sonra.
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:
@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 }
Neyle inşa edildi
| Kalem | Bileşen | Detay |
|---|---|---|
| B-01 | SAP Gateway servisi | OData V2, klasik SEGW — ZTEI_ELD_PM_SRV_SRV |
| B-02 | Analitik CDS view katmanı | 4 view: FLEET_HEALTH → PART_USAGE → PART_RISK → DASHBOARD |
| B-03 | Kestirimci ABAP sınıfları | ZCL_TEI_ELD_FORECAST, ZCL_TEI_ELD_EGT_TREND |
| B-04 | Test kapsamı | 10 ABAP Unit testi, gerçek bulunan hataları regresyona kilitliyor |
| Kalem | Bileşen | Detay |
|---|---|---|
| F-01 | UI framework | SAP Fiori Elements — Analytical List Page + Object Page |
| F-02 | Tablo tipi | GridTable — native analitik denemesi sonrası bilinçli tercih |
| F-03 | Runtime | SAPUI5 / OpenUI5 1.150.1 |
| F-04 | Mimari | Tamamen annotation-driven — Component.js'teki 5 satırlık framework guard'ı dışında özel controller kodu yok |
Neyin gerçek, neyin gösterimsel olduğu
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ı.Uygulamalı bir SAP Fiori Elements · ABAP OOP · CDS öğrenme ve portföy projesi olarak geliştirilmiştir.