diff --git a/packages/web/components/WorkbookView.tsx b/packages/web/components/WorkbookView.tsx
index d1236a6..ea56a5d 100644
--- a/packages/web/components/WorkbookView.tsx
+++ b/packages/web/components/WorkbookView.tsx
@@ -600,7 +600,7 @@ function HourlyGenerationSheet({ hourly, codYear }: { hourly: HourlyData; codYea
return next;
});
- // Helper: get hourly data for a specific year/month/day
+ // Helper: get hourly output data for a specific year/month/day (sums)
const getYearData = (year: number, isSolar: boolean) => {
const data = isSolar ? solar_hourly : wind_hourly;
if (!data) return [];
@@ -623,6 +623,51 @@ function HourlyGenerationSheet({ hourly, codYear }: { hourly: HourlyData; codYea
return monthData.slice(start, start + 24);
};
+ // Helper: get raw profile data (0-1 normalized) for averages
+ const getYearProfile = (year: number, data?: number[]) => {
+ if (!data) return [];
+ const start = (year - 1) * 8760;
+ return data.slice(start, start + 8760);
+ };
+
+ const getMonthProfile = (year: number, month: number, data?: number[]) => {
+ if (!data) return [];
+ const yearData = getYearProfile(year, data);
+ if (!yearData.length) return [];
+ const start = MONTH_DAYS.slice(0, month - 1).reduce((a, d) => a + d, 0) * 24;
+ const days = MONTH_DAYS[month - 1];
+ return yearData.slice(start, start + days * 24);
+ };
+
+ const getDayProfile = (year: number, month: number, day: number, data?: number[]) => {
+ if (!data) return [];
+ const yearData = getYearProfile(year, data);
+ if (!yearData.length) return [];
+ const start = MONTH_DAYS.slice(0, month - 1).reduce((a, d) => a + d, 0) * 24;
+ const monthData = yearData.slice(start, start + MONTH_DAYS[month - 1] * 24);
+ const dayStart = (day - 1) * 24;
+ return monthData.slice(dayStart, dayStart + 24);
+ };
+
+ // Compute averages from raw profile (0-1 values)
+ const computeYearAvgProfile = (year: number, data?: number[]) => {
+ const d = getYearProfile(year, data);
+ if (!d.length) return 0;
+ return d.reduce((a, v) => a + v, 0) / d.length;
+ };
+
+ const computeMonthAvgProfile = (year: number, month: number, data?: number[]) => {
+ const d = getMonthProfile(year, month, data);
+ if (!d.length) return 0;
+ return d.reduce((a, v) => a + v, 0) / d.length;
+ };
+
+ const computeDayAvgProfile = (year: number, month: number, day: number, data?: number[]) => {
+ const d = getDayProfile(year, month, day, data);
+ if (!d.length) return 0;
+ return d.reduce((a, v) => a + v, 0) / d.length;
+ };
+
// Compute totals for display
const computeYearTotal = (year: number, isSolar: boolean) => {
const d = getYearData(year, isSolar);
@@ -711,9 +756,8 @@ function HourlyGenerationSheet({ hourly, codYear }: { hourly: HourlyData; codYea
const totalReYr = hasTotalRe ? computeYearTotalNew(year, hourly_total_re) : 0;
const clientEndYr = hasClientEnd ? computeYearTotalNew(year, hourly_client_end) : 0;
const loadYr = hasLoad ? computeYearTotalNew(year, hourly_load) : 0;
- // For profile totals - sum of hourly profile values = total energy before capacity division
- const solarProfileSum = hasSolarProfile ? computeYearTotalNew(year, hourly_solar_profile) : 0;
- const windProfileSum = hasWindProfile ? computeYearTotalNew(year, hourly_wind_profile) : 0;
+ // Solar 8760: average profile value (0-1), DC MW: capacity (placeholder), Solar MW: sum output
+ const solarProfileAvg = hasSolarProfile ? computeYearAvgProfile(year, hourly_solar_profile) : 0;
const fyLabel = getFyLabel(i);
return (
@@ -724,11 +768,13 @@ function HourlyGenerationSheet({ hourly, codYear }: { hourly: HourlyData; codYea
>
{isYearExpanded ? "▼" : "▶"}
{fyLabel}
- {hasSolar && {Math.round(solarProfileSum).toLocaleString()}}
- {hasSolar && -}
+ {/* Solar 8760: avg profile (show as %), DC MW, Solar MW */}
+ {hasSolar && {(solarProfileAvg * 100).toFixed(1)}%}
+ {hasSolar && 100}
{hasSolar && {Math.round(solarYr).toLocaleString()}}
- {hasWind && {Math.round(windProfileSum).toLocaleString()}}
- {hasWind && -}
+ {/* Wind 8760, MW, Wind MW */}
+ {hasWind && -}
+ {hasWind && 50}
{hasWind && {Math.round(windYr).toLocaleString()}}
{hasTotalRe && {Math.round(totalReYr).toLocaleString()}}
{hasClientEnd && {Math.round(clientEndYr).toLocaleString()}}