private static async Task <WTPowerResultSet> getPredictedPower(WTPowerRequestInfo predictionInputs, Boolean allInfo = false) { DMResultInfo PredictionPowerDMSet = await MlApi.GetPowerAsync(predictionInputs.PowerInputs); float[] PredictionPowerPMSet = await PmAPI.GetPowerAsync(predictionInputs.PowerInputs); WTPowerResultSet results; int iterator = 0; if (allInfo) { results = new WTPowerResultSet { powerForecastResults = new List <WTPowerForecastResult>() }; } else { results = new WTPowerResultSet { powerResults = new List <WTPowerResult>() }; } foreach (WTInfo powerInfo in predictionInputs.PowerInputs) { if (allInfo) { results.powerForecastResults.Add(new WTPowerForecastResult { OriginSysTime = powerInfo.OriginSysTime, Power_DM = (float)PredictionPowerDMSet.result[iterator], Power_PM = (float)PredictionPowerPMSet[iterator], WindDir = powerInfo.WindDir, WindSpeed = powerInfo.WindSpeed, YawPosition = powerInfo.YawPosition }); } else { results.powerResults.Add(new WTPowerResult { OriginSysTime = powerInfo.OriginSysTime, Power_DM = (float)PredictionPowerDMSet.result[iterator], Power_PM = (float)PredictionPowerPMSet[iterator], }); } ++iterator; } return(results); }
public static async Task <IActionResult> HttpTriggerPrediction( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("Power Prediction HTTP trigger function processed a request."); try { // We'll check if there's a body first - prioritize manual prediction string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); if (requestBody.Length > 0) { // Manual request test, Example request body: /* * { * "PowerInputs": [{ * "Blade1PitchPosition": 1.99, * "Blade2PitchPosition": 2.02, * "Blade3PitchPosition": 1.92, * "OriginSysTime": "7/29/2018 11:43:00", * "WindDir": -8.6, * "WindSpeed": 6.66, * "YawPosition": 5.05 * },{ * "Blade1PitchPosition": 3.1, * "Blade2PitchPosition": 2.1, * "Blade3PitchPosition": 1.2, * "OriginSysTime": "7/29/2018 11:43:01", * "WindDir": -8.6, * "WindSpeed": 6.66, * "YawPosition": 5.05 * }] * } */ WTPowerRequestInfo data = JsonConvert.DeserializeObject <WTPowerRequestInfo>(requestBody); WTPowerResultSet manualPowerResults = await getPredictedPower(data); return((ActionResult) new OkObjectResult(manualPowerResults)); } // If no body is present, assume prediction for next day. else { using (HttpClient client = new HttpClient()) { HttpResponseMessage response = await client.GetAsync("http://iot-model-api.koreacentral.azurecontainer.io/api/predictiondata"); if (response.IsSuccessStatusCode) { IDictionary <string, string> urlParams = req.GetQueryParameterDictionary(); int steps = interpolationSteps; if (urlParams.ContainsKey("steps")) { // Let's keep steps to a low number to avoid too much data. if (steps > 0 && steps <= 50) { steps = Int32.Parse(urlParams["steps"]); } } string result = await response.Content.ReadAsStringAsync(); // Example data. /* * string predictionRequest = "[" + * " {'forecastDateTime':'" + tomorrow + "T00:00:00','windspeed':5.9,'winddirection':-1,'yawposition':-131.48,'bladepitch1':2,'bladepitch2':2,'bladepitch3':2}," + * " {'forecastDateTime':'" + tomorrow + "T03:00:00','windspeed':6.8,'winddirection':3,'yawposition':-109.37,'bladepitch1':2,'bladepitch2':2,'bladepitch3':2}," + * " {'forecastDateTime':'" + tomorrow + "T06:00:00','windspeed':6.3,'winddirection':5,'yawposition':-104.41,'bladepitch1':2,'bladepitch2':2,'bladepitch3':2}," + * " {'forecastDateTime':'" + tomorrow + "T09:00:00','windspeed':5.9,'winddirection':5,'yawposition':-104.41,'bladepitch1':2,'bladepitch2':2,'bladepitch3':2}," + * " {'forecastDateTime':'" + tomorrow + "T12:00:00','windspeed':6.9,'winddirection':2,'yawposition':-109.37,'bladepitch1':2,'bladepitch2':2,'bladepitch3':2}," + * " {'forecastDateTime':'" + tomorrow + "T15:00:00','windspeed':7.1,'winddirection':-4,'yawposition':-131.48,'bladepitch1':2,'bladepitch2':2,'bladepitch3':2}," + * " {'forecastDateTime':'" + tomorrow + "T18:00:00','windspeed':6.8,'winddirection':-4,'yawposition':-131.48,'bladepitch1':2,'bladepitch2':2,'bladepitch3':2}," + * " {'forecastDateTime':'" + tomorrow + "T21:00:00','windspeed':6.8,'winddirection':-3,'yawposition':-131.48,'bladepitch1':2,'bladepitch2':2,'bladepitch3':2}" + * " ]"; */ dynamic forecastData = JsonConvert.DeserializeObject(result); WTPowerRequestInfo predictionInput = new WTPowerRequestInfo { PowerInputs = new List <WTInfo>() }; for (int i = 0; i < forecastData.Count; ++i) { // Interpolation occurs here, we add *interpolationSteps* additional points between each data point. for (int j = 0; j < steps; ++j) { // We only do one step for last data point. if (j > 0 && i == forecastData.Count - 1) { break; } DateTime d1 = DateTime.Parse((string)forecastData[i].forecastDateTime); DateTime interpolatedDate = d1; float yawPositionCurrent = forecastData[i].yawposition; float interpolatedYaw = yawPositionCurrent; float windSpeedCurrent = forecastData[i].windspeed; float interpolatedWindSpeed = windSpeedCurrent; float windDirectionCurrent = forecastData[i].winddirection; float interpolatedWindDirection = windDirectionCurrent; // No data to interpolate to on last data point. if (i != forecastData.Count - 1) { // Date has a unique interpolation. DateTime d2 = DateTime.Parse((string)forecastData[i + 1].forecastDateTime); TimeSpan timeDiff = (d2 - d1); var timeStepDifference = timeDiff / (steps); var minutesElapsed = timeStepDifference * j; interpolatedDate = d1.AddMinutes(minutesElapsed.TotalMinutes); int next = i + 1; float yawPositionNext = forecastData[next].yawposition; interpolatedYaw = interpolateData(yawPositionCurrent, yawPositionNext, j, steps); float windSpeedNext = forecastData[next].windspeed; interpolatedWindSpeed = interpolateData(windSpeedCurrent, windSpeedNext, j, steps); float windDirectionNext = forecastData[next].winddirection; interpolatedWindDirection = interpolateData(windDirectionCurrent, windDirectionNext, j, steps); } // No need to interpolate blade angles since they remain constant. predictionInput.PowerInputs.Add(new WTInfo { Blade1PitchPosition = forecastData[i].bladepitch1, Blade2PitchPosition = forecastData[i].bladepitch2, Blade3PitchPosition = forecastData[i].bladepitch3, OriginSysTime = interpolatedDate.ToString(), WindDir = interpolatedWindDirection, WindSpeed = interpolatedWindSpeed, YawPosition = interpolatedYaw }); } } WTPowerResultSet predictedPowerResults; if (urlParams.ContainsKey("alldata")) { predictedPowerResults = await getPredictedPower(predictionInput, true); return((ActionResult) new OkObjectResult(predictedPowerResults.powerForecastResults)); } else { predictedPowerResults = await getPredictedPower(predictionInput); return((ActionResult) new OkObjectResult(predictedPowerResults.powerResults)); } } else { return(null); // new BadRequestObjectResult(response.Content); } } } } catch (Exception e) { return(new BadRequestObjectResult(e.ToString())); } }