Refactor watering scale logic flow

This commit is contained in:
Matthew Oslan
2019-06-28 00:33:00 -04:00
parent 95dadf601d
commit dc171ebe68
11 changed files with 70 additions and 50 deletions

View File

@@ -1,4 +1,4 @@
import { GeoCoordinates, WateringData } from "../../types";
import { BaseWateringData, GeoCoordinates } from "../../types";
import { WeatherProvider } from "../weatherProviders/WeatherProvider";
@@ -7,10 +7,8 @@ export interface AdjustmentMethod {
* Calculates the percentage that should be used to scale watering time.
* @param adjustmentOptions The user-specified options for the calculation. No checks will be made to ensure the
* AdjustmentOptions are the correct type that the function is expecting or to ensure that any of its fields are valid.
* @param wateringData The basic weather information of the watering site. This may be undefined if an error occurred
* while retrieving the data.
* @param coordinates The coordinates of the watering site.
* @param weatherProvider The WeatherProvider that should be used if the adjustment method needs to obtain any more
* @param weatherProvider The WeatherProvider that should be used if the adjustment method needs to obtain any
* weather data.
* @return A Promise that will be resolved with the result of the calculation, or rejected with an error message if
* the watering scale cannot be calculated.
@@ -18,7 +16,6 @@ export interface AdjustmentMethod {
*/
calculateWateringScale(
adjustmentOptions: AdjustmentOptions,
wateringData: WateringData | undefined,
coordinates: GeoCoordinates,
weatherProvider: WeatherProvider
): Promise< AdjustmentMethodResponse >;
@@ -52,6 +49,8 @@ export interface AdjustmentMethodResponse {
* user-configured watering scale instead of using the one returned by the AdjustmentMethod.
*/
errorMessage?: string;
/** The data that was used to calculate the watering scale, or undefined if no data was used. */
wateringData: BaseWateringData;
}
export interface AdjustmentOptions {}

View File

@@ -6,7 +6,8 @@ import { AdjustmentMethod, AdjustmentMethodResponse } from "./AdjustmentMethod";
*/
async function calculateManualWateringScale( ): Promise< AdjustmentMethodResponse > {
return {
scale: undefined
scale: undefined,
wateringData: undefined
}
}

View File

@@ -1,17 +1,20 @@
import { AdjustmentMethod, AdjustmentMethodResponse, AdjustmentOptions } from "./AdjustmentMethod";
import { WateringData } from "../../types";
import { GeoCoordinates, ZimmermanWateringData } from "../../types";
import { WeatherProvider } from "../weatherProviders/WeatherProvider";
/**
* Only delays watering if it is currently raining and does not adjust the watering scale.
*/
async function calculateRainDelayWateringScale( adjustmentOptions: RainDelayAdjustmentOptions, wateringData: WateringData | undefined ): Promise< AdjustmentMethodResponse > {
async function calculateRainDelayWateringScale( adjustmentOptions: RainDelayAdjustmentOptions, coordinates: GeoCoordinates, weatherProvider: WeatherProvider ): Promise< AdjustmentMethodResponse > {
const wateringData: ZimmermanWateringData = await weatherProvider.getWateringData( coordinates );
const raining = wateringData && wateringData.raining;
const d = adjustmentOptions.hasOwnProperty( "d" ) ? adjustmentOptions.d : 24;
return {
scale: undefined,
rawData: { raining: raining ? 1 : 0 },
rainDelay: raining ? d : undefined
rainDelay: raining ? d : undefined,
wateringData: wateringData
}
}

View File

@@ -1,13 +1,15 @@
import { AdjustmentMethod, AdjustmentMethodResponse, AdjustmentOptions } from "./AdjustmentMethod";
import { WateringData } from "../../types";
import { GeoCoordinates, ZimmermanWateringData } from "../../types";
import { validateValues } from "../weather";
import { WeatherProvider } from "../weatherProviders/WeatherProvider";
/**
* Calculates how much watering should be scaled based on weather and adjustment options using the Zimmerman method.
* (https://github.com/rszimm/sprinklers_pi/wiki/Weather-adjustments#formula-for-setting-the-scale)
*/
async function calculateZimmermanWateringScale( adjustmentOptions: ZimmermanAdjustmentOptions, wateringData: WateringData | undefined ): Promise< AdjustmentMethodResponse > {
async function calculateZimmermanWateringScale( adjustmentOptions: ZimmermanAdjustmentOptions, coordinates: GeoCoordinates, weatherProvider: WeatherProvider ): Promise< AdjustmentMethodResponse > {
const wateringData: ZimmermanWateringData = await weatherProvider.getWateringData( coordinates );
// Temporarily disabled since OWM forecast data is checking if rain is forecasted for 3 hours in the future.
/*
@@ -15,7 +17,8 @@ async function calculateZimmermanWateringScale( adjustmentOptions: ZimmermanAdju
if ( wateringData && wateringData.raining ) {
return {
scale: 0,
rawData: { raining: 1 }
rawData: { raining: 1 },
wateringData: wateringData
}
}
*/
@@ -33,7 +36,8 @@ async function calculateZimmermanWateringScale( adjustmentOptions: ZimmermanAdju
return {
scale: 100,
rawData: rawData,
errorMessage: "Necessary field(s) were missing from WateringData."
errorMessage: "Necessary field(s) were missing from ZimmermanWateringData.",
wateringData: wateringData
};
}
@@ -64,7 +68,8 @@ async function calculateZimmermanWateringScale( adjustmentOptions: ZimmermanAdju
return {
// Apply all of the weather modifying factors and clamp the result between 0 and 200%.
scale: Math.floor( Math.min( Math.max( 0, 100 + humidityFactor + tempFactor + precipFactor ), 200 ) ),
rawData: rawData
rawData: rawData,
wateringData: wateringData
}
}