Updated site to use new BMS data
This commit is contained in:
		@@ -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 style="max-width: 1000px;">
 | 
				
			||||||
        <div class="d-flex flex-column flex-md-row justify-content-between">
 | 
					        <div class="d-flex flex-column flex-md-row justify-content-between align-items-end mb-2">
 | 
				
			||||||
            <div class="mb-3">
 | 
					            <div>
 | 
				
			||||||
                <h1 class="mb-0">Powerwall: {{batteryService.charge | number : '1.1-1'}} V</h1>
 | 
					                <h1 class="mb-0">Powerwall: {{batteryService.charge | number : '1.1-1'}} V</h1>
 | 
				
			||||||
                <h6>Last Updated At: {{batteryService.lastUpdate | date: 'short'}}</h6>
 | 
					                <h6>Last Updated At: {{batteryService.lastUpdate | date: 'short'}}</h6>
 | 
				
			||||||
 | 
					                <h6 class="mb-0">Uptime: {{batteryService.uptime}}</h6>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div class="d-flex flex-column align-content-center mb-3">
 | 
					            <div>
 | 
				
			||||||
                <div>
 | 
					                <mat-button-toggle-group>
 | 
				
			||||||
                    <h5><mat-icon *ngIf="locked" class="mr-1">lock</mat-icon>Cooling Fans</h5>
 | 
					                    <mat-button-toggle value="24" [checked]="true">24 Hours</mat-button-toggle>
 | 
				
			||||||
                </div>
 | 
					                    <mat-button-toggle value="12">12 Hours</mat-button-toggle>
 | 
				
			||||||
                <div>
 | 
					                    <mat-button-toggle value="6">6 Hours</mat-button-toggle>
 | 
				
			||||||
                    <mat-button-toggle-group class="mb-3" [ngModel]="batteryService.relayMode"
 | 
					                </mat-button-toggle-group>
 | 
				
			||||||
                                             (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>
 | 
					            </div>
 | 
				
			||||||
        </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">
 | 
				
			||||||
                <div class="d-flex flex-grow-1 align-items-center">
 | 
					                <div class="d-flex flex-grow-1 align-items-center">
 | 
				
			||||||
                    <h5 class="mb-0">{{battery.name}}</h5>
 | 
					                    <h5 class="mb-0">{{battery.name}}</h5>
 | 
				
			||||||
@@ -27,13 +22,13 @@
 | 
				
			|||||||
                <div class="d-flex flex-grow-1 align-items-center justify-content-center">
 | 
					                <div class="d-flex flex-grow-1 align-items-center justify-content-center">
 | 
				
			||||||
                    <button mat-button (click)="selected = i"
 | 
					                    <button mat-button (click)="selected = i"
 | 
				
			||||||
                            [ngClass]="{'selected': selected == i, 'text-success': batteryService.charging, 'text-danger': !batteryService.charging}">
 | 
					                            [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>
 | 
					                    </button>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div class="d-flex flex-grow-1 align-items-center justify-content-end text-muted">
 | 
					                <div class="d-flex flex-grow-1 align-items-center justify-content-end text-muted">
 | 
				
			||||||
                    <button mat-button (click)="selected = batteryService.batteries.length + i"
 | 
					                    <button mat-button (click)="selected = batteries.length + i"
 | 
				
			||||||
                            [ngClass]="{'selected': selected == batteryService.batteries.length + i}">
 | 
					                            [ngClass]="{'selected': selected == batteries.length + i}">
 | 
				
			||||||
                        {{battery.temp | number : '1.1-1'}} °C
 | 
					                        {{battery.temperature | number : '1.1-1'}} °C
 | 
				
			||||||
                    </button>
 | 
					                    </button>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
@@ -50,7 +45,7 @@
 | 
				
			|||||||
                                       [roundDomains]="true"
 | 
					                                       [roundDomains]="true"
 | 
				
			||||||
                ></ngx-charts-area-chart>
 | 
					                ></ngx-charts-area-chart>
 | 
				
			||||||
            </div>
 | 
					            </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"
 | 
					                <ngx-charts-area-chart class="w-100 h-100"
 | 
				
			||||||
                                       [results]="[{name: battery.name, series: battery.tempHistory}]"
 | 
					                                       [results]="[{name: battery.name, series: battery.tempHistory}]"
 | 
				
			||||||
                                       [scheme]="scheme"
 | 
					                                       [scheme]="scheme"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,8 +8,7 @@ import {AppComponent} from '../app.component';
 | 
				
			|||||||
    styles: [`.selected { background-color: rgba(0, 0, 0, 0.1); }`]
 | 
					    styles: [`.selected { background-color: rgba(0, 0, 0, 0.1); }`]
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class BatteryComponent implements OnInit {
 | 
					export class BatteryComponent implements OnInit {
 | 
				
			||||||
 | 
					    batteries = [];
 | 
				
			||||||
    locked = true;
 | 
					 | 
				
			||||||
    scheme = {
 | 
					    scheme = {
 | 
				
			||||||
        name: 'cool',
 | 
					        name: 'cool',
 | 
				
			||||||
        selectable: true,
 | 
					        selectable: true,
 | 
				
			||||||
@@ -18,7 +17,20 @@ export class BatteryComponent implements OnInit {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
    selected = 0;
 | 
					    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() { }
 | 
					    ngOnInit() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,18 +1,26 @@
 | 
				
			|||||||
import {Injectable} from '@angular/core';
 | 
					import {Injectable} from '@angular/core';
 | 
				
			||||||
import {AngularFirestore} from '@angular/fire/firestore';
 | 
					import {AngularFirestore} from '@angular/fire/firestore';
 | 
				
			||||||
 | 
					import {Battery} from './battery';
 | 
				
			||||||
 | 
					import {BehaviorSubject} from 'rxjs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Injectable({
 | 
					@Injectable({
 | 
				
			||||||
    providedIn: 'root'
 | 
					    providedIn: 'root'
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class BatteryService {
 | 
					export class BatteryService {
 | 
				
			||||||
    batteries = [];
 | 
					 | 
				
			||||||
    charge: number;
 | 
					    charge: number;
 | 
				
			||||||
    lastCharge: number[] = [];
 | 
					    data = new BehaviorSubject<Battery[]>([]);
 | 
				
			||||||
    lastUpdate = new Date().getTime();
 | 
					    lastUpdate = new Date().getTime();
 | 
				
			||||||
    relayMode: string = 'null';
 | 
					    modules = [];
 | 
				
			||||||
    temp: number = 0;
 | 
					    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() {
 | 
					    get icon() {
 | 
				
			||||||
        if(new Date().getTime() - this.lastUpdate > 300000) return 'battery_alert';
 | 
					        if(new Date().getTime() - this.lastUpdate > 300000) return 'battery_alert';
 | 
				
			||||||
@@ -24,36 +32,21 @@ export class BatteryService {
 | 
				
			|||||||
        let afterDate = new Date();
 | 
					        let afterDate = new Date();
 | 
				
			||||||
        afterDate.setDate(afterDate.getDate() - 1);
 | 
					        afterDate.setDate(afterDate.getDate() - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.firestore.collection('Battery').doc('170614D').collection('data', ref => ref.where('timestamp', '>=', afterDate).orderBy('timestamp')).valueChanges().subscribe(data => {
 | 
					        this.firestore.collection('Battery').doc('170614D').collection<Battery>('data', ref => ref.where('timestamp', '>=', afterDate.getTime()).orderBy('timestamp')).valueChanges().subscribe(data => {
 | 
				
			||||||
            this.batteries = data.reduce((acc, row) => {
 | 
					            this.modules = data.reduce((acc: any, row) => {
 | 
				
			||||||
                row.payload.forEach((data, i) => {
 | 
					                Object.keys(row.modules).forEach(module => {
 | 
				
			||||||
                    if(!acc[i]) acc[i] = [];
 | 
					                    if(!acc[module]) acc[module] = [];
 | 
				
			||||||
                    acc[i].push(Object.assign(data, {timestamp: row.timestamp.toDate()}));
 | 
					                    acc[module].push(Object.assign(row.modules[module], {timestamp: row.timestamp}));
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                return acc;
 | 
					                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);
 | 
					            let last = data[data.length - 1];
 | 
				
			||||||
            this.lastCharge.splice(0, this.lastCharge.length - 3);
 | 
					            this.lastUpdate = last.timestamp;
 | 
				
			||||||
            this.lastUpdate = this.batteries[0].lastUpdate;
 | 
					            this.charge = last.voltage;
 | 
				
			||||||
            this.charge = this.batteries.reduce((acc, module) => acc + module.charge, 0) / 2;
 | 
					            this.temp = last.temperature;
 | 
				
			||||||
            this.temp = this.batteries.reduce((acc, module) => acc + module.temp, 0) / this.batteries.length;
 | 
					            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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user