Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a calculation of savings #243

Merged
merged 10 commits into from
Aug 31, 2024
17 changes: 17 additions & 0 deletions public/locales/de/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,22 @@
"wheel": "Zwei Finger: Vergrößern und Verkleinern",
"doubleClick": "Zweimal kurz auf Gebäude tippen: Weiteres Gebäude für Simulation auswählen"
}
},
"savingsCalculation": {
"button": "Wirtschaftlichkeit der Anlage berechnen",
"consumptionTitle": "Jährlicher Stromverbrauch",
"consumptionHelper": "Als grober Schätzwert gilt: Rechne pro Person im Haushalt mit 800 kWh, für eine Wärmepumpe 2000 kWh und pro Elektroauto weitere 2000 kWh.",
"consumptionPlaceholder": "Jährlicher Stromverbrauch in kWh",
"storageTitle": "Stromspeicher",
"storagePlaceholder": "Speicherkapazität in kWh",
"electricityPriceTitle": "Strompreis in cent",
"electricityPricePlaceholder": "Preis pro kWh in cent",
"disclaimer": "Die berechneten Erträge und Einsparungen dienen nur als grobe Orientierung. Die Angaben sind ohne Gewähr und ersetzen keine individuelle Berechnung und Beratung vor Ort!",
"results": {
"production": "Jährliche Stromerzeugung der Solaranlage: ",
"consumption": "Jährlicher Eigenverbrauch: ",
"savings": "Jährliche Einsparungen: "
},
"calculate": "Berechnen"
}
}
17 changes: 17 additions & 0 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,22 @@
"wheel": "Two fingers: Zoom in and out",
"doubleClick": "Double-tap on a building: Select another building for simulation"
}
},
"savingsCalculation": {
"button": "Calculate Earnings",
"consumptionTitle": "Annual electricity consumption",
"consumptionHelper": "As a rough estimate: Calculate 800 kWh per person in the household, 2000 kWh for a heat pump, and an additional 2000 kWh per electric car.",
"consumptionPlaceholder": "Annual electricity consumption in kWh",
"storageTitle": "Electricity storage",
"storagePlaceholder": "Storage capacity in kWh",
"electricityPriceTitle": "Electricity price in cents",
"electricityPricePlaceholder": "Price per kWh in cents",
"disclaimer": "The calculated yields and savings are only for rough guidance. The information is without guarantee and does not replace individual calculation and on-site consultation!",
"results": {
"production": "Annual electricity generation of the solar system: ",
"consumption": "Annual self-consumption: ",
"savings": "Annual savings: "
},
"calculate": "Calculate"
}
}
226 changes: 171 additions & 55 deletions src/components/PVSimulation/SavingsCalculation.js
Original file line number Diff line number Diff line change
@@ -1,80 +1,196 @@
import {
Box,
Button,
Checkbox,
CheckboxGroup,
Circle,
Flex,
FormControl,
FormLabel,
Input,
ListItem,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Radio,
RadioGroup,
Stack,
Text,
UnorderedList,
useDisclosure,
} from "@chakra-ui/react"

import React, { useState } from "react"
import { useTranslation } from "react-i18next"
import HoverHelp from "../Template/HoverHelp"

function SavingCalculation({ pvSystems }) {
const { isOpen, onOpen, onClose } = useDisclosure({ defaultIsOpen: false })
const { t } = useTranslation()
const [annualConsumption, setAnnualConsumption] = useState("")
const [storageCapacity, setStorageCapacity] = useState("")
const [electricityPrice, setElectricityPrice] = useState(25)
const [selfConsumption, setSelfConsumption] = useState(0)
const [annualSavings, setAnnualSavings] = useState(0)
let pvProduction
if (pvSystems.length > 0) {
pvProduction = Math.round(
pvSystems.reduce((previous, current) => previous + current.annualYield, 0)
)
}

async function handleCalculateSaving() {
async function calculateSaving({
pvProduction,
consumptionHousehold,
storageCapacity,
electricityPrice,
setSelfConsumption,
setAnnualSavings,
}) {
const response = await fetch(
"https://www.openpv.de/data/savings_calculation/cons_prod.json"
)
const data = await response.json()

const normalizedConsumption = data["Consumption"]
const normalizedProduction = data["Production"]

const result = {}
let currentStorageLevel = 0
for (const timestamp in normalizedConsumption) {
const consumptionValue =
(normalizedConsumption[timestamp] * consumptionHousehold) / 1000
const productionValue =
(normalizedProduction[timestamp] * pvProduction) / 1000

let selfConsumption = 0
let excessProduction = 0

if (productionValue > consumptionValue) {
selfConsumption = consumptionValue
excessProduction = productionValue - consumptionValue

function SavingCalculation() {
const { isOpen, onOpen, onClose } = useDisclosure({ defaultIsOpen: true })
const [currentPage, setCurrentPage] = useState(1)
const { t, i18n } = useTranslation()
// Charge the storage
const availableStorageSpace = storageCapacity - currentStorageLevel
const chargedAmount = Math.min(
excessProduction,
availableStorageSpace
)
currentStorageLevel += chargedAmount
} else {
const productionDeficit = consumptionValue - productionValue

const calculateSaving = () => {
console.log("Savings")
// Use storage if available
const usedFromStorage = Math.min(
productionDeficit,
currentStorageLevel
)
currentStorageLevel -= usedFromStorage

selfConsumption = productionValue + usedFromStorage
}

result[timestamp] = selfConsumption
}

let selfConsumedElectricity = Object.values(result).reduce(
(acc, val) => acc + val,
0
)

setSelfConsumption(Math.round(selfConsumedElectricity))
setAnnualSavings(
Math.round((selfConsumedElectricity * electricityPrice) / 100)
)
}

await calculateSaving({
pvProduction: pvProduction,
consumptionHousehold: parseFloat(annualConsumption),
storageCapacity: storageCapacity,
electricityPrice: electricityPrice,
setSelfConsumption: setSelfConsumption,
setAnnualSavings: setAnnualSavings,
})
}

const initialRef = React.useRef(null)
const finalRef = React.useRef(null)
const [value, setValue] = React.useState("1")

return (
<Modal isOpen={isOpen} onClose={onClose} size="xl">
<ModalOverlay />
<ModalContent>
<ModalHeader>{"Wirtschaftlichkeit berechnen"}</ModalHeader>
<ModalCloseButton />
<ModalBody>
<>
<FormControl>
<FormLabel>Jährlicher Stromverbrauch</FormLabel>
<Input
ref={initialRef}
placeholder="Jährlicher Stromverbrauch in kWh"
/>
</FormControl>
<br />
Wann verbrauche ich meinen Strom?
<RadioGroup onChange={setValue} value={value} colorScheme="teal">
<Stack direction="column">
<Radio value="1">Morgens und Abends</Radio>
<Radio value="2">Morgens, Mittags und Abends</Radio>
</Stack>
</RadioGroup>
<br />
Ich besitze oder plane den Kauf
<Stack spacing={5} direction="row">
<Checkbox colorScheme="teal">einer Wärmepumpe</Checkbox>
<Checkbox colorScheme="teal">eines Elektroautos</Checkbox>
</Stack>
</>
</ModalBody>

<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={calculateSaving}>
Berechnen
</Button>
</ModalFooter>
</ModalContent>
</Modal>
<>
{pvSystems.length > 0 && (
<Button onClick={onOpen} className="button-high-prio">
{t("savingsCalculation.button")}
</Button>
)}
<Modal isOpen={isOpen} onClose={onClose} size="xl">
<ModalOverlay />
<ModalContent>
<ModalHeader>{"Wirtschaftlichkeit berechnen"}</ModalHeader>
<ModalCloseButton />
<ModalBody>
<>
<FormControl>
<FormLabel>
{t("savingsCalculation.consumptionTitle")}
<HoverHelp
label={t("savingsCalculation.consumptionHelper")}
/>
</FormLabel>
<Input
ref={initialRef}
placeholder={t("savingsCalculation.consumptionPlaceholder")}
value={annualConsumption}
onChange={(e) => setAnnualConsumption(e.target.value)}
/>
</FormControl>
<br />
<FormControl>
<FormLabel>{t("savingsCalculation.storageTitle")}</FormLabel>
<Input
ref={initialRef}
placeholder={t("savingsCalculation.storagePlaceholder")}
value={storageCapacity}
onChange={(e) => setStorageCapacity(e.target.value)}
/>
</FormControl>
<br />
<FormControl>
<FormLabel>
{t("savingsCalculation.electricityPriceTitle")}
</FormLabel>
<Input
ref={initialRef}
placeholder={t(
"savingsCalculation.electricityPricePlaceholder"
)}
value={electricityPrice}
onChange={(e) => setElectricityPrice(e.target.value)}
/>
</FormControl>

<br />
<Text>{t("savingsCalculation.disclaimer")}</Text>
<UnorderedList>
<ListItem>
{t("savingsCalculation.results.production")}
{pvProduction} kWh
</ListItem>
<ListItem>
{t("savingsCalculation.results.consumption")}{" "}
{selfConsumption} kWh
</ListItem>
<ListItem>
{t("savingsCalculation.results.savings")} {annualSavings} €
</ListItem>
</UnorderedList>
</>
</ModalBody>

<ModalFooter>
<Button colorScheme="teal" mr={3} onClick={handleCalculateSaving}>
{t("savingsCalculation.calculate")}
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
)
}

Expand Down
53 changes: 0 additions & 53 deletions src/components/ThreeViewer/Meshes/PVSystem.js

This file was deleted.

Loading