170 lines
6.8 KiB
Python
170 lines
6.8 KiB
Python
#!/usr/bin/env python3
|
||
"""generate_all.py – build SafetyProgram L5X, MainProgram L5X, full tag CSV, and safety-tag mapping.
|
||
|
||
This is the updated version using the new configuration and logging systems.
|
||
Run from repository root:
|
||
python generate_all.py [options]
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
import sys
|
||
import argparse
|
||
|
||
# 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))
|
||
|
||
# Import new configuration and logging systems
|
||
from src.config import GeneratorConfig, get_config, set_config
|
||
from src.logging_config import setup_logging, get_logger, FileOperationContext
|
||
|
||
# Import existing generators and writers (these will be updated in later phases)
|
||
from src.generators.main_program import LimitedMainProgramGenerator as MainProgramGenerator
|
||
from src.generators.safety_program import LimitedSafetyProgramGenerator as SafetyProgramGenerator
|
||
from src.data_loader import DataLoader
|
||
from src.writers.csv_writer import create_limited_csv_with_tags
|
||
from src.writers.mapping_writer import create_safety_tag_mapping
|
||
|
||
def main() -> None:
|
||
parser = argparse.ArgumentParser(description="Generate safety-focused PLC program")
|
||
parser.add_argument(
|
||
'--config',
|
||
type=Path,
|
||
default=Path(__file__).parent.parent / 'generator_config.json',
|
||
help='Configuration file path'
|
||
)
|
||
parser.add_argument(
|
||
'--excel-file',
|
||
type=Path,
|
||
help='Override Excel file path from config'
|
||
)
|
||
parser.add_argument(
|
||
'--output-dir',
|
||
type=Path,
|
||
help='Override output directory from config'
|
||
)
|
||
parser.add_argument(
|
||
'--log-level',
|
||
choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'],
|
||
default='INFO',
|
||
help='Set logging level'
|
||
)
|
||
parser.add_argument(
|
||
'--log-file',
|
||
type=Path,
|
||
help='Optional log file path'
|
||
)
|
||
parser.add_argument(
|
||
'--desc-ip-mode',
|
||
action='store_true',
|
||
help='Legacy flag - DESC_IP mode is now the default'
|
||
)
|
||
args = parser.parse_args()
|
||
|
||
# Setup logging first
|
||
setup_logging(
|
||
level=args.log_level,
|
||
log_file=args.log_file,
|
||
use_colors=True
|
||
)
|
||
logger = get_logger(__name__)
|
||
|
||
try:
|
||
logger.info("=== Starting PLC Generation Process ===")
|
||
|
||
# Load configuration
|
||
logger.debug("Loading configuration", config_file=str(args.config))
|
||
config = GeneratorConfig.from_file(args.config)
|
||
|
||
# Override config with command line arguments
|
||
if args.excel_file:
|
||
config.files.excel_file = args.excel_file
|
||
logger.debug("Overridden Excel file", file_path=str(args.excel_file))
|
||
|
||
if args.output_dir:
|
||
config.files.output_dir = args.output_dir
|
||
logger.debug("Overridden output directory", output_dir=str(args.output_dir))
|
||
|
||
# Set global config
|
||
set_config(config)
|
||
|
||
# Validate Excel file exists
|
||
if not config.files.excel_file.exists():
|
||
logger.error("Excel file not found", file_path=str(config.files.excel_file))
|
||
sys.exit(1)
|
||
|
||
logger.info("Configuration loaded",
|
||
excel_file=str(config.files.excel_file),
|
||
controller_name=config.xml.controller_name)
|
||
|
||
# Show deprecation warning for desc-ip-mode flag
|
||
if args.desc_ip_mode:
|
||
logger.warning("--desc-ip-mode flag is deprecated. DESC_IP extraction is now the default mode.")
|
||
|
||
# Safety program generation
|
||
with FileOperationContext(logger, "SafetyProgram generation", config.files.safety_l5x):
|
||
safety_gen = SafetyProgramGenerator(config.files.excel_file)
|
||
safety_gen.write(config.files.safety_l5x)
|
||
logger.info("SafetyProgram generation completed", output_file=config.files.safety_l5x)
|
||
|
||
# Main program generation
|
||
logger.info("Starting MainProgram generation", stage="main_generation")
|
||
with FileOperationContext(logger, "MainProgram generation", config.files.main_l5x):
|
||
main_gen = MainProgramGenerator(config.files.excel_file)
|
||
main_gen.write(config.files.main_l5x)
|
||
logger.info("MainProgram generation completed", output_file=config.files.main_l5x)
|
||
|
||
# Generate CSV tags
|
||
logger.progress("csv_generation", "Starting CSV tags generation")
|
||
if not config.files.original_csv.exists():
|
||
logger.warning("Original CSV file not found, skipping CSV generation",
|
||
file_path=str(config.files.original_csv))
|
||
else:
|
||
with FileOperationContext(logger, "CSV generation", config.files.complete_csv):
|
||
beacon_so_tags = create_limited_csv_with_tags(
|
||
config.files.excel_file,
|
||
config.files.original_csv,
|
||
config.files.complete_csv
|
||
)
|
||
logger.info("CSV generation completed",
|
||
output_file=config.files.complete_csv,
|
||
beacon_tags=len(beacon_so_tags) if beacon_so_tags else 0)
|
||
|
||
# Generate Safety Tag Mapping
|
||
logger.progress("mapping_generation", "Starting safety tag mapping generation")
|
||
with FileOperationContext(logger, "Safety mapping generation", config.files.mapping_txt):
|
||
# Load data for safety tag extraction
|
||
loader = DataLoader.from_excel(config.files.excel_file)
|
||
safety_tags = loader.safety_tags_from_pb
|
||
|
||
logger.data_stats("safety_tags", len(safety_tags))
|
||
|
||
create_safety_tag_mapping(
|
||
safety_tags,
|
||
set(), # No beacon SO tags in limited mode
|
||
set(), # No beacon SFT tags in limited mode
|
||
config.files.mapping_txt
|
||
)
|
||
|
||
logger.info("Safety tag mapping completed",
|
||
output_file=config.files.mapping_txt,
|
||
safety_tag_count=len(safety_tags))
|
||
|
||
logger.info("=== PLC Generation Process Completed Successfully ===")
|
||
logger.info("Generated files:",
|
||
safety_l5x=config.files.safety_l5x,
|
||
main_l5x=config.files.main_l5x,
|
||
csv_file=config.files.complete_csv,
|
||
mapping_file=config.files.mapping_txt)
|
||
|
||
except Exception as e:
|
||
logger.error("Generation process failed", exception=str(e))
|
||
if args.log_level == 'DEBUG':
|
||
logger.exception("Full traceback")
|
||
sys.exit(1)
|
||
|
||
|
||
if __name__ == '__main__':
|
||
main() |