Search code examples
pythonfilesearchg-code

Simple python program to read . gcode file


I am completely new to Python and I wanted to create a simple script that will find me a specific value in a file and than perform some calculations with it.

So I have a .gcode file (it is a file with many thousands of lines for a 3D printer but it can be opened by any simple text editor). I wanted to create a simple Python program where when you start it, simple GUI opens, with button asking to select a .gcode file. Then after file is opened I would like the program to find specific line

; filament used = 22900.5mm (55.1cm3)

(above is the exact format of the line from the file) and extract the value 55.1 from it. Later I would like to do some simple calculations with this value. So far I have made a simple GUI and a button with open file option but I am stuck on how to get this value as a number (so it can be used in the equations later) from this file.

I hope I have explained my problem clear enough so somebody could help me :) Thank you in advance for the help!

My code so far:

from tkinter import *
import re




# Here, we are creating our class, Window, and inheriting from the Frame
# class. Frame is a class from the tkinter module. (see Lib/tkinter/__init__)
class Window(Frame):

    # Define settings upon initialization. Here you can specify
def __init__(self, master=None):

        # parameters that you want to send through the Frame class. 
Frame.__init__(self, master)   

        #reference to the master widget, which is the tk window                 
self.master = master

        #with that, we want to then run init_window, which doesn't yet exist
self.init_window()

    #Creation of init_window
def init_window(self):

        # changing the title of our master widget      
self.master.title("Used Filament Data")

        # allowing the widget to take the full space of the root window
self.pack(fill=BOTH, expand=1)

        # creating a menu instance
menu = Menu(self.master)
self.master.config(menu=menu)

        # create the file object)
file = Menu(menu)

        # adds a command to the menu option, calling it exit, and the
        # command it runs on event is client_exit
file.add_command(label="Exit", command=self.client_exit)

        #added "file" to our menu
menu.add_cascade(label="File", menu=file)

        #Creating the button
quitButton = Button(self, text="Load GCODE",command=self.read_gcode)
quitButton.place(x=0, y=0)

def get_filament_value(self, filename):
with open(filename, 'r') as f_gcode:
data = f_gcode.read()
re_value = re.search('filament used = .*? \(([0-9.]+)', data)

if re_value:
value = float(re_value.group(1))
else:
print 'filament not found in {}'.format(root.fileName)
value = 0.0
return value

print get_filament_value('test.gcode') 

def read_gcode(self):
root.fileName = filedialog.askopenfilename( filetypes = ( ("GCODE files", "*.gcode"),("All files", "*.*") ) )
self.value = self.get_filament_value(root.fileName)

def client_exit(self):
exit()





# root window created. Here, that would be the only window, but
# you can later have windows within windows.
root = Tk()

root.geometry("400x300")

#creation of an instance
app = Window(root)

#mainloop 
root.mainloop()  

Solution

  • You could use a regular expression to find the matching line in the gcode file. The following function loads the whole gcode file and does the search. If it is found, the value is returned as a float.

    import re
    
    def get_filament_value(filename):
        with open(filename, 'r') as f_gcode:
            data = f_gcode.read()
            re_value = re.search('filament used = .*? \(([0-9.]+)', data)
    
            if re_value:
                value = float(re_value.group(1))
            else:
                print('filament not found in {}'.format(filename))
                value = 0.0
            return value
    
    print(get_filament_value('test.gcode'))
    

    Which for your file should display:

    55.1
    

    So your original code would look something like this:

    from tkinter import *
    import re
    
    # Here, we are creating our class, Window, and inheriting from the Frame
    # class. Frame is a class from the tkinter module. (see Lib/tkinter/__init__)
    class Window(Frame):
    
        # Define settings upon initialization. Here you can specify
        def __init__(self, master=None):
    
            # parameters that you want to send through the Frame class. 
            Frame.__init__(self, master)   
    
            #reference to the master widget, which is the tk window                 
            self.master = master
    
            #with that, we want to then run init_window, which doesn't yet exist
            self.init_window()
    
        #Creation of init_window
        def init_window(self):
    
            # changing the title of our master widget      
            self.master.title("Used Filament Data")
    
            # allowing the widget to take the full space of the root window
            self.pack(fill=BOTH, expand=1)
    
            # creating a menu instance
            menu = Menu(self.master)
            self.master.config(menu=menu)
    
            # create the file object)
            file = Menu(menu)
    
            # adds a command to the menu option, calling it exit, and the
            # command it runs on event is client_exit
            file.add_command(label="Exit", command=self.client_exit)
    
            #added "file" to our menu
            menu.add_cascade(label="File", menu=file)
    
            #Creating the button
            quitButton = Button(self, text="Load GCODE",command=self.read_gcode)
            quitButton.place(x=0, y=0)
    
        # Load the gcode file in and extract the filament value
        def get_filament_value(self, fileName):
            with open(fileName, 'r') as f_gcode:
                data = f_gcode.read()
                re_value = re.search('filament used = .*? \(([0-9.]+)', data)
    
                if re_value:
                    value = float(re_value.group(1))
                    print('filament value is {}'.format(value))
                else:
                    value = 0.0
                    print('filament not found in {}'.format(fileName))
            return value
    
        def read_gcode(self):
            root.fileName = filedialog.askopenfilename(filetypes = (("GCODE files", "*.gcode"), ("All files", "*.*")))
            self.value = self.get_filament_value(root.fileName)
    
        def client_exit(self):
            exit()
    
    # root window created. Here, that would be the only window, but
    # you can later have windows within windows.
    root = Tk()
    
    root.geometry("400x300")
    
    #creation of an instance
    app = Window(root)
    
    #mainloop 
    root.mainloop() 
    

    This would save the result as a float into a class variable called value.