/// <summary> /// Execute the freezing algorithme depending on the forecast weather. /// It return a FreezeForcast object which contains /// a dictionnary of DateTime,FreezingProbability /// There is four levels of probability : /// ZERO = 0% of freezing /// LOW = The probability of freeze is under 50% /// MEDIUM = The probability of freezing is between 50% and 80% /// HIGH = The probability of freezing is greater than 80% /// IMMINENT = The probability of freezing is 100% /// </summary> /// <param name="device">Device telemetry with temperature in Celsius</param> /// <param name="devicePosition"></param> /// <param name="currentWeather">Weather with temperature in Celsius</param> /// <param name="forecast">Forecast weather with temperature in Celsius</param> /// <param name="forecastStation"></param> /// <returns></returns> public async Task <FreezeForecast> Execute(IWeather device, IStationPosition devicePosition, IWeather currentWeather, IEnumerable <IWeather> forecast, IStationPosition forecastStation) { if (!forecast.Any()) { return(null); } try { FreezeForecast freezeForecast = new FreezeForecast(); double deviceTemperature = device.Temperature; double estimateDeviceTemperature = await EstimateWeatherByAltitudeDiff(deviceTemperature, forecastStation, devicePosition); if (estimateDeviceTemperature == 0.0) { estimateDeviceTemperature = 1; } if (currentWeather.Humidity == 0.0) { // to force the coef to be 1 currentWeather.Humidity = device.Humidity; } double coefTemperature = Math.Abs(device.Temperature / estimateDeviceTemperature); double coefHumidity = Math.Abs(device.Humidity / currentWeather.Humidity); logger.Info($"coef temp. : {coefTemperature}"); logger.Info($"coef hum. : {coefHumidity}"); IWeather theoricWeather = Activator.CreateInstance(device.GetType()) as IWeather; theoricWeather.Temperature = coefTemperature * estimateDeviceTemperature; theoricWeather.Humidity = coefHumidity * currentWeather.Humidity; freezeForecast.FreezingProbabilityList[currentWeather.Date] = GetProbabilityFreezing(theoricWeather); IEnumerable <IWeather> forecastEstimation = await EstimateWeatherByAltitudeDiffForecast(forecast, forecastStation, devicePosition); int i = 0; IWeather forecastItem; IWeather estimationWeather; // while not out of range while (i < forecast.Count() || i < forecastEstimation.Count()) { forecastItem = forecast.ElementAt(i); estimationWeather = forecastEstimation.ElementAt(i); theoricWeather.Temperature = coefTemperature * estimationWeather.Temperature; theoricWeather.Humidity = coefHumidity * forecastItem.Humidity; freezeForecast.FreezingProbabilityList[forecastItem.Date] = GetProbabilityFreezing(theoricWeather); i++; } StringBuilder logBuilder = new StringBuilder(); logBuilder.Append($"Freeze probabibility {FreezingProbability.ZERO.ToString()} : {freezeForecast.FreezingProbabilityList.Count(e => e.Value == FreezingProbability.ZERO)}"); logBuilder.Append(" / "); logBuilder.Append($"Freeze probabibility {FreezingProbability.MINIMUM.ToString()} : {freezeForecast.FreezingProbabilityList.Count(e => e.Value == FreezingProbability.MINIMUM)}"); logBuilder.Append(" / "); logBuilder.Append($"Freeze probabibility {FreezingProbability.MEDIUM.ToString()} : {freezeForecast.FreezingProbabilityList.Count(e => e.Value == FreezingProbability.MEDIUM)}"); logBuilder.Append(" / "); logBuilder.Append($"Freeze probabibility {FreezingProbability.HIGH.ToString()} : {freezeForecast.FreezingProbabilityList.Count(e => e.Value == FreezingProbability.HIGH)}"); logBuilder.Append(" / "); logBuilder.Append($"Freeze probabibility {FreezingProbability.IMMINENT.ToString()} : {freezeForecast.FreezingProbabilityList.Count(e => e.Value == FreezingProbability.IMMINENT)}"); logger.Info(logBuilder.ToString()); freezeForecast.FreezingStart = forecast.OrderBy(e => e.Date).FirstOrDefault().Date; freezeForecast.FreezingEnd = forecast.OrderBy(e => e.Date).LastOrDefault().Date; return(freezeForecast); } catch (Exception e) { logger.Error($"Error occured on executing algorithme", e); throw new AlgorithmeException("Error occured on executing algorithme", e); } }