Add basic almanac on dashboard

This commit is contained in:
2019-10-07 22:09:09 -04:00
parent 130bd18ae6
commit 90c0dce614
9 changed files with 167 additions and 4 deletions

View File

@@ -12,6 +12,7 @@ import { LayoutModule } from '@angular/cdk/layout';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatListModule } from '@angular/material/list';
import { MatMomentDateModule } from '@angular/material-moment-adapter';
import { MomentModule } from 'ngx-moment';
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
import { GridsterModule } from 'angular-gridster2';
@@ -21,6 +22,7 @@ import { DashboardComponent } from './components/dashboard/dashboard.component';
import { WeatherChartsComponent } from './components/weather/charts/weather-charts.component';
import { WeatherCurrentComponent } from './components/weather/current/weather-current.component';
import { PressureTrendComponent } from './components/weather/pressure-trend/pressure-trend.component';
import { AlmanacComponent } from './components/weather/almanac/almanac.component';
const config: SocketIoConfig = { url: '/api/laundry', options: {} };
@@ -32,7 +34,8 @@ const config: SocketIoConfig = { url: '/api/laundry', options: {} };
DashboardComponent,
WeatherChartsComponent,
WeatherCurrentComponent,
PressureTrendComponent
PressureTrendComponent,
AlmanacComponent
],
imports: [
BrowserModule,
@@ -56,7 +59,8 @@ const config: SocketIoConfig = { url: '/api/laundry', options: {} };
ReactiveFormsModule,
MatMomentDateModule,
MatProgressSpinnerModule,
GridsterModule
GridsterModule,
MomentModule
],
providers: [],
bootstrap: [AppComponent]

View File

@@ -40,5 +40,15 @@
</div>
</div>
</gridster-item>
<gridster-item [item]="dashboardLayout.layout[3]">
<div class="dashboard-item">
<div class="dashboard-item-header">
Almanac
</div>
<div class="dashboard-item-content">
<app-almanac></app-almanac>
</div>
</div>
</gridster-item>
</gridster>
</div>

View File

@@ -13,11 +13,12 @@ export class DashboardComponent implements OnInit {
public locked = true;
private defaultLayout: DashboardLayout = {
version: 1,
version: 2,
layout: [
{ cols: 3, rows: 2, y: 0, x: 0 },
{ cols: 2, rows: 2, y: 0, x: 3 },
{ cols: 2, rows: 2, y: 0, x: 5 }
{ cols: 2, rows: 2, y: 0, x: 5 },
{ cols: 3, rows: 2, y: 0, x: 7 }
]
};

View File

@@ -0,0 +1,33 @@
<div class="almanac-content">
<div *ngIf="!loaded">
Loading...
</div>
<div *ngIf="loaded">
<table>
<tr>
<td class="almanac-table-header">
Sunrise
</td>
<td>
{{ sun.sunrise | amLocal | amDateFormat: 'hh:mm:ss A' }}
</td>
</tr>
<tr>
<td class="almanac-table-header">
Sunset
</td>
<td>
{{ sun.sunset | amLocal | amDateFormat: 'hh:mm:ss A' }}
</td>
</tr>
<tr>
<td class="almanac-table-header">
Moon
</td>
<td>
{{ moonPhaseName(moon.phase) }} - {{ (moon.fraction * 100).toFixed(0) }}% illuminated
</td>
</tr>
</table>
</div>
</div>

View File

@@ -0,0 +1,10 @@
.almanac-content {
font-size: 14px;
padding: 20px;
}
.almanac-table-header {
font-weight: 500;
text-align: right;
padding-right: 10px;
}

View File

@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AlmanacComponent } from './almanac.component';
describe('AlmanacComponent', () => {
let component: AlmanacComponent;
let fixture: ComponentFixture<AlmanacComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AlmanacComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AlmanacComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,59 @@
import { Component, OnInit } from '@angular/core';
import { WeatherReading } from 'src/app/models/weather/weather-reading';
import { WeatherService } from 'src/app/services/weather/weather.service';
import { first } from 'rxjs/operators';
import * as SunCalc from 'suncalc';
@Component({
selector: 'app-almanac',
templateUrl: './almanac.component.html',
styleUrls: ['./almanac.component.scss']
})
export class AlmanacComponent implements OnInit {
public loaded = false;
public latestReading: WeatherReading;
public sun: SunCalc.GetTimesResult;
public moon: SunCalc.GetMoonIlluminationResult;
constructor(private weatherService: WeatherService) { }
ngOnInit() {
this.update();
setInterval(() => this.update(), 60000);
}
async update() {
this.weatherService.getLatestReading().pipe(first(r => r !== null)).subscribe(r => {
this.latestReading = r;
const date = new Date();
this.sun = SunCalc.getTimes(date, this.latestReading.Latitude, this.latestReading.Longitude);
this.moon = SunCalc.getMoonIllumination(date);
this.loaded = true;
});
}
moonPhaseName(phase: number): string {
if (phase === 0) {
return 'New Moon';
} else if (phase < 0.25) {
return 'Waxing Crescent';
} else if (phase === 0.25) {
return 'First Quarter';
} else if (phase < 0.5) {
return 'Waxing Gibbous';
} else if (phase === 0.5) {
return 'Full Moon';
} else if (phase < 0.75) {
return 'Waning Gibbous';
} else if (phase === 0.75) {
return 'Last Quarter';
} else if (phase < 1.0) {
return 'Waning Crescent';
}
}
}