refactored big AppComponent into Dashboard and parts
This commit is contained in:
parent
9d12986720
commit
2882184a82
@ -25,3 +25,27 @@
|
|||||||
@productionBack: #2d4255;
|
@productionBack: #2d4255;
|
||||||
@selfBack: #2b4e2b;
|
@selfBack: #2b4e2b;
|
||||||
@deliveryBack: #753475;
|
@deliveryBack: #753475;
|
||||||
|
|
||||||
|
.consumption {
|
||||||
|
color: @consumption;
|
||||||
|
}
|
||||||
|
|
||||||
|
.purchase {
|
||||||
|
color: @purchase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.production {
|
||||||
|
color: @production;
|
||||||
|
}
|
||||||
|
|
||||||
|
.self {
|
||||||
|
color: @self;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delivery {
|
||||||
|
color: @delivery;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zero {
|
||||||
|
filter: opacity(20%);
|
||||||
|
}
|
||||||
50
src/main/angular/numberTable.less
Normal file
50
src/main/angular/numberTable.less
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
@import "./colors.less";
|
||||||
|
|
||||||
|
.numberTable {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
|
||||||
|
.arrowLeft {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrowRight {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
clear: left;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option {
|
||||||
|
clear: left;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
|
||||||
|
.entry {
|
||||||
|
clear: left;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.percent {
|
||||||
|
float: right;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
font-size: 60%;
|
||||||
|
width: 4.5em;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,89 +1 @@
|
|||||||
<div class="section">
|
|
||||||
|
|
||||||
<div class="title">
|
|
||||||
Leistung
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
<div class="entry consumption" [class.zero]="powerConsumption?.zero">
|
|
||||||
<div class="name">Bedarf</div>
|
|
||||||
<div class="percent"> </div>
|
|
||||||
<div class="value">{{ powerConsumption?.formatted }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="entry purchase" [class.zero]="powerPurchase?.zero">
|
|
||||||
<div class="name">Bezug</div>
|
|
||||||
<div class="percent">{{ powerPurchasePercent?.formatted }}</div>
|
|
||||||
<div class="value">{{ powerPurchase?.formatted }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="entry production" [class.zero]="powerProduction?.zero">
|
|
||||||
<div class="name">Produktion</div>
|
|
||||||
<div class="percent">{{ powerProducedPercent?.formatted }}</div>
|
|
||||||
<div class="value">{{ powerProduction?.formatted }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="entry self" [class.zero]="powerSelf?.zero">
|
|
||||||
<div class="name">Eigenbedarf</div>
|
|
||||||
<div class="percent">{{ powerSelfPercent?.formatted }}</div>
|
|
||||||
<div class="value">{{ powerSelf?.formatted }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="entry delivery" [class.zero]="powerDelivery?.zero">
|
|
||||||
<div class="name">Einspeisung</div>
|
|
||||||
<div class="percent">{{ powerDeliveryPercent?.formatted }}</div>
|
|
||||||
<div class="value">{{ powerDelivery?.formatted }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<app-percent-bar [produktion]="powerProduction" [self]="powerSelf" [purchase]="powerPurchase" [delivery]="powerDelivery"></app-percent-bar>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section">
|
|
||||||
|
|
||||||
<div class="title">
|
|
||||||
Energie
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="option">
|
|
||||||
<button class="back" (click)="shiftAlignment(+1)">←</button>
|
|
||||||
{{ alignment.display }} {{ offset > 0 ? -offset : '' }}
|
|
||||||
<button class="next" (click)="shiftAlignment(-1)">→</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="option">
|
|
||||||
<button class="back" (click)="shiftOffset(+1)">←</button>
|
|
||||||
{{ alignment.offsetTitle(offset, locale) }}
|
|
||||||
<button class="next" (click)="shiftOffset(-1)" [disabled]="offset === 0">→</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
<div class="entry consumption" [class.zero]="aggregations.energyConsumed?.zero">
|
|
||||||
<div class="name">Bedarf</div>
|
|
||||||
<div class="percent"> </div>
|
|
||||||
<div class="value">{{ aggregations.energyConsumed?.formatted }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="entry purchase" [class.zero]="aggregations.energyPurchased?.delta?.zero">
|
|
||||||
<div class="name">Bezug</div>
|
|
||||||
<div class="percent">{{ aggregations.energyPurchasedPercent?.formatted }}</div>
|
|
||||||
<div class="value">{{ aggregations.energyPurchased?.delta?.formatted }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="entry production" [class.zero]="aggregations.energyProduced?.delta?.zero">
|
|
||||||
<div class="name">Produktion</div>
|
|
||||||
<div class="percent">{{ aggregations.energyProducedPercent?.formatted }}</div>
|
|
||||||
<div class="value">{{ aggregations.energyProduced?.delta?.formatted }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="entry self" [class.zero]="aggregations.energySelf?.zero">
|
|
||||||
<div class="name">Eigenbedarf</div>
|
|
||||||
<div class="percent">{{ aggregations.energySelfPercent?.formatted }}</div>
|
|
||||||
<div class="value">{{ aggregations.energySelf?.formatted }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="entry delivery" [class.zero]="aggregations.energyDelivered?.delta?.zero">
|
|
||||||
<div class="name">Einspeisung</div>
|
|
||||||
<div class="percent">{{ aggregations.energyDeliveredPercent?.formatted }}</div>
|
|
||||||
<div class="value">{{ aggregations.energyDelivered?.delta?.formatted }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<app-percent-bar [produktion]="aggregations.energyProduced?.delta" [self]="aggregations.energySelf" [purchase]="aggregations.energyPurchased?.delta" [delivery]="aggregations.energyDelivered?.delta"></app-percent-bar>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<router-outlet/>
|
<router-outlet/>
|
||||||
|
|||||||
@ -1,86 +0,0 @@
|
|||||||
@import "../../config.less";
|
|
||||||
|
|
||||||
.section {
|
|
||||||
margin-bottom: 2em;
|
|
||||||
|
|
||||||
.back {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
clear: left;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option {
|
|
||||||
clear: left;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
|
|
||||||
.entry {
|
|
||||||
clear: left;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.percent {
|
|
||||||
float: right;
|
|
||||||
padding-top: 0.5em;
|
|
||||||
font-size: 60%;
|
|
||||||
width: 4.5em;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.live {
|
|
||||||
font-size: 40%;
|
|
||||||
color: green;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.archive {
|
|
||||||
font-size: 40%;
|
|
||||||
color: darkred;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.consumption {
|
|
||||||
color: @consumption;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purchase {
|
|
||||||
color: @purchase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.production {
|
|
||||||
color: @production;
|
|
||||||
}
|
|
||||||
|
|
||||||
.self {
|
|
||||||
color: @self;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delivery {
|
|
||||||
color: @delivery;
|
|
||||||
}
|
|
||||||
|
|
||||||
.zero {
|
|
||||||
filter: opacity(20%);
|
|
||||||
}
|
|
||||||
@ -1,113 +1,12 @@
|
|||||||
import {Component, Inject, LOCALE_ID, OnDestroy, OnInit} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {RouterOutlet} from '@angular/router';
|
import {RouterOutlet} from '@angular/router';
|
||||||
import {Alignment} from './series/Alignment';
|
|
||||||
import {AggregationWrapperDto} from './series/AggregationWrapperDto';
|
|
||||||
import {SeriesService} from './series/series.service';
|
|
||||||
import {Subscription} from 'rxjs';
|
|
||||||
import {Value} from './value/Value';
|
|
||||||
import {PercentBarComponent} from './percent-bar/percent-bar.component';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
imports: [RouterOutlet, PercentBarComponent],
|
imports: [RouterOutlet],
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrl: './app.component.less'
|
styleUrl: './app.component.less'
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit, OnDestroy {
|
export class AppComponent {
|
||||||
|
|
||||||
protected aggregations: AggregationWrapperDto = AggregationWrapperDto.EMPTY;
|
|
||||||
|
|
||||||
protected alignment: Alignment = Alignment.DAY;
|
|
||||||
|
|
||||||
protected offset: number = 0;
|
|
||||||
|
|
||||||
protected interval: any;
|
|
||||||
|
|
||||||
private readonly subs: Subscription[] = [];
|
|
||||||
|
|
||||||
get powerProduction(): Value | undefined {
|
|
||||||
return this.seriesService.powerProduced.series?.lastValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
get powerBalance(): Value | undefined {
|
|
||||||
return this.seriesService.powerBalance.series?.lastValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
get powerPurchase(): Value | undefined {
|
|
||||||
return this.powerBalance?.notNegative();
|
|
||||||
}
|
|
||||||
|
|
||||||
get powerDelivery(): Value | undefined {
|
|
||||||
return this.powerBalance?.negate()?.notNegative();
|
|
||||||
}
|
|
||||||
|
|
||||||
get powerSelf(): Value | undefined {
|
|
||||||
return this.powerProduction?.minus(this.powerDelivery)?.notNegative();
|
|
||||||
}
|
|
||||||
|
|
||||||
get powerConsumption(): Value | undefined {
|
|
||||||
return this.powerPurchase?.plus(this.powerProduction)?.minus(this.powerDelivery);
|
|
||||||
}
|
|
||||||
|
|
||||||
get powerProducedPercent(): Value | undefined {
|
|
||||||
return this.powerProduction?.percent(this.powerConsumption);
|
|
||||||
}
|
|
||||||
|
|
||||||
get powerSelfPercent(): Value | undefined {
|
|
||||||
return this.powerSelf?.percent(this.powerProduction);
|
|
||||||
}
|
|
||||||
|
|
||||||
get powerPurchasePercent(): Value | undefined {
|
|
||||||
return this.powerPurchase?.percent(this.powerConsumption);
|
|
||||||
}
|
|
||||||
|
|
||||||
get powerDeliveryPercent(): Value | undefined {
|
|
||||||
return this.powerDelivery?.percent(this.powerProduction);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@Inject(LOCALE_ID) public locale: string,
|
|
||||||
protected readonly seriesService: SeriesService,
|
|
||||||
) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.fetch();
|
|
||||||
this.subs.push(this.seriesService.subscribeAny());
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
this.intervalStop();
|
|
||||||
this.subs.forEach(sub => sub.unsubscribe());
|
|
||||||
}
|
|
||||||
|
|
||||||
shiftOffset(delta: number) {
|
|
||||||
this.offset = Math.max(0, this.offset + delta);
|
|
||||||
this.fetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
shiftAlignment(delta: number) {
|
|
||||||
this.alignment = this.alignment.plus(delta)
|
|
||||||
this.fetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
private fetch() {
|
|
||||||
if (this.offset === 0) {
|
|
||||||
if (!this.interval) {
|
|
||||||
this.interval = setInterval(() => this.fetch(), 5000);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.intervalStop();
|
|
||||||
}
|
|
||||||
this.seriesService.aggregations(this.alignment, this.offset, aggregations => this.aggregations = aggregations);
|
|
||||||
}
|
|
||||||
|
|
||||||
private intervalStop() {
|
|
||||||
if (this.interval) {
|
|
||||||
clearInterval(this.interval);
|
|
||||||
this.interval = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
import {Routes} from '@angular/router';
|
import {Routes} from '@angular/router';
|
||||||
|
import {DashboardComponent} from './dashboard/dashboard.component';
|
||||||
|
|
||||||
export const routes: Routes = [];
|
export const routes: Routes = [
|
||||||
|
{path: 'Dashboard', component: DashboardComponent},
|
||||||
|
{path: '**', redirectTo: 'Dashboard'},
|
||||||
|
];
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import {map, Subscription} from 'rxjs';
|
|||||||
import {StompService} from '@stomp/ng2-stompjs';
|
import {StompService} from '@stomp/ng2-stompjs';
|
||||||
import {FromJson, Next} from './types';
|
import {FromJson, Next} from './types';
|
||||||
|
|
||||||
const DEV_TO_PROD = false;
|
const DEV_TO_PROD = true;
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
<app-electro-power></app-electro-power>
|
||||||
|
|
||||||
|
<app-electro-energy></app-electro-energy>
|
||||||
16
src/main/angular/src/app/dashboard/dashboard.component.ts
Normal file
16
src/main/angular/src/app/dashboard/dashboard.component.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import {ElectroEnergyComponent} from "../electro/energy/electro-energy.component";
|
||||||
|
import {ElectroPowerComponent} from "../electro/power/electro-power.component";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-dashboard',
|
||||||
|
imports: [
|
||||||
|
ElectroEnergyComponent,
|
||||||
|
ElectroPowerComponent
|
||||||
|
],
|
||||||
|
templateUrl: './dashboard.component.html',
|
||||||
|
styleUrl: './dashboard.component.less'
|
||||||
|
})
|
||||||
|
export class DashboardComponent {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
<div class="numberTable">
|
||||||
|
|
||||||
|
<div class="title">
|
||||||
|
Energie
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option">
|
||||||
|
<button class="arrowLeft" (click)="shiftAlignment(+1)">←</button>
|
||||||
|
{{ alignment.display }} {{ offset > 0 ? -offset : '' }}
|
||||||
|
<button class="arrowRight" (click)="shiftAlignment(-1)">→</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option">
|
||||||
|
<button class="arrowLeft" (click)="shiftOffset(+1)">←</button>
|
||||||
|
{{ alignment.offsetTitle(offset, locale) }}
|
||||||
|
<button class="arrowRight" (click)="shiftOffset(-1)" [disabled]="offset === 0">→</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<div class="entry consumption" [class.zero]="aggregations.energyConsumed?.zero">
|
||||||
|
<div class="name">Bedarf</div>
|
||||||
|
<div class="percent"> </div>
|
||||||
|
<div class="value">{{ aggregations.energyConsumed?.formatted }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="entry purchase" [class.zero]="aggregations.energyPurchased?.delta?.zero">
|
||||||
|
<div class="name">Bezug</div>
|
||||||
|
<div class="percent">{{ aggregations.energyPurchasedPercent?.formatted }}</div>
|
||||||
|
<div class="value">{{ aggregations.energyPurchased?.delta?.formatted }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="entry production" [class.zero]="aggregations.energyProduced?.delta?.zero">
|
||||||
|
<div class="name">Produktion</div>
|
||||||
|
<div class="percent">{{ aggregations.energyProducedPercent?.formatted }}</div>
|
||||||
|
<div class="value">{{ aggregations.energyProduced?.delta?.formatted }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="entry self" [class.zero]="aggregations.energySelf?.zero">
|
||||||
|
<div class="name">Eigenbedarf</div>
|
||||||
|
<div class="percent">{{ aggregations.energySelfPercent?.formatted }}</div>
|
||||||
|
<div class="value">{{ aggregations.energySelf?.formatted }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="entry delivery" [class.zero]="aggregations.energyDelivered?.delta?.zero">
|
||||||
|
<div class="name">Einspeisung</div>
|
||||||
|
<div class="percent">{{ aggregations.energyDeliveredPercent?.formatted }}</div>
|
||||||
|
<div class="value">{{ aggregations.energyDelivered?.delta?.formatted }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<app-percent-bar [produktion]="aggregations.energyProduced?.delta" [self]="aggregations.energySelf" [purchase]="aggregations.energyPurchased?.delta" [delivery]="aggregations.energyDelivered?.delta"></app-percent-bar>
|
||||||
|
|
||||||
|
</div>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
@import "../../../../colors.less";
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
import {Component, Inject, LOCALE_ID, OnDestroy, OnInit} from '@angular/core';
|
||||||
|
import {PercentBarComponent} from '../../shared/percent-bar/percent-bar.component';
|
||||||
|
import {AggregationWrapperDto} from '../../series/AggregationWrapperDto';
|
||||||
|
import {Alignment} from '../../series/Alignment';
|
||||||
|
import {Subscription} from 'rxjs';
|
||||||
|
import {SeriesService} from '../../series/series.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-electro-energy',
|
||||||
|
imports: [
|
||||||
|
PercentBarComponent
|
||||||
|
],
|
||||||
|
templateUrl: './electro-energy.component.html',
|
||||||
|
styleUrl: './electro-energy.component.less'
|
||||||
|
})
|
||||||
|
export class ElectroEnergyComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
protected aggregations: AggregationWrapperDto = AggregationWrapperDto.EMPTY;
|
||||||
|
|
||||||
|
protected alignment: Alignment = Alignment.DAY;
|
||||||
|
|
||||||
|
protected offset: number = 0;
|
||||||
|
|
||||||
|
protected interval: any;
|
||||||
|
|
||||||
|
private readonly subs: Subscription[] = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject(LOCALE_ID) public locale: string,
|
||||||
|
protected readonly seriesService: SeriesService,
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.fetch();
|
||||||
|
this.subs.push(this.seriesService.subscribeAny());
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.intervalStop();
|
||||||
|
this.subs.forEach(sub => sub.unsubscribe());
|
||||||
|
}
|
||||||
|
|
||||||
|
shiftOffset(delta: number) {
|
||||||
|
this.offset = Math.max(0, this.offset + delta);
|
||||||
|
this.fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
shiftAlignment(delta: number) {
|
||||||
|
this.alignment = this.alignment.plus(delta)
|
||||||
|
this.fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private fetch() {
|
||||||
|
if (this.offset === 0) {
|
||||||
|
if (!this.interval) {
|
||||||
|
this.interval = setInterval(() => this.fetch(), 5000);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.intervalStop();
|
||||||
|
}
|
||||||
|
this.seriesService.aggregations(this.alignment, this.offset, aggregations => this.aggregations = aggregations);
|
||||||
|
}
|
||||||
|
|
||||||
|
private intervalStop() {
|
||||||
|
if (this.interval) {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
this.interval = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
<div class="numberTable">
|
||||||
|
|
||||||
|
<div class="title">
|
||||||
|
Leistung
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<div class="entry consumption" [class.zero]="powerConsumption?.zero">
|
||||||
|
<div class="name">Bedarf</div>
|
||||||
|
<div class="percent"> </div>
|
||||||
|
<div class="value">{{ powerConsumption?.formatted }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="entry purchase" [class.zero]="powerPurchase?.zero">
|
||||||
|
<div class="name">Bezug</div>
|
||||||
|
<div class="percent">{{ powerPurchasePercent?.formatted }}</div>
|
||||||
|
<div class="value">{{ powerPurchase?.formatted }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="entry production" [class.zero]="powerProduction?.zero">
|
||||||
|
<div class="name">Produktion</div>
|
||||||
|
<div class="percent">{{ powerProducedPercent?.formatted }}</div>
|
||||||
|
<div class="value">{{ powerProduction?.formatted }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="entry self" [class.zero]="powerSelf?.zero">
|
||||||
|
<div class="name">Eigenbedarf</div>
|
||||||
|
<div class="percent">{{ powerSelfPercent?.formatted }}</div>
|
||||||
|
<div class="value">{{ powerSelf?.formatted }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="entry delivery" [class.zero]="powerDelivery?.zero">
|
||||||
|
<div class="name">Einspeisung</div>
|
||||||
|
<div class="percent">{{ powerDeliveryPercent?.formatted }}</div>
|
||||||
|
<div class="value">{{ powerDelivery?.formatted }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<app-percent-bar [produktion]="powerProduction" [self]="powerSelf" [purchase]="powerPurchase" [delivery]="powerDelivery"></app-percent-bar>
|
||||||
|
|
||||||
|
</div>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
@import "../../../../colors.less";
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
import {Component} from '@angular/core';
|
||||||
|
import {PercentBarComponent} from "../../shared/percent-bar/percent-bar.component";
|
||||||
|
import {Value} from '../../value/Value';
|
||||||
|
import {SeriesService} from '../../series/series.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-electro-power',
|
||||||
|
imports: [
|
||||||
|
PercentBarComponent
|
||||||
|
],
|
||||||
|
templateUrl: './electro-power.component.html',
|
||||||
|
styleUrl: './electro-power.component.less'
|
||||||
|
})
|
||||||
|
export class ElectroPowerComponent {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
readonly seriesService: SeriesService,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
get powerProduction(): Value | undefined {
|
||||||
|
return this.seriesService.powerProduced.series?.lastValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
get powerBalance(): Value | undefined {
|
||||||
|
return this.seriesService.powerBalance.series?.lastValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
get powerPurchase(): Value | undefined {
|
||||||
|
return this.powerBalance?.notNegative();
|
||||||
|
}
|
||||||
|
|
||||||
|
get powerDelivery(): Value | undefined {
|
||||||
|
return this.powerBalance?.negate()?.notNegative();
|
||||||
|
}
|
||||||
|
|
||||||
|
get powerSelf(): Value | undefined {
|
||||||
|
return this.powerProduction?.minus(this.powerDelivery)?.notNegative();
|
||||||
|
}
|
||||||
|
|
||||||
|
get powerConsumption(): Value | undefined {
|
||||||
|
return this.powerPurchase?.plus(this.powerProduction)?.minus(this.powerDelivery);
|
||||||
|
}
|
||||||
|
|
||||||
|
get powerProducedPercent(): Value | undefined {
|
||||||
|
return this.powerProduction?.percent(this.powerConsumption);
|
||||||
|
}
|
||||||
|
|
||||||
|
get powerSelfPercent(): Value | undefined {
|
||||||
|
return this.powerSelf?.percent(this.powerProduction);
|
||||||
|
}
|
||||||
|
|
||||||
|
get powerPurchasePercent(): Value | undefined {
|
||||||
|
return this.powerPurchase?.percent(this.powerConsumption);
|
||||||
|
}
|
||||||
|
|
||||||
|
get powerDeliveryPercent(): Value | undefined {
|
||||||
|
return this.powerDelivery?.percent(this.powerProduction);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
@import "../../../config.less";
|
@import "../../../../colors.less";
|
||||||
|
|
||||||
.bar {
|
.bar {
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import {Component, Input} from '@angular/core';
|
import {Component, Input} from '@angular/core';
|
||||||
import {Value} from '../value/Value';
|
import {Value} from '../../value/Value';
|
||||||
import {NgIf} from '@angular/common';
|
import {NgIf} from '@angular/common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -1,4 +1,5 @@
|
|||||||
@import "../config.less";
|
@import "../colors.less";
|
||||||
|
@import "../numberTable.less";
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user