114 lines
3.5 KiB
TypeScript
114 lines
3.5 KiB
TypeScript
import {Inject, Injectable, LOCALE_ID} from '@angular/core';
|
|
import {ApiService} from '../core/api.service';
|
|
import {Alignment} from './Alignment';
|
|
import {AggregationWrapperDto} from './AggregationWrapperDto';
|
|
import {Subscription} from 'rxjs';
|
|
import {Series} from './Series';
|
|
import {SeriesWrapper} from './SeriesWrapper';
|
|
import {Next} from '../core/types';
|
|
|
|
@Injectable({
|
|
providedIn: 'root'
|
|
})
|
|
export class SeriesService {
|
|
|
|
private readonly clientSubscriptions: Subscription[] = [];
|
|
|
|
private readonly subs: Subscription[] = [];
|
|
|
|
private readonly clientCallbacks: Next<Series>[] = [];
|
|
|
|
readonly powerConsumed: SeriesWrapper = new SeriesWrapper("power/consumed", this.onSubscribe, this.onUnsubscribe);
|
|
|
|
readonly powerProduced: SeriesWrapper = new SeriesWrapper("power/produced", this.onSubscribe, this.onUnsubscribe);
|
|
|
|
readonly powerSelf: SeriesWrapper = new SeriesWrapper("power/self", this.onSubscribe, this.onUnsubscribe);
|
|
|
|
readonly powerBalance: SeriesWrapper = new SeriesWrapper("power/balance", this.onSubscribe, this.onUnsubscribe);
|
|
|
|
readonly liveValues: SeriesWrapper[] = [
|
|
this.powerConsumed,
|
|
this.powerProduced,
|
|
this.powerSelf,
|
|
this.powerBalance,
|
|
]
|
|
|
|
constructor(
|
|
@Inject(LOCALE_ID) readonly locale: string,
|
|
protected readonly api: ApiService,
|
|
) {
|
|
//
|
|
}
|
|
|
|
private onSubscribe(subscription: Subscription): Subscription {
|
|
this.clientSubscriptions.push(subscription);
|
|
this.ensureApiSubscribed();
|
|
return subscription;
|
|
}
|
|
|
|
private onUnsubscribe(subscription: Subscription): Subscription {
|
|
this.clientSubscriptions.splice(this.clientSubscriptions.indexOf(subscription), 1);
|
|
if (this.clientSubscriptions.length === 0) {
|
|
this.ensureApiUnsubscribed();
|
|
}
|
|
return subscription;
|
|
}
|
|
|
|
private ensureApiSubscribed() {
|
|
if (this.subs.length !== 0) {
|
|
return;
|
|
}
|
|
this.subs.push(this.api.subscribe(['Series'], j => Series.fromJson(j, this.locale), series => this.update(series)));
|
|
this.subs.push(this.api.subscribeConnection(connected => {
|
|
if (connected) {
|
|
this.all();
|
|
} else {
|
|
this.liveValues.forEach(liveValue => liveValue.series = null);
|
|
}
|
|
}));
|
|
}
|
|
|
|
private ensureApiUnsubscribed() {
|
|
if (this.subs.length <= 0) {
|
|
return;
|
|
}
|
|
this.subs.forEach(sub => sub.unsubscribe());
|
|
this.subs.length = 0;
|
|
}
|
|
|
|
private update(series: Series) {
|
|
this.liveValues
|
|
.filter(liveValue => liveValue.name === series.name)
|
|
.forEach(liveValue => liveValue.series = series);
|
|
this.clientCallbacks.forEach(next => next(series));
|
|
}
|
|
|
|
subscribeAny(next?: Next<Series>): Subscription {
|
|
const wrapper: Next<Series> = series => { // to let clientCallbacks only contain unique instances
|
|
if (next) {
|
|
next(series);
|
|
}
|
|
};
|
|
this.clientCallbacks.push(wrapper);
|
|
const subscription = new Subscription(() => {
|
|
this.onUnsubscribe(subscription);
|
|
this.clientCallbacks.splice(this.clientCallbacks.indexOf(wrapper), 1);
|
|
});
|
|
return this.onSubscribe(subscription);
|
|
}
|
|
|
|
all(next?: Next<Series[]>) {
|
|
this.api.getList(['Series', 'all'], j => Series.fromJson(j, this.locale), list => {
|
|
list.forEach(item => this.update(item));
|
|
if (next) {
|
|
next(list);
|
|
}
|
|
});
|
|
}
|
|
|
|
aggregations(alignment: Alignment, offset: number, next: Next<AggregationWrapperDto>) {
|
|
this.api.getSingle(['Series', 'agg', 'all', alignment.name, 'offset', offset], j => AggregationWrapperDto.fromJson(j, this.locale), next);
|
|
}
|
|
|
|
}
|