Skip to content

feat(ui): Smooth efficiency average display using Exponential Moving Average (EMA) #1801

Description

@chillingbee

Markdown

Problem

The efficiencyAverage in the web interface currently calculates the 1-minute average (or 1-hour average when modified) by dividing the live power consumption (info.power) by the hashrate. Because info.power is updated and telemetry is fetched every second, the displayed efficiency value fluctuates rapidly by ~0.15 J/TH or more due to minor real-time power draw spikes. This causes unnecessary visual flickering in the UI for a value labeled as an "average".

Solution

This introduces a frontend-side Exponential Moving Average (EMA) filter to smooth out the real-time power fluctuations for the efficiencyAverage display.

  1. Added smoothedEfficiencyAverage to home.component.ts to persist the filtered state.
  2. Applied a 99% historical / 1% new value split (old * 0.99) + (new * 0.01) to damp out the per-second noise.
  3. Changed the backend data source for the average from hashRate_1m to hashRate_1h to provide a true, rock-solid long-term efficiency metric.

Result

The efficiency average indicator is now visually stable and reflects the true hardware performance without nervous second-by-second jumping, while still accurately adapting to frequency or voltage changes over a few minutes.

diff --git a/main/http_server/axe-os/src/app/components/home/home.component.ts b/main/http_server/axe-os/src/app/components/home/home.component.ts
index b5314a74..7a5d4cdf 100644
--- a/main/http_server/axe-os/src/app/components/home/home.component.ts
+++ b/main/http_server/axe-os/src/app/components/home/home.component.ts
@@ -175,6 +175,7 @@ export class HomeComponent implements OnInit, OnDestroy {
    public asicDomainsAmount: number = 0;
    public efficiency: number = 0;
    public efficiencyAverage: number = 0;
+   public smoothedEfficiencyAverage: number = 0;
    public expectedEfficiency: number = 0;
    public activePoolUserAddressPart: string = '';
    public activePoolUserSuffixPart: string = '';
@@ -871,12 +872,24 @@ export class HomeComponent implements OnInit, OnDestroy {
 
          this.efficiency = this.calculateEfficiency(info, 'hashRate');
          
-        // MANUELLE BERECHNUNG FÜR DEN STUNDEN-DURCHSCHNITT:
+        // BERECHNUNG MIT GEGLÄTTETEM FILTER (DÄMPFUNG)
          if (info && info.power > 0 && info.hashRate_1h > 0) {
-            // Leistung (W) geteilt durch Hashrate (GH/s umgerechnet in TH/s -> durch 1000)
-            this.efficiencyAverage = (info.power * 1000) / info.hashRate_1h;
+            const currentRawAvg = (info.power * 1000) / info.hashRate_1h;
+            
+            // Wenn der Wert zum ersten Mal berechnet wird, nimm den aktuellen Wert
+            if (this.smoothedEfficiencyAverage === 0) {
+                this.smoothedEfficiencyAverage = currentRawAvg;
+            } else {
+                // FILTER: 99% alter Wert + 1% neuer Wert. 
+                this.smoothedEfficiencyAverage = (this.smoothedEfficiencyAverage * 0.99) + (currentRawAvg * 0.01);
+            }
+            
+            // Weise den geglätteten Wert der Anzeige zu
+            this.efficiencyAverage = this.smoothedEfficiencyAverage;
          } else {
             this.efficiencyAverage = 0;
+            this.smoothedEfficiencyAverage = 0;
          }
 
         this.expectedEfficiency = this.calculateEfficiency(info, 'expectedHashrate');```

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions