Files
Helmholtz_Test_Bench/config_handling.py
T
Martin Zietz f5dc7f097e cleanup and comments
user interface
2021-02-17 11:26:25 +01:00

132 lines
7.0 KiB
Python

# This file contains functions and variables related to reading and writing configuration files.
# The configparser module is used for processing. Config files are of type .ini
# import packages:
from configparser import ConfigParser
from tkinter import messagebox
# import other project files:
import globals as g
import cage_func as func
# noinspection PyPep8Naming
import User_Interface as ui
global CONFIG_FILE # string storing the path of the used config file
global CONFIG_OBJECT # object of type ConfigParser(), storing all configuration information
# CONFIG_OBJECT is what is mostly read/written by the program
# CONFIG_FILE is only used to export/import to/from a file
def get_config_from_file(file): # read a config file to a config_object
config_object = ConfigParser() # initialize config parser
config_object.read(file) # open config file
return config_object # return config object, that contains all info from the file
def write_config_to_file(config_object): # write contents of config object to a config file
with open(CONFIG_FILE, 'w') as conf: # Write changes to config file
config_object.write(conf)
def read_from_config(section, key, config_object): # read a specific value from a config object
try:
section_obj = config_object[section] # get relevant section
value = section_obj[key] # get relevant value in the section
return value
except KeyError as e: # a section or key was used, that does not exist
ui.ui_print("Error while reading config file:", e)
raise KeyError("Could not find key", key, "in config file.")
def edit_config(section, key, value, override=False): # edit a specific value in the CONFIG_OBJECT
# section: Section of the config, e.g. "X-Axis" or "PORTS"
# key: name of the value in the section, e.g. max_amps
# value: new value to be written into the config
# override: Bool to allow user to force writing a value into the config, even if it exceeds the safe limit
global CONFIG_OBJECT # get the global config object to edit it
# ToDo (optional): add check for data types, e.g. int for arduino ports
# Check if value to write is within acceptable limits (set in dictionary in globals.py):
try:
value_ok = 'OK'
if section in g.AXIS_NAMES and not override: # only check values in axis sections and not if check overridden
value_ok = func.value_in_limits(section, key, value) # check if value is ok, too high or too low
if value_ok == 'HIGH': # value is too high
max_value = g.default_arrays[key][1][g.AXIS_NAMES.index(section)] # get max value for message printing
message = "Prevented writing too high value for {s} {k} to config file:\n" \
"{v}, max. {mv} allowed. Erroneous values may damage equipment!" \
.format(s=section, k=key, v=value, mv=max_value)
raise ValueError(message) # return an error with the message attached
elif value_ok == 'LOW': # value is too low
min_value = g.default_arrays[key][2][g.AXIS_NAMES.index(section)] # get min value for message printing
message = "Prevented writing too low value for {s} {k} to config file:\n" \
"{v}, max. {mv} allowed. Erroneous values may damage equipment!" \
.format(s=section, k=key, v=value, mv=min_value)
raise ValueError(message) # return an error with the message attached
if value_ok == 'OK' or override: # value is within limits or user has overridden the checks
try:
section_obj = CONFIG_OBJECT[section] # get relevant section in the config
except KeyError: # there is no such section
ui.ui_print("Could not find section", section, "in config file, creating new.")
CONFIG_OBJECT.add_section(section) # create the missing section
section_obj = CONFIG_OBJECT[section] # get the object of the section
try:
section_obj[key] = str(value) # set value for correct entry in the section
except KeyError: # there is no entry with this key
ui.ui_print("Could not find key", key, "in config file, creating new.")
CONFIG_OBJECT.set(section, key, str(value)) # create the entry and set the value
except KeyError as e: # key for section or specific value does not exist in the dictionary for max/min values
ui.ui_print("Error while editing config file:", e)
raise KeyError("Could not find key", key, "in config file.") # return an error
def check_config(config_object): # check all numeric values in the config and see if they are within safe limits
ui.ui_print("Checking config file for values exceeding limits:")
concerns = {} # initialize dictionary for found problems
problem_counter = 0 # count the number of values that exceed limits
i = 0
for axis in g.AXIS_NAMES: # go through all 3 axes
concerns[axis] = [] # create dictionary entry for this axis
for key in g.default_arrays.keys(): # go over entries in this axis
value = float(read_from_config(axis, key, config_object)) # read value to check from config file
max_value = g.default_arrays[key][1][i] # get max value
min_value = g.default_arrays[key][2][i] # get min value
if not min_value <= value <= max_value: # value is not in safe limits
concerns[axis].append(key) # add this entry to the problem dictionary
problem_counter += 1
if len(concerns[axis]) == 0: # no problems were found for this axis
concerns[axis].append("No problems detected.")
ui.ui_print(axis, ":", *concerns[axis]) # print out results for this axis
i += 1
if problem_counter > 0: # some values are not ok
# shop pup-up warning message:
messagebox.showwarning("Warning!", "Found %i value(s) exceeding limits in config file. Check values "
"to ensure correct operation and avoid equipment damage!" % problem_counter)
g.app.show_frame(ui.Configuration) # open configuration window so user can check values
def reset_config_to_default(): # reset values in config object to defaults (set in globals.py)
config = ConfigParser() # reinitialize empty config object
global CONFIG_OBJECT # get the global config object
CONFIG_OBJECT = config # reset it to the empty object
i = 0
for axis_name in g.AXIS_NAMES: # go through axes
config.add_section(axis_name) # add section for this axis
for key in g.default_arrays.keys(): # go through dictionary with default values
config.set(axis_name, key, str(g.default_arrays[key][0][i])) # set values
i += 1
config.add_section("PORTS") # add section for PSU serial ports
for key in g.default_ports.keys(): # go through dictionary of default serial ports
config.set("PORTS", key, str(g.default_ports[key])) # set the value for each axis