101 lines
3.0 KiB
TypeScript
101 lines
3.0 KiB
TypeScript
import {
|
|
ChangeDetectionStrategy,
|
|
Component,
|
|
computed,
|
|
inject,
|
|
OnInit,
|
|
signal,
|
|
} from '@angular/core';
|
|
import { ActivatedRoute } from '@angular/router';
|
|
import { LiveDataService } from '../../core/services/live-data.service';
|
|
import { PvHistoryData, PvHistoryEntry } from '../../core/models/pv-data.model';
|
|
import { LoadingSpinnerComponent, ErrorMessageComponent } from '../../shared';
|
|
import { DecimalPipe, DatePipe } from '@angular/common';
|
|
|
|
type Resolution = 'hour' | 'day' | 'month' | 'year';
|
|
|
|
@Component({
|
|
selector: 'app-plant-history',
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
imports: [LoadingSpinnerComponent, ErrorMessageComponent, DecimalPipe, DatePipe],
|
|
templateUrl: './plant-history.component.html',
|
|
styleUrl: './plant-history.component.scss',
|
|
})
|
|
export class PlantHistoryComponent implements OnInit {
|
|
private readonly route = inject(ActivatedRoute);
|
|
private readonly liveDataService = inject(LiveDataService);
|
|
|
|
readonly resolution = signal<Resolution>('day');
|
|
readonly historyData = signal<PvHistoryData | null>(null);
|
|
readonly loading = signal(false);
|
|
readonly error = signal<string | null>(null);
|
|
|
|
readonly resolutions: { value: Resolution; label: string }[] = [
|
|
{ value: 'hour', label: 'Stündlich' },
|
|
{ value: 'day', label: 'Täglich' },
|
|
{ value: 'month', label: 'Monatlich' },
|
|
{ value: 'year', label: 'Jährlich' },
|
|
];
|
|
|
|
readonly totalEnergy = computed(() =>
|
|
this.historyData()?.entries.reduce((sum, e) => sum + e.energyKwh, 0) ?? 0
|
|
);
|
|
|
|
readonly peakEntry = computed(() => {
|
|
const entries = this.historyData()?.entries ?? [];
|
|
if (!entries.length) return null;
|
|
return entries.reduce((max, e) => (e.peakPowerKw > max.peakPowerKw ? e : max));
|
|
});
|
|
|
|
readonly chartBarData = computed(() => {
|
|
const entries = this.historyData()?.entries ?? [];
|
|
if (!entries.length) return [];
|
|
const max = Math.max(...entries.map((e) => e.energyKwh));
|
|
return entries.map((e) => ({
|
|
...e,
|
|
barPercent: max > 0 ? (e.energyKwh / max) * 100 : 0,
|
|
}));
|
|
});
|
|
|
|
private plantId = '';
|
|
|
|
ngOnInit(): void {
|
|
// plantId kommt vom Parent-Route-Snapshot (plant-shell)
|
|
this.plantId =
|
|
this.route.parent?.snapshot.paramMap.get('id') ??
|
|
this.route.snapshot.paramMap.get('id') ??
|
|
'';
|
|
this.loadHistory();
|
|
}
|
|
|
|
loadHistory(): void {
|
|
if (!this.plantId) return;
|
|
this.loading.set(true);
|
|
this.error.set(null);
|
|
this.liveDataService.getHistory(this.plantId, this.resolution()).subscribe({
|
|
next: (data) => {
|
|
this.historyData.set(data);
|
|
this.loading.set(false);
|
|
},
|
|
error: () => {
|
|
this.error.set('Verlaufsdaten konnten nicht geladen werden.');
|
|
this.loading.set(false);
|
|
},
|
|
});
|
|
}
|
|
|
|
setResolution(res: Resolution): void {
|
|
this.resolution.set(res);
|
|
this.loadHistory();
|
|
}
|
|
|
|
dateFormat(resolution: Resolution): string {
|
|
switch (resolution) {
|
|
case 'hour': return 'dd.MM.yy HH:mm';
|
|
case 'day': return 'dd.MM.yyyy';
|
|
case 'month': return 'MMM yyyy';
|
|
case 'year': return 'yyyy';
|
|
}
|
|
}
|
|
}
|