class ZoffsetWizard(object):
    def __init__(self, state, **kwargs):
        super(ZoffsetWizard, self).__init__()

        self.debug_mode = True

        #set up wizard flow
        self.state = state
        #self.process_state()

        #set up the wizard screen
        self.bb = Wizard_BB()
        self.group = 'Z_Offset_Group'
        #add bb
        roboprinter.robosm.add_widget(self.bb)
        roboprinter.robosm.current = self.bb.name

        self.welcome = None
        self.workflow = None
        self.finish_screen = None

        #initialize wizard variables
        self.z_offset = {}
        self.selected_tool = 'tool0'
        self.dual = False

        #variables for saving old z_offset
        self.old_z_offset = {}
        self.welcome_screen()

    def cleanup(self):
        Logger.info("Deleting: z_offset_wizard")
        roboprinter.robosm.remove_widget(self.bb)
        self.bb.delete_node()

        if self.welcome != None:
            self.welcome.cleanup()
        if self.workflow != None:
            self.workflow.cleanup()
        if self.finish_screen != None:
            self.finish_screen.cleanup()
        del_list = []
        for self_var in self.__dict__:
            del_list.append(self_var)
            self.__dict__[self_var] = ''
        for self_var in del_list:
            #Logger.info("Deleting: " + str(self_var))
            del self.__dict__[self_var]
        #Tell Self to print out any remaining referrers
        # Logger.info("---> Printing referrers of Z-Offset")
        # gc.collect()
        # for referer in gc.get_referrers(self):
        #     Logger.info(referer)
        # Logger.info("---> Done printing referrers of Z-Offset")
        del self

    def welcome_screen(self):
        #Make screen content
        self.welcome = Button_Screen(
            lang.pack['ZOffset_Wizard']['Wizard_Description'],
            self.process_state,
            button_text=lang.pack['ZOffset_Wizard']['Start'])
        self.welcome.change_screen_actions = self.cleanup
        #populate screen
        self.bb.make_screen(self.welcome,
                            roboprinter.lang.pack['ZOffset_Wizard']['Welcome'],
                            option_function='no_option')

    def process_state(self):
        ext_number = 1
        if 'extruder' in self.state:
            ext_number = int(self.state['extruder'])

        #decide what the layout should be
        if ext_number > 1:
            # self.select_extruder() Re enable this when the new head comes out
            self.selected_tool = 'tool0'
            self.start_workflow()
        else:
            self.selected_tool = 'tool0'
            self.start_workflow()

    def select_extruder(self):
        #detirmine machine state and behaviour of the wizard
        es = Extruder_Selector(self.dual_or_single_fork,
                               make_screen=self.bb.make_screen,
                               group=self.group)
        es.show_screen()

    def dual_or_single_fork(self, extruder):
        extruders = ['EXT1', 'EXT2', 'BOTH']

        if extruder in extruders:
            if extruder == 'BOTH':
                self.dual = True
            else:
                self.dual = False
                tool_dict = {'EXT1': 'tool0', 'EXT2': 'tool1'}
                self.selected_tool = tool_dict[extruder]
            self.start_workflow()
        else:
            Logger.info("ERROR Invalid selection")
            raise ValueError(str(extruder) + " Is not a valid selection")

    def start_workflow(self):
        if self.dual:
            #this will go through the workflow for both extruders
            def second_extruder():
                self.workflow = Z_Offset_Workflow('tool1', self.finish_wizard,
                                                  self.update_z_offset,
                                                  self.bb, self.group)

            #callback to second extruder function
            self.workflow = Z_Offset_Workflow('tool0', self.second_extruder,
                                              self.update_z_offset, self.bb,
                                              self.group)
        else:
            #This will go through the workflow for one extruder.
            self.workflow = Z_Offset_Workflow(self.selected_tool,
                                              self.finish_wizard,
                                              self.update_z_offset, self.bb,
                                              self.group)

    #callback to update the Z_Offset for each extruder. This callback does not save anything, it simply records
    #the z offset to be shown in the finish wizard segment.
    def update_z_offset(self, extruder, z_offset):
        self.z_offset[extruder] = z_offset

    def finish_wizard(self, *args, **kwargs):
        title = roboprinter.lang.pack['ZOffset_Wizard']['Z_44']

        #title_text, body_text,image_source, button_function, button_text = roboprinter.lang.pack['Button_Screen']['Default_Button']
        self.finish_screen = Picture_Button_Screen(
            '[size=40][color=#69B3E7]' +
            lang.pack['ZOffset_Wizard']['Finish_Title'] + '[/color][/size]',
            '[size=30]' + lang.pack['ZOffset_Wizard']['Finish_Body1'] +
            ' {} '.format(self.z_offset['tool0']) +
            lang.pack['ZOffset_Wizard']['Finish_Body2'],
            'Icons/Manual_Control/check_icon.png',
            self.end_wizard,
            button_text="[size=30]" + lang.pack['ZOffset_Wizard']['Save'])
        self.finish_screen.change_screen_actions = self.reset_to_zero_on_back
        self.finish_screen.update = self.skip_screen

        self.bb.make_screen(self.finish_screen,
                            title,
                            option_function='no_option')

    def reset_to_zero_on_back(self):
        #set the ZOffset to zero
        Logger.info("Setting the Z-Offset to 0 due to a back screen!")
        roboprinter.printer_instance._printer.commands('M206 Z0.00')
        roboprinter.printer_instance._printer.commands("M851 Z0.00")
        roboprinter.printer_instance._printer.commands("M500")
        roboprinter.printer_instance._printer.commands('M114')

    def skip_screen(self):
        self.bb.back_function_flow()

    def end_wizard(self):
        #home and go back
        roboprinter.printer_instance._printer.commands('G28')
        self.cleanup()
        roboprinter.robosm.go_back_to_main('printer_status_tab')
Exemple #2
0
class EEPROM(object):
    #self._generate_backbutton_screen(name=_name, title=kwargs['title'], back_destination=kwargs['back_destination'], content=layout)
    def __init__(self, *args, **kwargs):
        self.buttons = []
        self.name = kwargs['name']
        self.title = kwargs['title']
        self.back_destination = kwargs['back_destination']

        #set up the wizard screen
        self.bb = Wizard_BB()
        self.group = 'EEPROM_Group'

        #add bb
        roboprinter.robosm.add_widget(self.bb)
        roboprinter.robosm.current = self.bb.name

        model = roboprinter.printer_instance._settings.get(['Model'])
        self.refresh_eeprom()

        if model == "Robo R2":
            #add bed PID for the R2
            self.button_order = [
                roboprinter.lang.pack['EEPROM']['Home_Offset'],
                roboprinter.lang.pack['EEPROM']['Probe_Offset'],
                roboprinter.lang.pack['EEPROM']['Steps_Unit'],
                roboprinter.lang.pack['EEPROM']['Accelerations'],
                roboprinter.lang.pack['EEPROM']['Max_Accelerations'],
                roboprinter.lang.pack['EEPROM']['Filament_Settings'],
                roboprinter.lang.pack['EEPROM']['Feed_Rates'],
                roboprinter.lang.pack['EEPROM']['PID_Settings'],
                roboprinter.lang.pack['EEPROM']['Bed_PID'],
                roboprinter.lang.pack['EEPROM']['Advanced'],
                roboprinter.lang.pack['EEPROM']['Linear_Advanced'],
                roboprinter.lang.pack['EEPROM']['Reset']
            ]
        else:
            self.button_order = [
                roboprinter.lang.pack['EEPROM']['Home_Offset'],
                roboprinter.lang.pack['EEPROM']['Probe_Offset'],
                roboprinter.lang.pack['EEPROM']['Steps_Unit'],
                roboprinter.lang.pack['EEPROM']['Accelerations'],
                roboprinter.lang.pack['EEPROM']['Max_Accelerations'],
                roboprinter.lang.pack['EEPROM']['Filament_Settings'],
                roboprinter.lang.pack['EEPROM']['Feed_Rates'],
                roboprinter.lang.pack['EEPROM']['PID_Settings'],
                roboprinter.lang.pack['EEPROM']['Advanced'],
                roboprinter.lang.pack['EEPROM']['Linear_Advanced'],
                roboprinter.lang.pack['EEPROM']['Reset']
            ]
        self.load_eeprom()

    def load_eeprom(self):
        eeprom_list = []
        for entry in self.button_order:
            if entry in self.eeprom_dictionary and self.eeprom_dictionary[
                    entry]['values'] != {}:
                eeprom_list.append(self.eeprom_dictionary[entry])

        #make node
        self.EEPROM_Node = EEPROM_Node(data=eeprom_list, title=self.title)

        #render screen with list
        self.EEPROM_screen = Scroll_Box_EEPROM_List(self.EEPROM_Node.data,
                                                    self.open_setting)

        self.bb.make_screen(self.EEPROM_screen,
                            title=self.title,
                            back_function=self.previous_list,
                            option_function='no_option')

    def refresh_eeprom(self):
        pconsole.query_eeprom()
        '''
        This dictionary contains a few defining elements for each EEPROM entry that we want to display
        name: This is the name that will be displayed on the screen for this value
        command: This is the specific gcode command that this entry is attached to
        filter: This defines what values will be shown to the user
        order: This defines the order that the values will be shown to the user
        range: This will define the numbers by which the user will be able to edit the entry
        values: This will hold the actual values scraped from the EEPROM
        '''
        self.eeprom_dictionary = {
            roboprinter.lang.pack['EEPROM']['Home_Offset']: {
                'name': roboprinter.lang.pack['EEPROM']['Home_Offset'],
                'command': 'M206',
                'order': ['Z'],
                'range': [10, 0.01, 0.1, 1],
                'values': pconsole.home_offset
            },
            roboprinter.lang.pack['EEPROM']['Probe_Offset']: {
                'name': roboprinter.lang.pack['EEPROM']['Probe_Offset'],
                'command': 'M851',
                'order': ['Z'],
                'range': [10, 0.01, 0.1, 1],
                'values': pconsole.probe_offset
            },
            roboprinter.lang.pack['EEPROM']['Feed_Rates']: {
                'name': roboprinter.lang.pack['EEPROM']['Feed_Rates'],
                'command': 'M203',
                'order': ['X', 'Y', 'Z', 'E', 'T0 E', 'T1 E'],
                'range': [0.01, 0.1, 1, 10],
                'values': pconsole.feed_rate
            },
            roboprinter.lang.pack['EEPROM']['PID_Settings']: {
                'name': roboprinter.lang.pack['EEPROM']['PID_Settings'],
                'command': 'M301',
                'order': ['P', 'I', 'D'],
                'range': [0.01, 0.1, 1, 10],
                'values': pconsole.PID
            },
            roboprinter.lang.pack['EEPROM']['Bed_PID']: {
                'name': roboprinter.lang.pack['EEPROM']['Bed_PID'],
                'command': 'M304',
                'order': ['P', 'I', 'D'],
                'range': [0.01, 0.1, 1, 10],
                'values': pconsole.BPID
            },
            roboprinter.lang.pack['EEPROM']['Steps_Unit']: {
                'name': roboprinter.lang.pack['EEPROM']['Steps_Unit'],
                'command': 'M92',
                'order': ['X', 'Y', 'Z', 'E', 'T0 E', 'T1 E'],
                'range': [0.01, 0.1, 1, 10],
                'values': pconsole.steps_per_unit
            },
            roboprinter.lang.pack['EEPROM']['Accelerations']: {
                'name': roboprinter.lang.pack['EEPROM']['Accelerations'],
                'command': 'M204',
                'order': ['P', 'R', 'T'],
                'range': [0.01, 0.1, 1, 10, 100, 1000],
                'values': pconsole.accelerations
            },
            roboprinter.lang.pack['EEPROM']['Max_Accelerations']: {
                'name': roboprinter.lang.pack['EEPROM']['Max_Accelerations'],
                'command': 'M201',
                'order': ['X', 'Y', 'Z', 'E', 'T0 E', 'T1 E'],
                'range': [0.01, 0.1, 1, 10, 100, 1000],
                'values': pconsole.max_accelerations
            },
            roboprinter.lang.pack['EEPROM']['Advanced']: {
                'name': roboprinter.lang.pack['EEPROM']['Advanced'],
                'command': 'M205',
                'order': ['S', 'T', 'X', 'Y', 'Z', 'E'],
                'range': [0.01, 0.1, 1, 10, 100],
                'values': pconsole.advanced_variables
            },
            roboprinter.lang.pack['EEPROM']['Linear_Advanced']: {
                'name': roboprinter.lang.pack['EEPROM']['Linear_Advanced'],
                'command': 'M900',
                'order': ['K', 'R'],
                'range': [0.01, 0.1, 1, 10, 100],
                'values': pconsole.linear_advanced
            },
            roboprinter.lang.pack['EEPROM']['Reset']: {
                'name': roboprinter.lang.pack['EEPROM']['Reset'],
                'action': self.reset_defaults,
                'values': ''
            },
        }

    #this function will query the eeprom when the user backs out or applys a change to the eeprom
    def refresh_list(self, *args, **kwargs):
        pconsole.query_eeprom()
        self.EEPROM_screen.repopulate_for_new_screen()
        Clock.schedule_once(self.update_title, 0.0)

    #this function updates the title when backing out of the change value screen
    def update_title(self, *args, **kwargs):
        self.bb.update_title(self.EEPROM_Node.title)

    def open_eeprom_value(self, setting_data):
        pconsole.dict_logger(setting_data)
        change_value_screen = Change_Value(setting_data, self.bb.back_function)
        change_value_screen.change_screen_event = self.refresh_list

        self.bb.make_screen(change_value_screen,
                            title="Change Value",
                            option_function='no_option')

    def reset_defaults(self):

        #get the current screen
        back_screen = roboprinter.robosm.current

        def reset():
            roboprinter.printer_instance._printer.commands("M502")
            roboprinter.printer_instance._printer.commands("M500")
            roboprinter.printer_instance._printer.commands("M501")

            #make screen to say that the variables have been reset

            #body_text, button_function, button_text = roboprinter.lang.pack['Button_Screen']['Default_Button']
            content = Button_Screen(roboprinter.lang.pack['EEPROM']
                                    ['Acknowledge_Reset']['Body_Text'],
                                    roboprinter.robosm.go_back_to_main,
                                    button_text=roboprinter.lang.pack['EEPROM']
                                    ['Acknowledge_Reset']['Button'])

            #make screen
            roboprinter.robosm._generate_backbutton_screen(
                name='ack_reset_eeprom',
                title=roboprinter.lang.pack['EEPROM']['Acknowledge_Reset']
                ['Title'],
                back_destination=back_screen,
                content=content)

        def cancel():
            roboprinter.robosm.current = back_screen

        #make the confirmation screen
        #body_text, option1_text, option2_text, option1_function, option2_function
        content = Modal_Question_No_Title(
            roboprinter.lang.pack['EEPROM']['Reset_Confirmation']['Body_Text'],
            roboprinter.lang.pack['EEPROM']['Reset_Confirmation']['positive'],
            roboprinter.lang.pack['EEPROM']['Reset_Confirmation']['negative'],
            reset, cancel)

        #make screen
        roboprinter.robosm._generate_backbutton_screen(
            name='reset_eeprom',
            title=roboprinter.lang.pack['EEPROM']['Reset_Confirmation']
            ['Title'],
            back_destination=back_screen,
            content=content)

    def open_setting(self, setting_data):
        if 'order' in setting_data and 'values' in setting_data:
            #order acts like a filter for what we want the user to see.
            filtered_data = []
            for setting in setting_data['order']:
                if setting in setting_data['values']:
                    data = {
                        'name': setting + ": ",
                        'setting': setting,
                        'data': setting_data
                    }
                    filtered_data.append(data)
                else:
                    Logger.info(str(setting) + " is not in the values list.")
        elif 'action' in setting_data:
            setting_data['action']()
            return  #exit this function
        else:
            Logger.info("No Values or Order!")
            pconsole.dict_logger(setting_data)

        #update Node
        self.EEPROM_Node = EEPROM_Node(data=filtered_data,
                                       title=setting_data['name'],
                                       prev_data=self.EEPROM_Node)

        #update EEPROM list
        self.EEPROM_screen.eeprom_list = self.EEPROM_Node.data
        self.EEPROM_screen.repopulate_for_new_screen()

        #update callback
        self.EEPROM_screen.update_callback(self.open_eeprom_value)

        #update title
        self.bb.update_title(setting_data['name'])

    def previous_list(self):
        Logger.info("Previous list hit")
        if self.EEPROM_Node.return_previous() != None:
            #return the node to the previous node
            self.EEPROM_Node = self.EEPROM_Node.return_previous()

            #refresh the list
            self.EEPROM_screen.eeprom_list = self.EEPROM_Node.data
            self.EEPROM_screen.repopulate_for_new_screen()

            #update callback
            self.EEPROM_screen.update_callback(self.open_setting)
            #update title
            self.bb.update_title(self.EEPROM_Node.title
                                 )  #restore the title associated with the list
        else:
            #If there is no where left to go then go back to the previous screen in the wizard bb node list
            self.bb.update_back_function(self.bb.back_function_flow)
            self.bb.back_function_flow()
class PID_Overseer(object):
    """docstring for PID_Overseer"""
    def __init__(self, name, title, back_destination):
        super(PID_Overseer, self).__init__()
        self.autotune_complete = False
        pconsole.query_eeprom()
        self.bb = Wizard_BB()
        self.group = 'pid_wizard_group'
        self.welcome = None
        self.pid_screen = None
        self.debug_mode = False

        self.name = name  #name of initial screen
        self.title = title
        self.back_destination = back_destination
        self.bb.back_destination = self.back_destination
        self.selected_tool = 'tool0'

        #add bb
        roboprinter.robosm.add_widget(self.bb)
        roboprinter.robosm.current = self.bb.name
        #start wizard
        self.welcome_page()

    def cleanup(self):
        Logger.info("Deleting: PID_Overseer")
        #cleaning up bb elements
        self.bb.delete_node()
        self.bb = ''

        #cleanup workflow
        if self.welcome != None:
            self.welcome.cleanup()
        if self.pid_screen != None:
            self.pid_screen.cleanup()

        #dereference certain functions
        self.back_function_interrupt = ''

        #dereference self
        del_list = []
        for self_var in self.__dict__:
            del_list.append(self_var)
            self.__dict__[self_var] = ''  #set variables to nothing.
        for self_var in del_list:
            #Logger.info("Deleting " + str(self_var))
            del self.__dict__[self_var]

        #Tell Self to print out any remaining referrers
        # Logger.info("---> Printing referrers of PID_Overseer")
        # gc.collect()
        # for referer in gc.get_referrers(self):
        #     Logger.info(referer)
        # Logger.info("---> Done printing referrers of PID_Overseer")

        del self

    def welcome_page(self):

        self.welcome = Button_Screen(
            lang.pack['PID_Tool']['Welcome_Screen']['Body'],
            self.select_extruder,
            button_text=lang.pack['PID_Tool']['Welcome_Screen']['Button_Text'])

        title = lang.pack['PID_Tool']['Welcome_Screen']['Title']
        self.welcome.change_screen_actions = self.cleanup

        self.bb.make_screen(self.welcome, title, option_function='no_option')

    def select_extruder(self):
        #detirmine machine state and behaviour of the wizard
        model = roboprinter.printer_instance._settings.get(['Model'])

        if model == "Robo R2":
            es = Heater_Selector(self.heater_select,
                                 make_screen=self.bb.make_screen,
                                 group=self.group)
            es.show_screen()
        else:
            self.heater_select('EXT1')

    def heater_select(self, heater):
        heaters = ['EXT1', 'EXT2', 'BED']

        if heater in heaters:
            tool_dict = {'EXT1': '0', 'EXT2': '1', 'BED': '-1'}
            self.selected_tool = tool_dict[heater]
            self.start_workflow()
        else:
            Logger.info("ERROR Invalid selection")
            raise ValueError(str(extruder) + " Is not a valid selection")

    def start_workflow(self):
        self.autotune_complete = False  #reset autotune
        if self.pid_screen == None:
            self.pid_screen = PID_Test_Screen(self.selected_tool,
                                              self.finish_wizard,
                                              self.failure_callback,
                                              debug=self.debug_mode)
        else:
            self.pid_screen.cleanup()
            self.pid_screen = PID_Test_Screen(self.selected_tool,
                                              self.finish_wizard,
                                              self.failure_callback,
                                              debug=self.debug_mode)

        title = lang.pack['PID_Tool']['Workflow']['Title']

        self.bb.make_screen(self.pid_screen,
                            title,
                            back_function=self.back_function_interrupt,
                            option_function='no_option')

        #parse the correct command
        #The stage 3 variable will detirmine how many cycles the PID tool will do. This is so our Testers can easily adjust this number without having to consult me.
        if not self.debug_mode:
            command = 'M303 C' + str(lang.pack['PID_Tool']['Workflow']
                                     ['Stage3']) + ' E' + self.selected_tool
        else:

            def deffered_action(*args, **kwargs):
                command = ""

        if not self.debug_mode:
            #if it's the bed then set temp to 100, else set temp to 240
            if int(self.selected_tool) < 0:
                command = command + " S" + lang.pack['PID_Tool']['Workflow'][
                    'Target_Bed']
            else:
                command = command + " S" + lang.pack['PID_Tool']['Workflow'][
                    'Target_Ext']
        else:
            #Just make the wizard dwell for a little back_function_interrupt
            command = "G4 S3"

        Logger.info("Command sent is: " + str(command))

        #start the test
        roboprinter.printer_instance._printer.commands(command)
        roboprinter.printer_instance._printer.commands("M118 ACTION COMPLETE!")

    def back_function_interrupt(self):
        if self.autotune_complete:
            self.bb.back_function_flow()
        else:
            Info_Popup(
                lang.pack['PID_Tool']['Prevent_Back_Screen']['Title'],
                lang.pack['PID_Tool']['Prevent_Back_Screen']['Body']).show()

    def failure_callback(self):
        self.autotune_complete = True

        def cancel():
            roboprinter.robosm.go_back_to_main('printer_status_tab')

        layout = Button_Screen(lang.pack['PID_Tool']['Failure_Screen']['Body'],
                               cancel)

        title = lang.pack['PID_Tool']['Failure_Screen']['Title']
        self.bb.make_screen(layout, title, option_function='no_option')

    def finish_wizard(self, final_PID):
        self.autotune_complete = True

        def save_pid():
            self.save_PID(final_PID)

        body = lang.pack['PID_Tool']['Finish_Wizard']['Body']
        new_pid = lang.pack['PID_Tool']['Finish_Wizard']['New_PID']

        #make the text_object to put into the modal question
        finish_object = PID_Finish_Object(body, new_pid, final_PID)

        layout = Object_Modal_Question(
            finish_object, lang.pack['PID_Tool']['Finish_Wizard']['Save'],
            lang.pack['PID_Tool']['Finish_Wizard']['Cancel'], save_pid,
            self.goto_main)
        title = lang.pack['PID_Tool']['Finish_Wizard']['Title']

        self.bb.make_screen(layout, title, option_function='no_option')

    def save_PID(self, PID):
        #construct PID save command
        pid_command = ''
        if self.selected_tool == "-1":
            pid_command = 'M304 P' + str(PID['P']) + " I" + str(
                PID['I']) + " D" + str(PID['D'])
        else:
            pid_command = 'M301 P' + str(PID['P']) + " I" + str(
                PID['I']) + " D" + str(PID['D'])

        #save PID
        roboprinter.printer_instance._printer.commands(pid_command)
        roboprinter.printer_instance._printer.commands("M500")  #save

        #create a button screen
        layout = Button_Screen(lang.pack['PID_Tool']['Save_Screen']['Body'],
                               self.goto_main)

        title = lang.pack['PID_Tool']['Save_Screen']['Title']
        self.bb.make_screen(layout, title, option_function='no_option')

    def goto_main(self):
        #cleanup the wizard
        self.cleanup()
        roboprinter.robosm.go_back_to_main('printer_status_tab')