Skip to main content

Internationalization and Compliance

Capabilities

Internationalization and Compliance

EnerOS v0.47.0 focuses on internationalization and compliance capability building, adding Chinese/English/Japanese/Spanish 4-language i18n framework, GDPR/PIPL/CCPA privacy compliance automation, and DL/T 698.45 Chinese smart meter protocol adaptation, covering all international deployment scenarios. The compliance capabilities are provided by the eneros-i18n and eneros-compliance crates working together.

Compliance Architecture

┌──────────────────────────────────────────────────────────────┐
│                     Internationalization Layer                │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐    │
│  │ zh_CN    │  │ en_US    │  │ ja_JP    │  │ es_ES    │    │
│  │ Simplified│  │ English  │  │ Japanese │  │ Spanish  │    │
│  │ Chinese  │  │          │  │          │  │          │    │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘    │
└────────┬─────────────────────────────────────────────────────┘

┌────────▼─────────────────────────────────────────────────────┐
│                     Privacy Compliance Layer                  │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐    │
│  │ GDPR     │  │ PIPL     │  │ CCPA     │  │ APPI     │    │
│  │ EU       │  │ China    │  │ California│  │ Japan    │    │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘    │
└────────┬─────────────────────────────────────────────────────┘

┌────────▼─────────────────────────────────────────────────────┐
│                     Power Protocol Adaptation Layer          │
│  DL/T 698.45 / DL/T 645 / IEC 62056 / Modbus                │
└────────┬─────────────────────────────────────────────────────┘

┌────────▼─────────────────────────────────────────────────────┐
│                     Data Localization Layer                  │
│  China data no exit / EU data no exit / US preferred         │
└──────────────────────────────────────────────────────────────┘
DimensionCoverageImplementation
Language4 types (Chinese/English/Japanese/Spanish)eneros-i18n
PrivacyGDPR / PIPL / CCPA / APPIeneros-compliance
Power ProtocolDL/T 698.45 / DL/T 645 / IEC 62056eneros-iot
CybersecurityMLPS 2.0 / NERC CIP / IEC 62443eneros-trust
Data LocalizationChina/EU/US/Japaneneros-compliance

i18n Internationalization

Multi-Language Framework

EnerOS has a built-in i18n framework, supporting message translation, plural forms, date-time formatting, and number formatting:

use eneros_i18n::{I18n, Locale, Translator};
use std::collections::HashMap;

let i18n = I18n::new()
    .locale(Locale::zh_CN)
    .fallback(Locale::en_US)
    .load_dir("/etc/eneros/locales")?
    .strict(false);            // No error on missing translations

// Translation (with parameters)
let mut params = HashMap::new();
params.insert("bus", "5");
params.insert("voltage", "1.08");
let msg = i18n.t("alert.voltage_high", &params)?;
// zh_CN: "5 号母线电压过高: 1.08 pu"
// en_US: "Bus 5 voltage high: 1.08 pu"
// ja_JP: "5番母線電圧高: 1.08 pu"
// es_ES: "Tensión de barra 5 alta: 1.08 pu"

// Plural forms
let msg = i18n.tn("alert.devices_offline", count, &params)?;
// 1 device offline / 5 devices offline

// Date formatting
let date_str = i18n.format_date(timestamp, Format::Long)?;
// zh_CN: 2026年7月6日
// en_US: July 6, 2026
// ja_JP: 2026年7月6日
// es_ES: 6 de julio de 2026

// Number formatting
let num_str = i18n.format_number(1234567.89)?;
// zh_CN: 1,234,567.89
// en_US: 1,234,567.89
// es_ES: 1.234.567,89

Supported Languages

LocaleLanguageStatusCoverage
zh_CNSimplified Chinese✅ Complete100%
en_USEnglish✅ Complete100%
ja_JPJapanese✅ Complete95%
es_ESSpanish✅ Complete90%
zh_TWTraditional Chinese🚧 In Progress60%
fr_FRFrench🚧 In Progress40%
de_DEGerman📋 Planned-
ko_KRKorean📋 Planned-

Dynamic Switching

// By user preference
let user_locale = user.preferred_locale();
i18n.set_locale(user_locale).await?;

// By tenant configuration
tenant.set_default_locale(Locale::ja_JP).await?;

// By request Header
let locale = request.accept_language().best_match();

// By geographic location (based on IP)
let locale = geoip.lookup(client_ip).best_match_locale();

Translation File Format

Translation files use YAML format, organized by language directories:

/etc/eneros/locales/
├── zh_CN/
│   ├── common.yml
│   ├── alerts.yml
│   └── reports.yml
├── en_US/
│   ├── common.yml
│   ├── alerts.yml
│   └── reports.yml
├── ja_JP/
│   └── ...
└── es_ES/
    └── ...

zh_CN/alerts.yml example:

alert:
  voltage_high: "{bus} 号母线电压过高: {voltage} pu"
  voltage_low: "{bus} 号母线电压偏低: {voltage} pu"
  overload: "{line} 线路过载: {ratio}%"
  devices_offline:
    one: "{count} 台设备离线"
    other: "{count} 台设备离线"

Privacy Compliance

GDPR (EU)

use eneros_compliance::gdpr::{GdprCompliance, DataSubjectRequest, Pseudonymize};
use std::time::Duration;

let gdpr = GdprCompliance::new()
    .dpo_contact("dpo@eneros.com")                 // Data Protection Officer
    .retention(Duration::from_secs(86400 * 365 * 2))  // 2-year retention
    .pseudonymize(Pseudonymize::personal_data()
        .algorithm(HashAlgo::Sha256)
        .salt_from_kms("gdpr-salt"))
    .consent_required(true)
    .cross_border_restriction(true);

// Handle data subject requests
match request {
    DataSubjectRequest::Access(user_id) => {
        // Data portability - export all user data
        let data = gdpr.export_user_data(user_id).await?;
        return Json(data);
    }
    DataSubjectRequest::Erasure(user_id) => {
        // Right to be forgotten - delete user data
        gdpr.erase_user_data(user_id).await?;
    }
    DataSubjectRequest::Portability(user_id) => {
        // Data portability - JSON export
        let export = gdpr.portable_export(user_id)
            .format(ExportFormat::Json)
            .await?;
        return File(export);
    }
    DataSubjectRequest::Rectify(user_id, corrections) => {
        // Right to rectification
        gdpr.rectify(user_id, corrections).await?;
    }
    DataSubjectRequest::Restrict(user_id) => {
        // Right to restrict processing
        gdpr.restrict_processing(user_id).await?;
    }
    DataSubjectRequest::Object(user_id, purpose) => {
        // Right to object
        gdpr.object_processing(user_id, purpose).await?;
    }
}

PIPL (China Personal Information Protection Law)

use eneros_compliance::pipl::{PiplCompliance, Consent, Purpose, TransferType};

let pipl = PiplCompliance::new()
    .separate_storage(true)           // Personal information stored separately
    .cross_border_audit(true)         // Cross-border transfer assessment
    .minimization(true)               // Minimum necessary principle
    .anonymize_after_retention(true); // Anonymize after retention period

// Consent management
let consent = Consent::new(user_id)
    .purposes(vec![Purpose::Operation, Purpose::Analytics])
    .expiry(Duration::from_secs(86400 * 365))   // 1-year validity
    .withdrawable(true);

pipl.record_consent(consent).await?;

// Check consent status
let status = pipl.check_consent(user_id, Purpose::Analytics).await?;
if !status.valid {
    return Err(Error::ConsentRequired);
}

// Cross-border transfer assessment
let assessment = pipl.cross_border_transfer_assessment(
    data,
    dest_country: "US",
    TransferType::CloudStorage,
).await?;
if !assessment.approved {
    return Err(Error::CrossBorderDenied);
}

CCPA (California Consumer Privacy Act)

use eneros_compliance::ccpa::{CcpaCompliance, ConsumerRequest};

let ccpa = CcpaCompliance::new()
    .opt_out_sale(true)                       // Default opt-out of sale
    .notice_at_collection("We collect the following information...")
    .retention(Duration::from_secs(86400 * 365 * 2));

match request {
    ConsumerRequest::Know(consumer_id) => {
        // Right to know - what data was collected
        let data = ccpa.collect(consumer_id).await?;
        let categories = ccpa.categories(consumer_id).await?;
    }
    ConsumerRequest::Delete(consumer_id) => {
        // Right to delete
        ccpa.delete(consumer_id).await?;
    }
    ConsumerRequest::OptOut(consumer_id) => {
        // Opt out of sale
        ccpa.opt_out_sale(consumer_id).await?;
    }
    ConsumerRequest::NonDiscrimination(consumer_id) => {
        // Non-discrimination right - no discrimination for exercising rights
        ccpa.ensure_non_discrimination(consumer_id).await?;
    }
}

Privacy Regulation Comparison

RegulationRegionData Subject RightsCross-border RestrictionsFine Cap
GDPREU7 itemsStrict4% revenue
PIPLChina6 itemsStrict5% revenue
CCPACalifornia4 itemsNone$7,500/violation
APPIJapan5 itemsMedium100 million JPY
LGPDBrazil9 itemsMedium2% revenue

DL/T 698.45 Smart Meter Protocol

Adapts to the Chinese power industry standard DL/T 698.45 (IPv6-based smart meter communication protocol), supporting multiple security levels:

use eneros_iot::dlt698::{Dlt698Client, Frame, Apdu, Security, Authentication};

let client = Dlt698Client::new(meter_addr)
    .security(Security::aes128()
        .key_from_kms("dlt698-key"))
    .auth(Authentication::high("password"))
    .timeout(Duration::from_secs(5))
    .retry(3);

// Read energy
let energy = client.read("0x00010000").await?;   // Total energy
println!("Total energy: {} kWh", energy);

// Read voltage
let voltage = client.read("0x02010100").await?;
println!("Voltage: {} V", voltage);

// Read current
let current = client.read("0x02020100").await?;
println!("Current: {} A", current);

// Read power factor
let pf = client.read("0x02060100").await?;
println!("Power factor: {}", pf);

// Read event records
let events = client.read_events(Range::last(Duration::from_secs(86400))).await?;
for event in &events {
    println!("[{}] {:?}: {}",
        event.timestamp, event.event_type, event.description);
}

// Control command (requires high privilege)
client.control("0x0F000001", Action::PowerOff).await?;

DL/T 698.45 Security Levels

LevelAuthenticationEncryptionApplicable
0NoneNoneTesting
1Low (password)NoneIntranet
2Medium (password + MAC)AES-128General scenarios
3High (ESAM)AES-128Critical metering

Protocol Support

ProtocolStandardPurposeApplicable Region
DL/T 698.45ChinaSmart meter (IPv6)China
DL/T 645ChinaSmart meter (serial)China
IEC 62056 / DLMSInternationalEnergy meteringInternational
ModbusInternationalGeneralGlobal
IEC 61850InternationalIEDGlobal

Regional Compliance Matrix

RegionPrivacy RegulationPower ProtocolCybersecurityData Localization
ChinaPIPLDL/T 698MLPS 2.0Data no exit
EUGDPRENTSO-EIEC 62443Data no exit
USCCPANERCNERC CIPUS preferred
JapanAPPIJEAGISO 27001Recommended local
BrazilLGPDONSABNT NBRRecommended

Data Localization

Requires data storage location by regional regulations, with automatic routing:

use eneros_compliance::localization::{DataResidency, Region, Rule};

let residency = DataResidency::new()
    .rule(Rule::new("cn")
        .region(Region::CnOnly)             // China data no exit
        .replication(Replication::None)
        .backup(BackupTarget::LocalOnly))
    .rule(Rule::new("eu")
        .region(Region::EuOnly)             // EU data no exit
        .replication(Replication::WithinEu))
    .rule(Rule::new("us")
        .region(Region::UsPreferred)        // US preferred
        .replication(Replication::Any))
    .rule(Rule::new("jp")
        .region(Region::JapanPreferred)
        .replication(Replication::WithinJapan));

// Automatically route data to compliant regions
residency.route(personal_data).await?;

// Check data storage compliance
let audit = residency.audit_storage().await?;
for violation in &audit.violations {
    println!("Violation: {} data stored in {}",
        violation.data_type, violation.actual_region);
}

Compliance Audit

use eneros_compliance::audit::{ComplianceAudit, AuditReport};

let audit = ComplianceAudit::new()
    .standard(Standard::GDPR)
    .standard(Standard::PIPL)
    .standard(Standard::NERC_CIP)
    .period(Range::last(Duration::from_secs(86400 * 30)));

let report: AuditReport = audit.run().await?;
println!("Compliance status: {}", if report.compliant { "Compliant" } else { "Non-compliant" });
println!("Total checks: {}", report.total_checks);
println!("Passed: {}", report.passed);
println!("Failed: {}", report.failed);

for finding in &report.findings {
    println!("[{}] {}: {}",
        finding.severity, finding.standard, finding.description);
}

Performance Metrics

OperationLatencyRemarks
i18n translation lookup< 1μsIn-memory cache
Language switching< 10msIncluding file loading
GDPR data export< 5sSingle user full
PIPL consent recording< 5msIncluding audit
CCPA deletion< 30sIncluding cascade deletion
DL/T 698.45 read< 100msSingle point
DL/T 698.45 event read< 500ms100 records
Data localization routing< 1msRule matching
Compliance audit (monthly)< 5minFull check

Relationship with Other Capabilities

  • Zero Trust and Security Enhancement: Compliance underlying security support, see Zero Trust and Security Enhancement
  • IoT Ubiquitous Access: DL/T 698.45 meter access, see IoT Ubiquitous Access
  • Multi-tenant and Isolation: Tenant-level compliance isolation, see Multi-tenant and Isolation
  • High Availability Enhancement: Cross-region data replication subject to localization constraints
  • Audit Chain: Compliance audit uses WORM storage