From 740c4bbc95394b9f82462351f6a25a3a654c3714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Fri, 18 Oct 2024 10:56:12 +0200 Subject: [PATCH] refactor seriesService to cache series --- src/main/angular/public/air.svg | 15 +++ .../src/app/api/series/series.service.ts | 39 +++++- .../pages/dashboard/dashboard.component.html | 2 +- .../pages/dashboard/dashboard.component.ts | 121 +----------------- .../dashboard-electricity-tile.component.html | 1 + .../dashboard-electricity-tile.component.less | 0 .../dashboard-electricity-tile.component.ts | 91 +++++++++++++ .../values-tile/values-tile.component.html | 2 +- .../values-tile/values-tile.component.ts | 12 +- src/main/angular/src/styles.less | 2 +- src/main/angular/src/widths.less | 4 +- 11 files changed, 163 insertions(+), 126 deletions(-) create mode 100644 src/main/angular/public/air.svg create mode 100644 src/main/angular/src/app/pages/dashboard/electricity/dashboard-electricity-tile.component.html create mode 100644 src/main/angular/src/app/pages/dashboard/electricity/dashboard-electricity-tile.component.less create mode 100644 src/main/angular/src/app/pages/dashboard/electricity/dashboard-electricity-tile.component.ts diff --git a/src/main/angular/public/air.svg b/src/main/angular/public/air.svg new file mode 100644 index 0000000..06407da --- /dev/null +++ b/src/main/angular/public/air.svg @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/src/main/angular/src/app/api/series/series.service.ts b/src/main/angular/src/app/api/series/series.service.ts index bf11c7c..82c4642 100644 --- a/src/main/angular/src/app/api/series/series.service.ts +++ b/src/main/angular/src/app/api/series/series.service.ts @@ -9,10 +9,47 @@ type Next = (t: T) => any; }) export class SeriesService { + public series: Series[] = []; + + public gridPurchased: Series | null = null; + + public gridDelivered: Series | null = null; + + public photovoltaicProduced: Series | null = null; + + public photovoltaicPower: Series | null = null; + + public gridPower: Series | null = null; + constructor( private readonly api: ApiService, ) { - // - + this.api.connected(() => { + this.findAll(list => { + this.series = list; + list.forEach(s => this.seriesUpdate(s)); + }); + }); + this.subscribe(series => this.seriesUpdate(series)); + } + + private seriesUpdate(series: Series) { + this.gridPurchased = this.seriesUpdate2(series, this.gridPurchased, 'electricity.grid.purchase.energy'); + this.gridDelivered = this.seriesUpdate2(series, this.gridDelivered, 'electricity.grid.delivery.energy'); + this.gridPower = this.seriesUpdate2(series, this.gridPower, 'electricity.grid.power'); + + this.photovoltaicProduced = this.seriesUpdate2(series, this.photovoltaicProduced, 'electricity.photovoltaic.energy'); + this.photovoltaicPower = this.seriesUpdate2(series, this.photovoltaicPower, 'electricity.photovoltaic.power'); + } + + private seriesUpdate2(fresh: Series, old: Series | null, name: string): Series | null { + if (fresh.name !== name) { + return old; + } + if (old === null || old.lastDate.getTime() <= fresh.lastDate.getTime()) { + return fresh; + } + return old; } subscribe(next: Next) { diff --git a/src/main/angular/src/app/pages/dashboard/dashboard.component.html b/src/main/angular/src/app/pages/dashboard/dashboard.component.html index 83bb6c5..ef105b4 100644 --- a/src/main/angular/src/app/pages/dashboard/dashboard.component.html +++ b/src/main/angular/src/app/pages/dashboard/dashboard.component.html @@ -1,3 +1,3 @@
- +
diff --git a/src/main/angular/src/app/pages/dashboard/dashboard.component.ts b/src/main/angular/src/app/pages/dashboard/dashboard.component.ts index 89dbd7f..59b1031 100644 --- a/src/main/angular/src/app/pages/dashboard/dashboard.component.ts +++ b/src/main/angular/src/app/pages/dashboard/dashboard.component.ts @@ -1,14 +1,8 @@ -import {Component, OnInit} from '@angular/core'; +import {Component} from '@angular/core'; import {JsonPipe, NgForOf} from "@angular/common"; -import {Series} from "../../api/series/Series"; -import {SeriesService} from "../../api/series/series.service"; import {ValuesTileComponent} from "../../shared/values-tile/values-tile.component"; -import {Value} from "../../api/series/Value"; -import {Display, DisplayOrSeparator} from "../../api/series/IValue"; - -const PURCHASING_MUCH = 200; - -const PRODUCED_UNTIL_METER_CHANGE = 287.995; +import {DashboardElectricityTileComponent} from "./electricity/dashboard-electricity-tile.component"; +import {DashboardAirTileComponent} from "./air/dashboard-air-tile.component"; @Component({ selector: 'app-dashboard', @@ -16,114 +10,13 @@ const PRODUCED_UNTIL_METER_CHANGE = 287.995; imports: [ NgForOf, ValuesTileComponent, - JsonPipe + JsonPipe, + DashboardElectricityTileComponent, + DashboardAirTileComponent, ], templateUrl: './dashboard.component.html', styleUrl: './dashboard.component.less' }) -export class DashboardComponent implements OnInit { - - protected gridPurchased: Series | null = null; - - protected gridDelivered: Series | null = null; - - protected photovoltaicProduced: Series | null = null; - - protected photovoltaicPower: Series | null = null; - - protected gridPower: Series | null = null; - - constructor( - readonly seriesService: SeriesService, - ) { - // - - } - - ngOnInit(): void { - this.seriesService.findAll(list => list.forEach(s => this.seriesUpdate(s))); - this.seriesService.subscribe(series => this.seriesUpdate(series)); - } - - private seriesUpdate(series: Series) { - this.gridPurchased = this.seriesUpdate2(series, this.gridPurchased, 'electricity.grid.purchase.energy'); - this.gridDelivered = this.seriesUpdate2(series, this.gridDelivered, 'electricity.grid.delivery.energy'); - this.gridPower = this.seriesUpdate2(series, this.gridPower, 'electricity.grid.power'); - - this.photovoltaicProduced = this.seriesUpdate2(series, this.photovoltaicProduced, 'electricity.photovoltaic.energy'); - this.photovoltaicPower = this.seriesUpdate2(series, this.photovoltaicPower, 'electricity.photovoltaic.power'); - } - - private seriesUpdate2(fresh: Series, old: Series | null, name: string): Series | null { - if (fresh.name !== name) { - return old; - } - if (old === null || old.lastDate.getTime() <= fresh.lastDate.getTime()) { - return fresh; - } - return old; - } - - getElectricitySeries(): DisplayOrSeparator[] { - const consumptionPower = Value.positiveOnly(Value.plus(this.photovoltaicPower, this.gridPower)); - const selfConsumed = Value.map(this.photovoltaicProduced, producedTotal => { - if (this.gridDelivered === null || this.gridDelivered.value === null) { - return null; - } - const producedAfterChange = producedTotal - PRODUCED_UNTIL_METER_CHANGE; - const deliveredAfterChange = this.gridDelivered?.value; - const selfAfterChange = producedAfterChange - deliveredAfterChange; - const selfRatio = selfAfterChange / producedAfterChange; - return selfRatio * producedTotal; - }); - - const gridColor = this.getGridPowerColor(); - const productionColor = this.getProductionPowerColor(); - return [ - new Display('Bezug', '', this.gridPurchased), - new Display('Einspeisung', '', this.gridDelivered), - null, - new Display('Produktion', '#006600', this.photovoltaicProduced), - new Display('Eigenverbrauch', '#006600', selfConsumed), - null, - new Display('Produktion', productionColor, this.photovoltaicPower), - new Display('Netz', gridColor, this.gridPower), - new Display('Verbrauch', '', consumptionPower), - ]; - } - - private getGridPowerColor(): string { - if (this.gridPower !== null && this.gridPower.value !== null) { - const deliveringAny = this.gridPower.value < 0; - if (deliveringAny) { - return 'magenta'; - } - - const purchasingMuch = this.gridPower.value > PURCHASING_MUCH; - if (purchasingMuch) { - return 'red'; - } - - const purchasingAny = this.gridPower.value > 0; - if (purchasingAny) { - return 'orange'; - } - - return 'green'; - } - return ''; - } - - private getProductionPowerColor() { - if (this.photovoltaicPower === null || this.photovoltaicPower.value === null) { - return ''; - } - - const producingAny = this.photovoltaicPower.value > 0; - if (producingAny) { - return 'green'; - } - - return 'black'; - } +export class DashboardComponent { } diff --git a/src/main/angular/src/app/pages/dashboard/electricity/dashboard-electricity-tile.component.html b/src/main/angular/src/app/pages/dashboard/electricity/dashboard-electricity-tile.component.html new file mode 100644 index 0000000..c9aea84 --- /dev/null +++ b/src/main/angular/src/app/pages/dashboard/electricity/dashboard-electricity-tile.component.html @@ -0,0 +1 @@ + diff --git a/src/main/angular/src/app/pages/dashboard/electricity/dashboard-electricity-tile.component.less b/src/main/angular/src/app/pages/dashboard/electricity/dashboard-electricity-tile.component.less new file mode 100644 index 0000000..e69de29 diff --git a/src/main/angular/src/app/pages/dashboard/electricity/dashboard-electricity-tile.component.ts b/src/main/angular/src/app/pages/dashboard/electricity/dashboard-electricity-tile.component.ts new file mode 100644 index 0000000..21d1ef9 --- /dev/null +++ b/src/main/angular/src/app/pages/dashboard/electricity/dashboard-electricity-tile.component.ts @@ -0,0 +1,91 @@ +import {Component} from '@angular/core'; +import {ValuesTileComponent} from "../../../shared/values-tile/values-tile.component"; +import {Display, DisplayOrSeparator} from "../../../api/series/IValue"; +import {Value} from "../../../api/series/Value"; +import {SeriesService} from "../../../api/series/series.service"; + +const PURCHASING_MUCH = 200; + +const PRODUCED_UNTIL_METER_CHANGE = 287.995; + +@Component({ + selector: 'app-dashboard-electricity-tile', + standalone: true, + imports: [ + ValuesTileComponent + ], + templateUrl: './dashboard-electricity-tile.component.html', + styleUrl: './dashboard-electricity-tile.component.less' +}) +export class DashboardElectricityTileComponent { + + constructor( + protected readonly seriesService: SeriesService, + ) { + // - + } + + getDisplayList(): DisplayOrSeparator[] { + const consumptionPower = Value.positiveOnly(Value.plus(this.seriesService.photovoltaicPower, this.seriesService.gridPower)); + const selfConsumed = Value.map(this.seriesService.photovoltaicProduced, producedTotal => { + if (this.seriesService.gridDelivered === null || this.seriesService.gridDelivered.value === null) { + return null; + } + const producedAfterChange = producedTotal - PRODUCED_UNTIL_METER_CHANGE; + const deliveredAfterChange = this.seriesService.gridDelivered?.value; + const selfAfterChange = producedAfterChange - deliveredAfterChange; + const selfRatio = selfAfterChange / producedAfterChange; + return selfRatio * producedTotal; + }); + + const gridColor = this.getGridPowerColor(); + const productionColor = this.getProductionPowerColor(); + return [ + new Display('Bezug', '', this.seriesService.gridPurchased), + new Display('Einspeisung', '', this.seriesService.gridDelivered), + null, + new Display('Produktion', '#006600', this.seriesService.photovoltaicProduced), + new Display('Eigenverbrauch', '#006600', selfConsumed), + null, + new Display('Produktion', productionColor, this.seriesService.photovoltaicPower), + new Display('Netz', gridColor, this.seriesService.gridPower), + new Display('Verbrauch', '', consumptionPower), + ]; + } + + private getGridPowerColor(): string { + if (this.seriesService.gridPower !== null && this.seriesService.gridPower.value !== null) { + const deliveringAny = this.seriesService.gridPower.value < 0; + if (deliveringAny) { + return 'magenta'; + } + + const purchasingMuch = this.seriesService.gridPower.value > PURCHASING_MUCH; + if (purchasingMuch) { + return 'red'; + } + + const purchasingAny = this.seriesService.gridPower.value > 0; + if (purchasingAny) { + return 'orange'; + } + + return 'green'; + } + return ''; + } + + private getProductionPowerColor() { + if (this.seriesService.photovoltaicPower === null || this.seriesService.photovoltaicPower.value === null) { + return ''; + } + + const producingAny = this.seriesService.photovoltaicPower.value > 0; + if (producingAny) { + return 'green'; + } + + return 'black'; + } + +} diff --git a/src/main/angular/src/app/shared/values-tile/values-tile.component.html b/src/main/angular/src/app/shared/values-tile/values-tile.component.html index 6253463..0b15e0c 100644 --- a/src/main/angular/src/app/shared/values-tile/values-tile.component.html +++ b/src/main/angular/src/app/shared/values-tile/values-tile.component.html @@ -5,7 +5,7 @@
{{ number() }}
- + diff --git a/src/main/angular/src/app/shared/values-tile/values-tile.component.ts b/src/main/angular/src/app/shared/values-tile/values-tile.component.ts index c65b0b8..1ecc515 100644 --- a/src/main/angular/src/app/shared/values-tile/values-tile.component.ts +++ b/src/main/angular/src/app/shared/values-tile/values-tile.component.ts @@ -34,16 +34,16 @@ export class ValuesTileComponent implements OnInit, OnDestroy { icon?: string; @Input() - protected seriesList_: DisplayOrSeparator[] = []; + protected displayList_: DisplayOrSeparator[] = []; @Input() - set seriesList(seriesList: DisplayOrSeparator[]) { - this.seriesList_ = seriesList; + set displayList(seriesList: DisplayOrSeparator[]) { + this.displayList_ = seriesList; this.displayUpdate(); } - get seriesList(): DisplayOrSeparator[] { - return this.seriesList_; + get displayList(): DisplayOrSeparator[] { + return this.displayList_; } @Input() @@ -103,7 +103,7 @@ export class ValuesTileComponent implements OnInit, OnDestroy { private displayUpdate() { this.now = new Date(); - this.valid = this.seriesList.some(d => !!d && !!d.iValue && !!d.iValue.date && (this.now.getTime() - d.iValue.date.getTime()) <= TOO_OLD_MILLIS) + this.valid = this.displayList.some(d => !!d && !!d.iValue && !!d.iValue.date && (this.now.getTime() - d.iValue.date.getTime()) <= TOO_OLD_MILLIS) } } diff --git a/src/main/angular/src/styles.less b/src/main/angular/src/styles.less index 546868e..92a3742 100644 --- a/src/main/angular/src/styles.less +++ b/src/main/angular/src/styles.less @@ -3,7 +3,7 @@ body { font-family: sans-serif; font-size: @font; - margin: 0; + margin: calc(@space / 2); overflow-x: hidden; } diff --git a/src/main/angular/src/widths.less b/src/main/angular/src/widths.less index 2dff9a5..6d4462f 100644 --- a/src/main/angular/src/widths.less +++ b/src/main/angular/src/widths.less @@ -3,13 +3,13 @@ .width100 { float: left; width: 100%; - padding: @space; + padding: calc(@space / 2); } .width50 { float: left; width: 50%; - padding: @space; + padding: calc(@space / 2); } .width50:nth-child(2n) {
{{ display.title }} {{ display?.iValue?.value | number:'0.0-0' }}