from setup import getfhxschema from setup import convertfhxtoxml filename = "R14102" root = convertfhxtoxml(filename) a = getfhxschema(root) print(a)
import xlsxwriter from setup import convertfhxtoxml from dv_parser import ExpressionParser from dv_interpreter import MMMInterpreter import re data = [] """To get all 3M interlocks and dump into approved documentation format""" source_filename = "A_423" params = open('outputs\\debug.txt', 'w') root = convertfhxtoxml(source_filename, forcerebuild=False) mods = root.findall(".//module_instance[@tag]") mods += root.findall(".//module[@tag]") # this is a critical expression to find any possible attributes that may be interlock related for class-based modules paths = re.compile(r'(AT\d)|(DCC\d)|(CND\d{1,2})') delay_ons = re.compile('(I|T)_DELAY_?ON(\d+)', re.IGNORECASE) expression = re.compile('(I|T)_EXP(\d+)', re.IGNORECASE) description = re.compile('(I|T)_DESC_?(\d+)', re.IGNORECASE) def add_ilk_info_to_database(node, regex_search, field_search, data_entry,
f = PROVOXpath.split('/')[0] c = PROVOXpath.split('/')[1] for card in root.findall(f): for channel in card.findall(c): for dst in channel.findall(analog): if dst.text is not None: IOinfo.writelines(','.join([ card.attrib['controller'], card.attrib['file'], card.attrib['card_slot'], channel.attrib['position'], dst.text ]) + '\n') if __name__ == '__main__': # steps to create the xml tree convertfhxtoxml() p = XMLParser() root = parse(xmlfile, parser=p) PROVOXIOInfo() # adds standard DSTs DSTs = { chm.text for chm in root.findall(charmpath + analog) if chm.text is not None } # adds SIS DSTs DSTs.update(chm.text for chm in root.findall(sischarmpath) if chm.text is not None) # adds HART DSTs DSTs.update([
def __init__(self, source_filename, *args): if type(args) != dict: self.format_type = dict() self.format_type['csv'] = True self.format_type['docx'] = False # self.format_type['obj'] = True self.options = dict() self.options['run_logic'] = True self.options['abort_logic'] = True self.options['stop_logic'] = True self.options['hold_logic'] = True self.options['restart_logic'] = True self.options['compile_all_logic'] = True self.options['classless_EM'] = True self.options['class_based_EM'] = True else: self.options = args # self.source_filename = "_EM_CIP_CTRL" self.source_filename = source_filename logic_lookup = dict() root = convertfhxtoxml(source_filename) unclassed_object = re.compile('__[\d\w]{8}_[\d\w]{8}__') fb_defs = root.findall('.//function_block_definition') sfcs = list(filter(lambda a: not a.find('[sfc_algorithm]') is None, fb_defs)) sfcs_to_test = set() # TODO handle other types of SFCs other than just phase run logic phase_classes = root.findall('.//batch_equipment_phase_class') module_instances = root.findall('.//module') module_classes = root.findall('.//module_class') def add_logic_to_list(composite_name): for phase in phase_classes: definition = phase.find(".//function_block[@name='" + composite_name + "']").attrib['definition'] sfcs_to_test.add(definition) if unclassed_object.match(definition): logic_lookup[definition] = phase.attrib['name'] if self.options['run_logic']: add_logic_to_list('RUN_LOGIC') if self.options['abort_logic']: add_logic_to_list('ABORT_LOGIC') if self.options['stop_logic']: add_logic_to_list('STOP_LOGIC') if self.options['hold_logic']: add_logic_to_list('HOLD_LOGIC') if self.options['restart_logic']: add_logic_to_list('RESTART_LOGIC') if self.options['classless_EM']: for module in module_instances: flag = module.find(".//is_equipment_module") if flag is not None and flag.text == "T": commands = module.find(".//command_set").text command_set = root.find(".//enumeration_set[@name='" + commands + "']") ns = populatenamedset(command_set) definitions = module.findall(".//function_block") for d in definitions: definition = d.attrib['definition'] if unclassed_object.match(definition) is not None: cmd_match = re.search('\d+', d.attrib['name']) if cmd_match is not None: command_num = int(cmd_match[0]) logic_lookup[definition] = module.attrib['tag'] + ':' + ns[command_num] sfcs_to_test.add(definition) else: break if self.options['class_based_EM']: for module in module_classes: # print(module.attrib['name']) flag = module.find(".//is_equipment_module") if flag is not None and flag.text == "T": commands = module.find(".//command_set") if commands is not None: # command driven EM commands = commands.text else: # state driven EM commands = module.find(".//state_set").text command_set = root.find(".//enumeration_set[@name='" + commands + "']") ns = populatenamedset(command_set) definitions = module.findall(".//function_block") for d in definitions: definition = d.attrib['definition'] if unclassed_object.match(definition) is not None: cmd_match = re.search('\d+', d.attrib['name']) if cmd_match is not None: command_num = int(cmd_match[0]) logic_lookup[definition] = module.attrib['name'] + ':' + ns[command_num] sfcs_to_test.add(definition) else: continue if self.options['compile_all_logic']: csv_all_actions = open('outputs\\' + source_filename + '_compiled_actions.csv', 'w', newline='') csv_all_transitions = open('outputs\\' + source_filename + '_compiled_transitions.csv', 'w', newline='') csv_writer_actions_a = csv.writer(csv_all_actions) csv_writer_trans_a = csv.writer(csv_all_transitions) csv_writer_actions_a.writerow(['object name', 'step name', 'action name', 'action description', 'action qualifier', 'action delay', 'action expression', 'action confirm']) csv_writer_trans_a.writerow( ['object name', 'transition name', 'transition description', 'condition', 'upstream connections', 'downstream connections']) # sfcs = list(filter(lambda a: unclassed_object.match(a.attrib['name']), sfcs)) # print(sfcs_to_test) idx = 0 for sfc in sfcs: sfc_id = sfc.attrib['name'] # print(sfc_id) common_name = sfc_id if sfc_id in sfcs_to_test: if sfc_id in logic_lookup.keys(): common_name = logic_lookup[sfc_id] idx +=1 # strip bad characters from filenames filename = ''.join(filter(lambda ch: ch not in "/", common_name)) # print("Parsing SFC {0} {1} of {2}".format(sfc.attrib['name'], sfcs.index(sfc) + 1, len(sfcs))) print("Parsing SFC {0} {1} of {2}".format(filename, idx, len(sfcs_to_test))) step_connections = sfc.findall('.//step_transition_connection') t_connections = sfc.findall('.//transition_step_connection') steps = sfc.findall('.//step') transitions = sfc.findall('.//transition') trans_conn_data = defaultdict(list) # parse transitions for transition in transitions: t_name = transition.attrib['name'] for tcs in t_connections: if t_name == tcs.attrib['transition']: trans_conn_data[t_name].append(tcs.attrib['step']) step_conn_data = defaultdict(list) for step in steps: s_name = step.attrib['name'] for scs in step_connections: if s_name == scs.attrib['step']: step_conn_data[s_name].append(scs.attrib['transition']) # # create the tables for action logic if self.format_type['docx']: doc = Document() action_column_headings = ['Step', 'Action', 'Delay', 'Action Expression', 'Confirm Expression'] transition_column_headings = ['Transition', 'Condition'] t = doc.add_table(rows=1, cols=len(action_column_headings)) header = t.rows[0].cells if self.format_type['csv']: csv_out_actions = open('outputs\\' + filename + '_actions.csv', 'w', newline='') csv_out_transitions = open('outputs\\' + filename + '_transitions.csv', 'w', newline='') csv_writer_actions = csv.writer(csv_out_actions) csv_writer_actions.writerow(['step name', 'action name', 'action description', 'action qualifier', 'action delay', 'action expression', 'action confirm']) csv_writer_trans = csv.writer(csv_out_transitions) csv_writer_trans.writerow( ['transition name', 'transition description', 'condition', 'upstream connections', 'downstream connections']) for tr in transitions: t_name = '' t_expression = '' t_previous = '' t_previous_all = [] t_description = '' t_name = tr.attrib['name'] if tr.find('.//expression') is not None: t_expression = tr.find('.//expression').text if tr.find('.//description') is not None: t_description = tr.find('.//description').text for s in step_conn_data.keys(): if t_name in step_conn_data[s]: t_previous_all.append(s) t_previous = ','.join(t_previous_all) t_next = ','.join(trans_conn_data[t_name]) if self.format_type['csv']: csv_writer_trans.writerow([t_name, t_description, t_expression, t_previous, t_next]) if self.options['compile_all_logic']: csv_writer_trans_a.writerow([common_name, t_name, t_description, t_expression, t_previous, t_next]) for step in steps: s_name = step.attrib['name'] actions = step.findall('.//action') action_index = 0 num_actions = len(actions) if self.format_type['docx']: for i in range(0, len(action_column_headings)): header[i].text = action_column_headings[i] first_cell = '' last_cell = '' for action in actions: a_name = action.attrib['name'] a_qualifier = '' a_delay = 'N/A' a_confirm = 'N/A' a_expression = action.find('.//expression').text # either delay expression or delay time if action.find('.//delay_time') is not None: a_delay = action.find('.//delay_time').text elif action.find('.//delay_expression') is not None: a_delay = action.find('.//delay_expression').text if action.find('.//qualifier') is not None: a_qualifier = action.find('.//qualifier').text if action.find('.//delay_time') is not None: a_delay = action.find('.//delay_time').text if action.find('.//confirm_expression') is not None: a_confirm = action.find('.//confirm_expression').text if action.find('.//description') is not None: a_description = action.find('.//description').text if self.format_type['csv']: csv_writer_actions.writerow([s_name, a_name, a_description, a_qualifier, a_delay, a_expression, a_confirm]) if self.options['compile_all_logic']: csv_writer_actions_a.writerow( [common_name, s_name, a_name, a_description, a_qualifier, a_delay, a_expression, a_confirm]) # make docx table if self.format_type['docx']: action_row = t.add_row().cells if action_index == 0: first_cell = action_row[0] action_row[0].text = s_name action_index += 1 if action_index == num_actions: last_cell = action_row[0] action_row[1].text = a_name action_row[2].text = a_delay action_row[3].text = a_expression action_row[4].text = a_confirm if action_index != 0: first_cell.merge(last_cell) t_header_row = t.add_row().cells t_header_row[1].merge(t_header_row[4]) for i in range(0, len(transition_column_headings)): t_header_row[i].text = transition_column_headings[i] for next_t in step_conn_data[s_name]: trans_row = t.add_row().cells trans_row[0].text = next_t my_expression = '' for tr in transitions: if tr.attrib['name'] == next_t: my_expression = tr.find('expression').text trans_row[1].text = my_expression trans_row[1].merge(trans_row[4]) else: print(sfc_id) if self.format_type['docx']: doc.save('outputs\\SFC_report.docx')
action[ 'comments'] += "Reference to the wrong step in delay. " if str(path_tokens[2]) != self.actions[ a - 1]['action name']: action[ 'comments'] += "Delay isn't referenced to the previous action. " def show_steps(self): pass def print_table(self): csv_out = "outputs\\" + csv_file + "_output.csv" with open(csv_out, 'w') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=self.actions[0].keys(), lineterminator='\n') writer.writeheader() for a in self.actions: writer.writerow(a) if __name__ == '__main__': fhx = 'PH_RX_NAOH_CLEAN' root = convertfhxtoxml(fhx) D = SFCDocumenter(fhx) csv_file = fhx + '_compiled' P = CodeDocumenter() P.give_datafiles(csv_file) P.check_against_rules() P.print_table()