diff --git a/octoprint_CalibrationTools/EStepsApi.py b/octoprint_CalibrationTools/EStepsApi.py
index 31b1e3d..7b5f4be 100644
--- a/octoprint_CalibrationTools/EStepsApi.py
+++ b/octoprint_CalibrationTools/EStepsApi.py
@@ -22,7 +22,6 @@ class API(octoprint.plugin.SimpleApiPlugin):
}
def apiGateWay(self, command, data):
- self._logger.debug("api command [%s] received payload [%s]", command, data)
if command == CMD_ESTEPS_LOAD_STEPS:
self._logger.debug("Load steps from EEPROM")
if not self._printer.is_ready():
@@ -38,11 +37,11 @@ class API(octoprint.plugin.SimpleApiPlugin):
# Issue M92 command
self._printer.commands("M92")
- m92Event.wait()
+ m92Event.wait(5)
+
return flask.jsonify({
"data": self.data["steps"]
})
-
if command == CMD_ESTEPS_START_EXTRUSION:
self._logger.debug("Heating the extruder [%s]", data)
if not self._printer.is_ready():
@@ -53,10 +52,8 @@ class API(octoprint.plugin.SimpleApiPlugin):
# Register event to be trigger when temp is achieved
self.registerEventTemp("T0", int(data["extrudeTemp"]), self.startExtrusion, data["extrudeLength"], data["extrudeSpeed"])
-
# Heating the tool
self._printer.commands("M104 S%(extrudeTemp)s" % data)
- return
if command == CMD_ESTEPS_SAVE:
eStepsSettings = self._settings.get(['eSteps'])
diff --git a/octoprint_CalibrationTools/PIDAutoTune.py b/octoprint_CalibrationTools/PIDAutoTune.py
index f7a895d..2de9b14 100644
--- a/octoprint_CalibrationTools/PIDAutoTune.py
+++ b/octoprint_CalibrationTools/PIDAutoTune.py
@@ -8,17 +8,51 @@ import flask
import octoprint.plugin
CMD_PID_SAVE = "pid_save"
+CMD_PID_START = "pid_start"
+regexPID = "Kp:\s*(?P
\d{1,3}.\d{1,3})\s*Ki:\s*(?P\d{1,3}.\d{1,3})\s*Kd:\s*(?P\d{1,3}.\d{1,3})"
+regexGetPid = "\s*Kp:\s*(?P\d{1,3}.\d{1,3})\s*Ki:\s*(?P\d{1,3}.\d{1,3})\s*Kd:\s*(?P\d{1,3}.\d{1,3})"
+PIDStarted = "PID Autotune start"
+PIDStoped = "PID Autotune finished!"
+PIDStopedP = "#define DEFAULT_Kp\s*(?P\d{1,3}.\d{1,3})"
+PIDStopedI = "#define DEFAULT_Ki\s*(?P\d{1,3}.\d{1,3})"
+PIDStopedD = "#define DEFAULT_Kd\s*(?P\d{1,3}.\d{1,3})"
+regexFinished = "PID Autotune finished!.*\n#define DEFAULT_Kp\s*(?P\d{1,3}.\d{1,3}).*\n#define DEFAULT_Ki\s*(?P\d{1,3}.\d{1,3})\n#define DEFAULT_Kd\s*(?P\d{1,3}.\d{1,3})"
class API(octoprint.plugin.SimpleApiPlugin):
@staticmethod
def apiCommands():
return {
- CMD_PID_SAVE : ["fanSpeed", "noCycles" "hotEndIndex", "targetTemp"]
+ CMD_PID_SAVE : [],
+ CMD_PID_START: ["fanSpeed", "noCycles", "hotEndIndex", "targetTemp"]
}
def apiGateWay(self, command, data):
self._logger.debug("DIPGateway")
+ if command == CMD_PID_START:
+ self.pidCycles = []
+
+ for i in range(0,data['noCycles']):
+ self.registerRegexMsg(regexGetPid, self.m106CodeResponse)
+
+ self._printer.commands(["M106 S%(fanSpeed)s" % data, "M303 C%(noCycles)s E%(hotEndIndex)s S%(targetTemp)s U1" % data])
+ self._logger.debug("cycles %s", self.pidCycles)
+
if command == CMD_PID_SAVE:
self._logger.debug("DIPSave-")
+ return flask.jsonify({
+ "data": self.pidCycles
+ })
+ @staticmethod
+ def m106CodeResponse(self, line):
+ self._logger.debug("m106CodeResponse: %s", line)
+ # isM106Response = re.compile(regexFinished).match(line)
+ # if isM106Response:
+ # p = isM106Response.group("P")
+ # i = isM106Response.group("I")
+ # d = isM106Response.group("D")
+ # self._logger.debug("P:%s, I:%s, d:%d", p, i, d)
+ # self._logger.debug("line: %s", line)
+ self.pidCycles.append(line)
+ self._logger.debug("cycles %s", self.pidCycles)
diff --git a/octoprint_CalibrationTools/api.py b/octoprint_CalibrationTools/api.py
index 86d59b4..ccdfe3c 100644
--- a/octoprint_CalibrationTools/api.py
+++ b/octoprint_CalibrationTools/api.py
@@ -1,6 +1,9 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals
+import traceback
+from ast import Try
+
import flask
from octoprint_CalibrationTools import EStepsApi, PIDAutoTune
@@ -33,7 +36,13 @@ class API(EStepsApi.API, PIDAutoTune.API):
)
def on_api_command(self, command, data):
- self._logger.debug("API command [%s] received payload [%s]", command, data)
- for key, api in self.commandsRegistration.items():
- if command in api["commands"]:
- return api["cls"].apiGateWay(self, command, data)
+ try:
+ self._logger.debug("API command [%s] received payload [%s]", command, data)
+ for key, api in self.commandsRegistration.items():
+ if command in api["commands"]:
+ return api["cls"].apiGateWay(self, command, data)
+ except Exception as e:
+ self._logger.error(traceback.format_exc())
+ return flask.abort(500, {
+ "msg": "An error curred"
+ })
diff --git a/octoprint_CalibrationTools/hooks.py b/octoprint_CalibrationTools/hooks.py
index 1738668..1272b99 100644
--- a/octoprint_CalibrationTools/hooks.py
+++ b/octoprint_CalibrationTools/hooks.py
@@ -1,12 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals
-from ast import arg
+import collections
import re
import threading
import traceback
import types
-import collections
class Hooks():
@@ -15,20 +14,26 @@ class Hooks():
gCodeWaiters = []
def gCodeReceived(self, comm, line, *args, **kwargs):
- if len(self.gCodeWaiters) <= 0 and not line.startswith('echo:'):
- return line
-
- reg = re.compile("echo:\s*(?PM\d{1,4})")
- mCommand = reg.match(line)
- if mCommand:
- gCode = mCommand.group("gCode")
+ try:
+ if len(self.gCodeWaiters) <= 0:
+ return line
for waiter in self.gCodeWaiters:
- if gCode.upper() == waiter["cmd"]:
- arg = (line, *waiter["args"])
+ reg = waiter["regex"]
+ waiter["callCount"] = waiter["callCount"] + 1
+ if reg.match(line):
+ args = (line, *waiter["args"])
if isinstance(waiter["func"], types.FunctionType):
- arg = (self, *arg)
- threading.Thread(target=waiter["func"], args=arg).start()
- self.gCodeWaiters.remove(waiter)
+ args = (self, *args)
+ threading.Thread(target=waiter["func"], args=args).start()
+ waiter["dead"] = True
+ break
+ if waiter["callCount"] >= 3:
+ self._logger.warning("Hanging thread: Removing waiter regex: %(regex)s" % waiter)
+ waiter["dead"] = True
+ self.gCodeWaiters = [w for w in self.gCodeWaiters if "dead" not in w or not w["dead"]]
+ except Exception as e:
+ self._logger.error(traceback.format_exc())
+ self.gCodeWaiters = []
return line
def firmwareInfo(self, comm_instance, firmware_name, firmware_data, *args, **kwargs):
@@ -79,11 +84,20 @@ class Hooks():
# Registering a gCodeWaiter
def registerGCodeWaiter(self, command, func, *arguments):
- if command is None or not re.compile("(?PM\d{1,4})").match(command.upper()) or func is None or not isinstance(func, collections.Callable):
- self._logger.warn("registerGCodeAnswer: Attempt to register gCodeAnswer without a function or gCode command")
+ reg = re.compile(".*\s*(?P[M,G]\d{1,4})")
+ if command is None or not reg.match(command.upper()):
+ self._logger.warn("registerGCodeAnswer: Attempt to register gCodeAnswer without a function or valid gCode command")
return
+ self.registerRegexMsg(".*\s*(?P[M,G]\d{1,4})", func, *arguments)
+
+ def registerRegexMsg(self, regex, func, *arguments):
+ if regex is None or func is None or not isinstance(func, collections.Callable):
+ self._logger.warn("registerRegexMsg: Attempt to register gCodeAnswer without a function or regex")
+ return
+
self.gCodeWaiters.append({
- "cmd": command.upper(),
+ "regex": re.compile(regex),
"func": func,
- "args": arguments
+ "args": arguments,
+ "callCount": 0
})
diff --git a/octoprint_CalibrationTools/static/js/PIDTuneViewModel.js b/octoprint_CalibrationTools/static/js/PIDTuneViewModel.js
index ed45bfe..e835267 100644
--- a/octoprint_CalibrationTools/static/js/PIDTuneViewModel.js
+++ b/octoprint_CalibrationTools/static/js/PIDTuneViewModel.js
@@ -3,10 +3,11 @@ $(function () {
var self = this;
self.loginStateViewModel = parameters[0];
self.settingsViewModel = parameters[1];
+ self.controlViewModel = parameters[2];
self.bedCurrentTemp = ko.observable(0);
self.bedCurrentTarget = ko.observable(0);
- self.is_admin = ko.observable(false);
+ self.isAdmin = ko.observable(false);
self.pid = {
fanSpeed: ko.observable(255),
noCycles: ko.observable(5),
@@ -24,7 +25,30 @@ $(function () {
self.pid.noCycles(self.settingsViewModel.settings.plugins.CalibrationTools.pid.noCycles());
self.pid.hotEndIndex(self.settingsViewModel.settings.plugins.CalibrationTools.pid.hotEndIndex());
self.pid.targetTemp(self.settingsViewModel.settings.plugins.CalibrationTools.pid.targetTemp());
- self.is_admin(self.loginStateViewModel.isAdmin());
+ self.isAdmin(self.loginStateViewModel.isAdmin());
+ }
+
+ self.startPidHotEnd = function () {
+ OctoPrint.simpleApiCommand("CalibrationTools", "pid_start", {
+ "fanSpeed": self.pid.fanSpeed(),
+ "noCycles": self.pid.noCycles(),
+ "hotEndIndex": self.pid.hotEndIndex(),
+ "targetTemp": self.pid.targetTemp()
+ }).done(function (response) {
+ new PNotify({
+ title: "PID HotEnd tuning has started",
+ text: "In progress",
+ type: "info"
+ });
+ console.log(response);
+ }).fail(function (response) {
+ new PNotify({
+ title: "Error on starting extrusion ",
+ text: response.responseJSON.error,
+ type: "error",
+ hide: false
+ });
+ });
}
}
OCTOPRINT_VIEWMODELS.push({
diff --git a/octoprint_CalibrationTools/templates/tabs/tab-esteps.jinja2 b/octoprint_CalibrationTools/templates/tabs/tab-esteps.jinja2
index 1fa6ed5..34d58b0 100644
--- a/octoprint_CalibrationTools/templates/tabs/tab-esteps.jinja2
+++ b/octoprint_CalibrationTools/templates/tabs/tab-esteps.jinja2
@@ -42,7 +42,7 @@
-
- {{ snipped.linkToMarlin("M92", "Marlin website") }}
+ {{ snipped.linkToMarlin("M092", "Marlin website") }}
{{ snipped.m500Icon() }}
@@ -92,7 +92,7 @@
-