Call server side method from button click

I need to call a method on the server when I click a button on my web view.
What is the best way to do that?

Need more details as to what method you're talking about.

I have a libray module installed on the server with some methods to control some LEDs (camera light) via smbus. I need to call these methods when I click buttons on OctoPrints web page.

Probably very easy when you know howto. I gues you have to use a REST post message, but I think there are packages on top of this to help make it simple. I don't know what OctoPrint is using.

so your running system commands or shell scripts or python file? GCODE System Commands in combination with a custom control for the button would probably work.

It's a Python file comprising two classes and some constants. No GCODE commands.

I just mentioned the GCODE system command plugin as a means to get you a custom button on the control tab using custom controls. Otherwise, you'll have to convert your entire python file into an octoprint plugin.

Oh, another option if you don't necessarily need a button is system commands.

it adds a item in the menu where you restart octoprint and such.

I have done the mixin plugin_tab with a ViewModel and a jinja2 template. I just don't know what to put inside the button functions. I browsed the web and found something called Server Action. Would that help me?

I looked at your prevoius post and maybe that is one way of doing it. I have the driver installed on my Raspberry and I can control it from the command line. I would however like to include the library file into my plug-in so I can install it with the plug-in manager. I am therefor seeking a more integrated way to communicate with the library.

Oh I see what you're saying. You are creating a plugin. So you'll want to look into using the simpleapiplugin mixin to receive instructions for running the commands you need on the server side, and then in the js create a button click function that will utilize a jquery ajax call to your api. in your jinja you bind your click event to the click function.

OK. jquery ajax looks familiar. I will study that.

Thanks for your help.

BTW, this is also quite easy to do. If you are using SimpleApiPlugin, you can run:

OctoPrint.simpleAPICommand(plugin_id, api_command)

Example + (optional) add a function to register when the call has executed (since it is async):

check_response = function(response) {
    console.log("It's done")
}
OctoPrint.simpleAPICommand("my_awesome_plugin", "do_this").done(check_response)

You get the idea. The documentation explains the Python simpleAPI quite well IMO, the OctoPrint client is a little more hidden.

dang it, I keep forgetting about this...

To jog your memory :wink:

1 Like

I'm an old dog and just so used to jQuery I always just go that route.

foosel, I think the link you posted is for client side libraries. My library is on the server side, or do I need the client library as well?

Well, I will do some studying and then try to solv my little project.

The javascript of your plugin runs client side - that OctoPrint client lib is what you can use (it is completely optional :slightly_smiling_face:) to communicate from JS client to the python (server) side of your plugin.

My recommendation above is still relevant - wrap your python functions under SimpleApi commands, then call them from the client (on button click) using the JS client OctoPrint.SimpleAPICommand to trigger those commands server side.

2 Likes

Yes, my client is ready. If I understand correctly, I only need to complete my "on click functions" using the SimpleAPICommands. Then I will create the server side wrapper to recieve the commands and call my library functions. I will check this out tomorrow.

Thank you all for the great help.

2 Likes

Stuck again.

I do not quit understand what to call in my button onClick function. Here is what I have come up with so far, reading the posts here and the documentation I have found so far.

I added this to my plugin init.py file

# SimpleApiPlugin

def get_api_commands(self):
    return dict(
        whitLight=["on"],
        irLight=["on"]
    )

def on_api_command(self, command, data):
    import flask # (shall this be used here ?)
    if command == "whitLight":
        # TODO: Implement whiteLight control here.
        self._logger.info("whitLight called, parameter is {on}".format(**data))
    elif command == "irLight":
        # TODO: Implement irLight control here.
        self._logger.info("irLight called, some_parameter is {on}".format(**data))

and the following to my ViewModel

image

Above shows one of my botton functions with two alternatives. One according to Charlie_Powell and the second from the SimpleApiPlugin documentation.

Neither is complete. The first do not pass any parameters and I cannot find the command in the OctoPrint documentation.

I'm not sure if the second alternative is ment for a button click function and I don't know what to put in for the Host and X-Api-Key parameters.

Some further help would be much appreciated.

OK so you're most of the way there :slightly_smiling_face:.

The Python side bit looks good, there is just one part I would change:

self._logger.info("whitLight called, parameter is {on}".format(data.get('on')))

Since data is a dictionary, you can get the parameters using data.get(). You probably would have figured that out once the log would have shown the full response data.

Onto the JS side:
Here is a link to the simpleAPICommand client documentation. It does all the work for you making sure the command is valid, and tying up the host, apikey etc. from OctoPrint's internals.

The section you posted:

POST /api/plugin/brightpi HTTP/1.1
Host: example.com
Content-Type: application/json
[...]

is the raw HTTP request. That is what a request looks like behind the scenes - provided so you know how to call the command from any system, it is the 'standard protocol'. This is not required in your plugin.

I didn't realise that you wanted a parameter on your command, but that is easily added - now you have the link, you can see how this works too. Change it to this:

OctoPrint.simpleApiCommand("brightpi", "whitlight", {"on": true})

Hopefully that should now work.

Yes I was going to ask about the format function. I did't look right, so now I know. Thanks.

I did suspect that the code from the documentation was just information and not ment for the button function.

Thanks a lot for the information. I will try it.

1 Like