I wanted to share with you all how we are using the access to the JSON recipes via the web application. I have been looking for a way to streamline the creation of student recipes without having to have them all read and write JSON files. While some of my students benefit from digging in behind the scenes, others are just looking to setup their research as easily as possible.
I started by using my Adafruit IO Plus account ($10/mo) to create an online dashboard of widgets that could be used to set the variables associated with a recipe.
I then worked with students to write a Python script that would open a sample JSON file that was dowloaded from the MARSfarm web app. It gets converted it into a Python dictionary that can be modified by reading the feed values from Adafruit IO. The script then overwrites or modifies the dictionary in the appropriate value fields associated with a variable in the recipe. Finally, it exports a JSON file that can be uploaded to the web app.
I found that by modifying an existing JSON file prevented an inadvertent departure from the formatting that the web app is expecting. I am by no means a Pythonista, but the script allows you to:
-
Name your recipe
-
Auto populate the description with the values you have selected from Adafruit IO
-
Select the watering volume from 0-2000mL. It also ensures these are broken up into the requisite number of watering sequences so as not to try and pump more than 80mL in any one minute span
-
Select the time of day you would like your plants to be watered. This is on the hour from 0-23.
-
Select the time of day you would like your lights to turn on. The first light_intensity setting must be for 12:01am, so this is set to [0,0,0,0] and a middle time event is inserted to select your optimal sunrise.
-
Select the photoperiod you would like the lights on for. This setting is also used to establish your daytime and nighttime temperatures.
-
Choose a Red and Blue value for a specific end of the light spectrum you would want to work with.
-
Choose the White light intensity
-
Choose a daytime and nighttime temperature. Like with light intensity, a third setting needs to be created to start off at 12:01.
-
Choose to have the ventilation fan on or off.
Like I said above, it is not the cleanest code, but it works. Feel free to polish/modify as needed.
from Adafruit_IO import Client, Feed, RequestError
import math
import json
#Pull in MARSfarm JSON Template. Use File Path to Downloaded JSON File
with open("/Users/cregini/example.json") as file:
data = json.load(file)
#Enter Recipe Name
name = 'Your Recipe Name Here'
data['recipe_name'] = name
# Set to your Adafruit IO key.
# Remember, your key is a secret,
# so make sure not to publish it when you publish this code!
ADAFRUIT_IO_KEY = 'Your Key Here'
# Set to your Adafruit IO username.
# (go to https://accounts.adafruit.com to find your username)
ADAFRUIT_IO_USERNAME = 'Your Username Here'
# Create an instance of the REST client.
aio = Client(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)
#Function to convert hex to RGB from Adafruit IO
def hex_to_rgb(hex):
rgb = []
for i in (0, 2, 4):
decimal = int(hex[i:i+2], 16)
rgb.append(decimal)
return tuple(rgb)
#Create Adafruit IO Feeds. Your Feed names will be up to you.
volume = aio.feeds('mv1-volume')
watering_time = aio.feeds('mv1-watering-time')
airflow = aio.feeds('mv1-airflow')
sunrise = aio.feeds('mv1-sunrise')
photoperiod = aio.feeds('mv1-photoperiod')
light_spectrum = aio.feeds('mv1-light-spectrum')
light_intensity = aio.feeds('mv1-light-intensity')
day_temp = aio.feeds('mv1-day-temp')
night_temp = aio.feeds('mv1-night-temp')
#Read Adafruit IO Feeds
volume_data = aio.receive(volume.key)
watering_time_data = aio.receive(watering_time.key)
airflow_data = aio.receive(airflow.key)
sunrise_data = aio.receive(sunrise.key)
photoperiod_data = aio.receive(photoperiod.key)
light_spectrum_data = aio.receive(light_spectrum.key)
light_intensity_data = aio.receive(light_intensity.key)
day_temp_data = aio.receive(day_temp.key)
night_temp_data = aio.receive(night_temp.key)
#Determine necessary number of waterings given 80mL max/min
v = int(volume_data.value)
waterings = math.ceil(v/80)
remainder = int(v % 80)
#Assign watering setting and start times based on selected watering volume
waterings_list=[]
if remainder == 0:
for i in range (waterings):
waterings_list.append({'start_time': [9,i], 'setting':80})
else:
for i in range (waterings-1):
waterings_list.append({'start_time': [9,i], 'setting':80})
waterings_list.append({'start_time': [9,(waterings-1)], 'setting': remainder})
data['phases'][0]['step'][2]['pump_amount'] = waterings_list
wt = int(watering_time_data.value)
for i in range(waterings):
data['phases'][0]['step'][2]['pump_amount'][i]['start_time'][0]=wt
#Check for airflow setting and apply
air=int(airflow_data.value)
data['phases'][0]['step'][0]['circulation_fan'][0]['setting'] = air
if air == 0:
fan_state = 'OFF'
else:
fan_state = 'ON'
#Initiate 3 light settings to keep lights from turning on at midnight
light_list=[]
for i in range (3):
light_list.append({'start_time': [0,1], 'setting':[0,0,0,0]})
data['phases'][0]['step'][3]['light_intensity'] = light_list
#Establish sunrise and photoperiod
on_time = int(sunrise_data.value)
data['phases'][0]['step'][3]['light_intensity'][1]['start_time'][0] = on_time
daylight_hours = int(photoperiod_data.value)
off_time = daylight_hours + on_time
data['phases'][0]['step'][3]['light_intensity'][2]['start_time'][0] = off_time
#Establish light spectrum
color = light_spectrum_data.value
color = color.replace('#', '') #strips leading # off of hex value
color = hex_to_rgb(color) #Uses function on line 26 to grab red and blue values
red = color[0]
blue = color[2]
white = int(light_intensity_data.value)
data['phases'][0]['step'][3]['light_intensity'][1]['setting'][1] = red
data['phases'][0]['step'][3]['light_intensity'][1]['setting'][2] = blue
data['phases'][0]['step'][3]['light_intensity'][1]['setting'][3] = white
#Calculates light intensity. This will be replaced with an equation provided by MARSfarm.
mol = 12.96
#Estabish 3 temperature settings to maintain nightime temperature
temp_list=[]
for i in range (3):
temp_list.append({'start_time': [0,1], 'setting':[60]})
data['phases'][0]['step'][1]['temperature'] = temp_list
#Check and assign temperature settings to coincide with light on/off settings
dt = int(day_temp_data.value)
nt = int(night_temp_data.value)
data['phases'][0]['step'][1]['temperature'][1]['start_time'][0] = on_time
data['phases'][0]['step'][1]['temperature'][2]['start_time'][0] = off_time
data['phases'][0]['step'][1]['temperature'][0]['setting'] = nt
data['phases'][0]['step'][1]['temperature'][1]['setting'] = dt
data['phases'][0]['step'][1]['temperature'][2]['setting'] = nt
#Declare Recipe Description
description = f'Airflow - {fan_state}, {daylight_hours} Hour Days, Day Temp - {dt}F, Night Temp - {nt}F, Irrigation - {v}ml/day, Light - {mol}/mol/day - {red} red, {blue} blue, {white} umol/sec'
data['recipe_variable'] = description
#Write recipe to a JSON file to be uploaded on web app
with open(f"/Users/cregini/{name}.json", 'w') as file:
json.dump(data, file)
print('Recipe JSON File Complete')