diff --git a/routes/weather.ts b/routes/weather.ts index dc15a5b..7fa9497 100644 --- a/routes/weather.ts +++ b/routes/weather.ts @@ -5,7 +5,6 @@ import * as SunCalc from "suncalc"; import * as moment from "moment-timezone"; import * as geoTZ from "geo-tz"; -import * as local from "./local"; import { AdjustmentOptions, GeoCoordinates, TimeData, WateringData, WeatherData, WeatherProvider } from "../types"; import CompositeWeatherProvider from "./weatherProviders/CompositeWeatherProvider"; @@ -87,16 +86,6 @@ export async function httpJSONRequest(url: string ): Promise< any > { } } -/** - * Retrieves weather data necessary for watering level calculations from the a local record. - * @param coordinates The coordinates to retrieve the watering data for. - * @return A Promise that will be resolved with WateringData. - */ -async function getLocalWateringData( coordinates: GeoCoordinates ): Promise< WateringData > { - // TODO is this type assertion safe? - return local.getLocalWeather() as WateringData; -} - /** * Calculates timezone and sunrise/sunset for the specified coordinates. * @param coordinates The coordinates to use to calculate time data. @@ -262,12 +251,7 @@ export const getWateringData = async function( req: express.Request, res: expres // Continue with the weather request let timeData: TimeData = getTimeData( coordinates ); - let wateringData: WateringData; - if ( local.useLocalWeather() ) { - wateringData = await getLocalWateringData( coordinates ); - } else { - wateringData = await weatherProvider.getWateringData(coordinates); - } + let wateringData: WateringData = await weatherProvider.getWateringData(coordinates); // Process data to retrieve the resulting scale, sunrise/sunset, timezone, @@ -327,7 +311,9 @@ export const getWateringData = async function( req: express.Request, res: expres } }; - if ( local.useLocalWeather() ) { + /* Note: The local WeatherProvider will never return undefined, so there's no need to worry about this condition + failing to be met if the local WeatherProvider is used but wateringData is falsy (since it will never happen). */ + if ( wateringData && wateringData.weatherProvider === "local" ) { console.log( "OpenSprinkler Weather Response: %s", JSON.stringify( data ) ); } diff --git a/routes/local.ts b/routes/weatherProviders/local.ts similarity index 72% rename from routes/local.ts rename to routes/weatherProviders/local.ts index e9f0333..314df1c 100644 --- a/routes/local.ts +++ b/routes/weatherProviders/local.ts @@ -1,5 +1,6 @@ import * as express from "express"; import { CronJob } from "cron"; +import { GeoCoordinates, WateringData, WeatherProvider } from "../../types"; const count = { temp: 0, humidity: 0 }; @@ -42,25 +43,20 @@ export const captureWUStream = function( req: express.Request, res: express.Resp res.send( "success\n" ); }; -export const useLocalWeather = function(): boolean { - return process.env.PWS ? true : false; -}; - -export const getLocalWeather = function(): LocalWeather { - const result: LocalWeather = {}; - - // Use today's weather if we dont have information for yesterday yet (i.e. on startup) - Object.assign( result, today, yesterday); +export const getLocalWateringData = function(): WateringData { + const result: WateringData = { + ...yesterday as WateringData, + // Use today's weather if we dont have information for yesterday yet (i.e. on startup) + ...today, + // PWS report "buckets" so consider it still raining if last bucket was less than an hour ago + raining: last_bucket !== undefined ? ( ( Date.now() - +last_bucket ) / 1000 / 60 / 60 < 1 ) : undefined, + weatherProvider: "local" + }; if ( "precip" in yesterday && "precip" in today ) { result.precip = yesterday.precip + today.precip; } - // PWS report "buckets" so consider it still raining if last bucket was less than an hour ago - if ( last_bucket !== undefined ) { - result.raining = ( ( Date.now() - +last_bucket ) / 1000 / 60 / 60 < 1 ); - } - return result; }; @@ -79,6 +75,9 @@ interface PWSStatus { precip?: number; } -export interface LocalWeather extends PWSStatus { - raining?: boolean; -} +const LocalWeatherProvider: WeatherProvider = { + getWateringData: async function ( coordinates: GeoCoordinates ) { + return getLocalWateringData(); + } +}; +export default LocalWeatherProvider; diff --git a/server.ts b/server.ts index 15c8761..493dc70 100644 --- a/server.ts +++ b/server.ts @@ -5,7 +5,7 @@ import * as express from "express"; import * as cors from "cors"; import * as weather from "./routes/weather"; -import * as local from "./routes/local"; +import * as local from "./routes/weatherProviders/local"; let host = process.env.HOST || "127.0.0.1", port = parseInt( process.env.PORT ) || 3000; diff --git a/types.ts b/types.ts index ada033a..6727935 100644 --- a/types.ts +++ b/types.ts @@ -92,7 +92,7 @@ export interface WeatherProvider { * @return A Promise that will be resolved with the WateringData if it is successfully retrieved, * or resolved with undefined if an error occurs while retrieving the WateringData. */ - getWateringData( coordinates : GeoCoordinates ): Promise< WateringData >; + getWateringData?( coordinates : GeoCoordinates ): Promise< WateringData >; /** * Retrieves the current weather data for usage in the mobile app. @@ -100,7 +100,7 @@ export interface WeatherProvider { * @return A Promise that will be resolved with the WeatherData if it is successfully retrieved, * or resolved with undefined if an error occurs while retrieving the WeatherData. */ - getWeatherData( coordinates : GeoCoordinates ): Promise< WeatherData >; + getWeatherData?( coordinates : GeoCoordinates ): Promise< WeatherData >; } -export type WeatherProviderId = "OWM" | "DarkSky"; +export type WeatherProviderId = "OWM" | "DarkSky" | "local";