from datetime import datetime import os.path import json #import latestVersion from io import IOBase _selected_location: dict | None = None _configured_data: dict | None = None def configure(config_data: dict) -> None: """Store the resolved (common + project merged) config so the next FCTMacro() instantiation uses it. Must be called (via customer_loader.resolve()) before customer_loader.import_worker() triggers any module that instantiates FCTMacro() at import time. """ global _configured_data _configured_data = config_data def update_location(location: str) -> None: """Resolve ems_location name to its ID (via config.json's mapping) and stash both.""" global _selected_location _selected_location = {"name": location, "id": None} def update_location_with_id(location_name: str, location_id: int) -> None: """Stash ems_location name and ID directly (ID sourced from API).""" global _selected_location _selected_location = {"name": location_name, "id": location_id} class FCTMacro: def __init__(self): #self.heartBeat = [b'\xdd', b'\xa6', b'\xbb', b'\x02', b'\x00', b'\x00', b'\xff', b'C', b'w'] if _configured_data is None: raise RuntimeError( "No product config loaded.\n" "Call FCTMacro.configure(config_data) before importing any module\n" "that instantiates FCTMacro() (e.g. via customer_loader.import_worker)." ) dataConfig = _configured_data self.TestMode = dataConfig["TestMode"] self.DUMMY_QR_NUMBER = dataConfig.get("DUMMY_QR_NUMBER", "") self.SOC_COMMIT_ID = dataConfig["SOC_COMMIT_ID"] self.CUSTOMER_NAME = dataConfig["fct_info"].get("Customer Name") self.SOC_SW_VERSION = dataConfig["fct_info"].get("Software Version") # self.S_HW_VERSION = dataConfig.get("Power_Board_Version") self.SOC_LOGIC_HW_VERSION = dataConfig["fct_info"].get("Hardware Version") self.PCB_TYPE =dataConfig.get("PCB_TYPE","SOC") self.DELAY = dataConfig.get("DELAY_AFTER_POWER_ON_OFF", 5) self.DELAY_RELAY_OFF = dataConfig.get("DELAY_RELAY_OFF", 3) self.PRODUCT = dataConfig.get("PCB_TYPE", "SOC") self.PROCESS = dataConfig.get("PROCESS", "FCT") self.CUSTOMER_NAME = dataConfig.get("fct_info").get("Customer Name") self.PROCESS_LOGS_CONFIG = dataConfig.get("PROCESS_LOGS_CONFIG") self.PROCESS_CONFIG = dataConfig.get("PROCESS_CONFIG") if _selected_location is not None: location_id = _selected_location["id"] if location_id is None: mapping_raw = self.PROCESS_CONFIG.get("LOCATION_NAME_TO_ID_MAPPING", {}) mapping = {k.lower(): v for k, v in mapping_raw.items()} location_id = mapping.get(_selected_location["name"].lower(), 0) self.PROCESS_CONFIG["LOCATION_NAME"] = _selected_location["name"] self.PROCESS_CONFIG["LOCATION_ID"] = location_id self.SAVE_LOGS_PASS_MESSAGE = self.PROCESS_LOGS_CONFIG["SAVE_LOGS_PASS_MESSAGE"] self.SAVE_LOGS_FAIL_MESSAGE = self.PROCESS_LOGS_CONFIG["SAVE_LOGS_FAIL_MESSAGE"] self.SOC_ID_LENGTH = dataConfig.get("SOC_ID_LENGTH", 13) Mode = { "SOC": 1 } self.PDI_MODE = Mode[dataConfig.get("PCB_TYPE","SOC")] """Test array is defined per-project in Final/Projects//config.json under TEST_ARRAY.""" self.TEST_ARRAY_SOC = list(dataConfig["TEST_ARRAY"]) if self.TestMode == 1: try: self.TEST_ARRAY_SOC.remove("DisplayTest") self.TEST_ARRAY_SOC.remove("ButtonTest") self.TEST_ARRAY_SOC.remove("BuzzerTest") except Exception: pass self.SOC_TEST_BAT_SCRIPT = os.path.abspath(dataConfig.get("SOC_TEST_BATSCRIPT")) self.SOC_TEST_WORKING_DIR = os.path.dirname(self.SOC_TEST_BAT_SCRIPT) self.SOC_CUSTOMER_BAT_SCRIPT = os.path.abspath(dataConfig.get("SOC_CUSTOMER_BATSCRIPT")) self.SOC_CUSTOMER_WORKING_DIR = os.path.dirname(self.SOC_CUSTOMER_BAT_SCRIPT) self.SOC_KNOWN_VOLTAGE=dataConfig.get("SOC_KNOWN_VOLTAGE",52.4) self.SOC_VOLTAGE_THRESHOLD = dataConfig.get("SOC_VOLTAGE_THRESHOLD",0.5) self.BuckFiveVolt=21 self.IsolatorFiveVolt=22 self.MCUSupply =23 self.Enable_46V_Relay =30 self.Disable_46V_Relay =31 self.Enable_42V_Relay =32 self.Disable_42V_Relay =33 self.Relay_Off =29 self.Relay_On = 28 self.DBC_LOCATION = "../Final/common/DBC/DBC_Used_By_Application.dbc" # PID and VID values self.PID_SCANNER = dataConfig["PID_SCANNER"] self.VID_SCANNER = dataConfig["VID_SCANNER"] self.tenmaLoad_PID = 0x5011 self.tenmaLoad_VID = 0x0416 self.FCTBoard_PID = 0x5740 #0x22CE self.FCTBoard_VID = 0x0483 self.CAN_BUS_VID = 0X0FE5# self.CAN_BUS_PID = 0XCB65 #0xA455 self.PC_ID = 0x69#0x45 #for soc we've changed self.CAN_ID = 0x10 self.DB_PC_ID = 0x65 """Charger IDs""" # self.PC_ID=0x91 self.CHARGER_DIAG_MESSAGE_CAN_ID= 0x1FB #0X1FF #511 self.CHARGER_DIAG_RECIEVING_CAN_ID = 0X1FA self.ALL_OK = 0 self.REQUEST_DENIED = 2 self.TEST_FAIL = 3 self.TEST_PASS = 1 '''Parallel Testing changes''' try: a = [dataConfig.get("PCB1",None)[0].get(i,None) for i in ["J-link","FCT","CAN","TENMA","pcb"]] b =[dataConfig.get("PCB2",None)[0].get(i,None) for i in ["J-link","FCT","CAN","TENMA","pcb"]] self.PCB1 ={"J-link":a[0],"FCT":a[1],"CAN":a[2],"TENMA":a[3],"pcb":a[4]} self.PCB2 ={"J-link":b[0],"FCT":b[1],"CAN":b[2],"TENMA":b[3],"pcb":b[4]} except TypeError: self.PCB1=None self.PCB2=None self.DEFAULT_REQUEST_TIMEOUT = 1 #In seconds self.CAN_READ_COUNT = 5 self.TEST_COUNT = len(self.TEST_ARRAY_SOC) self.TEST_ARRAY = self.TEST_ARRAY_SOC[0:self.TEST_COUNT]