Compare commits

...

No commits in common. "5192ae5356752247c083d0cb0a6dc256c267af5a" and "1863ff393aa07177bd5d8cde3c3bd3ab28c7da71" have entirely different histories.

14 changed files with 1206 additions and 1206 deletions

View File

@ -1,14 +1,14 @@
## Autentication
Farmmaps uses OpenID-connect: https://openid.net/connect/
It is recommended to use a library to facilitate the authentication.
To get the openid configuration call the following url: https://accounts.farmmaps.awtest.nl/.well-known/openid-configuration
The user could also use the openid-configuration to handle authentication by themselves.
https://identitymodel.readthedocs.io/en/latest/native/overview.html
The token received needs to be used in the request header.
>'Authorization': 'bearer {token}'
The token can also easily be created through the swagger documentation:
## Autentication
Farmmaps uses OpenID-connect: https://openid.net/connect/
It is recommended to use a library to facilitate the authentication.
To get the openid configuration call the following url: https://accounts.farmmaps.awtest.nl/.well-known/openid-configuration
The user could also use the openid-configuration to handle authentication by themselves.
https://identitymodel.readthedocs.io/en/latest/native/overview.html
The token received needs to be used in the request header.
>'Authorization': 'bearer {token}'
The token can also easily be created through the swagger documentation:
https://farmmaps.awtest.nl/swagger/index.html

View File

@ -1,132 +1,132 @@
## Create cropfield with the farmmaps API
If there aren't any relevant cropfields in FarmMaps, you can create them yourself by executing the following steps:
* Execute the following REST call to create the 'my_drive' item which contains the needed itemcode:
> Request
```
GET /api/v1/folders/my_drive
```
> Response 200 Succes
```javascript
{
"url": "string",
"code": "string",
"name": "string",
"created": "2019-12-18T09:49:35.741Z",
"updated": "2019-12-18T09:49:35.741Z",
"dataDate": "2019-12-18T09:49:35.741Z",
"itemType": "string",
"sourceTask": "string",
"size": 0,
"state": 0,
"thumbnail": true
}
```
* Create a 'FOLDER' item as a child of the 'my_drive' item.
>Request
```javascript
POST /api/v1/items
{
"parentCode": "{my_drive_code}",
"itemType": "FOLDER",
"name": "string",
"data": {},
"dataDate": "2019-12-18T09:59:18.893Z",
"geometry": {},
"tags": [
"string"
]
}
```
> Response 201 Created
```javascript
{
"parentCode": "string",
"geometry": {},
"data": {},
"tags": [
"string"
],
"url": "string",
"code": "string",
"name": "string",
"created": "2019-12-18T10:16:21.455Z",
"updated": "2019-12-18T10:16:21.455Z",
"dataDate": "2019-12-18T10:16:21.455Z",
"itemType": "string",
"sourceTask": "string",
"size": 0,
"state": 0,
"thumbnail": true
}
```
Response 401 Not authenticated
Response 403 No WRITE permissions in parent item
Response 404 Parent Item not found
* Create a 'vnd.farmmaps.itemtype.cropfield' item as a child of the 'FOLDER' item.
Needs to contain dataDate and dataEndDate to specify cropfield season.
dataDate needs to be before dataEndDate and cannot be the same day.
> Request
```javascript
POST /api/v1/items
{
"parentCode": "{FOLDER_item_code}",
"itemType": "vnd.farmmaps.itemtype.cropfield",
"name": "cropfield for VRA",
"dataDate": "2019-1-18T10:16:21.455Z",
"dataEndDate": "2019-12-18T10:16:21.455Z",
"data": {},
"geometry": {"type":"Polygon","coordinates":[[[6.09942873984307,53.070025028087],[6.09992507404607,53.0705617890585],[6.10036959220086,53.0710679529031],[6.10065149010421,53.0714062774307],[6.10087493644271,53.0716712354474],[6.10091082982487,53.0716936039203],[6.10165087441291,53.0712041549161],[6.10204994718318,53.0709349338005],[6.10263143118855,53.0705789370018],[6.10311578125011,53.0702657538294],[6.10331686552072,53.0701314102389],[6.103326530575,53.070119463569],[6.10309137950343,53.0699829669055],[6.10184241586523,53.0692902201371],[6.10168497998891,53.0691984306747],[6.10092987659869,53.0694894453514],[6.09942873984307,53.070025028087]]]}
}
```
> Response 201 Created
```Javascript
{
"parentCode": "string",
"geometry": {},
"data": {},
"tags": [
"string"
],
"url": "string",
"code": "string",
"name": "string",
"created": "2019-12-18T10:16:21.455Z",
"updated": "2019-12-18T10:16:21.455Z",
"dataDate": "2019-12-18T10:16:21.455Z",
"itemType": "string",
"sourceTask": "string",
"size": 0,
"state": 0,
"thumbnail": true
}
```
* Execute the workflow task with the cropfield item code.
This steps makes sure that FarmMaps aggregates all needed data for the cropfield.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.workflow"
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.workflow",
"delay": "",
"attributes": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
## Create cropfield with the farmmaps API
If there aren't any relevant cropfields in FarmMaps, you can create them yourself by executing the following steps:
* Execute the following REST call to create the 'my_drive' item which contains the needed itemcode:
> Request
```
GET /api/v1/folders/my_drive
```
> Response 200 Succes
```javascript
{
"url": "string",
"code": "string",
"name": "string",
"created": "2019-12-18T09:49:35.741Z",
"updated": "2019-12-18T09:49:35.741Z",
"dataDate": "2019-12-18T09:49:35.741Z",
"itemType": "string",
"sourceTask": "string",
"size": 0,
"state": 0,
"thumbnail": true
}
```
* Create a 'FOLDER' item as a child of the 'my_drive' item.
>Request
```javascript
POST /api/v1/items
{
"parentCode": "{my_drive_code}",
"itemType": "FOLDER",
"name": "string",
"data": {},
"dataDate": "2019-12-18T09:59:18.893Z",
"geometry": {},
"tags": [
"string"
]
}
```
> Response 201 Created
```javascript
{
"parentCode": "string",
"geometry": {},
"data": {},
"tags": [
"string"
],
"url": "string",
"code": "string",
"name": "string",
"created": "2019-12-18T10:16:21.455Z",
"updated": "2019-12-18T10:16:21.455Z",
"dataDate": "2019-12-18T10:16:21.455Z",
"itemType": "string",
"sourceTask": "string",
"size": 0,
"state": 0,
"thumbnail": true
}
```
Response 401 Not authenticated
Response 403 No WRITE permissions in parent item
Response 404 Parent Item not found
* Create a 'vnd.farmmaps.itemtype.cropfield' item as a child of the 'FOLDER' item.
Needs to contain dataDate and dataEndDate to specify cropfield season.
dataDate needs to be before dataEndDate and cannot be the same day.
> Request
```javascript
POST /api/v1/items
{
"parentCode": "{FOLDER_item_code}",
"itemType": "vnd.farmmaps.itemtype.cropfield",
"name": "cropfield for VRA",
"dataDate": "2019-1-18T10:16:21.455Z",
"dataEndDate": "2019-12-18T10:16:21.455Z",
"data": {},
"geometry": {"type":"Polygon","coordinates":[[[6.09942873984307,53.070025028087],[6.09992507404607,53.0705617890585],[6.10036959220086,53.0710679529031],[6.10065149010421,53.0714062774307],[6.10087493644271,53.0716712354474],[6.10091082982487,53.0716936039203],[6.10165087441291,53.0712041549161],[6.10204994718318,53.0709349338005],[6.10263143118855,53.0705789370018],[6.10311578125011,53.0702657538294],[6.10331686552072,53.0701314102389],[6.103326530575,53.070119463569],[6.10309137950343,53.0699829669055],[6.10184241586523,53.0692902201371],[6.10168497998891,53.0691984306747],[6.10092987659869,53.0694894453514],[6.09942873984307,53.070025028087]]]}
}
```
> Response 201 Created
```Javascript
{
"parentCode": "string",
"geometry": {},
"data": {},
"tags": [
"string"
],
"url": "string",
"code": "string",
"name": "string",
"created": "2019-12-18T10:16:21.455Z",
"updated": "2019-12-18T10:16:21.455Z",
"dataDate": "2019-12-18T10:16:21.455Z",
"itemType": "string",
"sourceTask": "string",
"size": 0,
"state": 0,
"thumbnail": true
}
```
* Execute the workflow task with the cropfield item code.
This steps makes sure that FarmMaps aggregates all needed data for the cropfield.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.workflow"
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.workflow",
"delay": "",
"attributes": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found

View File

@ -1,30 +1,30 @@
## Create taskmap
The user can use the "ItemTask" API to execute the TaskmapTask with the item code which contains the tiff data in {code}.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.taskmap"
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.taskmap",
"delay": "",
"attributes": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
## Create taskmap
The user can use the "ItemTask" API to execute the TaskmapTask with the item code which contains the tiff data in {code}.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.taskmap"
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.taskmap",
"delay": "",
"attributes": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
This will create the item with shape data as a sibling of the input item.

View File

@ -1,38 +1,38 @@
## FarmMapsLibs
***-container** types dynamically loads components.
**For FarmMaps Openlayer feature items**
* feature-list
* feature-list-container
* feature-list-feature
* feature-list-feature-container
Examples:
* croppingscheme
* cropfield
**For FarmMaps items details tile/info**
* item-list
* item-list-item-container
* item-list-item
Examples:
* shadow
* height
* bofek
* etc...
**For FarmMaps item details page**
* selected-item
* selected-item-container
Examples:
* cropfield
* geotiff
* shape
**Other**
* item-widget-list
Examples:
## FarmMapsLibs
***-container** types dynamically loads components.
**For FarmMaps Openlayer feature items**
* feature-list
* feature-list-container
* feature-list-feature
* feature-list-feature-container
Examples:
* croppingscheme
* cropfield
**For FarmMaps items details tile/info**
* item-list
* item-list-item-container
* item-list-item
Examples:
* shadow
* height
* bofek
* etc...
**For FarmMaps item details page**
* selected-item
* selected-item-container
Examples:
* cropfield
* geotiff
* shape
**Other**
* item-widget-list
Examples:
* Weather

View File

@ -1,73 +1,73 @@
## Farmmaps Documentation Overview
### The documentation is still work in progress and heavily subject to change!
This page provides an index of the available documentation for the FarmMaps platform.
## Getting started
The main starting point for Farmmaps API access is the REST API.
To get started, follow the steps below.
The workflow and high-level architecture FarmMaps are documented on the [Farmmaps Workflow](Workflow) and [FarmMaps Main Components](Main-components.md) pages.
### Environments
At the moment, FarmMaps provides two environments for development.
* https://farmmaps.awtest.nl (testing environment, data is not persistent)
* https://farmmaps.awacc.nl (acceptation environment, data IS persistent)
When developing your application, using the **acceptation environment is highly recommended**.
### Obtaining credentials
To get access to the API, you need an akkerweb development account (akkerweb development and farmmaps development use the same credentials).
These can be created at:
* https://awacc.nl (for the acceptation environment)
* https://awtest.nl (for the testing environment)
Once you have an account, you can create a JSON Web Token to authenticate at the API endpoint.
### Authentication & Authorization flow
FarmMaps uses Open ID Connect to provide user authentication and authorization services.
Open ID Connect (and OAuth beneath the surface) allows your application to access user information or data that is located at another service, without providing you the password to access the account. This is very useful if your application relies on data that needs to provided by this other service for your application to work.
So, in the authentication flow there are two parties:
* The OpenID Provider (OP), holding the accounts database and providing the authentication services.
* The Relying Party (RP), relying on authentication through the OP, to get access to the required data or endpoints.
The general flow (for FarmMaps) is as follows:
* The user is at your application
* Your application needs to access the farmmaps account of that user (i.e. to upload, modify or retrieve data)
* Your application creates an authentication request for the Open ID Provider.
* The user is redirected to the "Log in page" of the OpenID Provider.
* The user logs in at the login page.
* On succesfull login, the user is redirected back to your application and the OpenID Provider returns an access token.
Now that the user is back at your applicaiton and the application has an access token, it can then request resources from the OpenID provider.
For each request, the access token needs to be sent along. This access token provides proof that the person sending the request is allowed to access the request and is who he/she claims to be. FarmMaps uses [JWT](https://jwt.io/introduction/) as the format for the access token.
To continue please see one of the articles below:
- [Integrating FarmMaps Open ID Connect into your application](Integrating-FarmMaps-OIDC.md)
- [Creating an access token for testing.](Create-access-token.md)
## Using the FarmMaps API
Once you have an access token, you can start querying the API.
A reference of the API can be found on [the swagger page](https://farmmaps.awacc.nl/swagger)
The API basics are uploading files, creating items and and running tasks to modify or convert data.
For testing purposes, [Postman](https://www.postman.com) can be used to perform HTTP requests more easily.
We provide the following guides:
* [Uploading a file](Upload-a-file.md)
* [Creating a cropfield](Create-a-cropfield.md)
* [Running a task](Running-tasks.md)
Generally, tasks can be run in the same way.
However, each specific task has it's own inputs and properties.
How these work can be found in the use task examples below.
### <a name="task-examples"></a>Task examples
* [VRAPoten-API](VRAPoten-API.md)
* [VRANbs-API](VRANbs-API.md)
* [VRAHerbicide-API](VRAHerbicide-API.md)
## Farmmaps Documentation Overview
### The documentation is still work in progress and heavily subject to change!
This page provides an index of the available documentation for the FarmMaps platform.
## Getting started
The main starting point for Farmmaps API access is the REST API.
To get started, follow the steps below.
The workflow and high-level architecture FarmMaps are documented on the [Farmmaps Workflow](Workflow.md) and [FarmMaps Main Components](Main-components.md) pages.
### Environments
At the moment, FarmMaps provides two environments for development.
* https://farmmaps.awtest.nl (testing environment, data is not persistent)
* https://farmmaps.awacc.nl (acceptation environment, data IS persistent)
When developing your application, using the **acceptation environment is highly recommended**.
### Obtaining credentials
To get access to the API, you need an akkerweb development account (akkerweb development and farmmaps development use the same credentials).
These can be created at:
* https://awacc.nl (for the acceptation environment)
* https://awtest.nl (for the testing environment)
Once you have an account, you can create a JSON Web Token to authenticate at the API endpoint.
### Authentication & Authorization flow
FarmMaps uses Open ID Connect to provide user authentication and authorization services.
Open ID Connect (and OAuth beneath the surface) allows your application to access user information or data that is located at another service, without providing you the password to access the account. This is very useful if your application relies on data that needs to provided by this other service for your application to work.
So, in the authentication flow there are two parties:
* The OpenID Provider (OP), holding the accounts database and providing the authentication services.
* The Relying Party (RP), relying on authentication through the OP, to get access to the required data or endpoints.
The general flow (for FarmMaps) is as follows:
* The user is at your application
* Your application needs to access the farmmaps account of that user (i.e. to upload, modify or retrieve data)
* Your application creates an authentication request for the Open ID Provider.
* The user is redirected to the "Log in page" of the OpenID Provider.
* The user logs in at the login page.
* On succesfull login, the user is redirected back to your application and the OpenID Provider returns an access token.
Now that the user is back at your applicaiton and the application has an access token, it can then request resources from the OpenID provider.
For each request, the access token needs to be sent along. This access token provides proof that the person sending the request is allowed to access the request and is who he/she claims to be. FarmMaps uses [JWT](https://jwt.io/introduction/) as the format for the access token.
To continue please see one of the articles below:
- [Integrating FarmMaps Open ID Connect into your application](Integrating-FarmMaps-OIDC.md)
- [Creating an access token for testing.](Create-access-token.md)
## Using the FarmMaps API
Once you have an access token, you can start querying the API.
A reference of the API can be found on [the swagger page](https://farmmaps.awacc.nl/swagger)
The API basics are uploading files, creating items and and running tasks to modify or convert data.
For testing purposes, [Postman](https://www.postman.com) can be used to perform HTTP requests more easily.
We provide the following guides:
* [Uploading a file](Upload-a-file.md)
* [Creating a cropfield](Create-a-cropfield.md)
* [Running a task](Running-tasks.md)
Generally, tasks can be run in the same way.
However, each specific task has it's own inputs and properties.
How these work can be found in the use task examples below.
### <a name="task-examples"></a>Task examples
* [VRAPoten-API](VRAPoten-API.md)
* [VRANbs-API](VRANbs-API.md)
* [VRAHerbicide-API](VRAHerbicide-API.md)

View File

@ -1,7 +1,7 @@
# Integrating FarmMaps OpenID Connect
Farmmaps uses OpenID Connect (OIDC).
This page lists the information needed to integrate OpenID connect into your application.
Note that for testing purposes it is quicker to just [generate an access token](.md) instead of implementing a complete integration.
Note that for testing purposes it is quicker to just [generate an access token]() instead of implementing a complete integration.
Please see [https://openid.net/connect/](https://openid.net/connect/) if you are not familiar with OpenID Connect.
To integrate OIDC, it is recommended to use a (certified) library/implementation for your language of choice:
@ -21,7 +21,7 @@ More about flow types can be found [here](https://www.scottbrady91.com/OpenID-Co
* At the moment, FarmMaps does not support dynamic client registration.
Please request a client id from one of our developers when you need one for your application.
In the meantime, it is recommended to simply [generate an access token](.md) to explore the REST API.
In the meantime, it is recommended to simply [generate an access token]() to explore the REST API.

View File

@ -67,7 +67,7 @@ The REST API is the primary API for FarmMaps and allows you to:
* Run other tasks (create a taskmap, create cropfield etc.)
* Monitor the progress of the processing tasks
Several how-to's can be found in the [examples folder][examples/]
Several how-to's can be found in the [examples folder][/wiki/examples/]
There's also swagger based reference of the [REST API](https://farmmaps.awacc.nl/swagger/index.html)
#### MQTT Endpoint

View File

@ -1,200 +1,200 @@
## Sending data to the MQTT endpoint
This documentation page provides the basics on how to access the MQTT endpoint of FarmMaps, using Python code for examples.
The same workflow can be followed for different languages, as long as there's a MQTT client and a Protobuf library for the language you are using.
FarmMaps provides an MQTT endpoint to allow your application to send signals to FarmMaps, and listen for events.
These signals are collected in a "message queue".
If you are not familiar with anything mentioned, please see the [FAQ](#faq.md) at the end.
### Prerequisites
To follow along with the examples, you need:
* Access to the FarmmMaps MQTT broker (user, password), these can be requested **here**
* To have Python 3.7 or higher installed.
* To come up with a unique identifier for your sensors, to use in the `URN`.
Generally the URN is composed of the company or brand name and a device serial number like so:
```python
"urn:dev:<company-name>:<device-serial-number>"
```
To run the python example code you also need to install the `paho-mqtt` and the `protobuf` modules.
### Workflow
The general workflow for pushing data to the FarmMaps MQTT endpoint consists of:
* Preparing your data as a protobuf message
* Connecting to the MQTT Broker
* Publishing the message and waiting for confirmation.
* Closing the connection
To be able to publish data to the broker, you need an username and password, and posibly a dedicated topic for your data.
An account can be requested through email from XXXXX. This user is only for the broker, and can not be used for the other API's.
Generally, one user is provided per application (so no individual users for different sensors within the same application).
### Settings
To connect to the MQTT Broker, we'll use the following settings:
| Parameter | Default | Description |
| :---: | :------------------------------------------: | --- |
| CLIENT_ID | - | This ID is used to identify the connecting party (your software) to the broker, please use your company or brand name. |
| USER | - | Your username at the FarmMaps broker. |
| PWD | - | Your password at the FarmMaps broker. |
| HOST | `farmmaps.awtest.nl` | The address of the FarmMaps broker. |
| PORT | `1883` | The port number of the FarmMaps broker. |
| KEEPALIVE | `60` | Number of seconds to maintain the connection, even if no messages are published.
| TOPIC | `trekkerdata/sensors` | The topic to publish the messages to at the broker. |
For preparing the message, we'll use the following settings:
| Parameter | Default | Description |
| :---: | :---------------------------------------------------------------: | --- |
| META_DATA_URL | - | HTTP adress where a JSON metadata file for the messages is provided (by the data source). |
| BASE_DEV_URN | `urn:dev:<company-name>:<device-serial-number>` | To identify each unique device from different parties, FarmMaps uses a Universal Resource Name (URN). Farmmaps uses this code to link devices and data to their owners and manage access to data devices. |
All settings are required except for the `META_DATA_URL`, this parameter is optional.
### Connecting to the MQTT Broker
First, we will create a MQTT client to connect to the FarmMaps MQTT broker:
```python
#import mqtt client
from farmmaps import mqtt
#MQTT connection settings
CLIENT_ID = '<your client id>'
USER = "<your username>"
PWD = "<your password here>"
HOST = "farmmaps.awacc.nl"
PORT = 1883
KEEPALIVE = 60
TOPIC = "<company-name>/<topic-name>"
#set up MQTT client
mqtt_client = mqtt.create_client(CLIENT_ID, USER, PWD, HOST, PORT, KEEPALIVE)
```
### Preparing your data as a protobuf message
Farmmaps uses protobuf to specify a structure for the messages published in MQTT.
More information on protobuf can be found at [Google Developer Documentation](https://developers.google.com/protocol-buffers/docs/overview).
Python objects can easily be converted to protobuf messages and back (when recieving messages from the broker).
The message structure for the data can be found in `farmmaps/farmmaps.proto`, and is shown below.
**Datastructure explained**
The main message is the Datapoint object, containing time, location, machine-id and a reference to metadata.
Then, there is a `sensors` parameter, which holds a dictionary of `SensorType` objects.
Each `SensorType` holds a key and a value, where the key identifies the Sensortype, and the value is the value of the sensor.
Finally, there's an optional `metadata_url` parameter that specifies where FarmMaps can get metadata.
This is data that specifies how the values for each sensortype are to be interpreted.
```
syntax = "proto2";
package farmmaps;
message DataPoint {
required string machine_id = 1;
required int64 ts = 2;
required float lat = 3;
required float lon = 4;
optional float altitude = 5;
optional float heading = 6;
optional float speed = 7;
message SensorType {
required string key = 1;
required float value = 2;
}
repeated SensorType sensors = 8;
optional string metadata_url = 9;
}
```
This `.proto` file is processed by protobuf and converted to a python class.
This class can be found in `farmmaps/farmmaps_pb2.py` and should not be edited directly.
Edit the proto file and regenerate when you need to change the format.
In our code we can then use the protobuff class like so:
```python
#import protobuf class
from farmmaps import farmmaps_pb2
# message settings
META_DATA_URL = 'http://68.183.9.30:8082/v3/meta/sensors'
BASE_DEV_URN = 'urn:dev:nl.trekkerdata:%s'
#create sample data for message
device_id = "ib017"
timestamp = 1582731928 #epoch timestamp
longitude = 6.07206584
latitude = 52.959456183
altitude = 7.3
heading = 94.8534
speed = 0.026
sensordata = {"spn_898": 0, "spn_518": 0, "spn_513": 50, "spn_190": 1000}
# create empty protobuf message
msg = farmmaps_pb2.DataPoint()
# assign values to message properties
msg.machine_id = BASE_DEV_URN % (device_id)
msg.ts = timestamp
msg.lon = longitude
msg.lat = latitude
msg.altitude = altitude
msg.heading = heading
msg.speed = speed
for key, value in sensordata.items():
measurement = msg.sensors.add()
measurement.key = key
measurement.value = value
```
In case you want to modify the structure of the object, the `.proto` can be modified, and the python module needs to be regenerated.
For now, we'll stick with the pregenerated protobuf class.
## References
* [Protobuf documentation](https://developers.google.com/protocol-buffers/docs/overview)
* [Paho MQTT documentation](https://www.eclipse.org/paho/clients/python/docs/)
## [FAQ](#faq.md)
#### How do I install the required Python modules?
This tutorial requires the `paho-mqtt` and `protobuf` modules.
These can be installed with the following commands:
**Windows command prompt:**
```
py -m pip install 'paho-mqtt==1.5.0'
py -m pip install 'protobuf==3.11.0'
```
**Linux terminal:**
```
python3 -m pip install 'paho-mqtt==1.5.0
python3 -m pip install 'protobuf==3.11.0'
```
#### What is a message queue?
A message queue is commonly used to make software programs able to send messages between eachother, and thereby making it easy for data to flow from one program into another. There are many variants of message queues, some popular names are Apache Kafka, MQTT and RabbitMQ.
In message queue systems there is usually one central "hub" called the broker or **"message broker"**. This broker holds all the messages. Usually, the messages are organised in groups called **"topics"**.
Now, there are two things that external services can do.
* An external service (like a sensor) could **publish a message to a certain topic**. For example, a temperature sensor would publish the temperature at a specific time and location to the "temperatureMeasurements" topic.
* An external service can **"subscribe" to this topic** by connecting to the broker. This service will then recieve every temperature measurement.
When the subscribed service temporarily disconnects from the broker, it will not recieve any messages, but the messages will remain stored at the broker. Depending on configuration, messages will be kept longer or shorter, or be deleted after they reach the subscribers but the intent is always to ensure the messages get from the **publisher** to the **subscriber**.
Setting communication between applications up like this makes things a lot more flexible than connecting systems directly and provides a central point for management of all communication.
#### What is protobuf?
To quote the Google Documentation:
> Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data think XML, but smaller, faster, and simpler.
> You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.
## Sending data to the MQTT endpoint
This documentation page provides the basics on how to access the MQTT endpoint of FarmMaps, using Python code for examples.
The same workflow can be followed for different languages, as long as there's a MQTT client and a Protobuf library for the language you are using.
FarmMaps provides an MQTT endpoint to allow your application to send signals to FarmMaps, and listen for events.
These signals are collected in a "message queue".
If you are not familiar with anything mentioned, please see the [FAQ](#faq) at the end.
### Prerequisites
To follow along with the examples, you need:
* Access to the FarmmMaps MQTT broker (user, password), these can be requested **here**
* To have Python 3.7 or higher installed.
* To come up with a unique identifier for your sensors, to use in the `URN`.
Generally the URN is composed of the company or brand name and a device serial number like so:
```python
"urn:dev:<company-name>:<device-serial-number>"
```
To run the python example code you also need to install the `paho-mqtt` and the `protobuf` modules.
### Workflow
The general workflow for pushing data to the FarmMaps MQTT endpoint consists of:
* Preparing your data as a protobuf message
* Connecting to the MQTT Broker
* Publishing the message and waiting for confirmation.
* Closing the connection
To be able to publish data to the broker, you need an username and password, and posibly a dedicated topic for your data.
An account can be requested through email from XXXXX. This user is only for the broker, and can not be used for the other API's.
Generally, one user is provided per application (so no individual users for different sensors within the same application).
### Settings
To connect to the MQTT Broker, we'll use the following settings:
| Parameter | Default | Description |
| :---: | :------------------------------------------: | --- |
| CLIENT_ID | - | This ID is used to identify the connecting party (your software) to the broker, please use your company or brand name. |
| USER | - | Your username at the FarmMaps broker. |
| PWD | - | Your password at the FarmMaps broker. |
| HOST | `farmmaps.awtest.nl` | The address of the FarmMaps broker. |
| PORT | `1883` | The port number of the FarmMaps broker. |
| KEEPALIVE | `60` | Number of seconds to maintain the connection, even if no messages are published.
| TOPIC | `trekkerdata/sensors` | The topic to publish the messages to at the broker. |
For preparing the message, we'll use the following settings:
| Parameter | Default | Description |
| :---: | :---------------------------------------------------------------: | --- |
| META_DATA_URL | - | HTTP adress where a JSON metadata file for the messages is provided (by the data source). |
| BASE_DEV_URN | `urn:dev:<company-name>:<device-serial-number>` | To identify each unique device from different parties, FarmMaps uses a Universal Resource Name (URN). Farmmaps uses this code to link devices and data to their owners and manage access to data devices. |
All settings are required except for the `META_DATA_URL`, this parameter is optional.
### Connecting to the MQTT Broker
First, we will create a MQTT client to connect to the FarmMaps MQTT broker:
```python
#import mqtt client
from farmmaps import mqtt
#MQTT connection settings
CLIENT_ID = '<your client id>'
USER = "<your username>"
PWD = "<your password here>"
HOST = "farmmaps.awacc.nl"
PORT = 1883
KEEPALIVE = 60
TOPIC = "<company-name>/<topic-name>"
#set up MQTT client
mqtt_client = mqtt.create_client(CLIENT_ID, USER, PWD, HOST, PORT, KEEPALIVE)
```
### Preparing your data as a protobuf message
Farmmaps uses protobuf to specify a structure for the messages published in MQTT.
More information on protobuf can be found at [Google Developer Documentation](https://developers.google.com/protocol-buffers/docs/overview).
Python objects can easily be converted to protobuf messages and back (when recieving messages from the broker).
The message structure for the data can be found in `farmmaps/farmmaps.proto`, and is shown below.
**Datastructure explained**
The main message is the Datapoint object, containing time, location, machine-id and a reference to metadata.
Then, there is a `sensors` parameter, which holds a dictionary of `SensorType` objects.
Each `SensorType` holds a key and a value, where the key identifies the Sensortype, and the value is the value of the sensor.
Finally, there's an optional `metadata_url` parameter that specifies where FarmMaps can get metadata.
This is data that specifies how the values for each sensortype are to be interpreted.
```
syntax = "proto2";
package farmmaps;
message DataPoint {
required string machine_id = 1;
required int64 ts = 2;
required float lat = 3;
required float lon = 4;
optional float altitude = 5;
optional float heading = 6;
optional float speed = 7;
message SensorType {
required string key = 1;
required float value = 2;
}
repeated SensorType sensors = 8;
optional string metadata_url = 9;
}
```
This `.proto` file is processed by protobuf and converted to a python class.
This class can be found in `farmmaps/farmmaps_pb2.py` and should not be edited directly.
Edit the proto file and regenerate when you need to change the format.
In our code we can then use the protobuff class like so:
```python
#import protobuf class
from farmmaps import farmmaps_pb2
# message settings
META_DATA_URL = 'http://68.183.9.30:8082/v3/meta/sensors'
BASE_DEV_URN = 'urn:dev:nl.trekkerdata:%s'
#create sample data for message
device_id = "ib017"
timestamp = 1582731928 #epoch timestamp
longitude = 6.07206584
latitude = 52.959456183
altitude = 7.3
heading = 94.8534
speed = 0.026
sensordata = {"spn_898": 0, "spn_518": 0, "spn_513": 50, "spn_190": 1000}
# create empty protobuf message
msg = farmmaps_pb2.DataPoint()
# assign values to message properties
msg.machine_id = BASE_DEV_URN % (device_id)
msg.ts = timestamp
msg.lon = longitude
msg.lat = latitude
msg.altitude = altitude
msg.heading = heading
msg.speed = speed
for key, value in sensordata.items():
measurement = msg.sensors.add()
measurement.key = key
measurement.value = value
```
In case you want to modify the structure of the object, the `.proto` can be modified, and the python module needs to be regenerated.
For now, we'll stick with the pregenerated protobuf class.
## References
* [Protobuf documentation](https://developers.google.com/protocol-buffers/docs/overview)
* [Paho MQTT documentation](https://www.eclipse.org/paho/clients/python/docs/)
## [FAQ](#faq)
#### How do I install the required Python modules?
This tutorial requires the `paho-mqtt` and `protobuf` modules.
These can be installed with the following commands:
**Windows command prompt:**
```
py -m pip install 'paho-mqtt==1.5.0'
py -m pip install 'protobuf==3.11.0'
```
**Linux terminal:**
```
python3 -m pip install 'paho-mqtt==1.5.0
python3 -m pip install 'protobuf==3.11.0'
```
#### What is a message queue?
A message queue is commonly used to make software programs able to send messages between eachother, and thereby making it easy for data to flow from one program into another. There are many variants of message queues, some popular names are Apache Kafka, MQTT and RabbitMQ.
In message queue systems there is usually one central "hub" called the broker or **"message broker"**. This broker holds all the messages. Usually, the messages are organised in groups called **"topics"**.
Now, there are two things that external services can do.
* An external service (like a sensor) could **publish a message to a certain topic**. For example, a temperature sensor would publish the temperature at a specific time and location to the "temperatureMeasurements" topic.
* An external service can **"subscribe" to this topic** by connecting to the broker. This service will then recieve every temperature measurement.
When the subscribed service temporarily disconnects from the broker, it will not recieve any messages, but the messages will remain stored at the broker. Depending on configuration, messages will be kept longer or shorter, or be deleted after they reach the subscribers but the intent is always to ensure the messages get from the **publisher** to the **subscriber**.
Setting communication between applications up like this makes things a lot more flexible than connecting systems directly and provides a central point for management of all communication.
#### What is protobuf?
To quote the Google Documentation:
> Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data think XML, but smaller, faster, and simpler.
> You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.
More information can be found in the [protobuf documentation](https://developers.google.com/protocol-buffers/docs/overview).

View File

@ -1,55 +1,55 @@
## Polling task status
When a task is executed with the task API your retrieve a code.
This code can be used to poll the status of an item task execution.
The response 'message' field can contain a string message based on the context.
#### Get a list task of status for a given item
> Request
```javascript
GET /api/v1/items/{code}/tasks
```
> Response 200 OK
```javascript
[
{
"taskType": "string",
"code": "string",
"message": "string",
"state": "Error, Ok, Scheduled, Processing",
"started": "2020-03-20T11:13:20.568Z",
"finished": "2020-03-20T11:13:20.568Z"
},
{
"taskType": "string",
"code": "string",
"state": "Error, Ok, Scheduled, Processing",
}
]
```
Response 401 Not authenticated
Response 403 No READ permissions in parent item
Response 404 Parent Item not found
#### Get the status of a task for a given item and item task code
> Request
```javascript
GET /api/v1/items/{code}/tasks/{itemTaskCode}
```
> Response 200 OK
```javascript
{
"taskType": "string",
"code": "string",
"message": "string",
"state": "Error, Ok, Scheduled, Processing",
"started": "2020-03-20T11:13:20.568Z",
"finished": "2020-03-20T11:13:20.568Z"
}
```
Response 401 Not authenticated
Response 403 No READ permissions in parent item
## Polling task status
When a task is executed with the task API your retrieve a code.
This code can be used to poll the status of an item task execution.
The response 'message' field can contain a string message based on the context.
#### Get a list task of status for a given item
> Request
```javascript
GET /api/v1/items/{code}/tasks
```
> Response 200 OK
```javascript
[
{
"taskType": "string",
"code": "string",
"message": "string",
"state": "Error, Ok, Scheduled, Processing",
"started": "2020-03-20T11:13:20.568Z",
"finished": "2020-03-20T11:13:20.568Z"
},
{
"taskType": "string",
"code": "string",
"state": "Error, Ok, Scheduled, Processing",
}
]
```
Response 401 Not authenticated
Response 403 No READ permissions in parent item
Response 404 Parent Item not found
#### Get the status of a task for a given item and item task code
> Request
```javascript
GET /api/v1/items/{code}/tasks/{itemTaskCode}
```
> Response 200 OK
```javascript
{
"taskType": "string",
"code": "string",
"message": "string",
"state": "Error, Ok, Scheduled, Processing",
"started": "2020-03-20T11:13:20.568Z",
"finished": "2020-03-20T11:13:20.568Z"
}
```
Response 401 Not authenticated
Response 403 No READ permissions in parent item
Response 404 Parent Item not found

View File

@ -259,7 +259,7 @@ Vary: Accept-Encoding
## What's next?
Now that you know how to run a task, you can start running specialized tasks to create or process your own data.
Head over to the [Task Examples](Home#task-examples.md)
Head over to the [Task Examples](README.md#task-examples)

View File

@ -1,117 +1,117 @@
## Upload Data
If the user wants to upload custom data (lutum/ec) they can use the FarmMaps file API.
The API is based on the google drive API.
C# explanation:
https://developers.google.com/api-client-library/dotnet/guide/media_upload
https://developers.google.com/drive/api/v3/manage-uploads#resumable
* Start request
> Request
```javascript
POST https://farmmaps.awacc.nl/api/v1/file
Host: farmmaps.awtest.nl
Authorization: Bearer < Token >
X-Upload-Content-Length: 13507747
X-Upload-Content-Type: application/x-zip-compressed
Content-Type: application/json; charset=UTF-8
Content-Length: 181
{
"name":"Grondsoorten2006-SHP.zip",
"mimeType":"application/x-zip-compressed",
"size":13507747,
"lastModified":1575293019617,
"parentCode":"c0787987a3f7449c97eecd6d015eb4c2:USER_FILES"
}
```
> Response
```javascript
Location: /api/v1/file/2831cd05ddc0415784930059c658db55
Content-Length: 194
Content-Type: application/json; charset=utf-8
{
"code":"2831cd05ddc0415784930059c658db55",
"chunks":1,
"parentCode":"c0787987a3f7449c97eecd6d015eb4c2:USER_FILES",
"name":"Grondsoorten2006-SHP.zip",
"size":13507747,
"chunkSize":13507747,
"data":{}
}
```
* Request upload chunk 1
> Request
```javascript
PUT https://farmmaps.awtest.nl/api/v1/file/2831cd05ddc0415784930059c658db55
Host: farmmaps.awtest.nl
Authorization: Bearer < Token >
Content-Type: application/octet-stream
Content-Length: 2097152
Content-Range: bytes 0-2097151/13507747
<data>
```
> Response
```javascript
HTTP/1.1 308 Resume Incomplete
Range: 0-2097151
Content-Length: 17
Resume Incomplete
```
* Request upload chunk 2
> Request
```javascript
PUT https://farmmaps.awtest.nl/api/v1/file/2831cd05ddc0415784930059c658db55
Host: farmmaps.awtest.nl
Authorization: Bearer < Token >
Content-Type: application/octet-stream
Content-Length: 2097152
Content-Range: bytes 2097152-4194303/13507747
<data>
```
> Response
```javascript
HTTP/1.1 308 Resume Incomplete
Range: 0-4194303
Content-Length: 17
Resume Incomplete
```
* Final request
> Request
```javascript
PUT https://farmmaps.awtest.nl/api/v1/file/2831cd05ddc0415784930059c658db55
Host: farmmaps.awtest.nl
Authorization: Bearer < Token >
Content-Type: application/octet-stream
Content-Length: 924835
Content-Range: bytes 12582912-13507746/13507747
<data>
```
> Response
```javascript
Upload response laatste chunk
HTTP/1.1 201 Created
Range: 0-13507746
Content-Length: 0
```
## Upload Data
If the user wants to upload custom data (lutum/ec) they can use the FarmMaps file API.
The API is based on the google drive API.
C# explanation:
https://developers.google.com/api-client-library/dotnet/guide/media_upload
https://developers.google.com/drive/api/v3/manage-uploads#resumable
* Start request
> Request
```javascript
POST https://farmmaps.awacc.nl/api/v1/file
Host: farmmaps.awtest.nl
Authorization: Bearer < Token >
X-Upload-Content-Length: 13507747
X-Upload-Content-Type: application/x-zip-compressed
Content-Type: application/json; charset=UTF-8
Content-Length: 181
{
"name":"Grondsoorten2006-SHP.zip",
"mimeType":"application/x-zip-compressed",
"size":13507747,
"lastModified":1575293019617,
"parentCode":"c0787987a3f7449c97eecd6d015eb4c2:USER_FILES"
}
```
> Response
```javascript
Location: /api/v1/file/2831cd05ddc0415784930059c658db55
Content-Length: 194
Content-Type: application/json; charset=utf-8
{
"code":"2831cd05ddc0415784930059c658db55",
"chunks":1,
"parentCode":"c0787987a3f7449c97eecd6d015eb4c2:USER_FILES",
"name":"Grondsoorten2006-SHP.zip",
"size":13507747,
"chunkSize":13507747,
"data":{}
}
```
* Request upload chunk 1
> Request
```javascript
PUT https://farmmaps.awtest.nl/api/v1/file/2831cd05ddc0415784930059c658db55
Host: farmmaps.awtest.nl
Authorization: Bearer < Token >
Content-Type: application/octet-stream
Content-Length: 2097152
Content-Range: bytes 0-2097151/13507747
<data>
```
> Response
```javascript
HTTP/1.1 308 Resume Incomplete
Range: 0-2097151
Content-Length: 17
Resume Incomplete
```
* Request upload chunk 2
> Request
```javascript
PUT https://farmmaps.awtest.nl/api/v1/file/2831cd05ddc0415784930059c658db55
Host: farmmaps.awtest.nl
Authorization: Bearer < Token >
Content-Type: application/octet-stream
Content-Length: 2097152
Content-Range: bytes 2097152-4194303/13507747
<data>
```
> Response
```javascript
HTTP/1.1 308 Resume Incomplete
Range: 0-4194303
Content-Length: 17
Resume Incomplete
```
* Final request
> Request
```javascript
PUT https://farmmaps.awtest.nl/api/v1/file/2831cd05ddc0415784930059c658db55
Host: farmmaps.awtest.nl
Authorization: Bearer < Token >
Content-Type: application/octet-stream
Content-Length: 924835
Content-Range: bytes 12582912-13507746/13507747
<data>
```
> Response
```javascript
Upload response laatste chunk
HTTP/1.1 201 Created
Range: 0-13507746
Content-Length: 0
```

View File

@ -1,172 +1,172 @@
## VRAHerbicide API
[<< Home](README.md)
FarmMaps is an asynchronous architecture, the API flow keeps this in mind.
The API expects that all data is already processed and available provided, for example through the normal FarmMaps flow (frontend).
For the currently available public FarmMaps API you can take a look at swagger: http://farmmaps.awtest.nl/swagger/index.html
**Input preperation**
* Users can upload their own data if needed. (in case of when FarmMaps has not processed the required data).
* The farmmaps file API can be used for this.
**Users can poll the task api to see if a task is completed**
**This can be achieved with the task execution id obtained from calling the 'ItemTask' API.**
[Poll task status](Polling-task-status.md)
**Users can query the API for child items of a cropfield to see what items it has.**
### API flow
* Authenticate User
* Optional steps
* *Create cropfield through FarmMaps API*
* Item 'vnd.farmmaps.itemtype.cropfield' must be created with its data as specified in the api.
* Task 'vnd.farmmaps.task.workflow' needs to be executed to aggregate all needed data.
* This is an asynchronous process and can take a while before all data is collected in FarmMaps.
* *Upload own data*
* IF shape data, convert to geotiff.
* Task 'vnd.farmmaps.task.vraherbicide' must be executed to create an application map.
* Task 'vnd.farmmaps.task.taskmap' can be executed to create a taskmap.
* Download item data (tiff of shape)
### Steps
[Authentication](Authentication.md)
##### Optional
[Create Cropfield](Create-Cropfield.md)
[Upload Data](Upload-Data.md)
###### Transform shape to geotiff
The VRAHerbicide task only processes tiff items as input.
If your input data is a processed shape file it first needs to be converted to geotiff, this can be done with the 'ShapeToGeoTiffTask'.
Pass the code of the shape item into the {code} parameter, this creates a new item with tiff data as the parent of the shape item.
This new geotiff item should be used as input to the a task.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.shapetogeotiff"
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.shapetogeotiff"
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
###### Querying predefined herbicide agents.
A list of herbicide agents can be requested by finding the "vnd.farmmaps.package.vra.herbicide" items, taking the first item found and reading it's data field 'agents' array content.
> Request
```javascript
GET /api/v1/items/?it=vnd.farmmaps.package.vra.herbicide
```
> Response 201
```javascript
{
"code": "....",
"data": {
"agents": [
{
"name": "Liberator",
"SoilType": "Dalgrond",
"ExtraInputType": "Lutum",
"MinDosis": 2,
"MaxDosis": 3,
"A": 0.1428,
"B": 1.285714,
"C": 1,
"D": 97,
"E": 3,
"P": 1,
"Crop": "Zetmeelaardappelen"
}
]
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No READ permissions in item
Response 404 Items not found
###### Creating an application map with the VRAHerbicide task
Execute the task with the item code of the cropfield as parameter inside {code}.
Use the input map code inside {itemCode}, specifying an inputCode for the input data item.
{itemCode} needs the code of the data input item passed into it.
An **optional** {extraItemCode} can be passed inside the 'extraInputcode' field to process herbicide from 2 inputs.
Fill in the agent field with an agent gotten from the herbicide agents query discussed above.
The resulting application map will be created as a child item of the cropfield item (this can be queried).
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.vraherbicide",
"attributes": {
"inputCode": "{itemCode}",
"extraInputCode": "{extraItemCode}",
"agent": {
"SoilType": "Dalgrond",
"ExtraInputType": "Lutum",
"MinDosis": 2,
"MaxDosis": 3,
"A": 0.1428,
"B": 1.285714,
"C": 1,
"D": 97,
"E": 3,
"P": 1,
"Crop": "Zetmeelaardappelen"
}
}
}
```
> Response 201
```javascript
{
"code": "string", // code of task operation, can be queried for status
"taskType": "vnd.farmmaps.task.vraherbicide",
"attributes": {
"inputCode": "{itemCode}",
"extraInputCode": "{extraItemCode}",
"agent": {
"SoilType": "Dalgrond",
"ExtraInputType": "Lutum",
"MinDosis": 2,
"MaxDosis": 3,
"A": 0.1428,
"B": 1.285714,
"C": 1,
"D": 97,
"E": 3,
"P": 1,
"Crop": "Zetmeelaardappelen"
}
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
##### Create taskmap
[Create Taskmap](Create-Taskmap.md)
##### Download the data
In case the data is available it can be downloaded with the File API.
> Request
```javascript
## VRAHerbicide API
[<< Home](README.md)
FarmMaps is an asynchronous architecture, the API flow keeps this in mind.
The API expects that all data is already processed and available provided, for example through the normal FarmMaps flow (frontend).
For the currently available public FarmMaps API you can take a look at swagger: http://farmmaps.awtest.nl/swagger/index.html
**Input preperation**
* Users can upload their own data if needed. (in case of when FarmMaps has not processed the required data).
* The farmmaps file API can be used for this.
**Users can poll the task api to see if a task is completed**
**This can be achieved with the task execution id obtained from calling the 'ItemTask' API.**
[Poll task status](Polling-task-status.md)
**Users can query the API for child items of a cropfield to see what items it has.**
### API flow
* Authenticate User
* Optional steps
* *Create cropfield through FarmMaps API*
* Item 'vnd.farmmaps.itemtype.cropfield' must be created with its data as specified in the api.
* Task 'vnd.farmmaps.task.workflow' needs to be executed to aggregate all needed data.
* This is an asynchronous process and can take a while before all data is collected in FarmMaps.
* *Upload own data*
* IF shape data, convert to geotiff.
* Task 'vnd.farmmaps.task.vraherbicide' must be executed to create an application map.
* Task 'vnd.farmmaps.task.taskmap' can be executed to create a taskmap.
* Download item data (tiff of shape)
### Steps
[Authentication](Authentication.md)
##### Optional
[Create Cropfield](Create-Cropfield.md)
[Upload Data](Upload-Data.md)
###### Transform shape to geotiff
The VRAHerbicide task only processes tiff items as input.
If your input data is a processed shape file it first needs to be converted to geotiff, this can be done with the 'ShapeToGeoTiffTask'.
Pass the code of the shape item into the {code} parameter, this creates a new item with tiff data as the parent of the shape item.
This new geotiff item should be used as input to the a task.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.shapetogeotiff"
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.shapetogeotiff"
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
###### Querying predefined herbicide agents.
A list of herbicide agents can be requested by finding the "vnd.farmmaps.package.vra.herbicide" items, taking the first item found and reading it's data field 'agents' array content.
> Request
```javascript
GET /api/v1/items/?it=vnd.farmmaps.package.vra.herbicide
```
> Response 201
```javascript
{
"code": "....",
"data": {
"agents": [
{
"name": "Liberator",
"SoilType": "Dalgrond",
"ExtraInputType": "Lutum",
"MinDosis": 2,
"MaxDosis": 3,
"A": 0.1428,
"B": 1.285714,
"C": 1,
"D": 97,
"E": 3,
"P": 1,
"Crop": "Zetmeelaardappelen"
}
]
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No READ permissions in item
Response 404 Items not found
###### Creating an application map with the VRAHerbicide task
Execute the task with the item code of the cropfield as parameter inside {code}.
Use the input map code inside {itemCode}, specifying an inputCode for the input data item.
{itemCode} needs the code of the data input item passed into it.
An **optional** {extraItemCode} can be passed inside the 'extraInputcode' field to process herbicide from 2 inputs.
Fill in the agent field with an agent gotten from the herbicide agents query discussed above.
The resulting application map will be created as a child item of the cropfield item (this can be queried).
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.vraherbicide",
"attributes": {
"inputCode": "{itemCode}",
"extraInputCode": "{extraItemCode}",
"agent": {
"SoilType": "Dalgrond",
"ExtraInputType": "Lutum",
"MinDosis": 2,
"MaxDosis": 3,
"A": 0.1428,
"B": 1.285714,
"C": 1,
"D": 97,
"E": 3,
"P": 1,
"Crop": "Zetmeelaardappelen"
}
}
}
```
> Response 201
```javascript
{
"code": "string", // code of task operation, can be queried for status
"taskType": "vnd.farmmaps.task.vraherbicide",
"attributes": {
"inputCode": "{itemCode}",
"extraInputCode": "{extraItemCode}",
"agent": {
"SoilType": "Dalgrond",
"ExtraInputType": "Lutum",
"MinDosis": 2,
"MaxDosis": 3,
"A": 0.1428,
"B": 1.285714,
"C": 1,
"D": 97,
"E": 3,
"P": 1,
"Crop": "Zetmeelaardappelen"
}
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
##### Create taskmap
[Create Taskmap](Create-Taskmap.md)
##### Download the data
In case the data is available it can be downloaded with the File API.
> Request
```javascript
GET /api/v1/items/{itemcode}/data

View File

@ -1,295 +1,295 @@
## VRANbs API v0.2
[<< Home](README.md)
FarmMaps is an asynchronous architecture, the API flow keeps this in mind.
The API expects that all data is already processed and available provided, for example through the normal FarmMaps flow (frontend).
For the currently available public FarmMaps API you can take a look at swagger: http://farmmaps.awtest.nl/swagger/index.html
**Limitations**
* Currently VRANbs only accepts input tiffs in WGS84/EPSG4326
* Data isn't automatically deleted as farmmaps has no support for this.
* But API users can delete their own items through the farmmaps API.
**Input preperation**
* Users can upload their own data if needed. (in case of when FarmMaps has not processed the required data).
* The farmmaps file API can be used for this.
**Users can poll the task api to see if a task is completed**
**This can be achieved with the task execution id obtained from calling the 'ItemTask' API.**
[Poll task status](Polling-task-status.md)
**Users can query the API for child items of a cropfield to see what items it has.**
### API flow
* Authenticate User
* Optional steps
* *Create cropfield through FarmMaps API*
* Item 'vnd.farmmaps.itemtype.cropfield' must be created with its data as specified in the api.
* Task 'vnd.farmmaps.task.workflow' needs to be executed to aggregate all needed data.
* This is an asynchronous process and can take a while before all data is collected in FarmMaps.
* *Upload own data*
* IF shape data, convert to geotiff.
* *Create 'vnd.farmmaps.itemtype.user.input' item for targetn calculation.*
* *Task 'vnd.farmmaps.task.vranbs' can be executed with the 'targetn' operation*
* *Task 'vnd.farmmaps.task.vranbs' can be executed with 'uptake' operation* to create an nitrogen uptake map.
* Task 'vnd.farmmaps.task.vranbs' must be executed with 'nitrogen' operation to create an appliance map.
* Task 'vnd.farmmaps.task.taskmap' can be executed to create a taskmap.
* Download item data (tiff of shape)
### Steps
[Authentication](Authentication.md)
##### Optional
[Create Cropfield](Create-Cropfield.md)
[Upload Data](Upload-Data.md)
###### Transform shape to geotiff
The VRANbs task only processes tiff items as input.
If your input data is a processed shape file it first needs to be converted to geotiff, this can be done with the 'ShapeToGeoTiffTask'.
Pass the code of the shape item into the {code} parameter, this creates a new item with tiff data as the parent of the shape item.
This new geotiff item should be used as input to the vranbs task.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.shapetogeotiff"
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.shapetogeotiff"
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
##### Using VRA Nitrogen fertilization task
The VraNbs task currently supports 3 operations:
* **targetn** - calculates the target nitrogen based on target yield.
* **uptake** - creates the nitrogen uptake map.
* **application** - creates the nitrogen fertilization application map.
###### targetn operation
Create a 'vnd.farmmaps.itemtype.user.input' item to use in this operation.
(step not needed if you already know the target nitrogen you want to work with.)
The user.input item must parent the '{user_code}:USER_IN' item and can be obtained by calling following request:
> Request
```javascript
GET /api/v1/Folders/my_uploads
```
> Response 201
```javascript
{
"url": "/api/v1/folders/{user_code}:USER_IN",
"code": "{user_code}:USER_IN",
"name": "Uploaded",
"created": "2020-03-04T14:41:41.099557",
"updated": "2020-03-04T14:41:41.099557",
"itemType": "FOLDER",
"size": 0,
"state": 0,
"thumbnail": false
}
```
**Create item**
Create user.input item, pass just obtained parent code as parameter in {user_code}.
> Request
```javascript
POST /api/v1/items
{
"parentCode": "{user_code}:USER_IN",
"itemType": "vnd.farmmaps.itemtype.user.input",
"name": "TargetN",
"dataDate": "2020-03-02T14:22:09.265Z"
}
```
> Response 201 Created
```javascript
{
"parentCode": "string",
"geometry": {},
"data": {},
"tags": [
"string"
],
"url": "string",
"code": "string",
"name": "string",
"created": "2019-12-18T10:16:21.455Z",
"updated": "2019-12-18T10:16:21.455Z",
"dataDate": "2019-12-18T10:16:21.455Z",
"itemType": "string",
"sourceTask": "string",
"size": 0,
"state": 0,
"thumbnail": true
}
```
Response 401 Not authenticated
Response 403 No WRITE permissions in parent item
Response 404 Parent Item not found
**Call the vranbs task**
Execute the VRANbsTask with the item code of the cropfield as parameter inside {code}.
Use the code obtained from creating the user.input item as a parameter in {itemCode}.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.vranbs",
"attributes": {
"operation": "targetn",
"inputCode": "{itemCode}",
"plantingDate": "2020-02-01T00:00:00.000Z",
"measurementDate": "2020-06-01T00:00:00.000Z",
"purposeType": "consumption", // consumption, fries, potato, starch
"targetYield": "60"
}
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.workflow"
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
**Query user.input targetN item**
You can query the user.input item to get the calculated targetN value from the data field of the item.
> Request
```javascript
GET /api/v1/items/{code}
```
> Response 200
```javascript
{
"parentCode": "string",
"geometry": {},
"data": {
"TSum": "2700",
"TargetYield": "60",
"TargetN": "249.2341"
},
"tags": [
"string"
],
"url": "string",
"code": "string",
"name": "TargetN",
"created": "2019-12-18T10:16:21.455Z",
"updated": "2019-12-18T10:16:21.455Z",
"dataDate": "2019-12-18T10:16:21.455Z",
"itemType": "vnd.farmmaps.itemtype.user.input",
"sourceTask": "string",
"size": 0,
"state": 0,
"thumbnail": true
}
```
###### Uptake map operation
Execute the VRANbsTask with the item code of the cropfield as parameter inside {code}.
Use the input map code inside {itemCode}, specifying an inputCode for the input data item.
{itemCode} needs the code of the data input item passed into it. ex. uploaded isaria/data data.
The resulting nitrogen uptake map will be created as a child item under the cropfield item (this can be queried).
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.vranbs",
"attributes": {
"operation": "uptake",
"inputCode": "{itemCode}",
"plantingDate": "2020-02-01T00:00:00.000Z",
"measurementDate": "2020-06-01T00:00:00.000Z",
"inputType": "irmi", // yara, ci, irmi or wdvi
}
}
```
> Response 201
```javascript
{
"code": "string", // code of task operation, can be queried for status
"taskType": "vnd.farmmaps.task.vranbs",
"attributes": {
"operation": "uptake",
"inputCode": "{itemCode}",
"inputType": "irmi", // yara, ci, irmi or wdvi
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
###### Application map operation
Execute the VRANbsTask with the item code of the cropfield as parameter inside {code}.
Use the input map code inside {itemCode}, specifying an inputCode for the input data item.
{itemCode} needs the code of the data input item passed into it. ex. uploaded isaria/data data.
The resulting nitrogen application map will be created as a child item under the cropfield item (this can be queried).
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.vranbs",
"attributes": {
"operation": "application",
"inputCode": "{itemCode}",
"plantingDate": "2020-02-01T00:00:00.000Z",
"measurementDate": "2020-06-01T00:00:00.000Z",
"inputType": "irmi", // yara, ci, irmi or wdvi
"targetN": "249.22948"
}
}
```
> Response 201
```javascript
{
"code": "string", // code of task operation, can be queried for status
"taskType": "vnd.farmmaps.task.vranbs",
"attributes": {
"operation": "nitrogen",
"inputCode": "{itemCode}",
"inputType": "irmi", // yara, ci, irmi or wdvi
"targetN": "249.22948"
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
##### Create taskmap
[Create Taskmap](Create-Taskmap.md)
##### Download the data
In case the data is available it can be downloaded with the File API.
> Request
```javascript
## VRANbs API v0.2
[<< Home](README.md)
FarmMaps is an asynchronous architecture, the API flow keeps this in mind.
The API expects that all data is already processed and available provided, for example through the normal FarmMaps flow (frontend).
For the currently available public FarmMaps API you can take a look at swagger: http://farmmaps.awtest.nl/swagger/index.html
**Limitations**
* Currently VRANbs only accepts input tiffs in WGS84/EPSG4326
* Data isn't automatically deleted as farmmaps has no support for this.
* But API users can delete their own items through the farmmaps API.
**Input preperation**
* Users can upload their own data if needed. (in case of when FarmMaps has not processed the required data).
* The farmmaps file API can be used for this.
**Users can poll the task api to see if a task is completed**
**This can be achieved with the task execution id obtained from calling the 'ItemTask' API.**
[Poll task status](Polling-task-status.md)
**Users can query the API for child items of a cropfield to see what items it has.**
### API flow
* Authenticate User
* Optional steps
* *Create cropfield through FarmMaps API*
* Item 'vnd.farmmaps.itemtype.cropfield' must be created with its data as specified in the api.
* Task 'vnd.farmmaps.task.workflow' needs to be executed to aggregate all needed data.
* This is an asynchronous process and can take a while before all data is collected in FarmMaps.
* *Upload own data*
* IF shape data, convert to geotiff.
* *Create 'vnd.farmmaps.itemtype.user.input' item for targetn calculation.*
* *Task 'vnd.farmmaps.task.vranbs' can be executed with the 'targetn' operation*
* *Task 'vnd.farmmaps.task.vranbs' can be executed with 'uptake' operation* to create an nitrogen uptake map.
* Task 'vnd.farmmaps.task.vranbs' must be executed with 'nitrogen' operation to create an appliance map.
* Task 'vnd.farmmaps.task.taskmap' can be executed to create a taskmap.
* Download item data (tiff of shape)
### Steps
[Authentication](Authentication.md)
##### Optional
[Create Cropfield](Create-Cropfield.md)
[Upload Data](Upload-Data.md)
###### Transform shape to geotiff
The VRANbs task only processes tiff items as input.
If your input data is a processed shape file it first needs to be converted to geotiff, this can be done with the 'ShapeToGeoTiffTask'.
Pass the code of the shape item into the {code} parameter, this creates a new item with tiff data as the parent of the shape item.
This new geotiff item should be used as input to the vranbs task.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.shapetogeotiff"
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.shapetogeotiff"
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
##### Using VRA Nitrogen fertilization task
The VraNbs task currently supports 3 operations:
* **targetn** - calculates the target nitrogen based on target yield.
* **uptake** - creates the nitrogen uptake map.
* **application** - creates the nitrogen fertilization application map.
###### targetn operation
Create a 'vnd.farmmaps.itemtype.user.input' item to use in this operation.
(step not needed if you already know the target nitrogen you want to work with.)
The user.input item must parent the '{user_code}:USER_IN' item and can be obtained by calling following request:
> Request
```javascript
GET /api/v1/Folders/my_uploads
```
> Response 201
```javascript
{
"url": "/api/v1/folders/{user_code}:USER_IN",
"code": "{user_code}:USER_IN",
"name": "Uploaded",
"created": "2020-03-04T14:41:41.099557",
"updated": "2020-03-04T14:41:41.099557",
"itemType": "FOLDER",
"size": 0,
"state": 0,
"thumbnail": false
}
```
**Create item**
Create user.input item, pass just obtained parent code as parameter in {user_code}.
> Request
```javascript
POST /api/v1/items
{
"parentCode": "{user_code}:USER_IN",
"itemType": "vnd.farmmaps.itemtype.user.input",
"name": "TargetN",
"dataDate": "2020-03-02T14:22:09.265Z"
}
```
> Response 201 Created
```javascript
{
"parentCode": "string",
"geometry": {},
"data": {},
"tags": [
"string"
],
"url": "string",
"code": "string",
"name": "string",
"created": "2019-12-18T10:16:21.455Z",
"updated": "2019-12-18T10:16:21.455Z",
"dataDate": "2019-12-18T10:16:21.455Z",
"itemType": "string",
"sourceTask": "string",
"size": 0,
"state": 0,
"thumbnail": true
}
```
Response 401 Not authenticated
Response 403 No WRITE permissions in parent item
Response 404 Parent Item not found
**Call the vranbs task**
Execute the VRANbsTask with the item code of the cropfield as parameter inside {code}.
Use the code obtained from creating the user.input item as a parameter in {itemCode}.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.vranbs",
"attributes": {
"operation": "targetn",
"inputCode": "{itemCode}",
"plantingDate": "2020-02-01T00:00:00.000Z",
"measurementDate": "2020-06-01T00:00:00.000Z",
"purposeType": "consumption", // consumption, fries, potato, starch
"targetYield": "60"
}
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.workflow"
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
**Query user.input targetN item**
You can query the user.input item to get the calculated targetN value from the data field of the item.
> Request
```javascript
GET /api/v1/items/{code}
```
> Response 200
```javascript
{
"parentCode": "string",
"geometry": {},
"data": {
"TSum": "2700",
"TargetYield": "60",
"TargetN": "249.2341"
},
"tags": [
"string"
],
"url": "string",
"code": "string",
"name": "TargetN",
"created": "2019-12-18T10:16:21.455Z",
"updated": "2019-12-18T10:16:21.455Z",
"dataDate": "2019-12-18T10:16:21.455Z",
"itemType": "vnd.farmmaps.itemtype.user.input",
"sourceTask": "string",
"size": 0,
"state": 0,
"thumbnail": true
}
```
###### Uptake map operation
Execute the VRANbsTask with the item code of the cropfield as parameter inside {code}.
Use the input map code inside {itemCode}, specifying an inputCode for the input data item.
{itemCode} needs the code of the data input item passed into it. ex. uploaded isaria/data data.
The resulting nitrogen uptake map will be created as a child item under the cropfield item (this can be queried).
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.vranbs",
"attributes": {
"operation": "uptake",
"inputCode": "{itemCode}",
"plantingDate": "2020-02-01T00:00:00.000Z",
"measurementDate": "2020-06-01T00:00:00.000Z",
"inputType": "irmi", // yara, ci, irmi or wdvi
}
}
```
> Response 201
```javascript
{
"code": "string", // code of task operation, can be queried for status
"taskType": "vnd.farmmaps.task.vranbs",
"attributes": {
"operation": "uptake",
"inputCode": "{itemCode}",
"inputType": "irmi", // yara, ci, irmi or wdvi
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
###### Application map operation
Execute the VRANbsTask with the item code of the cropfield as parameter inside {code}.
Use the input map code inside {itemCode}, specifying an inputCode for the input data item.
{itemCode} needs the code of the data input item passed into it. ex. uploaded isaria/data data.
The resulting nitrogen application map will be created as a child item under the cropfield item (this can be queried).
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.vranbs",
"attributes": {
"operation": "application",
"inputCode": "{itemCode}",
"plantingDate": "2020-02-01T00:00:00.000Z",
"measurementDate": "2020-06-01T00:00:00.000Z",
"inputType": "irmi", // yara, ci, irmi or wdvi
"targetN": "249.22948"
}
}
```
> Response 201
```javascript
{
"code": "string", // code of task operation, can be queried for status
"taskType": "vnd.farmmaps.task.vranbs",
"attributes": {
"operation": "nitrogen",
"inputCode": "{itemCode}",
"inputType": "irmi", // yara, ci, irmi or wdvi
"targetN": "249.22948"
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
##### Create taskmap
[Create Taskmap](Create-Taskmap.md)
##### Download the data
In case the data is available it can be downloaded with the File API.
> Request
```javascript
GET /api/v1/items/{itemcode}/data

View File

@ -1,85 +1,85 @@
## VRAPoten API v0.1.1
[<< Home](README.md)
FarmMaps is an asynchronous architecture, the API flow keeps this in mind.
The API expects that all data is already processed and available provided, for example through the normal FarmMaps flow.
For the currently available public FarmMaps API you can take a look at swagger: http://farmmaps.awtest.nl/swagger/index.html
**Input preperation**
* VRAPoten requires specific input which needs to be provided by the FarmMaps API or user interface.
* You can activate the VRAPotenTask with the Task API, passing the just created cropfield item code as a parameter.
* Users can upload their own soilmaps if needed. (in case of when FarmMaps has not processed the required data).
* The file API can be used for this.
**Users can poll the task api to see if a task is completed**
**This can be achieved with the task execution id obtained from calling the 'ItemTask' API.**
[Poll task status](Polling-task-status.md)
### API flow
* Authenticate User
* *Create cropfield through FarmMaps API (optioneel)*
* Item 'FOLDER' must be created for parent to cropfields.
* Item 'vnd.farmmaps.itemtype.cropfield' must be created with its data as specified in the api.
* Task 'vnd.farmmaps.task.workflow' needs to be executed to aggregate all needed data.
* This is an asynchronous process and can take a while before all data is collected in FarmMaps.
* Upload own soil data (optioneel)
* Task 'vnd.farmmaps.task.vrapoten' must be executed to create an appliance map.
* Task 'vnd.farmmaps.task.taskmap' must be executed to create a taskmap.
* Download item data (tiff of shape)
### Steps
###### Authentication
[Authentication](Authentication.md)
###### Create cropfield with FarmMaps API (optional)
[Create Cropfield](Create-Cropfield.md)
###### Uploading own data (optional)
[Upload Data](Upload-Data.md)
###### Creating appliance maps
Execute the VRAPotenTask with the item code of the cropfield as parameter inside {code}.
Use the input map code inside {itemCode}, specifying an inputCode is optional.
In case of no specified inputCode the BOFEK data is looked up and if it could not be found the task gives an error.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.vrapoten",
"attributes": {
"inputCode": "{itemCode}",
"meanDensity": "30",
"variation": "20"
}
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.workflow",
"delay": "",
"attributes": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
###### Create taskmap
[Create Taskmap](Create-Taskmap.md)
###### Download the data
In case the data is available it can be downloaded with the File API.
> Request
```javascript
GET /api/v1/items/{itemcode}/data
## VRAPoten API v0.1.1
[<< Home](README.md)
FarmMaps is an asynchronous architecture, the API flow keeps this in mind.
The API 2 that all data is already processed and available provided, for example through the normal FarmMaps flow.
For the currently available public FarmMaps API you can take a look at swagger: http://farmmaps.awtest.nl/swagger/index.html
**Input preperation**
* VRAPoten requires specific input which needs to be provided by the FarmMaps API or user interface.
* You can activate the VRAPotenTask with the Task API, passing the just created cropfield item code as a parameter.
* Users can upload their own soilmaps if needed. (in case of when FarmMaps has not processed the required data).
* The file API can be used for this.
**Users can poll the task api to see if a task is completed**
**This can be achieved with the task execution id obtained from calling the 'ItemTask' API.**
[Poll task status](Polling-task-status.md)
### API flow
* Authenticate User
* *Create cropfield through FarmMaps API (optioneel)*
* Item 'FOLDER' must be created for parent to cropfields.
* Item 'vnd.farmmaps.itemtype.cropfield' must be created with its data as specified in the api.
* Task 'vnd.farmmaps.task.workflow' needs to be executed to aggregate all needed data.
* This is an asynchronous process and can take a while before all data is collected in FarmMaps.
* Upload own soil data (optioneel)
* Task 'vnd.farmmaps.task.vrapoten' must be executed to create an appliance map.
* Task 'vnd.farmmaps.task.taskmap' must be executed to create a taskmap.
* Download item data (tiff of shape)
### Steps
###### Authentication
[Authentication](Authentication.md)
###### Create cropfield with FarmMaps API (optional)
[Create Cropfield](Create-Cropfield.md)
###### Uploading own data (optional)
[Upload Data](Upload-Data.md)
###### Creating appliance maps
Execute the VRAPotenTask with the item code of the cropfield as parameter inside {code}.
Use the input map code inside {itemCode}, specifying an inputCode is optional.
In case of no specified inputCode the BOFEK data is looked up and if it could not be found the task gives an error.
> Request
```javascript
POST /api/v1/items/{code}/tasks
{
"taskType": "vnd.farmmaps.task.vrapoten",
"attributes": {
"inputCode": "{itemCode}",
"meanDensity": "30",
"variation": "20"
}
}
```
> Response 201
```javascript
{
"code": "string",
"taskType": "vnd.farmmaps.task.workflow",
"delay": "",
"attributes": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
```
Response 400 Tasktype not found
Response 401 Not authenticated
Response 403 No WRITE permissions in item
Response 404 Item not found
###### Create taskmap
[Create Taskmap](Create-Taskmap.md)
###### Download the data
In case the data is available it can be downloaded with the File API.
> Request
```javascript
GET /api/v1/items/{itemcode}/data
```