Skip to main content

v0.26.0 Release Notes

EnerOS v0.26.0 Release Notes

Release Date: 2025-10-05 Codename: Babel Git Tag: v0.26.0 Support Status: Stable Total Crates: 67 (3 new) Test Cases: 8550+ (450+ new)

Overview

EnerOS v0.26.0 “Babel” is an internationalization (i18n)-focused release that enables EnerOS to serve power operators in different regions worldwide. Although power systems follow universal physical laws, different countries/regions differ significantly in language, unit system, voltage levels, frequency standards, regulatory requirements, and time zones. v0.26.0 abstracts these regional differences into a configurable localization layer, allowing the same kernel code to seamlessly adapt to different regions.

This release introduces five core capabilities: i18n Framework, Multi-language Support, Regional Adaptation, Timezone Handling, and Localized Documentation. All user-facing strings, dates, numbers, and units are rendered through the localization layer, while kernel logic remains language-agnostic.

In terms of design philosophy, v0.26.0 adheres to “kernel language-agnostic” — kernel and agent business logic does not depend on any specific language; “region configuration-driven” — regional differences are handled through configuration files rather than code branches; “timezone as first-class citizen” — all timestamps use UTC internally and are only converted to local time zones for display and interaction.

Key Metrics

MetricValueDescription
Supported languages12Chinese, English, Japanese, Korean, German, French, etc.
Supported time zonesAll IANA384 zones
Localization entries8000+UI strings
Region configuration sets8Major markets
New Crates3i18n-related
New tests450+Includes localization tests

New Features

1. i18n Framework

Introduces the eneros-i18n Crate, providing a unified internationalization framework. Based on Fluent (Project Fluent), it supports complex syntax such as plurals, gender, and context.

Basic Usage

use eneros_i18n::{I18n, Locale};

let i18n = I18n::new()
    .locale(Locale::zh_CN())
    .fallback(Locale::en_US())
    .load_dir("locales/")?;

// Translate
let msg = i18n.t("alarm.voltage-high", |b| b
    .arg("bus", "42")
    .arg("voltage", "1.08"))?;
// Chinese: "母线 42 电压 1.08pu 越上限"
// English: "Bus 42 voltage 1.08pu exceeds upper limit"

Plural Handling

// Plural form auto-adaptation
let msg = i18n.t("alarm.devices-offline", |b| b
    .arg("count", 3))?;
// Chinese: "3 台设备离线"
// English: "3 devices offline"
// Russian: "3 устройства не в сети" (Russian has 3 plural forms)

Supported Languages

LanguageCodeCompletenessMajor Market
Simplified Chinesezh-CN100%Mainland China
Englishen-US100%North America
Englishen-GB95%United Kingdom
Japaneseja-JP92%Japan
Koreanko-KR88%South Korea
Germande-DE90%Germany
Frenchfr-FR85%France
Spanishes-ES82%Spain/Latin America
Portuguesept-BR80%Brazil
Russianru-RU78%Russia
Arabicar-SA65%Middle East
Hindihi-IN60%India

2. Multi-language Support

Introduces eneros-i18n-mo (Multi-language Orchestrator), supporting runtime dynamic language switching without restart.

Dynamic Switching

use eneros_i18n_mo::LanguageManager;

let lang_mgr = LanguageManager::new(&i18n);

// Switch by user preference
lang_mgr.set_locale(user_id, Locale::ja_JP()).await?;

// Auto-detect by region
let detected = lang_mgr.detect_from_region("JP")?;
lang_mgr.set_default(detected)?;

Agent Multi-language

// Agent responds in user's language
let agent = Agent::new("dispatch-assistant")
    .language(LanguagePolicy::FollowUser);

// Chinese user question
let reply = agent.chat("母线 42 电压为什么偏高?").await?;
// Chinese reply

// English user question
let reply = agent.chat("Why is bus 42 voltage high?").await?;
// English reply

Translation Workflow

StageDescriptionTool
ExtractionExtract strings to translate from codextr
TranslationHuman/machine translationCrowdin
CompilationCompile to .ftl filesfluent
LoadingRuntime loadingeneros-i18n
ValidationCheck missing/conflictsIn-house tool

3. Regional Adaptation

Introduces the eneros-i18n-region Crate, providing regional difference adaptation. Voltage levels, frequency, unit systems, and protection configurations for different regions are managed through region configuration sets.

Region Configuration

use eneros_i18n_region::{Region, RegionConfig};

let region = Region::from_code("CN")
    .config(RegionConfig {
        frequency_hz: 50.0,
        voltage_levels: vec![110, 220, 500, 750, 1000],
        voltage_unit: VoltageUnit::KV,
        power_unit: PowerUnit::MW,
        coordinate_system: CoordSystem::CGCS2000,
        standard: Standard::GB,
    });

manager.set_region(region)?;

Regional Difference Table

RegionFrequency (Hz)Voltage Levels (kV)Unit SystemCoordinate SystemStandard
China50110/220/500/750/1000MetricCGCS2000GB
USA60115/230/500/765Imperial + MetricNAD83IEEE/NERC
Europe50110/220/380MetricETRS89EN/IEC
Japan50/6066/154/275/500MetricJGD2011JIS
Brazil60138/230/500/750MetricSIRGAS2000ABNT

Unit Conversion

use eneros_i18n_region::units::{Voltage, Power, Energy};

// Auto-convert by region
let v = Voltage::from_kv(220.0);
println!("{}", v.display(&region));  // CN: "220.0 kV"

let p = Power::from_mw(500.0);
println!("{}", p.display(&region));  // US: "500 MW"

let e = Energy::from_kwh(1000.0);
println!("{}", e.display(&region));  // CN: "1000 kWh"

4. Timezone Handling

Introduces the eneros-i18n-tz Crate, providing comprehensive timezone handling. All internal timestamps use UTC nanosecond precision and are only converted to local time zones for display and interaction.

Timezone Conversion

use eneros_i18n_tz::{Timestamp, TimeZone};

// Internal storage: UTC nanoseconds
let event_time = Timestamp::now_utc();

// Display: by user timezone
let tz = TimeZone::from_iana("Asia/Shanghai");
let local = event_time.to_local(&tz);
println!("Event time: {}", local.format("%Y-%m-%d %H:%M:%S %Z"));
// "Event time: 2025-10-05 14:30:00 CST"

// Cross-timezone comparison
let ny = TimeZone::from_iana("America/New_York");
println!("New York time: {}", event_time.to_local(&ny).format(...));
// "New York time: 2025-10-05 02:30:00 EDT"

Cross-timezone Scheduling

// Cross-timezone operations orchestration
let maintenance_window = MaintenanceWindow::new()
    .start("2025-10-05 02:00:00", TimeZone::America/New_York)
    .duration(Duration::hours(4));

// Auto-convert to each node's local time
for node in cluster.nodes() {
    let local_start = maintenance_window.start_at(&node.timezone);
    println!("{}: local start {}", node.id, local_start);
}

Timezone Handling Rules

ScenarioHandlingDescription
Internal storageUTC nanosecondsUnified baseline
LogsUTCEasy sorting
UI displayUser timezoneLocal-friendly
SchedulingRegional timezoneBy business
AlarmsUser timezoneInstant notification
ReportsRegional timezoneCompliance requirements

5. Localized Documentation

Introduces the eneros-i18n-docs Crate, providing documentation localization capabilities. Technical documentation, operations manuals, and API references all support multi-language versions.

Documentation Build

use eneros_i18n_docs::{DocBuilder, Locale};

let builder = DocBuilder::new()
    .source("docs/")
    .output("dist/docs/")
    .locales(vec![Locale::zh_CN(), Locale::en_US(), Locale::ja_JP()]);

builder.build().await?;

Documentation Translation Status

Document Typezh-CNen-USja-JPOther
Quick Start100%100%95%70%
User Guide100%95%80%60%
API Reference100%100%60%30%
Ops Manual100%85%50%20%
Best Practices90%80%40%15%

Improvements

  • String Extraction: Added eneros-i18n-extract tool to automatically extract strings to translate from code
  • RTL Support: Arabic and other right-to-left languages get full UI adaptation
  • Date Format: Supports region-specific date formats (YYYY-MM-DD / MM/DD/YYYY / DD/MM/YYYY)
  • Number Format: Supports regional differences in thousands separators and decimal points (1,000.00 / 1.000,00)

Bug Fixes

  • Fixed eneros-i18n parsing error with nested Fluent message references (#2605)
  • Fixed eneros-i18n-tz time offset issue at daylight saving time boundaries (#2610)
  • Fixed eneros-i18n-region precision loss in unit conversion with mixed imperial/metric (#2615)
  • Fixed eneros-i18n-docs link errors when building multi-language versions (#2620)

Breaking Changes

  • Timestamp::now: Renamed to Timestamp::now_utc to emphasize UTC semantics
  • format! calls: All user-facing strings must be translated via i18n.t(); hardcoding is prohibited

Upgrade Guide

  1. Run cargo update -p eneros-i18n
  2. Update Timestamp::now calls to Timestamp::now_utc
  3. Migrate hardcoded user-facing strings to .ftl files
  4. Refer to docs/migration/v0.26.0.md for detailed migration steps