GDD APS
The example Python source code is meant merely as a starting point to quickly interact and retrieve insights from ADMA. It is in no way intended for production workloads.
Overview
Once you have successfully created a Party
, Farm
and Field
, you are ready to execute the additional provided
examples.
Now that we have the needed entities created, we can use the GDD service. This is a
four-step process. These four steps have been captured and automated in tutorial/example/gdd.py
included in the downloadable tutorial zipfile.
Background
This example calculates growing degree days (GDD). GDD is an indicator of crop development based on weather conditions. Specifically, it accounts for heat accumulation.
The GDD service supports the following crops: canola, corn, cotton, sugar beet, soybean, and winter wheat.
The example assumes not all HTTP calls are successful and performs up to five retries for the following HTTP status codes: 429, 502, 503, 504.
GDD Processing
Approach
The example, tutorial.example.gdd
, uses the following approach. Note that this approach is for demonstration
purposes only.
- Given a
Party
,Field
, starting date, a range of days, and crop, attempt to generate GDD for each day while keeping a cumulative sum.
Logging
Due to the nature of this example, logging was enabled. The logging is configured to log to stdout in JSON
format, ensure that the timestamp is in ISO 8601 using the UTC time zone, and is backed by a queue. The log
configuration file is resource/logging.yml
and all logging code exists in tutorial/util/logging.py
.
Job IDs
In this example, job ids are generated using the following snippet. While this is sufficient for a first run, each separate request to the GDD service must have a unique job id, or you will receive an error like the one below the snippet.
job_id = f'{gdd_date.isoformat()}-{crop}'
Error for 2023-08-01-canola
{ "error": {
"code": "Conflict",
"message": "GDD-04103: Job JobId [https://dfs-fb-prod-instance.farmbeats.azure.net/, 2023-08-01-canola] already exists."
},
"traceId": "4c1add25c8075d86e9b09cb73405fed3"
}
So a potential workaround for this issue is to provide a suffix to the generated job ids, but this may not be sufficient for your use case.
job_id = f'{gdd_date.isoformat()}-{crop}-{number:03d}'
Whatever your use case, keep in mind that you will need to keep track of these job ids for subsequent requests to the GDD service and for retrieving the generated insight(s).
Additional Details
Before we execute the command, a little explanation is in order. A new directory will be created in the root of
the adma
directory named output
. Within the output directory, the following directory structure will be
created: party_id/resource_id/solution_id. This directory will hold log files of submitted requests and
subsequent responses. In the following example the log file is named 2023-08-01-canola.txt
. This directory
will also hold the generated insight(s). In the following example, the calculated GDD values are included in the file
name GDD-2023-08-01-2023-08-31-canola.json
.
Output Directory Structure
output
└── 551c7fb3-8b9c-4b5c-8ecc-d6830325ce12
└── b159f824-4d12-4b40-aa38-b98f0c876edf
└── bayerAgPowered.gdd
├── GDD-2023-08-01-2023-08-31-canola.json
├── GDD-2023-08-01-canola.txt
├── ...
└── GDD-2023-08-31-canola.txt
A sample output from this example may be downloaded as gdd-output.
E.g.
{
"temperature_unit": "C",
"gdd_measurements": [
{
"date": "2023-08-01",
"daily_contribution": 16.0,
"cumulative_sum": 16.0
},
{
"date": "2023-08-02",
"daily_contribution": 17.0,
"cumulative_sum": 33.0
}
]
}
Generate GDD
Note that you will need to modify lines 172-176 in tutorial/example/gdd.py
to change the number_of_days,
start_date, crop, and add the UUID of the Party
and Field
in order to generate and retrieve the insights.
Note this command will take a while to complete. You may want to limit the number of days for it to complete sooner.
Note there is a secondary Python file tutorial/example/concurrent/gdd.py
that works very similarly but executes GDD
in a concurrent manner. This will execute in a much more timely manner.
python -m tutorial.example.gdd