File size: 4,221 Bytes
c993983
 
 
 
70656b2
c993983
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70656b2
 
 
 
c993983
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/** StatusQuoComparison — table comparing status quo vs pinch-optimal demands. */

import { useAnalysisStore } from '../../store/analysisStore';
import type { HPIResult } from '../../types/analysis';
import ChartHelpButton from '../ui/ChartHelpButton';

export default function StatusQuoComparison() {
  const statusQuoResult = useAnalysisStore((s) => s.statusQuoResult);
  const pinchResult = useAnalysisStore((s) => s.pinchResult);
  const hpiResult = useAnalysisStore((s) => s.hpiResult);
  const selectedHPTypes = useAnalysisStore((s) => s.selectedHPTypes);
  const energyDemands = useAnalysisStore((s) => s.energyDemands);

  if (!pinchResult) return null;

  const hasDemands = energyDemands.some(
    (d) => d.heat_demand > 0 || d.cooling_demand > 0,
  );

  if (!hasDemands) {
    return (
      <div className="pa-info-box">
        💡 Current energy supplies are required to calculate the difference to
        status quo. Please configure them in the "Current energy supply" section
        above.
      </div>
    );
  }

  if (!statusQuoResult) return null;

  const { total_current_heating, total_current_cooling, pinch_hot_utility, pinch_cold_utility, heating_savings_kW, cooling_savings_kW } = statusQuoResult;

  const heatPct = total_current_heating > 0 ? `${(Math.abs(heating_savings_kW) / total_current_heating * 100).toFixed(1)}%` : 'N/A';
  const coolPct = total_current_cooling > 0 ? `${(Math.abs(cooling_savings_kW) / total_current_cooling * 100).toFixed(1)}%` : 'N/A';

  // Find best HP for coverage columns
  const bestHP = getBestHP(hpiResult, selectedHPTypes);
  const hpLabel = bestHP ? `HP Coverage – ${bestHP.name} (kW)` : 'HP Coverage (kW)';
  let hpHeatCov = 'N/A', hpCoolCov = 'N/A', hpHeatPct = 'N/A', hpCoolPct = 'N/A';

  if (bestHP && bestHP.q_sink != null && bestHP.q_source != null) {
    const hCov = Math.min(bestHP.q_sink, pinch_hot_utility);
    const cCov = Math.min(bestHP.q_source, pinch_cold_utility);
    hpHeatCov = hCov.toFixed(1);
    hpCoolCov = cCov.toFixed(1);
    hpHeatPct = pinch_hot_utility > 0 ? `${(hCov / pinch_hot_utility * 100).toFixed(1)}%` : 'N/A';
    hpCoolPct = pinch_cold_utility > 0 ? `${(cCov / pinch_cold_utility * 100).toFixed(1)}%` : 'N/A';
  }

  return (
    <div className="pa-section">
      <h3 style={{ display: 'flex', alignItems: 'center' }}>
        📊 Comparison of Status Quo and Proposal
        <ChartHelpButton inline title="Comparison of Status Quo and Proposal" description="Compare the current external energy supply with the absolute minimum external energy required after maximal internal heat recovery (the proposal). Savings indicate how much external utility is avoided." />
      </h3>
      <table className="pa-table">
        <thead>
          <tr>
            <th>Type of Energy Demand</th>
            <th>Current Status Quo (kW)</th>
            <th>Min. Demands after Heat Recovery (kW)</th>
            <th>Savings (kW)</th>
            <th>Savings (%)</th>
            <th>{hpLabel}</th>
            <th>Heat Pump Coverage (%)</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>Heating Demand</td>
            <td>{total_current_heating.toFixed(1)}</td>
            <td>{pinch_hot_utility.toFixed(1)}</td>
            <td>{heating_savings_kW.toFixed(1)}</td>
            <td>{heatPct}</td>
            <td>{hpHeatCov}</td>
            <td>{hpHeatPct}</td>
          </tr>
          <tr>
            <td>Cooling Demand</td>
            <td>{total_current_cooling.toFixed(1)}</td>
            <td>{pinch_cold_utility.toFixed(1)}</td>
            <td>{cooling_savings_kW.toFixed(1)}</td>
            <td>{coolPct}</td>
            <td>{hpCoolCov}</td>
            <td>{hpCoolPct}</td>
          </tr>
        </tbody>
      </table>
    </div>
  );
}

function getBestHP(hpiResult: HPIResult | null, selectedHPTypes: string[]) {
  if (!hpiResult) return null;
  const available = hpiResult.heat_pumps
    .filter((hp) => hp.available)
    .sort((a, b) => (b.cop ?? 0) - (a.cop ?? 0));
  if (selectedHPTypes.length > 0) {
    const sel = available.filter((hp) => selectedHPTypes.includes(hp.name));
    if (sel.length > 0) return sel[0];
  }
  return available[0] ?? null;
}