Updated site to use new BMS data
This commit is contained in:
parent
0f07821317
commit
5c4bb8b515
@ -1,25 +1,20 @@
|
||||
<div class="fill-height p-3" style="background-color: #b52e3c !important;">
|
||||
<div class="fill-height p-3" style="background-color: #b52e3c !important; overflow-y: scroll">
|
||||
<div style="max-width: 1000px;">
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between">
|
||||
<div class="mb-3">
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between align-items-end mb-2">
|
||||
<div>
|
||||
<h1 class="mb-0">Powerwall: {{batteryService.charge | number : '1.1-1'}} V</h1>
|
||||
<h6>Last Updated At: {{batteryService.lastUpdate | date: 'short'}}</h6>
|
||||
<h6 class="mb-0">Uptime: {{batteryService.uptime}}</h6>
|
||||
</div>
|
||||
<div class="d-flex flex-column align-content-center mb-3">
|
||||
<div>
|
||||
<h5><mat-icon *ngIf="locked" class="mr-1">lock</mat-icon>Cooling Fans</h5>
|
||||
</div>
|
||||
<div>
|
||||
<mat-button-toggle-group class="mb-3" [ngModel]="batteryService.relayMode"
|
||||
(change)="batteryService.setRelayMode($event.value)" [disabled]="locked">
|
||||
<mat-button-toggle value="null">Auto</mat-button-toggle>
|
||||
<mat-button-toggle value="true">On</mat-button-toggle>
|
||||
<mat-button-toggle value="false">Off</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
<div>
|
||||
<mat-button-toggle-group>
|
||||
<mat-button-toggle value="24" [checked]="true">24 Hours</mat-button-toggle>
|
||||
<mat-button-toggle value="12">12 Hours</mat-button-toggle>
|
||||
<mat-button-toggle value="6">6 Hours</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
</div>
|
||||
<mat-card class="mt-2" *ngFor="let battery of batteryService.batteries; let i = index">
|
||||
<mat-card class="mt-2" *ngFor="let battery of batteries; let i = index">
|
||||
<div class="d-flex">
|
||||
<div class="d-flex flex-grow-1 align-items-center">
|
||||
<h5 class="mb-0">{{battery.name}}</h5>
|
||||
@ -27,13 +22,13 @@
|
||||
<div class="d-flex flex-grow-1 align-items-center justify-content-center">
|
||||
<button mat-button (click)="selected = i"
|
||||
[ngClass]="{'selected': selected == i, 'text-success': batteryService.charging, 'text-danger': !batteryService.charging}">
|
||||
{{battery.charge | number : '1.1-1'}} V
|
||||
{{battery.voltage | number : '1.1-1'}} V
|
||||
</button>
|
||||
</div>
|
||||
<div class="d-flex flex-grow-1 align-items-center justify-content-end text-muted">
|
||||
<button mat-button (click)="selected = batteryService.batteries.length + i"
|
||||
[ngClass]="{'selected': selected == batteryService.batteries.length + i}">
|
||||
{{battery.temp | number : '1.1-1'}} °C
|
||||
<button mat-button (click)="selected = batteries.length + i"
|
||||
[ngClass]="{'selected': selected == batteries.length + i}">
|
||||
{{battery.temperature | number : '1.1-1'}} °C
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -50,7 +45,7 @@
|
||||
[roundDomains]="true"
|
||||
></ngx-charts-area-chart>
|
||||
</div>
|
||||
<div *ngIf="selected == batteryService.batteries.length + i" class="w-100" style="height: 200px">
|
||||
<div *ngIf="selected == batteries.length + i" class="w-100" style="height: 200px">
|
||||
<ngx-charts-area-chart class="w-100 h-100"
|
||||
[results]="[{name: battery.name, series: battery.tempHistory}]"
|
||||
[scheme]="scheme"
|
||||
|
@ -8,8 +8,7 @@ import {AppComponent} from '../app.component';
|
||||
styles: [`.selected { background-color: rgba(0, 0, 0, 0.1); }`]
|
||||
})
|
||||
export class BatteryComponent implements OnInit {
|
||||
|
||||
locked = true;
|
||||
batteries = [];
|
||||
scheme = {
|
||||
name: 'cool',
|
||||
selectable: true,
|
||||
@ -18,7 +17,20 @@ export class BatteryComponent implements OnInit {
|
||||
};
|
||||
selected = 0;
|
||||
|
||||
constructor(public app: AppComponent, public batteryService: BatteryService) { }
|
||||
constructor(public app: AppComponent, public batteryService: BatteryService) {
|
||||
this.batteryService.data.subscribe((data) => {
|
||||
console.log(data);
|
||||
this.batteries = Object.keys(this.batteryService.modules).map(key => {
|
||||
return {
|
||||
name: `Module ${key}`,
|
||||
chargeHistory: this.batteryService.modules[key].map(row => ({name: new Date(row.timestamp), value: row.voltage})),
|
||||
tempHistory: this.batteryService.modules[key].map(row => ({name: new Date(row.timestamp), value: row.temperature})),
|
||||
temperature: this.batteryService.modules[key][this.batteryService.modules[key].length - 1].temperature,
|
||||
voltage: this.batteryService.modules[key][this.batteryService.modules[key].length - 1].voltage
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() { }
|
||||
|
||||
|
@ -1,18 +1,26 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {AngularFirestore} from '@angular/fire/firestore';
|
||||
import {Battery} from './battery';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class BatteryService {
|
||||
batteries = [];
|
||||
charge: number;
|
||||
lastCharge: number[] = [];
|
||||
data = new BehaviorSubject<Battery[]>([]);
|
||||
lastUpdate = new Date().getTime();
|
||||
relayMode: string = 'null';
|
||||
modules = [];
|
||||
temp: number = 0;
|
||||
uptime: string;
|
||||
|
||||
get charging() { return this.lastCharge.reduce((acc, v) => acc + v, 0) / this.lastCharge.length < this.charge; }
|
||||
get charging() {
|
||||
let value = this.data.value;
|
||||
if(!value.length) return null;
|
||||
let last = value[value.length - 1];
|
||||
let secondLast = value[value.length - 2];
|
||||
return last.soc > secondLast.soc;
|
||||
}
|
||||
|
||||
get icon() {
|
||||
if(new Date().getTime() - this.lastUpdate > 300000) return 'battery_alert';
|
||||
@ -24,36 +32,21 @@ export class BatteryService {
|
||||
let afterDate = new Date();
|
||||
afterDate.setDate(afterDate.getDate() - 1);
|
||||
|
||||
this.firestore.collection('Battery').doc('170614D').collection('data', ref => ref.where('timestamp', '>=', afterDate).orderBy('timestamp')).valueChanges().subscribe(data => {
|
||||
this.batteries = data.reduce((acc, row) => {
|
||||
row.payload.forEach((data, i) => {
|
||||
if(!acc[i]) acc[i] = [];
|
||||
acc[i].push(Object.assign(data, {timestamp: row.timestamp.toDate()}));
|
||||
this.firestore.collection('Battery').doc('170614D').collection<Battery>('data', ref => ref.where('timestamp', '>=', afterDate.getTime()).orderBy('timestamp')).valueChanges().subscribe(data => {
|
||||
this.modules = data.reduce((acc: any, row) => {
|
||||
Object.keys(row.modules).forEach(module => {
|
||||
if(!acc[module]) acc[module] = [];
|
||||
acc[module].push(Object.assign(row.modules[module], {timestamp: row.timestamp}));
|
||||
});
|
||||
return acc;
|
||||
}, []).map((module, i) => {
|
||||
const last = module[module.length - 1];
|
||||
return {
|
||||
charge: last.charge,
|
||||
chargeHistory: module.map(row => ({name: row.timestamp, value: row.charge})),
|
||||
lastUpdate: last.timestamp,
|
||||
name: `Module ${i + 1}`,
|
||||
temp: last.temp,
|
||||
tempHistory: module.map(row => ({name: row.timestamp, value: row.temp}))
|
||||
};
|
||||
});
|
||||
}, {});
|
||||
|
||||
this.lastCharge.push(this.charge);
|
||||
this.lastCharge.splice(0, this.lastCharge.length - 3);
|
||||
this.lastUpdate = this.batteries[0].lastUpdate;
|
||||
this.charge = this.batteries.reduce((acc, module) => acc + module.charge, 0) / 2;
|
||||
this.temp = this.batteries.reduce((acc, module) => acc + module.temp, 0) / this.batteries.length;
|
||||
let last = data[data.length - 1];
|
||||
this.lastUpdate = last.timestamp;
|
||||
this.charge = last.voltage;
|
||||
this.temp = last.temperature;
|
||||
this.uptime = last.uptime;
|
||||
this.data.next(data);
|
||||
});
|
||||
}
|
||||
|
||||
setRelayMode(mode?: string) {
|
||||
if(mode == 'null') this.firestore.collection('Battery').doc('170614D').update({config: {relayMode: null}});
|
||||
else if(mode == 'true') this.firestore.collection('Battery').doc('170614D').update({config: {relayMode: true}});
|
||||
else if(mode == 'false') this.firestore.collection('Battery').doc('170614D').update({config: {relayMode: false}});
|
||||
}
|
||||
}
|
||||
|
30
src/app/battery/battery.ts
Normal file
30
src/app/battery/battery.ts
Normal file
@ -0,0 +1,30 @@
|
||||
export interface Battery {
|
||||
ampHours: number;
|
||||
avgCellVoltage: number;
|
||||
capacity: number;
|
||||
current: number;
|
||||
lifetimeCharge: number;
|
||||
lifetimeDischarge: number;
|
||||
maxCellVoltage: number;
|
||||
maxDischargeCurrent: number;
|
||||
maxVoltage: number;
|
||||
minCellVoltage: number;
|
||||
minVoltage: number;
|
||||
modules: {[key: number]: {
|
||||
cells: {[key: number]: number}
|
||||
negativeTemperature: number;
|
||||
positiveTemperature: number;
|
||||
temperature: number;
|
||||
voltage: number;
|
||||
}},
|
||||
negativeContactor: boolean,
|
||||
positiveContactor: boolean,
|
||||
power: number;
|
||||
soc: number;
|
||||
temperature: number;
|
||||
timestamp: number;
|
||||
uptime: string;
|
||||
version: number;
|
||||
voltage: number;
|
||||
wattHours: number;
|
||||
}
|
Loading…
Reference in New Issue
Block a user