Further work on the REST API, documented most of /api/printer and while at it also fixed #365
This commit is contained in:
parent
22614f09a0
commit
072079df05
10 changed files with 783 additions and 130 deletions
|
|
@ -258,7 +258,7 @@ Retrieve a specific file's information
|
||||||
|
|
||||||
.. sourcecode:: http
|
.. sourcecode:: http
|
||||||
|
|
||||||
HTTP/1.1 200 Ok
|
HTTP/1.1 200 OK
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,11 @@ Please be advised that clients should use the header field variant if at all pos
|
||||||
|
|
||||||
The API key options in the "Change password" dialog. Users can generate and revoke their custom API key here.
|
The API key options in the "Change password" dialog. Users can generate and revoke their custom API key here.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
OctoPrint's web interface uses a custom API key that is freshly generated on every server start. This key is not
|
||||||
|
intended to be used by any other client and would not be very useful in any case, since it basically represents
|
||||||
|
a completely anonymous client.
|
||||||
|
|
||||||
.. _sec-api-general-contenttype:
|
.. _sec-api-general-contenttype:
|
||||||
|
|
||||||
Content Type
|
Content Type
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,165 @@ Printer control is mostly achieved through the use of commands, issued to resour
|
||||||
printer. OctoPrint currently knows the following components:
|
printer. OctoPrint currently knows the following components:
|
||||||
|
|
||||||
Print head
|
Print head
|
||||||
Print head commands allow jogging and homing the print head in all three axes. See :ref:`sec-api-printer-printheadcommand`.
|
Print head commands allow jogging and homing the print head in all three axes. Querying the resource is currently
|
||||||
Heater
|
not supported.
|
||||||
Heater commands allow setting the temperature and temperature offsets for the printer's hotend and bed. Currently
|
See :ref:`sec-api-printer-printheadcommand`.
|
||||||
OctoPrint only supports one hotend heater (this will change in the future). See :ref:`sec-api-printer-heatercommand`.
|
Tool
|
||||||
Feeder
|
Tool commands allow setting the temperature and temperature offsets for the printer's hotends/tools. Querying the
|
||||||
Feeder commands allow extrusion/extraction of filament. Currently OctoPrint only supports one feeder (this will
|
corresponding resource returns temperature information including an optional history.
|
||||||
change in a future version). See :ref:`sec-api-printer-feedercommand`.
|
See :ref:`sec-api-printer-toolcommand`.
|
||||||
|
Bed
|
||||||
|
Bed commands allow setting the temperature and temperature offset for the printer's heated bed. Querying the
|
||||||
|
corresponding resource returns temperature information including an optional history.
|
||||||
|
See :ref:`sec-api-printer-bedcommand`.
|
||||||
SD card
|
SD card
|
||||||
SD commands allow initialization, refresh and release of the printer's SD card (if available). See :ref:`sec-api-printer-sdcommand`.
|
SD commands allow initialization, refresh and release of the printer's SD card (if available). Querying the
|
||||||
|
corresponding resource returns the current SD card state.
|
||||||
|
See :ref:`sec-api-printer-sdcommand`.
|
||||||
|
|
||||||
|
Besides that, OctoPrint also provides a :ref:`full state report of the printer <sec-api-printer-state>`.
|
||||||
|
|
||||||
|
.. _sec-api-printer-state:
|
||||||
|
|
||||||
|
Retrieve the current printer state
|
||||||
|
==================================
|
||||||
|
|
||||||
|
.. http:get:: /api/printer
|
||||||
|
|
||||||
|
Retrieves the current state of the printer. Returned information includes:
|
||||||
|
|
||||||
|
* temperature information (see also :ref:`Retrieve the current tool state <sec-api-printer-toolstate>` and
|
||||||
|
:ref:`Retrieve the current bed state <sec-api-printer-bedstate>`)
|
||||||
|
* sd state (if available, see also :ref:`Retrieve the current SD state <sec-api-printer-sdstate>`)
|
||||||
|
* general printer state
|
||||||
|
|
||||||
|
Temperature information can also be made to include the printer's temperature history by supplying the ``history``
|
||||||
|
query parameter. The amount of data points to return here can be limited using the ``limit`` query parameter.
|
||||||
|
|
||||||
|
Clients can specific a list of attributes to not return in the response (e.g. if they don't need it) via the
|
||||||
|
``exclude`` query parameter.
|
||||||
|
|
||||||
|
Returns a :http:statuscode:`200` with a :ref:`Full State Response <sec-api-printer-datamodel-fullstate>` in the
|
||||||
|
body upon success.
|
||||||
|
|
||||||
|
**Example 1**
|
||||||
|
|
||||||
|
Include temperature history data, but limit it to two entries.
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
GET /api/printer?history=true&limit=2 HTTP/1.1
|
||||||
|
Host: example.com
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"temperature": {
|
||||||
|
"tool0": {
|
||||||
|
"actual": 214.8821,
|
||||||
|
"target": 220.0,
|
||||||
|
"offset": 0
|
||||||
|
},
|
||||||
|
"tool1": {
|
||||||
|
"actual": 25.3,
|
||||||
|
"target": null,
|
||||||
|
"offset": 0
|
||||||
|
},
|
||||||
|
"bed": {
|
||||||
|
"actual": 50.221,
|
||||||
|
"target": 70.0,
|
||||||
|
"offset": 5
|
||||||
|
},
|
||||||
|
"history": [
|
||||||
|
{
|
||||||
|
"time": 1395651928,
|
||||||
|
"tool0": {
|
||||||
|
"actual": 214.8821,
|
||||||
|
"target": 220.0
|
||||||
|
},
|
||||||
|
"tool1": {
|
||||||
|
"actual": 25.3,
|
||||||
|
"target": null
|
||||||
|
},
|
||||||
|
"bed": {
|
||||||
|
"actual": 50.221,
|
||||||
|
"target": 70.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 1395651926,
|
||||||
|
"tool0": {
|
||||||
|
"actual": 212.32,
|
||||||
|
"target": 220.0
|
||||||
|
},
|
||||||
|
"tool1": {
|
||||||
|
"actual": 25.1,
|
||||||
|
"target": null
|
||||||
|
},
|
||||||
|
"bed": {
|
||||||
|
"actual": 49.1123,
|
||||||
|
"target": 70.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sd": {
|
||||||
|
"ready": true
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"text": "Operational",
|
||||||
|
"flags": {
|
||||||
|
"operational": true,
|
||||||
|
"paused": false,
|
||||||
|
"printing": false,
|
||||||
|
"sdReady": true,
|
||||||
|
"error": false,
|
||||||
|
"ready": true,
|
||||||
|
"closedOrError": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
**Example 2**
|
||||||
|
|
||||||
|
Exclude temperature and sd data.
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
GET /api/printer?exclude=temperature,sd HTTP/1.1
|
||||||
|
Host: example.com
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"state": {
|
||||||
|
"text": "Operational",
|
||||||
|
"flags": {
|
||||||
|
"operational": true,
|
||||||
|
"paused": false,
|
||||||
|
"printing": false,
|
||||||
|
"sdReady": true,
|
||||||
|
"error": false,
|
||||||
|
"ready": true,
|
||||||
|
"closedOrError": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:query exclude: An optional comma-separated list of fields to exclude from the response (e.g. if not needed by
|
||||||
|
the client). Valid values to supply here are ``temperature``, ``sd`` and ``state``.
|
||||||
|
:query history: If set to ``true`` (or: ``yes``, ``y``, ``1``), history information will be included in the response
|
||||||
|
too. If no ``limit`` parameter is given, all available temperature history data will be returned.
|
||||||
|
:query limit: If set to an integer (``n``), only the last ``n`` data points from the printer's temperature history
|
||||||
|
will be returned. Will be ignored if ``history`` is not enabled.
|
||||||
|
:statuscode 200: No error
|
||||||
|
:statuscode 409: If the printer is not operational.
|
||||||
|
|
||||||
.. _sec-api-printer-printheadcommand:
|
.. _sec-api-printer-printheadcommand:
|
||||||
|
|
||||||
|
|
@ -70,6 +220,10 @@ Issue a print head command
|
||||||
"z": 0.02
|
"z": 0.02
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
**Example Home Request**
|
**Example Home Request**
|
||||||
|
|
||||||
Home the X and Y axes.
|
Home the X and Y axes.
|
||||||
|
|
@ -86,6 +240,10 @@ Issue a print head command
|
||||||
"axes": ["x", "y"]
|
"axes": ["x", "y"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
:json string command: The command to issue, either ``jog`` or ``home``.
|
:json string command: The command to issue, either ``jog`` or ``home``.
|
||||||
:json number x: ``jog`` command: The amount to travel on the X axis in mm.
|
:json number x: ``jog`` command: The amount to travel on the X axis in mm.
|
||||||
:json number y: ``jog`` command: The amount to travel on the Y axis in mm.
|
:json number y: ``jog`` command: The amount to travel on the Y axis in mm.
|
||||||
|
|
@ -96,67 +254,74 @@ Issue a print head command
|
||||||
request.
|
request.
|
||||||
:statuscode 409: If the printer is not operational or currently printing.
|
:statuscode 409: If the printer is not operational or currently printing.
|
||||||
|
|
||||||
.. _sec-api-printer-heatercommand:
|
.. _sec-api-printer-toolcommand:
|
||||||
|
|
||||||
Issue a heater command
|
Issue a tool command
|
||||||
======================
|
====================
|
||||||
|
|
||||||
.. todo::
|
.. http:post:: /api/printer/tool
|
||||||
|
|
||||||
Update to current implementation!
|
Tool commands allow setting the temperature and temperature offsets for the printer's tools (hotends), selecting
|
||||||
|
the current tool and extruding/retracting from the currently selected tool. Available commands are:
|
||||||
|
|
||||||
.. http:post:: /api/printer/heater
|
target
|
||||||
|
Sets the given target temperature on the printer's tools. Additional parameters:
|
||||||
|
|
||||||
Heater commands allow setting the temperature and temperature offsets for the printer's hotend and bed. Available
|
* ``targets``: Target temperature(s) to set, properties must match the format ``tool{n}`` with ``n`` being the
|
||||||
commands are:
|
tool's index starting with 0.
|
||||||
|
|
||||||
temp
|
|
||||||
Sets the given target temperature on the printer's hotend and/or bed. Additional parameters:
|
|
||||||
|
|
||||||
* ``targets``: Target temperature(s) to set, allowed properties are:
|
|
||||||
|
|
||||||
* ``hotend``: New target temperature of the printer's hotend in centigrade.
|
|
||||||
* ``bed``: New target temperature of the printer's bed in centigrade.
|
|
||||||
|
|
||||||
offset
|
offset
|
||||||
Sets the given temperature offset on the printer's hotend and/or bed. Additional parameters:
|
Sets the given temperature offset on the printer's tools. Additional parameters:
|
||||||
|
|
||||||
* ``offsets``: Offset(s) to set, allowed properties are:
|
* ``offsets``: Offset(s) to set, properties must match the format ``tool{n}`` with ``n`` being the tool's index
|
||||||
|
starting with 0.
|
||||||
|
|
||||||
* ``hotend``: New offset of the printer's hotend temperature in centigrade, max/min of +/-50°C.
|
select
|
||||||
* ``bed``: New offset of the printer's bed temperature in centigrade, max/min of +/-50°C.
|
Selects the printer's current tool. Additional parameters:
|
||||||
|
|
||||||
All of these commands may only be sent if the printer is currently operational and not printing. Otherwise a
|
* ``tool``: Tool to select, format ``tool{n}`` with ``n`` being the tool's index starting with 0.
|
||||||
:http:statuscode:`409` is returned.
|
|
||||||
|
extrude
|
||||||
|
Extrudes the given amount of filament from the currently selected tool. Additional parameters:
|
||||||
|
|
||||||
|
* ``amount``: The amount of filament to extrude in mm. May be negative to retract.
|
||||||
|
|
||||||
|
|
||||||
|
All of these commands may only be sent if the printer is currently operational and -- in case of ``select`` and
|
||||||
|
``extrude`` -- not printing. Otherwise a :http:statuscode:`409` is returned.
|
||||||
|
|
||||||
Upon success, a status code of :http:statuscode:`204` and an empty body is returned.
|
Upon success, a status code of :http:statuscode:`204` and an empty body is returned.
|
||||||
|
|
||||||
**Example Target Temperature Request**
|
**Example Target Temperature Request**
|
||||||
|
|
||||||
Set the printer's hotend target temperature to 220°C and the bed target temperature to 75°C.
|
Set the target temperature for the printer's first hotend to 220°C and the printer's second extruder to 205°C.
|
||||||
|
|
||||||
.. sourcecode:: http
|
.. sourcecode:: http
|
||||||
|
|
||||||
POST /api/printer/heater HTTP/1.1
|
POST /api/printer/tool HTTP/1.1
|
||||||
Host: example.com
|
Host: example.com
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
X-Api-Key: abcdef...
|
X-Api-Key: abcdef...
|
||||||
|
|
||||||
{
|
{
|
||||||
"command": "temp",
|
"command": "target",
|
||||||
"temps": {
|
"targets": {
|
||||||
"hotend": 220,
|
"tool0": 220,
|
||||||
"bed": 75
|
"tool1": 205
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
**Example Offset Temperature Request**
|
**Example Offset Temperature Request**
|
||||||
|
|
||||||
Set the offset for hotend temperatures to +10°C and for bed temperatures to -5°C.
|
Set the offset for temperatures on ``tool0`` to +10°C and on ``tool1`` to -5°C.
|
||||||
|
|
||||||
.. sourcecode:: http
|
.. sourcecode:: http
|
||||||
|
|
||||||
POST /api/printer/heater HTTP/1.1
|
POST /api/printer/tool HTTP/1.1
|
||||||
Host: example.com
|
Host: example.com
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
X-Api-Key: abcdef...
|
X-Api-Key: abcdef...
|
||||||
|
|
@ -164,62 +329,62 @@ Issue a heater command
|
||||||
{
|
{
|
||||||
"command": "offset",
|
"command": "offset",
|
||||||
"offsets": {
|
"offsets": {
|
||||||
"hotend": 10,
|
"tool0": 10,
|
||||||
"bed": -5
|
"tool1": -5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:json string command: The command to issue, either ``temp`` or ``offset``
|
.. sourcecode:: http
|
||||||
:json object temps: ``temp`` command: The target temperatures to set. Valid properties are ``hotend`` and ``bed``
|
|
||||||
:json object offsets: ``offset`` command: The offset temperature to set. Valid properties are ``hotend`` and ``bed``
|
|
||||||
:statuscode 204: No error
|
|
||||||
:statuscode 400: If ``temps`` or ``offsets`` contains a property other than ``hotend`` or ``bed``, the
|
|
||||||
target or offset temperature is not a valid number or outside of the supported range, or if the
|
|
||||||
request is otherwise invalid.
|
|
||||||
:statuscode 409: If the printer is not operational.
|
|
||||||
|
|
||||||
.. _sec-api-printer-feedercommand:
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
Issue a feeder command
|
**Example Tool Select Request**
|
||||||
======================
|
|
||||||
|
|
||||||
.. http:post:: /api/printer/feeder
|
Select the second hotend of the printer for any following ``extrude`` commands.
|
||||||
|
|
||||||
Feeder commands allow extrusion/extraction of filament. Available commands are:
|
|
||||||
|
|
||||||
extrude
|
|
||||||
Extrudes the given amount of filament. Additional parameters:
|
|
||||||
|
|
||||||
* ``amount``: The amount of filament to extrude in mm. May be negative to retract.
|
|
||||||
|
|
||||||
All of these commands may only be sent if the printer is currently operational and not printing. Otherwise a
|
|
||||||
:http:statuscode:`409` is returned.
|
|
||||||
|
|
||||||
Upon success, a status code of :http:statuscode:`204` and an empty body is returned.
|
|
||||||
|
|
||||||
**Example Extrude Request**
|
|
||||||
|
|
||||||
Extrudes 1mm of filament
|
|
||||||
|
|
||||||
.. sourcecode:: http
|
.. sourcecode:: http
|
||||||
|
|
||||||
POST /api/printer/feeder HTTP/1.1
|
POST /api/printer/tool HTTP/1.1
|
||||||
|
Host: example.com
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Api-Key: abcdef...
|
||||||
|
|
||||||
|
{
|
||||||
|
"command": "select",
|
||||||
|
"tool": "tool1"
|
||||||
|
}
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
|
**Example Extrude Request**
|
||||||
|
|
||||||
|
Extrude 5mm on the currently selected tool.
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
POST /api/printer/tool HTTP/1.1
|
||||||
Host: example.com
|
Host: example.com
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
X-Api-Key: abcdef...
|
X-Api-Key: abcdef...
|
||||||
|
|
||||||
{
|
{
|
||||||
"command": "extrude",
|
"command": "extrude",
|
||||||
"amount": 1
|
"amount": 5
|
||||||
}
|
}
|
||||||
|
|
||||||
**Example Retract Request**
|
|
||||||
|
|
||||||
Retracts 3mm of filament
|
|
||||||
|
|
||||||
.. sourcecode:: http
|
.. sourcecode:: http
|
||||||
|
|
||||||
POST /api/printer/feeder HTTP/1.1
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
|
**Example Retract Request**
|
||||||
|
|
||||||
|
Retract 3mm of filament on the currently selected tool.
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
POST /api/printer/tool HTTP/1.1
|
||||||
Host: example.com
|
Host: example.com
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
X-Api-Key: abcdef...
|
X-Api-Key: abcdef...
|
||||||
|
|
@ -229,16 +394,238 @@ Issue a feeder command
|
||||||
"amount": -3
|
"amount": -3
|
||||||
}
|
}
|
||||||
|
|
||||||
:json string command: The command to issue, only ``extrude`` is supported right now.
|
.. sourcecode:: http
|
||||||
:json number amount: ``extrude`` command: The amount of filament to extrude/retract in mm.
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
|
:json string command: The command to issue, either ``target``, ``offset``, ``select`` or ``extrude``.
|
||||||
|
:json object targets: ``target`` command: The target temperatures to set. Valid properties have to match the format ``tool{n}``.
|
||||||
|
:json object offsets: ``offset`` command: The offset temperature to set. Valid properties have to match the format ``tool{n}``.
|
||||||
|
:json object tool: ``select`` command: The tool to select, value has to match the format ``tool{n}``.
|
||||||
|
:json object amount: ``extrude`` command: The amount of filament to extrude from the currently selected tool.
|
||||||
:statuscode 204: No error
|
:statuscode 204: No error
|
||||||
:statuscode 400: If the value given for `amount` is not a valid number or the request is otherwise invalid.
|
:statuscode 400: If ``targets`` or ``offsets`` contains a property or ``tool`` contains a value not matching the format
|
||||||
:statuscode 409: If the printer is not operational or currently printing.
|
``tool{n}``, the target/offset temperature or extrusion amount is not a valid number or outside of
|
||||||
|
the supported range, or if the request is otherwise invalid.
|
||||||
|
:statuscode 409: If the printer is not operational or -- in case of ``select`` or ``extrude`` -- currently printing.
|
||||||
|
|
||||||
|
.. _sec-api-printer-toolstate:
|
||||||
|
|
||||||
|
Retrieve the current tool state
|
||||||
|
===============================
|
||||||
|
|
||||||
|
.. http:get:: /api/printer/tool
|
||||||
|
|
||||||
|
Retrieves the current temperature data (actual, target and offset) plus optionally a (limited) history (actual, target,
|
||||||
|
timestamp) for all of the printer's available tools.
|
||||||
|
|
||||||
|
It's also possible to retrieve the temperature history by supplying the ``history`` query parameter set to ``true``. The
|
||||||
|
amount of returned history data points can be limited using the ``limit`` query parameter.
|
||||||
|
|
||||||
|
Returns a :http:statuscode:`200` with a Temperature Response in the body upon success.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
If you want both tool and bed temperature information at the same time, take a look at
|
||||||
|
:ref:`Retrieve the current printer state <sec-api-printer-state>`.
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
Query the tool temperature data and also include the temperature history but limit it to two entries.
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
GET /api/printer/tool?history=true&limit=2 HTTP/1.1
|
||||||
|
Host: example.com
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"tool0": {
|
||||||
|
"actual": 214.8821,
|
||||||
|
"target": 220.0,
|
||||||
|
"offset": 0
|
||||||
|
},
|
||||||
|
"tool1": {
|
||||||
|
"actual": 25.3,
|
||||||
|
"target": null,
|
||||||
|
"offset": 0
|
||||||
|
},
|
||||||
|
"history": [
|
||||||
|
{
|
||||||
|
"time": 1395651928,
|
||||||
|
"tool0": {
|
||||||
|
"actual": 214.8821,
|
||||||
|
"target": 220.0
|
||||||
|
},
|
||||||
|
"tool1": {
|
||||||
|
"actual": 25.3,
|
||||||
|
"target": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 1395651926,
|
||||||
|
"tool0": {
|
||||||
|
"actual": 212.32,
|
||||||
|
"target": 220.0
|
||||||
|
},
|
||||||
|
"tool1": {
|
||||||
|
"actual": 25.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
:query history: If set to ``true`` (or: ``yes``, ``y``, ``1``), history information will be included in the response
|
||||||
|
too. If no ``limit`` parameter is given, all available temperature history data will be returned.
|
||||||
|
:query limit: If set to an integer (``n``), only the last ``n`` data points from the printer's temperature history
|
||||||
|
will be returned. Will be ignored if ``history`` is not enabled.
|
||||||
|
:statuscode 200: No error
|
||||||
|
:statuscode 409: If the printer is not operational.
|
||||||
|
|
||||||
|
.. _sec-api-printer-bedcommand:
|
||||||
|
|
||||||
|
Issue a bed command
|
||||||
|
===================
|
||||||
|
|
||||||
|
.. http:post:: /api/printer/bed
|
||||||
|
|
||||||
|
Bed commands allow setting the temperature and temperature offsets for the printer's heated bed. Available commands
|
||||||
|
are:
|
||||||
|
|
||||||
|
target
|
||||||
|
Sets the given target temperature on the printer's tools. Additional parameters:
|
||||||
|
|
||||||
|
* ``target``: Target temperature to set.
|
||||||
|
|
||||||
|
offset
|
||||||
|
Sets the given temperature offset on the printer's tools. Additional parameters:
|
||||||
|
|
||||||
|
* ``offsets``: Offset to set.
|
||||||
|
|
||||||
|
All of these commands may only be sent if the printer is currently operational. Otherwise a :http:statuscode:`409`
|
||||||
|
is returned.
|
||||||
|
|
||||||
|
Upon success, a status code of :http:statuscode:`204` and an empty body is returned.
|
||||||
|
|
||||||
|
**Example Target Temperature Request**
|
||||||
|
|
||||||
|
Set the target temperature for the printer's heated bed to 75°C.
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
POST /api/printer/bed HTTP/1.1
|
||||||
|
Host: example.com
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Api-Key: abcdef...
|
||||||
|
|
||||||
|
{
|
||||||
|
"command": "target",
|
||||||
|
"target": 75
|
||||||
|
}
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
|
**Example Offset Temperature Request**
|
||||||
|
|
||||||
|
Set the temperature offset for the heated bed to -5°C.
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
POST /api/printer/bed HTTP/1.1
|
||||||
|
Host: example.com
|
||||||
|
Content-Type: application/json
|
||||||
|
X-Api-Key: abcdef...
|
||||||
|
|
||||||
|
{
|
||||||
|
"command": "offset",
|
||||||
|
"offset": -5
|
||||||
|
}
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
|
:json string command: The command to issue, either ``target`` or ``offset``.
|
||||||
|
:json object target: ``target`` command: The target temperature to set.
|
||||||
|
:json object offset: ``offset`` command: The offset temperature to set.
|
||||||
|
:statuscode 204: No error
|
||||||
|
:statuscode 400: If ``target`` or ``offset`` is not a valid number or outside of the supported range, or if the
|
||||||
|
request is otherwise invalid.
|
||||||
|
:statuscode 409: If the printer is not operational.
|
||||||
|
|
||||||
|
.. _sec-api-printer-bedstate:
|
||||||
|
|
||||||
|
Retrieve the current bed state
|
||||||
|
==============================
|
||||||
|
|
||||||
|
.. http:get:: /api/printer/bed
|
||||||
|
|
||||||
|
Retrieves the current temperature data (actual, target and offset) plus optionally a (limited) history (actual, target,
|
||||||
|
timestamp) for the printer's heated bed.
|
||||||
|
|
||||||
|
It's also possible to retrieve the temperature history by supplying the ``history`` query parameter set to ``true``. The
|
||||||
|
amount of returned history data points can be limited using the ``limit`` query parameter.
|
||||||
|
|
||||||
|
Returns a :http:statuscode:`200` with a Temperature Response in the body upon success.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
If you want both tool and bed temperature information at the same time, take a look at
|
||||||
|
:ref:`Retrieve the current printer state <sec-api-printer-state>`.
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
Query the bed temperature data and also include the temperature history but limit it to two entries.
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
GET /api/printer/bed?history=true&limit=2 HTTP/1.1
|
||||||
|
Host: example.com
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"bed": {
|
||||||
|
"actual": 50.221,
|
||||||
|
"target": 70.0,
|
||||||
|
"offset": 5
|
||||||
|
},
|
||||||
|
"history": [
|
||||||
|
{
|
||||||
|
"time": 1395651928,
|
||||||
|
"bed": {
|
||||||
|
"actual": 50.221,
|
||||||
|
"target": 70.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": 1395651926,
|
||||||
|
"bed": {
|
||||||
|
"actual": 49.1123,
|
||||||
|
"target": 70.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
:query history: If set to ``true`` (or: ``yes``, ``y``, ``1``), history information will be included in the response
|
||||||
|
too. If no ``limit`` parameter is given, all available temperature history data will be returned.
|
||||||
|
:query limit: If set to an integer (``n``), only the last ``n`` data points from the printer's temperature history
|
||||||
|
will be returned. Will be ignored if ``history`` is not enabled.
|
||||||
|
:statuscode 200: No error
|
||||||
|
:statuscode 409: If the printer is not operational.
|
||||||
|
|
||||||
.. _sec-api-printer-sdcommand:
|
.. _sec-api-printer-sdcommand:
|
||||||
|
|
||||||
Issue a SD command
|
Issue an SD command
|
||||||
==================
|
===================
|
||||||
|
|
||||||
.. http:post:: /api/printer/sd
|
.. http:post:: /api/printer/sd
|
||||||
|
|
||||||
|
|
@ -268,6 +655,8 @@ Issue a SD command
|
||||||
|
|
||||||
**Example Init Request**
|
**Example Init Request**
|
||||||
|
|
||||||
|
Initialize the SD card.
|
||||||
|
|
||||||
.. sourcecode:: http
|
.. sourcecode:: http
|
||||||
|
|
||||||
POST /api/printer/sd HTTP/1.1
|
POST /api/printer/sd HTTP/1.1
|
||||||
|
|
@ -279,8 +668,14 @@ Issue a SD command
|
||||||
"command": "init"
|
"command": "init"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
**Example Refresh Request**
|
**Example Refresh Request**
|
||||||
|
|
||||||
|
Refresh the file list of the SD card
|
||||||
|
|
||||||
.. sourcecode:: http
|
.. sourcecode:: http
|
||||||
|
|
||||||
POST /api/printer/sd HTTP/1.1
|
POST /api/printer/sd HTTP/1.1
|
||||||
|
|
@ -292,8 +687,14 @@ Issue a SD command
|
||||||
"command": "refresh"
|
"command": "refresh"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
**Example Release Request**
|
**Example Release Request**
|
||||||
|
|
||||||
|
Release the SD card
|
||||||
|
|
||||||
.. sourcecode:: http
|
.. sourcecode:: http
|
||||||
|
|
||||||
POST /api/printer/sd HTTP/1.1
|
POST /api/printer/sd HTTP/1.1
|
||||||
|
|
@ -305,6 +706,10 @@ Issue a SD command
|
||||||
"command": "release"
|
"command": "release"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
:json string command: The command to issue, either ``init``, ``refresh`` or ``release``.
|
:json string command: The command to issue, either ``init``, ``refresh`` or ``release``.
|
||||||
:statuscode 204: No error
|
:statuscode 204: No error
|
||||||
:statuscode 409: If a ``refresh`` or ``release`` command is issued but the SD card has not been initialized (e.g.
|
:statuscode 409: If a ``refresh`` or ``release`` command is issued but the SD card has not been initialized (e.g.
|
||||||
|
|
@ -324,15 +729,15 @@ Retrieve the current SD state
|
||||||
Returns a :http:statuscode:`200` with an :ref:`SD State Response <sec-api-printer-datamodel-sdstate>` in the body
|
Returns a :http:statuscode:`200` with an :ref:`SD State Response <sec-api-printer-datamodel-sdstate>` in the body
|
||||||
upon success.
|
upon success.
|
||||||
|
|
||||||
**Example Request**
|
**Example**
|
||||||
|
|
||||||
|
Read the current state of the SD card.
|
||||||
|
|
||||||
.. sourcecode:: http
|
.. sourcecode:: http
|
||||||
|
|
||||||
GET /api/printer/sd HTTP/1.1
|
GET /api/printer/sd HTTP/1.1
|
||||||
Host: example.com
|
Host: example.com
|
||||||
|
|
||||||
**Example Response**
|
|
||||||
|
|
||||||
.. sourcecode:: http
|
.. sourcecode:: http
|
||||||
|
|
||||||
HTTP/1.1 200 OK
|
HTTP/1.1 200 OK
|
||||||
|
|
@ -350,10 +755,116 @@ Retrieve the current SD state
|
||||||
Datamodel
|
Datamodel
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
.. _sec-api-printer-datamodel-fullstate:
|
||||||
|
|
||||||
|
Full State Response
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: 15 5 10 30
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Name
|
||||||
|
- Multiplicity
|
||||||
|
- Type
|
||||||
|
- Description
|
||||||
|
* - ``temperature``
|
||||||
|
- 0..1
|
||||||
|
- :ref:`Temperature State <sec-api-printer-datamodel-temps>`
|
||||||
|
- The printer's temperature state data
|
||||||
|
* - ``sd``
|
||||||
|
- 0..1
|
||||||
|
- :ref:`SD State <sec-api-printer-datamodel-sdstate>`
|
||||||
|
- The printer's sd state data
|
||||||
|
* - ``state``
|
||||||
|
- 0..1
|
||||||
|
- :ref:`Printer State <sec-api-printer-datamodel-printerstate>`
|
||||||
|
- The printer's general state
|
||||||
|
|
||||||
|
.. _sec-api-printer-datamodel-temps:
|
||||||
|
|
||||||
|
Temperature State
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: 15 5 10 30
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Name
|
||||||
|
- Multiplicity
|
||||||
|
- Type
|
||||||
|
- Description
|
||||||
|
* - ``tool{n}``
|
||||||
|
- 0..*
|
||||||
|
- :ref:`Temperature Data <sec-api-printer-datamodel-tempdata>`
|
||||||
|
- Current temperature stats for tool *n*. Enumeration starts at 0 for the first tool. Not included if querying
|
||||||
|
only bed state.
|
||||||
|
* - ``bed``
|
||||||
|
- 0..1
|
||||||
|
- :ref:`Temperature Data <sec-api-printer-datamodel-tempdata>`
|
||||||
|
- Current temperature stats for the printer's heated bed. Not included if querying only tool state.
|
||||||
|
* - ``history``
|
||||||
|
- 0..1
|
||||||
|
- List of :ref:`Historic Temperature Datapoint <sec-api-printer-datamodel-temphistory>`
|
||||||
|
- Temperature history
|
||||||
|
|
||||||
|
.. _sec-api-printer-datamodel-temphistory:
|
||||||
|
|
||||||
|
Historic Temperature Data Point
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: 15 5 10 30
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Name
|
||||||
|
- Multiplicity
|
||||||
|
- Type
|
||||||
|
- Description
|
||||||
|
* - ``time``
|
||||||
|
- 1
|
||||||
|
- Unix Timestamp
|
||||||
|
- Timestamp of this data point
|
||||||
|
* - ``tool{n}``
|
||||||
|
- 0..*
|
||||||
|
- :ref:`Temperature Data <sec-api-printer-datamodel-tempdata>`
|
||||||
|
- Temperature stats for tool *n*. Enumeration starts at 0 for the first tool. Not included if querying only
|
||||||
|
bed state.
|
||||||
|
* - ``bed``
|
||||||
|
- 0..*
|
||||||
|
- :ref:`Temperature Data <sec-api-printer-datamodel-tempdata>`
|
||||||
|
- Temperature stats for the printer's heated bed. Not included if querying only tool state.
|
||||||
|
|
||||||
|
.. _sec-api-printer-datamodel-tempdata:
|
||||||
|
|
||||||
|
Temperature Data
|
||||||
|
----------------
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: 15 5 10 30
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Name
|
||||||
|
- Multiplicity
|
||||||
|
- Type
|
||||||
|
- Description
|
||||||
|
* - ``actual``
|
||||||
|
- 1
|
||||||
|
- Number
|
||||||
|
- Current temperature
|
||||||
|
* - ``target``
|
||||||
|
- 1
|
||||||
|
- Number
|
||||||
|
- Target temperature, may be ``null`` if no target temperature is set.
|
||||||
|
* - ``offset``
|
||||||
|
- 0..1
|
||||||
|
- Number
|
||||||
|
- Currently configured temperature offset to apply, will be left out for historic temperature information.
|
||||||
|
|
||||||
.. _sec-api-printer-datamodel-sdstate:
|
.. _sec-api-printer-datamodel-sdstate:
|
||||||
|
|
||||||
SD State Response
|
SD State
|
||||||
-----------------
|
--------
|
||||||
|
|
||||||
.. list-table::
|
.. list-table::
|
||||||
:widths: 15 5 10 30
|
:widths: 15 5 10 30
|
||||||
|
|
@ -367,3 +878,54 @@ SD State Response
|
||||||
- 1
|
- 1
|
||||||
- Boolean
|
- Boolean
|
||||||
- Whether the SD card has been initialized (``true``) or not (``false``).
|
- Whether the SD card has been initialized (``true``) or not (``false``).
|
||||||
|
|
||||||
|
.. _sec-api-printer-datamodel-printerstate:
|
||||||
|
|
||||||
|
Printer State
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: 15 5 10 30
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Name
|
||||||
|
- Multiplicity
|
||||||
|
- Type
|
||||||
|
- Description
|
||||||
|
* - ``text``
|
||||||
|
- 1
|
||||||
|
- String
|
||||||
|
- A textual representation of the current state of the printer, e.g. "Operational" or "Printing"
|
||||||
|
* - ``flags``
|
||||||
|
- 1
|
||||||
|
- Printer state flags
|
||||||
|
- A couple of boolean printer state flags
|
||||||
|
* - ``flags.operational``
|
||||||
|
- 1
|
||||||
|
- Boolean
|
||||||
|
- ``true`` if the printer is operational, ``false`` otherwise
|
||||||
|
* - ``flags.paused``
|
||||||
|
- 1
|
||||||
|
- Boolean
|
||||||
|
- ``true`` if the printer is currently paused, ``false`` otherwise
|
||||||
|
* - ``flags.printing``
|
||||||
|
- 1
|
||||||
|
- Boolean
|
||||||
|
- ``true`` if the printer is currently printing, ``false`` otherwise
|
||||||
|
* - ``flags.sdReady``
|
||||||
|
- 1
|
||||||
|
- Boolean
|
||||||
|
- ``true`` if the printer's SD card is available and initialized, ``false`` otherwise. This is redundant information
|
||||||
|
to :ref:`the SD State <sec-api-printer-datamodel-sdstate>`.
|
||||||
|
* - ``flags.error``
|
||||||
|
- 1
|
||||||
|
- Boolean
|
||||||
|
- ``true`` if an unrecoverable error occurred, ``false`` otherwise
|
||||||
|
* - ``flags.ready``
|
||||||
|
- 1
|
||||||
|
- Boolean
|
||||||
|
- ``true`` if the printer is operational and no data is currently being streamed to SD, so ready to receive instructions
|
||||||
|
* - ``flags.closedOrError``
|
||||||
|
- 1
|
||||||
|
- Boolean
|
||||||
|
- ``true`` if the printer is disconnected (possibly due to an error), ``false`` otherwise
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
|
import uuid
|
||||||
|
|
||||||
__author__ = "Gina Häußge <osd@foosel.net>"
|
__author__ = "Gina Häußge <osd@foosel.net>"
|
||||||
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
||||||
|
|
||||||
|
|
@ -40,6 +42,9 @@ import octoprint.events as events
|
||||||
import octoprint.timelapse
|
import octoprint.timelapse
|
||||||
|
|
||||||
|
|
||||||
|
UI_API_KEY = ''.join('%02X' % ord(z) for z in uuid.uuid4().bytes)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
branch = None
|
branch = None
|
||||||
|
|
@ -64,7 +69,8 @@ def index():
|
||||||
gitCommit=commit,
|
gitCommit=commit,
|
||||||
stylesheet=settings().get(["devel", "stylesheet"]),
|
stylesheet=settings().get(["devel", "stylesheet"]),
|
||||||
gcodeMobileThreshold=settings().get(["gcodeViewer", "mobileSizeThreshold"]),
|
gcodeMobileThreshold=settings().get(["gcodeViewer", "mobileSizeThreshold"]),
|
||||||
gcodeThreshold=settings().get(["gcodeViewer", "sizeThreshold"])
|
gcodeThreshold=settings().get(["gcodeViewer", "sizeThreshold"]),
|
||||||
|
uiApiKey=UI_API_KEY
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
|
from octoprint.server.util import getApiKey, getUserForApiKey
|
||||||
|
|
||||||
__author__ = "Gina Häußge <osd@foosel.net>"
|
__author__ = "Gina Häußge <osd@foosel.net>"
|
||||||
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
||||||
|
|
||||||
|
|
@ -13,7 +15,7 @@ from flask.ext.principal import Identity, identity_changed, AnonymousIdentity
|
||||||
import octoprint.util as util
|
import octoprint.util as util
|
||||||
import octoprint.users
|
import octoprint.users
|
||||||
import octoprint.server
|
import octoprint.server
|
||||||
from octoprint.server import restricted_access, admin_permission, NO_CONTENT
|
from octoprint.server import restricted_access, admin_permission, NO_CONTENT, UI_API_KEY
|
||||||
from octoprint.settings import settings as s, valid_boolean_trues
|
from octoprint.settings import settings as s, valid_boolean_trues
|
||||||
|
|
||||||
#~~ init api blueprint, including sub modules
|
#~~ init api blueprint, including sub modules
|
||||||
|
|
@ -30,6 +32,41 @@ from . import users as api_users
|
||||||
from . import log as api_logs
|
from . import log as api_logs
|
||||||
|
|
||||||
|
|
||||||
|
@api.before_request
|
||||||
|
def beforeApiRequests():
|
||||||
|
"""
|
||||||
|
All requests in this blueprint need to be made supplying an API key. This may be the UI_API_KEY, in which case
|
||||||
|
the underlying request processing will directly take place, or it may be the global or a user specific case. In any
|
||||||
|
case it has to be present and must be valid, so anything other than the above three types will result in denying
|
||||||
|
the request.
|
||||||
|
"""
|
||||||
|
|
||||||
|
apikey = getApiKey(request)
|
||||||
|
if apikey is None:
|
||||||
|
# no api key => 401
|
||||||
|
return make_response("No API key provided", 401)
|
||||||
|
|
||||||
|
if apikey == UI_API_KEY:
|
||||||
|
# ui api key => continue regular request processing
|
||||||
|
return
|
||||||
|
|
||||||
|
if not s().get(["api", "enabled"]):
|
||||||
|
# api disabled => 401
|
||||||
|
return make_response("API disabled", 401)
|
||||||
|
|
||||||
|
if apikey == s().get(["api", "key"]):
|
||||||
|
# global api key => continue regular request processing
|
||||||
|
return
|
||||||
|
|
||||||
|
user = getUserForApiKey(apikey)
|
||||||
|
if user is not None:
|
||||||
|
# user specific api key => continue regular request processing
|
||||||
|
return
|
||||||
|
|
||||||
|
# invalid api key => 401
|
||||||
|
return make_response("Invalid API key", 401)
|
||||||
|
|
||||||
|
|
||||||
#~~ first run setup
|
#~~ first run setup
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,36 @@ import octoprint.util as util
|
||||||
|
|
||||||
#~~ Printer
|
#~~ Printer
|
||||||
|
|
||||||
|
|
||||||
@api.route("/printer", methods=["GET"])
|
@api.route("/printer", methods=["GET"])
|
||||||
def printerState():
|
def printerState():
|
||||||
if not printer.isOperational():
|
if not printer.isOperational():
|
||||||
return make_response("Printer is not operational", 409)
|
return make_response("Printer is not operational", 409)
|
||||||
|
|
||||||
|
# process excludes
|
||||||
|
excludes = []
|
||||||
|
if "exclude" in request.values:
|
||||||
|
excludeStr = request.values["exclude"]
|
||||||
|
if len(excludeStr.strip()) > 0:
|
||||||
|
excludes = filter(lambda x: x in ["temperature", "sd", "state"], map(lambda x: x.strip(), excludeStr.split(",")))
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
result.update(_getTemperatureData(lambda x: x))
|
|
||||||
|
# add temperature information
|
||||||
|
if not "temperature" in excludes:
|
||||||
|
result.update({"temperature": _getTemperatureData(lambda x: x)})
|
||||||
|
|
||||||
|
# add sd information
|
||||||
|
if not "sd" in excludes and settings().getBoolean(["feature", "sdSupport"]):
|
||||||
|
result.update({"sd": {"ready": printer.isSdReady()}})
|
||||||
|
|
||||||
|
# add state information
|
||||||
|
if not "state" in excludes:
|
||||||
|
state = printer.getCurrentData()["state"]
|
||||||
|
result.update({"state": {
|
||||||
|
"text": state["stateString"],
|
||||||
|
"flags": state["flags"]
|
||||||
|
}})
|
||||||
|
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
||||||
|
|
@ -276,11 +299,14 @@ def printerCommand():
|
||||||
data = request.json
|
data = request.json
|
||||||
|
|
||||||
parameters = {}
|
parameters = {}
|
||||||
if "parameters" in data.keys(): parameters = data["parameters"]
|
if "parameters" in data.keys():
|
||||||
|
parameters = data["parameters"]
|
||||||
|
|
||||||
commands = []
|
commands = []
|
||||||
if "command" in data.keys(): commands = [data["command"]]
|
if "command" in data.keys():
|
||||||
elif "commands" in data.keys(): commands = data["commands"]
|
commands = [data["command"]]
|
||||||
|
elif "commands" in data.keys():
|
||||||
|
commands = data["commands"]
|
||||||
|
|
||||||
commandsToSend = []
|
commandsToSend = []
|
||||||
for command in commands:
|
for command in commands:
|
||||||
|
|
@ -306,9 +332,6 @@ def _getTemperatureData(filter):
|
||||||
return make_response("Printer is not operational", 409)
|
return make_response("Printer is not operational", 409)
|
||||||
|
|
||||||
tempData = printer.getCurrentTemperatures()
|
tempData = printer.getCurrentTemperatures()
|
||||||
result = {
|
|
||||||
"temps": filter(tempData)
|
|
||||||
}
|
|
||||||
|
|
||||||
if "history" in request.values.keys() and request.values["history"] in valid_boolean_trues:
|
if "history" in request.values.keys() and request.values["history"] in valid_boolean_trues:
|
||||||
tempHistory = printer.getTemperatureHistory()
|
tempHistory = printer.getTemperatureHistory()
|
||||||
|
|
@ -320,9 +343,9 @@ def _getTemperatureData(filter):
|
||||||
history = list(tempHistory)
|
history = list(tempHistory)
|
||||||
limit = min(limit, len(history))
|
limit = min(limit, len(history))
|
||||||
|
|
||||||
result.update({
|
tempData.update({
|
||||||
"history": map(lambda x: filter(x), history[-limit:])
|
"history": map(lambda x: filter(x), history[-limit:])
|
||||||
})
|
})
|
||||||
|
|
||||||
return result
|
return filter(tempData)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,9 @@ def restricted_access(func, apiEnabled=True):
|
||||||
if settings().getBoolean(["server", "firstRun"]) and (octoprint.server.userManager is None or not octoprint.server.userManager.hasBeenCustomized()):
|
if settings().getBoolean(["server", "firstRun"]) and (octoprint.server.userManager is None or not octoprint.server.userManager.hasBeenCustomized()):
|
||||||
return make_response("OctoPrint isn't setup yet", 403)
|
return make_response("OctoPrint isn't setup yet", 403)
|
||||||
|
|
||||||
# if API is globally enabled, enabled for this request and an api key is provided, try to use that
|
# if API is globally enabled, enabled for this request and an api key is provided that is not the current UI API key, try to use that
|
||||||
apikey = _getApiKey(request)
|
apikey = getApiKey(request)
|
||||||
if settings().get(["api", "enabled"]) and apiEnabled and apikey is not None:
|
if settings().get(["api", "enabled"]) and apiEnabled and apikey is not None and apikey != octoprint.server.UI_API_KEY:
|
||||||
if apikey == settings().get(["api", "key"]):
|
if apikey == settings().get(["api", "key"]):
|
||||||
# master key was used
|
# master key was used
|
||||||
user = ApiUser()
|
user = ApiUser()
|
||||||
|
|
@ -61,7 +61,7 @@ def restricted_access(func, apiEnabled=True):
|
||||||
user = octoprint.server.userManager.findUser(apikey=apikey)
|
user = octoprint.server.userManager.findUser(apikey=apikey)
|
||||||
|
|
||||||
if user is None:
|
if user is None:
|
||||||
make_response("Invalid API key", 401)
|
return make_response("Invalid API key", 401)
|
||||||
if login_user(user, remember=False):
|
if login_user(user, remember=False):
|
||||||
identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id()))
|
identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id()))
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
|
@ -76,7 +76,7 @@ def api_access(func):
|
||||||
def decorated_view(*args, **kwargs):
|
def decorated_view(*args, **kwargs):
|
||||||
if not settings().get(["api", "enabled"]):
|
if not settings().get(["api", "enabled"]):
|
||||||
make_response("API disabled", 401)
|
make_response("API disabled", 401)
|
||||||
apikey = _getApiKey(request)
|
apikey = getApiKey(request)
|
||||||
if apikey is None:
|
if apikey is None:
|
||||||
make_response("No API key provided", 401)
|
make_response("No API key provided", 401)
|
||||||
if apikey != settings().get(["api", "key"]):
|
if apikey != settings().get(["api", "key"]):
|
||||||
|
|
@ -85,7 +85,7 @@ def api_access(func):
|
||||||
return decorated_view
|
return decorated_view
|
||||||
|
|
||||||
|
|
||||||
def _getUserForApiKey(apikey):
|
def getUserForApiKey(apikey):
|
||||||
if settings().get(["api", "enabled"]) and apikey is not None:
|
if settings().get(["api", "enabled"]) and apikey is not None:
|
||||||
if apikey == settings().get(["api", "key"]):
|
if apikey == settings().get(["api", "key"]):
|
||||||
# master key was used
|
# master key was used
|
||||||
|
|
@ -97,7 +97,7 @@ def _getUserForApiKey(apikey):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _getApiKey(request):
|
def getApiKey(request):
|
||||||
# Check Flask GET/POST arguments
|
# Check Flask GET/POST arguments
|
||||||
if hasattr(request, "values") and "apikey" in request.values:
|
if hasattr(request, "values") and "apikey" in request.values:
|
||||||
return request.values["apikey"]
|
return request.values["apikey"]
|
||||||
|
|
@ -148,6 +148,10 @@ class PrinterStateConnection(SockJSConnection):
|
||||||
def on_open(self, info):
|
def on_open(self, info):
|
||||||
remoteAddress = self._getRemoteAddress(info)
|
remoteAddress = self._getRemoteAddress(info)
|
||||||
self._logger.info("New connection from client: %s" % remoteAddress)
|
self._logger.info("New connection from client: %s" % remoteAddress)
|
||||||
|
|
||||||
|
# connected => update the API key, might be necessary if the client was left open while the server restarted
|
||||||
|
self._emit("connected", {"apikey": octoprint.server.UI_API_KEY})
|
||||||
|
|
||||||
self._printer.registerCallback(self)
|
self._printer.registerCallback(self)
|
||||||
self._gcodeManager.registerCallback(self)
|
self._gcodeManager.registerCallback(self)
|
||||||
octoprint.timelapse.registerCallback(self)
|
octoprint.timelapse.registerCallback(self)
|
||||||
|
|
@ -316,9 +320,9 @@ def admin_validator(request):
|
||||||
:param request: The Flask request object
|
:param request: The Flask request object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
apikey = _getApiKey(request)
|
apikey = getApiKey(request)
|
||||||
if settings().get(["api", "enabled"]) and apikey is not None:
|
if settings().get(["api", "enabled"]) and apikey is not None:
|
||||||
user = _getUserForApiKey(apikey)
|
user = getUserForApiKey(apikey)
|
||||||
else:
|
else:
|
||||||
user = current_user
|
user = current_user
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,31 +27,17 @@ function DataUpdater(loginStateViewModel, connectionViewModel, printerStateViewM
|
||||||
self._socket.onopen = self._onconnect;
|
self._socket.onopen = self._onconnect;
|
||||||
self._socket.onclose = self._onclose;
|
self._socket.onclose = self._onclose;
|
||||||
self._socket.onmessage = self._onmessage;
|
self._socket.onmessage = self._onmessage;
|
||||||
}
|
};
|
||||||
|
|
||||||
self.reconnect = function() {
|
self.reconnect = function() {
|
||||||
delete self._socket;
|
delete self._socket;
|
||||||
self.connect();
|
self.connect();
|
||||||
}
|
};
|
||||||
|
|
||||||
self._onconnect = function() {
|
self._onconnect = function() {
|
||||||
self._autoReconnecting = false;
|
self._autoReconnecting = false;
|
||||||
self._autoReconnectTrial = 0;
|
self._autoReconnectTrial = 0;
|
||||||
|
};
|
||||||
if ($("#offline_overlay").is(":visible")) {
|
|
||||||
$("#offline_overlay").hide();
|
|
||||||
self.logViewModel.requestData();
|
|
||||||
self.timelapseViewModel.requestData();
|
|
||||||
$("#webcam_image").attr("src", CONFIG_WEBCAM_STREAM + "?" + new Date().getTime());
|
|
||||||
self.loginStateViewModel.requestData();
|
|
||||||
self.gcodeFilesViewModel.requestData();
|
|
||||||
self.gcodeViewModel.reset();
|
|
||||||
|
|
||||||
if ($('#tabs li[class="active"] a').attr("href") == "#control") {
|
|
||||||
$("#webcam_image").attr("src", CONFIG_WEBCAM_STREAM + "?" + new Date().getTime());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self._onclose = function() {
|
self._onclose = function() {
|
||||||
$("#offline_overlay_message").html(
|
$("#offline_overlay_message").html(
|
||||||
|
|
@ -70,20 +56,43 @@ function DataUpdater(loginStateViewModel, connectionViewModel, printerStateViewM
|
||||||
} else {
|
} else {
|
||||||
self._onreconnectfailed();
|
self._onreconnectfailed();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
self._onreconnectfailed = function() {
|
self._onreconnectfailed = function() {
|
||||||
$("#offline_overlay_message").html(
|
$("#offline_overlay_message").html(
|
||||||
"The server appears to be offline, at least I'm not getting any response from it. I <strong>could not reconnect automatically</strong>, " +
|
"The server appears to be offline, at least I'm not getting any response from it. I <strong>could not reconnect automatically</strong>, " +
|
||||||
"but you may try a manual reconnect using the button below."
|
"but you may try a manual reconnect using the button below."
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
self._onmessage = function(e) {
|
self._onmessage = function(e) {
|
||||||
for (var prop in e.data) {
|
for (var prop in e.data) {
|
||||||
var data = e.data[prop];
|
var data = e.data[prop];
|
||||||
|
|
||||||
switch (prop) {
|
switch (prop) {
|
||||||
|
case "connected": {
|
||||||
|
// update the current UI API key and send it with any request
|
||||||
|
UI_API_KEY = data["apikey"];
|
||||||
|
$.ajaxSetup({
|
||||||
|
headers: {"X-Api-Key": UI_API_KEY}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($("#offline_overlay").is(":visible")) {
|
||||||
|
$("#offline_overlay").hide();
|
||||||
|
self.logViewModel.requestData();
|
||||||
|
self.timelapseViewModel.requestData();
|
||||||
|
$("#webcam_image").attr("src", CONFIG_WEBCAM_STREAM + "?" + new Date().getTime());
|
||||||
|
self.loginStateViewModel.requestData();
|
||||||
|
self.gcodeFilesViewModel.requestData();
|
||||||
|
self.gcodeViewModel.reset();
|
||||||
|
|
||||||
|
if ($('#tabs li[class="active"] a').attr("href") == "#control") {
|
||||||
|
$("#webcam_image").attr("src", CONFIG_WEBCAM_STREAM + "?" + new Date().getTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "history": {
|
case "history": {
|
||||||
self.connectionViewModel.fromHistoryData(data);
|
self.connectionViewModel.fromHistoryData(data);
|
||||||
self.printerStateViewModel.fromHistoryData(data);
|
self.printerStateViewModel.fromHistoryData(data);
|
||||||
|
|
@ -160,7 +169,7 @@ function DataUpdater(loginStateViewModel, connectionViewModel, printerStateViewM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
self.connect();
|
self.connect();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ $(function() {
|
||||||
gcodeFilesViewModel,
|
gcodeFilesViewModel,
|
||||||
timelapseViewModel,
|
timelapseViewModel,
|
||||||
gcodeViewModel,
|
gcodeViewModel,
|
||||||
logViewModel
|
logViewModel
|
||||||
);
|
);
|
||||||
|
|
||||||
// work around a stupid iOS6 bug where ajax requests get cached and only work once, as described at
|
// work around a stupid iOS6 bug where ajax requests get cached and only work once, as described at
|
||||||
|
|
@ -35,6 +35,11 @@ $(function() {
|
||||||
headers: { "cache-control": "no-cache" }
|
headers: { "cache-control": "no-cache" }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// send the current UI API key with any request
|
||||||
|
$.ajaxSetup({
|
||||||
|
headers: {"X-Api-Key": UI_API_KEY}
|
||||||
|
});
|
||||||
|
|
||||||
//~~ Show settings - to ensure centered
|
//~~ Show settings - to ensure centered
|
||||||
$('#navbar_show_settings').click(function() {
|
$('#navbar_show_settings').click(function() {
|
||||||
$('#settings_dialog').modal()
|
$('#settings_dialog').modal()
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@
|
||||||
|
|
||||||
var SOCKJS_URI = window.location.protocol.slice(0, -1) + "://" + (window.document ? window.document.domain : window.location.hostname) + ":" + window.location.port + "/sockjs";
|
var SOCKJS_URI = window.location.protocol.slice(0, -1) + "://" + (window.document ? window.document.domain : window.location.hostname) + ":" + window.location.port + "/sockjs";
|
||||||
var SOCKJS_DEBUG = {% if debug -%} true; {% else %} false; {%- endif %}
|
var SOCKJS_DEBUG = {% if debug -%} true; {% else %} false; {%- endif %}
|
||||||
|
|
||||||
|
var UI_API_KEY = "{{ uiApiKey }}";
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue