149 lines
6.6 KiB
Python
149 lines
6.6 KiB
Python
import pandas as pd
|
|
import os
|
|
import sys
|
|
import re
|
|
|
|
from io_paths import load_io_path_mappings
|
|
from process import process_data
|
|
from post_process import post_process_io_data
|
|
|
|
def create_desc_ip_sheet():
|
|
# Get Excel file path from command line arguments
|
|
if len(sys.argv) < 2:
|
|
print("Usage: python main.py <excel_file_path>")
|
|
sys.exit(1)
|
|
|
|
excel_file = sys.argv[1]
|
|
|
|
if not os.path.exists(excel_file):
|
|
print(f"CRITICAL: Excel file not found: {excel_file}")
|
|
sys.exit(1)
|
|
|
|
# Load IO path mappings
|
|
print("Loading IO path mappings...")
|
|
apf_df, m12dr_df, hub_df, sorter_hub_df, sio_df, ib16_df, ob16e_df, ib16s_df = load_io_path_mappings()
|
|
|
|
try:
|
|
# Read Excel file to check available sheets
|
|
xl = pd.ExcelFile(excel_file)
|
|
print(f"Available sheets: {xl.sheet_names}")
|
|
|
|
# Try to find sheets with similar names
|
|
desc_sheet = None
|
|
network_sheet = None
|
|
|
|
for sheet in xl.sheet_names:
|
|
if 'DESC' in sheet.upper():
|
|
desc_sheet = sheet
|
|
if 'NETWORK' in sheet.upper():
|
|
network_sheet = sheet
|
|
|
|
print(f"Found DESC sheet: {desc_sheet}")
|
|
print(f"Found NETWORK sheet: {network_sheet}")
|
|
|
|
if not desc_sheet or not network_sheet:
|
|
print("CRITICAL: Required sheets 'DESC...' and 'NETWORK...' not found in the Excel file.")
|
|
sys.exit(1)
|
|
|
|
# Read the sheets
|
|
desc_df = pd.read_excel(xl, sheet_name=desc_sheet)
|
|
network_df = pd.read_excel(xl, sheet_name=network_sheet)
|
|
|
|
print(f"\nDESC columns: {list(desc_df.columns)}")
|
|
print(f"NETWORK columns: {list(network_df.columns)}")
|
|
|
|
# Sort network data by PartNumber, DPM, and then Name
|
|
network_df['PartNumber'] = network_df['PartNumber'].fillna('') # Handle NaN in PartNumber
|
|
network_df['DPM'] = network_df['DPM'].fillna('') # Handle NaN in DPM
|
|
network_df = network_df.sort_values(by=['PartNumber', 'DPM', 'Name'])
|
|
|
|
# Process the data based on user requirements
|
|
process_data(
|
|
desc_df,
|
|
network_df,
|
|
excel_file,
|
|
apf_df,
|
|
m12dr_df,
|
|
hub_df,
|
|
sorter_hub_df,
|
|
sio_df,
|
|
ib16_df,
|
|
ob16e_df,
|
|
ib16s_df
|
|
)
|
|
|
|
# Determine subsystem (e.g. MCM04) from the Excel file path so that
|
|
# we reference the exact file produced in process_data
|
|
subsystem_match = re.search(r"(MCM\d+)", excel_file, re.IGNORECASE)
|
|
subsystem = subsystem_match.group(1).upper() if subsystem_match else "MCM"
|
|
|
|
# Now run post-processing on the freshly generated workbook
|
|
new_file = f"{subsystem}_DESC_IP_MERGED.xlsx"
|
|
output_file = f"{subsystem}_OUTPUT.csv"
|
|
post_process_io_data(new_file, output_file)
|
|
|
|
# Copy the output file to the standard name expected by streamlined generator
|
|
import shutil
|
|
if os.path.exists(new_file):
|
|
shutil.copy2(new_file, "DESC_IP_MERGED.xlsx")
|
|
print(f"Created standard output file: DESC_IP_MERGED.xlsx")
|
|
|
|
# Add minimal safety sheets for Routines Generator compatibility
|
|
print("Adding minimal safety sheets for Routines Generator...")
|
|
with pd.ExcelWriter("DESC_IP_MERGED.xlsx", mode='a', if_sheet_exists='replace') as writer:
|
|
# Create minimal empty safety sheets that LimitedDataLoader expects
|
|
# Note: These are minimal empty sheets - the actual safety devices will be extracted from DESC_IP
|
|
empty_rst = pd.DataFrame(columns=['TAGNAME', 'DESCA', 'IO_PATH', 'TERM'])
|
|
empty_sto = pd.DataFrame(columns=['TAGNAME', 'DESCA', 'IO_PATH', 'TERM'])
|
|
empty_epc = pd.DataFrame(columns=['TAGNAME', 'DESCA', 'IO_PATH', 'TERM'])
|
|
|
|
# Load zones configuration from zones_config.py
|
|
print("Loading zones configuration...")
|
|
try:
|
|
# Import zones configuration
|
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../')
|
|
from zones_config import ZONES_CONFIGS, DEFAULT_ZONES
|
|
|
|
# Determine which zones configuration to use based on subsystem
|
|
if subsystem in ZONES_CONFIGS:
|
|
zones_config = ZONES_CONFIGS[subsystem]
|
|
print(f"Using {subsystem} zones configuration")
|
|
else:
|
|
zones_config = DEFAULT_ZONES
|
|
print(f"Using default zones configuration (subsystem {subsystem} not found)")
|
|
|
|
# Convert zones configuration to DataFrame format
|
|
zone_data = []
|
|
for zone_config in zones_config:
|
|
zone_data.append({
|
|
'name': zone_config.get('name', ''),
|
|
'start': zone_config.get('start', ''),
|
|
'stop': zone_config.get('stop', ''),
|
|
'interlock': zone_config.get('interlock', '')
|
|
})
|
|
|
|
zones_df = pd.DataFrame(zone_data)
|
|
print(f"Loaded {len(zone_data)} zones: {[z['name'] for z in zone_data]}")
|
|
|
|
except ImportError as e:
|
|
print(f"Warning: Could not load zones_config.py ({e}), falling back to minimal MCM zone")
|
|
# Fallback to minimal MCM zone if zones_config.py is not available
|
|
zones_df = pd.DataFrame([{
|
|
'name': 'MCM',
|
|
'start': 'MCM_S_PB',
|
|
'stop': 'MCM_EPB_STATUS',
|
|
'interlock': ''
|
|
}])
|
|
|
|
empty_rst.to_excel(writer, sheet_name='RST', index=False)
|
|
empty_sto.to_excel(writer, sheet_name='STO', index=False)
|
|
empty_epc.to_excel(writer, sheet_name='EPC', index=False)
|
|
zones_df.to_excel(writer, sheet_name='ZONES', index=False)
|
|
print("Added empty RST, STO, EPC, and configured ZONES sheets")
|
|
|
|
except Exception as e:
|
|
print(f"Error occurred during processing: {e}")
|
|
sys.exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
create_desc_ip_sheet() |