refactor seriesService to cache series
This commit is contained in:
parent
08e3d71344
commit
740c4bbc95
15
src/main/angular/public/air.svg
Normal file
15
src/main/angular/public/air.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M844.936791 428.018878c0-183.933831-149.679748-333.678084-333.68218-333.678084-183.99936 0-333.743613 149.745277-333.743612 333.678084 0 89.15891 34.702545 172.945494 97.78412 236.023997 47.997696 47.997696 108.040379 79.411522 173.295663 91.744221-9.748412 70.1771-67.329675 119.643048-108.553346 124.022205-12.974675 1.34129-22.562337 12.654199-21.920361 25.690307 0.703409 13.040203 11.502328 23.265746 24.541507 23.265746h337.196154c13.037132 0 23.838098-10.225543 24.541508-23.265746 0.637881-13.037132-8.949782-24.349017-21.924457-25.690307-41.220599-4.378134-98.805958-53.845105-108.550274-124.022205 65.219447-12.332699 125.327659-43.776217 173.295663-91.744221 63.013998-63.078503 97.719615-146.864063 97.719615-236.023997z" fill="#27323A"/>
|
||||
<path d="M587.435775 879.68234H435.073448c31.187547-30.294719 55.85704-71.293135 62.601372-118.586399 4.538884 0.189419 9.012239 0.670645 13.579791 0.670645 4.571648 0 9.045003-0.481226 13.582863-0.670645 6.741261 47.293263 31.410754 88.291679 62.598301 118.586399zM511.254611 712.682548c-76.053178 0-147.507063-29.59131-201.256947-83.341194-53.746812-53.812341-83.402627-125.265202-83.402627-201.322476 0-156.901211 127.692834-284.594045 284.659574-284.594046 156.901211 0 284.598141 127.692834 284.598141 284.594046 0 76.057274-29.59131 147.510135-83.341193 201.322476-53.749884 53.749884-125.265202 83.341194-201.256948 83.341194z" fill="#F4CE73"/>
|
||||
<path
|
||||
d="M651.029293 354.841794c-24.989969-3.259027-62.025949 11.217688-87.398852 26.204297-1.020814-1.119107-1.917737-2.366199-3.004079-3.419777 7.44467-9.777081 20.611835-19.714912 33.58651-29.43056 26.714192-19.941191 57.008911-42.500456 57.008911-77.395492 0-33.108356-15.916297-62.37919-44.865631-82.32038-41.800118-28.822372-104.431184-35.085478-155.880397-15.592749-65.955621 25.114883-95.867407 96.056826-69.66311 165.016526 9.29995 24.574272 39.912074 49.979938 64.647096 64.839586-0.798631 2.044699-1.374054 4.185643-1.983266 6.325563-12.238501-1.403747-27.673573-7.860368-42.850625-14.345657-30.615195-13.101637-65.31774-27.994049-95.484474-10.546019-28.697458 16.554178-46.079959 44.993617-48.829091 80.016638-4.024893 50.618843 21.920361 107.945158 64.551874 142.650775 54.705169 44.545155 131.145376 34.957493 177.736254-22.241861 16.427216-20.196138 23.039468-58.638936 23.550386-86.983153 3.259027-0.510919 6.391092-1.308525 9.492441-2.267906 4.793831 11.152159 7.222487 27.064361 9.522133 42.660182 4.98325 32.977299 10.608476 70.366519 41.351657 86.855168 29.26981 15.657254 62.568608 15.402307 93.818612-0.703409 45.187131-23.265746 80.209129-75.480826 87.241173-129.996577 9.07572-69.97949-39.30491-129.864495-112.547522-139.325195z"
|
||||
fill="#27323A"/>
|
||||
<path d="M511.254611 390.119763c14.636441 0 26.970163 8.566849 33.298799 20.710128 0.448462 0.861088 0.670645 1.819444 1.279857 2.618075 0.156654 0.193514 0.382933 0.287712 0.543683 0.481226 1.756987 4.378134 2.84333 9.106436 2.843329 14.09071 0 20.965076-17.00264 37.964644-37.964644 37.964644s-37.961572-16.999568-37.961572-37.964644c-0.001024-20.897499 16.998544-37.900139 37.960548-37.900139z" fill="#FFFFFF"/>
|
||||
<path
|
||||
d="M411.424768 326.275393c-19.938119-52.343066 1.345385-104.048251 50.684372-122.83757 41.158142-15.595821 92.863327-10.674005 125.713664 11.949766 13.995489 9.715648 30.677652 27.162654 30.677652 55.412673 0 18.468843-22.30739 35.085478-43.844817 51.191195-15.880461 11.855568-32.051706 24.12581-42.306942 38.985458-6.711568-2.107156-13.710848-3.579503-21.093062-3.579504-18.212872 0-34.702545 7.127266-47.228758 18.471916-21.666437-12.685939-46.976883-34.640088-52.602109-49.593934zM473.227511 563.959109c-35.405955 43.396356-90.818628 50.811333-131.721824 17.513558-34.126098-27.801558-55.730078-74.96786-52.598013-114.722255 1.34129-16.934039 8.115315-40.134257 32.59539-54.322236 15.978754-9.204729 41.541075 1.724223 66.276097 12.332699 17.990689 7.735454 36.42984 15.595821 54.195274 17.163389 5.019086 25.147647 23.553458 45.2158 47.581999 53.013711-0.062457 24.76369-6.197578 56.527685-16.328923 69.021134zM731.11146 489.949606c-5.562769 43.652327-34.257155 86.855168-69.728639 105.134593-15.147359 7.797911-38.475563 14.315965-63.400003 0.958356-16.296159-8.756267-20.451085-36.237349-24.414546-62.889084-2.876094-18.978738-5.814645-38.442798-13.484569-54.228039 13.423137-12.876382 21.858928-30.867071 21.858927-50.906554 0-6.358328-1.119107-12.398227-2.716367-18.275329 21.377702-12.879454 51.960132-24.480074 67.584622-22.434352 55.667621 7.16003 91.073576 50.362871 84.300575 102.640409z"
|
||||
fill="#79CCBF"/>
|
||||
<path
|
||||
d="M466.516966 255.843346c14.126546-13.612555 30.549666-14.187979 36.940759-13.740542 9.012239 0.575424 16.809125-6.263107 17.385573-15.336778 0.575424-9.012239-6.263107-16.747692-15.33985-17.320044-10.736462-0.703409-38.21652 0.189419-61.737214 22.879742-23.262675 22.43128-25.435359 49.273457-25.307373 59.8205 0.127986 9.012239 7.542963 16.233702 16.616635 16.105716 9.012239-0.127986 16.233702-7.542963 16.105716-16.554178-0.067576-6.263107 1.274737-22.241861 15.335754-35.854416zM431.431488 538.71624c-4.665845 4.218408-17.513558 13.867503-36.940759 12.398227-19.558257-1.472347-30.935671-13.423137-34.960564-18.471915-5.559697-7.094501-15.850769-8.307806-22.945271-2.749132-7.094501 5.625226-8.307806 15.916297-2.749132 23.010799 14.061017 17.830963 35.281041 29.142848 58.160782 30.867071 32.146928 2.427632 53.684355-13.80607 61.482266-20.834019 6.64604-6.135121 7.155935-16.488649 1.086343-23.134689-6.134097-6.711568-16.487625-7.159006-23.133665-1.086342zM668.92476 405.587598c-8.373334-3.513974-17.957925 0.448462-21.475994 8.756267-3.513974 8.307806 0.448462 17.957925 8.756267 21.410467 5.752188 2.427632 19.941191 10.098581 26.779721 28.376981 6.83853 18.406386 0.765866 33.681732-2.172685 39.368391-4.155951 8.052858-0.958357 17.895468 7.094501 22.048347 7.987329 4.155951 17.892396 0.958357 21.982818-7.094502 4.921817-9.522134 15.147359-35.085478 3.773018-65.762106-11.310861-30.231238-35.087526-43.013422-44.737646-47.103845z"
|
||||
fill="#27323A"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
@ -9,10 +9,47 @@ type Next<T> = (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<Series>) {
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
<div class="width100">
|
||||
<app-values-tile title="Elektrizität" icon="electricity.svg" [seriesList]="getElectricitySeries()"></app-values-tile>
|
||||
<app-dashboard-electricity-tile></app-dashboard-electricity-tile>
|
||||
</div>
|
||||
|
||||
@ -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 {
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1 @@
|
||||
<app-values-tile title="Elektrizität" icon="electricity.svg" [displayList]="getDisplayList()"></app-values-tile>
|
||||
@ -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';
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
</div>
|
||||
<div class="number">{{ number() }}</div>
|
||||
<table class="values">
|
||||
<ng-container *ngFor="let display of seriesList">
|
||||
<ng-container *ngFor="let display of displayList">
|
||||
<tr class="rate" *ngIf="display" [style.color]="display.color">
|
||||
<th>{{ display.title }}</th>
|
||||
<td class="v">{{ display?.iValue?.value | number:'0.0-0' }}</td>
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: @font;
|
||||
margin: 0;
|
||||
margin: calc(@space / 2);
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user