Activating sequences by sending messages to the farmbot web app

Is it possible to activate sequences from outside the farmbot web app?
And what’s the easiest way to do it?

Yes. You can use JavaScript or Python libraries to do that. Search this forum for many examples :slight_smile:
AND Welcome :slight_smile:

1 Like

Woow, thank you!
Is it possible to activate an existing sequence in the farmbot web app with only a few lines of code in pyhton?
can you link me an example?
:slightly_smiling_face:

Oooops, the released Python library doesn’t seem to support that ( yet ) :slightly_frowning_face: sorry.

This is easily remedied, if you’re familiar with cloning repositories from GitHub !

I’ll post some code that will do what you want ( if you want ) :slight_smile:

1 Like

@Athos Even though it is not “officially” supported, it is possible using bot._do_cs(kind, args, body?) in FarmBot Py. (_do_cs means “Do CeleryScript”).

I’ve written an example below. You will need to know the sequence’s ID to perform this action. I will use 123 as a fake sequence ID. You can find your sequences ID via the API /api/sequences endpoint, or by looking at the Chrome Network Inspector inside the web app. Please let me know if you need help with this.

Executing a sequence that uses variables is more difficult. I can show you how to do that if you would like, but the example assumes your sequence does not use externally defined variables.

from farmbot import Farmbot

class MyHandler:
    def on_log(self, bot, log):
        print("LOG: " + log['message'])
    def on_connect(self, bot, mqtt_client):
        print("Connecte. Will execute seeqeunce.")
        bot._do_cs("execute", { "sequence_id": 123 } )
    def on_change(self, bot, state):
        pass
    def on_response(self, bot, response):
        pass
    def on_error(self, bot, response):
        pass

fb = Farmbot.login(email="", password="", server="https://my.farm.bot")
handler = MyHandler()
fb.connect(handler)
1 Like

Thank you very much, we just tried it, and it worked !!!
this is so cool, it’s just what we needed :grin: :grin: :sunglasses:

2 Likes

Thank you a lot for your disponibility to help us, I think we will use the shortcut Rick gave us

1 Like

You can also use the REST-API to schedule a sequence in a minute.

2 Likes

Great point !
Not constrained to use any particular language and could simply use cURL :slight_smile:

1 Like

@RickCarlino
I need to run multiple sequences in series, all controlled through a main in Python. I use the “farmbot” library (farmbot · PyPI) and, through the example on the site, I can run a certain sequence.
However, I need to execute other sequences once the first one is finished but I cannot get the execution of the last line of code to finish:
“fb.connect (handler)”

It appears that after completing all the scheduled actions in the sequence, the Python program does not proceed further.

I don’t know anything about the using of “system threads or processes” as mentioned in the site linked at the beginning of this message.

Now I press “ctrl + C” every time to stop the code, but this obviously kills the entire execution, not only the line with “fb.connect(handler)”.

Maybe this problem can be solved with a few lines of code?
Do I need to study how to use the “farmware_tool” library ( .device.execute(…) )?

FarmBot Py has an event-based architecture. If you run it on the main thread, it will block the main thread indefinitely (in the same way that running a Python-based server library might).

Threads allow you to run two functions at the same time (or give the illusion of doing so). A tutorial for Python threading can be found here. You could spin up a second Python process that communicates with the first, but this is more complicated than just using threads.

Another option that doesn’t involve threads:

  • Create an array of sequence IDs you want to execute (before connect()ing)
  • Execute the first sequence in the on_connect callback. Delete the sequence from the array.
  • Every time on_response is called, delete the previous sequence and execute the next one.

I have not tried this in FarmBotPy, but this is essentially how FarmBotJS works.

The big hint here is that you want to store all of your work in some kind of list, and you want to use on_response as your signal to delete old jobs and start new jobs.

If I have time today I might be able to write an example. My schedule is very hectic today, unfortunately.

You shouldn’t write Farmware in 2021. Farmware will be completely removed from FBOS by the end of the year. If you see any information that suggests authoring a Farmware, it is most likely old advice. Are there still links that advise users to write Farmware? If so, could you please send me the link so that I can update our documentation?

Thank you very much, I will wait for your example, meanwhile I will try to fix it following your advices.
Regarding the farmware, it’s already written that probably I won’t need that, I just tought this was the improbable case.
Sorry to bother, the documentation it’s all rigth.

https://developer.farm.bot/v14/Documentation/farmware.html

1 Like

Dear Rick,
I can never thank you enough, with your suggestions and other research I can now activate multiple sequences. here I attached the python file
Farmbot_multiple_sequence_TEST.py (4.2 KB)

And here an example of two sequences in the Shell
WhatsApp Image 2021-06-05 at 04.50.13

I found two inconsistencies:

  1. the LOG messages within the JSON file don’t seem to be in the right order
    So I added to the code line 94:
    all_logs.sort(reverse = True, key = get_first)

  2. on the Farmbot web app I can’t see the arrival of log through request.post, but I can read them from the download of the logs. To see them in the web app I need reload the page.
    for example in line 152 with:
    send_firstlog

Let me know if you have other suggestions or improvements to the code :grinning: :sunglasses: :computer: :+1:

Hi @Athos

Glad your code works the way you want :slight_smile:

You can execute multiple Sequences from inside the @RickCarlino sample code (above)
without using concurrency ( sub-processes or threads ) but you need to work with the Paho MQTT “event-based” design.

The most important thing to do when using this Farmbot.Py library is to keep account of your execute Request Id and all the Response Ids coming in.
The nature of the WebApp MQTT RPC connection is that you’ll receive Response packets which you don’t know about.

Here’s my modified sample code. Looks like Farmbot.Py could use a new function to be able to quit the Paho event loop ( call loop_stop() e.g. :slight_smile: )

from farmbot import Farmbot

class MyHandler:
    def __init__(self, sequences):
        self.sequences = iter(dict.values(sequences))
        self.executions = {}
    def on_log(self, bot, log):
        print("LOG: " + log['message'])
    def on_connect(self, bot, mqtt_client):
        print("   |=====> Connected.")
        MyHandler.execute_a_sequence(self, bot)
    def on_response(self, bot, response):
        print(f"   |=====> Response object for Request Id {response.id}.")
        if response.id in self.executions:
            print("   |=====> Response matches a Request.")
            MyHandler.execute_a_sequence(self, bot)
    def on_change(self, bot, state):
        pass
    def on_error(self, bot, response):
        pass
    def execute_a_sequence(self, bot):
        try:
            a_sequ = self.sequences.__next__()
        except StopIteration:
            return
        print("   |=====> Will execute a sequence.")
        request_id = bot._do_cs("execute", { "sequence_id": a_sequ })
        self.executions[request_id] = 1
        print(f"   |=====> Request Id for 'execute sequence({a_sequ})' is {request_id}.")

handler = MyHandler({'First sequence': 54170, 'Second sequence': 54171})

fb = Farmbot.login(email="inbox", password="password", server="https://my.farm.bot")
fb.connect(handler)
1 Like

Glad you figured it out @Athos !

API endpoints do not sort results via their created_at timestamp. This is true for other resources, also, though it looks like you have discovered the solution :tada:

The reason for this is somewhat complicated, but unlike other API resources, Log messages will not show up via auto-sync like other resources do. You will see them if you refresh the page, though.

I am extremely busy this month due to our usual “springtime rush”, but I can take a look later. I would also be open to accepting pull requests for such a feature if someone were to create a custom solution.

1 Like

I always forget that . . I’ll work on it :slight_smile: