DashboardAmortisationComponent
This commit is contained in:
parent
e02ed10cbc
commit
2daa73c457
@ -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);
|
||||
|
||||
@ -5,7 +5,7 @@ export class DisplayValue {
|
||||
constructor(
|
||||
readonly title: string,
|
||||
readonly value: Value,
|
||||
readonly color: string,
|
||||
readonly color: string = '',
|
||||
) {
|
||||
// -
|
||||
}
|
||||
|
||||
@ -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, '');
|
||||
|
||||
@ -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),
|
||||
];
|
||||
}
|
||||
|
||||
@ -0,0 +1 @@
|
||||
<app-value-list title="Amortisation" icon="amortisation.svg" [displayList]="getDisplayList()" [now]="now"></app-value-list>
|
||||
@ -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,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@ -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>
|
||||
|
||||
@ -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'
|
||||
|
||||
@ -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),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user