diff --git a/docs/src/gui/gmoccapy.adoc b/docs/src/gui/gmoccapy.adoc index 788835453f1..0c58db1f953 100644 --- a/docs/src/gui/gmoccapy.adoc +++ b/docs/src/gui/gmoccapy.adoc @@ -443,7 +443,7 @@ If this file is specified, this file is sourced just after the AXIS GUI is displ *instead* of `~/.gmoccapyrc`. -The following example changes the size of the vertical buttons and changes the order of buttons: +The following example changes the size of the vertical buttons: .Example of .axisrc file ----- self.widgets.vbtb_main.set_size_request(85,-1) @@ -456,11 +456,6 @@ self.widgets.rbt_auto.set_size_request(*BB_SIZE) self.widgets.tbtn_setup.set_size_request(*BB_SIZE) self.widgets.tbtn_user_tabs.set_size_request(*BB_SIZE) self.widgets.btn_exit.set_size_request(*BB_SIZE) - -self.widgets.vbtb_main.remove(self.widgets.tbtn_setup) -self.widgets.vbtb_main.remove(self.widgets.lbl_time) -self.widgets.vbtb_main.add(self.widgets.tbtn_setup) -self.widgets.vbtb_main.add(self.widgets.lbl_time) ----- The widget names can the looked up in the /usr/share/gmoccapy.glade file @@ -490,6 +485,44 @@ button:checked { ---- +=== Logging + +GMOCCAPY supports specifying the level of information (log level) that will be printed to the console and to the log file. + +The order is _VERBOSE_, _DEBUG_, _INFO_, _WARNING_, _ERROR_, _CRITICAL_. +Default is _WARNING_, that means _WARNING_, _ERROR_ and _CRITICAL_ are printed. + +You can specify the log level in the INI file like this: +[source,{ini}] +---- +[DISPLAY] +DISPLAY = gmoccapy +---- +using this parameters: +---- +Log level +DEBUG -d +INFO -i +VERBOSE -v +ERROR -q +---- + +.Example: Configure logging to print only errors +[source,{ini}] +---- +[DISPLAY] +DISPLAY = gmoccapy -q +---- + +You can specify where to save the log file: +[source,{ini}] +---- +[DISPLAY] +LOG_FILE = gmoccapy.log +---- +If `LOG_FILE` is not set, logging happens to `$HOME/.log` + + == HAL Pins GMOCCAPY exports several HAL pins to be able to react to hardware devices. @@ -944,7 +977,7 @@ There are several videos showing the way to do that on YouTube. ==== -=== Tool Measurement Pins +=== Provided Pins GMOCCAPY offers five pins for tool measurement purposes. These pins are mostly used to be read from a G-code subroutine, so the code can react to different values. @@ -955,7 +988,7 @@ These pins are mostly used to be read from a G-code subroutine, so the code can - *gmoccapy.searchvel* _(float OUT)_ - The velocity to search for the tool probe switch - *gmoccapy.probevel* _(float OUT)_ - The velocity to probe tool length -=== Tool Measurement INI File Modifications +=== INI File Modifications Modify your INI file to include the following sections. diff --git a/docs/src/gui/images/gmoccapy_3_axis.png b/docs/src/gui/images/gmoccapy_3_axis.png index 27f0c575342..9367c7c7c63 100644 Binary files a/docs/src/gui/images/gmoccapy_3_axis.png and b/docs/src/gui/images/gmoccapy_3_axis.png differ diff --git a/docs/src/gui/images/gmoccapy_3_axis_mid.png b/docs/src/gui/images/gmoccapy_3_axis_mid.png index 2c2d97473ec..fbc7f2df7d1 100644 Binary files a/docs/src/gui/images/gmoccapy_3_axis_mid.png and b/docs/src/gui/images/gmoccapy_3_axis_mid.png differ diff --git a/docs/src/gui/images/gmoccapy_5_axis.png b/docs/src/gui/images/gmoccapy_5_axis.png index ed3d22acfb0..4790b3af5af 100644 Binary files a/docs/src/gui/images/gmoccapy_5_axis.png and b/docs/src/gui/images/gmoccapy_5_axis.png differ diff --git a/docs/src/gui/images/gmoccapy_5_axis_mid.png b/docs/src/gui/images/gmoccapy_5_axis_mid.png index 5d209c3841a..3106284938d 100644 Binary files a/docs/src/gui/images/gmoccapy_5_axis_mid.png and b/docs/src/gui/images/gmoccapy_5_axis_mid.png differ diff --git a/docs/src/gui/images/gmoccapy_embedded_tabs.png b/docs/src/gui/images/gmoccapy_embedded_tabs.png index 5690363fa65..a91a0fe229a 100644 Binary files a/docs/src/gui/images/gmoccapy_embedded_tabs.png and b/docs/src/gui/images/gmoccapy_embedded_tabs.png differ diff --git a/docs/src/gui/images/gmoccapy_getting_macro_info.png b/docs/src/gui/images/gmoccapy_getting_macro_info.png index 094e1935fb7..864a925b697 100644 Binary files a/docs/src/gui/images/gmoccapy_getting_macro_info.png and b/docs/src/gui/images/gmoccapy_getting_macro_info.png differ diff --git a/docs/src/gui/images/gmoccapy_getting_macro_info_mid.png b/docs/src/gui/images/gmoccapy_getting_macro_info_mid.png index d0405e63bf3..3e03243af5e 100644 Binary files a/docs/src/gui/images/gmoccapy_getting_macro_info_mid.png and b/docs/src/gui/images/gmoccapy_getting_macro_info_mid.png differ diff --git a/docs/src/gui/images/gmoccapy_settings_advanced.png b/docs/src/gui/images/gmoccapy_settings_advanced.png index e119618d6e1..bca251bca64 100644 Binary files a/docs/src/gui/images/gmoccapy_settings_advanced.png and b/docs/src/gui/images/gmoccapy_settings_advanced.png differ diff --git a/docs/src/gui/images/gmoccapy_settings_appearance.png b/docs/src/gui/images/gmoccapy_settings_appearance.png index ea5b1fac141..4e7a4e09c3f 100644 Binary files a/docs/src/gui/images/gmoccapy_settings_appearance.png and b/docs/src/gui/images/gmoccapy_settings_appearance.png differ diff --git a/docs/src/gui/images/gmoccapy_settings_hardware.png b/docs/src/gui/images/gmoccapy_settings_hardware.png index 474becf1baf..68932d1cdfc 100644 Binary files a/docs/src/gui/images/gmoccapy_settings_hardware.png and b/docs/src/gui/images/gmoccapy_settings_hardware.png differ diff --git a/src/emc/usr_intf/gmoccapy/getiniinfo.py b/src/emc/usr_intf/gmoccapy/getiniinfo.py index c11f9490295..b5ad43bee6b 100644 --- a/src/emc/usr_intf/gmoccapy/getiniinfo.py +++ b/src/emc/usr_intf/gmoccapy/getiniinfo.py @@ -28,6 +28,13 @@ import os import operator +# Set up logging +from qtvcp import logger + +LOG = logger.getLogger(__name__) +# Force the log level for this module +# LOG.setLevel(logger.DEBUG) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL + CONFIGPATH = os.environ['CONFIG_DIR'] class GetIniInfo: @@ -36,7 +43,7 @@ def __init__(self): inipath = os.environ["INI_FILE_NAME"] self.inifile = ini(inipath) if not self.inifile: - print("**** GMOCCAPY GETINIINFO **** \nError, no INI File given !!") + LOG.critical("Error, no INI File given !!") sys.exit() def get_cycle_time(self): @@ -44,10 +51,9 @@ def get_cycle_time(self): try: return int(temp) except: - message = ("**** GMOCCAPY GETINIINFO **** \n") - message += ("Wrong entry [DISPLAY] CYCLE_TIME in INI File!\n") + message = ("Wrong entry [DISPLAY] CYCLE_TIME in INI File! ") message += ("Will use gmoccapy default 150") - print(message) + LOG.warning(message) return 150 def get_postgui_halfile(self): @@ -65,7 +71,7 @@ def get_preference_file_path(self): else: machinename = machinename.replace(" ", "_") temp = os.path.join(CONFIGPATH, "%s.pref" % machinename) - print("**** GMOCCAPY GETINIINFO **** \nPreference file path: %s" % temp) + LOG.info("Preference file path: %s" % temp) return temp def get_coordinates(self): @@ -74,14 +80,14 @@ def get_coordinates(self): temp = temp.replace(' ','') if not temp: - print("**** GMOCCAPY GETINIINFO **** \nNo coordinates entry found in [TRAJ] of INI file, will use XYZ as default") + LOG.warning("No coordinates entry found in [TRAJ] of INI file, will use XYZ as default") temp = "xyz" return temp.lower() def get_joints(self): temp = self.inifile.find("KINS", "JOINTS") if not temp: - print("**** GMOCCAPY GETINIINFO **** \nNo JOINTS entry found in [KINS] of INI file, will use 3 as default") + LOG.warning("No JOINTS entry found in [KINS] of INI file, will use 3 as default") return (3) return int(temp) @@ -95,10 +101,9 @@ def get_axis_list(self): # to much axes given, can only handle 9 if len(axis_list) > 9: - message = _("**** GMOCCAPY GETINIINFO : ****") - message += _("**** gmoccapy can only handle 9 axis, ****\n**** but you have given {0} through your INI file ****\n").format(len(axis_list)) - message += _("**** gmoccapy will not start ****\n\n") - print(message) + message = _("**** gmoccapy can only handle 9 axis, but you have given {0} through your INI file. ").format(len(axis_list)) + message += _("gmoccapy will not start ****\n") + LOG.critical(message) #dialogs.warning_dialog(self, _("Very critical situation"), message, sound = False) sys.exit() @@ -118,21 +123,19 @@ def get_joint_axis_relation(self): joint_axis_dic = {} coordinates = None for entry in temp: - print("Entry = {0}".format(entry)) + LOG.debug("Entry = {0}".format(entry)) if "coordinates" in entry.lower(): coordinates = entry.split("=")[1].lower() - print("found the following coordinates {0}".format(coordinates)) + LOG.debug("found the following coordinates {0}".format(coordinates)) if not coordinates: - print("no coordinates found in [KINS] KINEMATICS, we will use order from") - print("[TRAJ] COORDINATES") + LOG.warning("No coordinates found in [KINS] KINEMATICS, we will use order from [TRAJ] COORDINATES.") coordinates = self.get_coordinates() # at this point we should have the coordinates of the config, we will check if the amount of # coordinates does match the [KINS] JOINTS part - print("\n**** GMOCCAPY GETINIINFO **** ") - print("Number of joints = {0}".format(self.get_joints())) - print("{0} COORDINATES found = {1}".format(len(coordinates), coordinates)) + LOG.debug("Number of joints = {0}".format(self.get_joints())) + LOG.debug("{0} COORDINATES found = {1}".format(len(coordinates), coordinates)) # let us check if there are double letters, as that would be a gantry machine double_axis_letter = [] @@ -141,7 +144,7 @@ def get_joint_axis_relation(self): # OK we have a special case here, we need to take care off # i.e. a Gantry XYYZ config double_axis_letter.append(axisletter) - print("Found double letter ", double_axis_letter) + LOG.debug("Found double letter ", double_axis_letter) if self.get_joints() == len(coordinates): prev_double_axis_leter = "" @@ -153,41 +156,38 @@ def get_joint_axis_relation(self): axisletter = axisletter + str(count) count += 1 joint_axis_dic[joint] = axisletter - print("joint {0} = axis {1}".format(joint, joint_axis_dic[joint])) + LOG.debug("joint {0} = axis {1}".format(joint, joint_axis_dic[joint])) else: - print("\n**** GMOCCAPY GETINIINFO **** ") - print("Amount of joints from [KINS]JOINTS= is not identical with axisletters") - print("given in [TRAJ]COORDINATES or [KINS]KINEMATICS") - print("will use the old style used prior to joint axis branch merge,") - print("see man trivkins for details") - print("It is strongly recommended to update your config\n") - print("\nFor all unused joints an entry like [JOINT_3]HOME_SEQUENCE = 0 in your") - print("INI File is needed to get the <> signal and be able") - print("to switch to MDI or AUTO Mode\n") + LOG.warning("Amount of joints from [KINS]JOINTS= is not identical with axisletters " + "given in [TRAJ]COORDINATES or [KINS]KINEMATICS.\n" + "Will use the old style used prior to joint axis branch merge, see man trivkins for details.\n" + "It is strongly recommended to update your config.\n" + "For all unused joints an entry like [JOINT_3]HOME_SEQUENCE = 0 in your " + "INI File is needed to get the <> signal and be able " + "to switch to MDI or AUTO Mode.") for joint, axisletter in enumerate(["x", "y", "z", "a", "b", "c", "u", "v", "w"]): if axisletter in coordinates: joint_axis_dic[joint] = axisletter - print(joint_axis_dic) + LOG.debug(joint_axis_dic) #return sorted(joint_axis_dic, key=joint_axis_dic.get, reverse=False) return joint_axis_dic, double_axis_letter def get_trivial_kinematics(self): temp = self.inifile.find("KINS", "KINEMATICS").split() - print("\n**** GMOCCAPY GETINIINFO **** \n") - print("[KINS] KINESTYPE is {0}".format(temp[0])) + LOG.debug("[KINS] KINESTYPE is {0}".format(temp[0])) if temp[0].lower() == "trivkins": for element in temp: if "BOTH" in element.upper(): - print("Found kinstype=BOTH but using trivkins") - print("It is not recommended to do so!") - print("Will use mode to switch between Joints and World mode") - print("hopefully supported by the used <<{0}>> module\n".format(temp[0])) + LOG.warning("Found kinstype=BOTH but using trivkins. " + "It is not recommended to do so! " + "Will use mode to switch between Joints and World mode, " + "hopefully supported by the used <<{0}>> module.".format(temp[0])) return False return True else: - print("Will use mode to switch between Joints and World mode") - print("hopefully supported by the used <<{0}>> module\n".format(temp[0])) + LOG.debug("Will use mode to switch between Joints and World mode") + LOG.debug("hopefully supported by the used <<{0}>> module\n".format(temp[0])) # I.e. # pumakins = 6 axis XYZABC # scarakins = 4 axis XYZA @@ -235,10 +235,10 @@ def get_jog_vel(self): temp = self.inifile.find("TRAJ", "MAX_LINEAR_VELOCITY" ) if temp: temp = float(temp) / 2 - print("**** GMOCCAPY GETINIINFO **** \nNo DEFAULT_LINEAR_VELOCITY entry found in [TRAJ] of INI file\nUsing half on MAX_LINEAR_VELOCITY") + LOG.warning("No DEFAULT_LINEAR_VELOCITY entry found in [TRAJ] of INI file. Using half on MAX_LINEAR_VELOCITY.") else: temp = 3.0 - print("**** GMOCCAPY GETINIINFO **** \nNo DEFAULT_LINEAR_VELOCITY entry found in [TRAJ] of INI file\nUsing default value of 180 units / min") + LOG.warning("No DEFAULT_LINEAR_VELOCITY entry found in [TRAJ] of INI file. Using default value of 180 units / min.") return float(temp) * 60 def get_max_jog_vel(self): @@ -247,7 +247,7 @@ def get_max_jog_vel(self): temp = self.inifile.find("TRAJ", "MAX_LINEAR_VELOCITY") if not temp: temp = 10.0 - print("**** GMOCCAPY GETINIINFO **** \nNo MAX_LINEAR_VELOCITY entry found in [TRAJ] of INI file\nUsing default value of 600 units / min") + LOG.warning("No MAX_LINEAR_VELOCITY entry found in [TRAJ] of INI file. Using default value of 600 units / min.") return float(temp) * 60 def get_default_ang_jog_vel(self): @@ -255,7 +255,7 @@ def get_default_ang_jog_vel(self): temp = self.inifile.find("DISPLAY", "DEFAULT_ANGULAR_VELOCITY") if not temp: temp = 360.0 - print("**** GMOCCAPY GETINIINFO **** \nNo DEFAULT_ANGULAR_VELOCITY entry found in [DISPLAY] of INI file\nUsing default value of 360 degree / min") + LOG.warning("No DEFAULT_ANGULAR_VELOCITY entry found in [DISPLAY] of INI file. Using default value of 360 degree / min.") return float(temp) def get_max_ang_jog_vel(self): @@ -263,7 +263,7 @@ def get_max_ang_jog_vel(self): temp = self.inifile.find("DISPLAY", "MAX_ANGULAR_VELOCITY") if not temp: temp = 3600.0 - print("**** GMOCCAPY GETINIINFO **** \nNo MAX_ANGULAR_VELOCITY entry found in [DISPLAY] of INI file\nUsing default value of 3600 degree / min") + LOG.warning("No MAX_ANGULAR_VELOCITY entry found in [DISPLAY] of INI file. Using default value of 3600 degree / min.") return float(temp) def get_min_ang_jog_vel(self): @@ -271,7 +271,7 @@ def get_min_ang_jog_vel(self): temp = self.inifile.find("DISPLAY", "MIN_ANGULAR_VELOCITY") if not temp: temp = 0.1 - print("**** GMOCCAPY GETINIINFO **** \nNo MIN_ANGULAR_VELOCITY entry found in [DISPLAY] of INI file\nUsing default value of 0.1 degree / min") + LOG.warning("No MIN_ANGULAR_VELOCITY entry found in [DISPLAY] of INI file. Using default value of 0.1 degree / min.") return float(temp) def get_default_spindle_speed(self): @@ -279,7 +279,7 @@ def get_default_spindle_speed(self): temp = self.inifile.find("DISPLAY", "DEFAULT_SPINDLE_SPEED") if not temp: temp = 300 - print("**** GMOCCAPY GETINIINFO **** \n No DEFAULT_SPINDLE_SPEED entry found in [DISPLAY] of INI file") + LOG.warning("No DEFAULT_SPINDLE_SPEED entry found in [DISPLAY] of INI file") return float(temp) def get_max_spindle_override(self): @@ -287,28 +287,28 @@ def get_max_spindle_override(self): temp = self.inifile.find("DISPLAY", "MAX_SPINDLE_OVERRIDE") if not temp: temp = 1.0 - print("**** GMOCCAPY GETINIINFO **** \nNo MAX_SPINDLE_OVERRIDE entry found in [DISPLAY] of INI file") + LOG.warning("No MAX_SPINDLE_OVERRIDE entry found in [DISPLAY] of INI file") return float(temp) def get_min_spindle_override(self): temp = self.inifile.find("DISPLAY", "MIN_SPINDLE_OVERRIDE") if not temp: temp = 0.1 - print("**** GMOCCAPY GETINIINFO **** \nNo MIN_SPINDLE_OVERRIDE entry found in [DISPLAY] of INI file") + LOG.warning("No MIN_SPINDLE_OVERRIDE entry found in [DISPLAY] of INI file") return float(temp) def get_max_feed_override(self): temp = self.inifile.find("DISPLAY", "MAX_FEED_OVERRIDE") if not temp: temp = 1.0 - print("**** GMOCCAPY GETINIINFO **** \nNo MAX_FEED_OVERRIDE entry found in [DISPLAY] of INI file") + LOG.warning("No MAX_FEED_OVERRIDE entry found in [DISPLAY] of INI file") return float(temp) def get_max_rapid_override(self): temp = self.inifile.find("DISPLAY", "MAX_RAPID_OVERRIDE") if not temp: temp = 1.0 - print("**** GMOCCAPY GETINIINFO **** \nNo MAX_RAPID_OVERRIDE entry found in [DISPLAY] of INI file \n Default settings 100 % applied!") + LOG.warning("No MAX_RAPID_OVERRIDE entry found in [DISPLAY] of INI file. Default settings 100 % applied!") return float(temp) def get_embedded_tabs(self): @@ -343,12 +343,11 @@ def get_program_prefix(self): # and we want to set the default path default_path = self.inifile.find("DISPLAY", "PROGRAM_PREFIX") if not default_path: - print("**** GMOCCAPY GETINIINFO **** \nPath %s from DISPLAY , PROGRAM_PREFIX does not exist" % default_path) - print("**** GMOCCAPY GETINIINFO **** \nTrying default path...") + LOG.warning("Path {0} from DISPLAY , PROGRAM_PREFIX does not exist, ".format(default_path)\ + + "trying default path...") default_path = "~/linuxcnc/nc_files/" if not os.path.exists(os.path.expanduser(default_path)): - print("**** GMOCCAPY GETINIINFO **** \nDefault path to ~/linuxcnc/nc_files does not exist") - print("**** GMOCCAPY GETINIINFO **** \nsetting now home as path") + LOG.warning("Default path to ~/linuxcnc/nc_files does not exist, setting now home as path.") default_path = os.path.expanduser("~/") return default_path @@ -362,8 +361,8 @@ def get_file_ext(self): ext = extension.split() ext_list.append(ext[0].replace(".", "*.")) else: - print("**** GMOCCAPY GETINIINFO **** \nError converting the file extensions from INI File 'FILTER','PROGRAMM_PREFIX") - print("**** GMOCCAPY GETINIINFO **** \nusing as default '*.ngc'") + LOG.warning("Error converting the file extensions from INI file [FILTER]PROGRAM_PREFIX, " + "using as default '*.ngc'") ext_list = ["*.ngc"] return ext_list @@ -379,7 +378,7 @@ def get_increments(self): jog_increments.insert(0, 0) else: jog_increments = [0, "1.000", "0.100", "0.010", "0.001"] - print("**** GMOCCAPY GETINIINFO **** \nNo default jog increments entry found in [DISPLAY] of INI file\nUsing default values") + LOG.warning("No default jog increments entry found in [DISPLAY] of INI file. Using default values.") return jog_increments def get_toolfile(self): @@ -418,19 +417,17 @@ def get_macros(self): found = True break if not found: # report error! - message = ( "\n**** GMOCCAPY INFO ****\n" ) - message += ( "File %s of the macro %s could not be found ****\n" %((str(macro.split()[0]) + ".ngc"),[macro]) ) - message += ("we searched in subdirectories: %s" %subroutine_paths.split(":")) - print (message) + message = ("File %s of the macro %s could not be found. " %((str(macro.split()[0]) + ".ngc"),[macro]) ) + message += ("We searched in subdirectories: %s" %subroutine_paths.split(":")) + LOG.info(message) return checked_macros def get_subroutine_paths(self): subroutines_paths = self.inifile.find("RS274NGC", "SUBROUTINE_PATH") if not subroutines_paths: - message = _( "**** GMOCCAPY GETINIINFO ****\n" ) - message += _( "**** No subroutine folder or program prefix is given in the INI file **** \n" ) - print( message ) + message = _("No subroutine folder or program prefix is given in the INI file!") + LOG.warning(message) subroutines_paths = self.get_program_prefix() if not subroutines_paths: return False @@ -454,12 +451,12 @@ def get_user_messages(self): message_type = self.inifile.findall("DISPLAY", "MESSAGE_TYPE") message_pinname = self.inifile.findall("DISPLAY", "MESSAGE_PINNAME") if len(message_text) != len(message_type) or len(message_text) != len(message_pinname): - print("**** GMOCCAPY GETINIINFO **** \nERROR in user message setup") + LOG.warning("ERROR in user message setup") return None else: for element in message_pinname: if " " in element: - print("**** GMOCCAPY GETINIINFO **** \nERROR in user message setup \nPinname should not contain spaces") + LOG.warning("ERROR in user message setup. Pin name should not contain spaces.") return None messages = list(zip(message_text, message_type, message_pinname)) return messages @@ -469,18 +466,18 @@ def get_machine_units(self): if units == "mm" or units == "cm" or units == "inch": return units else: - print("**** GMOCCAPY GETINIINFO **** \nERROR getting machine units \n" - "please check [TRAJ] LINEAR_UNITS for a valid entry, found {0}".format(units)) + LOG.warning("ERROR getting machine units. " + "Please check [TRAJ] LINEAR_UNITS for a valid entry, found {0}.".format(units)) return None def get_user_command_file(self): temp = self.inifile.find("DISPLAY", "USER_COMMAND_FILE") if temp: - print("**** USER_COMMAND_FILE = " + temp) + LOG.info("USER_COMMAND_FILE = " + temp) return temp def get_user_css_file(self): temp = self.inifile.find("DISPLAY", "USER_CSS_FILE") if temp: - print("**** USER_CSS_FILE = " + temp) + LOG.info("USER_CSS_FILE = " + temp) return temp diff --git a/src/emc/usr_intf/gmoccapy/gmoccapy.glade b/src/emc/usr_intf/gmoccapy/gmoccapy.glade index 19defd1555e..53eba48071a 100644 --- a/src/emc/usr_intf/gmoccapy/gmoccapy.glade +++ b/src/emc/usr_intf/gmoccapy/gmoccapy.glade @@ -6419,7 +6419,7 @@ to test your settings. False False - 5 + 6 @@ -6439,7 +6439,7 @@ to test your settings. False False - 6 + 5 diff --git a/src/emc/usr_intf/gmoccapy/gmoccapy.py b/src/emc/usr_intf/gmoccapy/gmoccapy.py index fad749ce0d6..648da5d3d82 100644 --- a/src/emc/usr_intf/gmoccapy/gmoccapy.py +++ b/src/emc/usr_intf/gmoccapy/gmoccapy.py @@ -40,7 +40,6 @@ import hal_glib # needed to make our own hal pins import sys # handle system calls import os # needed to get the paths and directories -import gladevcp.makepins # needed for the dialog"s calculator widget import atexit # needed to register child's to be closed on closing the GUI import subprocess # to launch onboard and other processes import tempfile # needed only if the user click new in edit mode to open a new empty file @@ -48,14 +47,10 @@ import locale # for setting the language of the GUI import gettext # to extract the strings to be translated from collections import OrderedDict # needed for proper jog button arrangement - -from gladevcp.gladebuilder import GladeBuilder - -from gladevcp.combi_dro import Combi_DRO # we will need it to make the DRO - from time import strftime # needed for the clock in the GUI #from Gtk._Gtk import main_quit + # Throws up a dialog with debug info when an error is encountered def excepthook(exc_type, exc_obj, exc_tb): try: @@ -66,7 +61,7 @@ def excepthook(exc_type, exc_obj, exc_tb): w = None lines = traceback.format_exception(exc_type, exc_obj, exc_tb) message ="Found an error!\nThe following information may be useful in troubleshooting:\n\n" + "".join(lines) - print(message) + LOG.error(message) m = Gtk.MessageDialog(parent = w, modal = True , destroy_with_parent = True, @@ -83,7 +78,7 @@ def excepthook(exc_type, exc_obj, exc_tb): # constants # # gmoccapy #" -_RELEASE = " 3.4.1" +_RELEASE = " 3.4.2" _INCH = 0 # imperial units are active _MM = 1 # metric units are active @@ -110,13 +105,6 @@ def excepthook(exc_type, exc_obj, exc_tb): LIBDIR = os.path.join(BASE, "lib", "python") sys.path.insert(0, LIBDIR) -# as now we know the libdir path we can import our own modules -from gmoccapy import widgets # a class to handle the widgets -from gmoccapy import notification # this is the module we use for our error handling -from gmoccapy import preferences # this handles the preferences -from gmoccapy import getiniinfo # this handles the INI File reading so checking is done in that module -from gmoccapy import dialogs # this takes the code of all our dialogs -from gmoccapy import icon_theme_helper _AUDIO_AVAILABLE = False try: @@ -258,25 +246,22 @@ def __init__(self, argv): self.user_mode = False self.logofile = None for index, arg in enumerate(argv): - print(index, " = ", arg) + LOG.debug(index, " = ", arg) if arg == "-user_mode": self.user_mode = True self.widgets.tbtn_setup.set_sensitive(False) - message = _("**** GMOCCAPY INI Entry ****") - message += "\n" + _("user mode selected") - print (message) + message = "\n" + _("user mode selected") + LOG.debug(message) if arg == "-logo": self.logofile = str(argv[ index + 1 ]) - message = _("**** GMOCCAPY INI Entry ****") - message += "\n" + _("logo entry found = {0}").format(self.logofile) - print (message) + message = "\n" + _("logo entry found = {0}").format(self.logofile) + LOG.debug(message) self.logofile = self.logofile.strip("\"\'") if not os.path.isfile(self.logofile): self.logofile = None - message = _("**** GMOCCAPY INI Entry Error ****") - message += "\n" + _("Logofile entry found, but could not be converted to path.") + message = "\n" + _("Logofile entry found, but could not be converted to path.") message += "\n" + _("The file path should not contain any spaces") - print(message) + LOG.warning(message) # check if the user want a Logo (given as command line argument) if self.logofile: @@ -466,7 +451,7 @@ def __init__(self, argv): LANGDIR = os.path.join(BASE, "share", "Gtksourceview-2.0", "language-specs") file_path = os.path.join(LANGDIR, "gcode.lang") if os.path.isfile(file_path): - print("**** GMOCCAPY INFO: Gcode.lang found ****") + LOG.info("Gcode.lang found") self.widgets.gcode_view.set_language("gcode", LANGDIR) # set the user colors and digits of the DRO @@ -524,7 +509,7 @@ def __init__(self, argv): exec(compile(open(rcfile, "rb").read(), rcfile, 'exec')) except: tb = traceback.format_exc() - print(tb, file=sys.stderr) + LOG.error(tb, file=sys.stderr) self.notification.add_message(_("Error in ") + rcfile + "\n" \ + _("Please check the console output."), ALERT_ICON) @@ -545,7 +530,7 @@ def __init__(self, argv): style_context.add_provider_for_screen(screen, provider_custom, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) except: tb = traceback.format_exc() - print(tb, file=sys.stderr) + LOG.error(tb, file=sys.stderr) self.notification.add_message(_("Error in ") + css_file + "\n" \ + _("Please check the console output."), ALERT_ICON) @@ -642,9 +627,8 @@ def _get_pref_data(self): ############################################################################### def _make_DRO(self): - print("**** GMOCCAPY INFO ****") - print("**** Entering make_DRO") - print("axis_list = {0}".format(self.axis_list)) + LOG.debug("Entering make_DRO") + LOG.debug("axis_list = {0}".format(self.axis_list)) # we build one DRO for each axis self.dro_dic = {} @@ -681,8 +665,7 @@ def _get_joint_from_joint_axis_dic(self, value): return list(self.joint_axis_dic.keys())[list(self.joint_axis_dic.values()).index(value)] def _make_ref_axis_button(self): - print("**** GMOCCAPY INFO ****") - print("**** Entering make ref axis button") + LOG.debug("Entering make ref axis button") # check if we need axis or joint homing button if self.trivial_kinematics: @@ -814,7 +797,7 @@ def _new_button_with_predefined_image(self, name, size, image = None, image_name else: raise ValueError("Either image or image_name must not be None") except Exception as e: - print(f"Error creating button with predefined image: {e}") + LOG.warning(f"Error creating button with predefined image: {e}") missing_image = Gtk.Image() # TODO: Deprecated missing_image.set_from_stock(Gtk.STOCK_MISSING_IMAGE, Gtk.IconSize.BUTTON) @@ -823,7 +806,7 @@ def _new_button_with_predefined_image(self, name, size, image = None, image_name return btn def _get_button_with_image(self, name, filepath, icon_name): - print("get button with image") + LOG.debug("get button with image") image = Gtk.Image() image.set_size_request(72,48) btn = Gtk.Button.new() @@ -839,10 +822,9 @@ def _get_button_with_image(self, name, filepath, icon_name): image.set_from_icon_name(icon_name, Gtk.IconSize.DIALOG) btn.add(image) except Exception as e: - print(e) - message = _("**** GMOCCAPY ERROR ****\n") - message += _("**** could not resolv the image path '{0}' given for button '{1}' ****".format(filepath, name)) - print(message) + LOG.error(e) + message = _("could not resolv the image path '{0}' given for button '{1}'".format(filepath, name)) + LOG.error(message) image.set_from_icon_name("image-missing", Gtk.IconSize.DIALOG) btn.add(image) @@ -911,7 +893,7 @@ def _on_btn_next_macro_clicked(self, widget): self.macro_dic["keyboard"].show() def _on_btn_previous_clicked(self, widget): - print("previous") + LOG.debug("previous") self._remove_button(self.ref_button_dic, self.widgets.hbtb_ref) self.widgets.hbtb_ref.pack_start(self.ref_button_dic["ref_all"], True, True, 0) @@ -986,8 +968,7 @@ def _put_unref_and_back(self): self.widgets.hbtb_ref.pack_start(self.ref_button_dic["home_back"], True, True, 0) def _make_touch_button(self): - print("**** GMOCCAPY INFO ****") - print("**** Entering make touch button") + LOG.debug("Entering make touch button") dic = self.axis_list num_elements = len(dic) @@ -1117,9 +1098,7 @@ def _check_toolmeasurement(self): xpos, ypos, zpos, maxprobe = self.get_ini_info.get_tool_sensor_data() if not xpos or not ypos or not zpos or not maxprobe: self.widgets.lbl_tool_measurement.show() - print(_("**** GMOCCAPY INFO ****")) - print(_("**** no valid probe config in INI File ****")) - print(_("**** disabled tool measurement ****")) + LOG.info(_("No valid probe config in INI File. Tool measurement disabled.")) self.widgets.chk_use_tool_measurement.set_active(False) self.widgets.chk_use_tool_measurement.set_sensitive(False) return False @@ -1133,14 +1112,11 @@ def _check_toolmeasurement(self): self.widgets.lbl_y_probe.set_label(str(ypos)) self.widgets.lbl_z_probe.set_label(str(zpos)) self.widgets.lbl_maxprobe.set_label(str(maxprobe)) - print(_("**** GMOCCAPY INFO ****")) - print(_("**** found valid probe config in INI File ****")) - print(_("**** will use auto tool measurement ****")) + LOG.info(_("Found valid probe config in INI file. Will use auto tool measurement.")) return True def _make_jog_increments(self): - print("**** GMOCCAPY INFO ****") - print("**** Entering make jog increments") + LOG.debug("Entering make jog increments") # Now we will build the option buttons to select the Jog-rates # We do this dynamically, because users are able to set them in INI File # because of space on the screen only 10 items are allowed @@ -1150,9 +1126,8 @@ def _make_jog_increments(self): # We get the increments from INI File if len(self.jog_increments) > 10: - print(_("**** GMOCCAPY build_GUI INFO ****")) - print(_("**** To many increments given in INI File for this screen ****")) - print(_("**** Only the first 10 will be reachable through this screen ****")) + LOG.warning(_("To many increments given in INI File for this screen. " + "Only the first 10 will be reachable through this screen.")) # we shorten the increment list to 10 (first is default = 0) self.jog_increments = self.jog_increments[0:11] @@ -1197,7 +1172,7 @@ def _jog_increment_changed(self, widget,): self.active_increment = widget.get_property("name") def _on_btn_jog_pressed(self, widget, button_name, shift=False): - print("Jog Button pressed = {0}".format(button_name)) + LOG.debug("Jog Button pressed = {0}".format(button_name)) # only in manual mode we will allow jogging the axis at this development state # needed to avoid error on start up, machine not on @@ -1206,7 +1181,7 @@ def _on_btn_jog_pressed(self, widget, button_name, shift=False): joint_no_or_axis_index = self._get_joint_no_or_axis_index(button_name) if joint_no_or_axis_index is None: - print("Did not get an axis number in jog part of the code") + LOG.debug("Did not get an axis number in jog part of the code") return # if shift = True, then the user pressed SHIFT for Jogging and @@ -1244,7 +1219,7 @@ def _on_btn_jog_pressed(self, widget, button_name, shift=False): self.command.jog(linuxcnc.JOG_CONTINUOUS, JOGMODE, joint_no_or_axis_index, dir * velocity) def _on_btn_jog_released(self, widget, button_name, shift=False): - print ("Jog Button released = {0}".format(button_name)) + LOG.debug("Jog Button released = {0}".format(button_name)) # only in manual mode we will allow jogging the axis at this development state if not self.stat.enabled or self.stat.task_mode != linuxcnc.MODE_MANUAL: return @@ -1273,14 +1248,13 @@ def _get_jog_mode(self): def _get_joint_no_or_axis_index(self, button_name): joint_btn = False if not button_name[0] in "xyzabcuvw": - print("Axis button") + LOG.debug("Axis button") # OK, it may be a Joints button if button_name[0] in "012345678": - print("joint button") + LOG.debug("joint button") joint_btn = True else: - print(_("**** GMOCCAPY INFO ****")) - print (_("unknown jog command {0}".format(button_name))) + LOG.warning(_("unknown jog command {0}".format(button_name))) return None if not joint_btn: @@ -1295,8 +1269,7 @@ def _get_joint_no_or_axis_index(self, button_name): return joint_no_or_axis_index def _make_jog_button(self): - print("**** GMOCCAPY INFO ****") - print("**** Entering make jog button") + LOG.debug("Entering make jog button") self.jog_button_dic = OrderedDict() @@ -1316,8 +1289,7 @@ def _make_jog_button(self): self.jog_button_dic[name] = btn def _make_joints_button(self): - print("**** GMOCCAPY INFO ****") - print("**** Entering make joints button") + LOG.debug("Entering make joints button") self.joints_button_dic = {} @@ -1338,8 +1310,7 @@ def _make_joints_button(self): # check if macros are in the INI file and add them to MDI Button List def _make_macro_button(self): - print("**** GMOCCAPY INFO ****") - print("**** Entering make macro button") + LOG.debug("Entering make macro button") macros = self.get_ini_info.get_macros() @@ -1350,12 +1321,12 @@ def _make_macro_button(self): else: num_macros = len(macros) - print("found {0} Macros".format(num_macros)) + LOG.debug("found {0} Macros".format(num_macros)) if num_macros > 16: - message = _("**** GMOCCAPY INFO ****\n") - message += _("**** found more than 16 macros, will use only the first 16 ****") - print(message) + message = _("GMOCCAPY INFO\n") + message += _("found more than 16 macros, will use only the first 16") + LOG.info(message) num_macros = 16 @@ -1374,8 +1345,8 @@ def _make_macro_button(self): image = self._check_macro_for_image(name) if image: - print("Macro {0} has image link".format(name)) - print("Image = {0}".format(image)) + LOG.debug("Macro {0} has image link".format(name)) + LOG.debug("Image = {0}".format(image)) btn = self._get_button_with_image("macro_{0}".format(pos), image, None) else: lbl = name.split()[0] @@ -1463,8 +1434,7 @@ def _check_macro_for_image(self, name): # if this is a lathe we need to rearrange some button and add a additional DRO def _make_lathe(self): - print("**** GMOCCAPY INFO ****") - print("**** we have a lathe here") + LOG.debug("we have a lathe here") # if we have a lathe, we will need an additional DRO to display # diameter and radius simultaneous, we will call that one Combi_DRO_9, as that value @@ -1515,7 +1485,7 @@ def _make_lathe(self): # we need to arrange the jog button, # a lathe should have at least X and Z axis if not "x" in self.axis_list or not "z" in self.axis_list: - message = _("***** GMOCCAPY ERROR *****") + message = _("* GMOCCAPY ERROR *") message += _("this is not a lathe, as a lathe must have at least\n") message += _("an X and an Z axis\n") message += _("Wrong lathe configuration, we will leave here") @@ -1564,9 +1534,8 @@ def _make_lathe(self): self.jog_button_dic[btn_name].show() def _arrange_dro(self): - print("**** GMOCCAPY INFO ****") - print("**** arrange DRO") - print(len(self.dro_dic)) + LOG.debug("arrange DRO") + LOG.debug(len(self.dro_dic)) # if we have less than 4 axis, we can resize the table, as we have # enough space to display each one in it's own line @@ -1601,8 +1570,7 @@ def _arrange_dro(self): self.dro_dic[dro_name].set_property("font_size", size) else: - print("**** GMOCCAPY build_GUI INFO ****") - print("**** more than 5 axis ") + LOG.debug("more than 5 axis ") # check if amount of axis is an even number, adapt the needed lines if len(self.dro_dic) % 2 == 0: rows = len(self.dro_dic) / 2 @@ -1614,8 +1582,7 @@ def _arrange_dro(self): self.widgets.adj_dro_size.set_value(self.dro_size) def _place_in_table(self, rows, cols, dro_size): - print("**** GMOCCAPY INFO ****") - print("**** Place in table") + LOG.debug("Place in table") self.widgets.tbl_DRO.resize(rows, cols) col = 0 @@ -1642,8 +1609,7 @@ def _place_in_table(self, rows, cols, dro_size): row += 1 def _get_DRO_order(self): - print("**** GMOCCAPY INFO ****") - print("**** get DRO order") + LOG.debug("get DRO order") dro_order = [] # if Combi_DRO_9 exist we have a lathe with an additional DRO for diameter mode if "Combi_DRO_9" in list(self.dro_dic.keys()): @@ -1656,8 +1622,7 @@ def _get_DRO_order(self): return dro_order def _arrange_jog_button(self): - print("**** GMOCCAPY INFO ****") - print("**** arrange JOG button") + LOG.debug("arrange JOG button") # if we have a lathe, we have done the arrangement in _make_lathe # but if the lathe has more than 5 axis we will use standard @@ -1669,20 +1634,19 @@ def _arrange_jog_button(self): return if not "x" in self.axis_list or not "y" in self.axis_list or not "z" in self.axis_list: - message = _("***** GMOCCAPY INFO *****") - message += _("this is not a usual config\n") + message = _("this is not a usual config\n") message += _("we miss one of X , Y or Z axis\n") message += _("We will use by axisletter ordered jog button") - print(message) + LOG.warning(message) self._arrange_jog_button_by_axis() return if len(self.axis_list) < 3: - print("Less than 3 axis") + LOG.debug("Less than 3 axis") # we can resize the jog_btn_table self.widgets.tbl_jog_btn_axes.resize(3, 3) else: - print("less than 6 axis") + LOG.debug("less than 6 axis") # we can resize the jog_btn_table self.widgets.tbl_jog_btn_axes.resize(3, 4) @@ -1722,9 +1686,8 @@ def _arrange_jog_button(self): self.widgets.tbl_jog_btn_axes.show_all() def _arrange_jog_button_by_axis(self): - print("**** GMOCCAPY INFO ****") - print("**** arrange JOG button by axis") - print(sorted(self.jog_button_dic.keys())) + LOG.debug("arrange JOG button by axis") + LOG.debug(sorted(self.jog_button_dic.keys())) # check if amount of axis is an even number, adapt the needed lines cols = 4 if len(self.dro_dic) % 2 == 0: @@ -1758,9 +1721,8 @@ def _arrange_jog_button_by_axis(self): self.widgets.tbl_jog_btn_axes.show_all() def _arrange_joint_button(self): - print("**** GMOCCAPY INFO ****") - print("**** arrange JOINTS button") - print("Found {0} Joints Button".format(len(self.joints_button_dic))) + LOG.debug("arrange JOINTS button") + LOG.debug("Found {0} Joints Button".format(len(self.joints_button_dic))) cols = 4 if self.stat.joints % 2 == 0: @@ -1867,16 +1829,14 @@ def _init_dynamic_tabs(self): if not tab_names: self.widgets.tbtn_user_tabs.set_sensitive( False ) self.user_tabs_enabled = False - print (_("**** GMOCCAPY INFO ****")) - print (_("**** Invalid embedded tab configuration ****")) - print (_("**** No tabs will be added! ****")) + LOG.info(_("No embedded tabs configured or invalid configuration. No tabs will be added!")) return try: for t, c, name in zip(tab_names, tab_cmd, tab_locations): nb = self.widgets[name] if c == "hide": - print("hide widget : ", name, type(self.widgets[name])) + LOG.debug("hide widget : ", name, type(self.widgets[name])) nb.hide() continue xid = self._dynamic_tab(nb, t) @@ -1886,8 +1846,8 @@ def _init_dynamic_tabs(self): self._dynamic_childs[xid] = child nb.show_all() except: - print(_("ERROR, trying to initialize the user tabs or panels, check for typos")) - print(tab_locations) + LOG.error(_("ERROR, trying to initialize the user tabs or panels, check for typos")) + LOG.error(tab_locations) self.set_up_user_tab_widgets(tab_locations) @@ -1906,7 +1866,7 @@ def _dynamic_tab(self, widget, text): # Gotta kill the embedded processes when gmoccapy closes #@atexit.register def _kill_dynamic_childs(self): - print("_kill_dynamic_childs") + LOG.debug("_kill_dynamic_childs") for child in list(self._dynamic_childs.values()): if type(child) == Gtk.Socket: if self.onboard: @@ -1992,9 +1952,8 @@ def _init_tooleditor(self): # get the path to the tool table tooltable = self.get_ini_info.get_toolfile() if not tooltable: - message = _("**** GMOCCAPY ERROR ****\n") - message += _("**** Did not find a toolfile file in [EMCIO] TOOL_TABLE ****") - print(message) + message = _("Did not find a toolfile file in [EMCIO] TOOL_TABLE") + LOG.error(message) self.dialogs.warning_dialog(self, _("Very critical situation"), message, sound = False) sys.exit() toolfile = os.path.join(CONFIGPATH, tooltable) @@ -2067,7 +2026,7 @@ def _init_icon_themes(self): selected_index = [icon_theme[1] for icon_theme in valid_icon_themes].index(icon_theme_preference) icon_theme_choice.set_active(selected_index) except ValueError: - print(f"Warning: preferred icon-theme '{icon_theme_preference}' not found; switching to 'default'.") + LOG.warning(f"Preferred icon-theme '{icon_theme_preference}' not found. Switching to '{DEFAULT_ICON_THEME}'.") icon_theme_choice.set_active(0) # load icon theme @@ -2077,8 +2036,7 @@ def _init_icon_themes(self): def _init_audio(self): # try to add ability for audio feedback to user. if _AUDIO_AVAILABLE: - print (_("**** GMOCCAPY INFO ****")) - print (_("**** audio available! ****")) + LOG.debug(_("audio available!")) # the sounds to play if an error or message rises self.alert_sound = "/usr/share/sounds/freedesktop/stereo/dialog-warning.oga" @@ -2090,18 +2048,15 @@ def _init_audio(self): self.widgets.audio_alert_chooser.set_filename(self.alert_sound) self.widgets.audio_error_chooser.set_filename(self.error_sound) else: - print (_("**** GMOCCAPY INFO ****")) - print (_("**** no audio available! ****")) - print(_("**** PYGST library not installed? ****")) - print(_("**** is python-gstX.XX installed? ****")) + LOG.warning(_("No audio available! PYGST library not installed? " + "Is python-gstX.XX installed?")) self.widgets.audio_alert_chooser.set_sensitive(False) self.widgets.audio_error_chooser.set_sensitive(False) # init the preview def _init_gremlin( self ): - print (_("**** GMOCCAPY INFO ****")) - print (_("**** Entering init gremlin ****")) + LOG.debug(_("Entering init gremlin")) grid_size = self.prefs.getpref( 'grid_size', 1.0, float ) self.widgets.grid_size.set_value( grid_size ) @@ -2116,7 +2071,7 @@ def _init_gremlin( self ): self.widgets.eb_blockheight_label.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0.0, 0.0, 0.0, 1.0)) def _init_kinematics_type (self): - print("Kinematics type changed") + LOG.debug("Kinematics type changed") if self.stat.kinematics_type != linuxcnc.KINEMATICS_IDENTITY: self.widgets.gremlin.set_property("enable_dro", True ) self.widgets.gremlin.use_joints_mode = True @@ -2165,12 +2120,10 @@ def _init_keyboard(self, args="", x="", y=""): stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True) - print (_("**** GMOCCAPY INFO ****")) - print (_("**** virtual keyboard program found : ")) + LOG.info(_("Virtual keyboard program found : ")) else: - print (_("**** GMOCCAPY INFO ****")) - print (_("**** No virtual keyboard installed, we checked for .")) - print (_("**** try sudo apt-get install onboard")) + LOG.warning(_("No virtual keyboard installed, we checked for . " + "Try 'sudo apt-get install onboard'.")) self._no_virt_keyboard() return sid = self.onboard_kb.stdout.readline() @@ -2182,10 +2135,8 @@ def _init_keyboard(self, args="", x="", y=""): self._dynamic_childs[int(sid)] = self.socket self.onboard = True except Exception as e: - print (_("**** GMOCCAPY ERROR ****")) - print (_("**** Error with launching virtual keyboard,")) - print (_("**** is onboard installed? ****")) - print (_("**** try sudo apt-get install onboard")) + LOG.error(_("Error with launching virtual keyboard. Is onboard installed?" + "Try sudo apt-get install onboard")) traceback.print_exc() self._no_virt_keyboard() @@ -2221,7 +2172,7 @@ def _no_virt_keyboard(self): self.widgets.btn_keyb.set_sensitive(False) def _kill_keyboard(self): - print("_kill_keyboard") + LOG.debug("_kill_keyboard") try: self.onboard_kb.kill() self.onboard_kb.terminate() @@ -2247,9 +2198,8 @@ def _init_offsetpage(self): parameterfile = self.get_ini_info.get_parameter_file() if not parameterfile: - message = _("**** GMOCCAPY ERROR ****\n") - message += _("**** Did not find a parameter file in [RS274NGC] PARAMETER_FILE ****") - print(message) + message = _("Did not find a parameter file in [RS274NGC] PARAMETER_FILE") + LOG.error(message) self.dialogs.warning_dialog(self, _("Very critical situation"), message, sound = False) sys.exit() path = os.path.join(CONFIGPATH, parameterfile) @@ -2352,7 +2302,7 @@ def _init_user_messages(self): pin = hal_glib.GPin( self.halcomp.newpin("messages." + message[2] + "-response", hal.HAL_BIT, hal.HAL_OUT)) else: - print(_("**** GMOCCAPY ERROR **** /n Message type {0} not supported").format(message[1])) + LOG.error(_("Message type {0} not supported").format(message[1])) def _show_user_message(self, pin, message): if message[1] == "status": @@ -2376,7 +2326,7 @@ def _show_user_message(self, pin, message): else: self.halcomp["messages." + message[2] + "-waiting"] = 0 else: - print(_("**** GMOCCAPY ERROR **** /n Message type {0} not supported").format(message[1])) + LOG.error(_("Message type {0} not supported").format(message[1])) def _show_offset_tab(self, state): page = self.widgets.ntb_preview.get_nth_page(1) @@ -2552,17 +2502,17 @@ def on_tbtn_on_toggled(self, widget, data=None): # The mode buttons def on_rbt_manual_pressed(self, widget, data=None): - print("mode Manual") + LOG.debug("mode Manual") self.command.mode(linuxcnc.MODE_MANUAL) self.command.wait_complete() def on_rbt_mdi_pressed(self, widget, data=None): - print("mode MDI") + LOG.debug("mode MDI") self.command.mode(linuxcnc.MODE_MDI) self.command.wait_complete() def on_rbt_auto_pressed(self, widget, data=None): - print("mode Auto") + LOG.debug("mode Auto") self.command.mode(linuxcnc.MODE_AUTO) self.command.wait_complete() @@ -2579,7 +2529,7 @@ def on_btn_exit_clicked(self, widget, data=None): # use the hal_status widget to control buttons and # actions allowed by the user and sensitive widgets def on_hal_status_all_homed(self, widget): - print("Hal Status all homed") + LOG.debug("Hal Status all homed") self.all_homed = True self.widgets.ntb_button.set_current_page(_BB_MANUAL) widgetlist = ["rbt_mdi", "rbt_auto", "btn_index_tool", "btn_change_tool", "btn_select_tool_by_no", @@ -2599,7 +2549,7 @@ def on_hal_status_all_homed(self, widget): self.command.mode(linuxcnc.MODE_MANUAL) def on_hal_status_not_all_homed(self, widget, joints): - print("Hal Status not all homed", joints) + LOG.debug("Hal Status not all homed", joints) self.all_homed = False if self.no_force_homing: return @@ -2637,7 +2587,7 @@ def on_hal_status_line_changed(self, widget, line): # print("Progress = {0:.2f} %".format(100.00 * line / self.halcomp["program.length"])) def on_hal_status_interp_idle(self, widget): - print("IDLE") + LOG.debug("IDLE") if self.load_tool: return @@ -2689,7 +2639,7 @@ def on_hal_status_interp_idle(self, widget): self.halcomp["program.progress"] = 0.0 def on_hal_status_interp_run(self, widget): - print("RUN") + LOG.debug("RUN") widgetlist = ["rbt_manual", "rbt_mdi", "rbt_auto", "tbtn_setup", "btn_index_tool", "btn_from_line", "btn_change_tool", "btn_select_tool_by_no", @@ -2708,7 +2658,7 @@ def on_hal_status_interp_run(self, widget): self.macro_dic["keyboard"].set_sensitive(True) def on_hal_status_tool_in_spindle_changed(self, object, new_tool_no): - print("hal signal tool changed") + LOG.debug("hal signal tool changed") # need to save the tool in spindle as preference, to be able to reload it on startup self.prefs.putpref("tool_in_spindle", new_tool_no, int) self._update_toolinfo(new_tool_no) @@ -2795,7 +2745,7 @@ def on_hal_status_limits_tripped(self, object, state, lst_limits): self.widgets.chk_ignore_limits.set_active(False) def on_hal_status_mode_manual(self, widget): - print ("MANUAL Mode") + LOG.debug("MANUAL Mode") self.widgets.rbt_manual.set_active(True) # if setup page is activated, we must leave here, otherwise the pages will be reset if self.widgets.tbtn_setup.get_active(): @@ -2818,7 +2768,7 @@ def on_hal_status_mode_manual(self, widget): self.last_key_event = None, 0 def on_hal_status_mode_mdi(self, widget): - print ("MDI Mode", self.tool_change) + LOG.debug("MDI Mode", self.tool_change) # if the edit offsets button is active, we do not want to change # pages, as the user may want to edit several axis values @@ -2869,7 +2819,7 @@ def on_hal_status_mode_mdi(self, widget): self.last_key_event = None, 0 def on_hal_status_mode_auto(self, widget): - print ("AUTO Mode") + LOG.debug("AUTO Mode") # if Auto button is not sensitive, we are not ready for AUTO commands # so we have to abort external commands and get back to manual mode # This will happen mostly, if we are in settings mode, as we do disable the mode button @@ -2898,7 +2848,7 @@ def on_hal_status_mode_auto(self, widget): self.last_key_event = None, 0 def on_hal_status_motion_mode_changed(self, widget, new_mode): - print("hal status motion mode changed") + LOG.debug("hal status motion mode changed") # Motion mode change in identity kinematics makes no sense # but we will react on the signal and correct the misbehavior # self.stat.motion_mode return @@ -2928,7 +2878,7 @@ def on_hal_status_motion_mode_changed(self, widget, new_mode): self._sensitize_widgets(widgetlist, state) def on_hal_status_metric_mode_changed(self, widget, metric_units): - print("hal status metric mode changed") + LOG.debug("hal status metric mode changed") # set gremlin_units self.widgets.gremlin.set_property("metric_units", metric_units) # unit switch could be done here if not done in combi_dro/_position() @@ -3033,7 +2983,7 @@ def on_window1_show(self, widget, data=None): # kill keyboard and estop machine before closing def on_window1_destroy(self, widget, data=None): - print("estoping / killing gmoccapy") + LOG.debug("estoping / killing gmoccapy") self._kill_dynamic_childs() # self._kill_keyboard() if self.onboard: @@ -3049,7 +2999,7 @@ def on_focus_out(self, widget, data=None): JOGMODE = self._get_jog_mode() for jnum in range(self.stat.joints): self.command.jog(linuxcnc.JOG_STOP, JOGMODE, jnum) - print("Stopped jogging on focus-out-event") + LOG.debug("Stopped jogging on focus-out-event") # What to do if a macro button has been pushed def _on_btn_macro_pressed( self, widget = None, data = None ): @@ -3061,7 +3011,7 @@ def _on_btn_macro_pressed( self, widget = None, data = None ): parameter = self.dialogs.entry_dialog(self, data=None, header=_("Enter value:"), label=_("Set parameter {0} to:").format(code), integer=False) if parameter == "ERROR": - print(_("conversion error")) + LOG.debug(_("conversion error")) self.dialogs.warning_dialog(self, _("Conversion error !"), ("Please enter only numerical values\nValues have not been applied")) return @@ -3107,7 +3057,7 @@ def _update_widgets(self, state): def _switch_to_g7(self, state): # we do this only if we have a lathe, the check for lathe is done in gmoccapy - print("switch to G7:", state) + LOG.debug("switch to G7:", state) if state: self.dro_dic["Combi_DRO_0"].set_property("abs_color", self._get_RGBA_color("#F2F1F0")) self.dro_dic["Combi_DRO_0"].set_property("rel_color", self._get_RGBA_color("#F2F1F0")) @@ -3183,12 +3133,12 @@ def on_key_event(self, widget, event, signal): # in this case we do not return true, otherwise entering code in MDI history # and the integrated editor will not work if not self.widgets.chk_use_kb_shortcuts.get_active(): - print("Settings say: do not use keyboard shortcuts, abort") + LOG.debug("Settings say: do not use keyboard shortcuts, abort") return # Only in MDI mode the RETURN key should execute a command if keyname == "Return" and signal and self.stat.task_mode == linuxcnc.MODE_MDI: - # print("Got enter in MDI") + # LOG.debug("Got enter in MDI") self.widgets.hal_mdihistory.submit() self.widgets.hal_mdihistory.entry.grab_focus() # we need to leave here, otherwise the check for jogging @@ -3236,7 +3186,7 @@ def on_key_event(self, widget, event, signal): if (keyname == "R" or keyname == "r") and self.stat.interp_state == linuxcnc.INTERP_IDLE: if event.state & Gdk.ModifierType.CONTROL_MASK: - print("R und Control gedrückt") + LOG.debug("R und Control gedrückt") self.widgets.hal_action_reload.emit("activate") else: self.command.auto(linuxcnc.AUTO_RUN,0) @@ -3339,7 +3289,7 @@ def on_key_event(self, widget, event, signal): if self.stat.state != 1: # still moving return # The active button name is hold in self.active_increment - print(self.active_increment) + LOG.debug(self.active_increment) rbt = int(self.active_increment.split("_")[1]) if keyname == "I": # so lets increment it by one @@ -3358,8 +3308,8 @@ def on_key_event(self, widget, event, signal): # and we have to update all pin and variables self._jog_increment_changed(self.incr_rbt_dic["rbt_{0}".format(rbt)]) else: - print("This key has not been implemented yet") - print("Key {0} ({1:d}) was pressed".format(keyname, event.keyval), signal, self.last_key_event) + LOG.info("This key has not been implemented yet") + LOG.info("Key {0} ({1:d}) was pressed".format(keyname, event.keyval), signal, self.last_key_event) self.last_key_event = keyname, signal return True @@ -3388,7 +3338,7 @@ def _from_internal_linear_unit(self, v, unit=None): return v * lu def _parse_increment(self, btn_name): - print("parse_jogincrement") + LOG.debug("parse_jogincrement") if self.incr_rbt_dic[btn_name] == self.incr_rbt_dic["rbt_0"]: jogincr = "0" else: @@ -3417,18 +3367,16 @@ def _parse_increment(self, btn_name): def show_try_errors(self): exc_type, exc_value, exc_traceback = sys.exc_info() formatted_lines = traceback.format_exc().splitlines() - print(_("**** GMOCCAPY ERROR ****")) - print(_("**** {0} ****").format(formatted_lines[0])) + LOG.error(_("{0}").format(formatted_lines[0])) traceback.print_tb(exc_traceback, limit=1, file=sys.stdout) - print (formatted_lines[-1]) + LOG.debug(formatted_lines[-1]) def _sensitize_widgets(self, widgetlist, value): for name in widgetlist: try: self.widgets[name].set_sensitive(value) except Exception as e: - print (_("**** GMOCCAPY ERROR ****")) - print(_("**** No widget named: {0} to sensitize ****").format(name)) + LOG.debug(_("No widget named: {0} to sensitize").format(name)) traceback.print_exc() def _update_active_gcodes(self): @@ -3548,8 +3496,8 @@ def _update_slider(self, widgetlist): self.rabbit_jog = self.rabbit_jog * self.faktor def _change_dro_color(self, property, color): - print(property) - print(color.red, color.green, color.blue, color.alpha) + LOG.debug(property) + LOG.debug(color.red, color.green, color.blue, color.alpha) for dro in self.dro_dic: self.dro_dic[dro].set_property(property, color) @@ -3613,7 +3561,7 @@ def _update_toolinfo(self, tool): self.command.wait_complete() def _set_enable_tooltips(self, value): - print("_set_enable_tooltips = ", value) + LOG.debug("_set_enable_tooltips = ", value) # this will hide the tooltips from the glade file widgets, # but not from the ones we created dynamically for widget in self.widgets_with_tooltips: @@ -3923,7 +3871,7 @@ def _on_btn_home_back_clicked(self, widget): def _on_btn_home_clicked(self, widget): # home axis or joint? - print("on button home clicked = ", widget.get_property("name")) + LOG.debug("on button home clicked = ", widget.get_property("name")) if "axis" in widget.get_property("name"): value = widget.get_property("name")[-1] # now get the joint from directory by the value @@ -4118,7 +4066,7 @@ def _set_spindle(self, command): elif command == "reverse": self.command.spindle(-1, rpm_out) else: - print(_("Something went wrong, we have an unknown spindle widget {0}").format(command)) + LOG.debug(_("Something went wrong, we have an unknown spindle widget {0}").format(command)) def _check_spindle_range(self): rpm = (self.stat.settings[2]) @@ -4237,7 +4185,6 @@ def on_btn_delete_clicked(self, widget, data=None): result = self.dialogs.yesno_dialog(self, message, _("Attention!!")) if result: self.widgets.hal_mdihistory.model.clear() - print(message) def on_btn_show_kbd_clicked(self, widget): #print("show Keyboard clicked", self.widgets.key_box.get_children()) @@ -4369,7 +4316,7 @@ def _on_btn_set_value_clicked(self, widget, data=None): else: axis = data - print("touch button clicked ",axis.upper()) + LOG.debug("touch button clicked ",axis.upper()) if self.lathe_mode and axis =="x": if self.diameter_mode: @@ -4387,7 +4334,7 @@ def _on_btn_set_value_clicked(self, widget, data=None): if offset == "CANCEL": return elif offset == "ERROR": - print(_("Conversion error in btn_set_value")) + LOG.debug(_("Conversion error in btn_set_value")) self.dialogs.warning_dialog(self, _("Conversion error in btn_set_value!"), _("Please enter only numerical values. Values have not been applied")) else: @@ -4494,7 +4441,7 @@ def on_theme_choice_changed(self, widget): #settings.set_string_property("Gtk-theme-name", theme, "") def _set_icon_theme(self, name): - print(f"Setting icon theme '{name}'") + LOG.debug(f"Setting icon theme '{name}'") if name is None or name == "none": # Switching to none required a restart (skip entire icon theme stuff) message = "Change to no icon theme requires a restart to take effect." @@ -4645,11 +4592,11 @@ def _set_icon_theme(self, name): image.set_from_pixbuf(pixbuf) image.set_size_request(size, size) except BaseException as err: - print(f"Warning: Failed to change icon for <{widget_name}> to '{icon_name}': {str(err)}") + LOG.warning(f"Failed to change icon for <{widget_name}> to '{icon_name}': {str(err)}") failed_icons += 1 if failed_icons > 0: - print(f"Warning: {failed_icons} icons failed to load! (Maybe the icon theme is incomplete?)") + LOG.warning(f"{failed_icons} icons failed to load! (Maybe the icon theme is incomplete?)") def on_icon_theme_choice_changed(self, widget): active = widget.get_active_iter() @@ -4804,7 +4751,7 @@ def _convert_color(self, color): return ('#' + ''.join(f'{i:02X}' for i in colortuple)) def on_chk_hide_tooltips_toggled(self, widget, data=None): - print("hide tooltips toggled") + LOG.debug("hide tooltips toggled") self.hide_tooltips = widget.get_active() self.prefs.putpref("hide_tooltips", self.hide_tooltips) self._set_enable_tooltips(not self.hide_tooltips) @@ -4905,7 +4852,7 @@ def on_btn_tool_clicked(self, widget, data=None): # Here we create a manual tool change dialog def on_tool_change(self, widget): - print("on tool change") + LOG.debug("on tool change") change = self.halcomp['toolchange-change'] toolnumber = self.halcomp['toolchange-number'] if change: @@ -4925,7 +4872,7 @@ def on_tool_change(self, widget): if result: self.halcomp["toolchange-changed"] = True else: - print("toolchange abort", self.stat.tool_in_spindle, self.halcomp['toolchange-number']) + LOG.debug("toolchange abort", self.stat.tool_in_spindle, self.halcomp['toolchange-number']) self.command.abort() self.halcomp['toolchange-number'] = self.stat.tool_in_spindle self.halcomp['toolchange-change'] = False @@ -5191,7 +5138,7 @@ def on_IconFileSelection1_sensitive(self, widget, buttonname, state): self.widgets[buttonname].set_sensitive(state) def on_IconFileSelection1_exit(self, widget): - print("exit icon file selection") + LOG.debug("exit icon file selection") self.widgets.ntb_preview.set_current_page(0) self.widgets.tbtn_fullsize_preview0.set_active(False) # self.widgets.tbtn_fullsize_preview1.set_active(False) @@ -5227,7 +5174,7 @@ def on_btn_edit_clicked(self, widget, data=None): self.widgets.tbtn_setup.set_sensitive(False) def on_gcode_view_changed(self, widget, state): - print("G-code view changed (modified: {})".format(state)) + LOG.debug("G-code view changed (modified: {})".format(state)) self.file_changed = state # Search and replace handling in edit mode @@ -5261,7 +5208,7 @@ def on_btn_redo_clicked(self, widget, data=None): # if we leave the edit mode, we will have to show all widgets again def on_ntb_button_switch_page(self, *args): - print("ntb_button_switch_page") + LOG.debug("ntb_button_switch_page") if self.widgets.ntb_preview.get_current_page() == 0: # preview tab is active, # check if offset tab is visible, if so we have to hide it page = self.widgets.ntb_preview.get_nth_page(1) @@ -5281,7 +5228,7 @@ def on_ntb_button_switch_page(self, *args): if self.widgets.ntb_button.get_current_page() == _BB_EDIT or \ self.widgets.ntb_preview.get_current_page() == _BB_HOME or \ self.widgets.ntb_preview.get_current_page() == _BB_LOAD_FILE: - print("we are in special case") + LOG.debug("we are in special case") self.widgets.ntb_preview.show() self.widgets.tbl_DRO.show() self.widgets.vbx_jog.set_size_request(360, -1) @@ -5499,14 +5446,14 @@ def _on_unlock_settings_changed(self, pin): self.widgets.tbtn_setup.set_sensitive(pin.get()) def _on_play_sound(self, widget, sound = None): - print(self,widget,sound) + LOG.debug(self,widget,sound) if _AUDIO_AVAILABLE and sound: if sound == "error": self.audio.set_sound(self.error_sound) elif sound == "alert": self.audio.set_sound(self.alert_sound) else: - print("got unknown sound to play") + LOG.debug("got unknown sound to play") return self.audio.run() @@ -5543,12 +5490,12 @@ def _on_pin_incr_changed(self, pin, buttonnumber): self.incr_rbt_dic[btn_name].set_active(True) def _on_pin_jog_changed(self, pin, button_name): - print("Jog Pin Changed") - print(button_name) + LOG.debug("Jog Pin Changed") + LOG.debug(button_name) if self.stat.kinematics_type != linuxcnc.KINEMATICS_IDENTITY: if self.stat.motion_mode == 1 and pin.get(): message = _("Axis jogging is only allowed in world mode, but you are in joint mode!") - print(message) + LOG.debug(message) self._show_error((13, message)) return @@ -5583,32 +5530,32 @@ def _button_pin_changed(self, pin): elif "v-button" in pin.name: location = "right" else: - print(_("Received a not classified signal from pin {0}".format(pin.name))) + LOG.debug(_("Received a not classified signal from pin {0}".format(pin.name))) return number = int(pin.name[-1]) if number is not number: - print(_("Could not translate {0} to number".format(pin.name))) + LOG.debug(_("Could not translate {0} to number".format(pin.name))) return button = self._get_child_button(location, number) if not button: - print(_("no button here")) + LOG.debug(_("no button here")) return elif button == -1: - print(_("the button is not sensitive")) + LOG.debug(_("the button is not sensitive")) return if type(button[0]) == Gtk.ToggleButton: button[0].set_active(not button[0].get_active()) - print(_("Button {0} has been toggled".format(button[1]))) + LOG.debug(_("Button {0} has been toggled".format(button[1]))) elif type(button[0]) == Gtk.RadioButton: button[0].set_active(True) button[0].emit("pressed") - print(_("Button {0} has been pressed".format(button[1]))) + LOG.debug(_("Button {0} has been pressed".format(button[1]))) else: button[0].emit("clicked") - print(_("Button {0} has been clicked".format(button[1]))) + LOG.debug(_("Button {0} has been clicked".format(button[1]))) # this handles the relation between hardware button and the software button def _get_child_button(self, location, number = None): @@ -5621,7 +5568,7 @@ def _get_child_button(self, location, number = None): elif location == "right": container = self.widgets.vbtb_main else: - print(_("got wrong location to locate the childs")) + LOG.debug(_("got wrong location to locate the childs")) children = container.get_children() hidden = 0 @@ -5783,12 +5730,60 @@ def _make_hal_pins(self): # ========================================================= if __name__ == "__main__": + # Set up the base logger + # We have do do this before importing other modules because on import + # they set up their own loggers as children of the base logger. + + # If log_file is none, logger.py will attempt to find the log file specified in + # INI [DISPLAY] LOG_FILE, failing that it will log to $HOME/.log + + # Note: In all other modules it is best to use the `__name__` attribute + # to ensure we get a logger with the correct hierarchy. + # Ex: LOG = logger.getLogger(__name__) + + from qtvcp import logger + LOG = logger.initBaseLogger('Gmoccapy', log_file=None, log_level=logger.WARNING) + + # we set the log level early so the imported modules get the right level + # The order is: VERBOSE, DEBUG, INFO, WARNING, ERROR, CRITICAL. + + if '-d' in sys.argv: + # Log level defaults to WARNING, so set lower if in debug mode + logger.setGlobalLevel(logger.DEBUG) + LOG.debug('DEBUGGING logging on') + elif '-i' in sys.argv: + # Log level defaults to WARNING, so set lower if in info mode + logger.setGlobalLevel(logger.INFO) + LOG.info('INFO logging on') + elif '-v' in sys.argv: + # Log level defaults to WARNING, so set lowest if in verbose mode + logger.setGlobalLevel(logger.VERBOSE) + LOG.verbose('VERBOSE logging on') + elif '-q' in sys.argv: + logger.setGlobalLevel(logger.ERROR) + + # Some of these libraries log when imported so logging level must already be set. + import gladevcp.makepins + from gladevcp.combi_dro import Combi_DRO # we will need it to make the DRO + from gmoccapy import widgets # a class to handle the widgets + from gmoccapy import notification # this is the module we use for our error handling + from gmoccapy import preferences # this handles the preferences + from gmoccapy import getiniinfo # this handles the INI File reading so checking is done in that module + from gmoccapy import dialogs # this takes the code of all our dialogs + from gmoccapy import icon_theme_helper + + # instantiate gmoccapy app = gmoccapy(sys.argv) + # get the INI path inifile = sys.argv[2] - print ("**** GMOCCAPY INFO : inifile = {0} ****:".format(sys.argv[2])) + + # find the POST_GUI HAL file path + LOG.debug("inifile = {0} :".format(sys.argv[2])) postgui_halfile = app.get_ini_info.get_postgui_halfile() - print ("**** GMOCCAPY INFO : postgui halfile = {0} ****:".format(postgui_halfile)) + + # run it depending on type + LOG.debug("postgui halfile = {0}".format(postgui_halfile)) if postgui_halfile is not None: for f in postgui_halfile: if f.lower().endswith('.tcl'): @@ -5797,5 +5792,6 @@ def _make_hal_pins(self): res = os.spawnvp(os.P_WAIT, "halcmd", ["halcmd", "-i", inifile, "-f", f]) if res: raise SystemExit(res) + # start the event loop Gtk.main() diff --git a/src/emc/usr_intf/gmoccapy/release_notes.txt b/src/emc/usr_intf/gmoccapy/release_notes.txt index 7d0afebd4cd..ed3b1470a69 100644 --- a/src/emc/usr_intf/gmoccapy/release_notes.txt +++ b/src/emc/usr_intf/gmoccapy/release_notes.txt @@ -1,6 +1,12 @@ +ver 3.4.2 + + New: + - Log levels can now be specified in the INI file (#2323, thanks Chris!) + - Swapped position of settings button with user tabs button + ver 3.4.1 - New features: + New: - added possibility for sourcing an user defined file (rcfile) - added option to use external CSS file