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 HEATING_LOOP_RETURN_TEMPERATURE = 'heating.loop.return.temperature';
|
||||||
|
|
||||||
export const PERCENT = new ValueConstant(100, "%");
|
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_FEW = 7.7;
|
||||||
export const ELECTRICITY_GRID_PURCHASED_MUCH = 9.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_FEW = 50;
|
||||||
export const ELECTRICITY_PHOTOVOLTAIC_POWER_MUCH = 200;
|
export const ELECTRICITY_PHOTOVOLTAIC_POWER_MUCH = 200;
|
||||||
export const ELECTRICITY_PHOTOVOLTAIC_PRODUCED_BEFORE_METER_CHANGE = new ValueConstant(287.995, "kWh");
|
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(
|
constructor(
|
||||||
readonly title: string,
|
readonly title: string,
|
||||||
readonly value: Value,
|
readonly value: Value,
|
||||||
readonly color: string,
|
readonly color: string = '',
|
||||||
) {
|
) {
|
||||||
// -
|
// -
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,6 +56,10 @@ export class Value {
|
|||||||
return this.unary(a => a * factor);
|
return this.unary(a => a * factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
neg() {
|
||||||
|
return this.unary((v: number) => -v);
|
||||||
|
}
|
||||||
|
|
||||||
unary(func: (v: number) => number): Value {
|
unary(func: (v: number) => number): Value {
|
||||||
if (this.value === null) {
|
if (this.value === null) {
|
||||||
return new Value(null, null, '');
|
return new Value(null, null, '');
|
||||||
|
|||||||
@ -32,16 +32,16 @@ export class DashboardAirTileComponent {
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'Garten',
|
'Garten',
|
||||||
new DisplayValue('Temperatur', this.seriesCacheService.outdoorTemperature, ''),
|
new DisplayValue('Temperatur', this.seriesCacheService.outdoorTemperature),
|
||||||
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.outdoorHumidityRelative, ''),
|
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.outdoorHumidityRelative),
|
||||||
new DisplayValue('Luftfeuchte Absolut', this.seriesCacheService.outdoorHumidityAbsolute, ''),
|
new DisplayValue('Luftfeuchte Absolut', this.seriesCacheService.outdoorHumidityAbsolute),
|
||||||
'Schlafzimmer',
|
'Schlafzimmer',
|
||||||
new DisplayValue('Temperatur', this.seriesCacheService.schlafzimmerTemperature, ''),
|
new DisplayValue('Temperatur', this.seriesCacheService.schlafzimmerTemperature),
|
||||||
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.schlafzimmerHumidityRelative, ''),
|
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.schlafzimmerHumidityRelative),
|
||||||
new DisplayValue('Luftfeuchte Absolut', this.seriesCacheService.schlafzimmerHumidityAbsolute, bedroomVentColor),
|
new DisplayValue('Luftfeuchte Absolut', this.seriesCacheService.schlafzimmerHumidityAbsolute, bedroomVentColor),
|
||||||
'Heizungskeller',
|
'Heizungskeller',
|
||||||
new DisplayValue('Temperatur', this.seriesCacheService.heatingRoomTemperature, ''),
|
new DisplayValue('Temperatur', this.seriesCacheService.heatingRoomTemperature),
|
||||||
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.heatingRoomHumidityRelative, ''),
|
new DisplayValue('Luftfeuchte Relativ', this.seriesCacheService.heatingRoomHumidityRelative),
|
||||||
new DisplayValue('Luftfeuchte Absolut', this.seriesCacheService.heatingRoomHumidityAbsolute, heatingRoomVentColor),
|
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">
|
<div class="tile">
|
||||||
<app-dashboard-heating-tile [now]="now"></app-dashboard-heating-tile>
|
<app-dashboard-heating-tile [now]="now"></app-dashboard-heating-tile>
|
||||||
</div>
|
</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 {DashboardAirTileComponent} from "./air/dashboard-air-tile.component";
|
||||||
import {Subscription, timer} from "rxjs";
|
import {Subscription, timer} from "rxjs";
|
||||||
import {DashboardHeatingTileComponent} from "./heating/dashboard-heating-tile.component";
|
import {DashboardHeatingTileComponent} from "./heating/dashboard-heating-tile.component";
|
||||||
|
import {DashboardAmortisationComponent} from "./amortisation/dashboard-amortisation.component";
|
||||||
|
|
||||||
const UPDATE_INTERVAL_MILLIS = 1000;
|
const UPDATE_INTERVAL_MILLIS = 1000;
|
||||||
const SLOW_UPDATE_INTERVAL_MILLIS = 60 * 1000;
|
const SLOW_UPDATE_INTERVAL_MILLIS = 60 * 1000;
|
||||||
@ -19,6 +20,7 @@ const SLOW_UPDATE_INTERVAL_MILLIS = 60 * 1000;
|
|||||||
DashboardElectricityTileComponent,
|
DashboardElectricityTileComponent,
|
||||||
DashboardAirTileComponent,
|
DashboardAirTileComponent,
|
||||||
DashboardHeatingTileComponent,
|
DashboardHeatingTileComponent,
|
||||||
|
DashboardAmortisationComponent,
|
||||||
],
|
],
|
||||||
templateUrl: './dashboard.component.html',
|
templateUrl: './dashboard.component.html',
|
||||||
styleUrl: './dashboard.component.less'
|
styleUrl: './dashboard.component.less'
|
||||||
|
|||||||
@ -73,30 +73,30 @@ export class DashboardElectricityTileComponent {
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'Zählerstände',
|
'Zählerstände',
|
||||||
new DisplayValue('Bezogen', this.seriesCacheService.gridPurchased, ''),
|
new DisplayValue('Bezogen', this.seriesCacheService.gridPurchased),
|
||||||
new DisplayValue('Eingespeist', this.seriesCacheService.gridDelivered, ''),
|
new DisplayValue('Eingespeist', this.seriesCacheService.gridDelivered),
|
||||||
new DisplayValue('Produziert', this.seriesCacheService.photovoltaicProduced, ''),
|
new DisplayValue('Produziert', this.seriesCacheService.photovoltaicProduced),
|
||||||
new DisplayValue('Selbst verbraucht', selfConsumed, ''),
|
new DisplayValue('Selbst verbraucht', selfConsumed),
|
||||||
'Leistung',
|
'Leistung',
|
||||||
new DisplayValue('Produktion', this.seriesCacheService.photovoltaicPower, this.seriesCacheService.photovoltaicPower.color(ELECTRICITY_PHOTOVOLTAIC_POWER_FEW, ELECTRICITY_PHOTOVOLTAIC_POWER_MUCH, 'red', 'orange', 'green')),
|
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('Netz', this.seriesCacheService.gridPower, gridColor),
|
||||||
new DisplayValue('Verbrauch', consumptionPower, ''),
|
new DisplayValue('Verbrauch', consumptionPower),
|
||||||
'Heute',
|
'Heute',
|
||||||
new DisplayValue('Produziert', this.producedToday, this.producedToday.color(ELECTRICITY_PHOTOVOLTAIC_PRODUCED_FEW, ELECTRICITY_PHOTOVOLTAIC_PRODUCED_MUCH, 'red', 'orange', 'green')),
|
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('Eingespeist', this.deliveredToday),
|
||||||
new DisplayValue('Eigenverbrauch', selfToday, ''),
|
new DisplayValue('Selbst verbraucht', selfToday),
|
||||||
new DisplayValue('Eigenverbrauch', selfPercentToday, ''),
|
new DisplayValue('Eigenverbrauch', selfPercentToday),
|
||||||
new DisplayValue('Autarkie', selfAutarkyPercentToday, ''),
|
new DisplayValue('Autarkie', selfAutarkyPercentToday),
|
||||||
new DisplayValue('Bezogen', this.purchasedToday, this.purchasedToday.color(ELECTRICITY_GRID_PURCHASED_FEW, ELECTRICITY_GRID_PURCHASED_MUCH, 'green')),
|
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',
|
'Gestern',
|
||||||
new DisplayValue('Produziert', this.producedYesterday, this.producedYesterday.color(ELECTRICITY_PHOTOVOLTAIC_PRODUCED_FEW, ELECTRICITY_PHOTOVOLTAIC_PRODUCED_MUCH, 'red', 'orange', 'green')),
|
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('Eingespeist', this.deliveredYesterday),
|
||||||
new DisplayValue('Eigenverbrauch', selfYesterday, ''),
|
new DisplayValue('Selbst verbraucht', selfYesterday),
|
||||||
new DisplayValue('Eigenverbrauch', selfPercentYesterday, ''),
|
new DisplayValue('Eigenverbrauch', selfPercentYesterday),
|
||||||
new DisplayValue('Autarkie', selfAutarkyPercentYesterday, ''),
|
new DisplayValue('Autarkie', selfAutarkyPercentYesterday),
|
||||||
new DisplayValue('Bezogen', this.purchasedYesterday, this.purchasedYesterday.color(ELECTRICITY_GRID_PURCHASED_FEW, ELECTRICITY_GRID_PURCHASED_MUCH, 'green')),
|
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