Updated angular
This commit is contained in:
64
src/app/views/battery/battery.component.html
Normal file
64
src/app/views/battery/battery.component.html
Normal file
@ -0,0 +1,64 @@
|
||||
<div class="fill-height p-3" style="background-color: #b52e3c !important; overflow-y: scroll">
|
||||
<!-- Header -->
|
||||
<div class="ml-2 d-flex align-items-center">
|
||||
<div class="d-inline pr-2">
|
||||
<img src="../../../assets/tesla.png" height="85px" width="auto">
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="mb-0">Powerwall: {{batteryService.last.voltage | number : '1.1-1'}} V</h1>
|
||||
<h6>Last Updated At: {{batteryService.last.timestamp | date: 'short'}}</h6>
|
||||
<h6 class="mb-0">Uptime: {{batteryService.last.uptime}}</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 d-flex flex-column flex-md-row">
|
||||
<div class="d-flex flex-md-column flex-row flex-wrap">
|
||||
<mat-card style="margin: 10px; min-width: 200px; width: 200px; height: 200px;">
|
||||
<canvas id="netPower" class="w-100"></canvas>
|
||||
<h5 class="text-center text-muted"><strong>Power: </strong>{{batteryService.last.power | number : '1.1-1'}} Watts</h5>
|
||||
<h5 class="text-center text-muted"><strong>Current: </strong>{{batteryService.last.current | number : '1.1-1'}} Amps</h5>
|
||||
</mat-card>
|
||||
<mat-card style="margin: 10px; min-width: 200px; width: 200px; height: 200px;">
|
||||
<mwl-gauge
|
||||
[max]="100"
|
||||
[color]="color"
|
||||
[dialStartAngle]="-90"
|
||||
[dialEndAngle]="-90.001"
|
||||
[value]="(batteryService.last.soc || 0) * 100"
|
||||
[label]="percent"
|
||||
[animated]="true"
|
||||
[animationDuration]="1">
|
||||
</mwl-gauge>
|
||||
</mat-card>
|
||||
</div>
|
||||
<div class="flex-grow-1" style="overflow: hidden; margin: 10px">
|
||||
<mat-card class="w-100">
|
||||
<canvas baseChart
|
||||
[datasets]="socData"
|
||||
[labels]="socLabels"
|
||||
[options]="socOptions"
|
||||
[legend]="false"
|
||||
chartType="line">
|
||||
</canvas>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Battery Cells -->
|
||||
<div class="d-flex flex-wrap mt-5">
|
||||
<div class="p-2 col-12 col-sm-6 col-lg-3" *ngFor="let battery of batteries; let i = index">
|
||||
<mat-card>
|
||||
<div class="d-flex w-100 justify-content-between align-items-center">
|
||||
<div>
|
||||
<h5 class="mb-0">{{battery.name}}</h5>
|
||||
</div>
|
||||
<div class="text-muted">
|
||||
{{battery.negativeTemperature | number : '1.1-1'}} °C / {{battery.positiveTemperature | number : '1.1-1'}} °C
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center my-3">
|
||||
<mat-icon style="width: 240px; height: 240px; font-size: 240px">battery_full</mat-icon>
|
||||
<span class="text-white font-weight-bold" style="position: absolute; left: 50%; top: 50%; transform: translate(-50%, 25%)">{{battery.voltage | number : '1.1-1'}} V</span>
|
||||
</div>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
113
src/app/views/battery/battery.component.ts
Normal file
113
src/app/views/battery/battery.component.ts
Normal file
@ -0,0 +1,113 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {BatteryService} from '../../services/battery.service';
|
||||
import {AppComponent} from '../app/app.component';
|
||||
|
||||
declare const Gauge: any;
|
||||
|
||||
@Component({
|
||||
selector: 'app-batteries',
|
||||
templateUrl: './battery.component.html',
|
||||
styles: [`.selected { background-color: rgba(0, 0, 0, 0.1); }`]
|
||||
})
|
||||
export class BatteryComponent implements OnInit {
|
||||
batteries: any[] = [];
|
||||
gauge: any;
|
||||
socData: any[] = [];
|
||||
socLabels: string[] = [];
|
||||
socOptions = {
|
||||
responsive: true,
|
||||
scales: {
|
||||
xAxes: [{}],
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
min: 0,
|
||||
max: 1.2,
|
||||
step: 0.1,
|
||||
callback: (label: any) => this.percent(Math.round(label * 100))
|
||||
}
|
||||
}]
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: (tooltipItem: any) => `SOC: ${this.percent(tooltipItem.yLabel * 100)}`
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
constructor(public app: AppComponent, public batteryService: BatteryService) {
|
||||
this.batteryService.data.subscribe((data) => {
|
||||
this.socLabels = data.filter(row => new Date(row.timestamp).getMinutes() % 15 == 0).map(row => this.dateFormat(new Date(row.timestamp)));
|
||||
this.socData = [{label: 'SOC', fill: false, data: data.filter(row => new Date(row.timestamp).getMinutes() % 15 == 0).map(row => row.soc)}];
|
||||
if(this.gauge) this.gauge.set(batteryService.last.power || 0);
|
||||
this.batteries = Object.keys(this.batteryService.modules).map((key: string) => {
|
||||
return {
|
||||
name: `Module ${key}`,
|
||||
negativeTemperature: this.batteryService.modules[key][this.batteryService.modules[key].length - 1].negativeTemperature,
|
||||
positiveTemperature: this.batteryService.modules[key][this.batteryService.modules[key].length - 1].positiveTemperature,
|
||||
voltage: this.batteryService.modules[key][this.batteryService.modules[key].length - 1].voltage
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const canvas = document.getElementById('netPower');
|
||||
if(!canvas) return;
|
||||
|
||||
canvas.style.height = canvas.style.width;
|
||||
this.gauge = new Gauge(canvas).setOptions({
|
||||
angle: 0.2, // The span of the gauge arc
|
||||
lineWidth: 0.2, // The line thickness
|
||||
radiusScale: 1, // Relative radius
|
||||
pointer: {
|
||||
length: 0.5,
|
||||
strokeWidth: 0.035,
|
||||
color: '#000000'
|
||||
},
|
||||
limitMax: true,
|
||||
limitMin: true,
|
||||
generateGradient: true,
|
||||
highDpiSupport: true,
|
||||
staticLabels: {
|
||||
font: "75% sans-serif",
|
||||
labels: [-4000, 0, 4000],
|
||||
color: "black",
|
||||
},
|
||||
staticZones: [
|
||||
{strokeStyle: "#eb575c", min: -4000, max: 0},
|
||||
{strokeStyle: "#49b571", min: 0, max: 4000}
|
||||
],
|
||||
renderTicks: {
|
||||
divisions: 2,
|
||||
divWidth: 1.1,
|
||||
divLength: 1,
|
||||
divColor: '#000',
|
||||
subDivisions: 4,
|
||||
subLength: 0.5,
|
||||
subWidth: 0.6,
|
||||
subColor: '#000'
|
||||
}
|
||||
});
|
||||
this.gauge.minValue = -4000;
|
||||
this.gauge.maxValue = 4000;
|
||||
this.gauge.set(this.batteryService.last.power); // set actual value
|
||||
}
|
||||
|
||||
color() {
|
||||
return '#4f55b6';
|
||||
}
|
||||
|
||||
percent(val: number) {
|
||||
return `${Math.round(val)}%`;
|
||||
}
|
||||
|
||||
dateFormat(date: Date) {
|
||||
let hours = date.getHours();
|
||||
if(hours > 12) hours -= 12;
|
||||
|
||||
let minutes: any = date.getMinutes();
|
||||
if(minutes < 10) minutes = '0' + minutes;
|
||||
|
||||
return `${hours}:${minutes} ${date.getHours() > 12 ? 'PM' : 'AM'}`;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user