2025-08-05 14:38:54 +04:00

170 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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()