Skip to content

feat(phases): add the manual phase's group (HBM / ACME Container) to the grouped consumption - #312

Merged
shrutesh-tether merged 2 commits into
tetherto:developfrom
arif-dewi:feat/phase-consumption-groups
Oct 15, 2026
Merged

shrutesh-tether merged 2 commits into
tetherto:developfrom
arif-dewi:feat/phase-consumption-groups

Conversation

@arif-dewi

@arif-dewi arif-dewi commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Asana

Summary

ACME-MCS Phase 1.5, BE-04 for consumption.

The Energy Miner Type View and Mining Unit View (moria-app-ui #3159) read GET /auth/metrics/consumption?groupBy=miner|container. getGroupedConsumption only adds up miner telemetry, so a phase whose power is entered by hand never shows there, even though featureConfig names its groups (groups: { minerType: 'HBM', container: 'acme-container' }). Grouped hashrate already adds these groups (injectSyntheticHashrateGroups); grouped consumption did not.

This PR adds injectSyntheticConsumptionGroups, called in getGroupedConsumption just before the summary is built:

  • When it runs:
    • only for groupBy=miner or groupBy=container (not rack);
    • only with no phase or phase=total (a concrete phase with groupBy is still rejected with ERR_PHASE_NOT_SUPPORTED);
    • only when Central DCS is enabled, since the hand-entered values live on the DCS worker.
  • Which phases: every phase with consumption.source: 'manual'. Its key is groups.minerType for the miner grouping and groups.container for the container grouping.
  • Value:
    • Each daily row gets the mean of the hours entered that day, as average W (powerW[key]).
    • consumptionMWh[key] is the MWh actually entered that day, not the mean × 24 h. Otherwise a day with only some hours entered would report hours that were never logged: one 123 MWh hour would read as 2952 MWh.
    • Hours with no entry are skipped, as getPhaseConsumption already does. A day with nothing entered gets no key rather than a 0.
    • The hand-entered store is read once for the whole range, starting at the first row's UTC midnight, which can be before start.
  • Safety:
    • A key that already exists in the telemetry is never overwritten (same rule as hashrate).
    • The power and MWh maps are copied before the key is added, so a map shared with the worker response or between rows is never changed.
    • The grouped series is miner telemetry only, so the phase's load is not counted twice.
  • calculateGroupedConsumptionSummary lists the new group. Its totalConsumptionMWh, and the site total, use the entered MWh instead of power × 24 h. Telemetry groups give exactly the same numbers as before, because their MWh is still power × 24 h.

Tests

New in tests/unit/handlers/metrics.handlers.test.js:

Test Asserts
groupBy miner injects the manual phase group from its logged hours 0.9 and 0.7 MWh give HBM = 800 kW and 1.6 MWh (not 19.2), and the summary totals add 1.6 MWh; telemetry is untouched; a day with no entries gets no key; summary.groupedBy.HBM; one read starting at the first row's UTC midnight
groupBy container injects the container group, phase=total too acme-container = 1.2 MW and no HBM key; phase=total gives the same result
groupBy never overwrites a telemetry key with the phase group a real HBM key keeps its telemetry value
groupBy is untouched without central DCS, phases, a manual phase or for racks keys unchanged in all four cases, and the hand-entered store is never read

Checks

  • Run end-to-end against a local app-node (on this branch, with the phase config): HBM and acme-container appear only on days with entered hours, and the values match the entered data (04/10 2663.67 MW, 05/10 132 MW, 13/10 123 MW). Miner Type and Mining Unit show HBM and ACME Container as the last bars. That run was before the MWh change, which only affects consumptionMWh and the summary, not the bars.
  • NODE_ENV=test brittle 'tests/unit/**/*.test.js': 1947/1947 pass
  • standard: clean

QA steps

  1. Run the specs: NODE_ENV=test npx brittle tests/unit/handlers/metrics.handlers.test.js. Expect all to pass, including the 4 getConsumption - groupBy … tests above.
  2. On a site with featureConfig.phases containing a consumption.source: 'manual' phase with groups, and Central DCS enabled (staging has both):
    • Open https://dev-moria.tether.to/reports/operations/energy and click Miner Type View. metrics/consumption?…&groupBy=miner returns an HBM key on every day that has hand-entered hours. HBM is the last bar.
    • Click Mining Unit View. …&groupBy=container returns acme-container, and ACME Container is the last bar, after group-16.
    • The bar value is the mean of that day's hand-entered MWh, as MW. Cross-check it with ACME Consumption Input for the same day.
  3. Pick a day range with no hand-entered hours (Custom). The bar is absent, not 0.
  4. Regression checks:
    • Site View and the per-phase views send no groupBy and are unchanged.
    • ?phase=phase1_5&groupBy=miner still returns 400 ERR_PHASE_NOT_SUPPORTED.
    • A site without phases or without Central DCS returns exactly the same grouped series as before.

Note: staging's Phase 1.5 currently reads about 123 MW (very likely an oversized hand-entered value). The ACME Container bar will show that value until the entry is corrected. That is a data issue, not part of this change.

FE dependency

None. moria-app-ui #3159 already labels HBM / acme-container and puts them last in both charts.

The Miner Type / Mining Unit energy views read GET /auth/metrics/consumption?groupBy=miner|container, which only sums miner telemetry, so a phase whose power is entered by hand (HBM / acme-container) never showed there. Each daily row now carries the phase's group at the mean of the hours logged that day, as the grouped hashrate already does with the pool hashrate.
…over 24 h

A day with only some hours entered reported hours that were never logged (one 123 MWh hour came back as 2952 MWh). The row now carries the logged MWh, and the grouped summary totals use it; telemetry groups are unchanged.
@shrutesh-tether
shrutesh-tether merged commit 34833f7 into tetherto:develop Oct 15, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants