From 2d588026e24c1d76f16b8fdd4a9f756c873c96c3 Mon Sep 17 00:00:00 2001 From: Pepijn van Oort Date: Mon, 16 Oct 2023 15:34:07 +0200 Subject: [PATCH] also write totalNapplied to csv file with KPI outputs per cropfield --- FarmmapsApi/Services/GeneralService.cs | 19 ++++ FarmmapsKPI/KPIApplication.cs | 26 +++++ FarmmapsKPI/KPIInput.json | 152 ++++++++++++++++++++++++- FarmmapsKPI/KPIdefinitions.csv | 1 + 4 files changed, 195 insertions(+), 3 deletions(-) diff --git a/FarmmapsApi/Services/GeneralService.cs b/FarmmapsApi/Services/GeneralService.cs index 6b452a0..d95380c 100644 --- a/FarmmapsApi/Services/GeneralService.cs +++ b/FarmmapsApi/Services/GeneralService.cs @@ -44,6 +44,25 @@ namespace FarmmapsApi.Services var currentYear = new DateTime(year, 1, 1); JObject jdata = JObject.Parse(data); string name = string.Format($"CrpRec Operation, {jdata.GetValue("name")}"); + int code022; + string type022; + double quantity; + double applied_kgNha; + double ncontent = 0.0; // for now just any value + + //Is it a fertilizer application? + + //If the operation contains an element "n" then nothing, use that value (kg N/ha administred) + //Else: look up the N content for the code022, calculate "n" based on fertilizer amount (data) & content (cl022) and add applied_kgNha to the jdata + if (jdata.ContainsKey("n") == false) + { + quantity = jdata.GetValue("quantity").ToObject(); + code022 = jdata.GetValue("product").ToObject(); + //TODO: Now here look up this code022 in the cl022 and get the ncontent from that list. + //And check the unit in which the ncontent is expressed, e.g. % or kg/ton and check if it is not null + applied_kgNha = quantity * ncontent; + jdata.Add("n", applied_kgNha.ToString()); //all Data elements in Farmmaps code ar strings + }; ItemRequest operationItemRequest = new ItemRequest() { diff --git a/FarmmapsKPI/KPIApplication.cs b/FarmmapsKPI/KPIApplication.cs index 6b1eec3..5fec1ad 100644 --- a/FarmmapsKPI/KPIApplication.cs +++ b/FarmmapsKPI/KPIApplication.cs @@ -288,6 +288,32 @@ namespace FarmmapsKPI kpioPrevious = kpio; } + //Total N applied + double totalNapplied = 0.0; + double operationNapplied; + JObject opData; + for (int i = 0; i < crpOperationItemCodes.Count; i++) + { + codeOperation = crpOperationItemCodes[i]; + crpOperationItem = await _farmmapsApiService.GetItemAsync(codeOperation); + operationNapplied = crpOperationItem.Data.GetValue("n").ToObject(); + totalNapplied = totalNapplied + operationNapplied; + } + //Also add totalNapplied to the csv + dataList = new List { }; + //Seems sometimes duplicate KPI items are returned. So check that here and only write if this kpio is different from previous + dataList.Add(kpioPrevious.parentName); + dataList.Add(kpioPrevious.data.area); + dataList.Add(kpioPrevious.data.cropTypeCode); + dataList.Add(kpioPrevious.data.cropTypeName); + dataList.Add(""); + dataList.Add("totalNapplied"); + dataList.Add(totalNapplied.ToString()); + dataList.Add(kpioPrevious.unit); + dataList.Add(""); + dataList.Add(""); + sw.WriteLine(string.Join(",", dataList)); + //Clean up. Only newly created fields //Look up instruction in Swagger / api / v1 / items /{ code} if (useExistingCropfieldWithChildren == false && input.DeleteNewlyCreatedAfterCalc == true) diff --git a/FarmmapsKPI/KPIInput.json b/FarmmapsKPI/KPIInput.json index 46eff35..36922f0 100644 --- a/FarmmapsKPI/KPIInput.json +++ b/FarmmapsKPI/KPIInput.json @@ -64,6 +64,7 @@ }, { "useExistingCropfieldWithChildren": false, + "deleteNewlyCreatedAfterCalc": true, "CropfieldItemCode": "", "dataCropfield": { //"area": 4.22, //not needed for KPI calculation, but shown here to know this is a possible property @@ -85,11 +86,11 @@ "contractor": false, "designator": "Kunstmest strooien", "from": "2022-05-23T11:34:00", - "method": "70400", + "method": "70400", //refers to codelist 127 with operation types "n": "92", "name": "Kunstmest strooien", "operationCode": "7", - "product": "7360", + "product": "7360", //refers to codelist 022 with fertilizer types "quantity": "200", "status": "3", "to": "2022-05-23T12:34:00", @@ -151,6 +152,151 @@ ] ] } + }, + { + "useExistingCropfieldWithChildren": false, + "deleteNewlyCreatedAfterCalc": true, + "CropfieldItemCode": "", + "dataCropfield": { + //"area": 4.22, //not needed for KPI calculation, but shown here to know this is a possible property + "final": true, //always true + //"soilCode": "5", //not needed for KPI calculation, but shown here to know this is a possible property + //"soilName": "Loam", //not needed for KPI calculation, but shown here to know this is a possible property + "cropTypeCode": "1010101", + "cropTypeName": "Potato", + //"rootDepthMax": 45, //not needed for KPI calculation, but shown here to know this is a possible property + //"emergenceDate": "2022-05-16T00:00:00", //not needed for KPI calculation, but shown here to know this is a possible property + "productionPurposeCode": "003" + //"productionPurposeName": "consumption" //not needed for KPI calculation, but shown here to know this is a possible property + }, + "CropRecordingItemCode": "", + "OperationItemCodes": [], + "dataOperations": [ + { + "area": "0.08", //?! + "contractor": false, + "designator": "Kunstmest strooien", + "from": "2022-05-23T11:34:00", + "method": "70400", + "n": "92", + "name": "Kunstmest strooien", + "operationCode": "7", + "product": "7360", + "quantity": "200", + "status": "3", + "to": "2022-05-23T12:34:00", + "unit": "kg/ha", + "unitCode": "KGMHAR" + } + ], + "CropfieldCharacteristicItemCode": "", + "DataCropfieldCharacteristic": { + "code": "860619", //PO20231004: so what does this code mean? Can we see the code list somewhere? + "label": "cropyield", + "value": "48.01" + }, + //"DownloadFolder": "Downloads", //"C:\\hugoschrererdir\\kpidir\\", // "Downloads", -> if you just put "Downloads" the program will download to somewhere in ..\FarmMapsApiClient_WURtest\FarmmapsDataDownload\bin\Debug\netcoreapp3.1\Downloads\ + "CropYear": 2022, + "fieldName": "aardappelveld_test_Potato_Urea92kgNha", + "geometryJson": { + "type": "Polygon", + "coordinates": [ + [ + [ + 5.5945257993548765, + 52.57080744107003 + ], + [ + 5.598645994070678, + 52.571540800206236 + ], + [ + 5.599381743127071, + 52.57012773140724 + ], + [ + 5.595408698222548, + 52.56968054825188 + ], + [ + 5.5945257993548765, + 52.57080744107003 + ] + ] + ] + } + }, + { + "useExistingCropfieldWithChildren": false, + "deleteNewlyCreatedAfterCalc": true, + "CropfieldItemCode": "", + "dataCropfield": { + //"area": 4.22, //not needed for KPI calculation, but shown here to know this is a possible property + "final": true, //always true + //"soilCode": "5", //not needed for KPI calculation, but shown here to know this is a possible property + //"soilName": "Loam", //not needed for KPI calculation, but shown here to know this is a possible property + "cropTypeCode": "1010101", + "cropTypeName": "Potato", + //"rootDepthMax": 45, //not needed for KPI calculation, but shown here to know this is a possible property + //"emergenceDate": "2022-05-16T00:00:00", //not needed for KPI calculation, but shown here to know this is a possible property + "productionPurposeCode": "003" + //"productionPurposeName": "consumption" //not needed for KPI calculation, but shown here to know this is a possible property + }, + "CropRecordingItemCode": "", + "OperationItemCodes": [], + "dataOperations": [ + { + "area": "0.08", //?! + "contractor": false, + "designator": "Kunstmest strooien", + "from": "2022-05-23T11:34:00", + "method": "70400", + //"n": "92", + "name": "Kunstmest strooien", + "operationCode": "7", + "product": "7360", + "quantity": "200", + "status": "3", + "to": "2022-05-23T12:34:00", + "unit": "kg/ha", + "unitCode": "KGMHAR" + } + ], + "CropfieldCharacteristicItemCode": "", + "DataCropfieldCharacteristic": { + "code": "860619", //PO20231004: so what does this code mean? Can we see the code list somewhere? + "label": "cropyield", + "value": "48.01" + }, + //"DownloadFolder": "Downloads", //"C:\\hugoschrererdir\\kpidir\\", // "Downloads", -> if you just put "Downloads" the program will download to somewhere in ..\FarmMapsApiClient_WURtest\FarmmapsDataDownload\bin\Debug\netcoreapp3.1\Downloads\ + "CropYear": 2022, + "fieldName": "aardappelveld_test_Potato_Urea200kgha", + "geometryJson": { + "type": "Polygon", + "coordinates": [ + [ + [ + 5.5945257993548765, + 52.57080744107003 + ], + [ + 5.598645994070678, + 52.571540800206236 + ], + [ + 5.599381743127071, + 52.57012773140724 + ], + [ + 5.595408698222548, + 52.56968054825188 + ], + [ + 5.5945257993548765, + 52.57080744107003 + ] + ] + ] + } } - ] \ No newline at end of file diff --git a/FarmmapsKPI/KPIdefinitions.csv b/FarmmapsKPI/KPIdefinitions.csv index 5d31cae..b82cbc5 100644 --- a/FarmmapsKPI/KPIdefinitions.csv +++ b/FarmmapsKPI/KPIdefinitions.csv @@ -6,3 +6,4 @@ C1,organic matter supply,Organic matter surplus = Organic matter from manure + C D1,pesticides,? ,KPItargetvalue,target value as in benchmark value for same crop in same region ,KPIthresholdValue,threshold from ??? Ask farmmaps. Surplus nitrogen / phosphate / pesticides must not be above threshold. Surplus organic matter supply must be above threshold +,totalNapplied,"Not a KPI output, simply calculated from the input operations with their respective ""n"" in their ""data"""