Grow Recipe Schema

A grow recipe defines instructions for how to grow plants in a controlled environment. Typically, recipes are printed in plain text which make it easier for farmers to read. However, plain text recipes are not easy for computers to intepret. As more effort is being put into automation of plant production, there needs to be a interoperable method of storing recipes. Defining a schema for grow recipes will ensure they can be safely interpreted by multiple types of grow systems.

Getting Started

Say you are given an instruction to keep the air temperature above 65℉. This is how you can translate this requirement into a grow recipe:

<?xml version="1.0" encoding="UTF-8"?>

<recipe>

  <default>
    <air>
      <temperature min="18.3" />
    </air>
  </default>

</recipe>

Notice the conversion from Fahrenheit to Celsius. All metrics defined in a grow recipe are standardized to SI. A complete list of metric types and their units can be found in Metrics.

Next, say you are now given a second instruction keep the air temperature between 75℉ and 85℉ during flowering. You can add this second instruction into you existing recipe:

<?xml version="1.0" encoding="UTF-8"?>

<recipe>

  <default>
    <air>
      <temperature min="18.3" />
    </air>
  </default>

  <flowering>
    <air>
      <temperature min="23.9" max="29.4" />
    </air>
  </flowering>

</recipe>

Structure

The root element of a grow recipe is recipe. Although the structure of the recipes is strictly defined, all data is optional. An extreme example used to prove this point would be a completely empty recipe.

<?xml version="1.0" encoding="UTF-8"?>

<recipe>
</recipe>

The minimum required structure is the XML document declaration and the root recipe element to pass Schema validation. The flexibility to specify as much or little data as desired allows for growers at any skill level to utilize the Grow Recipe Standard. For example, a novice grower whose only defined recipe rule is to maintain a constant air temperature between 18℃ and 24℃ would have his recipe look as such:

<?xml version="1.0" encoding="UTF-8"?>

<recipe>

  <default>
    <air>
      <temperature min="18" max="24" />
    </air>
  </default>

</recipe>

The default node is a special node under the root node recipe because it is used to define cycles and metrics which are fallback throughout the grow. The default stage should be used primarily to alleviate the need to specify redundant data within the various stages of a grow. Any cycle or metric defined in the default stage should be overridden by any matching cycles or metrics defined in other stages. For example, imagine our novice grower has learned that his seeds will germinate faster if the air temperature is increased. The novice grower’s recipe might evolve into something like:

<?xml version="1.0" encoding="UTF-8"?>

<recipe>

  <default>
    <air>
      <temperature min="18" max="24" />
    </air>
  </default>
    
  <germination>
    <air>
      <temperature min="26" max="32" />
    </air>
  </germination>

</recipe>

Metrics can also be defined in periods within a cycle which can be used to represent different periods of a day. Let’s say our novice grower has learned that his plants react positively to dropping the temperature for a certain period of the day. The grower’s recipe might evolve into something like:

<?xml version="1.0" encoding="UTF-8"?>

<recipe>

  <default>
    <!-- 24 hours -->
    <cycle duration="86400">

      <!-- Day Time, 18 hours -->
      <period start="0" end="64799">
        <air>
          <temperature min="18" max="24" />
        </air>
      </period>

      <!-- Night Time, 6 hours -->
      <period start="64800" end="86399">
        <air>
          <temperature min="15" max="17" />
        </air>
      </period>
      
    </cycle>
  </default>
  
  <germination>
    <air>
      <temperature min="26" max="32" />
    </air>
  </germination>

</recipe>

This example also demonstrates metric and cycle definition specificity. The most specific metric and cycle definitions should always be used at any given time in a grow. Metric and cycle definitions within the current stage should always take priority to ones defined in the default stage. Also, metric definitions defined within the current stage cycle period should take priority over metric definitions defined within the current stage, but outside of the stage cycle. Here is a list of priority when choosing the specificity of a metric definition at a given time from highest to lowest:

  1. Current stage, current stage cycle period
  2. Current stage outside of stage cycle
  3. Default, current cycle period
  4. Default, outside of default cycle

There are predefined stages that can be used. These stages are:

  1. default
  2. germination
  3. vegetative
  4. flowering
  5. fruiting

Metrics

Metrics are broken down into three topics: Air, Light, and Water. Each metric contains a min and max acceptable value. The smaller the difference between the min and max of a metric, the more strictly it should be regulated. The absence of a metric should indicate that the metric should not be tracked. If a certain metric is supposed to not appear, it should be explicitly defined with a min and max of zero.

Air

Name Unit
temperature
relative-humidity %
co mg/m3 (a ppm converter.)

Water

Name Unit
temperature
electro-conductivity mS/cm
dissolved-oxygen mg/L (a ppm converter.)
oxidizing-reduction-potential mV
hardness mg/L
ph pH
vpd kPa
bicarbonate mg/L
nitrogen mg/L
potassium mg/L
calcium mg/L
magnesium mg/L
sulfer mg/L
iron mg/L
copper mg/L
zinc mg/L
manganese mg/L
sodium mg/L
boron mg/L
chlorine mg/L
silicon mg/L
iron-chelates mg/L
sodium-chloride mg/L

Light

Light metrics are separated into one or more bands. A band is defined as an upper and lower wavelength (nanometers) within the electromagnetic spectrum. Within a band a light intensity is defined with the usual min and max values. Light intensity is represented in PPFD (µmol/m2/s)

<?xml version="1.0" encoding="UTF-8"?>

<recipe>

  <default>
    <light>
      <!--red-->
      <band min="590" max="750">
        <ppfd min="650" max="650" />
      </band>
    </light> 
  </default>
    
</recipe>

Indices and tables