In this example we’ll get today’s weather forecast from an external service based on your FarmBot’s latitude and longitude. We’ll then determine if we should water a plant based on its age and watering curve as well as the expected volume of rain that will fall within the plant’s root zone.

Weather data provided by and licensed Attribution 4.0 International (CC BY 4.0).

Step 1: Add a plant variable

Add a location variable named “Plant” to the sequence. Set the variable to “Externally defined” with the default value set to a test plant. After testing you should set the default to “None”.

Step 2: Ensure your plants have watering curves

Make sure all of the plants you wish to use with this sequence have a water curve assigned to them. If a plant’s water_curve_id is not set, the sequence will skip watering that plant entirely.

Step 3: Add the Lua code

Add the Lua command with the following code:

plant = variable("Plant")
root_area = 3.14 * plant.radius^2

-- Get today's precipitation forecast from Open Meteo
request_url =
    "" ..
    "?latitude=" .. get_device("lat") ..
    "&longitude=" .. get_device("lng") ..
debug("Getting weather from " .. request_url)
api_response = http({url=request_url})
forecast = json.decode(api_response.body)
rain_mm = forecast.daily.precipitation_sum[1]

-- Calculate the volume of water the plant will get from the rain
rain_ml = math.floor(root_area * rain_mm / 1000)
debug("Forecasting " .. rain_mm .. "mm of rain today; plant's roots can expect " .. rain_ml .. "mL")

-- Get plant's water curve and water needs in mL based on plant's age
local water_curve, water_needs_ml
if plant.water_curve_id then
    water_curve = get_curve(plant.water_curve_id)
    water_needs_ml =
    debug("Plant needs " .. water_needs_ml .. "mL of water today")
    toast("Plant has no assigned water curve; skipping", "warn")

-- Determine how much FarmBot should water
water_deficit = water_needs_ml - rain_ml

-- Move to and water the plant, or don't
if water_deficit > 0 then
    toast("Watering the deficit amount of " .. water_deficit .. "mL.")
    move{ x = plant.x, y = plant.y, z = safe_z() }
    toast("Rain will provide enough water for this plant today; skipping")

Step 4: Make the sequence your own

Here are some ideas for modifying the sequence:

  • Add a loop to water all of the plant’s in the garden while only needing to get the weather forecast once.
  • Add a fallback watering amount in case a plant does not have a watering curve assigned to it.
  • Explore other features of the Open-Meteo API to utilize more weather data. For example, you could get the temperature forecast and use it to increase the watering amount if it will be very hot.