How to download multiple images from the camera at once

Hello, I want to make a time lapse of my plants growing in my farm bot. I’ve created a sequence already to take a photo of all of my plants. I was wondering if there is a way to download all of the photos that I’ve taken at once so that I can more easily put them together, thank you.

That sounds like a fun project @Jqck !

Currently, the UI does not have such a feature, but that’s not to say it is impossible. Based on your past forum posts, I am going to assume that you are a more advanced user. The solution below assumes you are comfortable with the Linux command line (let me know if that’s not the case).

To get a list of every photo:

image

  1. Export account data as export.json
  2. Download the JSON fie (in your email inbox)
  3. Use a tool like Jq to extract the attachment_url property from images: jq ".images | map(.attachment_url)" export.json
  4. Download the images. You can use curl or wget if you are familiar with such tools.

Another way to do it that I have mentioned in the past is to download everything via the REST API.

1 Like

Okay, thank you, I will try this soon and let you know how it goes. : )

1 Like

Multi-selection of photos would be a nice feature to have though. Deleting multiple photos is a real pain at the moment.

@mdingena If your destruction selection is “all images in a time-range” then it’s easy to do using the REST API.
( I’ll post some code once @RickCarlino tells us whether the FarmBot Web API code does an automatic delete of the image file on the Google storage API :slight_smile: )

@mdingena I will bring this up to the team today for consideration in a future release. I have been interested in having a similar feature like this, also.

@jsimmonds The automatic delete takes place in a background worker. I misunderstood your original statement and thought you were making a bug report- I can confirm that the API is still deleting files off of Google Cloud automatically (as intended)

Okay, you might have over-estimated my ability with Linux commands. So I have a nice json output from JQ but I’m not sure how to use that it wget or curl to actually download them since they are parsed weirdly and also I’m just not familiar enough with those commands to download multiple urls.

@RickCarlino @mdingena here is my API client code in CoffeeScript ( warts and all ) which can delete all photo images within a specified datetime range with interval-timer-based rate-limiting so that we don’t stress the REST API too much :sweat_smile: Very hacky but tested to work.

You need a node command-line environment.
I used Node.js v14.16.0 on Linux ubuntu 5.4.0-1029-raspi aarch64

within_time_range = (begin_datetime, image_datetime, end_datetime) ->
  image_created = (new Date(image_datetime)).getTime()
  return if (begin_datetime <= image_created) and (end_datetime >= image_created) then true else false

delete_one_image = (del_images) ->
  image_id = del_images.shift()
  unless image_id?
    clearInterval intervalTimer0
  else
    api.del '/api/images/' + image_id,
      (err, req, res, obj) ->
        util.log "err #{util.inspect err}" if err
        util.log "image [id: #{image_id}] destroyed"

delete_some_images = (range_begin, range_end) ->
  begin_datetime = (new Date(range_begin)).getTime()
  end_datetime = (new Date(range_end)).getTime()
  api.get '/api/images',
    (err, req, res, obj) ->
      util.log "err #{util.inspect err}" if err
      all_images = JSON.parse res.body
      del_images = (image.id for image in all_images when within_time_range(begin_datetime, image.created_at, end_datetime))
      intervalTimer0 = setInterval delete_one_image, 500, del_images

delete_some_images process.argv[2], process.argv[3]

so you’d run this from shell prompt like

node main '2021-03-09T00:00+11:00' '2021-03-09T23:59:59.999+11:00'

where main.js is a shim to invoke the CoffeeScript compiler such as

require('coffeescript/register');
module.exports = require('./destroy_images');

|Ooops|

I forgot other essentials, such as

api = (require 'restify-clients').createJsonClient {url: 'https://my.farm.bot', headers: {'authorization' : "Bearer #{token}"}}

intervalTimer0 = null

Assume you know how to fetch your current JWT :sweat_smile:

@Jqck I will try to simplify the script. Please let me know if you still need help. The script below assumes Bash on Ubuntu, not Fish or Windows.

Install Required Programs

sudo apt-get install curl jq --yes

Set Auth Info

Be sure to replace YOUR_EMAIL and YOUR_PASSWORD with appropriate values.

TOKEN=`curl -H "Content-Type: application/json" \
     -X POST \
     -d '{"user":{"email":"YOUR_EMAIL","password":"YOUR_PASSWORD"}}' \
     https://my.farm.bot/api/tokens | jq ".token.encoded" --raw-output`

Run Script in Download Directory

curl -H "Authorization: Bearer ${TOKEN}" https://my.farm.bot/api/images | jq 'map(.attachment_url)' | jq -r '.[]'

IMAGES=`curl -H "Authorization: Bearer ${TOKEN}" https://my.farm.bot/api/images | jq 'map(.attachment_url)' | jq -r '.[]'`

for url in $IMAGES; do
  curl ${url} --remote-name;
done

Done

You should see a bunch of JPG images in whatever directory you ran the command in.

1 Like

Thank you it worked perfectly! :slight_smile:

1 Like

Quick update: We’ve added “Ability to download and destroy multiple images in one operation” to the feature backlog.

2 Likes

I wanted to do the same thing and wrote a small script in python to download the images, sort them in a folder for each plant and delete i from the bot. You can find it here: https://github.com/pinae/FarmBot-API-scripts/blob/main/get_plant_images.py

It uses this script to acquire a token for API access: https://github.com/pinae/FarmBot-API-scripts/blob/main/acquire_token.py
The only thing not in the repository is the secrets.json which has the following format:

{
  "username": "YOUREMAL@YOURDOMAIN.COM",
  "password": "YOURPASSWORD"
}
3 Likes