Switched to accuWeather and updated some css
This commit is contained in:
parent
454fe07d49
commit
1ee0606b5b
@ -6,7 +6,7 @@
|
||||
<small class="text-muted ml-2">v{{environment.version}}</small>
|
||||
</span>
|
||||
</mat-toolbar>
|
||||
<mat-drawer-container [hasBackdrop]="false" [ngClass]="{'mobile-height': mobile, 'desktop-height': !mobile}">
|
||||
<mat-drawer-container class="fill-height" [hasBackdrop]="false">
|
||||
<mat-drawer class="bg-primary" [mode]="mobile ? 'push' : 'side'" [opened]="open" [disableClose]="!mobile" [autoFocus]="false">
|
||||
<mat-nav-list class="p-0">
|
||||
<mat-divider></mat-divider>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="desktop-height p-3" style="background-color: #b52e3c !important;">
|
||||
<div class="fill-height p-3" style="background-color: #b52e3c !important;">
|
||||
<div style="max-width: 1000px;">
|
||||
<h1 class="text-white">Powerwall: {{batteryService.charge | round}} V</h1>
|
||||
<mat-button-toggle-group [ngModel]="batteryService.relayMode" (change)="batteryService.setRelayMode($event.value)"><!---->
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="desktop-height p-3">
|
||||
<div class="fill-height p-3">
|
||||
<div style="max-width: 1000px;">
|
||||
<div class="d-flex">
|
||||
<div class="pr-2 border-right border-white">
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="desktop-height p-3">
|
||||
<div class="fill-height p-3">
|
||||
<div style="max-width: 1000px">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<div class="w-100 p-3" [style.backgroundColor]="day ? '#88aaff' : '#000e31'">
|
||||
<div class="fill-height p-3" [style.backgroundColor]="day ? '#88aaff' : '#000e31'" style="overflow-y: scroll">
|
||||
<!-- Current Weather -->
|
||||
<div class="my-5 d-flex flex-column align-items-center">
|
||||
<div class="d-flex flex-column align-items-center">
|
||||
<div>
|
||||
<h3 class="mb-0 text-center">London, ON</h3>
|
||||
<h3>{{weatherService.weather?.currently.summary}}</h3>
|
||||
<h3>{{weatherService.weather[0].phrase}}</h3>
|
||||
</div>
|
||||
<div class="d-flex flex-column flex-md-row align-items-center justify-content-center">
|
||||
<div class="p-3 text-center">
|
||||
@ -12,23 +12,23 @@
|
||||
<div class="d-flex">
|
||||
<div class="d-flex flex-column mr-3">
|
||||
<div>
|
||||
<h1 class="mb-0">{{weatherService.weather?.currently.temperature | round: 1}} °C</h1>
|
||||
<h1 class="mb-0">{{weatherService.weather[0].current | round: 1}} °C</h1>
|
||||
</div>
|
||||
<div>
|
||||
Feels Like: {{weatherService.weather?.currently.apparentTemperature | round}} °C
|
||||
Feels Like: {{weatherService.weather[0].feelsLike | round}} °C
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<div>
|
||||
<mat-icon style="font-size: 18px; width: 18px; height: 18px">arrow_upward</mat-icon>
|
||||
{{weatherService.weather?.daily.data[0].temperatureHigh | round}} °C
|
||||
{{weatherService.weather[0].high | round}} °C
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon style="font-size: 18px; width: 18px; height: 18px">arrow_downward</mat-icon>
|
||||
{{weatherService.weather?.daily.data[0].temperatureLow | round}} °C
|
||||
{{weatherService.weather[0].low | round}} °C
|
||||
</div>
|
||||
<div>
|
||||
<i class="wi wi-fw wi-umbrella"></i> {{weatherService.weather?.daily.data[0].precipProbability * 100 | round}}%
|
||||
<i class="wi wi-fw wi-umbrella"></i> {{weatherService.weather[0].pop * 100 | round}}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -37,11 +37,11 @@
|
||||
<!-- Forecast -->
|
||||
<mat-card class="m-3 mx-auto" style="max-width: 450px">
|
||||
<div class="d-flex justify-content-center">
|
||||
<div *ngFor="let day of weatherService.weather?.daily.data.slice(1, 7)" class="d-flex flex-column align-items-center flex-grow-1" style="max-width: 75px;">
|
||||
{{day.time.toString().slice(0, 4).toUpperCase()}}
|
||||
<div *ngFor="let day of weatherService.weather.slice(1, 5)" class="d-flex flex-column align-items-center flex-grow-1" style="max-width: 75px;">
|
||||
{{day.date.toString().slice(0, 4).toUpperCase()}}
|
||||
<i [class]="'my-2 wi wi-fw ' + day.icon" style="font-size: 2rem"></i>
|
||||
<div class="text-center">{{day.temperatureHigh | round}} °C</div>
|
||||
<div class="text-center text-muted">{{day.temperatureLow | round}} °C</div>
|
||||
<div class="text-center">{{day.high | round}} °C</div>
|
||||
<div class="text-center text-muted">{{day.low | round}} °C</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
@ -50,13 +50,13 @@
|
||||
<h5>Sunlight</h5>
|
||||
<div class="d-flex justify-content-center">
|
||||
<div class="d-flex align-items-center flex-grow-1">
|
||||
<i class="wi wi-sunrise mr-1"></i> {{weatherService.weather?.daily.data[0].sunriseTime | date: 'shortTime'}}
|
||||
<i class="wi wi-sunrise mr-1"></i> {{weatherService.weather[0].sunrise | date: 'shortTime'}}
|
||||
</div>
|
||||
<div class="d-flex align-items-center justify-content-center flex-grow-1">
|
||||
<i class="wi wi-fw wi-cloud mr-1"></i> {{weatherService.weather?.currently.cloudCover * 100 | round}}%
|
||||
<i class="wi wi-fw wi-cloud mr-1"></i> {{weatherService.weather[0].cloudCover * 100 | round}}%
|
||||
</div>
|
||||
<div class="d-flex align-items-center justify-content-end flex-grow-1">
|
||||
<i class="wi wi-sunset mr-1"></i> {{weatherService.weather?.daily.data[0].sunsetTime | date: 'shortTime'}}
|
||||
<i class="wi wi-sunset mr-1"></i> {{weatherService.weather[0].sunset | date: 'shortTime'}}
|
||||
</div>
|
||||
</div>
|
||||
<canvas id="myCanvas" class="mt-3" style="width: 100%" height="150"></canvas>
|
||||
@ -66,47 +66,17 @@
|
||||
<h5>Wind</h5>
|
||||
<div class="d-flex justify-content-center">
|
||||
<div class="d-flex align-items-center flex-grow-1">
|
||||
<i class="wi wi-fw wi-windy"></i> {{weatherService.weather?.currently.windSpeed | round}} km/h
|
||||
<i class="wi wi-fw wi-windy"></i> {{weatherService.weather[0].wind.speed | round}} km/h
|
||||
</div>
|
||||
<div class="d-flex align-items-center justify-content-center flex-grow-1">
|
||||
{{weatherService.weather?.currently.windBearing}}°
|
||||
{{weatherService.weather[0].wind.direction}}°
|
||||
</div>
|
||||
<div class="d-flex align-items-center justify-content-end flex-grow-1">
|
||||
<i class="wi wi-fw wi-strong-wind"></i> {{weatherService.weather?.currently.windGust | round}} km/h
|
||||
<i class="wi wi-fw wi-strong-wind"></i> {{weatherService.weather[0].wind.gusts | round}} km/h
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-3 text-center">
|
||||
<i class="wi wi-wind wi-fw wi-towards-0" [style.transform]="'rotate(' + weatherService.weather?.currently.windBearing + 'deg)'" style="color: #5d8cff; font-size: 14rem; height: 14rem; width: 14rem"></i>
|
||||
|
||||
<i class="wi wi-wind wi-fw wi-towards-0" [style.transform]="'rotate(' + weatherService.weather[0].wind.direction + 'deg)'" style="color: #5d8cff; font-size: 14rem; height: 14rem; width: 14rem"></i>
|
||||
</div>
|
||||
</mat-card>
|
||||
<!-- Atmospheric -->
|
||||
<mat-card class="m-3 mx-auto" style="max-width: 450px">
|
||||
<h5>Atmospheric</h5>
|
||||
<div class="d-flex">
|
||||
<div class="flex-grow-1">
|
||||
<div>
|
||||
<i class="wi wi-fw wi-barometer"></i> {{weatherService.weather?.currently.pressure / 10 | round: 1}} kPa
|
||||
</div>
|
||||
<div>
|
||||
<i class="wi wi-fw wi-hot"></i> UV Index: {{weatherService.weather?.currently.uvIndex}}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon>remove_red_eye</mat-icon> {{weatherService.weather?.currently.visibility | round}} km
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div>
|
||||
<i class="wi wi-fw wi-humidity"></i> {{weatherService.weather?.currently.humidity * 100 | round}}% Humidity
|
||||
</div>
|
||||
<div>
|
||||
<i class="wi wi-fw wi-umbrella"></i> {{weatherService.weather?.daily.data[0].precipProbability * 100 | round}}%
|
||||
</div>
|
||||
<div>
|
||||
<i class="wi wi-fw wi-flood"></i> {{weatherService.weather?.daily.data[0].precipAccumulation | round: 1}} cm {{weatherService.weather?.daily.data[0].precipType}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</mat-card>
|
||||
</div>
|
||||
|
@ -13,10 +13,10 @@ export class WeatherComponent implements OnInit {
|
||||
constructor(public weatherService: WeatherService) { }
|
||||
|
||||
ngOnInit() {
|
||||
timer(0, 1000).pipe(filter(() => this.weatherService.weather)).subscribe(() => {
|
||||
timer(0, 1000).pipe(filter(() => !!this.weatherService.weather[0])).subscribe(() => {
|
||||
const now = new Date().getTime();
|
||||
const sunrise = this.weatherService.weather.daily.data[0].sunriseTime.getTime();
|
||||
const sunset = this.weatherService.weather.daily.data[0].sunsetTime.getTime();
|
||||
const sunrise = this.weatherService.weather[0].sunrise.getTime();
|
||||
const sunset = this.weatherService.weather[0].sunset.getTime();
|
||||
|
||||
this.day = now > sunrise && now < sunset;
|
||||
let diff = sunset - sunrise;
|
||||
|
@ -1,31 +1,62 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {Subscription, timer} from 'rxjs';
|
||||
import {environment} from '../../environments/environment';
|
||||
import {Weather} from './weather';
|
||||
import {WeatherIcons} from './weatherIcons';
|
||||
import {timer} from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class WeatherService {
|
||||
icon: string;
|
||||
lat = 42.9849;
|
||||
lng = -81.2453;
|
||||
units = 'ca';
|
||||
weather: any;
|
||||
locationKey: string;
|
||||
metric = true;
|
||||
sub: Subscription;
|
||||
weather: Weather[];
|
||||
|
||||
constructor(http: HttpClient) {
|
||||
// Get weather every 5 minutes
|
||||
timer(0, 5 * 60000).subscribe(async () => {
|
||||
this.weather = await http.get(`https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/88373fac9e52db6ad33a296f3b30404d/${this.lat},${this.lng}?units=${this.units}`).toPromise();
|
||||
get icon() {
|
||||
if(!this.weather.length) return '';
|
||||
return this.weather[0].icon;
|
||||
}
|
||||
|
||||
// Format data
|
||||
this.weather.daily.data.map(day => Object.assign(day, {
|
||||
icon: WeatherIcons[day.icon],
|
||||
time: new Date(day.time * 1000),
|
||||
sunsetTime: new Date(day.sunsetTime * 1000),
|
||||
sunriseTime: new Date(day.sunriseTime * 1000),
|
||||
constructor(private http: HttpClient) {
|
||||
this.search('London ON');
|
||||
}
|
||||
|
||||
async search(text: string) {
|
||||
this.locationKey = (await this.http.get(`http://dataservice.accuweather.com/locations/v1/search?apikey=${environment.accuWeather}&q=${text}`).toPromise())[0].Key;
|
||||
this.update();
|
||||
}
|
||||
|
||||
async update() {
|
||||
if(this.sub) {
|
||||
this.sub.unsubscribe();
|
||||
this.sub = null;
|
||||
}
|
||||
|
||||
this.sub = timer(0, 60000).subscribe(async () => {
|
||||
let temp: any = await this.http.get(`http://dataservice.accuweather.com/forecasts/v1/daily/5day/${this.locationKey}?apikey=${environment.accuWeather}&metric=${this.metric}&details=true`).toPromise();
|
||||
this.weather = temp['DailyForecasts'].map(forecast => ({
|
||||
cloudCover: forecast.Day.CloudCover / 100,
|
||||
date: new Date(forecast.Date),
|
||||
high: forecast.Temperature.Maximum.Value,
|
||||
icon: WeatherIcons[forecast.Day.Icon],
|
||||
low: forecast.Temperature.Minimum.Value,
|
||||
phrase: forecast.Day.ShortPhrase,
|
||||
pop: forecast.Day.PrecipitationProbability / 100,
|
||||
sunrise: new Date(forecast.Sun.Rise),
|
||||
sunset: new Date(forecast.Sun.Set),
|
||||
}));
|
||||
this.icon = WeatherIcons[this.weather.currently.icon];
|
||||
temp = (await this.http.get(`http://dataservice.accuweather.com/currentconditions/v1/${this.locationKey}?apikey=${environment.accuWeather}&details=true`).toPromise())[0];
|
||||
Object.assign(this.weather[0], {
|
||||
cloudCover: temp.CloudCover / 100,
|
||||
current: temp.Temperature[this.metric ? 'Metric' : 'Imperial'].Value,
|
||||
feelsLike: temp.RealFeelTemperature[this.metric ? 'Metric' : 'Imperial'].Value,
|
||||
humidity: temp.RelativeHumidity,
|
||||
icon: WeatherIcons[temp.WeatherIcon],
|
||||
UVIndex: temp.UVIndex,
|
||||
wind: {direction: temp.Wind.Direction.Degrees, speed: temp.Wind.Speed[this.metric ? 'Metric' : 'Imperial'].Value, gusts: temp.WindGust.Speed[this.metric ? 'Metric' : 'Imperial'].Value}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
16
src/app/weather/weather.ts
Normal file
16
src/app/weather/weather.ts
Normal file
@ -0,0 +1,16 @@
|
||||
export interface Weather {
|
||||
cloudCover: number;
|
||||
current: number;
|
||||
date: Date;
|
||||
feelsLike: number;
|
||||
high: number;
|
||||
humidity: number;
|
||||
icon: string;
|
||||
low: number;
|
||||
phrase: string;
|
||||
pop: number;
|
||||
sunrise: Date;
|
||||
sunset: Date;
|
||||
UVIndex: number;
|
||||
wind: {direction: number, speed: number, gusts: number}
|
||||
}
|
@ -1,16 +1,47 @@
|
||||
export enum WeatherIcons {
|
||||
'clear-day' = 'wi-day-sunny',
|
||||
'clear-night' = 'wi-night-clear',
|
||||
'cloudy' = 'wi-cloudy',
|
||||
'default' = '',
|
||||
'fog' = 'wi-fog',
|
||||
'hail' = 'wi-hail',
|
||||
'partly-cloudy-day' = 'wi-day-cloudy',
|
||||
'partly-cloudy-night' = 'wi-night-alt-cloudy',
|
||||
'rain' = 'wi-rain',
|
||||
'sleet' = 'wi-sleet',
|
||||
'snow' = 'wi-snow',
|
||||
'thunderstorm' = 'wi-thunderstorm',
|
||||
'tornado' = 'wi-tornado',
|
||||
'wind' = 'wi-strong-wind',
|
||||
}
|
||||
export const WeatherIcons = [
|
||||
'',
|
||||
'wi-day-sunny', // Sunny
|
||||
'wi-day-sunny', // Mostly Sunny
|
||||
'wi-day-sunny-overcast', // Partly Sunny
|
||||
'wi-day-sunny-overcast', // Intermittent Clouds
|
||||
'wi-day-cloudy', // Hazy Sunshine
|
||||
'wi-day-cloudy-high', // Mostly Cloudy
|
||||
'wi-cloudy', // Cloudy
|
||||
'wi-cloudy', // Overcast
|
||||
'',
|
||||
'',
|
||||
'wi-fog', // Fog
|
||||
'wi-showers', // Showers
|
||||
'wi-day-showers', // Mostly Cloudy With Showers
|
||||
'wi-day-showers', // Partly Cloudy With Showers
|
||||
'wi-thunderstorm', // Thunderstorms
|
||||
'wi-day-storm-showers', // Mostly Cloudy With Thunderstorms
|
||||
'wi-day-storm-showers', // Partly Cloudy With Thunderstorms
|
||||
'wi-sprinkle', // Rain
|
||||
'wi-sleet', // Flurries
|
||||
'wi-day-sleet', // Mostly Cloudy With Flurries
|
||||
'wi-day-sleet', // Partly Cloudy With Flurries
|
||||
'wi-snow', // Snow
|
||||
'wi-day-snow', // Mostly Cloudy With Snow
|
||||
'wi-snowflake-cold', // Ice
|
||||
'wi-sleet', // Sleet
|
||||
'wi-hail', // Freezing Rain
|
||||
'',
|
||||
'',
|
||||
'wi-rain-mix', // Rain And Snow
|
||||
'wi-thermometer', // Hot
|
||||
'wi-thermometer-exterior', // Cold
|
||||
'wi-strong-wind', // Windy
|
||||
'wi-night-clear', // Clear
|
||||
'wi-night-clear', // Mostly Clear
|
||||
'wi-night-partly-cloudy', // Partly Clear
|
||||
'wi-night-partly-cloudy', // Intermittent Clouds
|
||||
'wi-night-alt-cloudy', // Hazy Moonlight
|
||||
'wi-night-alt-cloudy', // Mostly Cloudy
|
||||
'wi-night-alt-showers', // Partly Cloudy With Showers
|
||||
'wi-night-alt-showers', // Mostly Cloudy With Showers
|
||||
'wi-night-alt-storm-showers', // Partly Cloudy With Thunderstorms
|
||||
'wi-night-alt-storm-showers', // Mostly Cloudy With Thunderstorms
|
||||
'wi-night-alt-sleet', // Mostly Cloudy With Flurries
|
||||
'wi-night-alt-snow' // Mostly Cloudy With Snow
|
||||
];
|
||||
|
@ -1,26 +1,26 @@
|
||||
<div class="w-100 h-100">
|
||||
<h3 class="mb-0 text-center">{{weatherService.weather?.currently.summary}}</h3>
|
||||
<h3 class="text-center">{{weatherService.weather[0].phrase}}</h3>
|
||||
<div class="d-flex align-items-center">
|
||||
<div><i [class]="'mt-4 wi wi-fw ' + weatherService.icon" style="font-size: 6rem"></i></div>
|
||||
<div>
|
||||
<div>
|
||||
<h1 class="mb-0">{{weatherService.weather?.currently.temperature | round: 1}} °C</h1>
|
||||
<h1 class="mb-0">{{weatherService.weather[0].current | round: 1}} °C</h1>
|
||||
</div>
|
||||
<div>
|
||||
Feels Like: {{weatherService.weather?.currently.apparentTemperature | round}} °C
|
||||
Feels Like: {{weatherService.weather[0].feelsLike | round}} °C
|
||||
</div>
|
||||
</div>
|
||||
<div class="pl-3">
|
||||
<div>
|
||||
<mat-icon style="font-size: 18px; width: 18px; height: 18px">arrow_upward</mat-icon>
|
||||
{{weatherService.weather?.daily.data[0].temperatureHigh | round}} °C
|
||||
{{weatherService.weather[0].high | round}} °C
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon style="font-size: 18px; width: 18px; height: 18px">arrow_downward</mat-icon>
|
||||
{{weatherService.weather?.daily.data[0].temperatureLow | round}} °C
|
||||
{{weatherService.weather[0].low | round}} °C
|
||||
</div>
|
||||
<div>
|
||||
<i class="wi wi-fw wi-umbrella"></i> {{weatherService.weather?.daily.data[0].precipProbability * 100 | round}}%
|
||||
<i class="wi wi-fw wi-umbrella"></i> {{weatherService.weather[0].pop * 100 | round}}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
2
src/assets/bootstrap.min.css
vendored
2
src/assets/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
@ -1,4 +1,5 @@
|
||||
export const environment = {
|
||||
accuWeather: 'DktD9hoGvnnylAWDA3p1lVvqPXOAuRZD',
|
||||
firebase: {
|
||||
apiKey: "AIzaSyAs3FvBCADM66wR1-leBz6aIjK1wZfUxRo",
|
||||
authDomain: "homefront-2ccb4.firebaseapp.com",
|
||||
|
@ -1,4 +1,5 @@
|
||||
export const environment = {
|
||||
accuWeather: 'DktD9hoGvnnylAWDA3p1lVvqPXOAuRZD',
|
||||
firebase: {
|
||||
apiKey: "AIzaSyAs3FvBCADM66wR1-leBz6aIjK1wZfUxRo",
|
||||
authDomain: "homefront-2ccb4.firebaseapp.com",
|
||||
|
@ -52,7 +52,7 @@ html, body {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.desktop-height {
|
||||
.fill-height {
|
||||
height: calc(100vh - 64px);
|
||||
}
|
||||
|
||||
@ -122,10 +122,6 @@ html, body {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.mobile-height{
|
||||
height: calc(100vh - 56px);
|
||||
}
|
||||
|
||||
.off-center {
|
||||
position: fixed;
|
||||
left: calc(50% - 75px);
|
||||
@ -153,7 +149,7 @@ html, body {
|
||||
}
|
||||
|
||||
@media (max-width: 599px) {
|
||||
.desktop-height {
|
||||
.fill-height {
|
||||
height: calc(100vh - 56px);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user