DashboardAmortisationComponent

This commit is contained in:
Patrick Haßel 2024-10-31 09:53:55 +01:00
parent e02ed10cbc
commit 2daa73c457
10 changed files with 108 additions and 23 deletions

View File

@ -29,6 +29,8 @@ export const HEATING_LOOP_SUPPLY_TEMPERATURE = 'heating.loop.supply.temperature'
export const HEATING_LOOP_RETURN_TEMPERATURE = 'heating.loop.return.temperature';
export const PERCENT = new ValueConstant(100, "%");
export const MILLIS_PER_MONTH = new ValueConstant(24 * 60 * 60 * 30 * 1000, '');
export const MILLIS_PER_YEAR = new ValueConstant(24 * 60 * 60 * 365 * 1000, '');
export const ELECTRICITY_GRID_PURCHASED_FEW = 7.7;
export const ELECTRICITY_GRID_PURCHASED_MUCH = 9.7;
@ -39,3 +41,13 @@ export const ELECTRICITY_PHOTOVOLTAIC_PRODUCED_MUCH = 2;
export const ELECTRICITY_PHOTOVOLTAIC_POWER_FEW = 50;
export const ELECTRICITY_PHOTOVOLTAIC_POWER_MUCH = 200;
export const ELECTRICITY_PHOTOVOLTAIC_PRODUCED_BEFORE_METER_CHANGE = new ValueConstant(287.995, "kWh");
export const GRID_KWH_EURO = new ValueConstant(0.33, "€");
export const PV_COST_MONTAGESCHIENE_EURO = 6.19;
export const PV_COST_MONTAGESCHIENE_COUNT = 8;
export const PV_COST_ANLAGE_EURO = 498;
export const PV_COST_ANLAGE_VERSAND_EURO = 29;
export const PV_COST_TOTAL_EURO = new ValueConstant(PV_COST_MONTAGESCHIENE_EURO * PV_COST_MONTAGESCHIENE_COUNT + PV_COST_ANLAGE_EURO + PV_COST_ANLAGE_VERSAND_EURO, "€");
export const PV_COST_AMORTISATION_KWH = PV_COST_TOTAL_EURO.div(GRID_KWH_EURO);
export const PV_COST_AMORTISATION_BEGIN = new Date(2024, 1, 10, 13, 39, 42, 345);

View File

@ -5,7 +5,7 @@ export class DisplayValue {
constructor(
readonly title: string,
readonly value: Value,
readonly color: string,
readonly color: string = '',
) {
// -
}

View File

@ -56,6 +56,10 @@ export class Value {
return this.unary(a => a * factor);
}
neg() {
return this.unary((v: number) => -v);
}
unary(func: (v: number) => number): Value {
if (this.value === null) {
return new Value(null, null, '');

View File

@ -32,16 +32,16 @@ export class DashboardAirTileComponent {
return [
'Garten',
new DisplayValue('Temperatur', this.seriesCacheService.outdoorTemperature, ''),
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.outdoorHumidityRelative, ''),
new DisplayValue('Luftfeuchte Absolut', this.seriesCacheService.outdoorHumidityAbsolute, ''),
new DisplayValue('Temperatur', this.seriesCacheService.outdoorTemperature),
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.outdoorHumidityRelative),
new DisplayValue('Luftfeuchte Absolut', this.seriesCacheService.outdoorHumidityAbsolute),
'Schlafzimmer',
new DisplayValue('Temperatur', this.seriesCacheService.schlafzimmerTemperature, ''),
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.schlafzimmerHumidityRelative, ''),
new DisplayValue('Temperatur', this.seriesCacheService.schlafzimmerTemperature),
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.schlafzimmerHumidityRelative),
new DisplayValue('Luftfeuchte Absolut', this.seriesCacheService.schlafzimmerHumidityAbsolute, bedroomVentColor),
'Heizungskeller',
new DisplayValue('Temperatur', this.seriesCacheService.heatingRoomTemperature, ''),
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.heatingRoomHumidityRelative, ''),
new DisplayValue('Temperatur', this.seriesCacheService.heatingRoomTemperature),
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.heatingRoomHumidityRelative),
new DisplayValue('Luftfeuchte Absolut', this.seriesCacheService.heatingRoomHumidityAbsolute, heatingRoomVentColor),
];
}

View File

@ -0,0 +1 @@
<app-value-list title="Amortisation" icon="amortisation.svg" [displayList]="getDisplayList()" [now]="now"></app-value-list>

View File

@ -0,0 +1,62 @@
import {Component, Input} from '@angular/core';
import {SeriesCacheService} from "../../../api/series/series-cache.service";
import {Display, DisplayValue} from "../../../api/value/Display";
import {ELECTRICITY_PHOTOVOLTAIC_PRODUCED_BEFORE_METER_CHANGE, GRID_KWH_EURO, MILLIS_PER_YEAR, PERCENT, PV_COST_AMORTISATION_BEGIN, PV_COST_AMORTISATION_KWH, PV_COST_TOTAL_EURO} from "../../../api/series/constants";
import {ValueListComponent} from "../../../shared/value-list/value-list.component";
import {ValueConstant} from "../../../api/value/Value";
import {DatePipe} from "@angular/common";
@Component({
selector: 'app-dashboard-amortisation',
standalone: true,
imports: [
ValueListComponent,
],
providers: [
DatePipe,
],
templateUrl: './dashboard-amortisation.component.html',
styleUrl: './dashboard-amortisation.component.less'
})
export class DashboardAmortisationComponent {
@Input()
now!: Date;
constructor(
protected readonly seriesCacheService: SeriesCacheService,
protected readonly datePipe: DatePipe,
) {
// -
}
getDisplayList(): Display[] {
const producedAfterChange = this.seriesCacheService.photovoltaicProduced.minus(ELECTRICITY_PHOTOVOLTAIC_PRODUCED_BEFORE_METER_CHANGE);
const selfAfterChange = producedAfterChange.minus(this.seriesCacheService.gridDelivered);
const selfRatio = selfAfterChange.div(producedAfterChange);
const selfConsumed = selfRatio.mul(this.seriesCacheService.photovoltaicProduced);
const costsSaved = selfConsumed.mul(GRID_KWH_EURO).withUnit("€")
const amortisationPercent = selfConsumed.div(PV_COST_AMORTISATION_KWH).mul(PERCENT).withUnit('%');
const amortisationAlreadyMillis = new ValueConstant(this.now.getTime() - PV_COST_AMORTISATION_BEGIN.getTime(), 'ms');
const amortisationMilliPerKWh = amortisationAlreadyMillis.div(selfConsumed).withUnit('ms/kWh');
const amortisationRestKWh = PV_COST_AMORTISATION_KWH.minus(selfConsumed);
const amortisationRestMillis = amortisationRestKWh.mul(amortisationMilliPerKWh).withUnit('ms');
const amortisationRestYears = amortisationRestMillis.div(MILLIS_PER_YEAR).withUnit('Jahre');
const amortisationTotalMillis = PV_COST_AMORTISATION_KWH.mul(amortisationMilliPerKWh).withUnit('ms');
const amortisationTotalYears = amortisationTotalMillis.div(MILLIS_PER_YEAR).withUnit('Jahre');
const amortisationDate = new Date(this.now.getTime() + (amortisationRestMillis.value || 0));
const constRestEuro = PV_COST_TOTAL_EURO.minus(costsSaved);
const amortisationDateString = 'Erwarte Amortisation am: ' + this.datePipe.transform(amortisationDate, 'dd. MMM yyyy');
return [
new DisplayValue('Ausgaben', PV_COST_TOTAL_EURO),
new DisplayValue('Ersparnis', costsSaved),
' ',
new DisplayValue('Noch offen', constRestEuro),
new DisplayValue('Amortisiert', amortisationPercent),
new DisplayValue('Restdauer', amortisationRestYears),
new DisplayValue('Gesamtdauer', amortisationTotalYears),
amortisationDateString,
];
}
}

View File

@ -9,3 +9,7 @@
<div class="tile">
<app-dashboard-heating-tile [now]="now"></app-dashboard-heating-tile>
</div>
<div class="tile">
<app-dashboard-amortisation [now]="now"></app-dashboard-amortisation>
</div>

View File

@ -5,6 +5,7 @@ import {DashboardElectricityTileComponent} from "./electricity/dashboard-electri
import {DashboardAirTileComponent} from "./air/dashboard-air-tile.component";
import {Subscription, timer} from "rxjs";
import {DashboardHeatingTileComponent} from "./heating/dashboard-heating-tile.component";
import {DashboardAmortisationComponent} from "./amortisation/dashboard-amortisation.component";
const UPDATE_INTERVAL_MILLIS = 1000;
const SLOW_UPDATE_INTERVAL_MILLIS = 60 * 1000;
@ -19,6 +20,7 @@ const SLOW_UPDATE_INTERVAL_MILLIS = 60 * 1000;
DashboardElectricityTileComponent,
DashboardAirTileComponent,
DashboardHeatingTileComponent,
DashboardAmortisationComponent,
],
templateUrl: './dashboard.component.html',
styleUrl: './dashboard.component.less'

View File

@ -73,30 +73,30 @@ export class DashboardElectricityTileComponent {
return [
'Zählerstände',
new DisplayValue('Bezogen', this.seriesCacheService.gridPurchased, ''),
new DisplayValue('Eingespeist', this.seriesCacheService.gridDelivered, ''),
new DisplayValue('Produziert', this.seriesCacheService.photovoltaicProduced, ''),
new DisplayValue('Selbst verbraucht', selfConsumed, ''),
new DisplayValue('Bezogen', this.seriesCacheService.gridPurchased),
new DisplayValue('Eingespeist', this.seriesCacheService.gridDelivered),
new DisplayValue('Produziert', this.seriesCacheService.photovoltaicProduced),
new DisplayValue('Selbst verbraucht', selfConsumed),
'Leistung',
new DisplayValue('Produktion', this.seriesCacheService.photovoltaicPower, this.seriesCacheService.photovoltaicPower.color(ELECTRICITY_PHOTOVOLTAIC_POWER_FEW, ELECTRICITY_PHOTOVOLTAIC_POWER_MUCH, 'red', 'orange', 'green')),
new DisplayValue('Netz', this.seriesCacheService.gridPower, gridColor),
new DisplayValue('Verbrauch', consumptionPower, ''),
new DisplayValue('Verbrauch', consumptionPower),
'Heute',
new DisplayValue('Produziert', this.producedToday, this.producedToday.color(ELECTRICITY_PHOTOVOLTAIC_PRODUCED_FEW, ELECTRICITY_PHOTOVOLTAIC_PRODUCED_MUCH, 'red', 'orange', 'green')),
new DisplayValue('Eingespeist', this.deliveredToday, ''),
new DisplayValue('Eigenverbrauch', selfToday, ''),
new DisplayValue('Eigenverbrauch', selfPercentToday, ''),
new DisplayValue('Autarkie', selfAutarkyPercentToday, ''),
new DisplayValue('Eingespeist', this.deliveredToday),
new DisplayValue('Selbst verbraucht', selfToday),
new DisplayValue('Eigenverbrauch', selfPercentToday),
new DisplayValue('Autarkie', selfAutarkyPercentToday),
new DisplayValue('Bezogen', this.purchasedToday, this.purchasedToday.color(ELECTRICITY_GRID_PURCHASED_FEW, ELECTRICITY_GRID_PURCHASED_MUCH, 'green')),
new DisplayValue('Verbraucht', consumedToday, ''),
new DisplayValue('Verbraucht', consumedToday),
'Gestern',
new DisplayValue('Produziert', this.producedYesterday, this.producedYesterday.color(ELECTRICITY_PHOTOVOLTAIC_PRODUCED_FEW, ELECTRICITY_PHOTOVOLTAIC_PRODUCED_MUCH, 'red', 'orange', 'green')),
new DisplayValue('Eingespeist', this.deliveredYesterday, ''),
new DisplayValue('Eigenverbrauch', selfYesterday, ''),
new DisplayValue('Eigenverbrauch', selfPercentYesterday, ''),
new DisplayValue('Autarkie', selfAutarkyPercentYesterday, ''),
new DisplayValue('Eingespeist', this.deliveredYesterday),
new DisplayValue('Selbst verbraucht', selfYesterday),
new DisplayValue('Eigenverbrauch', selfPercentYesterday),
new DisplayValue('Autarkie', selfAutarkyPercentYesterday),
new DisplayValue('Bezogen', this.purchasedYesterday, this.purchasedYesterday.color(ELECTRICITY_GRID_PURCHASED_FEW, ELECTRICITY_GRID_PURCHASED_MUCH, 'green')),
new DisplayValue('Verbraucht', consumedYesterday, ''),
new DisplayValue('Verbraucht', consumedYesterday),
];
}