# Savings Calculator

## Savings Calculator

**Files:** `src/content/sections/english/calculator-section.md`, `src/content/calculator/english/-index.md` · **Skill level:** Beginner

<div class="border border-dark">
  ![Ecozen savings calculator](/images/ecozen/calculator.jpg)
</div>

The calculator on `/calculator/` turns one number, the visitor's average monthly electricity bill, into four results: the **system size** in kWp, the **yearly savings**, the **payback** time in years, and the **CO₂ avoided** per year. A bar shows how much of the visitor's usage the system covers. The results update as the slider moves, and a button sends the visitor to the quote form.

The numbers come from a few assumptions you set once. Out of the box they are sample values. **Set them for your region before you launch**, or the calculator will promise savings your quotes can't match.

### The Assumptions
They are in `src/content/sections/english/calculator-section.md`, under `calculator.assumptions`:

```yaml
calculator:
  assumptions:
    rate: 0.28              # price per kWh
    sunHours: 4.2           # average peak sun hours per day
    performanceRatio: 0.8   # system losses
    coverageTarget: 0.9     # share of yearly usage to size for
    maxSystemKwp: 10        # typical residential roof limit
    costPerKwp: 1900        # installed price per kWp
    co2Factor: 0.38         # kg CO₂ per grid kWh
```

| Key                | What to put there                                                                 |
| ------------------ | --------------------------------------------------------------------------------- |
| `rate`             | Your customers' typical electricity price per kWh, in the calculator's currency  |
| `sunHours`         | Average daily peak sun hours for your region. Solar maps and your design software give this figure |
| `performanceRatio` | The share of the panels' rated output that reaches the home after inverter, cable, heat, and soiling losses. `0.75` to `0.85` is common |
| `coverageTarget`   | How much of the yearly usage you size systems to cover, from `0` to `1`. `0.9` sizes for 90% |
| `maxSystemKwp`     | The largest system that fits a typical roof you install on. Larger bills are capped at this size |
| `costPerKwp`       | Your average installed price per kWp, including panels, inverter, mounting, and labor |
| `co2Factor`        | Kilograms of CO₂ per kWh of grid electricity where you work. Your national grid operator or energy agency publishes it |

### How The Estimate Is Calculated
The formula is in `src/lib/utils/solarEstimate.ts`. For a monthly bill:

<Steps>

1. **Yearly usage** (kWh) = monthly bill ÷ `rate` × 12
2. **Output of 1 kWp** per year (kWh) = `sunHours` × 365 × `performanceRatio`
3. **System size** (kWp) = yearly usage × `coverageTarget` ÷ output of 1 kWp, capped at `maxSystemKwp`
4. **Yearly output** (kWh) = system size × output of 1 kWp
5. **Yearly savings** = yearly output × `rate`
6. **Payback** (years) = system size × `costPerKwp` ÷ yearly savings
7. **CO₂ avoided** (t / year) = yearly output × `co2Factor` ÷ 1000
8. **Usage covered** = yearly output ÷ yearly usage, at most 100%

</Steps>

With the shipped values and a $180 bill: yearly usage is about 7,714 kWh, 1 kWp makes about 1,226 kWh a year, so the system is 5.7 kWp. It makes about 6,943 kWh, saves $1,944 a year, pays back in 5.5 years, and avoids 2.6 t of CO₂.

<Aside type="caution" title="What the estimate leaves out">
  The formula values every kWh the panels make at the full `rate`, as if the
  home used all of it. Where exported power earns less than the tariff, real
  savings are lower: lower `rate` or `coverageTarget` to stay on the safe side.
  It also leaves out batteries, incentives, tariff changes, and panel
  degradation. Keep the `note` under the results ("Estimate only…") and the FAQ
  on the calculator page, which say so.
</Aside>

### The Slider, Labels, And Currency
The rest of `calculator` sets what visitors see:

```yaml
calculator:
  title: "Estimate your savings"
  billLabel: "Average monthly bill"
  currency: "$"        # shown before amounts; "€" is shown after them (180 €)
  min: 50              # slider range and step, in the currency
  max: 600
  step: 10
  default: 180         # starting bill
  coverageLabel: "of your usage covered"
  labels:
    size: "System size"
    savings: "Yearly savings"
    payback: "Payback"
    co2: "CO₂ avoided"
  units:
    size: "kWp"
    payback: "years"
    co2: "t / year"
  note: "Estimate only. Your survey confirms roof space, shading, and local tariffs."
  button:
    enable: true
    label: "Get my exact quote"
    url: "/contact/"
```

The shipped French file uses `currency: "€"` with the same numbers. If your languages serve the same market, give them the same currency and assumptions. Amounts follow the language's `dateLocale` in `src/config/language.json`, with Latin digits in every language.

**How we calculate it.** `assumptionsList` is the numbered list beside the calculator. Keep it in step with your assumptions, in plain words.

### The Calculator Page
`src/content/calculator/english/-index.md` sets the page header and three blocks:

- `calculatorSection` clears the section's badge, title, and description, because the page header shows them. It can also override any `calculator` key for this page, for example `calculator: { currency: "£" }`.
- `faqSection` holds questions about the estimate.
- `ctaSection` sends visitors to the quote form.

The contact page's call to action links to `/calculator/`. If you remove the calculator, change that button in `src/content/contact/english/-index.md`, and remove the **Savings calculator** link from the **Pages** menu.

Neither file has a schema, so `npm run astro-check` doesn't report a typo. After you change a value, open `/calculator/`, move the slider, and check a result by hand with the formula above.

### Do It With AI
```text
Set the savings calculator for [REGION]. In src/content/sections/english/calculator-section.md,
under calculator.assumptions, set rate [PRICE PER KWH], sunHours [PEAK SUN HOURS],
performanceRatio [VALUE], costPerKwp [INSTALLED PRICE PER KWP], co2Factor [KG CO2 PER KWH], and
maxSystemKwp [TYPICAL ROOF LIMIT]. Set currency "[SYMBOL]" and a slider range of [MIN] to [MAX]
with default [VALUE]. Copy the same numbers to calculator-section.md in the other language folders.
Then work out the results for a [AMOUNT] bill with the formula in src/lib/utils/solarEstimate.ts
and show me the numbers, so I can compare them with a real quote.
```