From e1750287b31b00e992bcfe07c231a0e7ce2abf41 Mon Sep 17 00:00:00 2001 From: Matthew Oslan Date: Mon, 13 May 2019 19:41:00 -0400 Subject: [PATCH] Use historic data for watering level calculation with Dark Sky --- routes/weatherProviders/DarkSky.ts | 34 ++++++++++++------------------ types.ts | 13 ++++++++---- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/routes/weatherProviders/DarkSky.ts b/routes/weatherProviders/DarkSky.ts index 4f1b19a..c934d94 100644 --- a/routes/weatherProviders/DarkSky.ts +++ b/routes/weatherProviders/DarkSky.ts @@ -1,35 +1,29 @@ +import * as moment from "moment-timezone"; + import { GeoCoordinates, WateringData, WeatherData, WeatherProvider } from "../../types"; import { httpJSONRequest } from "../weather"; async function getDarkSkyWateringData( coordinates: GeoCoordinates ): Promise< WateringData > { - const DARKSKY_API_KEY = process.env.DARKSKY_API_KEY, - forecastUrl = `https://api.darksky.net/forecast/${DARKSKY_API_KEY}/${coordinates[0]},${coordinates[1]}`; + // The Unix timestamp of 24 hours ago. + const timestamp: number = moment().subtract( 1, "day" ).unix(); - let forecast; + const DARKSKY_API_KEY = process.env.DARKSKY_API_KEY, + historicUrl = `https://api.darksky.net/forecast/${DARKSKY_API_KEY}/${coordinates[0]},${coordinates[1]},${timestamp}`; + + let historicData; try { - forecast = await httpJSONRequest( forecastUrl ); + historicData = await httpJSONRequest( historicUrl ); } catch (err) { // Indicate watering data could not be retrieved if an API error occurs. return undefined; } - - let totalTemp = 0, - totalHumidity = 0, - totalPrecip = 0; - - const periods = Math.min( forecast.hourly.data.length, 30 ); - for ( let index = 0; index < periods; index++ ) { - totalTemp += forecast.hourly.data[ index ].temperature; - totalHumidity += forecast.hourly.data[ index ].humidity * 100; - totalPrecip += forecast.hourly.data[ index ].precipIntensity; - } - return { - temp: totalTemp / periods, - humidity: totalHumidity / periods, - precip: totalPrecip, - raining: forecast.currently.precipType === "rain" + // Calculate average temperature for the day using hourly data. + temp : historicData.hourly.data.reduce( ( sum, hourlyData ) => sum + hourlyData.temperature, 0 ) / historicData.hourly.data.length, + humidity: historicData.daily.data[ 0 ].humidity * 100, + precip: historicData.daily.data[ 0 ].precipIntensity * 24, + raining: historicData.currently.precipType === "rain" }; } diff --git a/types.ts b/types.ts index ba856ea..5f94ab5 100644 --- a/types.ts +++ b/types.ts @@ -48,14 +48,19 @@ export interface WeatherDataForecast { description: string; } +/** + * Data from a 24 hour window that is used to calculate how watering levels should be scaled. This should ideally use + * historic data from the past day, but may also use forecasted data for the next day if historical data is not + * available. + */ export interface WateringData { - /** The average forecasted temperature over the next 30 hours (in Fahrenheit). */ + /** The average temperature over the window (in Fahrenheit). */ temp: number; - /** The average forecasted humidity over the next 30 hours (as a percentage). */ + /** The average humidity over the window (as a percentage). */ humidity: number; - /** The forecasted total precipitation over the next 30 hours (in inches). */ + /** The total precipitation over the window (in inches). */ precip: number; - /** A boolean indicating if it is currently raining. */ + /** A boolean indicating if it is raining at the time that this data was retrieved. */ raining: boolean; }