More documentation
This commit is contained in:
parent
7de90e16f6
commit
197ed7b912
3 changed files with 318 additions and 5 deletions
|
|
@ -56,7 +56,7 @@ Example
|
|||
Placeholders
|
||||
============
|
||||
|
||||
You can use the following generic placeholders in your events:
|
||||
You can use the following generic placeholders in your event hooks:
|
||||
|
||||
* ``{__currentZ}``: the current Z position of the head if known, -1 if not available
|
||||
* ``{__filename}``: filename of the currently selected file, "NO FILE" if not available
|
||||
|
|
|
|||
|
|
@ -385,13 +385,137 @@ class TemplatePlugin(Plugin):
|
|||
|
||||
|
||||
class SimpleApiPlugin(Plugin):
|
||||
"""
|
||||
Utilizing the ``SimpleApiPlugin`` mixin plugins may implement a simple API based around one GET resource and one
|
||||
resource accepting JSON commands POSTed to it. This is the easy alternative for plugin's which don't need the
|
||||
full power of a `Flask Blueprint <http://flask.pocoo.org/docs/0.10/blueprints/>`_ that the :class:`BlueprintPlugin`
|
||||
mixin offers.
|
||||
|
||||
Use this mixin if all you need to do is return some kind of dynamic data to your plugin from the backend
|
||||
and/or want to react to simple commands which boil down to a type of command and a couple of flat parameters
|
||||
supplied with it.
|
||||
|
||||
The simple API constructed by OctoPrint for you will be made available under ``/api/plugin/<plugin identifier>/``.
|
||||
OctoPrint will do some preliminary request validation for your defined commands, making sure the request body is in
|
||||
the correct format (content type must be JSON) and contains all obligatory parameters for your command.
|
||||
|
||||
Let's take a look at a small example for such a simple API and how you would go about calling it.
|
||||
|
||||
Take this example of a plugin registered under plugin identifier ``mysimpleapiplugin``:
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
|
||||
import octoprint.plugin
|
||||
|
||||
import flask
|
||||
|
||||
class MySimpleApiPlugin(octoprint.plugin.SimpleApiPlugin):
|
||||
def get_api_commands(self):
|
||||
return dict(
|
||||
command1=[],
|
||||
command2=["some_parameter"]
|
||||
)
|
||||
|
||||
def on_api_command(self, command, data):
|
||||
import flask
|
||||
if command == "command1":
|
||||
parameter = "unset"
|
||||
if "parameter" in data:
|
||||
parameter = "set"
|
||||
self._logger.info("command1 called, parameter is {parameter}".format(**locals()))
|
||||
elif command == "command2":
|
||||
self._logger.info("command2 called, some_parameter is {some_parameter}".format(**data))
|
||||
|
||||
def on_api_get(self, request):
|
||||
return flask.jsonify(foo="bar")
|
||||
|
||||
__plugin_implementations__ = [MySimpleApiPlugin()]
|
||||
|
||||
|
||||
Our plugin defines two commands, ``command1`` with no mandatory parameters and ``command2`` with one
|
||||
mandatory parameter ``some_parameter``.
|
||||
|
||||
``command1`` can also accept an optional parameter ``parameter``, and will log whether
|
||||
that parameter was set or unset. ``command2`` will log the content of the mandatory ``some_parameter`` parameter.
|
||||
|
||||
A valid POST request for ``command2`` sent to ``/api/plugin/mysimpleapiplugin`` would look like this:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/plugin/mysimpleapiplugin HTTP/1.1
|
||||
Host: example.com
|
||||
Content-Type: application/json
|
||||
X-Api-Key: abcdef...
|
||||
|
||||
{
|
||||
"command": "command2",
|
||||
"some_parameter": "some_value",
|
||||
"some_optional_parameter": 2342
|
||||
}
|
||||
|
||||
which would produce a response like this:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 204 No Content
|
||||
|
||||
and print something like this line to ``octoprint.log``::
|
||||
|
||||
2015-02-12 17:40:21,140 - octoprint.plugins.mysimpleapiplugin - INFO - command2 called, some_parameter is some_value
|
||||
|
||||
A GET request on our plugin's simple API resource will only return a JSON document like this:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 Ok
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"foo": "bar"
|
||||
}
|
||||
"""
|
||||
|
||||
def get_api_commands(self):
|
||||
"""
|
||||
Return a dictionary here with the keys representing the accepted commands and the values being lists of
|
||||
mandatory parameter names.
|
||||
"""
|
||||
return None
|
||||
|
||||
def on_api_command(self, command, data):
|
||||
"""
|
||||
Called by OctoPrint upon a POST request to ``/api/plugin/<plugin identifier>``. ``command`` will contain one of
|
||||
the commands as specified via :func:`get_api_commands`, ``data`` will contain the full request body parsed
|
||||
from JSON into a Python dictionary. Note that this will also contain the ``command`` attribute itself. For the
|
||||
example given above, for the ``command2`` request the ``data`` received by the plugin would be equal to
|
||||
``dict(command="command2", some_parameter="some_value")``.
|
||||
|
||||
If your plugin returns nothing here, OctoPrint will return an empty response with return code ``204 No content``
|
||||
for you. You may also return regular responses as you would return from any Flask view here though, e.g.
|
||||
``return flask.jsonify(result="some json result")`` or ``return flask.make_response("Not found", 404)``.
|
||||
|
||||
:param string command: the command with which the resource was called
|
||||
:param dict data: the full request body of the POST request parsed from JSON into a Python dictionary
|
||||
:return: ``None`` in which case OctoPrint will generate a ``204 No content`` response with empty body, or optionally
|
||||
a proper Flask response.
|
||||
"""
|
||||
return None
|
||||
|
||||
def on_api_get(self, request):
|
||||
"""
|
||||
Called by OctoPrint upon a GET request to ``/api/plugin/<plugin identifier>``. ``request`` will contain the
|
||||
received `Flask request object <http://flask.pocoo.org/docs/0.9/api/#flask.Request>`_ which you may evaluate
|
||||
for additional arguments supplied with the request.
|
||||
|
||||
If your plugin returns nothing here, OctoPrint will return an empty response with return code ``204 No content``
|
||||
for you. You may also return regular responses as you would return from any Flask view here though, e.g.
|
||||
``return flask.jsonify(result="some json result")`` or ``return flask.make_response("Not found", 404)``.
|
||||
|
||||
:param request: the Flask request object
|
||||
:return: ``None`` in which case OctoPrint will generate a ``204 No content`` response with empty body, or optionally
|
||||
a proper Flask response.
|
||||
"""
|
||||
return None
|
||||
|
||||
|
||||
|
|
@ -604,15 +728,60 @@ class SettingsPlugin(Plugin):
|
|||
|
||||
|
||||
class EventHandlerPlugin(Plugin):
|
||||
"""
|
||||
The ``EventHandlerPlugin`` mixin allows OctoPrint plugins to react to any of :ref:`OctoPrint's events <sec-events>`.
|
||||
OctoPrint will call the :func:`on_event` method for any event fired on its internal event bus, supplying the
|
||||
event type and the associated payload. Please note that until your plugin returns from that method, further event
|
||||
processing within OctoPrint will block - the event queue itself is run asynchronously from the rest of OctoPrint,
|
||||
but the processing of the events within the queue itself happens consecutively.
|
||||
|
||||
This mixin is especially interesting for plugins which want to react on things like print jobs finishing, timelapse
|
||||
videos rendering etc.
|
||||
"""
|
||||
|
||||
def on_event(self, event, payload):
|
||||
"""
|
||||
Called by OctoPrint upon processing of a fired event on the platform.
|
||||
|
||||
:param string event: the type of event that got fired, see :ref:`the list of events <sec-events-available_events>`_
|
||||
for possible values
|
||||
:param dict payload: the payload as provided with the event
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class SlicerPlugin(Plugin):
|
||||
"""
|
||||
Via the ``SlicerPlugin`` mixin plugins can add support for slicing engines to be used by OctoPrint.
|
||||
|
||||
"""
|
||||
|
||||
def is_slicer_configured(self):
|
||||
"""
|
||||
Unless the return value of this method is ``True``, OctoPrint will not register the slicer within the slicing
|
||||
sub system upon startup. Plugins may use this to do some start up checks to verify that e.g. the path to
|
||||
a slicing binary as set and the binary is executable, or credentials of a cloud slicing platform are properly
|
||||
entered etc.
|
||||
"""
|
||||
return False
|
||||
|
||||
def get_slicer_properties(self):
|
||||
"""
|
||||
Plugins should override this method to return a ``dict`` containing a bunch of meta data about the implemented slicer.
|
||||
|
||||
The expected keys in the returned ``dict`` have the following meaning:
|
||||
|
||||
type
|
||||
The type identifier to use for the slicer. This should be a short unique lower case string which will be
|
||||
used to store slicer profiles under or refer to the slicer programmatically or from the API.
|
||||
name
|
||||
The human readable name of the slicer. This will be displayed to the user during slicer selection.
|
||||
same_device
|
||||
``True`` if the slicer runs on the same device as OctoPrint, ``False`` otherwise. Slicers running on the same
|
||||
device will TODO
|
||||
progress_report
|
||||
``True`` if the slicer can report back slicing progress to OctoPrint ``False`` otherwise.
|
||||
"""
|
||||
return dict(
|
||||
type=None,
|
||||
name=None,
|
||||
|
|
@ -620,22 +789,71 @@ class SlicerPlugin(Plugin):
|
|||
progress_report=False
|
||||
)
|
||||
|
||||
def get_slicer_profile_options(self):
|
||||
def get_slicer_default_profile(self):
|
||||
"""
|
||||
Should return a :class:`SlicingProfile` containing the default slicing profile to use with this slicer if
|
||||
no other profile has been selected.
|
||||
"""
|
||||
return None
|
||||
|
||||
def get_slicer_profile(self, path):
|
||||
return None
|
||||
"""
|
||||
Should return a :class:`SlicingProfile` parsed from the slicing profile stored at the indicated ``path``.
|
||||
|
||||
def get_slicer_default_profile(self):
|
||||
:param string path: the path from which to read the slicing profile
|
||||
"""
|
||||
return None
|
||||
|
||||
def save_slicer_profile(self, path, profile, allow_overwrite=True, overrides=None):
|
||||
"""
|
||||
Should save the provided :class:`SlicingProfile` to the indicated ``path``, after applying any supplied
|
||||
``overrides``. If a profile is already saved under the indicated path and ``allow_overwrite`` is set to
|
||||
``False`` (defaults to ``True``), an ``IOError`` should be raised.
|
||||
|
||||
:param string path: the path to which to save the profile
|
||||
:param :class:`SlicingProfile` profile: the profile to save
|
||||
:param bool allow_overwrite: whether to allow to overwrite an existing profile at the indicated path (``True``, default)
|
||||
or not (``False``) - if a profile already exists on the path and this is ``False``
|
||||
and :class:`IOError` should be raised
|
||||
:param dict overrides: profile overrides to apply to the ``profile`` before saving it
|
||||
"""
|
||||
pass
|
||||
|
||||
def do_slice(self, model_path, printer_profile, machinecode_path=None, profile_path=None, on_progress=None, on_progress_args=None, on_progress_kwargs=None):
|
||||
def do_slice(self, model_path, printer_profile, machinecode_path=None, profile_path=None, position=None, on_progress=None, on_progress_args=None, on_progress_kwargs=None):
|
||||
"""
|
||||
Called by OctoPrint to slice ``model_path`` for the indicated ``printer_profile``. If the ``machinecode_path`` is ``None``,
|
||||
slicer implementations should generate it from the provided model_path.
|
||||
|
||||
If provided, the ``profile_path`` is guaranteed by OctoPrint to be a serialized slicing profile created through the slicing
|
||||
plugin's own :func:`save_slicer_profile` method.
|
||||
|
||||
If provided, ``position`` will be a ``dict`` containing and ``x`` and a ``y`` key, indicating the position
|
||||
the center of the model on the print bed should have in the final sliced machine code. If not provided, slicer
|
||||
implementations should place the model in the center of the print bed.
|
||||
|
||||
``on_progress`` will be a callback which expects an additional keyword argument ``_progress`` with the current
|
||||
slicing progress which - if progress reporting is supported - the slicing plugin should call like the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if on_progress is not None:
|
||||
if on_progress_args is None:
|
||||
on_progress_args = ()
|
||||
if on_progress_kwargs is None:
|
||||
on_progress_kwargs = dict()
|
||||
|
||||
on_progress_kwargs["_progress"] = your_plugins_slicing_progress
|
||||
on_progress(*on_progress_args, **on_progress_kwargs)
|
||||
|
||||
Please note that both ``on_progress_args`` and ``on_progress_kwargs`` as supplied by OctoPrint might be ``None``,
|
||||
so always make sure to initialize those values to sane defaults like depicted above before invoking the callback.
|
||||
"""
|
||||
pass
|
||||
|
||||
def cancel_slicing(self, machinecode_path):
|
||||
"""
|
||||
Cancels the slicing to the indicated file
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,101 @@ class BedTypes(object):
|
|||
return [getattr(cls, name) for name in cls.__dict__ if not name.startswith("__")]
|
||||
|
||||
class PrinterProfileManager(object):
|
||||
"""
|
||||
Manager for printer profiles. Offers methods to select the globally used printer profile and to list, add, remove,
|
||||
load and save printer profiles.
|
||||
|
||||
A printer profile is a ``dict`` of the following structure:
|
||||
|
||||
.. list-table::
|
||||
:widths: 15 5 10 30
|
||||
:header-rows: 1
|
||||
|
||||
* - Name
|
||||
- Type
|
||||
- Description
|
||||
* - ``id``
|
||||
- ``string``
|
||||
- Internal id of the printer profile
|
||||
* - ``name``
|
||||
- ``string``
|
||||
- Human readable name of the printer profile
|
||||
* - ``model``
|
||||
- ``string``
|
||||
- Printer model
|
||||
* - ``color``
|
||||
- ``string``
|
||||
- Color to associate with the printer profile
|
||||
* - ``volume``
|
||||
- ``dict``
|
||||
- Information about the print volume
|
||||
* - ``volume.width``
|
||||
- ``float``
|
||||
- Width of the print volume (X axis)
|
||||
* - ``volume.depth``
|
||||
- ``float``
|
||||
- Depth of the print volume (Y axis)
|
||||
* - ``volume.height``
|
||||
- ``float``
|
||||
- Height of the print volume (Z axis)
|
||||
* - ``volume.formFactor``
|
||||
- ``string``
|
||||
- Form factor of the print bed, either ``rectangular`` or ``circular``
|
||||
* - ``heatedBed``
|
||||
- ``bool``
|
||||
- Whether the printer has a heated bed (``True``) or not (``False``)
|
||||
* - ``extruder``
|
||||
- ``dict``
|
||||
- Information about the printer's extruders
|
||||
* - ``extruder.count``
|
||||
- ``int``
|
||||
- How many extruders the printer has (default 1)
|
||||
* - ``extruder.offsets``
|
||||
- ``list`` of ``tuple``s
|
||||
- Extruder offsets relative to first extruder, list of (x, y) tuples, first is always (0,0)
|
||||
* - ``extruder.nozzleDiameter``
|
||||
- ``float``
|
||||
- Diameter of the printer nozzle
|
||||
* - ``axes``
|
||||
- ``dict``
|
||||
- Information about the printer axes
|
||||
* - ``axes.x``
|
||||
- ``dict``
|
||||
- Information about the printer's X axis
|
||||
* - ``axes.x.speed``
|
||||
- ``float``
|
||||
- Speed of the X axis in mm/s
|
||||
* - ``axes.x.inverted``
|
||||
- ``bool``
|
||||
- Whether a positive value change moves the nozzle away from the print bed's origin (False, default) or towards it (True)
|
||||
* - ``axes.y``
|
||||
- ``dict``
|
||||
- Information about the printer's Y axis
|
||||
* - ``axes.y.speed``
|
||||
- ``float``
|
||||
- Speed of the Y axis in mm/s
|
||||
* - ``axes.y.inverted``
|
||||
- ``bool``
|
||||
- Whether a positive value change moves the nozzle away from the print bed's origin (False, default) or towards it (True)
|
||||
* - ``axes.z``
|
||||
- ``dict``
|
||||
- Information about the printer's Z axis
|
||||
* - ``axes.z.speed``
|
||||
- ``float``
|
||||
- Speed of the Z axis in mm/s
|
||||
* - ``axes.z.inverted``
|
||||
- ``bool``
|
||||
- Whether a positive value change moves the nozzle away from the print bed (False, default) or towards it (True)
|
||||
* - ``axes.e``
|
||||
- ``dict``
|
||||
- Information about the printer's E axis
|
||||
* - ``axes.e.speed``
|
||||
- ``float``
|
||||
- Speed of the E axis in mm/s
|
||||
* - ``axes.e.inverted``
|
||||
- ``bool``
|
||||
- Whether a positive value change extrudes (False, default) or retracts (True) filament
|
||||
"""
|
||||
|
||||
default = dict(
|
||||
id = "_default",
|
||||
|
|
|
|||
Loading…
Reference in a new issue