Files
pv-pulse-angular-app/src/app/features/plant-history/plant-history.component.ts

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';
}
}
}