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

156 lines
5.5 KiB
Python

#!/usr/bin/env python3
"""
VFD Module Boilerplate Model
============================
Model for VFD (Variable Frequency Drive) modules with support for different horsepower ratings.
Supports 15, 20, and 30 HP variants.
"""
from typing import Optional, TYPE_CHECKING
import xml.etree.ElementTree as ET
from dataclasses import dataclass
from datetime import datetime
import os
if TYPE_CHECKING:
from excel_data_processor import ModuleData
@dataclass
class VFDModuleConfig:
"""Configuration for a VFD module instance."""
name: str # Module name (e.g., "VFD1")
hp: str # Horsepower rating: "15", "20", "30"
ip_address: str = "11.200.1.10"
parent_module: str = "SLOT2_EN4TR"
parent_port_id: str = "2"
class VFDModuleGenerator:
"""Generator for VFD module XML with different HP support."""
# Mapping of HP values to boilerplate filenames
HP_BOILERPLATE_MAP = {
"15": "VFD_Module_15_HP.L5X",
"20": "VFD_Module_20_HP.L5X",
"30": "VFD_Module_30_HP.L5X"
}
def __init__(self, config: VFDModuleConfig):
self.config = config
# Determine the correct boilerplate file
if self.config.hp not in self.HP_BOILERPLATE_MAP:
raise ValueError(f"Unsupported HP value: {self.config.hp}. Supported values: 15, 20, 30")
self.boilerplate_filename = self.HP_BOILERPLATE_MAP[self.config.hp]
self.boilerplate_path = os.path.join("boilerplate", self.boilerplate_filename)
self.tree = None
self.root = None
def load_boilerplate(self):
"""Load the appropriate boilerplate template based on HP rating."""
if not os.path.exists(self.boilerplate_path):
raise FileNotFoundError(f"Boilerplate file not found: {self.boilerplate_path}")
self.tree = ET.parse(self.boilerplate_path)
self.root = self.tree.getroot()
def update_module_name(self):
"""Update the module name throughout the XML."""
# Update in root attributes
self.root.set("TargetName", self.config.name)
# Update Module element
module = self.root.find(".//Module[@Use='Target']")
if module is not None:
module.set("Name", self.config.name)
def update_ip_address(self):
"""Update the IP address in the Ethernet port."""
port = self.root.find(".//Port[@Type='Ethernet']")
if port is not None:
port.set("Address", self.config.ip_address)
def update_parent_module(self):
"""Update parent module references."""
module = self.root.find(".//Module[@Use='Target']")
if module is not None:
module.set("ParentModule", self.config.parent_module)
module.set("ParentModPortId", self.config.parent_port_id)
def update_export_date(self):
"""Update the export date to current time."""
export_date = datetime.now().strftime("%a %b %d %H:%M:%S %Y")
self.root.set("ExportDate", export_date)
def apply_updates(self):
"""Apply all updates to the boilerplate."""
self.update_module_name()
self.update_ip_address()
self.update_parent_module()
self.update_export_date()
def save(self, output_path: str):
"""Save the updated module to file."""
if self.tree is None:
raise RuntimeError("No boilerplate loaded. Call load_boilerplate() first.")
# Save with proper formatting
self.tree.write(output_path, encoding='UTF-8', xml_declaration=True)
def get_xml_string(self) -> str:
"""Get the XML as a string."""
if self.tree is None:
raise RuntimeError("No boilerplate loaded. Call load_boilerplate() first.")
return ET.tostring(self.root, encoding='unicode')
# ------------------------------------------------------------------
# Helper for EnhancedMCMGenerator refactor
# ------------------------------------------------------------------
@classmethod
def from_excel(cls, module_data: 'ModuleData', hp: str) -> 'VFDModuleGenerator':
cfg = create_vfd_module(
name=module_data.tagname,
hp=hp,
ip_address=module_data.ip_address or "11.200.1.10",
parent_module="SLOT2_EN4TR",
parent_port_id="2",
)
gen = cls(cfg)
gen.load_boilerplate()
gen.apply_updates()
return gen
def create_vfd_module(name: str, hp: str, ip_address: str = "11.200.1.10",
parent_module: str = "SLOT2_EN4TR", parent_port_id: str = "2") -> VFDModuleConfig:
"""Factory function to create a VFD module configuration."""
return VFDModuleConfig(
name=name,
hp=hp,
ip_address=ip_address,
parent_module=parent_module,
parent_port_id=parent_port_id
)
# Example usage
if __name__ == "__main__":
# Example: Create a 15 HP VFD module
config = create_vfd_module(
name="VFD1_15HP",
hp="15", # Specify the horsepower
ip_address="11.200.1.10",
parent_module="SLOT2_EN4TR"
)
generator = VFDModuleGenerator(config)
generator.load_boilerplate()
generator.apply_updates()
generator.save("generated/VFD1_15HP.L5X")
print(f"Generated {config.hp} HP VFD module: {config.name}")