From fb5aaffdc17e834e8aade42eca9727a30091e8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 27 Apr 2015 18:13:39 +0200 Subject: [PATCH] Added a "fake ack" button to terminal tab, as counter measure for lost "ok"s In case an ok gets lost on the line, this allows to have the communication between OctoPrint and the printer take up again. --- docs/api/connection.rst | 25 ++++++++++++++++++- src/octoprint/printer/__init__.py | 8 ++++++ src/octoprint/printer/standard.py | 6 +++++ src/octoprint/server/api/connection.py | 5 +++- .../static/js/app/viewmodels/terminal.js | 10 ++++++++ src/octoprint/templates/tabs/terminal.jinja2 | 9 +++++++ src/octoprint/util/comm.py | 3 +++ 7 files changed, 64 insertions(+), 2 deletions(-) diff --git a/docs/api/connection.rst b/docs/api/connection.rst index 49904369..fc44ff8b 100644 --- a/docs/api/connection.rst +++ b/docs/api/connection.rst @@ -75,6 +75,12 @@ Issue a connection command disconnect Instructs OctoPrint to disconnect from the printer. + fake_ack + Fakes an acknowledgement message for OctoPrint in case one got lost on the serial line and the communication + with the printer since stalled. This should only be used in "emergencies" (e.g. to save prints), the reason + for the lost acknowledgement should always be properly investigated and removed instead of depending on this + "symptom solver". + **Example Connect Request** .. sourcecode:: http @@ -114,7 +120,24 @@ Issue a connection command HTTP/1.1 204 No Content - :json string command: The command to issue, either ``connect`` or ``disconnect`` + **Example FakeAck Request** + + .. sourcecode:: http + + POST /api/connection HTTP/1.1 + Host: example.com + Content-Type: application/json + X-Api-Key: abcdef... + + { + "command": "fake_ack" + } + + .. sourcecode:: http + + HTTP/1.1 204 No Content + + :json string command: The command to issue, either ``connect``, ``disconnect`` or ``fake_ack``. :json string port: ``connect`` command: The port to connect to. If left out either the existing ``portPreference`` will be used, or if that is not available OctoPrint will attempt auto detection. Must be part of the available ports. diff --git a/src/octoprint/printer/__init__.py b/src/octoprint/printer/__init__.py index 3f97deda..e0989a93 100644 --- a/src/octoprint/printer/__init__.py +++ b/src/octoprint/printer/__init__.py @@ -97,6 +97,14 @@ class PrinterInterface(object): """ raise NotImplementedError() + def fake_ack(self): + """ + Fakes an acknowledgement for the communication layer. If the communication between OctoPrint and the printer + gets stuck due to lost "ok" responses from the server due to communication issues, this can be used to get + things going again. + """ + raise NotImplementedError() + def commands(self, commands): """ Sends the provided ``commands`` to the printer. diff --git a/src/octoprint/printer/standard.py b/src/octoprint/printer/standard.py index 03e169cd..48d89cc3 100644 --- a/src/octoprint/printer/standard.py +++ b/src/octoprint/printer/standard.py @@ -212,6 +212,12 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): return self._comm.getTransport() getTransport = util.deprecated("getTransport has been renamed to get_transport", since="1.2.0-dev-590", includedoc="Replaced by :func:`get_transport`") + def fake_ack(self): + if self._comm is None: + return + + self._comm.fakeOk() + def commands(self, commands): """ Sends one or more gcode commands to the printer. diff --git a/src/octoprint/server/api/connection.py b/src/octoprint/server/api/connection.py index 7f858c7d..75f9b1d8 100644 --- a/src/octoprint/server/api/connection.py +++ b/src/octoprint/server/api/connection.py @@ -33,7 +33,8 @@ def connectionState(): def connectionCommand(): valid_commands = { "connect": [], - "disconnect": [] + "disconnect": [], + "fake_ack": [] } command, data, response = get_json_command_from_request(request, valid_commands) @@ -68,6 +69,8 @@ def connectionCommand(): printer.connect(port=port, baudrate=baudrate, profile=printerProfile) elif command == "disconnect": printer.disconnect() + elif command == "fake_ack": + printer.fake_ack() return NO_CONTENT diff --git a/src/octoprint/static/js/app/viewmodels/terminal.js b/src/octoprint/static/js/app/viewmodels/terminal.js index 235dd0c8..6ce008f6 100644 --- a/src/octoprint/static/js/app/viewmodels/terminal.js +++ b/src/octoprint/static/js/app/viewmodels/terminal.js @@ -173,6 +173,16 @@ $(function() { } }; + self.fakeAck = function() { + $.ajax({ + url: API_BASEURL + "connection", + type: "POST", + dataType: "json", + contentType: "application/json; charset=UTF-8", + data: JSON.stringify({"command": "fake_ack"}) + }); + }; + self.handleKeyDown = function(event) { var keyCode = event.keyCode; diff --git a/src/octoprint/templates/tabs/terminal.jinja2 b/src/octoprint/templates/tabs/terminal.jinja2 index 13a1cc3e..18d2a30a 100644 --- a/src/octoprint/templates/tabs/terminal.jinja2 +++ b/src/octoprint/templates/tabs/terminal.jinja2 @@ -20,3 +20,12 @@ {{ _('Hint: Use the arrow up/down keys to recall commands sent previously') }} + +
+
{{ _('Advanced options') }}
+
+ + {{ _("If acknowledgements (\"ok\"s) sent by the firmware get lost due to issues with the serial communication to your printer, OctoPrint's communication with it can become stuck. If that happens, this can help. Please be advised that such occurences hint at general communication issues with your printer which will probably negatively influence your printing results and which you should therefore try to resolve!") }} +
+
+ diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index 13bbd783..3546b1ed 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -412,6 +412,9 @@ class MachineCom(object): def setTemperatureOffset(self, offsets): self._tempOffsets.update(offsets) + def fakeOk(self): + self._clear_to_send.set() + def sendCommand(self, cmd, cmd_type=None, processed=False): cmd = cmd.encode('ascii', 'replace') if not processed: