Plugin Request - Generic API calls


#1

There doesn't seem to be a plugin to allow for generic API calls.

I'm looking to see if anyone would be interested in making one?

The benefits would be access to utilities like IFTTT, Tasker, or any other automation utility that could accept inbound REST API requests.

I was looking at OctoSlack an though that a similar plugin with the same events and picture ability would be absolutely amazing if you could specify your own API url to send to instead of interacting directly with Slack.

I'd be thrilled with just event driven API calls, but the picture ability would be a plus.

Is anyone up to the challenge?


#2

I've basically done this with a Node-based service. In this case it's just a single API point which can pause the print job with a simple GET endpoint. It is run from rc.boot and then listens on port 3000 to expose the API.

It works in conjunction with the BRB (big red button) IFTTT project (ESP8266-based) dash button, if you will. I'm sure my rationale was that I looked at the plugin space for this, found it wanting, and rolled my own solution.

All this isn't a generic API framework as you're requesting but one could take a similar approach.


#3

This is great input, Thank you!

I was looking for something going the other direction though. I'd like to send an API call when a printer event (start, %progress, Complete, cancelled, etc...) occurs.


#4

That would be similar to my MQTTSubscribe plugin. It basically creates an API proxy via MQTT protocol. This allows for sending the command to the server, and getting the response on another topic. You could also use PolarCloud and it's IFTT integration or possibly IFTTTmaker.


#5

So basically, the plugin would have a settings page which asks for the main server's API root, there's a series of checkboxes for events/hooks that you'd like to subscribe to and probably a test button.

The receiving server would need to support the indicated verbs for printStart, printProgress, printComplete, printCanceled and similar as POSTs. If the server is available, then it's not too processing-intensive. If the server can't be reached or can't be looked up then it starts to look like a problem. In the case of printProgress it could potentially affect print quality, in theory.

Good idea, though.


#6

Yeah from what I can tell from the source of IFTTTMaker it supports "PrintStarted", "PrintFailed", "PrintDone", "PrintCancelled", "MovieDone", and "ClientOpened" events.


#7

you guys mentioned IFTTTMaker several times. Are you referring to the Maker channel in IFTTT or something else? It seems like your talking about a plugin or something that I just can't find.

Ha!, nevermind...

Is this what you are talking about?


#8

Pretty sure that's what he'd be talking about.


#9

Pretty sure that's the one I linked to earlier. It does use the maker channel I think on the backend.


#10

I am currently writing my backend for my octofarm(printerview style dashboard written in due) project

my plans are splitting the project into a server and client part.

the server uses a modded version of OutsourcedGuru's octo-client which i modified so i can set the apikey, ip, port

So i can save the data for several printers.

The server probes the octoprint instances in an interval and holds all the data of all the printers in one object.

client and server communicate with socket.io

on the frontend side
initially the whole data will be loaded.

then the specific written Vue components only register/request the data they need.

then only the necessary data will be transmitted and only when the data changes on the server.


Need help accessing the API from outside OctoPrint
#11

This is how the GUI looks like actually:

Only the webcam "window" which is hovered plays the live stream.
the other will only show a snapshot which is actualized every second.
Actually it is only the still picture...


Actually the view scale up to 9 "printers".


#12

Awe, man... only nine printers? /mocksadness

Really cool. And it's smart not to try to stream all of them at once. I think I'd consider overlaying a little logistics in each frame like status and progress.


#13

16 is possible on a fullHD screen.

yes there will be overlays with some info and when you click you will get a fullscreen view of the specific printer.#

On the server side i did some checks to not crash the server when a instance gets down:

function checkConnection(host, port, timeout) {
    return new Promise(function(resolve, reject) {
        timeout = timeout || 10000;     // default of 10 seconds
        var timer = setTimeout(function() {
            reject("timeout");
            socket.end();
        }, timeout);
        var socket = net.createConnection(port, host, function() {
            clearTimeout(timer);
            resolve();
            socket.end();
        });
        socket.on('error', function(err) {
            clearTimeout(timer);
            reject(err);
        });
    });
}

-----------
   var OctoPrint = require('octo-client');
        // setup instance 
        OctoPrint.setPrinter(printers[index].apiKey, printers[index].ip, printers[index].port );
        // update data
        checkConnection(printers[index].ip, printers[index].port).then(function() {
            // successful
            OctoPrint.printerState(function(response){printers[index].data.printerState = response;});
            OctoPrint.connection(function(response){printers[index].data.connection = response;});
            OctoPrint.job(function(response){printers[index].data.job = response;});
            OctoPrint.languages(function(response){printers[index].data.languages = response;});
            OctoPrint.settings(function(response){printers[index].data.settings = response;});
            OctoPrint.printerProfiles(function(response){printers[index].data.printerProfiles = response;});
        }, function(err) {
            // error
            console.log("Octoprint instance on : " + printers[index].ip + " @" + printers[index].port + " is not reachable");
            return;
        })

#14

You might also consider throwing in a safety layer for the DNS lookup itself. I'm doing some coding for an autonomous tank and I forgot to flip the switch. One of these modules then did an untrapped catch situation, bringing down the app.

So I now routinely wrap a safety function using the npm install --save dns module, something like this:

var dns =         require('dns');

...
  var host = config.tankHostname;
  if (config.tankIsDown) host = 'localhost';
  dns.lookup(host, function(err) {
    if (err) {debug(err); callback(null); return;}

    // carry on with regular code

  }); // dns.lookup()
...

#15

On my home network i don't use a local dns server.
actually the ip's are fine for me :smiley:


#16

I'm glad octo-client is working out for you. I burned it out in a hurry but I've been using the hell out of it myself for all kinds of things.