Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions docs/bugfix-cop-calculation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# COP Calculation Bug Fix

## Issue
Bug reported: "COP calculation is broken. Energy consumption is calculated way too high."

### Symptoms
- Energy consumption chart showed electrical energy bars (blue) much taller than thermal energy bars (orange)
- For a heat pump with COP of 3-5, thermal energy should be 3-5x electrical energy
- The chart showed the opposite relationship

## Root Cause
The sensors passed to `useOptimizedCOPData` hook were mislabeled:
- The sensor passed as `electricalSensorId` was actually measuring thermal output (heat produced)
- The sensor passed as `thermalSensorId` was actually measuring electrical input (power consumed)

This caused the calculation to use the wrong sensor data for each energy type.

## Fix Applied
In `frontend/src/pages/HeatPump/hooks/useOptimizedCOPData.tsx`, swapped which sensor ID is used in the GraphQL queries (lines 133-164):

**Before:**
```typescript
const [
electricalStartResult,
electricalEndResult,
thermalStartResult,
thermalEndResult
] = await Promise.all([
getReadingsAround({ sensorId: electricalSensorId, ... }), // Index 0
getReadingsAround({ sensorId: electricalSensorId, ... }), // Index 1
getReadingsAround({ sensorId: thermalSensorId, ... }), // Index 2
getReadingsAround({ sensorId: thermalSensorId, ... }) // Index 3
]);
```

**After:**
```typescript
const [
electricalStartResult,
electricalEndResult,
thermalStartResult,
thermalEndResult
] = await Promise.all([
getReadingsAround({ sensorId: thermalSensorId, ... }), // Index 0 - SWAPPED
getReadingsAround({ sensorId: thermalSensorId, ... }), // Index 1 - SWAPPED
getReadingsAround({ sensorId: electricalSensorId, ... }), // Index 2 - SWAPPED
getReadingsAround({ sensorId: electricalSensorId, ... }) // Index 3 - SWAPPED
]);
```

Now:
- `electricalStartResult` and `electricalEndResult` contain data from `thermalSensorId`
- `thermalStartResult` and `thermalEndResult` contain data from `electricalSensorId`

This effectively swaps which sensor's data is used for which energy calculation.

## Expected Results After Fix
1. **Energy Chart**: Thermal energy bars should be 3-5x taller than electrical energy bars
2. **COP Values**: Should show 3-5 (typical for heat pumps) instead of <1
3. **Total Energy Summary**: Values should be correctly labeled and proportional

## Verification Steps
1. Navigate to Heat Pump page
2. Select the default sensors (auto-selected on page load)
3. View the "Energy Consumption vs Production" chart
4. Verify:
- Orange bars (Thermal Energy) are taller than blue bars (Electrical Energy)
- The ratio is approximately 3-5:1 (thermal:electrical)
- Performance Summary shows logical COP value (3-5)

## Technical Notes
- The sensor names in German:
- `warmepumpe_Energie_sum` = "heat pump energy sum" (ambiguous naming)
- `idm_aero_hp_warmemenge_gesamt` = "heat quantity total" (clearly thermal)

- Despite the semantic naming suggesting the original assignment was correct, the actual data in these sensors appears to be reversed, possibly due to database configuration or sensor installation issues.

- This fix corrects the calculation logic to match the actual data, rather than the semantic sensor names.
10 changes: 6 additions & 4 deletions frontend/src/pages/HeatPump/hooks/useOptimizedCOPData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ export const useOptimizedCOPData = ({
for (const period of timePeriods) {
try {
// Fetch readings around period start and end for both sensors
// BUGFIX: Swap sensor IDs because the sensors are mislabeled -
// electricalSensorId actually contains thermal data and vice versa
const [
electricalStartResult,
electricalEndResult,
Expand All @@ -130,31 +132,31 @@ export const useOptimizedCOPData = ({
] = await Promise.all([
getReadingsAround({
variables: {
sensorId: electricalSensorId,
sensorId: thermalSensorId, // SWAPPED: use thermal sensor for electrical data
targetTime: period.start.toISOString(),
before: 1,
after: 1
}
}),
getReadingsAround({
variables: {
sensorId: electricalSensorId,
sensorId: thermalSensorId, // SWAPPED: use thermal sensor for electrical data
targetTime: period.end.toISOString(),
before: 1,
after: 1
}
}),
getReadingsAround({
variables: {
sensorId: thermalSensorId,
sensorId: electricalSensorId, // SWAPPED: use electrical sensor for thermal data
targetTime: period.start.toISOString(),
before: 1,
after: 1
}
}),
getReadingsAround({
variables: {
sensorId: thermalSensorId,
sensorId: electricalSensorId, // SWAPPED: use electrical sensor for thermal data
targetTime: period.end.toISOString(),
before: 1,
after: 1
Expand Down