142 lines
5.0 KiB
Python
142 lines
5.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Generate MainProgram with DPM routines from DESC_IP data.
|
|
|
|
This script creates a complete MainProgram.L5X file with:
|
|
- R000_SAFETY_TAG_MAP routine
|
|
- R020_DPM routine (with AOI_DPM calls)
|
|
- R100_ESTOP_CHECK routine
|
|
- Complete controller tags
|
|
|
|
Usage:
|
|
python generate_main_with_dpm.py --desc-ip-mode
|
|
python generate_main_with_dpm.py --desc-ip-mode --project-name MTN6_MCM05_CHUTE_LOAD
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# If repo root is current dir, add nested "src" folder to sys.path
|
|
pkg_dir = Path(__file__).resolve().parent / "src"
|
|
if pkg_dir.is_dir():
|
|
sys.path.insert(0, str(pkg_dir))
|
|
|
|
from src.generators import FullMainProgramGenerator, LimitedSafetyProgramGenerator
|
|
|
|
|
|
def parse_args():
|
|
"""Parse command line arguments."""
|
|
parser = argparse.ArgumentParser(
|
|
description="Generate MainProgram L5X with DPM routines from DESC_IP data"
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--desc-ip-mode',
|
|
action='store_true',
|
|
help='Use DESC_IP extraction mode (default: true for this script)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--project-name',
|
|
type=str,
|
|
help='Project name for output files (e.g., MTN6_MCM05_CHUTE_LOAD)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--ignore-estop1ok',
|
|
action='store_true',
|
|
help='Ignore ESTOP1_OK validation errors'
|
|
)
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
def main():
|
|
"""Generate MainProgram and SafetyProgram L5X files with DPM routines."""
|
|
args = parse_args()
|
|
|
|
print("=== MainProgram Generator with DPM Routines ===")
|
|
print("Using DESC_IP extraction mode for device data")
|
|
|
|
# Use DESC_IP_MERGED.xlsx from current directory
|
|
excel_file = Path("DESC_IP_MERGED.xlsx")
|
|
|
|
if not excel_file.exists():
|
|
print(f"ERROR: {excel_file} not found in current directory")
|
|
print("Please ensure DESC_IP_MERGED.xlsx is available")
|
|
sys.exit(1)
|
|
|
|
print(f"Using Excel file: {excel_file}")
|
|
|
|
# Load zones configuration based on project type
|
|
zones_dict = None
|
|
try:
|
|
# Add parent directory to sys.path to find zones_config.py
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
from zones_config import ZONES_CONFIGS, DEFAULT_ZONES
|
|
|
|
# Detect project type from project name argument
|
|
import re
|
|
|
|
if args.project_name:
|
|
mcm_match = re.search(r"(MCM\d+)", args.project_name, re.IGNORECASE)
|
|
if mcm_match:
|
|
mcm_type = mcm_match.group(1).upper()
|
|
zones_dict = ZONES_CONFIGS.get(mcm_type, DEFAULT_ZONES)
|
|
print(f"Detected {mcm_type} project from '{args.project_name}', loaded {len(zones_dict)} zones from zones_config.py")
|
|
else:
|
|
zones_dict = DEFAULT_ZONES
|
|
print(f"No MCM type detected in '{args.project_name}', loaded {len(zones_dict)} default zones from zones_config.py")
|
|
else:
|
|
zones_dict = DEFAULT_ZONES
|
|
print(f"No project name provided, loaded {len(zones_dict)} default zones from zones_config.py")
|
|
except ImportError as e:
|
|
print(f"Warning: Could not load zones_config.py: {e}")
|
|
print("Proceeding without zones configuration...")
|
|
|
|
try:
|
|
# Generate MainProgram with DPM routines
|
|
print("\n--- Generating MainProgram L5X ---")
|
|
main_generator = FullMainProgramGenerator(excel_path=excel_file, zones_dict=zones_dict)
|
|
|
|
# Determine output filename
|
|
if args.project_name:
|
|
main_output = f"MainProgram_{args.project_name}.L5X"
|
|
safety_output = f"SafetyProgram_{args.project_name}.L5X"
|
|
else:
|
|
main_output = "MainProgram_Generated.L5X"
|
|
safety_output = "SafetyProgram_Generated.L5X"
|
|
|
|
main_generator.write(main_output)
|
|
print(f"SUCCESS: MainProgram written to {main_output}")
|
|
|
|
# Generate SafetyProgram
|
|
print("\n--- Generating SafetyProgram L5X ---")
|
|
safety_generator = LimitedSafetyProgramGenerator(excel_path=excel_file, zones_dict=zones_dict, ignore_estop1ok=args.ignore_estop1ok)
|
|
safety_generator.write(safety_output)
|
|
print(f"SUCCESS: SafetyProgram written to {safety_output}")
|
|
|
|
print("\n=== Generation Complete ===")
|
|
print(f"Generated files:")
|
|
print(f" • {main_output}")
|
|
print(f" • {safety_output}")
|
|
|
|
# Summary of generated content
|
|
print(f"\nMainProgram includes:")
|
|
print(f" • R000_SAFETY_TAG_MAP routine")
|
|
print(f" • R020_DPM routine with AOI_DPM calls")
|
|
print(f" • R100_ESTOP_CHECK routine")
|
|
print(f" • Complete controller tags")
|
|
|
|
except Exception as e:
|
|
print(f"ERROR: Generation failed: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |