Skip to main content

v0.33.0 Release Notes

EnerOS v0.33.0

Release Date: 2026-02-29 Codename: Predict Git Tag: v0.33.0 Support Status: Stable Total Crates: 66 (6 new) Test Cases: 8600+ (700 new)

Overview

EnerOS v0.33.0 “Predict” is a predictive maintenance-focused release, shifting the operation and maintenance mode of power equipment from “repair after failure” to “Predictive Maintenance.” Based on the ML runtime from v0.32.0, this release builds a complete Prognostics and Health Management (PHM) system, covering four core capabilities: equipment health scoring, Remaining Useful Life (RUL) prediction, fault early warning, and maintenance advisory.

The core design philosophy of the Predict release is “data-driven + physics model fusion” — purely data-driven ML models tend to fail when equipment operating conditions drift, while purely physical models are limited by parameter accuracy. EnerOS adopts a hybrid architecture: ML models learn degradation patterns from historical data, physical models provide boundary constraints and mechanism validation, and the two are fused through the kernel’s ConstraintEngine to output the final health assessment.

This release introduces five core capabilities: Equipment Health Scoring, RUL Prediction, Fault Early Warning Engine, Maintenance Advisory Generation, and Equipment Profile System. All capabilities are implemented through five new crates: eneros-phm, eneros-phm-score, eneros-phm-rul, eneros-phm-alert, and eneros-phm-advisor.

Key Metrics

MetricValueDescription
Health score accuracy93.7%Compared with manual assessment
RUL prediction error±8.5%Median life scenario
Early warning lead time72 hoursMedian before failure
False positive rate1.8%Monthly statistics
New Crates6PHM-related
New tests700+Includes 100 end-to-end

New Features

1. Equipment Health Scoring

Adds the eneros-phm-score crate, calculating a 0-100 health score for each piece of equipment, comprehensively reflecting the equipment’s current status and degradation level. The score is based on multi-source data: real-time sensor data, historical operation records, maintenance work orders, and environmental factors.

Scoring Dimensions

DimensionWeightData SourceDescription
Electrical performance25%PMU/RTUVoltage deviation, harmonics, imbalance
Thermal state20%Temperature sensorsWinding temperature, oil temperature
Mechanical state20%Vibration sensorsVibration amplitude, spectrum
Insulation state15%Online monitoringInsulation resistance, dielectric loss
Operation history10%Timeseries databaseCumulative operating hours, start-stop count
Environmental factors10%Meteorological dataTemperature, humidity, contamination

Health Score API

use eneros_phm_score::{HealthScorer, ScoreConfig, EquipmentId};

let scorer = HealthScorer::new(&ctx)
    .config(ScoreConfig {
        update_interval: Duration::minutes(5),
        history_window: Duration::days(90),
        weights: ScoreWeights::default(),
    })
    .build().await?;

// Calculate health score for a single piece of equipment
let score = scorer.score(EquipmentId::from("TFR-001")).await?;

println!("Equipment TFR-001 health score: {:.1}", score.value);
println!("Health grade: {:?}", score.grade);
println!("Dimension scores:");
for (dim, val) in &score.dimensions {
    println!("  {}: {:.1}", dim, val);
}
// Example output:
// Equipment TFR-001 health score: 78.3
// Health grade: Good
// Dimension scores:
//   electrical: 85.2
//   thermal: 72.1
//   mechanical: 80.5
//   insulation: 75.0
//   history: 68.3
//   environment: 88.0

Health Grade Classification

GradeScore RangeStatusRecommended Action
Excellent90-100ExcellentNo intervention needed
Good75-89GoodRoutine inspection
Fair60-74FairPlanned maintenance
Poor40-59PoorTime-limited maintenance
Critical0-39CriticalImmediate shutdown

Score Trend Tracking

// Get equipment health score trend
let trend = scorer.trend(EquipmentId::from("TFR-001"))
    .range(now() - Duration::days(30), now())
    .fetch().await?;

// Degradation rate analysis
let degradation_rate = trend.degradation_rate();  // -0.15 points/day
let projected_fail = trend.project_crossing(40.0); // Estimated to drop to 40 in 256 days

2. Remaining Useful Life (RUL) Prediction

Adds the eneros-phm-rul crate, predicting remaining useful life based on equipment degradation trajectories. Supports multiple RUL algorithms, from simple linear extrapolation to deep learning sequence prediction.

RUL Algorithm Matrix

AlgorithmApplicable EquipmentAccuracyData Requirements
Linear extrapolationTransformers±15%Historical trend
Wiener processCircuit breakers±10%Degradation trajectory
LSTMGeneral±8.5%Multi-dimensional timeseries
TransformerComplex equipment±7.2%Large amount of history
Physics-fusedRotating machines±6.0%Mechanism model

RUL Prediction API

use eneros_phm_rul::{RulPredictor, RulConfig, Algorithm};

let predictor = RulPredictor::new(&ctx)
    .algorithm(Algorithm::Lstm {
        model: "rul-lstm-v3",
        sequence_length: 168,  // 7-day history
    })
    .config(RulConfig {
        confidence_level: 0.9,
        failure_threshold: 40.0,  // Health score below 40 considered failure
        update_interval: Duration::hours(1),
    })
    .build().await?;

// Predict remaining useful life
let rul = predictor.predict(EquipmentId::from("TFR-001")).await?;

println!("Remaining useful life prediction:");
println!("  Point estimate: {:.0} days", rul.point_estimate);
println!("  90% confidence interval: [{:.0}, {:.0}] days", rul.lower, rul.upper);
println!("  Degradation model: {:?}", rul.model_type);

Multi-equipment RUL Summary

// Batch predict all equipment in a substation
let station_rul = predictor.predict_station(StationId::from("SS-110-01")).await?;

// Sort by urgency
let sorted = station_rul.sorted_by_urgency();
for item in &sorted {
    println!("{}: RUL = {:.0} days ({}), score = {:.1}",
        item.equipment_id, item.rul, item.urgency, item.health_score);
}

3. Fault Early Warning Engine

Adds the eneros-phm-alert crate, generating multi-level fault early warnings based on health scores and RUL predictions.

Warning Levels

LevelTrigger ConditionResponse TimeNotification Method
Level 1 (Critical)Score < 40 or RUL < 7 daysImmediateSMS + phone + work order
Level 2 (Important)Score < 60 or RUL < 30 days24 hoursSMS + work order
Level 3 (General)Score < 75 or RUL < 90 days7 daysWork order
Level 4 (Info)Abnormal degradation rate acceleration30 daysSystem notification

Warning Engine

use eneros_phm_alert::{AlertEngine, AlertConfig};

let engine = AlertEngine::new(&ctx)
    .config(AlertConfig {
        check_interval: Duration::minutes(5),
        dedup_window: Duration::hours(1),
        escalation: true,  // Auto-escalate if unhandled
    })
    .build().await?;

// Start warning monitoring
engine.start().await?;

// Subscribe to warning events
let mut alerts = engine.subscribe();
while let Some(alert) = alerts.next().await {
    match alert.level {
        AlertLevel::Critical => {
            sms::send(&on_call_team, &alert.message).await?;
            work_order::create_urgent(alert).await?;
        }
        AlertLevel::High => {
            work_order::create(alert).await?;
        }
        _ => { log::info!("Warning: {:?}", alert); }
    }
}

4. Maintenance Advisory Generation

Adds the eneros-phm-advisor crate, combining LLM with a rule engine to generate actionable maintenance recommendations.

Advisory Generation Flow

use eneros_phm_advisor::{MaintenanceAdvisor, AdviceRequest};

let advisor = MaintenanceAdvisor::new(&ctx)
    .with_llm(client.clone())
    .with_rules(&maintenance_rules)
    .with_history(&work_order_db)
    .build().await?;

let request = AdviceRequest::new(EquipmentId::from("TFR-001"))
    .include_rul(true)
    .include_history(true)
    .include_similar_cases(true);

let advice = advisor.advise(request).await?;

println!("Maintenance advice: {}", advice.summary);
println!("Recommended actions:");
for action in &advice.actions {
    println!("  - {} (priority: {:?}, estimated duration: {:?})",
        action.description, action.priority, action.estimated_duration);
}
println!("Required parts: {:?}", advice.required_parts);
println!("Estimated cost: {:.0} CNY", advice.estimated_cost);

Advisory Types

Advisory TypeTrigger ConditionExample
Immediate shutdownScore < 40”Winding temperature exceeded limit, recommend immediate shutdown for inspection”
Time-limited maintenanceScore 40-60”Insulation dielectric loss increased, recommend maintenance within 7 days”
Planned maintenanceScore 60-75”Vibration amplitude increased, recommend planned maintenance next month”
Condition monitoringDegradation accelerated”Increase temperature monitoring frequency to 15 minutes”
Parameter adjustmentPerformance deviation”Adjust tap position to gear 5”

5. Equipment Profile System

Adds the eneros-phm crate (PHM core), establishing a complete digital profile for each piece of equipment, integrating static parameters, dynamic status, maintenance history, and health assessment.

Equipment Profile Structure

use eneros_phm::{EquipmentProfile, EquipmentType};

let profile = phm.get_profile(EquipmentId::from("TFR-001")).await?;

// Static information
println!("Equipment type: {:?}", profile.equipment_type);  // Transformer
println!("Model: {}", profile.model);                  // SZ-31500/110
println!("Commissioning date: {}", profile.commissioning_date);
println!("Rated capacity: {} MVA", profile.rated_capacity);

// Dynamic status
println!("Current load rate: {:.1}%", profile.current_load_rate);
println!("Cumulative operation: {} hours", profile.total_running_hours);
println!("Start-stop count: {}", profile.start_stop_count);

// Health assessment
println!("Health score: {:.1}", profile.health_score.value);
println!("Remaining life: {:.0} days", profile.rul.point_estimate);
println!("Warning level: {:?}", profile.alert_level);

Equipment Comparative Analysis

// Horizontal comparison of same-model equipment
let comparison = phm.compare(EquipmentType::Transformer)
    .model("SZ-31500/110")
    .metric(HealthMetric::InsulationLoss)
    .fetch().await?;

// Output: Insulation loss comparison of all same-model transformers, identifying abnormal equipment

Improvements

  • Timeseries Engine: Added downsampling aggregation, long-term trend query speed improved 5x
  • ML Runtime: Model inference supports dynamic batching, throughput improved 40%
  • Alert System: Alert deduplication logic optimized, reducing duplicate alerts by 70%
  • Equipment Model: eneros-equipment adds parameter templates for 200+ equipment models
  • Observability: PHM chain integrated with Grafana dashboard templates

Bug Fixes

  • Fixed eneros-phm-score abnormally low scores during initial equipment commissioning (#3303)
  • Fixed eneros-phm-rul LSTM model crashing on missing data (#3309)
  • Fixed eneros-phm-alert warning deduplication window failing across days (#3315)
  • Fixed eneros-phm-advisor LLM-generated recommendations not validating parts inventory (#3320)
  • Fixed eneros-phm equipment profile electrical position not updating after topology changes (#3325)

Breaking Changes

  • HealthScorer::score: Return type adds grade field
  • RulPredictor::predict: Parameter changed from EquipmentId to &PredictTarget
  • AlertLevel: Enum value Emergency changed to Critical

Upgrade Guide

  1. Update the eneros dependency in Cargo.toml to 0.33.0
  2. Run eneros phm init to initialize the equipment profile database
  3. Import equipment historical maintenance data into the PHM system
  4. Configure warning notification channels in eneros.toml

Acknowledgments

Thanks to the 28 contributors who submitted 410+ commits, and to grid operations experts for domain knowledge support.