Communicating our own Raspberry Pi with Farmbot

Hi forum,
my group is trying to start a program from the Farmbot Web App to our own Raspberry Pi. Then send data from our Pi to the webapp. Does anybody know of the best way to accomplish this? Currently we are thinking to trigger the program using the GPIO pins of our PI and sending data back via PWM to the Arduino of the Farmbot, but so far it does not seem very reliable. We would love to use USB or the serial TSRX but the farmware Celery doesnt seem to accomadate this???

The best way for a Raspberry Pi without FarmBot OS on it to communicate with FarmBot OS is by running an HTTP server on it and communicating through HTTP requests from within a Farmware. You could also communicate through serial from within a Farmware by using pySerial. If you just need to communicate with the Web App and not the other Raspberry Pi, you could connect directly using the Web App documentation. What is requiring it to be a separate Raspberry Pi?

We’ve developed an image processing routine that will estimate a plant’s SPAD number (used for chlorophyll estimation). It is written in python. We’ve mounted a rasberrypi and a picam to the fambot and can manually run our setup. But, we’d like to figure out how to trigger it from the web app and get the data (three digit SPAD number) to to display on the webapp. We are not strong coders (not familiar with MQTT/celery), so we we’re trying to work with what the sequence editor gives us access to.

Thank you for the info, can you please clarify when you say “other Raspberry Pi” do you mean the ones connected to the Farmbot or our Raspberry Pi.
Respectfully Team FarmBot

Have you considered running your code as a Farmware on the FarmBot’s Raspberry Pi? (Farmware development documentation) That will be the easiest way to communicate with the Web App since you’ve written your code in Python.

Previously I was referring to communication between the two Raspberry Pis, which I don’t recommend.

when you sent us the web app documentation, Did you mean to setup that github file in our own Raspberry Pi to try an communicate with the Web App?

To try and clarify, we are using a second Pi (our Pi) to take pictures of a plant and get data from that plant using a python program in our own Pi. We are trying to send one number to report back on the logs on the Farmbot Wep App data log. We are having trouble sending that number to the FarmBot Web App. We are not very familiar with communication between Raspberry Pi and Websites.

What is the best way for us to send that number from our own Raspberry Pi to the Web App? We hope that explanation can clarify. Thank you

If you don’t want to run your program in FarmBot OS (running code as a Farmware makes the process easier by providing the token for you), you will have to get a token and use that to send the number to the Web App.

To get your token, open the FarmBot Web App and use Ctrl + Shift + J to open the JavaScript console. Paste store.getState().auth.token.encoded and press Enter. Copy the output string (between quotes), and replace paste_token_here in the code below with the string.

import json
import requests

TOKEN = 'paste_token_here'
NUMBER = 100

headers = {'Authorization': 'Bearer ' + TOKEN,
           'content-type': 'application/json'}
data = json.dumps({'message': 'Reported number: ' + str(NUMBER)})
response = requests.post('https://my.farmbot.io/api/logs',
                         headers=headers, data=data)

Alternatively, you could do it all in the code as shown (if you don’t mind storing your password in the code):

#!/usr/bin/env python

'''Report a number to the FarmBot Web App.'''

import json
import requests

# Inputs:
NUMBER = 100
EMAIL = 'farmbot@account.email'
PASSWORD = 'password'

# Get your FarmBot Web App token.
headers = {'content-type': 'application/json'}
user = {'user': {'email': EMAIL, 'password': PASSWORD}}
payload = json.dumps(user)
response = requests.post('https://my.farmbot.io/api/tokens',
                         headers=headers, data=payload)
TOKEN = response.json()['token']['encoded']

# Send the number to the FarmBot Web App logs.
headers = {'Authorization': 'Bearer ' + TOKEN,
           'content-type': 'application/json'}
data = json.dumps({'message': 'Reported number: ' + str(NUMBER)})
response = requests.post('https://my.farmbot.io/api/logs',
                         headers=headers, data=data)

Thank you that worked.

We seem to have run into another issue, our farmbot will not connect to the web app. This has been going on for two days. The farmbot wifi (farmbot-xxxx) will not display. We tried reflashing the sd card as mentioned in some forum questions but it still wont connect. Do you have any idea what it could be ?

hello again,
we want to run a farmware that can send a message to our personal raspberry to execute a program. You mentioned that the best way to do something like that was using HTTP server. Could you explain how to do that or send us a link that explains it? Thank you

You can search around for other options since there are a lot of ways to do something like this, but something similar to this could work:

Run at location of script.py:

import subprocess
import SocketServer
from BaseHTTPServer import BaseHTTPRequestHandler

class RequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        subprocess.call('python script.py', shell=True)
        self.send_response(200)

server = SocketServer.TCPServer(("", 8080), RequestHandler)
server.serve_forever()

Run within Farmware:

import requests
requests.get('http://localhost:8080')

This would run script.py on the http server. localhost should be replaced with the IP address of the server (for example, 192.168.1.100).

Once again, thank you for your tireless help with our project. We decided to try the py.serial method. We wrote a simple script (that reflects what we want to do) and created a manifest. After installing it, we can select our Farmware from the web-app, but in testing we do not receive the log messages put in for troubleshooting. Below is our code.

Import libraries

import os
import json
import requests
import serial

Define Functions

ser =serial.Serial(
"/dev/tty4",
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
writeTimeout = 0,
timeout = 10,
rtscts=False,
dsrdtr=False,
xonxoff=False)
init = ‘0xBF’

def initiate():
log(“Serial Initiated…”,“success”)
ser.write(init)
print(ser.read())
log(“Message Sent”, “success”)

def farmware_api_url():
major_version = int(os.getenv(‘FARMBOT_OS_VERSION’, ‘0.0.0’)[0])
base_url = os.environ[‘FARMWARE_URL’]
return base_url + ‘api/v1/’ if major_version > 5 else base_url

def log(message, message_type):
'Send a message to the log.'
try:
os.environ[‘FARMWARE_URL’]
except KeyError:
print(message)
else:
log_message = str(message)
headers = {
‘Authorization’: ‘bearer {}’.format(os.environ[‘FARMWARE_TOKEN’]),
‘content-type’: “application/json”}
payload = json.dumps(
{“kind”: “send_message”,
“args”: {“message”: log_message, “message_type”: message_type}})
requests.post(farmware_api_url() + ‘celery_script’,
data=payload, headers=headers)

    #### EXECUTE ####

if name == ‘main’:
initiate()

Hopefully the general tools and tips throughout this topic will help other people with similar questions and applications.

Do you see a message in the logs if you run the following code as a Farmware?

#!/usr/bin/env python

'''Farmware: execute a Send Message command.'''

import os
import json
import requests

def log(message, message_type):
    'Send a send_message command to post a log to the Web App.'
    requests.post(
        os.environ['FARMWARE_URL'] + 'api/v1/celery_script',
        headers={'Authorization': 'Bearer ' + os.environ['FARMWARE_TOKEN'],
                 'content-type': 'application/json'},
        data=json.dumps({
            'kind': 'send_message',
            'args': {
                'message': message,
                'message_type': message_type}}))

if __name__ == '__main__':
    log('Hello World!', 'success')

it does not show up in logs. Here is the mainfest.json file I have written:

{
“package”: “farmwareTest”,
“language”: “python”,
“author”: “UNH_Farmbot”,
“description”: “Farmware Test”,
“version”: “1.0.0”,
“min_os_version_major”: 3,
“url”: “https://raw.githubusercontent.com/ea2004/SampleUNHFarm1/master/manifest2.json”,
“zip”: “https://github.com/ea2004/SampleUNHFarm1/archive/master.zip”,
“executable”: “python”,
“args”: [“farmwareTest-master/farmwareTest.py”]
}

I named your test file farmwareTest.py. THis is how we have been writing the other manifest.json files for our programs. Is there anything worng with how we wrote this?

This line of the manifest:

"args": ["farmwareTest-master/farmwareTest.py"]

needs to be changed to

"args": ["SampleUNHFarm1-master/farmwareTest.py"]

The creating a Farmware manifest section of the Farmware development documentation discusses the "<repository-name>-master/script.py" format.

Thanks that seemed to work. Now after testing our program we were able to get output but after doing some debugging it seems that the farmware doesnt like it when we import serial. I commented out multiple lines to see if I could find the origin of the problem and it has led me to believe that the line “import serial” is giving an error message. Do you know how we can import serial so that the farmware can accept it?Thank you

I have been following this thread for a while. Thanks for all the information!

I can confirm that I am also unable to import pyserial in my Farmware. I connected up a serial monitor and got the following error when trying to import serial:

ImportError: No module named serial

Thanks for the error reports. I just checked and the pySerial package is not installed in FarmBot OS anymore, so it looks like the HTTP server method will need to be used instead.

Is there any specific reason that pyserial was removed? (And any chance of adding it back in the future?) In my case, the HTTP method is not an option as wifi is not reliable. The farmbot pi is connected to an ethernet cable on a paid port, but we are at a university with strict rules prohibiting the use of a port switch.

As with @unhfarmbot, the main pi is communicating to a secondary pi because it needs to run python code that relies on modules not available in Farmbot OS (among other reasons).

1 Like

Yes, we can add it back in a future release. It was removed because it was no longer being used to communicate with Arduino devices. Serial connections in Farmware cannot be used to communicate with FarmBot’s Arduino (since it is used by FarmBot OS), and FarmBot OS now automatically detects Arduino connections so a new interface would have to be created to support multiple Arduinos.

Hello @sven, thank you for your input.

@Gabriel, Is there a way to somehow get the last version of farmbot_OS that used pyserial? We are also in a similar situation as sven, where we are using a university port with strict rules. Also we have had connectivity issues with the latest version of farmbot_os where the farmbot will be fine for multiple hours, even days and just suddenly disconnect and we have to factory reset it again, as seen from previous blog posts you have so graciously helped us out with.