7e76cffc88
- SettingsTab: chamber ID, master CSV mapping, wafer behavior toggle, light/dark mode toggle, Edit CSV Metadata dialog - StatusTab: connection status, wafer info, activity log (blank until Detect Wafer fires) - DataTab: empty state, ready for parsed data - HomePage: side rail buttons dispatch device actions and jump to Status tab; selectedSideActionIndex defaults to -1 (nothing active on startup) - DeviceController registered as QML context property in main.py - LocalSettings: added status persistence fields - Theme: added subheadingColor and disabledText - Added serialcomm/ package and backend data/graph modules - gitignore: added build/, dist/, *.spec
105 lines
3.4 KiB
Python
105 lines
3.4 KiB
Python
import json
|
|
import os
|
|
from pathlib import Path
|
|
|
|
|
|
# ===== Settings Persistence Model =====
|
|
class LocalSettings:
|
|
# ===== Defaults =====
|
|
def __init__(self):
|
|
# Configuration settings
|
|
self.chamber_id = ""
|
|
self.reverse_z_wafer = False
|
|
self.master = {} # Dict[str, str]
|
|
self.wafer_data_size = {} # Dict[str, int]
|
|
self.debug = False
|
|
self.wafer_read_retries = 8
|
|
# Timeout in msec for reading from the wafer (default 2 min)
|
|
self.wafer_read_timeout = 120000
|
|
self.wafer_detect_timeout = 5000
|
|
self.split_threshold = 40.0
|
|
|
|
# Status persistence (operational state)
|
|
self.connection_status = "Disconnected"
|
|
self.selected_port = ""
|
|
self.last_wafer_info = {} # Dict[str, Any]
|
|
self.save_data_dir = ""
|
|
self.activity_log = [] # List[str]
|
|
self.data_row_count = 0
|
|
self.data_col_count = 0
|
|
self.last_csv_path = ""
|
|
|
|
# ===== File Path Helpers =====
|
|
@classmethod
|
|
def _settings_path(cls, directory: str) -> Path:
|
|
return Path(directory) / "settings.json"
|
|
|
|
# ===== Load/Save =====
|
|
@classmethod
|
|
def read_settings(cls, directory: str) -> "LocalSettings":
|
|
"""Read settings from settings.json in the provided directory."""
|
|
settings = cls()
|
|
path = cls._settings_path(directory)
|
|
|
|
if not path.exists():
|
|
return settings
|
|
|
|
try:
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
for key, value in data.items():
|
|
if hasattr(settings, key):
|
|
setattr(settings, key, value)
|
|
except Exception as e:
|
|
print(f"Error reading setting file: {e}")
|
|
|
|
return settings
|
|
|
|
@classmethod
|
|
def save_settings(cls, directory: str, settings: "LocalSettings") -> None:
|
|
"""Save the current settings instance to settings.json."""
|
|
path = cls._settings_path(directory)
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
data = settings.__dict__.copy()
|
|
|
|
try:
|
|
with open(path, "w", encoding="utf-8") as f:
|
|
json.dump(data, f, indent=4)
|
|
except Exception as e:
|
|
print(f"Error saving settings: {e}")
|
|
|
|
# ===== Master File Helpers =====
|
|
@classmethod
|
|
def get_master(cls, directory: str, wtype: str) -> str:
|
|
"""Return the full path to a master file if it exists."""
|
|
settings = cls.read_settings(directory)
|
|
if wtype not in settings.master:
|
|
return ""
|
|
|
|
file_path = Path(directory) / settings.master[wtype]
|
|
if file_path.exists():
|
|
return str(file_path)
|
|
return ""
|
|
|
|
@classmethod
|
|
def set_master(cls, directory: str, wtype: str, filename: str) -> None:
|
|
"""Store a master filename for a wafer type and save settings."""
|
|
settings = cls.read_settings(directory)
|
|
settings.master[wtype] = os.path.basename(filename)
|
|
cls.save_settings(directory, settings)
|
|
|
|
# ===== Wafer Sizing =====
|
|
def get_wafer_data_size(self, wtype: str) -> int:
|
|
"""Return the expected transfer size in bytes for a wafer type."""
|
|
if not wtype:
|
|
return 393216
|
|
|
|
if wtype in self.wafer_data_size:
|
|
return self.wafer_data_size[wtype]
|
|
|
|
if wtype == "P":
|
|
return 393216
|
|
if wtype == "X":
|
|
return 1310720
|
|
return 393216
|