using System; using System.Globalization; using System.Linq; using System.Threading.Tasks; using FarmmapsApi.Models; using FarmmapsApi.Services; using Microsoft.Extensions.Logging; using static FarmmapsApi.Extensions; using static FarmmapsApiSamples.Constants; namespace FarmmapsApiSamples { public class NitrogenService { private readonly ILogger _logger; private readonly FarmmapsApiService _farmmapsApiService; public NitrogenService(ILogger logger, FarmmapsApiService farmmapsApiService) { _logger = logger; _farmmapsApiService = farmmapsApiService; } /// /// Calculates TargetN, makes the assumption the cropfield and user.input(targetn) item have the same parent /// /// The cropfield to base the calculations on /// The target yield input for the TargetN calculation /// The TargetN public async Task CalculateTargetN(Item cropfieldItem, int targetYield) { var targetNItems = await _farmmapsApiService.GetItemChildrenAsync(cropfieldItem.ParentCode, USERINPUT_ITEMTYPE); Item targetNItem; if (targetNItems.Count == 0) { _logger.LogInformation("Creating targetN item"); var itemRequest = CreateTargetNItemRequest(cropfieldItem.ParentCode); targetNItem = await _farmmapsApiService.CreateItemAsync(itemRequest); } else { targetNItem = targetNItems[0]; } var nbsTargetNRequest = new TaskRequest {TaskType = VRANBS_TASK}; nbsTargetNRequest.attributes["operation"] = "targetn"; nbsTargetNRequest.attributes["inputCode"] = targetNItem.Code; nbsTargetNRequest.attributes["inputType"] = "irmi"; nbsTargetNRequest.attributes["purposeType"] = "consumption"; 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.State != ItemTaskState.Processing && itemTaskStatus.State != ItemTaskState.Scheduled) 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 0; } var item = await _farmmapsApiService.GetItemAsync(targetNItem.Code); if (item.Data.ContainsKey("TargetN")) return item.Data.Value("TargetN"); return 0; } public async Task CalculateNitrogenMap(Item cropfieldItem, Item inputItem, double targetN) { var nbsNitrogenRequest = new TaskRequest {TaskType = VRANBS_TASK}; nbsNitrogenRequest.attributes["operation"] = "nitrogen"; nbsNitrogenRequest.attributes["inputCode"] = inputItem.Code; nbsNitrogenRequest.attributes["inputType"] = "irmi"; nbsNitrogenRequest.attributes["targetN"] = targetN.ToString(CultureInfo.InvariantCulture); string itemTaskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, nbsNitrogenRequest); await PollTask(TimeSpan.FromSeconds(5), async (tokenSource) => { var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, itemTaskCode); if (itemTaskStatus.State != ItemTaskState.Processing && itemTaskStatus.State != ItemTaskState.Scheduled) 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 geotiffItems = await _farmmapsApiService.GetItemChildrenAsync(cropfieldItem.Code, GEOTIFF_ITEMTYPE); // how to uniquely know which item is really created!? var nitrogenItem = geotiffItems.SingleOrDefault(i => i.Name.Contains("nitrogen")); if (nitrogenItem == null) { _logger.LogError("Could not find the nitrogen geotiff child item under cropfield"); return null; } return nitrogenItem; } private ItemRequest CreateTargetNItemRequest(string parentItemCode) { return new ItemRequest() { ParentCode = parentItemCode, ItemType = USERINPUT_ITEMTYPE, Name = "TargetN", DataDate = DateTime.UtcNow }; } } }