diff --git a/README.md b/README.md index 520807e..ed49bf6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ATA defines a standard, programming language-agnostic interface description for REST APIs, which allows both humans and computers to discover and understand the capabilities of a service without requiring access to source code or inspection of network traffic. When an API conforms to ATA, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interface descriptions have done for lower-level programming, ATA removes guesswork in calling a service. Use cases for machine-readable API definition documents include, but are not limited to: interactive documentation; code generation for documentation, clients, and servers; and automation of test cases. ATA documents describe an API's services and are represented in either YAML or JSON formats. These documents may either be produced and served statically or be generated dynamically from an application. -The current version of the AgTech API Specification is [Version 0.0.1](versions/0.0.1.md). The next version will be 0.0.2. +The current version of the AgTech API Specification is [Version 0.0.1](versions/0.0.1). The next version will be 0.0.2. ### See It in Action @@ -14,9 +14,10 @@ Development of ATA is guided by the Technical Steering Committee (TSC). All deve The TSC holds weekly web conferences to review open pull requests and discuss open issues related to ATA. Participation in weekly calls and scheduled working sessions is open to the community. Open AgTech encourages participation from individuals and companies alike. If you want to participate in the evolution of ATA, consider taking the following actions: -- Review the current specification. The human-readable markdown file is the source of truth for the specification. +- Review the current specification, in [master](versions/master). - Review the development process so you understand how the spec is evolving. - Check the issues and pull requests to see if someone has already documented your idea or feedback on the specification. You can follow an existing conversation by adding a comment to the existing issue or PR. - Create an issue to describe a new concern. If possible, propose a solution. +- Open a PR related to your issue or concern. This will be reviewed and merged by the TSC. Not all feedback can be accommodated and there may be solid arguments for or against a change being appropriate for the specification. diff --git a/versions/0.0.1/README.md b/versions/0.0.1/README.md new file mode 100644 index 0000000..b4e8c62 --- /dev/null +++ b/versions/0.0.1/README.md @@ -0,0 +1,13 @@ +# API Specification +This directory contains the various parts of the open API specification for exchanging data and operational control in indoor agricultural environments. + +The specification is divided into the following sub-sections to make it easier to follow... + +* **General** - contains all of the essential rules that need to be followed, including common concepts, common data structures, timestamp formats, error handling, and so on. +* **Plan** - specifies the API for interacting with the basic concepts of a well-planned facility (compartments, zones, crop varieties, and so on) +* **Lights** - specifies the API for interacting with lighting systems +* **Air** - specifies the API for interacting with air control systems (heating, cooling, ventilation, humidity, and so on) +* **Soil** - specifies the API for interacting with soil monitoring systems +* **Roots** - specifies the API for interacting with root monitoring systems +* **Reservoirs** - specifies the API for interacting with reservoir control systems +* **Nutrients** - specifies the API for monitoring nutrients diff --git a/versions/0.0.1/air.md b/versions/0.0.1/air.md new file mode 100644 index 0000000..d8660f5 --- /dev/null +++ b/versions/0.0.1/air.md @@ -0,0 +1,22 @@ +# Purpose + +This specification is intended to define a standardized way of communicating with climate control systems for real-time monitoring and control of air quality and to allow data collection between control systems and / or peripheral devices. + +# Scope + +The scope of this document is limited to providing a payload structure and endpoint type definitions to allow basic control and data acquisition. The addition of product specific features is left to the implementer, but to be in compliance the product must support the basic set of features specified below. + +# Definitions + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. + +# Endpoints +## Sensors +### URLS +### Measurements +| Data point | Description | Unit | +| ---------- | -------------------------------- | ------- | +| temp | The temperature of the air | celsius | +| humidity | The level of humidity in the air | % | +| co2 | The level of CO2 in the air | ppm | +| airflow | The speed of the airflow | m3/s | \ No newline at end of file diff --git a/versions/0.0.1/general.md b/versions/0.0.1/general.md new file mode 100644 index 0000000..a6490f2 --- /dev/null +++ b/versions/0.0.1/general.md @@ -0,0 +1,890 @@ +# Purpose + +This specification is intended to define a standardized way of communicating real-time command-and-control data and to allow data collection between control systems and / or peripheral devices. + +# Scope + +The scope of this document is limited to providing a payload structure and endpoint type definitions to allow basic control and data acquisition. This document does not set out to define an API but rather to specify a uniform way to build one. It does not seek to dictate endpoint names, server architecture, or security protocols. The addition of product specific features is left to the implementer, but to be in compliance the product must support the basic set of features specified below. + +# Definitions + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. + +# Common Concepts + +There are specific concepts that all participants in this open API must support in order to make interaction possible. Each of these concepts should be driven by factory configurations or by on-site configurations made by the customer or a professional integrator. +The diagram below captures their essential relationships. + +![Common Concepts](https://docs.google.com/drawings/d/e/2PACX-1vRptSa5X7K6yzOqA95Jpncwwl8rUZgxOo6l13m_VcnCyd5dHmlLZvUyrED-HX2b5Q9YNHiBltB6cY5t/pub?w=982&h=1042) + +## Company + +A company refers to a single entity that owns and operates one or more facilities. Each company makes its own purchasing and planning decisions and has only one set of executives. + +## System + +Every company has one or more systems that are helping to control all activity related to agriculture (e.g., Argus, Lumigrow, Priva, and so on). In order to help identify compatibility levels, each system should be able to report its make and model number as well as a version number related to its embedded software. Each system can own one or more systems and / or devices and must be able to accept calls on behalf of its devices. For example, a large climate control system might own a network of light and air sensors while also controlling lighting, ventilation and irrigation systems. Systems can manage devices across zones and crops. + +## Crop Variety + +A crop refers to one or more types of plants that are being grown in the same environment - i.e., if a single greenhouse is inter-planting strawberries and mint, this would be considered a single crop for the purposes of management and prediction. Crop variety IDs do not need to be standardized, so long as they are consistent within a single company. + +## Facility + +A facility is a single physical site that contains one or more compartments - e.g., a greenhouse. A company can own many facilities and each facility will have one or more Head Growers to oversee its operations. + +## Compartment + +A compartment is a physically isolated space within a facility for the purpose of establishing a unique macro climate. Each compartment is dedicated to one or more crop varieties. Every compartment has a length, width and height. By default, every compartment contains a single zone that is the length, width, and height of the compartment. + +## Zone + +A zone identifies an area within a compartment dedicated to maintaining a micro-climate. For example, a compartment would maintain uniform levels of humidity and air temperature, whereas a zone might alter the light levels or nutrient mix in the irrigation to create unique micro-climates. + +Every zone contains zero or more zones and / or devices. Every device that is deployed should be assigned to the correct zone. Zones are a natural way of grouping devices for control purposes, so that a configuration can be pushed to a zone and affect all relevant devices within the zone at the same time. + +All zones must be able to identify the crop variety they are overseeing. All data produced from a zone must include a crop variety ID for easy identification. + +Each zone must be able to identify its size (in width and height) as well as its relative location within the compartment, since all sensors and controllers within that zone will report their location relative to the zone, not the compartment. + +Zones can be combined into deep hierarchies. For example, a compartment can have multiple rows of plants that are 1 foot off the floor (e.g., lettuce), with an additional layer of plants 4 feet off the floor (e.g., strawberries). The grower would want to create unique zones for the lettuce vs. the strawberries, reflecting their unique feeds for irrigation and supplemental lighting. However, the grower would also want to maintain a general climate zone for the overall compartment for the purposes of controlling heating and ventilation. This means that the compartment would have a global zone containing two sub-zones. + +## Location + +Every device and zone should know its position relative to its container (devices are contained by zones, zones are contained by compartments). Locations are described using x, y, and z co-ordinates (or length, width, and height). + +## Device + +A device refers to any physical mechanism that can either monitor or control the growing environment (lights, pumps, heaters, humidifiers, etc). + +Every device must be related to a zone and a location within that zone. It should be able to report these relationships along with its own unique ID. + +## Sensor + +A sensor refers to any device that is gathering data about the growing environment (light, air, water, nutrients, and so on). + +## Controller + +A controller refers to any device that can affect the growing environment (light fixtures, nutrient dosers, heaters, humidifiers, and so on). + +# Endpoint Structure + +The detailed endpoint structure is outside the scope of this document because it needs to make sense for the overall architecture of the implementation. However, there are a few standards that need to be considered when it comes to endpoint design. + +*Path elements within the URL...* +- The first element of all compliant apis MUST be "agroapi" +- The second element of all compliant apis MUST be the version number +- The third element of all compliant apis MUST be a domain identifier (e.g., "lights", "air", and so on) +- All elements after the third and before the final element are optional and SHOULD describe collections and / or a single member of a collection +- The final element of all compliant apis MUST identify the information or action that is the subject of the call + +*Structure of collections...* +- Collection identifiers MUST be plural +- Endpoints SHOULD NOT nest more than 2 collections deep (e.g., collection/{id}/collection/{id}) + +*Data structures...* +- Individual data points coming from the same device SHOULD be grouped in a structure with other data points that are related to the same topic + +**Example** + +GET https://www.googleapis.com/books/v1/volumes/zyTCAlFPjgYC?key=yourAPIKey + +# Error Handling + +In principle, a successful API call should return an HTTP status code of 200. An unsuccessful API call will return an HTTP status code of 550 and the body should contain an error code that has been properly documented by the owner of the API. + +The interpretation of error codes, including the text describing the error, will be left up to the API user based on their understanding of the error code documentation provided by the API owner. + +# Validation Handshake + +*TBD* + +Although a data consumer / receiver will have its own limits when it comes to value ranges and so on, there is a perceived need for the consumer / receiver to know what value ranges the data producer / sender might provide. This gives the consumer / receiver a secondary validation check to ensure that the data makes sense. + +# Timestamps + +All monitoring data MUST be accompanied by a timestamp that includes year, month, day, hour, minute, second, and time zone. The format MUST be as follows… + +```[year]-[month]-[day]_[hour]-[min]-[sec]_[timezone]``` + +Here is an example of a properly formatted timestamp… + +```2018-01-25_04-56-05_UTC``` + +# Common Structures +Many concepts use the same data structures to report their essential information. Those structures are listed here. + +## Info Data +| Name | Description | Unit | +| ----------- | ----------------------------------------------- | ---- | +| id | ID of the entity | uid | +| zone | ID of the zone containing this entity | uid | +| compartment | ID of the compartment that contains this entity | uid | +| facility | ID of the facility that contains this entity | uid | + +## Version Data +| Name | Description | Unit | +| ------- | ------------------------------------------ | ---- | +| id | unique id of the device | uid | +| make | Name of the company that makes this device | text | +| model | Model number of this device | text | +| version | Version number of this device | text | + +## Location Data +| Name | Description | Unit | +| ---- | ------------------------------------------------------- | ---- | +| id | Unique id of this entity | uid | +| x | x coordinate of this entity within its parent container | m | +| y | y coordinate of this entity within its parent container | m | +| z | z coordinate of this entity within its parent container | m | + +## Dimension Data +| Name | Description | Unit | +| ------ | ----------------------- | ---- | +| id | Unique id of the entity | uid | +| length | Length of the entity | m | +| width | Width of the entity | m | +| height | Height of the entity | m | + +# Data Types +## Boolean +Used to express T/F, Y/N, or ON/OFF values +```json +type: object + required: + - name + - status + properties: + status: + type: bool +``` +## Integer +Used to express whole 4-byte numbers +```json +type: object + required: + - name + - value + properties: + value: + type: integer +``` +## Decimal +Used to express numbers with 8-byte decimal precision +```json +type: object + required: + - name + - value + properties: + value: + type: number + format: double +``` +## String +Used to send alphanumeric strings +```json +type: object + required: + - name + - text + properties: + text: + type: string +``` + +# Primitive Endpoints +The following endpoints provide examples of payloads that would be exchanged for any endpoints that are trying to work with simple primitive values (e.g., a single number, boolean flag, or piece of text). + +Request and response bodies are presented below in JSON as well as YAML (which is compatible with OpenAPI 3.0). +NOTE: proper RESTful URLs should contain the identification of the entities being queries or acted upon (names or IDs) in the URL itself. Therefore, those identifications do not show up in the payloads. + +## Integer +**Operation:** GET +Fetches an integer entry. This will fail if the integer entry does not yet exist. +**Request Body** +None +**Response Body** +YAML +``` +responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + required: + - value + properties: + value: + type: integer + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "value": "", + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` + +**Operation:** POST +Updates an existing integer entry. This will fail if the integer entry does not yet exist. +**Request Body** +YAML +``` +required: true + content: + application/json: + schema: + type: object + required: + - value + properties: + value: + type: integer +``` +JSON +```json +{ + "value": "" +} +``` +**Response Body** +YAML +``` +responses: + '200': + description: Success + content: + application/json: + schema: + type: object + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` +**Operation:** PUT +Creates a new integer entry. This will fail if the integer entry already exists. +**Request Body** +YAML +``` +required: true + content: + application/json: + schema: + type: object + required: + - value + properties: + value: + type: integer +``` +JSON +```json +{ + "value": "" +} +``` +**Response Body** +YAML +``` +responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` +**Operation:** DELETE +Deletes an existing integer entry. This will fail if the integer entry does not already exist. +**Request Body** +None +**Response Body** +YAML +``` +responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` +## Decimal +**Operation:** GET +Fetches a decimal entry. This will fail if the decimal entry does not yet exist. +**Request Body** +None +**Response Body** +YAML +``` +responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + required: + - value + properties: + value: + type: double + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "value": "", + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` +**Operation:** POST +Updates an existing decimal entry. This will fail if the decimal entry does not yet exist. +**Request Body** +YAML +``` +required: true + content: + application/json: + schema: + type: object + required: + - value + properties: + value: + type: double +``` +JSON +```json +{ + "value": "" +} +``` +**Response Body** +YAML +``` +responses: + '200': + description: Success + content: + application/json: + schema: + type: object + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` +**Operation:** PUT +Creates a new decimal entry. This will fail if the decimal entry already exists. +**Request Body** +YAML +``` +required: true + content: + application/json: + schema: + type: object + required: + - value + properties: + value: + type: double +``` +JSON +```json +{ + "value": "" +} +``` +**Response Body** +YAML +``` +responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` +**Operation:** DELETE +Deletes an existing decimal entry. This will fail if the decimal entry does not already exist. +**Request Body** +None +**Response Body** +YAML +``` +responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` +## String +**Operation:** GET +Fetches a string entry. This will fail if the string entry does not yet exist +**Request Body** +None +**Response Body** +YAML +``` +responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + required: + - value + properties: + value: + type: string + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "value": "", + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` + +**Operation:** POST +Updates an existing string entry. This will fail if the string entry does not yet exist. +**Request Body** +YAML +``` +required: true + content: + application/json: + schema: + type: object + required: + - value + properties: + value: + type: string +``` +JSON +```json +{ + "value": "" +} +``` +**Response Body** +YAML +``` +responses: + '200': + description: Success + content: + application/json: + schema: + type: object + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` +**Operation:** PUT +Creates a new string entry. This will fail if the string entry already exists. +**Request Body** +YAML +``` +required: true + content: + application/json: + schema: + type: object + required: + - value + properties: + value: + type: string +``` +JSON +```json +{ + "value": "" +} +``` +**Response Body** +YAML +``` +responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` +**Operation:** DELETE +Deletes an existing string entry. This will fail if the string entry does not already exist. +**Request Body** +None +**Response Body** +YAML +``` +responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + links: + type: array + items: + type: string + '400': + description: Failure + content: + application/json: + schema: + type: object + required: + - error + properties: + error: + type: integer + links: + type: array + items: + type: string +``` +JSON +```json +200: +{ + "links": [{""},{"..."}] +} +400: +{ + "error": "", + "links": [{""},{"..."}] +} +``` diff --git a/versions/0.0.1/light.md b/versions/0.0.1/light.md new file mode 100644 index 0000000..51e4e34 --- /dev/null +++ b/versions/0.0.1/light.md @@ -0,0 +1,216 @@ +# Purpose + +This specification is intended to define a standardized way of communicating with lighting systems for real-time monitoring and control and to allow data collection between control systems and / or peripheral devices. + +**NOTE:** need to add API to query last-known update...identify what was done and when (and by whom?) + +# Scope + +The scope of this document is limited to providing a payload structure and endpoint type definitions to allow basic control and data acquisition. The addition of product specific features is left to the implementer, but to be in compliance the product must support the basic set of features specified below. + +# Definitions + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. + +# Endpoints +## Sensors +### Talking to one sensor +``` +GET http://[domain:port]/agroapi/[version]/lights/sensors/[sensorid]/info +``` +Returns [Info](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#info-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/sensors/[sensorid]/version +``` +Returns [Version](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#version-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/sensors/[sensorid]/location +``` +Returns [Location](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#location-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/sensors/[sensorid]/ppf +``` +Returns [Light PPF](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#light-ppf) + +``` +GET http://[domain:port]/agroapi/[version]/lights/sensors/[sensorid]/ppfd +``` +Returns [Light PPFD](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#light-ppfd) + +### Talking to all sensors +``` +GET http://[domain:port]/agroapi/[version]/lights/sensors/info +``` +Returns an array of [Info](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#info-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/sensors/version +``` +Returns an array of [Version](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#version-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/sensors/location +``` +Returns an array of [Location](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#location-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/sensors/ppf +``` +Returns an array of [Light PPF](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#light-ppf) + +``` +GET http://[domain:port]/agroapi/[version]/lights/sensors/ppfd +``` +Returns an array of [Light PPFD](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#light-ppfd) + +### Talking to all sensors in a zone +``` +GET http://[domain:port]/agroapi/[version]/zones/[zoneid]/lights/sensors/info +``` +Returns an array of [Info](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#info-data) + +``` +GET http://[domain:port]/agroapi/[version]/zones/[zoneid]/lights/sensors/version +``` +Returns an array of [Version](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#version-data) + +``` +GET http://[domain:port]/agroapi/[version]/zones/[zoneid]/lights/sensors/location +``` +Returns an array of [Location](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#location-data) + +``` +GET http://[domain:port]/agroapi/[version]/zones/[zoneid]/lights/sensors/ppf +``` +Returns an array of [Light PPF](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#light-ppf) + +``` +GET http://[domain:port]/agroapi/[version]/zones/[zoneid]/lights/sensors/ppfd +``` +Returns an array of [Light PPFD](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#light-ppfd) + +### Light PPF +| Name | Description | Unit | +| --------- | -------------------------------- | -------- | +| id | Unique id of the device | uid | +| timestamp | UTC timestamp of the measurement | datetime | +| red | Level of red spectrum light | PPF | +| blue | Level of blue spectrum light | PPF | +| green | Level of green spectrum light | PPF | +| uv | Level of ultraviolet light | PPF | +| infrared | Level of infrared light | PPF | +| par | Level of absorbable light | PPF | +| light | Level of all spectrums of light | PPF | + +### Light PPFD +| Name | Description | Unit | +| --------- | -------------------------------- | -------- | +| id | Unique id of the device | uid | +| timestamp | UTC timestamp of the measurement | datetime | +| red | Level of red spectrum light | PPFD | +| blue | Level of blue spectrum light | PPFD | +| green | Level of green spectrum light | PPFD | +| uv | Level of ultraviolet light | PPFD | +| infrared | Level of infrared light | PPFD | +| par | Level of absorbable light | PPFD | +| light | Level of all spectrums of light | PPFD | + +## Fixtures +### Talking to one fixture +``` +GET http://[domain:port]/agroapi/[version]/lights/fixtures/[fixtureid]/info +``` +Returns [Info](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#info-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/fixtures/[fixtureid]/version +``` +Returns [Version](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#version-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/fixtures/[fixtureid]/location +``` +Returns [Location](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#location-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/fixtures/[fixtureid]/config +``` +Returns [Fixture Configuration](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#fixture-configuration) + +``` +GET http://[domain:port]/agroapi/[version]/lights/fixtures/[fixtureid]/power +``` +Returns [Fixture Power](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#fixture-power) + +### Talking to all fixtures +``` +GET http://[domain:port]/agroapi/[version]/lights/fixtures/info +``` +Returns an array of [Info](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#info-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/fixtures/version +``` +Returns an array of [Version](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#version-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/fixtures/location +``` +Returns an array of [Location](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#location-data) + +``` +GET http://[domain:port]/agroapi/[version]/lights/fixtures/config +``` +Returns an array of [Fixture Configuration](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#fixture-configuration) + +``` +GET http://[domain:port]/agroapi/[version]/lights/fixtures/power +``` +Returns an array of [Fixture Power](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#fixture-power) + +### Talking to all fixtures in a zone +``` +GET http://[domain:port]/agroapi/[version]/zones/[zoneid]/lights/fixtures/info +``` +Returns an array of [Info](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#info-data) + +``` +GET http://[domain:port]/agroapi/[version]/zones/[zoneid]/lights/fixture/[fixtureid]/version +``` +Returns an array of [Version](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#version-data) + +``` +GET http://[domain:port]/agroapi/[version]/zones/[zoneid]/lights/fixtures/location +``` +Returns an array of [Location](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#location-data) + +``` +GET http://[domain:port]/agroapi/[version]/zones/[zoneid]/lights/fixtures/config +``` +Returns an array of [Fixture Configuration](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#fixture-configuration) + +``` +GET http://[domain:port]/agroapi/[version]/zones/[zoneid]/lights/fixtures/power +``` +Returns an array of [Fixture Power](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#fixture-power) + +### Fixture Configuration +| Name | Description | Unit | +| -------- | ------------------------------- | ----- | +| id | Unique id of the fixture | uid | +| channels | array of channel configurations | [Channel Configuration](https://github.com/open-ag-tech/api-spec/blob/master/versions/light-0.0.1.md#channel-configuration) | +### Channel Configuration +| Name | Description | Unit | +| --------- | ------------------------------------- | ----- | +| id | Unique id of the channel | uid | +| lower | Lower boundary of the frequency range | nm | +| upper | Upper boundary of the frequency range | nm | +| intensity | Light intensity | % | +### Fixture Power +| Name | Description | Unit | +| ------ | ------------------------------ | ------------- | +| id | Unique id of the fixture | uid | +| status | The active state of the lights | "on" or "off" | diff --git a/versions/0.0.1/nutrients.md b/versions/0.0.1/nutrients.md new file mode 100644 index 0000000..7757c01 --- /dev/null +++ b/versions/0.0.1/nutrients.md @@ -0,0 +1,31 @@ +# Purpose + +This specification is intended to define a standardized way of communicating with climate control systems for real-time monitoring and control of root systems and to allow data collection between systems and / or peripheral devices. + +# Scope + +The scope of this document is limited to providing a payload structure and endpoint type definitions to allow basic control and data acquisition. The addition of product specific features is left to the implementer, but to be in compliance the product must support the basic set of features specified below. + +# Definitions + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. + +# Endpoints +## Sensors +### URLS +### Measurements +| Data point | Description | Unit | +| ---------- | ----------------------------- | ---- | +| nitrogen | The amount of nitrogen (N) | ppm | +| phosphorus | The amount of phosphorus (P) | ppm | +| potassium | The amount of potassium (K) | ppm | +| sulphur | The amount of sulfur (S) | ppm | +| calcium | The amount of calcium (Ca) | ppm | +| magnesium | The amount of magnesium (Mg) | ppm | +| iron | The amount of iron (Fe) | ppm | +| manganese | The amount of manganese (Mg) | ppm | +| boron | The amount of boron (B) | ppm | +| copper | The amount of copper (Cu) | ppm | +| zinc | The amount of zinc (Zn) | ppm | +| molybdenum | The amount of molybdenum (Mo) | ppm | +| ammonium | The amount of ammonium (NH4+) | ppm | diff --git a/versions/0.0.1/plan.md b/versions/0.0.1/plan.md new file mode 100644 index 0000000..3862dbb --- /dev/null +++ b/versions/0.0.1/plan.md @@ -0,0 +1,118 @@ +# Purpose + +This specification is intended to define a standardized way of communicating with facility planning systems for planning the layout of a facility and the deployment of monitoring and control systems. + +# Scope + +The scope of this document is limited to providing a payload structure and endpoint type definitions to allow basic control and data acquisition. The addition of product specific features is left to the implementer, but to be in compliance the product must support the basic set of features specified below. + +# Definitions + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. + +# Endpoints +The relationship between the common concepts (facilities, compartments, zones, etc) is maintained as part of a Plan that can be interrogated. The following URLs MUST be supported by any service that wishes to interact with a Plan. + +## Facilities +### All facilities +``` +GET http://[domain:port]/agroapi/[version]/plan/facilities +``` +Returns an array of Facility IDs + +### Single facility +``` +GET http://[domain:port]/agroapi/[version]/plan/facilities/[facilityid]/compartments +``` +Returns an array of Compartment IDs + +``` +GET http://[domain:port]/agroapi/[version]/plan/facilities/[facilityid]/zones +``` +Returns an array of Zone IDs + +## Compartments +### All compartments +``` +GET http://[domain:port]/agroapi/[version]/plan/compartments +``` +Returns an array of Compartment IDs + +``` +GET http://[domain:port]/agroapi/[version]/plan/compartments/info +``` +Returns an array of [Info](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#info-data) + +``` +GET http://[domain:port]/agroapi/[version]/plan/compartments/location +``` +Returns an array of [Location](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#location-data) +``` +GET http://[domain:port]/agroapi/[version]/plan/compartments/dimensions +``` +Returns an array of [Dimensions](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#dimension-data) + + +### Single compartment +``` +GET http://[domain:port]/agroapi/[version]/plan/compartments/[compartmentid]/info +``` +Returns [Info](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#info-data) + +``` +GET http://[domain:port]/agroapi/[version]/plan/compartments/[compartmentid]/location +``` +Returns [Location](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#location-data) + +``` +GET http://[domain:port]/agroapi/[version]/plan/compartments/[compartmentid]/dimensions +``` +Returns [Dimensions](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#dimension-data) + +``` +GET http://[domain:port]/agroapi/[version]/plan/compartment/[compartmentid]/zones +``` +Returns an array of [Info](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#info-data) + +## Zones +### All zones +``` +GET http://[domain:port]/agroapi/[version]/plan/zones/info +``` +Returns an array of [Info](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#info-data) + +``` +GET http://[domain:port]/agroapi/[version]/plan/zones/location +``` +Returns an array of [Location](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#location-data) + +``` +GET http://[domain:port]/agroapi/[version]/plan/zones/dimensions +``` +Returns an array of [Dimensions](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#dimension-data) + +### Single zone +``` +GET http://[domain:port]/agroapi/[version]/plan/zones/[zoneid]/info +``` +Returns [Info](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#info-data) + +``` +GET http://[domain:port]/agroapi/[version]/plan/zones/[zoneid]/location +``` +Returns [Location](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#location-data) + +``` +GET http://[domain:port]/agroapi/[version]/plan/zones/[zoneid]/dimensions +``` +Returns [Dimensions](https://github.com/open-ag-tech/api-spec/blob/master/versions/general-0.0.1.md#dimension-data) + +``` +GET http://[domain:port]/agroapi/[version]/plan/zones/[zoneid]/zones +``` +Returns an array of Zone IDs + +``` +GET http://[domain:port]/agroapi/[version]/plan/zones/[zoneid]/crops +``` +Returns an array of Crop Variety IDs diff --git a/versions/0.0.1/reservoirs.md b/versions/0.0.1/reservoirs.md new file mode 100644 index 0000000..5d799f1 --- /dev/null +++ b/versions/0.0.1/reservoirs.md @@ -0,0 +1,24 @@ +# Purpose + +This specification is intended to define a standardized way of communicating with climate control systems for real-time monitoring and control of reservoir systems and to allow data collection between systems and / or peripheral devices. + +# Scope + +The scope of this document is limited to providing a payload structure and endpoint type definitions to allow basic control and data acquisition. The addition of product specific features is left to the implementer, but to be in compliance the product must support the basic set of features specified below. + +# Definitions + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. + +# Endpoints +## Sensors +### URLS +### Measurements +| Data point | Description | Unit | +| ---------- | -------------------------------------------------------------- | ------- | +| water | The amount of the water in the reservoir | % | +| temp | The temperature of the water / air around the roots | celsius | +| turbidity | The level of solids in the water | ntu | +| oxygen | The amount of oxygen dissolved in the water** around the roots | ppm | +| ec | The electrical conductivity of the water | Ds / m | +| ph | The alkalinity of the water | n/a | diff --git a/versions/0.0.1/roots.md b/versions/0.0.1/roots.md new file mode 100644 index 0000000..ad1dba4 --- /dev/null +++ b/versions/0.0.1/roots.md @@ -0,0 +1,27 @@ +# Purpose + +This specification is intended to define a standardized way of communicating with climate control systems for real-time monitoring and control of root systems and to allow data collection between systems and / or peripheral devices. + +# Scope + +The scope of this document is limited to providing a payload structure and endpoint type definitions to allow basic control and data acquisition. The addition of product specific features is left to the implementer, but to be in compliance the product must support the basic set of features specified below. + +# Definitions + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. + +# Endpoints +## Sensors +### URLS +### Measurements +| Data point | Description | Unit | +| ---------- | ------------------------------------------------------------------------ | ------- | +| water | The amount of the water surrounding the roots (aquaponics & hydroponics) | % | +| light | The level of all spectrums of light | µmoles | +| temp | The temperature of the water / air around the roots | celsius | +| humidity | The level of humidity around the roots (for airponics) | % | +| oxygen | The amount of oxygen dissolved in the water** around the roots | ppm | +| ec | The electrical conductivity of the water** around the roots | Ds / m | +| ph | The alkalinity of the water** around the roots | n/a | + +**NOTE:** for airponics, water levels would be measured from the moisture in the air around the roots diff --git a/versions/0.0.1/soil.md b/versions/0.0.1/soil.md new file mode 100644 index 0000000..980da37 --- /dev/null +++ b/versions/0.0.1/soil.md @@ -0,0 +1,25 @@ +# Purpose + +This specification is intended to define a standardized way of communicating with soil systems for real-time monitoring and control and to allow data collection between control systems and / or peripheral devices. + +# Scope + +The scope of this document is limited to providing a payload structure and endpoint type definitions to allow basic control and data acquisition. The addition of product specific features is left to the implementer, but to be in compliance the product must support the basic set of features specified below. + +# Definitions + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. + +# Endpoints +## Sensors +### URLS +### Measurements +| Data point | Description | Unit | +| ------------- | ----------------------------------------------------------------------- | ---------- | +| heatflow | The amount of heat that transfers from one point in the soil to another | watts / m2 | +| h2o-retention | The rate at which water dissipates from the soil | ??? | +| soil-temp | The temperature of the soil | celsius | +| humidity | The amount of humidity in the soil | % | +| oxygen | The amount of oxygen dissolved in the soil | % | +| ec | The electrical conductivity of the soil | Ds / m | +| ph | The alkalinity of the soil | n/a |