using System; using System.Globalization; using System.Threading.Tasks; using FarmmapsApi.Models; using FarmmapsApi.Services; using FarmmapsNbs.Models; using Microsoft.Extensions.Logging; using static FarmmapsApi.Extensions; using static FarmmapsApiSamples.Constants; namespace FarmmapsNbs { public class NitrogenService { private readonly ILogger _logger; private readonly FarmmapsApiService _farmmapsApiService; private readonly GeneralService _generalService; public NitrogenService(ILogger logger, FarmmapsApiService farmmapsApiService, GeneralService generalService) { _logger = logger; _farmmapsApiService = farmmapsApiService; _generalService = generalService; } public async Task CreateTargetNItem(Item cropfieldItem) { var itemRequest = new ItemRequest() { ParentCode = cropfieldItem.ParentCode, ItemType = USERINPUT_ITEMTYPE, Name = "TargetN" }; return await _farmmapsApiService.CreateItemAsync(itemRequest); } /// /// Calculates TargetN, makes the assumption the cropfield and user.input(targetn) item have the same parent /// /// The cropfield to base the calculations on /// The targetN item to save calculations in /// The date the crop is planted /// The date the measurements are taken /// The crop purpose /// The target yield input for the TargetN calculation /// The TargetN public async Task CalculateTargetN(Item cropfieldItem, Item targetNItem, DateTime plantingDate, DateTime measurementDate, string purposeType, int targetYield) { var nbsTargetNRequest = new TaskRequest {TaskType = VRANBS_TASK}; nbsTargetNRequest.attributes["operation"] = "targetn"; nbsTargetNRequest.attributes["inputCode"] = targetNItem.Code; nbsTargetNRequest.attributes["plantingDate"] = plantingDate.ToString("o"); nbsTargetNRequest.attributes["measurementDate"] = measurementDate.ToString("o"); nbsTargetNRequest.attributes["purposeType"] = purposeType.ToLower(); nbsTargetNRequest.attributes["targetYield"] = targetYield.ToString(); string itemTaskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, nbsTargetNRequest); await PollTask(TimeSpan.FromSeconds(3), async (tokenSource) => { var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode); if (itemTaskStatus.IsFinished) tokenSource.Cancel(); }); var itemTask = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode); if(itemTask.State == ItemTaskState.Error) { _logger.LogError($"Something went wrong with task execution: {itemTask.Message}"); return null; } var item = await _farmmapsApiService.GetItemAsync(targetNItem.Code); return item.Data.ToObject(); } /// /// Calculates the uptake map based on the given inputs /// /// The cropfield to base the calculations on /// /// The date the crop is planted /// The date the measurements are taken /// Data type, could be yara, ci, irmi or wdvi /// Column name in which the sensor value is stored /// public async Task CalculateUptakeMap(Item cropfieldItem, Item inputItem, DateTime plantingDate, DateTime measurementDate, string inputType, string inputLayerName) { var nbsUptakeMapRequest = new TaskRequest {TaskType = VRANBS_TASK}; nbsUptakeMapRequest.attributes["operation"] = "uptake"; nbsUptakeMapRequest.attributes["inputCode"] = inputItem.Code; nbsUptakeMapRequest.attributes["plantingDate"] = plantingDate.ToString("o"); nbsUptakeMapRequest.attributes["measurementDate"] = measurementDate.ToString("o"); nbsUptakeMapRequest.attributes["inputType"] = inputType.ToLower(); if (!(string.IsNullOrEmpty(inputLayerName))) nbsUptakeMapRequest.attributes["inputLayerName"] = inputLayerName; //toevoeging FS. Kolom IRMI hernoemd als IMI. Deze wordt niet automatisch herkend. En moet dus gespecificeerd worden. string itemTaskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, nbsUptakeMapRequest); await PollTask(TimeSpan.FromSeconds(5), async (tokenSource) => { var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode); _logger.LogInformation($"Calculating uptake map; status: {itemTaskStatus.State}"); if (itemTaskStatus.IsFinished) tokenSource.Cancel(); }); var itemTask = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode); if (itemTask.State == ItemTaskState.Error) { _logger.LogError($"Something went wrong with task execution: {itemTask.Message}"); return null; } var itemName = "VRANbs uptake"; var uptakeMapItem = await _generalService.FindChildItemAsync(cropfieldItem.Code, GEOTIFF_PROCESSED_ITEMTYPE, itemName, i => i.Updated >= itemTask.Finished.GetValueOrDefault(DateTime.UtcNow) && i.Name.ToLower().Contains(itemName.ToLower())); if (uptakeMapItem == null) { _logger.LogError("Could not find the uptake geotiff child item under cropfield"); return null; } return uptakeMapItem; } /// /// Creates the nitrogen application map based on given input data /// /// The cropfield to base the calculations on /// The farmmaps item containing the geotiff data /// The date the crop is planted /// The date the measurements are taken /// The inputtype to use, could be yara, ci, irmi or wdvi /// The target nitrogen to use for the calculations /// public async Task CalculateApplicationMap(Item cropfieldItem, Item inputItem, DateTime plantingDate, DateTime measurementDate, string inputType, double targetN, string inputLayerName) { var nbsApplicationMapRequest = new TaskRequest {TaskType = VRANBS_TASK}; nbsApplicationMapRequest.attributes["operation"] = "application"; nbsApplicationMapRequest.attributes["inputCode"] = inputItem.Code; nbsApplicationMapRequest.attributes["plantingDate"] = plantingDate.ToString("o"); nbsApplicationMapRequest.attributes["measurementDate"] = measurementDate.ToString("o"); nbsApplicationMapRequest.attributes["inputCode"] = inputItem.Code; nbsApplicationMapRequest.attributes["inputType"] = inputType.ToLower(); nbsApplicationMapRequest.attributes["targetN"] = targetN.ToString(CultureInfo.InvariantCulture); if (!(string.IsNullOrEmpty(inputLayerName))) nbsApplicationMapRequest.attributes["inputLayerName"] = inputLayerName; string itemTaskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, nbsApplicationMapRequest); await PollTask(TimeSpan.FromSeconds(5), async (tokenSource) => { var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode); _logger.LogInformation($"Calculating application map; status: {itemTaskStatus.State}"); if (itemTaskStatus.IsFinished) tokenSource.Cancel(); }); var itemTask = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode); if(itemTask.State == ItemTaskState.Error) { _logger.LogError($"Something went wrong with task execution: {itemTask.Message}"); return null; } var itemName = $"VRANbs application"; var applicationMapItem = await _generalService.FindChildItemAsync(cropfieldItem.Code, GEOTIFF_PROCESSED_ITEMTYPE, itemName, i => i.Updated >= itemTask.Finished.GetValueOrDefault(DateTime.UtcNow) && i.Name.ToLower().Contains(itemName.ToLower())); if (applicationMapItem == null) { _logger.LogError("Could not find the application map geotiff child item under cropfield"); return null; } return applicationMapItem; } } }