Open Ximidar opened 6 years ago
Interesting note... neither terminal.js
nor any of the python scripts appear to be a call to the serial functionality which include a callback function.
English version of that: it's okay to send sendGcode() but you then have to parse the log it produces; there's no immediate feedback from that call.
RoboLCD actually works similarly. The sending command just sends, and the receiving code has to parse through the output to find the information we want.
It would be an okay process to call M501, Start the parser to capture the Z-Offset, Shut down the parser after it returns the right information, then display the warning or start the print. This will lag the interface a little bit though since it will have to wait for information to be returned before it reacts, but it would be worse to have a bed crash.
for finding the Z-Offset in roboLCD we go through this code:
This is a condensed version of code, we also use this to find other parts of the EEPROM, but I'll show you just the code for finding the Z-Offset
def on_printer_add_message(self, data):
find_data = ['M206']
acceptable_finds = {
'M206': self.find_M206
}
for query in find_data:
found = data.find(query)
if found != -1:
#execute dictionary function
acceptable_finds[query](data)
break
find m206 looks like this
#home offset
def find_M206(self, data):
self.home_offset = self.merge_dicts(self.home_offset, self.parse_M_commands(data, "M206"))
This is the parse M command function
def parse_M_commands(self, data, command):
return_dict = {}
#cut M command
data = data.replace(command, "")
#remove all spaces
data = data.replace(" ", "")
acceptable_data = ['X', 'Y', 'Z', 'E', 'P', 'I', 'D', 'R', 'T' , 'S', 'B', 'K']
while [x for x in acceptable_data if (x in data)] != []: #this is the equivalent of if 'X' in data or 'Y' in data or 'Z' in data ect
if data.find("X") != -1:
var_data = self.scrape_data(data, "X")
end_var_data = var_data.replace('X','')
return_dict['X'] = float(end_var_data)
data = data.replace(var_data, '')
elif data.find("Y") != -1:
var_data = self.scrape_data(data, "Y")
end_var_data = var_data.replace('Y','')
return_dict['Y'] = float(end_var_data)
data = data.replace(var_data, '')
elif data.find("Z") != -1:
var_data = self.scrape_data(data, "Z")
end_var_data = var_data.replace('Z','')
return_dict['Z'] = float(end_var_data)
data = data.replace(var_data, '')
return return_dict
Here are the helper functions for that
def scrape_data(self, data, scraper):
start_pos = data.find(scraper)
if start_pos == -1:
print("Cannot find data for scraper: " + str(scraper))
return False
end_pos = self.find_next_space(data[start_pos:len(data)], scraper)
scraped = data[start_pos:start_pos + end_pos]
return scraped
def find_next_space(self, data, scraper):
counter = 0
acceptable_input = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.', scraper]
for i in data:
counter += 1
if i not in acceptable_input:
break
if counter == len(data):
return len(data)
else:
return counter -1
def merge_dicts(self, *dict_args):
result = {}
for dictionary in dict_args:
result.update(dictionary)
return result
All this code does is return a dictionary with M206s X,Y, and Z variables. The PConsole class will then hold the master dictionary with all EEPROM values. You might not need to get this in depth with what you return, you might just want to return the Z value and not an entire dictionary.
Hopefully this helps you in some way.
New knowledge: Having gone to school on the Flask/factory mechanism, this looks like it's a way of talking to the API side of OctoPrint. This is why—in JavaScript—you have access to an OctoPrint.connection object since the code is there in connection.py.
Unfortunately, there isn't a COMM class in the API so punching through into an OctoPrint.comm object isn't possible.
Feature Development
What is this Feature?
Create a message on the web dash that will pop up when the M206 offset is not in the range between 0 and -20. 0 should pop the warning and -20 should pop the warning
Web Dash
Find the source code for the files system on the web dash and write a piece of code that will fire before the print command is issued that will check if the offset is ready for printing.
Tasks
Here is the load file function that will decide if a print will go off or not. It is located in "roboOctoprint/src/octoprint/static/js/app/viewmodels/files.js" line 401
Adding another check to the
var print
line would be the easiest solution here.This needs to be a simple Modal screen that has a title, a body of text, and two buttons (Cancel, Continue). Alternatively you should search for other prebuilt HTML popups that foosel may have already built. (roboOctoprint/src/octoprint/static/js/app/bindings/popover.js) See if you can use this.
M503 will show you the current EEPROM, then you can parse out what you need however you wish. http://docs.octoprint.org/en/1.3.3/jsclientlib/control.html#OctoPrintClient.control.sendGcode Here is how to send a command to the printer.
terminal.js somehow gets the output from Marlin, Study that for how to get the output.