Ultimately the reasons that I choose to add intelligence to the things around my home fit into two buckets, either simplicity or "because it's cool". There are a few technologies that start out in the "because it's cool" bucket and, through some developments or integrations, end up in the simplicity bucket. I purchased the indoor/outdoor soil monitors for my garden primarily to provide some insight about some factors that may be contributing to my inability to produce any produce (ugh, that was bad).
The first purchase was the
Koubachi nearly 4 years ago. While expensive, this product worked as advertised and provided some nice data including moisture, light, and temperature. The product and dashboard have entered a sunset period after the acquisition by Husqvarna. Our Koubachi fell victim to the elements (or an aggressive weeding session) and needed to be replaced. At that time, I chose to use the
PlantLink system for monitoring of the two planters that house my annual frustration efforts.
After the purchase of the
Rach.io Iro for irrigation, the next steps seemed obvious to move the PlantLink from one bucket to the other.
- Get moisture data from PlantLink
- Trigger Rachio to water the garden if the sensor says it's dry
- ???
- Profit
Well, after waiting and waiting for some official integration, spurred on by a mention on PlantLink
blog and seeing a
forum pop up on the PlantLink support forums (though it has no posts yet), I've come to the conclusion that official support isn't coming.
So, I decided to write my own using a simple script and their official APIs.
Disclosure: I am a python hack. I take and reuse code from other projects, so I can guarantee it's not the most elegant way of doing it, could be more efficient, and may make programmers physically ill reading it.
I did this in an afternoon reading through the
PlantLink and
Rachio API docs. It seems to work OK, but there's probably a better way to do it. If you have ideas, please comment below. My general approach was to have a script that runs once a day with a cron job on my ubuntu server at home and queries the PlantLink sensor to see if it needs water... if it does, it triggers Rachio to water a particular zone for a definable amount of time, say 20 mins.
The code is out on github, the most difficult part was finding all of the variables I needed to trigger the Rachio to start a particular zone. It relies on a auth token for authorization, a person ID to find the device properties, a device ID to find the zone ID that will be used for the API call.
The PlantLink side is relatively easy. Their API supports basic HTTP authentication, so it's a matter of using your username and password and parsing the plant health value from the returned JSON. This value is called "Plant_Fuel_Level" and ranges from 0 to 1 based on the amount of detected moisture in relation to how much the configured plant needs. A support post off the API page mentioned that 0.2 is a good value to trigger the watering of the plant. Other value that could potentially be used is "predicted_water_needed" which is in epoch time.
The value is then compared to the defined watering threshold and if it's below, it asks Rachio to kick off a watering job.
Rachio's API is a little more difficult to navigate. It first requires that you use the API Auth Token discovered from their web dashboard.
This token is used to discover your person_ID with the following call:
curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer [auth_token]" https://api.rach.io/1/public/person/info
This will return your person_ID which you can use to determine information about the devices associated with your account. You'll need this to find the zones you have configured and their associated zone_ID.
HTTP/1.1 200 OK {
"id" : "[person_ID]"
}
Next, take your discovered person_ID and plug it into another API call to discover your device_ID.
curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer [auth_token]" https://api.rach.io/1/public/device/[device_id]
Dig through the returned JSON and find the zone that you'd like to trigger if the plant needs to be watered.
HTTP/1.1 200 OK
{
"id": "2a5e7d3c-c140-4e2e-91a1-a212a518adc5",
"status": "ONLINE",
"zones": [
{
"id": "e02de192-5a2b-4669-95c6-34deea3d23cb",
"zoneNumber": 3,
"name": "Zone 3",
"enabled": false,
"customNozzle": {
"name": "Fixed Spray Head",
"imageUrl": "https://s3-us-west-2.amazonaws.com/rachio-api-icons/nozzle/fixed_spray.png",
"category": "FIXED_SPRAY_HEAD",
"inchesPerHour": 1.4
},
"availableWater": 0.17,
"rootZoneDepth": 10,
"managementAllowedDepletion": 0.5,
"efficiency": 0.6,
"yardAreaSquareFeet": 1000,
"irrigationAmount": 0,
"depthOfWater": 0.85,
"runtime": 3643
},
That zone_ID will be required for the API call to trigger the watering job. If you have more than one PlantLink sensor, each fed by a different watering zone, you can replicate my JSON parse code adjusting the list number for each different sensor.
moisture = parse[0]["last_measurements"][0]["plant_fuel_level"]
Finally, I just setup the script to run once a day to minimize the impact on the APIs. You can make this every other day or once a week depending on what you are monitoring.
$ crontab -e
0 5 * * * ~/PlantLinktoRachio.py
This can be done in the cloud also as it doesn't need to directly communicate with either your PlantLink or Rachio device, all calls use cloud services, not the devices themselves.
Code:
PlantLink_to_Rachio