Better version with support of multiple projects
This commit is contained in:
parent
322d662011
commit
12a85c2fc3
@ -4,3 +4,4 @@ node_modules/
|
||||
pycache/
|
||||
cloned_repo/
|
||||
extracted_texts/
|
||||
projects/
|
||||
|
||||
BIN
__pycache__/config.cpython-313.pyc
Normal file
BIN
__pycache__/config.cpython-313.pyc
Normal file
Binary file not shown.
BIN
__pycache__/drawing_checker.cpython-313.pyc
Normal file
BIN
__pycache__/drawing_checker.cpython-313.pyc
Normal file
Binary file not shown.
BIN
__pycache__/manifest_reader.cpython-313.pyc
Normal file
BIN
__pycache__/manifest_reader.cpython-313.pyc
Normal file
Binary file not shown.
BIN
__pycache__/progress_calculator.cpython-313.pyc
Normal file
BIN
__pycache__/progress_calculator.cpython-313.pyc
Normal file
Binary file not shown.
BIN
__pycache__/scada_checker.cpython-313.pyc
Normal file
BIN
__pycache__/scada_checker.cpython-313.pyc
Normal file
Binary file not shown.
BIN
__pycache__/utils.cpython-313.pyc
Normal file
BIN
__pycache__/utils.cpython-313.pyc
Normal file
Binary file not shown.
851
app.py
851
app.py
@ -3,541 +3,512 @@ import threading
|
||||
import time
|
||||
import json
|
||||
import git
|
||||
import csv
|
||||
import re
|
||||
from flask import Flask, render_template, jsonify, Response
|
||||
import re # Import re for project name validation
|
||||
from flask import Flask, render_template, jsonify, Response, request # Add request
|
||||
from werkzeug.utils import secure_filename # For securing filenames
|
||||
from concurrent.futures import ThreadPoolExecutor # Import ThreadPoolExecutor
|
||||
|
||||
# Import configurations and new modules
|
||||
import config
|
||||
import utils
|
||||
from manifest_reader import read_manifest
|
||||
from scada_checker import check_scada
|
||||
from drawing_checker import check_drawings
|
||||
from progress_calculator import calculate_combined_progress
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# --- Configuration ---
|
||||
REPO_URL = "http://192.168.5.191:3000/LCI/MTN6"
|
||||
REPO_DIR = "./cloned_repo" # Directory to clone the repo into
|
||||
BRANCH = "main"
|
||||
CSV_FILENAME = "MTN6 Equipment Manifest REV6(Conveyor List).csv"
|
||||
VIEWS_DIR_RELATIVE = "MTN6_SCADA/com.inductiveautomation.perspective/views/Detailed-Views"
|
||||
TEXT_OUTPUT_FOLDER = "./extracted_texts" # Added: Directory with .txt files
|
||||
CHECK_INTERVAL_SECONDS = 60
|
||||
# --- Global state (Per-Project) ---
|
||||
# Dictionaries keyed by project name
|
||||
project_last_commit = {}
|
||||
project_progress_data = {}
|
||||
project_status = {}
|
||||
all_projects = utils.discover_projects() # Discover projects at startup
|
||||
|
||||
# --- Column Names from CSV (Adjust if necessary) ---
|
||||
CSV_ALIAS_COL = 'Alias'
|
||||
CSV_PANEL_COL = 'Control Panel'
|
||||
CSV_EQ_TYPE_COL = 'Equipment Type' # Optional, for details modal
|
||||
CSV_CONV_TYPE_COL = 'Type of Conveyor' # Optional, for details modal
|
||||
|
||||
# --- Global state ---
|
||||
last_commit_hash = None
|
||||
# New detailed progress data structure
|
||||
progress_data = {
|
||||
"overall": {
|
||||
"total_csv": 0, "found_both": 0, "found_scada_only": 0, "found_drawing_only": 0, "missing_both": 0,
|
||||
"percentage_found_both": 0,
|
||||
"missing_list": [], "found_scada_only_list": [], "found_drawing_only_list": [], "found_both_list": []
|
||||
},
|
||||
"panels": {} # Populated dynamically
|
||||
}
|
||||
status_message = "Initializing..."
|
||||
repo_lock = threading.Lock() # Lock for accessing repo and shared data
|
||||
data_updated_event = threading.Event() # Event to signal data updates
|
||||
|
||||
# --- Helper Functions ---
|
||||
|
||||
def get_repo_path():
|
||||
return os.path.abspath(REPO_DIR)
|
||||
|
||||
def get_csv_path():
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
return os.path.join(script_dir, CSV_FILENAME)
|
||||
|
||||
def get_views_dir_path():
|
||||
return os.path.join(get_repo_path(), VIEWS_DIR_RELATIVE)
|
||||
|
||||
def get_text_output_dir_path():
|
||||
# Construct absolute path based on the script's directory
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
# Use os.path.join to handle path separators correctly and avoid './'
|
||||
return os.path.abspath(os.path.join(script_dir, TEXT_OUTPUT_FOLDER))
|
||||
|
||||
def normalize(text):
|
||||
"""Normalize string for comparison: lowercase, treat '-' and '_' the same, remove all whitespace."""
|
||||
if not isinstance(text, str):
|
||||
return ""
|
||||
text = text.lower() # Convert to lowercase
|
||||
text = text.replace('-', '_') # Replace hyphens with underscores
|
||||
text = re.sub(r'\s+', '', text) # Remove ALL whitespace characters (including newlines)
|
||||
return text
|
||||
|
||||
def read_manifest(csv_filepath):
|
||||
"""Reads the manifest CSV into a list of dictionaries."""
|
||||
manifest_items = []
|
||||
# Only require Alias and Panel now for basic grouping
|
||||
required_cols = {CSV_ALIAS_COL, CSV_PANEL_COL}
|
||||
optional_cols = {CSV_EQ_TYPE_COL, CSV_CONV_TYPE_COL}
|
||||
try:
|
||||
# Revert back to 'utf-8-sig' to handle potential BOM from Excel
|
||||
with open(csv_filepath, mode='r', newline='', encoding='utf-8-sig') as infile:
|
||||
reader = csv.DictReader(infile)
|
||||
headers = set(h.strip() for h in reader.fieldnames)
|
||||
|
||||
# Check for required columns
|
||||
missing_required = required_cols - headers
|
||||
if missing_required:
|
||||
print(f"Error: Missing required columns in CSV '{csv_filepath}': {', '.join(missing_required)}")
|
||||
print(f"Available columns: {', '.join(headers)}")
|
||||
return None
|
||||
|
||||
for row in reader:
|
||||
alias = row.get(CSV_ALIAS_COL, "").strip()
|
||||
panel = row.get(CSV_PANEL_COL, "").strip()
|
||||
# unit_number = row.get('Unit Number', "").strip() # No longer needed for filename
|
||||
|
||||
# Add if Alias and Control Panel are present (Panel needed for grouping results later)
|
||||
if alias and panel:
|
||||
item = {
|
||||
"alias": alias,
|
||||
"normalized_alias": normalize(alias),
|
||||
"control_panel": panel,
|
||||
# "unit_number": unit_number, # Removed
|
||||
# "expected_drawing_filename": f"MTN6_SYSDL-{unit_number}.txt", # Removed
|
||||
# Add optional data if columns exist
|
||||
"equipment_type": row.get(CSV_EQ_TYPE_COL, "").strip() if CSV_EQ_TYPE_COL in headers else "N/A",
|
||||
"conveyor_type": row.get(CSV_CONV_TYPE_COL, "").strip() if CSV_CONV_TYPE_COL in headers else "N/A",
|
||||
# Status fields to be filled later
|
||||
"found_scada": False,
|
||||
"found_drawing": False
|
||||
}
|
||||
manifest_items.append(item)
|
||||
# elif alias and panel: # If Unit Number is missing but others are present # Condition removed
|
||||
# print(f"Warning: Alias '{alias}' in Panel '{panel}' is missing 'Unit Number' in CSV. Skipping drawing check for this item.")
|
||||
elif alias and not panel:
|
||||
print(f"Warning: Alias '{alias}' found in CSV but is missing its '{CSV_PANEL_COL}'. Skipping.")
|
||||
# Add other specific warnings if needed
|
||||
|
||||
except FileNotFoundError:
|
||||
print(f"Error: Manifest file not found at {csv_filepath}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"Error reading CSV file {csv_filepath}: {e}")
|
||||
return None
|
||||
print(f"Read {len(manifest_items)} valid items from manifest.")
|
||||
return manifest_items
|
||||
|
||||
def check_scada(manifest_data, views_dir):
|
||||
"""Checks for aliases in SCADA JSON view files."""
|
||||
if not manifest_data: return
|
||||
print(f"Starting SCADA check in directory: {views_dir}...")
|
||||
found_count = 0
|
||||
processed_files = 0
|
||||
|
||||
# Create a quick lookup map of normalized_alias -> list of manifest items (handles duplicate aliases)
|
||||
alias_map = {}
|
||||
for item in manifest_data:
|
||||
na = item['normalized_alias']
|
||||
if na not in alias_map:
|
||||
alias_map[na] = []
|
||||
alias_map[na].append(item)
|
||||
|
||||
try:
|
||||
for root, _, files in os.walk(views_dir):
|
||||
for filename in files:
|
||||
if filename == 'view.json':
|
||||
filepath = os.path.join(root, filename)
|
||||
processed_files += 1
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
# Read the whole file, normalize it for substring search
|
||||
content = f.read()
|
||||
normalized_content = normalize(content)
|
||||
|
||||
# Check manifest aliases against this file's normalized content
|
||||
for norm_alias, items in alias_map.items():
|
||||
if norm_alias in normalized_content:
|
||||
for item in items:
|
||||
if not item['found_scada']: # Update only if not already found elsewhere
|
||||
item['found_scada'] = True
|
||||
found_count += 1 # Count unique aliases found
|
||||
except Exception as e:
|
||||
print(f" Warning: Could not read or process JSON file {filepath}: {e}")
|
||||
except Exception as e:
|
||||
print(f"Error walking SCADA views directory {views_dir}: {e}")
|
||||
|
||||
print(f"SCADA check finished. Processed {processed_files} view.json files. Found {found_count} manifest aliases.")
|
||||
|
||||
|
||||
def check_drawings(manifest_data, text_output_dir):
|
||||
"""Checks if aliases from manifest exist in *any* extracted drawing text file."""
|
||||
if not manifest_data: return
|
||||
print(f"Starting Drawings check: Scanning all .txt files in directory: {text_output_dir}...")
|
||||
|
||||
all_normalized_content = "" # Combine all text content here
|
||||
processed_files = 0
|
||||
found_files = []
|
||||
|
||||
try:
|
||||
# Step 1: Read and combine content of all .txt files in the directory
|
||||
for filename in os.listdir(text_output_dir):
|
||||
if filename.lower().endswith('.txt'):
|
||||
filepath = os.path.join(text_output_dir, filename)
|
||||
processed_files += 1
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
# Add a separator to prevent false matches across file boundaries
|
||||
all_normalized_content += normalize(content) + "\n--file-separator--\n"
|
||||
found_files.append(filename)
|
||||
except Exception as e:
|
||||
print(f" Warning: Could not read or process text file {filepath}: {e}")
|
||||
|
||||
if processed_files == 0:
|
||||
print(" Warning: No .txt files found in the directory. Cannot perform drawing check.")
|
||||
return
|
||||
else:
|
||||
print(f" Successfully read and normalized content from {len(found_files)} out of {processed_files} .txt files found.")
|
||||
|
||||
# Step 2: Check each manifest alias against the combined content
|
||||
found_count = 0
|
||||
for item in manifest_data:
|
||||
normalized_alias = item['normalized_alias']
|
||||
if normalized_alias and normalized_alias in all_normalized_content:
|
||||
item['found_drawing'] = True
|
||||
found_count += 1
|
||||
# else: item['found_drawing'] is already False by default
|
||||
|
||||
print(f"Drawings check finished. Found {found_count} manifest aliases within the combined text content.")
|
||||
|
||||
except FileNotFoundError:
|
||||
print(f" Error: Drawings text directory not found: {text_output_dir}")
|
||||
except Exception as e:
|
||||
print(f" Error during drawings check: {e}")
|
||||
|
||||
|
||||
def calculate_combined_progress(manifest_data):
|
||||
"""Calculates the combined progress based on scada/drawing status."""
|
||||
print("Calculating combined progress statistics...")
|
||||
results = {
|
||||
"overall": {
|
||||
"total_csv": 0, "found_both": 0, "found_scada_only": 0, "found_drawing_only": 0, "missing_both": 0,
|
||||
"percentage_found_both": 0,
|
||||
"missing_list": [], "found_scada_only_list": [], "found_drawing_only_list": [], "found_both_list": []
|
||||
},
|
||||
# Initialize state for discovered projects
|
||||
def get_default_progress():
|
||||
# Helper to return a fresh copy of the default progress structure
|
||||
return {
|
||||
"overall": {"total_csv": 0, "found_both": 0, "found_scada_only": 0, "found_drawing_only": 0, "missing_both": 0, "percentage_found_both": 0, "missing_list": [], "found_scada_only_list": [], "found_drawing_only_list": [], "found_both_list": []},
|
||||
"panels": {}
|
||||
}
|
||||
if not manifest_data:
|
||||
print("Warning: No manifest data to calculate progress from.")
|
||||
return results
|
||||
|
||||
results["overall"]["total_csv"] = len(manifest_data)
|
||||
for proj_name in all_projects:
|
||||
project_last_commit[proj_name] = None
|
||||
project_progress_data[proj_name] = get_default_progress()
|
||||
project_status[proj_name] = "Initializing..."
|
||||
|
||||
for item in manifest_data:
|
||||
panel = item['control_panel']
|
||||
repo_lock = threading.Lock() # Lock remains global for now, managing access to shared dicts
|
||||
data_updated_event = threading.Event() # Event signals ANY project update
|
||||
|
||||
# Initialize panel data if not present
|
||||
if panel not in results["panels"]:
|
||||
results["panels"][panel] = {
|
||||
"total": 0, "found_both": 0, "found_scada_only": 0, "found_drawing_only": 0, "missing_both": 0,
|
||||
"percentage_found_both": 0,
|
||||
"missing_list": [], "found_scada_only_list": [], "found_drawing_only_list": [], "found_both_list": []
|
||||
}
|
||||
# Define max workers for thread pools
|
||||
MAX_INITIAL_CHECK_WORKERS = 5 # Adjust as needed
|
||||
MAX_PERIODIC_CHECK_WORKERS = 5 # Adjust as needed
|
||||
|
||||
results["panels"][panel]["total"] += 1
|
||||
# --- Core Logic Orchestration (Per-Project) ---
|
||||
|
||||
# Categorize and add to lists
|
||||
item_detail = {k: v for k, v in item.items() if k not in ['normalized_alias']} # Don't need normalized in output
|
||||
|
||||
if item['found_scada'] and item['found_drawing']:
|
||||
results["overall"]["found_both"] += 1
|
||||
results["panels"][panel]["found_both"] += 1
|
||||
results["overall"]["found_both_list"].append(item_detail)
|
||||
results["panels"][panel]["found_both_list"].append(item_detail)
|
||||
elif item['found_scada'] and not item['found_drawing']:
|
||||
results["overall"]["found_scada_only"] += 1
|
||||
results["panels"][panel]["found_scada_only"] += 1
|
||||
results["overall"]["found_scada_only_list"].append(item_detail)
|
||||
results["panels"][panel]["found_scada_only_list"].append(item_detail)
|
||||
elif not item['found_scada'] and item['found_drawing']:
|
||||
results["overall"]["found_drawing_only"] += 1
|
||||
results["panels"][panel]["found_drawing_only"] += 1
|
||||
results["overall"]["found_drawing_only_list"].append(item_detail)
|
||||
results["panels"][panel]["found_drawing_only_list"].append(item_detail)
|
||||
else: # Missing both
|
||||
results["overall"]["missing_both"] += 1
|
||||
results["panels"][panel]["missing_both"] += 1
|
||||
results["overall"]["missing_list"].append(item_detail)
|
||||
results["panels"][panel]["missing_list"].append(item_detail)
|
||||
|
||||
# Calculate percentages
|
||||
if results["overall"]["total_csv"] > 0:
|
||||
results["overall"]["percentage_found_both"] = round(
|
||||
(results["overall"]["found_both"] / results["overall"]["total_csv"]) * 100, 1
|
||||
)
|
||||
for panel_data in results["panels"].values():
|
||||
if panel_data["total"] > 0:
|
||||
panel_data["percentage_found_both"] = round(
|
||||
(panel_data["found_both"] / panel_data["total"]) * 100, 1
|
||||
)
|
||||
|
||||
print("Combined progress calculation finished.")
|
||||
# print(json.dumps(results, indent=2)) # DEBUG: Print structure
|
||||
return results
|
||||
|
||||
|
||||
# --- Core Logic ---
|
||||
|
||||
def update_progress_data():
|
||||
"""Reads manifest, runs both checks, combines results, and updates global state."""
|
||||
global progress_data, status_message
|
||||
csv_path = get_csv_path()
|
||||
views_dir = get_views_dir_path()
|
||||
text_dir = get_text_output_dir_path()
|
||||
def update_progress_data(project_name):
|
||||
"""Reads manifest, runs checks, combines results for a specific project."""
|
||||
global project_progress_data, project_status # Reference the global dicts
|
||||
current_status = ""
|
||||
new_data_calculated = None
|
||||
|
||||
print(f"[{project_name}] Starting analysis workflow...")
|
||||
|
||||
# 1. Read Manifest
|
||||
status_message = "Reading manifest file..."
|
||||
print(f"Reading manifest: {csv_path}")
|
||||
manifest_data = read_manifest(csv_path)
|
||||
set_status(project_name, "Reading manifest file...")
|
||||
manifest_data = read_manifest(project_name)
|
||||
if manifest_data is None:
|
||||
current_status = f"Error: Failed to read or process manifest file {csv_path}"
|
||||
current_status = f"[{project_name}] Error: Failed to read or process manifest file."
|
||||
print(current_status)
|
||||
status_message = current_status
|
||||
data_updated_event.set(); data_updated_event.clear()
|
||||
set_status(project_name, current_status)
|
||||
# Reset progress data for this project on manifest error
|
||||
with repo_lock:
|
||||
project_progress_data[project_name] = get_default_progress()
|
||||
data_updated_event.set(); data_updated_event.clear() # Signal update (error status + reset data)
|
||||
return # Cannot proceed without manifest
|
||||
|
||||
# 2. Check SCADA (JSON files)
|
||||
status_message = "Checking SCADA views..."
|
||||
if not os.path.exists(views_dir):
|
||||
current_status = f"Warning: SCADA Views directory not found at {views_dir}. Skipping SCADA check."
|
||||
print(current_status)
|
||||
# Mark all as not found in SCADA? Or just skip update? Skipping update is safer.
|
||||
else:
|
||||
check_scada(manifest_data, views_dir)
|
||||
set_status(project_name, "Checking SCADA views...")
|
||||
check_scada(project_name, manifest_data)
|
||||
|
||||
# 3. Check Drawings (TXT files)
|
||||
status_message = "Checking drawing text files..."
|
||||
if not os.path.exists(text_dir):
|
||||
current_status = f"Warning: Extracted Text directory not found at {text_dir}. Skipping Drawings check."
|
||||
print(current_status)
|
||||
# Mark all as not found in Drawings? Or skip? Skipping update.
|
||||
else:
|
||||
check_drawings(manifest_data, text_dir)
|
||||
set_status(project_name, "Checking drawing text files...")
|
||||
check_drawings(project_name, manifest_data)
|
||||
|
||||
# 4. Calculate Combined Progress
|
||||
status_message = "Calculating combined progress..."
|
||||
set_status(project_name, "Calculating combined progress...")
|
||||
try:
|
||||
new_data_calculated = calculate_combined_progress(manifest_data)
|
||||
new_data_calculated = calculate_combined_progress(project_name, manifest_data)
|
||||
if new_data_calculated:
|
||||
current_status = f"Analysis complete at {time.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
current_status = f"[{project_name}] Analysis complete at {time.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
else:
|
||||
# This case shouldn't happen if manifest_data was valid
|
||||
current_status = "Error: Failed to calculate combined progress."
|
||||
current_status = f"[{project_name}] Warning: Progress calculation yielded no results (manifest might be empty)."
|
||||
new_data_calculated = get_default_progress() # Reset to default empty structure
|
||||
except Exception as e:
|
||||
current_status = f"Error during progress calculation: {e}"
|
||||
print(f"Detailed Calculation Error: {e}", exc_info=True) # Log stack trace
|
||||
current_status = f"[{project_name}] Error during progress calculation: {e}"
|
||||
print(f"Detailed Calculation Error: {e}") # Log stack trace (removed exc_info)
|
||||
new_data_calculated = None # Ensure no partial data update
|
||||
|
||||
# Update global state
|
||||
# Update global state atomically for this project
|
||||
with repo_lock:
|
||||
print(current_status)
|
||||
status_message = current_status # Update status regardless of calculation success/failure
|
||||
# Update status first (always)
|
||||
project_status[project_name] = current_status
|
||||
# Update progress data only if calculation was successful or yielded default empty
|
||||
if new_data_calculated is not None:
|
||||
progress_data = new_data_calculated
|
||||
# Signal that an update attempt finished WITH new data
|
||||
project_progress_data[project_name] = new_data_calculated
|
||||
# Signal update regardless of calculation success if status changed or data changed
|
||||
data_updated_event.set()
|
||||
data_updated_event.clear()
|
||||
|
||||
# --- Git Repo Handling (Modified slightly to use updated status messages) ---
|
||||
|
||||
def check_and_update_repo():
|
||||
global last_commit_hash, status_message
|
||||
repo_path = get_repo_path()
|
||||
did_update = False # Flag to track if files were actually updated
|
||||
initial_hash = last_commit_hash # Store hash before check
|
||||
|
||||
def set_status(project_name, message):
|
||||
"""Helper to update status message for a project and signal change."""
|
||||
global project_status
|
||||
with repo_lock:
|
||||
if project_status.get(project_name) != message:
|
||||
print(f"[{project_name}] Status: {message}")
|
||||
project_status[project_name] = message
|
||||
data_updated_event.set()
|
||||
data_updated_event.clear()
|
||||
|
||||
# --- Git Repo Handling (Per-Project) ---
|
||||
|
||||
def check_and_update_repo(project_name):
|
||||
"""Checks and updates the Git repository for a specific project, minimizing lock contention."""
|
||||
global project_last_commit, project_status # Reference global dicts
|
||||
|
||||
repo_path = utils.get_repo_path(project_name)
|
||||
repo_url = config.REPO_URL # Assuming global for now
|
||||
branch = config.BRANCH # Assuming global for now
|
||||
|
||||
did_update = False # Flag to track if files were actually updated
|
||||
initial_hash = None
|
||||
with repo_lock: # Briefly lock to get initial hash
|
||||
initial_hash = project_last_commit.get(project_name)
|
||||
|
||||
try:
|
||||
project_base_path = utils.get_project_base_path(project_name)
|
||||
if not os.path.exists(project_base_path):
|
||||
# Use set_status which handles locking
|
||||
set_status(project_name, f"Error: Project directory not found: {project_base_path}")
|
||||
return False # Cannot proceed
|
||||
|
||||
# Ensure parent directory exists (outside lock)
|
||||
os.makedirs(os.path.dirname(repo_path), exist_ok=True)
|
||||
|
||||
repo_existed = os.path.exists(os.path.join(repo_path, ".git"))
|
||||
|
||||
if not repo_existed:
|
||||
print(f"Cloning repository {REPO_URL} into {repo_path}...")
|
||||
status_message = f"Cloning repository {REPO_URL}..."
|
||||
git.Repo.clone_from(REPO_URL, repo_path, branch=BRANCH)
|
||||
print(f"[{project_name}] Cloning repository {repo_url} into {repo_path}...")
|
||||
set_status(project_name, "Cloning repository...")
|
||||
# --- Clone happens OUTSIDE lock ---
|
||||
try:
|
||||
git.Repo.clone_from(repo_url, repo_path, branch=branch)
|
||||
repo = git.Repo(repo_path)
|
||||
last_commit_hash = repo.head.commit.hexsha
|
||||
print(f"Initial clone complete. Commit: {last_commit_hash}")
|
||||
did_update = True # Cloned, so considered an update
|
||||
new_commit_hash = repo.head.commit.hexsha
|
||||
with repo_lock: # Lock ONLY to update shared state
|
||||
project_last_commit[project_name] = new_commit_hash
|
||||
print(f"[{project_name}] Initial clone complete. Commit: {new_commit_hash}")
|
||||
did_update = True
|
||||
except git.GitCommandError as clone_err:
|
||||
set_status(project_name, f"Error cloning repository: {clone_err}")
|
||||
print(f"[{project_name}] Git clone error: {clone_err}")
|
||||
# Ensure commit state reflects error if needed
|
||||
with repo_lock:
|
||||
if project_last_commit.get(project_name) is None:
|
||||
project_last_commit[project_name] = "Clone Error"
|
||||
return False # Indicate no update occurred
|
||||
# --- End Clone ---
|
||||
else:
|
||||
# --- Fetch/Pull Logic ---
|
||||
repo = git.Repo(repo_path)
|
||||
print("Fetching updates from remote...")
|
||||
current_local_commit = repo.head.commit.hexsha
|
||||
# Update hash *before* fetch in case fetch fails but commit was readable
|
||||
if last_commit_hash is None: last_commit_hash = current_local_commit
|
||||
|
||||
# Ensure initial hash is set if missing (brief lock)
|
||||
with repo_lock:
|
||||
if project_last_commit.get(project_name) is None:
|
||||
project_last_commit[project_name] = current_local_commit
|
||||
initial_hash = current_local_commit # Update local var too
|
||||
|
||||
print(f"[{project_name}] Fetching updates from remote...")
|
||||
set_status(project_name, "Checking for updates...")
|
||||
origin = repo.remotes.origin
|
||||
|
||||
# --- Fetch happens OUTSIDE lock ---
|
||||
try:
|
||||
fetch_info = origin.fetch()
|
||||
except git.GitCommandError as fetch_err:
|
||||
set_status(project_name, f"Error fetching remote: {fetch_err}")
|
||||
print(f"[{project_name}] Git fetch error: {fetch_err}")
|
||||
return False # No update occurred
|
||||
# --- End Fetch ---
|
||||
|
||||
# Check if fetch actually brought new data for the target branch
|
||||
# fetched_new_commits = any(info.flags & info.NEW_HEAD for info in fetch_info if info.name == f'origin/{BRANCH}') # More precise check if needed
|
||||
|
||||
current_remote_commit = repo.commit(f'origin/{BRANCH}').hexsha
|
||||
|
||||
print(f"Local commit: {current_local_commit}, Remote commit: {current_remote_commit}")
|
||||
|
||||
# --- Check commits (brief lock) ---
|
||||
current_remote_commit = None
|
||||
pull_needed = False
|
||||
try:
|
||||
# Must read remote commit *after* fetch
|
||||
current_remote_commit = repo.commit(f'origin/{branch}').hexsha
|
||||
# Check if pull is needed inside the try block after getting remote commit
|
||||
if current_local_commit != current_remote_commit:
|
||||
print("New commit detected! Pulling changes...")
|
||||
status_message = "Pulling updates..."
|
||||
pull_needed = True
|
||||
except git.GitCommandError as commit_err:
|
||||
set_status(project_name, f"Error accessing remote branch origin/{branch}: {commit_err}")
|
||||
print(f"[{project_name}] Error accessing remote branch: {commit_err}")
|
||||
return False # Cannot compare/pull
|
||||
# --- End Check commits ---
|
||||
|
||||
print(f"[{project_name}] Local commit: {current_local_commit}, Remote commit (origin/{branch}): {current_remote_commit}")
|
||||
|
||||
if pull_needed:
|
||||
print(f"[{project_name}] New commit detected! Pulling changes...")
|
||||
set_status(project_name, "Pulling updates...")
|
||||
# --- Pull happens OUTSIDE lock ---
|
||||
try:
|
||||
pull_info = origin.pull()
|
||||
new_commit_hash = repo.head.commit.hexsha
|
||||
print(f"Pull successful. New commit: {new_commit_hash}")
|
||||
last_commit_hash = new_commit_hash
|
||||
did_update = True # Pulled, so considered an update
|
||||
except git.GitCommandError as e:
|
||||
status_message = f"Error pulling repository: {e}"
|
||||
print(status_message)
|
||||
# Revert hash if pull failed
|
||||
last_commit_hash = current_local_commit
|
||||
new_commit_hash = repo.head.commit.hexsha # Get hash after pull
|
||||
with repo_lock: # Lock ONLY to update shared state
|
||||
project_last_commit[project_name] = new_commit_hash
|
||||
print(f"[{project_name}] Pull successful. New commit: {new_commit_hash}")
|
||||
did_update = True
|
||||
except git.GitCommandError as pull_err:
|
||||
set_status(project_name, f"Error pulling repository: {pull_err}")
|
||||
print(f"[{project_name}] Git pull error: {pull_err}")
|
||||
# Revert shared state hash if pull failed? Safest is to keep the pre-pull local commit.
|
||||
with repo_lock:
|
||||
project_last_commit[project_name] = current_local_commit # Revert to known local state before pull attempt
|
||||
# Keep did_update = False
|
||||
# --- End Pull ---
|
||||
else:
|
||||
print("No new commits detected.")
|
||||
# Update status if it wasn't an error before
|
||||
if not status_message.startswith("Error"):
|
||||
status_message = f"Checked repo at {time.strftime('%Y-%m-%d %H:%M:%S')}. No changes."
|
||||
print(f"[{project_name}] No new commits detected.")
|
||||
# Update status only if it wasn't an error before (set_status handles lock)
|
||||
current_status = project_status.get(project_name, "")
|
||||
if not current_status.startswith("Error"):
|
||||
set_status(project_name, f"Checked repo at {time.strftime('%Y-%m-%d %H:%M:%S')}. No changes.")
|
||||
# --- End Fetch/Pull Logic ---
|
||||
|
||||
# Run analysis IF the repo was updated (cloned or pulled)
|
||||
# --- Run analysis IF repo was updated (outside lock) ---
|
||||
if did_update:
|
||||
# Status will be updated within update_progress_data
|
||||
update_progress_data()
|
||||
# If no git update, signal any status change (e.g., "No changes" or error)
|
||||
# else: # REMOVED block that signaled event for no changes
|
||||
# REMOVED: data_updated_event.set() # Signal status change event
|
||||
# REMOVED: data_updated_event.clear()
|
||||
# Status message is still updated globally, just won't trigger event
|
||||
print(f"[{project_name}] Repository updated. Triggering analysis...")
|
||||
update_progress_data(project_name) # Calls the orchestrator function
|
||||
|
||||
except git.InvalidGitRepositoryError:
|
||||
msg = f"Error: Directory '{repo_path}' exists but is not a valid Git repository. Consider deleting it and restarting."
|
||||
set_status(project_name, msg) # Handles lock
|
||||
print(f"[{project_name}] {msg}")
|
||||
with repo_lock: # Lock to update commit state
|
||||
project_last_commit[project_name] = "Invalid Repository"
|
||||
except git.GitCommandError as e:
|
||||
status_message = f"Git command error: {e}"
|
||||
print(status_message)
|
||||
# Try to get commit hash even if failed
|
||||
# General Git command error (if not caught above)
|
||||
msg = f"Git command error: {e}"
|
||||
set_status(project_name, msg) # Handles lock
|
||||
print(f"[{project_name}] {msg}")
|
||||
# Try to set commit hash state even on error (brief lock)
|
||||
with repo_lock:
|
||||
if project_last_commit.get(project_name) is None: # Only set if not already set (e.g., by failed pull)
|
||||
try:
|
||||
if os.path.exists(os.path.join(repo_path, ".git")):
|
||||
repo = git.Repo(repo_path)
|
||||
# Use previous hash if available, else try to read current
|
||||
if last_commit_hash is None: last_commit_hash = repo.head.commit.hexsha
|
||||
project_last_commit[project_name] = repo.head.commit.hexsha
|
||||
else:
|
||||
project_last_commit[project_name] = "Error (No repo)"
|
||||
except Exception:
|
||||
if last_commit_hash is None: last_commit_hash = "Error reading commit"
|
||||
# REMOVED: data_updated_event.set() # Signal error status change
|
||||
# REMOVED: data_updated_event.clear()
|
||||
project_last_commit[project_name] = "Error reading commit"
|
||||
|
||||
except Exception as e:
|
||||
status_message = f"Error checking repository: {e}"
|
||||
print(status_message)
|
||||
if last_commit_hash is None: last_commit_hash = "Error checking repo"
|
||||
# REMOVED: data_updated_event.set() # Signal error status change
|
||||
# REMOVED: data_updated_event.clear()
|
||||
# Catch-all for other unexpected errors
|
||||
msg = f"Unexpected error checking repository: {e}"
|
||||
set_status(project_name, msg) # Handles lock
|
||||
print(f"[{project_name}] {msg}") # Log stack trace for unexpected errors
|
||||
with repo_lock: # Lock to update commit state
|
||||
if project_last_commit.get(project_name) is None:
|
||||
project_last_commit[project_name] = "Error checking repo"
|
||||
|
||||
# Return true if analysis was run (because repo changed), false otherwise
|
||||
return did_update
|
||||
|
||||
def periodic_repo_check():
|
||||
"""Runs the check_and_update_repo function periodically."""
|
||||
"""Runs the check_and_update_repo function periodically for all projects using a thread pool."""
|
||||
global all_projects
|
||||
# Use a ThreadPoolExecutor to manage periodic checks concurrently
|
||||
with ThreadPoolExecutor(max_workers=MAX_PERIODIC_CHECK_WORKERS) as executor:
|
||||
while True:
|
||||
print(f"\nStarting periodic repository check (Interval: {CHECK_INTERVAL_SECONDS}s)...")
|
||||
repo_changed = check_and_update_repo()
|
||||
# If repo didn't change, analysis wasn't triggered, but we might want to run it anyway?
|
||||
# For now, analysis only runs if repo changes or on initial startup.
|
||||
# If you want analysis *every* interval regardless of git changes, add a call here:
|
||||
# if not repo_changed:
|
||||
# print("Repo unchanged, triggering analysis anyway...")
|
||||
# update_progress_data()
|
||||
print(f"Check finished. Sleeping...")
|
||||
time.sleep(CHECK_INTERVAL_SECONDS)
|
||||
print(f"\nStarting periodic check cycle for all projects (Interval: {config.CHECK_INTERVAL_SECONDS}s)...")
|
||||
current_projects = list(all_projects) # Copy list in case it changes
|
||||
|
||||
# --- Flask Routes (Largely unchanged, rely on updated global state) ---
|
||||
futures = []
|
||||
for project_name in current_projects:
|
||||
print(f"--- Submitting periodic check for project: {project_name} ---")
|
||||
# Submit check_and_update_repo to the thread pool
|
||||
futures.append(executor.submit(run_check_and_log_errors, project_name, "periodic"))
|
||||
|
||||
# Wait briefly for tasks to start, but don't block the loop long
|
||||
# time.sleep(1) # Optional: short sleep if needed
|
||||
|
||||
print(f"Periodic check cycle submitted. Sleeping for {config.CHECK_INTERVAL_SECONDS}s...")
|
||||
time.sleep(config.CHECK_INTERVAL_SECONDS)
|
||||
# Note: We don't explicitly wait for futures to complete here.
|
||||
# The pool manages threads, and the loop continues periodically.
|
||||
|
||||
def run_check_and_log_errors(project_name, check_type="initial"):
|
||||
"""Wrapper to run check_and_update_repo and log any exceptions."""
|
||||
try:
|
||||
print(f"--- [{check_type.capitalize()}] Running check for project: {project_name} ---")
|
||||
check_and_update_repo(project_name)
|
||||
print(f"--- [{check_type.capitalize()}] Finished check for project: {project_name} ---")
|
||||
except Exception as e:
|
||||
err_msg = f"Critical error during {check_type} check for {project_name}: {e}"
|
||||
print(err_msg)
|
||||
# Use set_status which handles locking and event signaling
|
||||
set_status(project_name, f"Error during {check_type} check: {e}")
|
||||
|
||||
def initial_project_setup_and_analysis(project_name):
|
||||
"""Performs initial repo check/update AND ensures initial analysis runs."""
|
||||
try:
|
||||
print(f"--- [Initial Setup] Starting for project: {project_name} ---")
|
||||
# Run check_and_update_repo first. It returns True if it triggered an update/analysis.
|
||||
update_occurred = check_and_update_repo(project_name)
|
||||
|
||||
# If no update occurred (repo was cloned before or was already up-to-date),
|
||||
# we still need to run the analysis once on startup.
|
||||
if not update_occurred:
|
||||
print(f"--- [Initial Analysis] Repo up-to-date or non-git. Running analysis for project: {project_name} ---")
|
||||
update_progress_data(project_name) # Run the analysis explicitly
|
||||
print(f"--- [Initial Setup] Finished for project: {project_name} ---")
|
||||
|
||||
except Exception as e:
|
||||
err_msg = f"Critical error during initial setup/analysis for {project_name}: {e}"
|
||||
print(err_msg)
|
||||
set_status(project_name, f"Error during initial setup: {e}")
|
||||
|
||||
# --- Flask Routes ---
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
# Pass the list of projects and initial statuses to the template
|
||||
with repo_lock:
|
||||
initial_statuses = dict(project_status) # Get a consistent snapshot
|
||||
project_list = list(all_projects)
|
||||
return render_template('index.html', projects=project_list, initial_statuses=initial_statuses)
|
||||
|
||||
@app.route('/drawings')
|
||||
def drawings_page():
|
||||
# Render the main index template which now contains all content
|
||||
return render_template('index.html')
|
||||
|
||||
@app.route('/conflicts')
|
||||
def conflicts_page():
|
||||
# Render the main index template which now contains all content
|
||||
return render_template('index.html')
|
||||
# Removed redundant routes for /drawings and /conflicts as index.html handles tabs
|
||||
|
||||
@app.route('/stream')
|
||||
def stream():
|
||||
def event_stream():
|
||||
last_sent_hash_to_client = None # Track hash sent to *this specific client*
|
||||
# Track state sent to *this specific client* (using a copy of global state)
|
||||
last_sent_state = {}
|
||||
|
||||
# Send initial state immediately on connection
|
||||
with repo_lock:
|
||||
current_global_hash = last_commit_hash
|
||||
current_global_status = status_message
|
||||
current_global_progress = progress_data
|
||||
# Send data for all known projects
|
||||
current_global_state = {
|
||||
"projects": list(all_projects),
|
||||
"status": dict(project_status),
|
||||
"progress": dict(project_progress_data),
|
||||
"last_commit": dict(project_last_commit)
|
||||
}
|
||||
|
||||
initial_payload = json.dumps({
|
||||
"status": current_global_status,
|
||||
"progress": current_global_progress,
|
||||
"last_commit": current_global_hash
|
||||
})
|
||||
initial_payload = json.dumps(current_global_state)
|
||||
yield f"data: {initial_payload}\n\n"
|
||||
last_sent_hash_to_client = current_global_hash # Record that we sent the initial state for this client
|
||||
print(f"Sent initial state to new client (Hash: {last_sent_hash_to_client})")
|
||||
last_sent_state = current_global_state # Store the state sent to this client
|
||||
print(f"Sent initial state to new client for projects: {last_sent_state.get('projects')}")
|
||||
|
||||
# Now wait for subsequent updates signaled by the event
|
||||
while True:
|
||||
data_updated_event.wait() # Wait for background thread to signal completion
|
||||
data_updated_event.wait() # Wait for ANY background thread signal
|
||||
|
||||
with repo_lock: # Re-acquire lock to get the latest state
|
||||
current_global_hash = last_commit_hash
|
||||
current_global_status = status_message
|
||||
current_global_progress = progress_data
|
||||
current_global_state = {
|
||||
"projects": list(all_projects),
|
||||
"status": dict(project_status),
|
||||
"progress": dict(project_progress_data),
|
||||
"last_commit": dict(project_last_commit)
|
||||
}
|
||||
|
||||
# Send update to the client IF the data is different from what they last received
|
||||
# Check hash first as primary indicator of change in underlying data
|
||||
if current_global_hash != last_sent_hash_to_client:
|
||||
print(f"Data updated (Hash changed: {last_sent_hash_to_client} -> {current_global_hash}). Sending update to client.")
|
||||
data_payload = json.dumps({
|
||||
"status": current_global_status,
|
||||
"progress": current_global_progress,
|
||||
"last_commit": current_global_hash
|
||||
})
|
||||
yield f"data: {data_payload}\n\n"
|
||||
last_sent_hash_to_client = current_global_hash # Update the hash sent to this client
|
||||
# else: # No need for the else block logging here anymore, as the event shouldn't trigger if hash is same
|
||||
# If hash is the same, maybe only the status message changed (e.g., error occurred)
|
||||
# Option: Send update only if status is different from last sent status?
|
||||
# For simplicity now, we only send if hash differs. Client UI shows last known status.
|
||||
# print(f"Data updated event triggered, but hash {current_global_hash} unchanged for this client. Status: '{current_global_status}'") # Removed log
|
||||
# Basic check: Compare entire state dictionaries (can be refined if needed)
|
||||
# Using json.dumps for a quick deep comparison, might be slow for huge data
|
||||
current_state_json = json.dumps(current_global_state, sort_keys=True)
|
||||
last_sent_state_json = json.dumps(last_sent_state, sort_keys=True)
|
||||
|
||||
if current_state_json != last_sent_state_json:
|
||||
print(f"Global state changed. Sending update to client.")
|
||||
# print(f"Debug: Old state: {last_sent_state_json}") # Optional debug
|
||||
# print(f"Debug: New state: {current_state_json}") # Optional debug
|
||||
yield f"data: {current_state_json}\n\n"
|
||||
last_sent_state = current_global_state # Update the state sent to this client
|
||||
# else: # Log if event triggered but nothing changed
|
||||
# print(f"Data update event triggered, but state unchanged for this client.")
|
||||
|
||||
return Response(event_stream(), mimetype="text/event-stream")
|
||||
|
||||
# --- NEW: Add Project Endpoint ---
|
||||
ALLOWED_PROJECT_NAME_REGEX = re.compile(r'^[a-zA-Z0-9_-]+$')
|
||||
|
||||
@app.route('/add_project', methods=['POST'])
|
||||
def add_project():
|
||||
if 'projectName' not in request.form:
|
||||
return jsonify(success=False, message="Missing project name."), 400
|
||||
if 'repoUrl' not in request.form: # We receive it but don't use it for cloning yet
|
||||
return jsonify(success=False, message="Missing repository URL."), 400
|
||||
if 'manifestFile' not in request.files:
|
||||
return jsonify(success=False, message="Missing manifest CSV file."), 400
|
||||
|
||||
project_name_raw = request.form['projectName'].strip()
|
||||
repo_url = request.form['repoUrl'].strip()
|
||||
manifest_file = request.files['manifestFile']
|
||||
pdf_files = request.files.getlist('pdfFiles') # Use getlist for multiple files
|
||||
|
||||
# --- Validation ---
|
||||
if not project_name_raw:
|
||||
return jsonify(success=False, message="Project name cannot be empty."), 400
|
||||
if not ALLOWED_PROJECT_NAME_REGEX.match(project_name_raw):
|
||||
return jsonify(success=False, message="Invalid Project Name. Use only letters, numbers, underscores, or hyphens."), 400
|
||||
if not manifest_file.filename or not manifest_file.filename.lower().endswith('.csv'):
|
||||
return jsonify(success=False, message="Manifest file must be a .csv file."), 400
|
||||
if not pdf_files or all(not f.filename for f in pdf_files): # Check if list is empty or contains only empty filenames
|
||||
return jsonify(success=False, message="At least one PDF file must be provided."), 400
|
||||
for pdf_file in pdf_files:
|
||||
if not pdf_file.filename or not pdf_file.filename.lower().endswith('.pdf'):
|
||||
return jsonify(success=False, message=f"Invalid file type uploaded: {pdf_file.filename}. Only PDF files allowed."), 400
|
||||
|
||||
# Use secure_filename for the project name used in paths
|
||||
# Although we validated with regex, this adds another layer against path traversal etc.
|
||||
safe_project_name = secure_filename(project_name_raw)
|
||||
if safe_project_name != project_name_raw: # Extra check if secure_filename modified it unexpectedly (e.g., spaces removed)
|
||||
print(f"Warning: Project name sanitized from '{project_name_raw}' to '{safe_project_name}'")
|
||||
# Optionally reject here, or proceed with the sanitized name
|
||||
|
||||
project_base_path = os.path.join(config.PROJECTS_ROOT_DIR, safe_project_name)
|
||||
pdf_dir_path = os.path.join(project_base_path, 'pdfs')
|
||||
repo_dir_path = os.path.join(project_base_path, 'repo') # Create repo dir, but don't clone yet
|
||||
|
||||
# --- Check if project already exists ---
|
||||
if os.path.exists(project_base_path):
|
||||
return jsonify(success=False, message=f"Project '{safe_project_name}' already exists."), 400
|
||||
|
||||
# --- Create Directories ---
|
||||
try:
|
||||
print(f"Creating directory structure for project: {safe_project_name}")
|
||||
os.makedirs(project_base_path, exist_ok=False) # Base dir first, fail if exists
|
||||
os.makedirs(pdf_dir_path, exist_ok=True)
|
||||
os.makedirs(repo_dir_path, exist_ok=True)
|
||||
except OSError as e:
|
||||
print(f"Error creating directories for {safe_project_name}: {e}")
|
||||
return jsonify(success=False, message=f"Server error creating project directories: {e}"), 500
|
||||
|
||||
# --- Save Manifest File ---
|
||||
try:
|
||||
manifest_filename = secure_filename(manifest_file.filename)
|
||||
manifest_save_path = os.path.join(project_base_path, manifest_filename)
|
||||
print(f"Saving manifest file to: {manifest_save_path}")
|
||||
manifest_file.save(manifest_save_path)
|
||||
except Exception as e:
|
||||
print(f"Error saving manifest file for {safe_project_name}: {e}")
|
||||
# Clean up created directories on error?
|
||||
# shutil.rmtree(project_base_path, ignore_errors=True)
|
||||
return jsonify(success=False, message=f"Error saving manifest file: {e}"), 500
|
||||
|
||||
# --- Save PDF Files ---
|
||||
saved_pdfs = []
|
||||
try:
|
||||
for pdf_file in pdf_files:
|
||||
if pdf_file and pdf_file.filename: # Check again if file is valid
|
||||
pdf_filename = secure_filename(pdf_file.filename)
|
||||
pdf_save_path = os.path.join(pdf_dir_path, pdf_filename)
|
||||
print(f"Saving PDF file to: {pdf_save_path}")
|
||||
pdf_file.save(pdf_save_path)
|
||||
saved_pdfs.append(pdf_filename)
|
||||
except Exception as e:
|
||||
print(f"Error saving PDF files for {safe_project_name}: {e}")
|
||||
# Clean up potentially partially saved files and directories?
|
||||
# shutil.rmtree(project_base_path, ignore_errors=True)
|
||||
return jsonify(success=False, message=f"Error saving PDF files: {e}"), 500
|
||||
|
||||
# --- Store Repo URL (optional, e.g., in a simple info file) ---
|
||||
try:
|
||||
info_file_path = os.path.join(project_base_path, 'project_info.txt')
|
||||
with open(info_file_path, 'w') as f:
|
||||
f.write(f"ProjectName: {safe_project_name}\n")
|
||||
f.write(f"RepoURL: {repo_url}\n")
|
||||
print(f"Saved project info (including repo URL) to: {info_file_path}")
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not save project_info.txt for {safe_project_name}: {e}")
|
||||
# Don't treat this as a fatal error for the add operation itself
|
||||
|
||||
|
||||
print(f"Successfully added project '{safe_project_name}' with {len(saved_pdfs)} PDF(s).")
|
||||
# NOTE: Server needs restart for this new project to be discovered and processed.
|
||||
return jsonify(success=True, message=f"Project '{safe_project_name}' created successfully.")
|
||||
|
||||
# --- Main Execution ---
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Ensure repo and text directories exist (optional for text dir if PDFs are pre-processed)
|
||||
if not os.path.exists(REPO_DIR):
|
||||
os.makedirs(REPO_DIR)
|
||||
if not os.path.exists(TEXT_OUTPUT_FOLDER):
|
||||
print(f"Warning: Text output folder '{TEXT_OUTPUT_FOLDER}' not found. Drawing check might fail unless PDF extraction runs first or files are manually placed.")
|
||||
# os.makedirs(TEXT_OUTPUT_FOLDER) # Optionally create it
|
||||
# Ensure project-specific directories (like text output) exist if needed
|
||||
# This is now handled within drawing_checker
|
||||
|
||||
# Perform initial check/clone and data load
|
||||
print("Performing initial repository check and data load...")
|
||||
# Run check_and_update_repo which calls update_progress_data if repo updated
|
||||
initial_update_done = check_and_update_repo()
|
||||
# If repo existed and was up-to-date on first check, analysis wasn't run yet. Run it now.
|
||||
if not initial_update_done:
|
||||
print("Repository present and up-to-date. Running initial analysis...")
|
||||
# No need for lock here as background thread isn't running yet
|
||||
update_progress_data() # Run the full analysis
|
||||
# Perform initial check/clone and data load FOR EACH PROJECT in parallel
|
||||
print("--- Performing initial checks and analysis for all discovered projects in background threads ---")
|
||||
if not all_projects:
|
||||
print("Warning: No projects discovered in projects directory.")
|
||||
else:
|
||||
print("Initial analysis was triggered by repo clone/pull.")
|
||||
# Use a ThreadPoolExecutor for initial setup
|
||||
with ThreadPoolExecutor(max_workers=MAX_INITIAL_CHECK_WORKERS, thread_name_prefix='InitialCheck') as executor:
|
||||
for proj_name in all_projects:
|
||||
print(f"--- Submitting initial setup for project: {proj_name} ---")
|
||||
# Submit the combined setup and analysis function to the pool
|
||||
executor.submit(initial_project_setup_and_analysis, proj_name)
|
||||
# We exit the 'with' block here, but the threads continue running in the background.
|
||||
# The executor automatically manages the threads. We don't call shutdown(wait=True).
|
||||
|
||||
# Start the background thread for periodic checks
|
||||
print("Starting background repository check thread...")
|
||||
repo_check_thread = threading.Thread(target=periodic_repo_check, daemon=True)
|
||||
# Start the background thread for PERIODIC checks (now uses its own thread pool internally)
|
||||
print("--- Starting background periodic check manager thread ---")
|
||||
# This thread now manages submitting tasks to its own pool
|
||||
repo_check_thread = threading.Thread(target=periodic_repo_check, daemon=True, name="PeriodicCheckManager")
|
||||
repo_check_thread.start()
|
||||
|
||||
# Run the Flask app
|
||||
print("Starting Flask server on port 5050...")
|
||||
# Use threaded=True for SSE background sending, debug=False for production/stability
|
||||
# Run the Flask app - This will start *before* initial checks might be complete
|
||||
print(f"--- Starting Flask server on http://0.0.0.0:5050 ... ---")
|
||||
# Ensure Flask runs threaded to handle multiple requests (like SSE connections)
|
||||
app.run(host='0.0.0.0', port=5050, debug=False, threaded=True)
|
||||
|
||||
30
config.py
Normal file
30
config.py
Normal file
@ -0,0 +1,30 @@
|
||||
import os
|
||||
|
||||
# --- Configuration ---
|
||||
REPO_URL = "http://192.168.5.191:3000/LCI/MTN6" # Assuming same base URL for now? Needs clarification if varies per project.
|
||||
BRANCH = "main" # Assuming same branch for all projects
|
||||
|
||||
# Define the root directory containing all project subdirectories
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
# PROJECTS_ROOT_DIR is one level up from SCRIPT_DIR if config.py is at the root
|
||||
# If config.py is inside a 'src' folder, adjust accordingly. Assuming root for now.
|
||||
PROJECTS_ROOT_DIR = os.path.join(SCRIPT_DIR, 'projects')
|
||||
|
||||
# Relative path within a project's repo to the SCADA views
|
||||
# Remove project-specific prefix, utils.py will find the correct parent folder
|
||||
VIEWS_DIR_RELATIVE = "com.inductiveautomation.perspective/views/Detailed-Views"
|
||||
|
||||
# Relative path within a project's base folder for extracted drawing text
|
||||
# We will construct this as 'project_name/extracted_texts' within PROJECTS_ROOT_DIR
|
||||
TEXT_OUTPUT_FOLDER_RELATIVE = "extracted_texts"
|
||||
|
||||
CHECK_INTERVAL_SECONDS = 60
|
||||
|
||||
# --- Column Names from CSV (Adjust if necessary) ---
|
||||
CSV_ALIAS_COL = 'Alias'
|
||||
CSV_PANEL_COL = 'Control Panel'
|
||||
CSV_EQ_TYPE_COL = 'Equipment Type' # Optional, for details modal
|
||||
CSV_CONV_TYPE_COL = 'Type of Conveyor' # Optional, for details modal
|
||||
|
||||
# --- Ensure Projects Root Directory Exists ---
|
||||
os.makedirs(PROJECTS_ROOT_DIR, exist_ok=True)
|
||||
117
drawing_checker.py
Normal file
117
drawing_checker.py
Normal file
@ -0,0 +1,117 @@
|
||||
import os
|
||||
# Assume utils contains the necessary helper functions
|
||||
import utils
|
||||
from utils import normalize, get_text_output_dir_path
|
||||
|
||||
def check_drawings(project_name, manifest_data):
|
||||
"""
|
||||
Checks if aliases from manifest exist ANYWHERE within the combined text extracted
|
||||
from all available drawings for a project.
|
||||
Attempts to extract text from PDFs if the corresponding TXT file is missing.
|
||||
Updates the 'found_drawing' flag in the manifest_data items directly.
|
||||
"""
|
||||
if not manifest_data:
|
||||
print(f"[{project_name}] Drawings Check: No manifest data provided.")
|
||||
return
|
||||
|
||||
print(f"[{project_name}] Starting Drawings check...")
|
||||
text_output_dir = utils.get_text_output_dir_path(project_name)
|
||||
pdf_source_dir = utils.get_pdf_dir_path(project_name)
|
||||
os.makedirs(text_output_dir, exist_ok=True) # Ensure output dir exists
|
||||
|
||||
# --- Preliminary Step: Ensure TXT exists for every PDF ---
|
||||
print(f"[{project_name}] Checking PDF source directory ({pdf_source_dir}) against text output directory ({text_output_dir})...")
|
||||
extraction_attempts = 0
|
||||
successful_extractions = 0
|
||||
failed_extractions = 0
|
||||
|
||||
if not os.path.isdir(pdf_source_dir):
|
||||
print(f" Warning: PDF source directory not found at '{pdf_source_dir}'. Skipping extraction check.")
|
||||
else:
|
||||
for pdf_filename in os.listdir(pdf_source_dir):
|
||||
if pdf_filename.lower().endswith('.pdf'):
|
||||
pdf_path = os.path.join(pdf_source_dir, pdf_filename)
|
||||
txt_filename = os.path.splitext(pdf_filename)[0] + '.txt'
|
||||
txt_path = os.path.join(text_output_dir, txt_filename)
|
||||
|
||||
if not os.path.exists(txt_path):
|
||||
extraction_attempts += 1
|
||||
print(f" TXT file '{txt_filename}' missing for PDF '{pdf_filename}'. Attempting extraction...")
|
||||
try:
|
||||
success = utils.extract_text_from_pdf(pdf_path, txt_path)
|
||||
if success:
|
||||
# print(f" Successfully extracted text to '{txt_filename}'.")
|
||||
successful_extractions += 1
|
||||
else:
|
||||
# print(f" Extraction failed or produced no text for '{pdf_filename}'.")
|
||||
failed_extractions += 1
|
||||
except AttributeError:
|
||||
print(f" ERROR: utils.extract_text_from_pdf function not found! Cannot extract text.")
|
||||
break # Stop trying if function missing
|
||||
except Exception as extract_err:
|
||||
print(f" Error during text extraction for '{pdf_filename}': {extract_err}")
|
||||
failed_extractions += 1
|
||||
|
||||
print(f"[{project_name}] Text extraction check complete. Attempted: {extraction_attempts}, Succeeded: {successful_extractions}, Failed: {failed_extractions}.")
|
||||
# --- End Preliminary Step ---
|
||||
|
||||
# --- Main Check: Scan all available TXT files and compare aliases ---
|
||||
print(f"[{project_name}] Reading and combining text from all .txt files in: {text_output_dir}...")
|
||||
|
||||
all_raw_content = "" # Combine all raw text content here
|
||||
processed_files = 0
|
||||
found_txt_files = []
|
||||
|
||||
try:
|
||||
if not os.path.isdir(text_output_dir):
|
||||
print(f" Error: Text output directory not found: {text_output_dir}. Cannot perform drawing check.")
|
||||
for item in manifest_data: item['found_drawing'] = False
|
||||
return
|
||||
|
||||
txt_files = [f for f in os.listdir(text_output_dir) if f.lower().endswith('.txt')]
|
||||
if not txt_files:
|
||||
print(" Warning: No .txt files found in the directory. Cannot perform drawing check.")
|
||||
for item in manifest_data: item['found_drawing'] = False
|
||||
return
|
||||
|
||||
for filename in txt_files:
|
||||
filepath = os.path.join(text_output_dir, filename)
|
||||
processed_files += 1
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
# Simple concatenation is sufficient now
|
||||
all_raw_content += content + "\n" # Add newline as separator
|
||||
found_txt_files.append(filename)
|
||||
except Exception as e:
|
||||
print(f" Warning: Could not read or process text file {filepath}: {e}")
|
||||
|
||||
print(f" Read content from {len(found_txt_files)} out of {processed_files} total .txt files found.")
|
||||
|
||||
# Step 2: Normalize the entire combined content ONCE
|
||||
print(f" Normalizing combined text content...")
|
||||
all_normalized_content = utils.normalize(all_raw_content)
|
||||
print(f" Normalization complete. Total normalized length: {len(all_normalized_content)} chars.")
|
||||
|
||||
# Step 3: Check each manifest alias against the normalized combined content
|
||||
found_count = 0
|
||||
checked_count = 0
|
||||
for item in manifest_data:
|
||||
# Ensure 'found_drawing' is initialized to False
|
||||
item['found_drawing'] = False
|
||||
|
||||
alias = item.get('alias') # Use lowercase 'alias' key
|
||||
if alias:
|
||||
checked_count += 1
|
||||
normalized_alias = utils.normalize(alias)
|
||||
if normalized_alias and normalized_alias in all_normalized_content:
|
||||
item['found_drawing'] = True
|
||||
found_count += 1
|
||||
# else: item['found_drawing'] remains False
|
||||
|
||||
print(f"[{project_name}] Drawings check finished. Checked {checked_count} aliases. Found {found_count} aliases within the combined drawing text.")
|
||||
|
||||
except Exception as e:
|
||||
print(f" Error during drawings check main phase: {e}")
|
||||
# Ensure flags are false on error
|
||||
for item in manifest_data: item['found_drawing'] = False
|
||||
60
manifest_reader.py
Normal file
60
manifest_reader.py
Normal file
@ -0,0 +1,60 @@
|
||||
import csv
|
||||
import config
|
||||
from utils import normalize, find_csv_path
|
||||
|
||||
def read_manifest(project_name):
|
||||
"""Reads the manifest CSV for a specific project into a list of dictionaries."""
|
||||
csv_filepath = find_csv_path(project_name)
|
||||
if not csv_filepath:
|
||||
return None
|
||||
|
||||
print(f"[{project_name}] Reading manifest: {csv_filepath}")
|
||||
manifest_items = []
|
||||
# Only require Alias and Panel now for basic grouping
|
||||
required_cols = {config.CSV_ALIAS_COL, config.CSV_PANEL_COL}
|
||||
optional_cols = {config.CSV_EQ_TYPE_COL, config.CSV_CONV_TYPE_COL}
|
||||
try:
|
||||
# Revert back to 'utf-8-sig' to handle potential BOM from Excel
|
||||
with open(csv_filepath, mode='r', newline='', encoding='utf-8-sig') as infile:
|
||||
reader = csv.DictReader(infile)
|
||||
# Strip whitespace from headers for reliable matching
|
||||
headers = set(h.strip() for h in reader.fieldnames if h) # Added 'if h' to handle potential empty headers
|
||||
|
||||
# Check for required columns
|
||||
missing_required = required_cols - headers
|
||||
if missing_required:
|
||||
print(f"Error: Missing required columns in CSV '{csv_filepath}': {', '.join(missing_required)}")
|
||||
print(f"Available columns: {', '.join(headers)}")
|
||||
return None
|
||||
|
||||
for row in reader:
|
||||
# Strip whitespace from values as well
|
||||
alias = row.get(config.CSV_ALIAS_COL, "").strip()
|
||||
panel = row.get(config.CSV_PANEL_COL, "").strip()
|
||||
|
||||
# Add if Alias and Control Panel are present (Panel needed for grouping results later)
|
||||
if alias and panel:
|
||||
item = {
|
||||
"alias": alias,
|
||||
"normalized_alias": normalize(alias),
|
||||
"control_panel": panel,
|
||||
# Add optional data if columns exist and have values
|
||||
"equipment_type": row.get(config.CSV_EQ_TYPE_COL, "").strip() if config.CSV_EQ_TYPE_COL in headers else "N/A",
|
||||
"conveyor_type": row.get(config.CSV_CONV_TYPE_COL, "").strip() if config.CSV_CONV_TYPE_COL in headers else "N/A",
|
||||
# Status fields to be filled later
|
||||
"found_scada": False,
|
||||
"found_drawing": False
|
||||
}
|
||||
manifest_items.append(item)
|
||||
elif alias and not panel:
|
||||
print(f"Warning: Alias '{alias}' found in CSV but is missing its '{config.CSV_PANEL_COL}'. Skipping.")
|
||||
# Add other specific warnings if needed
|
||||
|
||||
except FileNotFoundError:
|
||||
print(f"Error: Manifest file not found at {csv_filepath}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"Error reading CSV file {csv_filepath}: {e}")
|
||||
return None
|
||||
print(f"Read {len(manifest_items)} valid items from manifest.")
|
||||
return manifest_items
|
||||
@ -5,6 +5,7 @@ import os
|
||||
from pypdf import PdfReader
|
||||
import sys
|
||||
import re # Import the regex module
|
||||
import argparse # Import argparse
|
||||
|
||||
def normalize(text):
|
||||
"""Normalize string for comparison: lowercase, treat '-' and '_' the same, remove all whitespace."""
|
||||
@ -159,32 +160,18 @@ def find_missing_aliases(aliases, pdf_text):
|
||||
return sorted(list(missing)) # Return sorted list for consistent output
|
||||
|
||||
if __name__ == "__main__":
|
||||
# --- Configuration ---
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
default_manifest_path = os.path.join(script_dir, 'MTN6 Equipment Manifest REV6(Conveyor List).csv')
|
||||
default_pdf_folder = os.path.join(script_dir, 'pdfs')
|
||||
default_text_output_folder = os.path.join(script_dir, 'extracted_texts')
|
||||
# --- Argument Parsing ---
|
||||
parser = argparse.ArgumentParser(description='Check if aliases from a manifest CSV exist in text extracted from PDFs.')
|
||||
parser.add_argument('manifest_file', help='Path to the manifest CSV file.')
|
||||
parser.add_argument('pdf_folder', help='Path to the folder containing PDF files.')
|
||||
parser.add_argument('text_output_folder', help='Path to the folder where extracted text files should be saved/read from.')
|
||||
args = parser.parse_args()
|
||||
|
||||
manifest_file_path = default_manifest_path
|
||||
pdf_folder_path = default_pdf_folder
|
||||
text_output_folder_path = default_text_output_folder
|
||||
manifest_file_path = args.manifest_file
|
||||
pdf_folder_path = args.pdf_folder
|
||||
text_output_folder_path = args.text_output_folder
|
||||
|
||||
if len(sys.argv) == 3:
|
||||
manifest_file_path = sys.argv[1]
|
||||
pdf_folder_path = sys.argv[2]
|
||||
# If args are provided, still save text relative to script/default location,
|
||||
# or you could add a third argument for the text output path.
|
||||
print("Using command-line paths for Manifest and PDFs.")
|
||||
print(f" Manifest: {manifest_file_path}")
|
||||
print(f" PDF Folder: {pdf_folder_path}")
|
||||
print(f" Text Output Folder: {text_output_folder_path} (Default)")
|
||||
elif len(sys.argv) != 1: # Check if incorrect number of args were given (but not zero extra)
|
||||
print("Usage: python pdf_manifest_checker.py [<path_to_manifest.csv> <path_to_pdf_folder>]")
|
||||
print("If no arguments are provided, default paths will be used.")
|
||||
sys.exit(1) # Exit if incorrect arguments
|
||||
else:
|
||||
# No arguments provided, use defaults
|
||||
print("Using default paths:")
|
||||
print("Using provided paths:")
|
||||
print(f" Manifest: {manifest_file_path}")
|
||||
print(f" PDF Folder: {pdf_folder_path}")
|
||||
print(f" Text Output Folder: {text_output_folder_path}")
|
||||
|
||||
72
progress_calculator.py
Normal file
72
progress_calculator.py
Normal file
@ -0,0 +1,72 @@
|
||||
def calculate_combined_progress(project_name, manifest_data):
|
||||
"""Calculates the combined progress based on scada/drawing status for a project."""
|
||||
print(f"[{project_name}] Calculating combined progress statistics...")
|
||||
results = {
|
||||
"overall": {
|
||||
"total_csv": 0, "found_both": 0, "found_scada_only": 0, "found_drawing_only": 0, "missing_both": 0,
|
||||
"percentage_found_both": 0,
|
||||
"missing_list": [], "found_scada_only_list": [], "found_drawing_only_list": [], "found_both_list": []
|
||||
},
|
||||
"panels": {}
|
||||
}
|
||||
if not manifest_data:
|
||||
print("Warning: No manifest data to calculate progress from.")
|
||||
return results # Return the empty structure
|
||||
|
||||
results["overall"]["total_csv"] = len(manifest_data)
|
||||
|
||||
for item in manifest_data:
|
||||
panel = item.get('control_panel', 'Unknown Panel') # Use get with default
|
||||
|
||||
# Initialize panel data if not present
|
||||
if panel not in results["panels"]:
|
||||
results["panels"][panel] = {
|
||||
"total": 0, "found_both": 0, "found_scada_only": 0, "found_drawing_only": 0, "missing_both": 0,
|
||||
"percentage_found_both": 0,
|
||||
"missing_list": [], "found_scada_only_list": [], "found_drawing_only_list": [], "found_both_list": []
|
||||
}
|
||||
|
||||
results["panels"][panel]["total"] += 1
|
||||
|
||||
# Categorize and add to lists
|
||||
# Create a copy of the item detail to avoid modifying the original if needed later
|
||||
# Exclude 'normalized_alias' from the output dictionary
|
||||
item_detail = {k: v for k, v in item.items() if k != 'normalized_alias'}
|
||||
|
||||
found_scada = item.get('found_scada', False)
|
||||
found_drawing = item.get('found_drawing', False)
|
||||
|
||||
if found_scada and found_drawing:
|
||||
category = "found_both"
|
||||
elif found_scada and not found_drawing:
|
||||
category = "found_scada_only"
|
||||
elif not found_scada and found_drawing:
|
||||
category = "found_drawing_only"
|
||||
else: # Missing both
|
||||
category = "missing_both"
|
||||
|
||||
results["overall"][category] += 1
|
||||
results["panels"][panel][category] += 1
|
||||
# Correct the list keys used for appending
|
||||
if category == "missing_both":
|
||||
results["overall"]["missing_list"].append(item_detail)
|
||||
results["panels"][panel]["missing_list"].append(item_detail)
|
||||
else:
|
||||
results["overall"][f"{category}_list"].append(item_detail)
|
||||
results["panels"][panel][f"{category}_list"].append(item_detail)
|
||||
|
||||
|
||||
# Calculate percentages
|
||||
if results["overall"]["total_csv"] > 0:
|
||||
results["overall"]["percentage_found_both"] = round(
|
||||
(results["overall"]["found_both"] / results["overall"]["total_csv"]) * 100, 1
|
||||
)
|
||||
for panel_data in results["panels"].values():
|
||||
if panel_data["total"] > 0:
|
||||
panel_data["percentage_found_both"] = round(
|
||||
(panel_data["found_both"] / panel_data["total"]) * 100, 1
|
||||
)
|
||||
|
||||
print("Combined progress calculation finished.")
|
||||
# print(json.dumps(results, indent=2)) # DEBUG: Print structure if needed
|
||||
return results
|
||||
806
projects/MTN6 copy/extracted_texts/MTN6_SYSDL-MCM05.txt
Normal file
806
projects/MTN6 copy/extracted_texts/MTN6_SYSDL-MCM05.txt
Normal file
@ -0,0 +1,806 @@
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
PRS1_2A_VFD13HP120 FPMPRS1_2B_VFD13HP120 FPM
|
||||
PRS1_3_VFD17.5HP120 FPM
|
||||
PRS1_4_VFD13HP120 FPMPRS1_6_VFD12HP120 FPMPRS2_1_VFD17.5HP120 FPM
|
||||
PRS1_2A_JPE1
|
||||
EPCPRS1_6_EPC1
|
||||
EPCPRS1_6_EPC2
|
||||
EPCPRS2_1_EPC1
|
||||
EPCPRS2_1_EPC2GPRS2_1_S1
|
||||
GPRS2_1_S2BBR
|
||||
ABBWPRS1_2A_JR2
|
||||
ABBWPRS1_3_JR1
|
||||
ABBWPRS1_4_JR1GPRS1_6_S1BBR
|
||||
GPRS1_6_S2BBR
|
||||
11'-3" EL
|
||||
9'-1" EL
|
||||
ULC1_3_VFD12HP80FPMULC2_3_VFD12HP80FPMULC3_3_VFD12HP80FPMULC4_3_VFD12HP80FPM
|
||||
PS8_1_VFD17.5HP140-200 FPM
|
||||
PS8_2_VFD110HP180-240 FPM
|
||||
PS8_4_VFD115HP240 FPM PS8_5_VFD115HP240 FPM
|
||||
PS9_2_VFD17.5HP240 FPM
|
||||
PS8_8_VFD17.5HP220-330 FPM
|
||||
PS8_9_VFD115HP240 FPM
|
||||
PS8_11_VFD110HP240 FPM
|
||||
PS8_11_DIV1_LS1LSPS8_11_DIV1_LS2LSSOLPS8_11_DIV1_SOL1SOLPS8_11_DIV1_SOL2
|
||||
PS8_11_DIV2_LS1LSPS8_11_DIV2_LS2LSSOLPS8_11_DIV2_SOL1SOLPS8_11_DIV2_SOL2
|
||||
PS8_5_JPE1
|
||||
PS8_11_JPE1
|
||||
PS8_2_JPE1
|
||||
PS8_1_JPE6
|
||||
PS8_11_FIO1
|
||||
WPS8_11_JR1ABB
|
||||
WPS8_11_JR2
|
||||
WPS8_9_JR1ABBPS8_5_SIO1
|
||||
ABB
|
||||
WPS8_1_JR2ABB RABB EPCULC1_3_EPC1
|
||||
EPCULC1_3_EPC2
|
||||
EPCULC2_3_EPC1
|
||||
EPCULC3_3_EPC1
|
||||
EPCULC4_3_EPC1
|
||||
EPCPS8_2_EPC1
|
||||
EPCPS8_1_EPC1
|
||||
EPCPS8_11_EPC1
|
||||
GPS8_11_S1ABBR
|
||||
EPCPS8_5_EPC2ABBR
|
||||
GPS8_5_S2
|
||||
ABBR
|
||||
EPCPS8_4_EPC1
|
||||
EPCPS8_4_EPC2
|
||||
BB
|
||||
BBR
|
||||
ARGPS8_4_S1
|
||||
GPS8_4_S2 EPCPS8_5_EPC1GPS8_5_S1ABBR
|
||||
PS8_1_FIO1PS8_1_FIO2
|
||||
BB
|
||||
PS8_12CH_FPE1
|
||||
GBBAB
|
||||
EPCPS8_2_EPC2
|
||||
ULC1_3_JPE1
|
||||
B
|
||||
EPCPS9_2_EPC1
|
||||
GPS9_2_S1
|
||||
PS8-12CH-PS1PS
|
||||
PS8_11_CH1_JPE1PS8_11_CH1_FPE1GPS8_11_CH1_S1
|
||||
VV
|
||||
FL_DPM3MCM05
|
||||
FL_DPM4MCM05
|
||||
ULGLA_DPM1MCM05
|
||||
PRS2_DPM1MCM05
|
||||
CH_DPM7MCM05 CH_DPM8MCM05 CH_DPM10MCM05 CH_DPM11MCM05
|
||||
R
|
||||
GPS8_2_S2
|
||||
GPS8_2_S1BBR
|
||||
PS8_4_SIO1 PS8_6_FIO1
|
||||
PS8_6_VFD15HP240 FPM
|
||||
PS8_8_TPE1PS8_8_TPE2 PS8_9_SIO1PS8_9_JPE1
|
||||
PS8_11_TPE1
|
||||
PS8_11_CH1_FPE2PS8_11_JPE2PS8_11_CH2_JPE1PS8_11_CH2_FPE1PS8_11_CH2_FPE2
|
||||
GPS8_11_CH2_S1GBBAB PS8_11_FIO2
|
||||
PS8_11_DIV3_LS1LSPS8_11_DIV3_LS2LSSOLPS8_11_DIV3_SOL1SOLPS8_11_DIV3_SOL2
|
||||
PS8_11_DIV4_LS1LSPS8_11_DIV4_LS2LSSOLPS8_11_DIV4_SOL1SOLPS8_11_DIV4_SOL2
|
||||
PS8_11_FIO3GBBABPS8_11_CH3_JPE1PS8_11_CH3_FPE1GPS8_11_CH3_S1
|
||||
PS8_11_CH3_FPE2PS8_11_JPE4PS8_11_CH4_JPE1PS8_11_CH4_FPE1PS8_11_CH4_FPE2
|
||||
GPS8_11_CH4_S1GBBAB PS8_11_FIO4
|
||||
PS8_11_JPE3
|
||||
ABPS8_11_JPE5PS8_11_FIO5
|
||||
EPCPS9_2_EPC2BBRGPS9_2_S2PS9_1CH_JPE1
|
||||
PS9_2_TPE1
|
||||
PS9_3_VFD17.5HP190-270 FPM
|
||||
WPS9_3_JR1ABB
|
||||
PS9_3_FIO1 EPCPS9_3_EPC1ABBRB PS9-3-PS1PS
|
||||
GPS9_3_S1
|
||||
PS9_3_JPE1
|
||||
GBBAB
|
||||
GBBAB
|
||||
GPS9_3CH2_S1
|
||||
GPS9_3CH1_S1
|
||||
PS9_3CH2_JPE1PS9_3CH2_FPE1PS9_3CH2_FPE2
|
||||
PS9_3CH1_JPE1PS9_3CH1_FPE1PS9_3CH1_FPE2
|
||||
GBBAB
|
||||
GBBAB
|
||||
GPS9_3CH4_S1
|
||||
GPS9_3CH6_S1
|
||||
PS9_3CH4_JPE1PS9_3CH4_FPE1PS9_3CH4_FPE2PS9_3CH3_JPE1PS9_3CH6_FPE1PS9_3CH6_FPE2
|
||||
PS9_3DIV1_LS1LSPS9_3DIV1_LS2LSSOLPS9_3DIV1_SOL1SOLPS9_3DIV1_SOL2
|
||||
PS9_3DIV2_LS1LSPS9_3DIV2_LS2LSSOLPS9_3DIV2_SOL1SOLPS9_3DIV2_SOL2
|
||||
PS9_3DIV3_LS1LSPS9_3DIV3_LS2LSSOLPS9_3DIV3_SOL1SOLPS9_3DIV3_SOL2
|
||||
PS9_3DIV4_LS1LSPS9_3DIV4_LS2LSSOLPS9_3DIV4_SOL1SOLPS9_3DIV4_SOL2
|
||||
PS9_3_FIO2PS9_3_JPE3
|
||||
PS9_3_FIO3PS9_3_JPE4
|
||||
PS9_3_FIO4
|
||||
PS9_3_JPE5PS9_4CH_FPE1
|
||||
RGULC1_3_SS1
|
||||
ULC1_3_ENC1
|
||||
PS8_1_ENC1
|
||||
PS8_2_ENC1
|
||||
PS8_4_ENC1 PS8_5_ENC1 PS8_8_ENC1 PS8_9_ENC1
|
||||
PS8_11_ENC1PS9_2_ENC1
|
||||
ULC1_3_JPE2
|
||||
RGULC1_3_SS2ULC2_3_JPE1ULC3_3_JPE1ULC4_3_JPE1
|
||||
ULC2_3_ENC1ULC3_3_ENC1ULC4_3_ENC1RABBULC2_3_JPE2RABBULC3_3_JPE2RABBULC4_3_JPE2
|
||||
WULC1_3_JR1
|
||||
WULC2_3_JR1
|
||||
WULC3_3_JR1
|
||||
WULC4_3_JR1
|
||||
RGULC2_3_SS1RGULC3_3_SS1RGULC4_3_SS1
|
||||
PS8_1_FIO3PS8_1_FIO4PS8_1_FIO5
|
||||
RGPS8_1_SS1
|
||||
PS8_1_JPE2PS8_1_JPE1PS8_1_JPE3PS8_1_JPE4PS8_1_JPE5
|
||||
WPS8_1_JR1ABB
|
||||
PRS1_1ACH_JPE1
|
||||
WPRS1_2A_JR1ABBB
|
||||
PRS1_2A_FIO1
|
||||
ABBRPRS2_1_JPE1
|
||||
PRS1_2A_JPE2
|
||||
PRS1_1BCH_JPE1ABBBPRS1_2B_JPE1
|
||||
WPRS1_2B_JR1PRS1_2B_FIO1PRS1_2B_JPE2ABBWPRS1_2B_JR2PRS1_3_FIO1
|
||||
PRS1_3_JPE1
|
||||
PRS1_4_FIO1
|
||||
PRS1_3_JPE2
|
||||
PRS1_4_JPE1PRS1_4_JPE2PRS1_5CH_JPE1PRS1_5CH_FPE1PRS1_6_TPE1
|
||||
PRS1_6_TPE2
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASHTRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
ERSCPRS1-7-ERSC1
|
||||
MDR POWER SUPPLYPRS1-7-PS180AMDR POWER SUPPLYPRS1-7-PS280A
|
||||
PRS1_7_PE1PRS1_7_PE2PRS1_7_PE3PRS1_7_PE4PRS1_7_PE5PRS1_7_PE6PRS1_7_PE7PRS1_7_PE8PRS1_7_PE9PRS1_7_PE10PRS1_7_PE11PRS1_7_PE12PRS1_7_PE13PRS1_7_PE14PRS1_7_PE15PRS1_7_PE16PRS1_7_PE17PRS1_7_PE18PRS1_7_PE19PRS1_7_PE20PRS1_7_PE21PRS1_7_PE22PRS1_7_PE23PRS1_7_PE24PRS1_7_PE25PRS1_7_PE26PRS1_7_PE27
|
||||
ERSCPRS1-7-ERSC2
|
||||
ERSCPRS1-7-ERSC3
|
||||
ERSCPRS1-7-ERSC4
|
||||
ERSCPRS1-7-ERSC5
|
||||
ERSCPRS1-7-ERSC6
|
||||
ERSCPRS1-7-ERSC7
|
||||
ERSCPRS1-7-ERSC8
|
||||
ERSCPRS1-7-ERSC9
|
||||
ERSCPRS1-7-ERSC10
|
||||
ERSCPRS1-7-ERSC11
|
||||
ERSCPRS1-7-ERSC12
|
||||
ERSCPRS1-7-ERSC13
|
||||
ERSCPRS1-7-ERSC14
|
||||
GDTC_SCH1_EN1
|
||||
GDTC_SCH2_EN1BBGABBBGB
|
||||
FL2074_2_PE1ABBB
|
||||
FL2074_1CH_PE1
|
||||
FL2074_2_PE2
|
||||
FL2074_2_VFD15HP350FPM
|
||||
FL2074_3CH_PE1BBBWFL2074_2_JR2
|
||||
WFL2074_2_JR1
|
||||
FL2078_2_PE1ABBB
|
||||
FL2078_1CH_PE1
|
||||
FL2078_2_PE2
|
||||
FL2078_2_VFD15HP350FPM
|
||||
FL2078_3CH_PE1BBBWFL2078_2_JR2
|
||||
WFL2078_2_JR1
|
||||
FL2086_2_PE1ABBB
|
||||
FL2086_1CH_PE1
|
||||
FL2086_2_PE2
|
||||
FL2086_2_VFD15HP350FPM
|
||||
FL2086_3CH_PE1BBBWFL2086_2_JR2
|
||||
WFL2086_2_JR1
|
||||
FL2090_2_PE1ABBB
|
||||
FL2090_1CH_PE1
|
||||
FL2090_2_PE2
|
||||
FL2090_2_VFD15HP350FPM
|
||||
FL2090_3CH_PE1BBBWFL2090_2_JR2
|
||||
WFL2090_2_JR1
|
||||
FL2094_2_PE1ABBB
|
||||
FL2094_1CH_PE1
|
||||
FL2094_2_PE2
|
||||
FL2094_2_VFD15HP350FPM
|
||||
FL2094_3CH_PE1BBBWFL2094_2_JR2
|
||||
WFL2094_2_JR1
|
||||
FL4082_2_PE1ABBB
|
||||
FL4082_1CH_PE1
|
||||
FL4082_2_PE2
|
||||
FL4082_2_VFD15HP350FPM
|
||||
FL4082_3CH_PE1BBBWFL4082_2_JR2
|
||||
WFL4082_2_JR1
|
||||
FL4078_2_PE1ABBB
|
||||
FL4078_1CH_PE1
|
||||
FL4078_2_PE2
|
||||
FL4078_2_VFD15HP350FPM
|
||||
FL4078_3CH_PE1BBBWFL4078_2_JR2
|
||||
WFL4078_2_JR1
|
||||
FL4074_2_PE1ABBB
|
||||
FL4074_1CH_PE1
|
||||
FL4074_2_PE2
|
||||
FL4074_2_VFD15HP350FPM
|
||||
FL4074_3CH_PE1BBBWFL4074_2_JR2
|
||||
WFL4074_2_JR1
|
||||
FL4070_2_PE1ABBB
|
||||
FL4070_1CH_PE1
|
||||
FL4070_2_PE2
|
||||
FL4070_2_VFD15HP350FPM
|
||||
FL4070_3CH_PE1BBBWFL4070_2_JR2
|
||||
WFL4070_2_JR1
|
||||
FL4066_2_PE1ABBB
|
||||
FL4066_1CH_PE1
|
||||
FL4066_2_PE2
|
||||
FL4066_2_VFD15HP350FPM
|
||||
FL4066_3CH_PE1BBBWFL4066_2_JR2
|
||||
WFL4066_2_JR1
|
||||
CH_DPM9MCM05 CH_DPM12MCM05CH_DPM7_FIOM2CH_DPM7_FIOM1CH_DPM7_FIOM4CH_DPM7_FIOM3CH_DPM7_FIOM6CH_DPM7_FIOM5CH_DPM7_FIOM8CH_DPM7_FIOM7CH_DPM8_FIOM2CH_DPM8_FIOM1CH_DPM8_FIOM4CH_DPM8_FIOM3CH_DPM8_FIOM6CH_DPM8_FIOM5CH_DPM8_FIOM8CH_DPM8_FIOM7CH_DPM9_FIOM2CH_DPM9_FIOM1CH_DPM9_FIOM4CH_DPM9_FIOM3CH_DPM9_FIOM5CH_DPM9_FIOM6 CH_DPM10_FIOM2CH_DPM10_FIOM1CH_DPM10_FIOM4CH_DPM10_FIOM3CH_DPM10_FIOM6CH_DPM10_FIOM5CH_DPM10_FIOM8CH_DPM10_FIOM7CH_DPM11_FIOM2CH_DPM11_FIOM1CH_DPM11_FIOM4CH_DPM11_FIOM3CH_DPM11_FIOM6CH_DPM11_FIOM5CH_DPM11_FIOM8CH_DPM11_FIOM7CH_DPM12_FIOM2CH_DPM12_FIOM1CH_DPM12_FIOM4CH_DPM12_FIOM3
|
||||
GDTC_SCH3_EN1BBGB
|
||||
GDTC_SCH4_EN1BBGB
|
||||
GDTC_SCH5_EN1BBGAB
|
||||
GDTC_SCH6_EN1BBGB
|
||||
GDTC_SCH7_EN1BBGB
|
||||
GDTC_SCH8_EN1BBGB
|
||||
GDTC_SCH10_EN1BBGB
|
||||
GDTC_SCH11_EN1BBGB
|
||||
GDTC_SCH12_EN1BBGB
|
||||
GDTC_SCH14_EN1BBGB
|
||||
GDTC_SCH15_EN1BBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GBBGB
|
||||
GDTC_SCH41_EN1BBGB
|
||||
GDTC_SCH42_EN1BBGB
|
||||
GDTC_SCH45_EN1BBGB
|
||||
GDTC_SCH48_EN1BBGB
|
||||
GDTC_SCH50_EN1BBGB
|
||||
GDTC_SCH51_EN1BBGB
|
||||
GDTC_SCH52_EN1BBGB
|
||||
GDTC_SCH54_EN1BBGB
|
||||
GDTC_SCH55_EN1BBGB
|
||||
GDTC_SCH57_EN1BBGB
|
||||
GDTC_SCH58_EN1BBGB
|
||||
GDTC_SCH60_EN1BBGB
|
||||
GDTC_SCH61_EN1BBGB
|
||||
GDTC_SCH63_EN1BBGB
|
||||
GDTC_SCH64_EN1BBGB
|
||||
GDTC_SCH65_EN1BBGB
|
||||
GDTC_SCH67_EN1BBGB
|
||||
GDTC_SCH68_EN1BBGB
|
||||
GDTC_SCH69_EN1BBGB
|
||||
GDTC_SCH9_EN1BBGAB
|
||||
GDTC_SCH13_EN1BBGAB
|
||||
GDTC_SCH16_EN1BBGAB BBGAB
|
||||
G G G G GBBGAB BBGAB BBGAB BBGAB BBGAB
|
||||
G
|
||||
GDTC_SCH40_EN1BBGAB
|
||||
GDTC_SCH43_EN1BBGAB
|
||||
GDTC_SCH46_EN1BBGAB
|
||||
GDTC_SCH49_EN1BBGAB
|
||||
GDTC_SCH44_EN1BBGB
|
||||
GDTC_SCH47_EN1BBGB
|
||||
GDTC_SCH53_EN1BBGAB
|
||||
GDTC_SCH56_EN1BBGAB
|
||||
GDTC_SCH59_EN1BBGAB
|
||||
GDTC_SCH62_EN1BBGAB
|
||||
GDTC_SCH66_EN1BBGAB
|
||||
PB_SCH1_FIOH1
|
||||
PB_SCH1_PE1
|
||||
PB_SCH1_PE2
|
||||
BBGAB
|
||||
W
|
||||
PB_SCH1_PKGREL_PB1
|
||||
SOLPB_SCH1_PKGREL_SOL1
|
||||
BBGB
|
||||
PB_SCH2_PE1
|
||||
PB_SCH2_PE2
|
||||
SOL
|
||||
PB_SCH2_PKGREL_SOL1
|
||||
WPB_SCH2_PKGREL_PB1
|
||||
PB_SCH3_FIOH1PB_SCH5_FIOH1PB_SCH7_FIOH1PB_SCH9_FIOH1PB_SCH11_FIOH1PB_SCH13_FIOH1PB_SCH15_FIOH1PB_SCH17_FIOH1PB_SCH18_FIOH1PB_SCH20_FIOH1PB_SCH22_FIOH1PB_SCH24_FIOH1PB_SCH26_FIOH1PB_SCH28_FIOH1PB_SCH30_FIOH1PB_SCH32_FIOH1PB_SCH33_FIOH1PB_SCH35_FIOH1PB_SCH36_FIOH1PB_SCH38_FIOH1PB_SCH39_FIOH1PB_SCH40_FIOH1PB_SCH41_FIOH1 PB_SCH42_FIOH1PB_SCH43_FIOH1PB_SCH44_FIOH1PB_SCH45_FIOH1PB_SCH46_FIOH1PB_SCH48_FIOH1PB_SCH50_FIOH1PB_SCH52_FIOH1PB_SCH54_FIOH1PB_SCH56_FIOH1PB_SCH58_FIOH1PB_SCH60_FIOH1PB_SCH62_FIOH1PB_SCH63_FIOH1PB_SCH65_FIOH1PB_SCH67_FIOH1PB_SCH69_FIOH1PB_SCH71_FIOH1PB_SCH73_FIOH1PB_SCH75_FIOH1
|
||||
BBGB
|
||||
PB_SCH3_PE1
|
||||
PB_SCH3_PE2
|
||||
SOLPB_SCH3_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH3_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH4_PE1
|
||||
PB_SCH4_PE2
|
||||
SOL
|
||||
PB_SCH4_PKGREL_SOL1
|
||||
WPB_SCH4_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH6_PE1
|
||||
PB_SCH6_PE2
|
||||
SOL
|
||||
PB_SCH6_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH6_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH7_PE1
|
||||
PB_SCH7_PE2
|
||||
SOLPB_SCH7_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH7_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH8_PE1
|
||||
PB_SCH8_PE2
|
||||
SOLPB_SCH8_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH8_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH10_PE1
|
||||
PB_SCH10_PE2
|
||||
SOLPB_SCH10_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH10_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH11_PE1
|
||||
PB_SCH11_PE2
|
||||
SOLPB_SCH11_PKGREL_SOL1
|
||||
WPB_SCH11_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH12_PE1
|
||||
PB_SCH12_PE2
|
||||
SOLPB_SCH12_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH12_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH14_PE1
|
||||
PB_SCH14_PE2
|
||||
SOLPB_SCH14_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH14_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH15_PE1
|
||||
PB_SCH15_PE2
|
||||
SOL
|
||||
PB_SCH15_PKGREL_SOL1
|
||||
WPB_SCH15_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH16_PE1
|
||||
PB_SCH16_PE2
|
||||
SOLPB_SCH16_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH16_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH18_PE1
|
||||
PB_SCH18_PE2
|
||||
SOLPB_SCH18_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH18_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH19_PE1
|
||||
PB_SCH19_PE2
|
||||
SOLPB_SCH19_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH19_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH21_PE1
|
||||
PB_SCH21_PE2
|
||||
SOLPB_SCH21_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH21_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH22_PE1
|
||||
PB_SCH22_PE2
|
||||
SOLPB_SCH22_PKGREL_SOL1
|
||||
WPB_SCH22_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH23_PE1
|
||||
PB_SCH23_PE2
|
||||
SOLPB_SCH23_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH23_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH25_PE1
|
||||
PB_SCH25_PE2
|
||||
SOLPB_SCH25_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH25_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH26_PE1
|
||||
PB_SCH26_PE2
|
||||
SOLPB_SCH26_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH26_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH27_PE1
|
||||
PB_SCH27_PE2
|
||||
SOLPB_SCH27_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH27_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH29_PE1
|
||||
PB_SCH29_PE2
|
||||
SOLPB_SCH29_PKGREL_SOL1
|
||||
WPB_SCH29_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH30_PE1
|
||||
PB_SCH30_PE2
|
||||
SOLPB_SCH30_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH30_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH31_PE1
|
||||
PB_SCH31_PE2
|
||||
SOLPB_SCH31_PKGREL_SOL1
|
||||
WPB_SCH31_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH33_PE1
|
||||
PB_SCH33_PE2
|
||||
SOLPB_SCH33_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH33_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH34_PE1
|
||||
PB_SCH34_PE2
|
||||
SOLPB_SCH34_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH34_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH36_PE1
|
||||
PB_SCH36_PE2
|
||||
SOL
|
||||
PB_SCH36_PKGREL_SOL1
|
||||
WPB_SCH36_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH37_PE1
|
||||
PB_SCH37_PE2
|
||||
SOLPB_SCH37_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH37_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH39_PE1
|
||||
PB_SCH39_PE2
|
||||
SOLPB_SCH39_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH39_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH41_PE1
|
||||
PB_SCH41_PE2
|
||||
SOLPB_SCH41_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH41_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH43_PE1
|
||||
PB_SCH43_PE2
|
||||
SOLPB_SCH43_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH43_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH45_PE1
|
||||
PB_SCH45_PE2
|
||||
SOLPB_SCH45_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH45_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH47_PE1
|
||||
PB_SCH47_PE2
|
||||
SOL
|
||||
PB_SCH47_PKGREL_SOL1
|
||||
WPB_SCH47_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH49_PE1
|
||||
PB_SCH49_PE2
|
||||
SOL
|
||||
PB_SCH49_PKGREL_SOL1
|
||||
WPB_SCH49_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH50_PE1
|
||||
PB_SCH50_PE2
|
||||
SOLPB_SCH50_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH50_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH51_PE1
|
||||
PB_SCH51_PE2
|
||||
SOL
|
||||
PB_SCH51_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH51_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH53_PE1
|
||||
PB_SCH53_PE2
|
||||
SOLPB_SCH53_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH53_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH54_PE1
|
||||
PB_SCH54_PE2
|
||||
SOLPB_SCH54_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH54_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH55_PE1
|
||||
PB_SCH55_PE2
|
||||
SOLPB_SCH55_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH55_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH57_PE1
|
||||
PB_SCH57_PE2
|
||||
SOLPB_SCH57_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH57_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH58_PE1
|
||||
PB_SCH58_PE2
|
||||
SOLPB_SCH58_PKGREL_SOL1
|
||||
WPB_SCH58_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH59_PE1
|
||||
PB_SCH59_PE2
|
||||
SOLPB_SCH59_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH59_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH61_PE1
|
||||
PB_SCH61_PE2
|
||||
SOLPB_SCH61_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH61_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH62_PE1
|
||||
PB_SCH62_PE2
|
||||
SOL
|
||||
PB_SCH62_PKGREL_SOL1
|
||||
WPB_SCH62_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH64_PE1
|
||||
PB_SCH64_PE2
|
||||
SOLPB_SCH64_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH64_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH65_PE1
|
||||
PB_SCH65_PE2
|
||||
SOL
|
||||
PB_SCH65_PKGREL_SOL1
|
||||
WPB_SCH65_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH66_PE1
|
||||
PB_SCH66_PE2
|
||||
SOLPB_SCH66_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH66_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH68_PE1
|
||||
PB_SCH68_PE2
|
||||
SOLPB_SCH68_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH68_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH69_PE1
|
||||
PB_SCH69_PE2
|
||||
SOL
|
||||
PB_SCH69_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH69_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH70_PE1
|
||||
PB_SCH70_PE2
|
||||
SOLPB_SCH70_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH70_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH72_PE1
|
||||
PB_SCH72_PE2
|
||||
SOLPB_SCH72_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH72_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH73_PE1
|
||||
PB_SCH73_PE2
|
||||
SOLPB_SCH73_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH73_PKGREL_PB1
|
||||
BBGB
|
||||
PB_SCH75_PE1
|
||||
PB_SCH75_PE2
|
||||
SOLPB_SCH75_PKGREL_SOL1
|
||||
W
|
||||
PB_SCH75_PKGREL_PB1
|
||||
PB_SCH5_PE1
|
||||
PB_SCH5_PE2
|
||||
BBGAB
|
||||
W
|
||||
PB_SCH5_PKGREL_PB1
|
||||
SOLPB_SCH5_PKGREL_SOL1
|
||||
PB_SCH9_PE1
|
||||
PB_SCH9_PE2
|
||||
BBGAB
|
||||
WPB_SCH9_PKGREL_PB1
|
||||
SOLPB_SCH9_PKGREL_SOL1
|
||||
PB_SCH13_PE1
|
||||
PB_SCH13_PE2
|
||||
BBGAB
|
||||
WPB_SCH13_PKGREL_PB1
|
||||
SOLPB_SCH13_PKGREL_SOL1
|
||||
PB_SCH17_PE1
|
||||
PB_SCH17_PE2
|
||||
BBGAB
|
||||
WPB_SCH17_PKGREL_PB1
|
||||
SOL
|
||||
PB_SCH17_PKGREL_SOL1
|
||||
PB_SCH20_PE1
|
||||
PB_SCH20_PE2
|
||||
BBGAB
|
||||
WPB_SCH20_PKGREL_PB1
|
||||
SOLPB_SCH20_PKGREL_SOL1
|
||||
PB_SCH24_PE1
|
||||
PB_SCH24_PE2
|
||||
BBGAB
|
||||
WPB_SCH24_PKGREL_PB1
|
||||
SOL
|
||||
PB_SCH24_PKGREL_SOL1
|
||||
PB_SCH28_PE1
|
||||
PB_SCH28_PE2
|
||||
BBGAB
|
||||
W
|
||||
PB_SCH28_PKGREL_PB1
|
||||
SOLPB_SCH28_PKGREL_SOL1
|
||||
PB_SCH32_PE1
|
||||
PB_SCH32_PE2
|
||||
BBGAB
|
||||
W
|
||||
PB_SCH32_PKGREL_PB1
|
||||
SOLPB_SCH32_PKGREL_SOL1
|
||||
PB_SCH35_PE1
|
||||
PB_SCH35_PE2
|
||||
BBGAB
|
||||
W
|
||||
PB_SCH35_PKGREL_PB1
|
||||
SOL
|
||||
PB_SCH35_PKGREL_SOL1
|
||||
PB_SCH38_PE1
|
||||
PB_SCH38_PE2
|
||||
BBGAB
|
||||
WPB_SCH38_PKGREL_PB1
|
||||
SOL
|
||||
PB_SCH38_PKGREL_SOL1
|
||||
PB_SCH40_PE1
|
||||
PB_SCH40_PE2
|
||||
BBGAB
|
||||
W
|
||||
PB_SCH40_PKGREL_PB1
|
||||
SOLPB_SCH40_PKGREL_SOL1
|
||||
PB_SCH42_PE1
|
||||
PB_SCH42_PE2
|
||||
BBGAB
|
||||
WPB_SCH42_PKGREL_PB1
|
||||
SOLPB_SCH42_PKGREL_SOL1
|
||||
PB_SCH44_PE1
|
||||
PB_SCH44_PE2
|
||||
BBGAB
|
||||
W
|
||||
PB_SCH44_PKGREL_PB1
|
||||
SOLPB_SCH44_PKGREL_SOL1
|
||||
PB_SCH46_PE1
|
||||
PB_SCH46_PE2
|
||||
BBGAB
|
||||
W
|
||||
PB_SCH46_PKGREL_PB1
|
||||
SOLPB_SCH46_PKGREL_SOL1
|
||||
PB_SCH48_PE1
|
||||
PB_SCH48_PE2
|
||||
BBGAB
|
||||
W
|
||||
PB_SCH48_PKGREL_PB1
|
||||
SOLPB_SCH48_PKGREL_SOL1
|
||||
PB_SCH52_PE1
|
||||
PB_SCH52_PE2
|
||||
BBGAB
|
||||
W
|
||||
PB_SCH52_PKGREL_PB1
|
||||
SOLPB_SCH52_PKGREL_SOL1
|
||||
PB_SCH56_PE1
|
||||
PB_SCH56_PE2
|
||||
BBGAB
|
||||
WPB_SCH56_PKGREL_PB1
|
||||
SOLPB_SCH56_PKGREL_SOL1
|
||||
PB_SCH60_PE1
|
||||
PB_SCH60_PE2
|
||||
BBGAB
|
||||
WPB_SCH60_PKGREL_PB1
|
||||
SOL
|
||||
PB_SCH60_PKGREL_SOL1
|
||||
PB_SCH63_PE1
|
||||
PB_SCH63_PE2
|
||||
BBGAB
|
||||
WPB_SCH63_PKGREL_PB1
|
||||
SOL
|
||||
PB_SCH63_PKGREL_SOL1
|
||||
PB_SCH67_PE1
|
||||
PB_SCH67_PE2
|
||||
BBGAB
|
||||
WPB_SCH67_PKGREL_PB1
|
||||
SOL
|
||||
PB_SCH67_PKGREL_SOL1
|
||||
PB_SCH71_PE1
|
||||
PB_SCH71_PE2
|
||||
BBGAB
|
||||
W
|
||||
PB_SCH71_PKGREL_PB1
|
||||
SOLPB_SCH71_PKGREL_SOL1
|
||||
PB_SCH74_PE1
|
||||
PB_SCH74_PE2
|
||||
BBGAB
|
||||
WPB_SCH74_PKGREL_PB1
|
||||
SOLPB_SCH74_PKGREL_SOL1
|
||||
MCM05
|
||||
MCM05
|
||||
387
projects/MTN6 copy/extracted_texts/MTN6_SYSDL-MCM06.txt
Normal file
387
projects/MTN6 copy/extracted_texts/MTN6_SYSDL-MCM06.txt
Normal file
@ -0,0 +1,387 @@
|
||||
ST 4.0kW 1.4375
|
||||
CL
|
||||
ST 1.5kW 1.4375
|
||||
12'-11"
|
||||
12'-11"
|
||||
S02-101CH2S02-101CH4S02-101CH6S02-101CH8S02-101CH10S02-101CH12S02-101CH14S02-101CH16S02-101CH18S02-101CH20S02-101CH22S02-101CH24S02-101CH26S02-101CH28S02-101CH30
|
||||
S02-101CH1S02-101CH3S02-101CH5S02-101CH7S02-101CH9S02-101CH11S02-101CH13S02-101CH15S02-101CH17S02-101CH19S02-101CH21S02-101CH23S02-101CH25S02-101CH27S02-101CH29
|
||||
NCS2-050-CH2NCS2-050-CH4NCS2-050-CH6NCS2-050-CH8NCS2-050-CH10NCS2-050-CH12NCS2-050-CH14NCS2-050-CH16NCS2-050-CH18NCS2-050-CH20NCS2-050-CH22NCS2-050-CH24NCS2-050-CH26NCS2-050-CH28NCS2-050-CH30
|
||||
NCS2-050-CH1NCS2-050-CH3NCS2-050-CH5NCS2-050-CH7NCS2-050-CH9NCS2-050-CH11NCS2-050-CH13NCS2-050-CH15NCS2-050-CH17NCS2-050-CH19NCS2-050-CH21NCS2-050-CH23NCS2-050-CH25NCS2-050-CH27NCS2-050-CH29
|
||||
NCP1_9_VFD12HP350 FPM
|
||||
NCP1_10B_VFD12HP350 FPMNCP1_10A_VFD12HP350 FPM
|
||||
NCP1_11_VFD12HP350 FPMNCP1_12_VFD12HP350 FPMNCP1_13_VFD12HP350 FPM
|
||||
NCP1_14A_VFD12HP350 FPMNCP1_14B_VFD12HP350 FPMNCP1_14C_VFD12HP350 FPM
|
||||
NCP1_15_VFD17.5HP350 FPM
|
||||
NCP1_16_VFD15HP350 FPMNCP1_17_VFD12HP350 FPMNCP1_18A_VFD12HP350 FPM
|
||||
NCP1_19_VFD12HP350 FPM
|
||||
NCP1_20_VFD15HP300 FPM
|
||||
NCS1_1_VFD12HP300 FPMNCS1_2_VFD12HP300 FPMNCS1_3_VFD15HP300 FPM
|
||||
NCS1_4_VFD12HP300 FPM
|
||||
NCS1_5B_VFD12HP300 FPMNCS1_5A_VFD12HP300 FPM
|
||||
NCS1_6_VFD12HP240 FPMNCS1_7_VFD12HP240 FPMNCS1_8_VFD12HP240 FPMNCS1_9_VFD12HP240 FPMS02_1_VFD130HP250 FPM
|
||||
NCP1_21_VFD17.5HP300 FPM
|
||||
NCP2_1_VFD15HP300 FPMNCS2_2_VFD12HP300 FPM
|
||||
NCS2_3A_VFD12HP300 FPM
|
||||
NCS2_4_VFD12HP240 FPMNCS2_5_VFD12HP240 FPMNCS2_6_VFD12HP240 FPMNCS2_7_VFD12HP240 FPM
|
||||
WGS02_102CH_ER1
|
||||
S02_102CH_PE1
|
||||
S02_102CH_PE2
|
||||
SNDRCV
|
||||
S02_1_LRPE1
|
||||
MCM06
|
||||
SNDRCV
|
||||
S02_1_LRPE2
|
||||
MCM06
|
||||
RBB
|
||||
EPCNCP1_9_EPC2RBB
|
||||
EPCNCP1_15_EPC1RBB
|
||||
EPCNCP1_15_EPC2ABB
|
||||
NCP1_20_PE1(INFEED PRODUCT SENSOR)
|
||||
NCP1_20_PE3(OUTFEED PRODUCT SENSOR)
|
||||
NCP1_20_PE2(IDLE DEBRIS SENSOR)
|
||||
NCP1_20_PE4(DRIVE END DEBRIS/SPROCKET ENGAGEMENT SENSOR)
|
||||
NCP1_20_APS1APSNCP1_20_SOL1SOLNCP1_20_SOL2SOL
|
||||
EPCNCP1_21_EPC1RBB
|
||||
RGNCP1_21_SS1
|
||||
EPCNCP1_21_EPC2
|
||||
RG NCP1_21_SS2RBB
|
||||
EPCNCS1_4_EPC4RBB
|
||||
EPCNCS1_4_EPC2RBB
|
||||
WNCP1_16_JR1ABB
|
||||
WNCS1_3_JR1ABB
|
||||
EPCNCS2_2_EPC2RBB
|
||||
EPCNCS2_2_EPC1RBBRGNCS2_2_SS1
|
||||
BBBGBBBG
|
||||
WS02_1_JR2
|
||||
A
|
||||
WS02_1_JR1
|
||||
S02_1_JPE1S02_1CH_JPE1
|
||||
HBBBA
|
||||
EPCNCS1_4_EPC3
|
||||
EPCNCS1_4_EPC1
|
||||
WNCP1_16_JR2R
|
||||
GNCP1_9_S1
|
||||
GNCP1_9_S2
|
||||
GNCP1_15_S1
|
||||
GNCP1_15_S2
|
||||
GNCS1_4_S1
|
||||
GNCS1_4_S2EPCS02_1_EPC2
|
||||
EPCS02_1_EPC1
|
||||
NCP1_11_ENC1NCP1_12_ENC1NCP1-13-ENC1 NCP1_15_ENC1
|
||||
NCP1_17_ENC1
|
||||
NCP1_19_ENC1
|
||||
NCS1_2_ENC1
|
||||
NCS1_4_ENC1NCS1_6_ENC1NCS1_7_ENC1NCS1_8_ENC1NCS1_9_ENC1
|
||||
NCS2_7_ENC1NCS2_6_ENC1NCS2_5_ENC1NCS2_4_ENC1NCS2_2_ENC1
|
||||
NCP1_21_ENC1
|
||||
NCP1_15_JPE1
|
||||
NCP1_17_TPE1
|
||||
NCS1_1_TPE1
|
||||
NCS1_4_TPE1
|
||||
NCS2_2_TPE1
|
||||
NCP1_21_TPE1
|
||||
NCP1_9_TPE1NCP_11_TPE1
|
||||
V
|
||||
ST 4.0kW 1.4375
|
||||
CL
|
||||
ST 1.5kW 1.4375
|
||||
S02-101CH2S02-101CH4S02-101CH6S02-101CH8S02-101CH10S02-101CH12S02-101CH14S02-101CH16S02-101CH18S02-101CH20S02-101CH22S02-101CH24S02-101CH26S02-101CH28S02-101CH30
|
||||
S02-101CH1S02-101CH3S02-101CH5S02-101CH7S02-101CH9S02-101CH11S02-101CH13S02-101CH15S02-101CH17S02-101CH19S02-101CH21S02-101CH23S02-101CH25S02-101CH27S02-101CH29
|
||||
NCS2-050-CH2NCS2-050-CH4NCS2-050-CH6NCS2-050-CH8NCS2-050-CH10NCS2-050-CH12NCS2-050-CH14NCS2-050-CH16NCS2-050-CH18NCS2-050-CH20NCS2-050-CH22NCS2-050-CH24NCS2-050-CH26NCS2-050-CH28NCS2-050-CH30
|
||||
NCS2-050-CH1NCS2-050-CH3NCS2-050-CH5NCS2-050-CH7NCS2-050-CH9NCS2-050-CH11NCS2-050-CH13NCS2-050-CH15NCS2-050-CH17NCS2-050-CH19NCS2-050-CH21NCS2-050-CH23NCS2-050-CH25NCS2-050-CH27NCS2-050-CH29
|
||||
EPCNCP1_9_EPC1
|
||||
RGNCS2_2_SS2
|
||||
NCS2_DPM1MCM06
|
||||
NCS1_DPM1MCM06
|
||||
NCP_DPM3MCM06
|
||||
NCP_DPM2MCM06NCP_11_TPE2NCP1_12_TPE1NCP1_13_TPE1NCP1_15_TPE1
|
||||
NCP1_14D_VFD12HP350 FPM
|
||||
NCP1_17_TPE2
|
||||
NCP1_18B_VFD12HP350 FPMNCP1_19_TPE1
|
||||
NCP1_19_TPE2
|
||||
NCS1_2_JPE1
|
||||
NCS1_4_TPE2
|
||||
NCS1_6_TPE1NCS1_6_TPE2NCS1_7_TPE1NCS1_8_TPE1NCS1_9_TPE1S02_104CH_FIOH1
|
||||
S02_1_FIO1S02_104CH_PE1
|
||||
S02_104CH_PE2
|
||||
S02_106CH_PE1
|
||||
S02_106CH_PE2
|
||||
S02_108CH_PE1
|
||||
S02_108CH_PE2
|
||||
S02_110CH_PE1
|
||||
S02_110CH_PE2
|
||||
S02_112CH_PE1
|
||||
S02_112CH_PE2
|
||||
S02_114CH_PE1
|
||||
S02_114CH_PE2
|
||||
S02_116CH_PE1
|
||||
S02_116CH_PE2
|
||||
S02_118CH_PE1
|
||||
S02_118CH_PE2
|
||||
S02_120CH_PE1
|
||||
S02_120CH_PE2
|
||||
S02_122CH_PE1
|
||||
S02_122CH_PE2
|
||||
S02_124CH_PE1
|
||||
S02_124CH_PE2
|
||||
S02_126CH_PE1
|
||||
S02_126CH_PE2
|
||||
S02_128CH_PE1
|
||||
S02_128CH_PE2
|
||||
S02_130CH_PE1
|
||||
S02_130CH_PE2
|
||||
S02_101CH_PE1
|
||||
S02_101CH_PE2BBBGA
|
||||
WGS02_101CH_ER1
|
||||
S02_103CH_FIOH1S02_103CH_PE1
|
||||
S02_103CH_PE2
|
||||
S02_105CH_PE1
|
||||
S02_105CH_PE2
|
||||
S02_107CH_PE1
|
||||
S02_107CH_PE2
|
||||
S02_109CH_PE1
|
||||
S02_109CH_PE2
|
||||
S02_111CH_PE1
|
||||
S02_111CH_PE2
|
||||
S02_113CH_PE1
|
||||
S02_113CH_PE2
|
||||
S02_115CH_PE1
|
||||
S02_115CH_PE2
|
||||
S02_117CH_PE1
|
||||
S02_117CH_PE2
|
||||
S02_119CH_PE1
|
||||
S02_119CH_PE2
|
||||
S02_121CH_PE1
|
||||
S02_121CH_PE2
|
||||
S02_123CH_PE1
|
||||
S02_123CH_PE2
|
||||
S02_125CH_PE1
|
||||
S02_125CH_PE2
|
||||
S02_127CH_PE1
|
||||
S02_127CH_PE2
|
||||
S02_129CH_PE1
|
||||
S02_129CH_PE2 BBBG
|
||||
WGS02_103CH_ER1WGS02_105CH_ER1WGS02_107CH_ER1WGS02_109CH_ER1WGS02_111CH_ER1WGS02_113CH_ER1WGS02_115CH_ER1WGS02_117CH_ER1WGS02_119CH_ER1WGS02_121CH_ER1WGS02_123CH_ER1WGS02_125CH_ER1WGS02_127CH_ER1WGS02_129CH_ER1
|
||||
WGS02_104CH_ER1WGS02_106CH_ER1WGS02_108CH_ER1WGS02_110CH_ER1WGS02_112CH_ER1WGS02_114CH_ER1WGS02_116CH_ER1WGS02_118CH_ER1WGS02_120CH_ER1WGS02_122CH_ER1WGS02_124CH_ER1WGS02_126CH_ER1WGS02_128CH_ER1WGS02_130CH_ER1
|
||||
SNDRCV
|
||||
S02_1_LRPE3
|
||||
MCM06
|
||||
SNDRCV
|
||||
S02_1_LRPE4
|
||||
MCM06
|
||||
WS02_1_JR4WS02_1_JR3
|
||||
SNDRCV
|
||||
S02_1_LRPE5
|
||||
MCM06
|
||||
SNDRCV
|
||||
S02_1_LRPE6
|
||||
MCM06
|
||||
WS02_1_JR6WS02_1_JR5
|
||||
SNDRCV
|
||||
S02_1_LRPE7
|
||||
MCM06
|
||||
SNDRCV
|
||||
S02_1_LRPE8
|
||||
MCM06
|
||||
WS02_1_JR8WS02_1_JR7
|
||||
SNDRCV
|
||||
S02_1_LRPE9
|
||||
MCM06
|
||||
SNDRCV
|
||||
S02_1_LRPE10
|
||||
MCM06
|
||||
WS02_1_JR10WS02_1_JR9
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
S02_108CH_FIOH1
|
||||
S02_107CH_FIOH1
|
||||
S02_112CH_FIOH1
|
||||
S02_111CH_FIOH1
|
||||
S02_116CH_FIOH1
|
||||
S02_115CH_FIOH1
|
||||
S02_120CH_FIOH1
|
||||
S02_119CH_FIOH1
|
||||
S02_124CH_FIOH1
|
||||
S02_123CH_FIOH1
|
||||
S02_128CH_FIOH1
|
||||
S02_127CH_FIOH1
|
||||
S02_1_FIO2S02_1_FIO3S02_1_FIO4S02_1_FIO5S02_1_FIO6S02_1_FIO7S02_1_FIO8
|
||||
S02_129CH_FIOH1
|
||||
S02_2_VFD130HP250 FPM
|
||||
WGS02_202CH_ER1
|
||||
S02_202CH_PE1
|
||||
S02_202CH_PE2
|
||||
SNDRCV
|
||||
S02_2_LRPE1
|
||||
MCM06
|
||||
SNDRCV
|
||||
S02_2_LRPE2
|
||||
MCM06
|
||||
BBBGBBBG
|
||||
WS02_2_JR2
|
||||
A
|
||||
WS02_2_JR1
|
||||
S02_2_JPE1S02_2CH_JPE1
|
||||
HBBBA
|
||||
NCS2_050_PE1
|
||||
EPCS02_2_EPC2
|
||||
EPCS02_2_EPC1S02_204CH_FIOH1
|
||||
S02_2_FIO1S02_204CH_PE1
|
||||
S02_204CH_PE2
|
||||
S02_206CH_PE1
|
||||
S02_206CH_PE2
|
||||
S02_208CH_PE1
|
||||
S02_208CH_PE2
|
||||
S02_210CH_PE1
|
||||
S02_210CH_PE2
|
||||
S02_212CH_PE1
|
||||
S02_212CH_PE2
|
||||
S02_214CH_PE1
|
||||
S02_214CH_PE2
|
||||
S02_216CH_PE1
|
||||
S02_216CH_PE2
|
||||
S02_218CH_PE1
|
||||
S02_218CH_PE2
|
||||
S02_220CH_PE1
|
||||
S02_220CH_PE2
|
||||
S02_222CH_PE1
|
||||
S02_222CH_PE2
|
||||
S02_224CH_PE1
|
||||
S02_224CH_PE2
|
||||
S02_226CH_PE1
|
||||
S02_226CH_PE2
|
||||
S02_228CH_PE1
|
||||
S02_228CH_PE2
|
||||
S02_230CH_PE1
|
||||
S02_230CH_PE2
|
||||
S02_201CH_PE1
|
||||
S02_201CH_PE2BBBGA
|
||||
WGS02_201CH_ER1
|
||||
S02_203CH_FIOH1S02_203CH_PE1
|
||||
S02_203CH_PE2
|
||||
S02_205CH_PE1
|
||||
S02_205CH_PE2
|
||||
S02_207CH_PE1
|
||||
S02_207CH_PE2
|
||||
S02_209CH_PE1
|
||||
S02_209CH_PE2
|
||||
S02_211CH_PE1
|
||||
S02_211CH_PE2
|
||||
S02_213CH_PE1
|
||||
S02_213CH_PE2
|
||||
S02_215CH_PE1
|
||||
S02_215CH_PE2
|
||||
S02_217CH_PE1
|
||||
S02_217CH_PE2
|
||||
S02_219CH_PE1
|
||||
S02_219CH_PE2
|
||||
S02_221CH_PE1
|
||||
S02_221CH_PE2
|
||||
S02_223CH_PE1
|
||||
S02_223CH_PE2
|
||||
S02_225CH_PE1
|
||||
S02_225CH_PE2
|
||||
S02_227CH_PE1
|
||||
S02_227CH_PE2
|
||||
S02_229CH_PE1
|
||||
S02_229CH_PE2 BBBG
|
||||
WGS02_203CH_ER1WGS02_205CH_ER1WGS02_207CH_ER1WGS02_209CH_ER1WGS02_211CH_ER1WGS02_213CH_ER1WGS02_215CH_ER1WGS02_217CH_ER1WGS02_219CH_ER1WGS02_221CH_ER1WGS02_223CH_ER1WGS02_225CH_ER1WGS02_227CH_ER1WGS02_229CH_ER1
|
||||
WGS02_204CH_ER1WGS02_206CH_ER1WGS02_208CH_ER1WGS02_210CH_ER1WGS02_212CH_ER1WGS02_214CH_ER1WGS02_216CH_ER1WGS02_218CH_ER1WGS02_220CH_ER1WGS02_222CH_ER1WGS02_224CH_ER1WGS02_226CH_ER1WGS02_228CH_ER1WGS02_230CH_ER1
|
||||
SNDRCV
|
||||
S02_2_LRPE3
|
||||
MCM06
|
||||
SNDRCV
|
||||
S02_2_LRPE4
|
||||
MCM06
|
||||
WS02_2_JR4WS02_2_JR3
|
||||
SNDRCV
|
||||
S02_2_LRPE5
|
||||
MCM06
|
||||
SNDRCV
|
||||
S02_2_LRPE6
|
||||
MCM06
|
||||
WS02_2_JR6WS02_2_JR5
|
||||
SNDRCV
|
||||
S02_2_LRPE7
|
||||
MCM06
|
||||
SNDRCV
|
||||
S02_2_LRPE8
|
||||
MCM06
|
||||
WS02_2_JR8WS02_2_JR7
|
||||
SNDRCV
|
||||
S02_2_LRPE9
|
||||
MCM06
|
||||
SNDRCV
|
||||
S02_2_LRPE10
|
||||
MCM06
|
||||
WS02_2_JR10WS02_2_JR9
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBGA
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
BBBG
|
||||
S02_208CH_FIOH1
|
||||
S02_207CH_FIOH1
|
||||
S02_212CH_FIOH1
|
||||
S02_211CH_FIOH1
|
||||
S02_216CH_FIOH1
|
||||
S02_215CH_FIOH1
|
||||
S02_220CH_FIOH1
|
||||
S02_219CH_FIOH1
|
||||
S02_224CH_FIOH1
|
||||
S02_223CH_FIOH1
|
||||
S02_228CH_FIOH1
|
||||
S02_227CH_FIOH1
|
||||
S02_2_FIO2S02_2_FIO3S02_2_FIO4S02_2_FIO5S02_2_FIO6S02_2_FIO7S02_2_FIO8
|
||||
S02_229CH_FIOH1
|
||||
NCP1_21_JPE1
|
||||
NCS2_2_TPE2
|
||||
NCS2_3B_VFD12HP300 FPMNCS2_4_TPE1NCS2_4_TPE2NCS2_5_TPE1NCS2_6_TPE1
|
||||
NCS2_7_TPE1
|
||||
MCM06
|
||||
MCM06
|
||||
449
projects/MTN6 copy/extracted_texts/MTN6_SYSDL-MCM07.txt
Normal file
449
projects/MTN6 copy/extracted_texts/MTN6_SYSDL-MCM07.txt
Normal file
@ -0,0 +1,449 @@
|
||||
BYAB_2_VFD15HP550 FPM BYAB_3_VFD15HP550 FPM
|
||||
BYAB_4_VFD13HP500 FPM
|
||||
BYAB_5_VFD15HP450 FPMBYAB_6_VFD13HP400 FPM
|
||||
BYAB_7_VFD17.5HP350 FPMBYAB_8_VFD15HP300 FPMBYAB_9_VFD12HP300 FPM
|
||||
BYAB_10_VFD13HP300 FPM
|
||||
BYAB_11_VFD13HP300 FPM
|
||||
BYAB_12_VFD17.5HP300 FPMBYAB_13_VFD110HP300 FPMBYAB_14_VFD110HP300 FPMBYAB_15_VFD13HP300 FPM
|
||||
BYAD_2_VFD13HP550 FPM BYAD_3_VFD17.5HP500 FPMBYAD_4_VFD15HP450 FPM
|
||||
BYAD_5_VFD17.5HP400 FPM
|
||||
BYAD_6_VFD13HP350 FPM BYAD_7_VFD110HP300 FPM
|
||||
BYAD_8_VFD110HP300 FPMBYAD_9_VFD13HP300 FPM
|
||||
BYAC_2_VFD13HP550 FPM BYAC_3_VFD17.5HP500 FPMBYAC_4_VFD15HP450 FPM
|
||||
BYAC_5_VFD15HP400 FPM
|
||||
BYAC_6_VFD13HP350 FPMBYAC_7_VFD110HP300 FPMBYAC_8_VFD110HP300 FPMBYAC_9_VFD13HP300 FPM
|
||||
BYAC_10_VFD15HP300 FPMBYAC_11_VFD13HP300 FPM
|
||||
ABB
|
||||
BYAC_2_JPE1
|
||||
SNDRCV
|
||||
BYA_LRPE1
|
||||
MCM07
|
||||
BYAD_2_JPE1
|
||||
BYAB_2_JPE1
|
||||
BYAC_2_TPE1 BYAC_3_JPE1
|
||||
BYAC_5_TPE1
|
||||
BYAC_5_JPE1BYAC_7_TPE1BYAC_7_TPE2
|
||||
BYAC_8_TPE1BYAC_9_TPE1
|
||||
BYAC_11_TPE1
|
||||
BYAD_3_JPE1
|
||||
BYAB_2_JPE2
|
||||
BYAD_2_TPE1
|
||||
BYAB_6_TPE1BYAB_6_TPE2
|
||||
BYAB_7_TPE1BYAB_8_JPE1
|
||||
BYAB_12_TPE1BYAB_12_TPE2BYAB_13_TPE1
|
||||
BYAB_14_TPE1BYAB_15_TPE1
|
||||
BYAB_10_TPE1
|
||||
BYAB_10_JPE1
|
||||
BYAB_4_TPE1
|
||||
BYAB_4_JPE1
|
||||
BYAD_5_TPE1
|
||||
BYAD_5_JPE1BYAD_7_TPE1 BYAD_7_TPE2
|
||||
BYAD_8_TPE1BYAD_9_TPE1
|
||||
EPCBYAB_15_EPC1RBB
|
||||
EPCBYAB_15_EPC2RBB
|
||||
R
|
||||
G
|
||||
BYAB_2_S1RBBGBYAB_2_S2
|
||||
ABBR
|
||||
ABBR
|
||||
RBB
|
||||
RBB
|
||||
EPCBYAD_9_EPC1RBBGBYAD_9_S1
|
||||
EPCBYAD_9_EPC2RBBGBYAD_9_S2
|
||||
EPCBYAC_11_EPC1
|
||||
ABBGBYAC_11_S2EPCBYAC_11_EPC2
|
||||
RBBGBYAC_11_S1
|
||||
GBYAC_2_S1
|
||||
GBYAD_2_S2
|
||||
GBYAC_2_S2
|
||||
G
|
||||
BYAD_2_S1
|
||||
V
|
||||
BYBD_2_VFD13HP550 FPM BYBD_3_VFD110HP550 FPM BYBD_4_VFD110HP450 FPM
|
||||
BYBD_5_VFD110HP400 FPM BYBD_6_VFD15HP350 FPM BYBD_7_VFD17.5HP300 FPM
|
||||
BYBD_8_VFD13HP300 FPM
|
||||
BYBD_9_VFD12HP300 FPM
|
||||
BYBD_10_VFD110HP300 FPM
|
||||
BYBD_11_VFD13HP300 FPM
|
||||
BYBD_12_VFD110HP300 FPM
|
||||
BYBD_13_VFD110HP300 FPM
|
||||
BYBD_14_VFD12HP300 FPM
|
||||
BYBC_2_VFD13HP550 FPM BYBC_3_VFD110HP500 FPM BYBC_4_VFD17.5HP450 FPM
|
||||
BYBC_5_VFD15HP400 FPM
|
||||
BYBC_6_VFD13HP350 FPM
|
||||
BYBC_7_VFD13HP300 FPM BYBC_8_VFD110HP300 FPM
|
||||
BYBC_9_VFD110HP300 FPMBYBC_10_VFD12HP300 FPM
|
||||
BYBA_2_VFD13HP550 FPM BYBA_4_VFD17.5HP450 FPM
|
||||
BYBA_5_VFD13HP400 FPM
|
||||
BYBA_9_VFD110HP300 FPM BYBA_10_VFD17.5HP300 FPMBYBA_11_VFD12HP300 FPMBYBA_12_VFD13HP300 FPM
|
||||
BYBA_13_VFD12HP300 FPM
|
||||
BYBA_14_VFD13HP300 FPMBYBA_15_VFD12HP300 FPM
|
||||
BYBC_2_JPE1
|
||||
BYBD_2_JPE1
|
||||
BYBC_2_TPE1
|
||||
BYBD_2_TPE1 BYBD_3_TPE1
|
||||
BYBC_3_TPE1
|
||||
BYBA_4_JPE1
|
||||
BYBC_4_JPE1
|
||||
BYBD_4_TPE1 BYBD_5_TPE1 BYBD_6_TPE1
|
||||
BYBD_7_JPE1
|
||||
BYBD_12_TPE1 BYBD_12_TPE2
|
||||
BYBD_13_TPE1BYBD_14_TPE1
|
||||
BYBA_10_TPE1
|
||||
BYBC_9_TPE1BYBC_10_TPE1BYBC_8_TPE1 BYBC_8_TPE2
|
||||
BYBA_10_JPE1BYBA_15_TPE1BYBA_15_TPE2
|
||||
BYBA_13_TPE1
|
||||
BYBC_6_JPE1
|
||||
BYBC_6_TPE1
|
||||
BYBD_9_TPE1
|
||||
BYBD_10_JPE1 EPCBYBD_14_EPC1RBBGBYBD_14_S1
|
||||
EPCBYBD_14_EPC2RBBGBYBD_14_S2
|
||||
EPCBYBC_10_EPC1RBB
|
||||
GBYBC_10_S1
|
||||
EPCBYBC_10_EPC2RBBGBYBC_10_S2
|
||||
EPCBYBA_15_EPC2
|
||||
EPCBYBA_15_EPC1BB
|
||||
GBYBA_15_S2RBB
|
||||
BYCD_2_VFD15HP400 FPMBYCD_3_VFD15HP380 FPMBYCD_4_VFD12HP450 FPM
|
||||
BYCD_5_VFD15HP400 FPM
|
||||
BYCD_6_VFD13HP400 FPMBYCD_7_VFD12HP300 FPM
|
||||
BYCD_8_VFD17.5HP300 FPM BYCD_9_VFD110HP300 FPM BYCD_10_VFD110HP300 FPM BYCD_11_VFD17.5HP300 FPMBYCD_12_VFD12HP300 FPM
|
||||
BYCB_2_VFD13HP550 FPMBYCB_3_VFD15HP500 FPM
|
||||
BYCB_4_VFD13HP450 FPM
|
||||
BYCB_5_VFD15HP400 FPM
|
||||
BYCB_6_VFD15HP350 FPMBYCB_7_VFD110HP300 FPMBYCB_8_VFD110HP300 FPM
|
||||
BYCB_9_VFD15HP300 FPMBYCB_10_VFD12HP300 FPM
|
||||
BYCA_2_VFD13HP550 FPMBYCA_3_VFD15HP500 FPM
|
||||
BYCA_4_VFD15HP450 FPM
|
||||
BYCA_5_VFD15HP400 FPM
|
||||
BYCA_6_VFD110HP350 FPM
|
||||
BYCA_7_VFD12HP300 FPMBYCA_8_VFD15HP300 FPMBYCA_9_VFD12HP300 FPM
|
||||
BYCD_2_JPE1
|
||||
SND RCVBYC_LRPE1MCM07
|
||||
BYCB_2_TPE1BYCB_3_JPE1
|
||||
BYCD_2_JPE2
|
||||
BYCD_7_TPE1
|
||||
BYCB_7_TPE1
|
||||
BYCA_5_TPE1
|
||||
BYCA_9_TPE2
|
||||
EPCBYCD_12_EPC1RBBGBYCD_12_S1
|
||||
EPCBYCD_12_EPC2RBBGBYCD_12_S2
|
||||
EPCBYCB_10_EPC1RBBGBYCB_10_S1
|
||||
EPCBYCB_10_EPC2RBBGBYCB_10_S2
|
||||
EPCBYCA_9_EPC1RBBGBYCA_9_S1
|
||||
EPCBYCA_9_EPC2RBBGBYCA_9_S2
|
||||
BYDB_2_VFD13HP550 FPM
|
||||
BYDB_3_VFD17.5HP500 FPMBYDB_4_VFD110HP450 FPMBYDB_5_VFD13HP400 FPMBYDB_6_VFD17.5HP350 FPMBYDB_7_VFD17.5HP300 FPMBYDB_8_VFD15HP300 FPMBYDB_9_VFD13HP300 FPMBYDB_10_VFD15HP300 FPM
|
||||
BYDB_11_VFD15HP300 FPM
|
||||
BYDB_12_VFD15HP300 FPMBYDB_13_VFD110HP300 FPMBYDB_14_VFD110HP300 FPMBYDB_15_VFD15HP300 FPMBYDB_16_VFD13HP300 FPM
|
||||
BYDA_2_VFD13HP550 FPMBYDA_3_VFD17.5HP500 FPMBYDA_4_VFD110HP450 FPM
|
||||
BYDA_5_VFD15HP400 FPM
|
||||
BYDA_6_VFD110HP350 FPM
|
||||
BYDA_7_VFD13HP300 FPMBYDA_8_VFD110HP300 FPMBYDA_9_VFD13HP300 FPM
|
||||
BYDC_2_VFD13HP550 FPMBYDC_3_VFD17.5HP500 FPMBYDC_4_VFD110HP450 FPM
|
||||
BYDC_5_VFD15HP400 FPM
|
||||
BYDC_6_VFD110HP350 FPM
|
||||
BYDC_7_VFD13HP300 FPM
|
||||
BYDC_8_VFD110HP300 FPMBYDC_9_VFD110HP300 FPM
|
||||
BYDC_10_VFD110HP300 FPMBYDC_11_VFD13HP300 FPM
|
||||
BYDC_12_VFD15HP300 FPMBYDC_13_VFD13HP300 FPM
|
||||
SND RCV
|
||||
BYD_LRPE1
|
||||
MCM07
|
||||
WBYD_JR1BYDB_2_TPE1BYDB_11_TPE1
|
||||
EPCBYDC_13_EPC1
|
||||
ABBGBYDC_13_S2EPCBYDC_13_EPC2
|
||||
RBBGBYDC_13_S1 EPCBYDA_9_EPC1RBBGBYDA_9_S1
|
||||
EPCBYDA_9_EPC2RBBGBYDA_9_S2
|
||||
EPCBYDB_16_EPC1RBBGBYDB_16_S1
|
||||
EPCBYDB_16_EPC2RBBGBYDB_16_S2
|
||||
EPCBYDA_8_EPC1
|
||||
EPCBYDA_8_EPC2ABBGBYDA_8_S2
|
||||
RBBGBYDA_8_S1
|
||||
RR
|
||||
R
|
||||
BBA
|
||||
WBYBA_5_JR1
|
||||
BBA
|
||||
WBYBC_5_JR1
|
||||
BBA
|
||||
WBYBC_7_JR1
|
||||
R
|
||||
BBA
|
||||
WBYCB_6_JR1
|
||||
BBA
|
||||
WBYAB_11_JR1
|
||||
BBA
|
||||
WBYDB_12_JR1
|
||||
BBA
|
||||
WBYCB_4_JR1
|
||||
BBA
|
||||
WBYAB_9_JR1
|
||||
BBA
|
||||
WBYDB_10_JR1
|
||||
BBA
|
||||
WBYCD_6_JR1
|
||||
BBA
|
||||
WBYCD_3_JR1
|
||||
BBA
|
||||
WBYBD_11_JR1
|
||||
BYBD_9_TPE2
|
||||
BBA
|
||||
WBYAD_6_JR1
|
||||
BBA
|
||||
WBYAD_4_JR1
|
||||
BBA
|
||||
WBYAC_4_JR1
|
||||
EPCBYDA_6_EPC2
|
||||
EPCBYDA_6_EPC1
|
||||
EPCBYDB_4_EPC1
|
||||
EPCBYDB_4_EPC2
|
||||
EPCBYDC_6_EPC1
|
||||
EPCBYDC_6_EPC2ABBGBYDA_6_S1R ABBGBYDC_6_S1
|
||||
R
|
||||
BBGBYDB_4_S2R
|
||||
BBGBYDB_4_S1R
|
||||
BBGBYDA_6_S2R BBGBYDC_6_S2R
|
||||
GBYBA_15_S1
|
||||
BBA
|
||||
WBYCA_8_JR1
|
||||
BBA
|
||||
WBYBA_12_JR1
|
||||
BBA
|
||||
WBYBD_8_JR1
|
||||
BBA
|
||||
WBYAB_5_JR1
|
||||
BBA
|
||||
WBYAB_3_JR1
|
||||
BYCD_4_TPE1
|
||||
BYCB_5_JPE1
|
||||
BYCB_5_TPE1
|
||||
BYAC_11_TPE2
|
||||
EPCBYAC_2_EPC1
|
||||
EPCBYAC_2_EPC2EPCBYAD_2_EPC1
|
||||
EPCBYAD_2_EPC2EPCBYAB_2_EPC2EPCBYAB_2_EPC1
|
||||
EPCBYAB_2_EPC4EPCBYAB_2_EPC3
|
||||
EPCBYDA_3_EPC1
|
||||
EPCBYDA_3_EPC2EPCBYDB_3_EPC1
|
||||
EPCBYDB_3_EPC2
|
||||
ABBR
|
||||
RBBGBYBC_3_S2
|
||||
G
|
||||
BYBC_3_S1EPCBYBC_3_EPC1
|
||||
EPCBYBC_3_EPC2ABBR
|
||||
RBBGBYBD_3_S2
|
||||
G
|
||||
BYBD_3_S1EPCBYBD_3_EPC1
|
||||
EPCBYBD_3_EPC2
|
||||
EPCBYCB_3_EPC1
|
||||
EPCBYCB_3_EPC2ABBR
|
||||
RBBGBYCB_3_S2
|
||||
GBYCB_3_S1
|
||||
BBR
|
||||
GBYCD_5_S1RBBGBYCD_5_S2
|
||||
ABBRGBYDA_3_S1
|
||||
ABBR
|
||||
GBYDB_3_S1RBBGBYDA_3_S2
|
||||
RBBGBYDB_3_S2
|
||||
2'-5" EL (PLTF2)TYP.
|
||||
2'-5" EL (PLTF2)
|
||||
11'-0" EL (PLTF1)9'-0" EL (PLTF1)19'-0'' EL (FLOOR)9'-0" EL (PLTF1)6'-8'' EL (PLTF2)2'-9" EL (PLTF2)
|
||||
7'-6" EL (PLTF2)
|
||||
7'-6" EL (PLTF2)2'-9" EL (PLTF2)
|
||||
2'-9" EL (PLTF2)
|
||||
X-SQ-43.1875_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-96_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-60-P2.5+
|
||||
ST 1.5kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
TRANSITION CHUTES FROMCROSSBELT TO CONVEYORSURFACE WITH 3'' DROP
|
||||
2'-5" EL (PLTF2)TYP.
|
||||
7'-6" EL (PLTF2)
|
||||
7'-6" EL (PLTF2)
|
||||
7'-6" EL (PLTF2)
|
||||
7'-6" EL (PLTF2)
|
||||
7'-6" EL (PLTF2)
|
||||
8'-8" EL (PLTF2)9'-0" EL (PLTF2)11'-0'' EL (PLTF1)
|
||||
5'-1" EL (PLTF1)2'-9" EL (PLTF2)
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
2'-5" EL(PLTF2)
|
||||
2'-5" EL (PLTF2)TYP. (3) PLCS
|
||||
8'-0" EL (PLTF2)10'-4'' EL (PLTF1)TYP. (3) PLCS
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
8'-0" EL (PLTF2)
|
||||
5'-8" EL (PLTF2)8'-0'' EL (PLTF1)
|
||||
10'-8" EL (PLTF2) 10'-8" EL (PLTF2)
|
||||
8'-0" EL (PLTF2)
|
||||
8'-0" EL (PLTF2)
|
||||
8'-0" EL (PLTF2) 8'-0" EL (PLTF2) 2'-9" EL (PLTF2)
|
||||
8'-0" EL (PLTF2)
|
||||
8'-0" EL (PLTF2)
|
||||
8'-0" EL (PLTF2)
|
||||
8'-0" EL (PLTF2) 8'-0" EL (PLTF2)2'-9" EL (PLTF2) 2'-9" EL (PLTF2)
|
||||
2'-9" EL (PLTF2)
|
||||
2'-9" EL (PLTF2)8'-0" EL (PLTF2) 8'-0" EL (PLTF2)
|
||||
X-SQ-43.1875_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-60-P2.5+
|
||||
ST 1.5kW 1.4375
|
||||
X-SQ-96_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
TRANSITION CHUTES FROMCROSSBELT TO CONVEYORSURFACE WITH 3'' DROP2'-5" EL(PLTF2)
|
||||
7'-4" EL(PLTF2)
|
||||
6'-3" EL(PLTF2) 10'-8" EL(PLTF2)
|
||||
JSA
|
||||
JSA
|
||||
2'-5" EL(PLTF2)
|
||||
X-SQ-43.1875_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-96_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-43.1875_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-96_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
2'-5" EL (PLTF2)TYP.
|
||||
8'-0" EL (PLTF2)TYP.
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
3'-6" EL (PLTF3)
|
||||
7'-5" EL (PLTF3)11'-11'' EL (PLTF2)
|
||||
11'-11" EL (PLTF2)
|
||||
8'-8" EL (PLTF2)8'-8" EL (PLTF2)11'-0'' EL (PLTF1)
|
||||
11'-0" EL (PLTF1)
|
||||
11'-0" EL (PLTF1)11'-0" EL (PLTF1)
|
||||
2'-9" EL (PLTF2)5'-4'' EL (PLTF1)2'-9" EL (PLTF2)
|
||||
3'-6" EL (PLTF3)
|
||||
3'-6" EL (PLTF3)
|
||||
3'-6" EL (PLTF3)
|
||||
3'-6" EL (PLTF3)
|
||||
3'-6" EL (PLTF3)8'-0'' EL (PLTF2)8'-0" EL (PLTF2)2'-9" EL (PLTF2)2'-9" EL (PLTF2) 3'-6" EL (PLTF3)8'-0'' EL (PLTF2)
|
||||
2'-9" EL (PLTF2)
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
BBA
|
||||
WBYAC_6_JR1
|
||||
BYD1_DPM1MCM07
|
||||
BYD1_DPM2MCM07
|
||||
BYD3_DPM1MCM07
|
||||
BYA1_DPM1MCM07
|
||||
BYA3_DPM1MCM07
|
||||
BYB1_DPM1MCM07
|
||||
BYB2_DPM1MCM07
|
||||
BYB3_DPM1MCM07
|
||||
BYC1_DPM1MCM07
|
||||
BYC3_DPM1MCM07
|
||||
MCM07
|
||||
BYAB_2_FIO1
|
||||
BYAD_2_FIO1
|
||||
BYAC_2_FIO1BYCA_2_FIO1
|
||||
BYCB_2_FIO1
|
||||
GBYAB_15_S2
|
||||
GBYAB_15_S1BYAB_14_FIO1
|
||||
BYAD_8_FIO1
|
||||
BYAC_11_FIO1
|
||||
BYBD_2_FIO1
|
||||
BYBD_14_FIO1
|
||||
BYBC_2_FIO1
|
||||
BYBC_10_FIO1
|
||||
BYBA_2_FIO1BYBA_2_JPE1BYBA_2_TPE1ABBR
|
||||
RBBGBYBA_3_S2
|
||||
G
|
||||
BYBA_3_S1EPCBYBA_3_EPC1
|
||||
EPCBYBA_3_EPC2 BYBA_3_VFD110HP500 FPMBYBA_3_TPE1
|
||||
BYBA_6_TPE1
|
||||
BYBA_6_VFD13HP350 FPM
|
||||
BYBA_6_JPE1
|
||||
BBA
|
||||
WBYBA_7_JR1
|
||||
BYBA_7_VFD13HP300 FPMBYBA_8_TPE1 BYBA_8_VFD110HP300 FPM
|
||||
BYBA_8_TPE2 BYBA_9_TPE1
|
||||
BYBA_13_JPE1BBA
|
||||
WBYBA_14_JR1
|
||||
BYBA_15_FIO1
|
||||
EPCBYCD_5_EPC2
|
||||
EPCBYCD_5_EPC1
|
||||
BYCD_4_TPE2
|
||||
BYCD_5_JPE1
|
||||
BYCD_7_TPE2
|
||||
BYCD_8_TPE1 BYCD_9_TPE1 BYCD_10_TPE1 BYCD_11_TPE1BYCD_12_TPE1BYCD_11_FIO1
|
||||
BYCB_2_JPE1
|
||||
BYCA_2_JPE1
|
||||
BYCB_7_TPE2BYCB_8_TPE1BYCB_9_TPE1BYCB_10_TPE1
|
||||
BYCB_9_FIO1
|
||||
BYCA_2_TPE1
|
||||
EPCBYCA_3_EPC1
|
||||
EPCBYCA_3_EPC2ABBRRBB
|
||||
GBYCA_3_S2
|
||||
GBYCA_3_S1BYCA_3_JPE1
|
||||
BBA
|
||||
WBYCA_4_JR1 BYCA_5_TPE2 BYCA_6_TPE1BYCA_7_JPE1
|
||||
BYCA_9_TPE1
|
||||
SND RCV
|
||||
BYB_LRPE1
|
||||
MCM07
|
||||
WBYB_JR1
|
||||
WBYC_JR1WBYA_JR1
|
||||
BYDB_2_FIO1
|
||||
BYDA_2_FIO1
|
||||
BYDC_2_FIO1BYDC_2_JPE1
|
||||
BYDA_2_JPE1
|
||||
BYDB_2_JPE1
|
||||
BYDB_3_TPE1BYDB_4_TPE1BYDB_5_TPE1BYDB_6_TPE1BYDB_7_TPE1BYDB_8_TPE1BYDB_9_JPE1
|
||||
BYDB_11_JPE1BYDB_13_TPE1BYDB_13_TPE2BYDB_14_TPE1
|
||||
BYDB_15_TPE1BYDB_16_TPE1
|
||||
BYDA_2_TPE1BYDA_3_TPE1BYDA_4_JPE1
|
||||
BYDA_6_TPE1
|
||||
BYDA_6_FIO1
|
||||
BYDA_6_JPE1BYDA_8_TPE1BYDA_8_FIO1BYDA_9_TPE1BYDA_8_TPE2BYDA_8_FIO2
|
||||
EPCBYDC_3_EPC1
|
||||
EPCBYDC_3_EPC2ABBRGBYDC_3_S1RBBGBYDC_3_S2BYDC_2_TPE1BYDC_3_TPE1BYDC_4_JPE1
|
||||
BYDC_6_FIO1
|
||||
BYDC_6_TPE1
|
||||
BYDC_6_JPE1
|
||||
BYDC_8_FIO1
|
||||
BYDC_8_TPE1
|
||||
EPCBYDC_8_EPC1
|
||||
EPCBYDC_8_EPC2ABB
|
||||
GBYDC_8_S2
|
||||
RBBGBYDC_8_S1RBYDC_8_TPE2BYDC_9_TPE1
|
||||
BYDC_10_TPE1BYDC_11_JPE1BYDC_13_TPE1
|
||||
BYDC_13_TPE2
|
||||
MCM07
|
||||
1738
projects/MTN6/MTN6 Equipment Manifest REV6(Conveyor List).csv
Normal file
1738
projects/MTN6/MTN6 Equipment Manifest REV6(Conveyor List).csv
Normal file
File diff suppressed because it is too large
Load Diff
475
projects/MTN6/extracted_texts/MTN6_SYSDL-MCM01.txt
Normal file
475
projects/MTN6/extracted_texts/MTN6_SYSDL-MCM01.txt
Normal file
@ -0,0 +1,475 @@
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375ST 1.5kW 1.4375
|
||||
PALLET STAGING
|
||||
PALLET STAGING
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR40
|
||||
10T
|
||||
S7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR40
|
||||
10T
|
||||
S7000
|
||||
SQR4010T
|
||||
S7000
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
TRAILER DIMENSIONS
|
||||
TRAILER DIMENSIONS
|
||||
EL. 2'-6"
|
||||
EL. 2'-6"EL. 2'-6"
|
||||
EL. 5'-2"TYP. (2) PLCS
|
||||
EL. 6'-4"TYP. (2) PLCS
|
||||
EL. 13'-1"EL. 3'-1" (PLTF)TYP. (4) PLCS
|
||||
EL. 2'-6"
|
||||
EL. 5'-2"TYP. (2) PLCS
|
||||
EL. 6'-4"TYP. (2) PLCS
|
||||
EL. 13'-1"EL. 3'-1" (PLTF)TYP. (3) PLCS
|
||||
UL1_3_VFD15HP280 FPM UL1_4_VFD15HP280 FPMUL1_5_VFD13HP420 FPMUL1_6_VFD13HP420 FPMUL1_7_VFD13HP420 FPM
|
||||
UL1_8_VFD13HP420 FPM UL1_9_VFD15HP280 FPM UL1_10A_VFD13HP280 FPMUL1_10B_VFD13HP280 FPM
|
||||
UL1_11_VFD12HP280 FPMUL1_12_VFD12HP280 FPMUL1_13_VFD15HP280 FPM
|
||||
UL2_3_VFD13HP280 FPM UL2_4_VFD15HP280 FPM
|
||||
UL2_5_VFD13HP280 FPMUL2_6_VFD13HP420 FPMUL2_7_VFD13HP420 FPMUL2_8_VFD13HP420 FPMUL2_9_VFD13HP420 FPMUL2_10_VFD13HP420 FPM
|
||||
UL3_1_VFD12HP120 FPM
|
||||
UL3_2_VFD17.5HP280 FPMUL3_3_VFD13HP280 FPMUL3_4_VFD12HP280 FPMUL3_5_VFD13HP420 FPMUL3_6_VFD13HP420 FPMUL3_7_VFD13HP420 FPMUL3_8_VFD13HP420 FPMUL3_9_VFD13HP420 FPM
|
||||
UL4_3_VFD13HP280 FPM UL4_4_VFD15HP280 FPM
|
||||
UL4_9_VFD13HP280 FPM
|
||||
UL5_3_VFD13HP280 FPM UL5_4_VFD15HP280 FPM
|
||||
UL3_3_ENC1
|
||||
UL3_5_ENC1UL3_6_ENC1UL3_7_ENC1UL3_8_ENC1UL2_9_ENC1UL2_8_ENC1UL2_7_ENC1UL2_6_ENC1
|
||||
UL2_5_ENC1
|
||||
UL1_5_ENC1UL1_6_ENC1UL1_7_ENC1
|
||||
UL5_3_ENC1 UL5_4_ENC1
|
||||
UL4_3_ENC1 UL4_4_ENC1
|
||||
UL3_2_ENC1
|
||||
UL3_4_ENC1UL2_3_ENC1 UL2_4_ENC1
|
||||
UL1_3_ENC1 UL1_4_ENC1 UL1_9_ENC1
|
||||
UL1_5_TPE1UL1_6_TPE1UL1_7_TPE1
|
||||
UL1_9_TPE3
|
||||
UL1_9_TPE1
|
||||
UL1_9_TPE2
|
||||
UL1_9_TPE4
|
||||
UL1_9_TPE5
|
||||
UL1_11_TPE1UL1_11_TPE2
|
||||
UL1_12_TPE1
|
||||
UL4_9_TPE1
|
||||
UL4_9_TPE2
|
||||
UL4_9_TPE3
|
||||
UL4_9_TPE4
|
||||
UL4_9_TPE5
|
||||
UL5_3_TPE2UL4_3_TPE2
|
||||
UL3_1_TPE1
|
||||
UL2_3_TPE2UL1_3_TPE2
|
||||
UL1_4_TPE1UL2_4_TPE1 UL5_4_TPE1
|
||||
UL3_4_TPE1
|
||||
UL3_4_TPE2UL3_5_TPE1UL3_6_TPE1UL3_7_TPE1UL3_8_TPE1UL2_9_TPE1UL2_8_TPE1
|
||||
UL2_7_TPE1UL2_6_TPE2UL2_6_TPE1
|
||||
EPCUL5_4_EPC2
|
||||
EPCUL5_4_EPC1
|
||||
EPCUL4_4_EPC2
|
||||
EPCUL4_4_EPC1
|
||||
EPCUL3_2_EPC2
|
||||
EPCUL3_2_EPC1EPCUL2_4_EPC2
|
||||
EPCUL2_4_EPC1
|
||||
EPCUL1_4_EPC2
|
||||
EPCUL1_4_EPC1
|
||||
RBBGUL5_4_S2
|
||||
RBBGUL5_4_S1RBBGUL4_4_S2
|
||||
RBBGUL4_4_S1
|
||||
RBBGUL3_2_S2
|
||||
RBBGUL2_4_S2RBBGUL3_2_S1
|
||||
RBBGUL2_4_S1RBBGUL1_4_S2
|
||||
RBBGUL1_4_S1
|
||||
EPCUL4_9_EPC2
|
||||
EPCUL4_9_EPC1
|
||||
RBBGUL4_9_S2
|
||||
RBBGUL4_9_S1A
|
||||
EPCUL1_9_EPC2
|
||||
EPCUL1_9_EPC1
|
||||
RBBGUL1_9_S2
|
||||
RBBGUL1_9_S1A
|
||||
RBB
|
||||
RBBGPS1_1_S2
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
EPCUL3_1_EPC2EPCUL3_1_EPC1
|
||||
RGUL3_1_SS1
|
||||
WUL1_9_JR1
|
||||
WUL1_9_JR2
|
||||
WUL4_9_JR2
|
||||
WUL4_9_JR1
|
||||
UL7_3_VFD15HP280 FPMUL7_4_VFD15HP280 FPM
|
||||
UL9_3_VFD15HP280 FPM
|
||||
UL9_4_VFD15HP280 FPM
|
||||
UL11_3_VFD15HP280 FPM
|
||||
UL11_11A_VFD13HP280 FPMUL11_11B_VFD13HP280 FPMUL11_12_VFD12HP280 FPMUL11_13_VFD12HP280 FPM
|
||||
UL11_14_VFD15HP280 FPM
|
||||
UL12_3_VFD15HP280 FPM
|
||||
UL7_3_TPE2
|
||||
UL11_9_ENC1UL11_12_ENC1UL11_13_ENC1
|
||||
UL7_4_ENC1UL7_3_ENC1
|
||||
EPCUL11_9_EPC1
|
||||
EPCUL11_10_EPC1
|
||||
RBBGUL11_9_S1A
|
||||
RBBGUL11_10_S1
|
||||
BB
|
||||
GPS3_1_S2
|
||||
RBBGPS4_1_S2
|
||||
RA
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
WUL11_9_JR1
|
||||
V
|
||||
PS2_3_VFD15HP300 FPM
|
||||
PS1_1_VFD12HP300 FPMPS1_2_VFD12HP300 FPM
|
||||
PS2_4_VFD13HP300 FPM PS2_5_VFD17.5HP300 FPMPS2_6_VFD13HP300 FPM
|
||||
PS1_4_VFD17.5HP300 FPMPS1_3_VFD12HP300 FPM
|
||||
PS1_5_VFD15HP300 FPM
|
||||
EPCPS1_1_EP2EPCPS1_1_EPC1RBBGPS1_1_S1
|
||||
EPCPS2_6_EPC2RBBGPS2_6_S2
|
||||
EPCPS1_5_EPC1
|
||||
RBBGPS1_5_S1
|
||||
PS1_2_TPE1
|
||||
PS1_4_TPE1
|
||||
PS1_4_TPE2
|
||||
PS2_5_TPE1
|
||||
PS2_5_TPE2
|
||||
BBA
|
||||
PS1_2_TPE2 EPCPS1_5_EPC2
|
||||
RBBGPS1_5_S2
|
||||
STOP THE EPC AT 8'-3"
|
||||
EPCPS2_6_EPC1PS2_6_TPE1PS1_5_TPE1
|
||||
PS2_3_JPE1
|
||||
RBBGPS2_6_S1
|
||||
PS4_1_VFD12HP300 FPMPS4_2_VFD13HP300 FPMPS4_3_VFD12HP220 FPMPS4_4_VFD13HP220 FPMPS4_5_VFD15HP300 FPM PS4_6_VFD17.5HP300 FPM PS4_7_VFD17.5HP300 FPM PS4_8_VFD15HP300 FPM
|
||||
PS3_1_VFD12HP300 FPMPS3_2_VFD13HP300 FPM
|
||||
PS3_3_VFD13HP300 FPMPS3_4_VFD12HP300 FPM PS3_5_VFD15HP300 FPM PS3_6_VFD15HP300 FPM PS3_7_VFD110HP300 FPM
|
||||
PS4_9_VFD13HP300 FPM
|
||||
PS3_8_VFD13HP300 FPMPS3_9_VFD15HP300 FPMPS3_10_VFD15HP300 FPM
|
||||
PS4_11_VFD15HP300 FPMPS4_12_VFD13HP300 FPM
|
||||
PS3_11_VFD13HP300 FPMPS3_12_VFD13HP300 FPM
|
||||
PS4_13_VFD13HP300 FPMPS4_14_VFD13HP300 FPM
|
||||
EPCPS4_1_EPC2EPCPS4_1_EPC1RBBGPS4_1_S1
|
||||
EPCPS3_1_EPC1EPCPS3_1_EPC2RBBGPS3_1_S1
|
||||
EPCPS4_14_EPC1R
|
||||
EPCPS3_12_EPC1RBBGPS3_12_S1
|
||||
PS4_2_TPE1
|
||||
PS3_1_TPE1
|
||||
PS3_5_TPE1
|
||||
PS3_5_TPE2 PS3_9_TPE1
|
||||
PS4_14_TPE1
|
||||
PS3_12_TPE1
|
||||
BBAWPS3_3_JR1PS3_3_JPE1
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
EPCPS3_12_EPC2
|
||||
RBBGPS3_12_S2A
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
EPCPS4_14_EPC2
|
||||
BBA
|
||||
BBA
|
||||
BBGPS4_14_S1A
|
||||
RBBGPS4_14_S2BBA
|
||||
WPS4_8_JR1
|
||||
WPS4_13_JR1
|
||||
WPS3_7_JR1
|
||||
WPS2_3_JR1RBB
|
||||
STOP THE EPC AT 8'-3"
|
||||
EPCUL2_3_EPC2
|
||||
EPCUL2_3_EPC1
|
||||
RBB
|
||||
STOP THE EPC AT 8'-3"
|
||||
EPCUL1_3_EPC2
|
||||
EPCUL1_3_EPC1
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
STOP THE EPC AT 8'-3"
|
||||
ST 1.5kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
V
|
||||
PS3_2_TPE1
|
||||
EPCUL4_3_EPC2
|
||||
EPCUL4_3_EPC1
|
||||
RBBEPCUL5_3_EPC2
|
||||
EPCUL5_3_EPC1
|
||||
EPCUL7_1_EPC2
|
||||
EPCUL7_1_EPC1
|
||||
GUL2_3_S2
|
||||
GUL1_3_S2
|
||||
UL3_2_TPE2
|
||||
GUL5_3_S2
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
UL1_3_TPE1UL2_3_TPE1
|
||||
UL2_3_LPE1
|
||||
UL2_3_LPE2UL4_3_TPE1
|
||||
UL4_3_LPE1
|
||||
UL4_3_LPE2UL5_3_TPE1
|
||||
UL5_3_LPE2
|
||||
UL5_3_LPE1
|
||||
UL2_3_FIO1
|
||||
UL1_3_FIO1
|
||||
UL3_2_TPE1UL3_2_LPE2
|
||||
UL3_2_LPE1
|
||||
UL3_2_FIO1
|
||||
UL4_3_FIO1
|
||||
UL5_3_FIO1
|
||||
UL6_2_FIO1
|
||||
UL7_3_FIO1
|
||||
UL8_2_FIO1
|
||||
UL9_3_FIO1
|
||||
UL10_2_FIO1
|
||||
UL11_3_FIO1
|
||||
UL12_3_FIO1
|
||||
RBBGUL1_3_S1
|
||||
RBBGUL2_3_S1
|
||||
UL1_3_LPE1
|
||||
UL1_3_DPE2
|
||||
UL1_8_ENC1UL1_8_TPE1
|
||||
RBB
|
||||
RBBGUL4_3_S2
|
||||
RBBGUL4_3_S1 UL4_5_VFD13HP420 FPMUL4_6_VFD13HP420 FPMUL4_7_VFD13HP420 FPM
|
||||
UL4_8_VFD13HP420 FPM
|
||||
UL4_5_ENC1UL4_6_ENC1UL4_7_ENC1UL4_5_TPE1UL4_6_TPE1UL4_7_TPE1
|
||||
UL4_4_TPE1
|
||||
UL4_8_ENC1UL4_8_TPE1 UL4_10A_VFD13HP280 FPMUL4_10B_VFD13HP280 FPM
|
||||
UL4_11_VFD12HP280 FPMUL4_12_VFD12HP280 FPMUL4_13_VFD15HP280 FPM
|
||||
UL4_11_TPE1UL4_11_TPE2
|
||||
UL4_12_TPE1RBBGPS2_1_S2EPCPS2_1_EP2EPCPS2_1_EPC1RBBGPS2_1_S1PS2_2_TPE1PS2_1_VFD12HP300 FPMPS2_2_VFD12HP300 FPMPS2_2_TPE2
|
||||
RBBGUL5_3_S1
|
||||
UL5_5_VFD13HP280 FPMUL5_6_VFD13HP420 FPMUL5_7_VFD13HP420 FPMUL5_8_VFD13HP420 FPMUL5_9_VFD13HP420 FPMUL5_10_VFD13HP420 FPMUL5_9_ENC1UL5_8_ENC1UL5_7_ENC1UL5_6_ENC1
|
||||
UL5_5_ENC1
|
||||
UL5_9_TPE1UL5_8_TPE1
|
||||
UL5_7_TPE1UL5_6_TPE2UL5_6_TPE1
|
||||
UL6_1_VFD12HP120 FPM UL6_2_VFD17.5HP280 FPM
|
||||
UL6_3_VFD13HP280 FPM
|
||||
UL6_4_VFD12HP280 FPMUL6_5_VFD13HP420 FPMUL6_6_VFD13HP420 FPMUL6_7_VFD13HP420 FPMUL6_8_VFD13HP420 FPMUL6_9_VFD13HP420 FPM
|
||||
UL6_3_ENC1
|
||||
UL6_5_ENC1UL6_6_ENC1UL6_7_ENC1UL6_8_ENC1
|
||||
UL6_2_ENC1
|
||||
UL6_4_ENC1
|
||||
UL6_1_TPE1 UL6_4_TPE1
|
||||
UL6_4_TPE2UL6_5_TPE1UL6_6_TPE1UL6_7_TPE1UL6_8_TPE1
|
||||
EPCUL6_2_EPC2
|
||||
EPCUL6_2_EPC1
|
||||
RBBGUL6_2_S2RBBGUL6_2_S1
|
||||
RBBEPCUL6_1_EPC2EPCUL6_1_EPC1
|
||||
RGUL6_1_SS1
|
||||
UL6_2_TPE2
|
||||
UL6_2_TPE1UL6_2_LPE2
|
||||
UL6_2_LPE1RBB
|
||||
UL12_DPM1MCM01
|
||||
UL11_DPM1MCM01
|
||||
UL10_DPM1MCM01
|
||||
UL9_DPM1MCM01
|
||||
UL8_DPM1MCM01
|
||||
UL7_DPM1MCM01
|
||||
UL6_DPM1MCM01
|
||||
UL5_DPM1MCM01
|
||||
UL4_DPM1MCM01
|
||||
UL3_DPM1MCM01
|
||||
UL2_DPM1MCM01
|
||||
UL1_DPM1MCM01
|
||||
PS1_DPM1MCM01
|
||||
PS3_DPM1MCM01 PS3_DPM2MCM01
|
||||
MCM01
|
||||
RBBGUL7_3_S2UL7_3_TPE1
|
||||
UL7_3_LPE2
|
||||
UL7_3_LPE1RBBGUL7_3_S1 UL7_9_VFD13HP280 FPM
|
||||
UL7_9_TPE2
|
||||
UL7_9_TPE4
|
||||
UL7_9_TPE5EPCUL7_4_EPC2
|
||||
EPCUL7_4_EPC1
|
||||
RBBGUL7_4_S2
|
||||
RBBGUL7_4_S1
|
||||
EPCUL7_9_EPC2
|
||||
EPCUL7_9_EPC1
|
||||
RBBGUL7_9_S2
|
||||
RBBGUL7_9_S1A
|
||||
WUL7_9_JR2
|
||||
WUL7_9_JR1
|
||||
UL7_5_VFD13HP420 FPMUL7_6_VFD13HP420 FPMUL7_7_VFD13HP420 FPM
|
||||
UL7_8_VFD13HP420 FPM
|
||||
UL7_5_ENC1UL7_6_ENC1UL7_7_ENC1UL7_5_TPE1UL7_6_TPE1UL7_7_TPE1
|
||||
UL7_4_TPE1
|
||||
UL7_8_ENC1UL7_8_TPE1 UL7_10A_VFD13HP280 FPMUL7_10B_VFD13HP280 FPM
|
||||
UL7_11_VFD12HP280 FPMUL7_12_VFD12HP280 FPM
|
||||
UL7_13_VFD15HP280 FPM
|
||||
UL7_11_TPE1UL7_11_TPE2
|
||||
UL7_12_TPE1
|
||||
UL7_9_TPE1
|
||||
PS3_6_TPE1
|
||||
PS3_7_JPE1
|
||||
PS3_9_TPE2
|
||||
PS3_10_JPE1
|
||||
PS3_12_TPE2
|
||||
UL8_1_VFD12HP120 FPM
|
||||
UL8_1_TPE1
|
||||
RBBEPCUL8_1_EPC2EPCUL8_1_EPC1
|
||||
RGUL8_1_SS1
|
||||
UL8_2_TPE1UL8_2_LPE2
|
||||
UL8_2_LPE1RBB
|
||||
UL8_3_VFD15HP280 FPMUL8_3_ENC1
|
||||
UL8_3_TPE1
|
||||
EPCUL8_3_EPC2RBBGUL8_3_S2
|
||||
RBBGUL8_3_S1
|
||||
UL8_4_VFD13HP280 FPMUL8_5_VFD13HP420 FPMUL8_6_VFD13HP420 FPMUL8_7_VFD13HP420 FPMUL8_8_VFD13HP420 FPMUL8_9_VFD13HP420 FPMUL8_8_ENC1UL8_7_ENC1UL8_6_ENC1
|
||||
UL8_5_ENC1
|
||||
UL8_4_ENC1
|
||||
UL8_8_TPE1UL8_7_TPE1
|
||||
UL8_6_TPE1UL8_5_TPE2UL8_5_TPE1
|
||||
UL8_2_VFD17.5HP120 FPM
|
||||
EPCUL8_3_EPC1
|
||||
EPCUL9_1_EPC2
|
||||
EPCUL9_1_EPC1
|
||||
RBBGUL9_3_S2UL9_3_TPE1
|
||||
UL9_3_LPE2
|
||||
UL9_3_LPE1RBBGUL9_3_S1 UL9_3_ENC1
|
||||
UL9_5_VFD12HP280 FPM
|
||||
UL9_6_VFD12HP280 FPMUL9_7_VFD13HP420 FPMUL9_8_VFD13HP420 FPMUL9_9_VFD13HP420 FPMUL9_10_VFD13HP420 FPMUL9_11_VFD12HP420 FPM
|
||||
UL9_5_ENC1
|
||||
UL9_7_ENC1UL9_8_ENC1UL9_9_ENC1UL9_10_ENC1
|
||||
UL9_6_ENC1
|
||||
UL9_6_TPE1
|
||||
UL9_6_TPE2UL9_7_TPE1UL9_8_TPE1UL9_9_TPE1UL9_10_TPE1
|
||||
EPCUL9_4_EPC2
|
||||
EPCUL9_4_EPC1
|
||||
RBBGUL9_4_S2RBBGUL9_4_S1UL9_4_ENC1
|
||||
UL8_2_TPE2
|
||||
UL9_3_TPE2
|
||||
UL9_4_TPE1
|
||||
UL10_1_VFD12HP120 FPM
|
||||
UL10_1_TPE1
|
||||
RBBEPCUL10_1_EPC2EPCUL10_1_EPC1
|
||||
RGUL10_1_SS1
|
||||
UL10_2_TPE1
|
||||
UL10_2_LPE2
|
||||
UL10_2_LPE1RBB
|
||||
UL10_2_VFD17.5HP120 FPM EPCUL10_3_EPC2RBBGUL10_3_S2RBBGUL10_3_S1EPCUL10_3_EPC1
|
||||
UL10_2_TPE2UL10_3_VFD12HP120 FPMUL10_4_VFD13HP420 FPMUL10_5_VFD13HP420 FPMUL10_6_VFD13HP420 FPMUL10_7_VFD13HP420 FPM
|
||||
UL10_4_ENC1UL10_5_ENC1UL10_6_ENC1UL10_4_TPE1UL10_5_TPE1UL10_6_TPE1
|
||||
UL10_3_TPE1
|
||||
UL10_7_ENC1UL10_7_TPE1UL10_8_VFD13HP420 FPMUL10_9_VFD13HP420 FPM
|
||||
UL10_10_VFD12HP420 FPM
|
||||
UL10_8_ENC1
|
||||
UL10_9_TPE1UL10_9_TPE2UL10_9_ENC1
|
||||
EPCUL11_1_EPC2EPCUL11_1_EPC1
|
||||
RBBG
|
||||
UL11_3_S2
|
||||
UL11_3_TPE1UL11_3_LPE2
|
||||
UL11_3_LPE1RBBGUL11_3_S1 UL11_3_ENC1UL11_3_TPE2
|
||||
EPCUL11_4_EPC2
|
||||
EPCUL11_4_EPC1
|
||||
RBBGUL11_4_S2RBBGUL11_4_S1
|
||||
UL11_8_VFD13HP300 FPM
|
||||
UL11_5_ENC1UL11_6_ENC1UL11_7_ENC1
|
||||
UL11_5_TPE1UL11_6_TPE1UL11_7_TPE1UL11_4_TPE1
|
||||
UL11_8_ENC1UL11_8_TPE1
|
||||
UL11_7_VFD13HP300 FPMUL11_6_VFD13HP300 FPMUL11_5_VFD13HP300 FPMUL11_4_VFD15HP420 FPM
|
||||
UL11_9_TPE1UL11_9_TPE2
|
||||
UL11_9_TPE3UL11_9_VFD13HP300 FPMUL11_10_VFD15HP280 FPM
|
||||
UL11_10_ENC1
|
||||
UL11_10_TPE1
|
||||
UL11_10_TPE2
|
||||
UL11_12_TPE1
|
||||
UL11_12_TPE2
|
||||
UL11_13_TPE1
|
||||
EPCUL12_3_EPC2
|
||||
EPCUL12_3_EPC1
|
||||
RBBG
|
||||
UL12_3_S2UL12_3_TPE1UL12_3_LPE2
|
||||
UL12_3_LPE1RBBGUL12_3_S1
|
||||
UL12_3_TPE2UL12_3_ENC1
|
||||
UL12_4_VFD15HP280 FPMUL12_4_ENC1
|
||||
UL12_4_TPE1
|
||||
EPCUL12_4_EPC2
|
||||
EPCUL12_4_EPC1
|
||||
RBBGUL12_4_S2
|
||||
RBBGUL12_4_S1
|
||||
UL12_5_VFD12HP280 FPMUL12_6_VFD13HP420 FPMUL12_8_VFD13HP420 FPM
|
||||
UL12_9_VFD13HP420 FPMUL12_10_VFD12HP420 FPMUL12_9_ENC1UL12_8_ENC1UL12_7_ENC1UL12_6_ENC1
|
||||
UL12_5_ENC1
|
||||
UL12_9_TPE1UL12_8_TPE1UL12_7_TPE1UL12_6_TPE2UL12_6_TPE1UL12_7_VFD13HP420 FPM
|
||||
UL11_14_TPE1
|
||||
PS4_2_JPE1
|
||||
PS4_4_TPE1PS4_4_TPE2
|
||||
BBA
|
||||
WPS4_2_JR1
|
||||
PS4_5_TPE1 PS4_6_TPE1 PS4_7_TPE1 PS4_8_JPE1
|
||||
PS4_10_TPE1
|
||||
PS4_10_VFD110HP300 FPM
|
||||
PS4_10_TPE2
|
||||
PS4_11_TPE1
|
||||
PS4_12_JPE1
|
||||
MCM01
|
||||
401
projects/MTN6/extracted_texts/MTN6_SYSDL-MCM02.txt
Normal file
401
projects/MTN6/extracted_texts/MTN6_SYSDL-MCM02.txt
Normal file
@ -0,0 +1,401 @@
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR40
|
||||
10T
|
||||
S7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR40
|
||||
10T
|
||||
S7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR40
|
||||
10T
|
||||
S7000
|
||||
SQR4010TS7000
|
||||
SQR4010T
|
||||
S7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000 SQR4010TS7000
|
||||
SQR4010TS7000
|
||||
SQR40
|
||||
10T
|
||||
S7000
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
PS5_12_TPE2
|
||||
UL16_3_TPE2 UL17_4_TPE1
|
||||
UL16_2_TPE2UL16_3_TPE1UL15_4_TPE1
|
||||
UL15_3_TPE2
|
||||
UL14_3_TPE2
|
||||
UL13_10_TPE2
|
||||
UL13_11_TPE1
|
||||
UL21_16_TPE1
|
||||
UL21_15_TPE2
|
||||
UL21_11_ENC1
|
||||
UL18_10_ENC1
|
||||
UL18_3_ENC1
|
||||
UL17_3_ENC1 UL17_4_ENC1
|
||||
UL16_2_ENC1
|
||||
UL15_3_ENC1 UL15_4_ENC1
|
||||
UL15_6_ENC1
|
||||
UL13_8_ENC1
|
||||
UL14_3_ENC1
|
||||
UL21_13_TPE1
|
||||
UL21_13_TPE2
|
||||
UL13_8_TPE5
|
||||
UL13_8_TPE4
|
||||
UL13_8_TPE3
|
||||
UL13_8_TPE2
|
||||
UL13_8_TPE1
|
||||
UL18_12_TPE2
|
||||
PS5_8_JPE1
|
||||
UL21_11_TPE2
|
||||
UL21_11_TPE3
|
||||
UL21_11_TPE4
|
||||
UL16_4_TPE1
|
||||
UL17_5_TPE1UL17_7_TPE1UL17_7_TPE2UL17_8_TPE1UL17_9_TPE1
|
||||
UL16_6_TPE1
|
||||
UL15_6_TPE1
|
||||
UL18_10_TPE1
|
||||
UL18_10_TPE2UL18_10_TPE3
|
||||
UL18_10_TPE4PS5_10_TPE1
|
||||
UL13_10_ENC1UL13_11_ENC1
|
||||
UL18_14_ENC1UL18_15_ENC1
|
||||
UL21_15_ENC1UL21_16_ENC1UL21_13_ENC1UL16_4_ENC1
|
||||
UL17_5_ENC1UL17_6_ENC1
|
||||
UL17_7_ENC1UL17_8_ENC1UL17_9_ENC1
|
||||
UL16_5_ENC1 UL21_12_ENC1
|
||||
UL15_11_ENC1
|
||||
EPCUL17_4_EPC2
|
||||
EPCUL17_4_EPC1
|
||||
EPCUL16_2_EPC2
|
||||
EPCUL16_2_EPC1
|
||||
EPCUL15_4_EPC2
|
||||
EPCUL15_4_EPC1
|
||||
RBBGUL17_4_S2
|
||||
RBBGUL17_4_S1RBBGUL16_2_S2
|
||||
RBBGUL16_2_S1RBBGUL15_4_S2
|
||||
RBBGUL15_4_S1
|
||||
EPC
|
||||
UL21_11_EPC1
|
||||
EPCUL21_11_EPC2
|
||||
RBBGUL21_11_S1A
|
||||
RBBGUL21_11_S2
|
||||
EPCUL21_13_EPC1RBBGUL21_13_S1
|
||||
EPCUL21_13_EPC2RBBGUL21_13_S2
|
||||
EPC
|
||||
UL18_10_EPC1RBBGUL18_10_S1A
|
||||
EPCUL18_10_EPC2RBBGUL18_10_S2
|
||||
EPCUL13_8_EPC2
|
||||
EPCUL13_8_EPC1
|
||||
RBBGUL13_8_S2
|
||||
RBBGUL13_8_S1A
|
||||
BBGPS7_1_S2
|
||||
BBGPS6_1_S2
|
||||
BBGPS5_1_S2
|
||||
RA
|
||||
RA
|
||||
RA
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
RBB
|
||||
STOP THE EPC AT 8'-3"
|
||||
WUL13_8_JR2
|
||||
WUL13_8_JR1
|
||||
WUL18_10_JR3
|
||||
W
|
||||
UL18_10_JR1
|
||||
WUL21_11_JR1
|
||||
V
|
||||
PS5_1_VFD12HP300 FPMPS5_2_VFD13HP300 FPM
|
||||
PS6_1_VFD12HP300 FPMPS6_2_VFD13HP300 FPM
|
||||
PS7_1_VFD12HP300 FPMPS7_2_VFD13HP300 FPM
|
||||
PS5_3_VFD13HP300 FPM
|
||||
PS5_4_VFD13HP300 FPM
|
||||
PS5_5_VFD15HP300 FPM PS5_6_VFD15HP300 FPMPS5_7_VFD110HP300 FPM
|
||||
PS5_8_VFD15HP300 FPM
|
||||
PS5_9_VFD13HP300 FPM
|
||||
PS5_10_VFD110HP300 FPM
|
||||
PS5_11_VFD12HP300 FPMPS5_12_VFD110HP300 FPMPS5_13_VFD13HP300 FPM
|
||||
PS6_5_VFD15HP300 FPM
|
||||
PS6_7_VFD17.5HP300 FPM
|
||||
PS6_9_VFD13HP300 FPM
|
||||
PS6_10_VFD110HP300 FPM
|
||||
PS6_11_VFD13HP300 FPMPS6_12_VFD110HP300 FPMPS6_13_VFD13HP300 FPM
|
||||
PS7_3_VFD12HP300 FPMPS7_4_VFD13HP300 FPMPS7_5_VFD17.5HP300 FPM
|
||||
PS7_6_VFD17.5HP300 FPM
|
||||
PS7_7_VFD110HP300 FPM PS7_8_VFD110HP300 FPM PS7_9_VFD17.5HP300 FPM PS7_10_VFD13HP300 FPM
|
||||
PS7_14_VFD17.5HP300 FPM
|
||||
PS5_4_TPE1PS5_4_TPE2 PS5_5_JPE1
|
||||
PS5_7_TPE1
|
||||
UL18_10_TPE5
|
||||
PS5_10_JPE1PS5_12_TPE1
|
||||
PS5_13_TPE1PS6_12_TPE2
|
||||
PS6_8_JPE1
|
||||
UL21_15_TPE1
|
||||
PS6_4_TPE1
|
||||
PS7_14_TPE2
|
||||
EPCPS5_1_EPC1EPCPS5_1_EPC2
|
||||
RBBGPS5_1_S1
|
||||
EPCPS6_1_EPC1EPCPS6_1_EPC2
|
||||
RBBGPS6_1_S1
|
||||
EPCPS7_1_EPC1EPCPS7_1_EPC2
|
||||
RBBGPS7_1_S1
|
||||
EPCPS5_13_EPC1
|
||||
EPCPS6_13_EPC2
|
||||
EPCPS7_14_EPC1
|
||||
RBB
|
||||
PS5_2_JPE1 BBA
|
||||
WPS5_6_JR1
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
BBA
|
||||
WPS7_13_JR1 EPCPS7_14_EPC2
|
||||
RBB
|
||||
EPCPS7_9_EPC1
|
||||
RBBGPS7_9_S2EPCPS7_9_EPC2
|
||||
RBBGPS7_9_S1
|
||||
WPS5_9_JR1
|
||||
BBA
|
||||
WPS6_8_JR1
|
||||
BBA
|
||||
WPS5_9_JR2
|
||||
W
|
||||
PS6_9_JR1
|
||||
W
|
||||
UL21_5_JR1
|
||||
BBA
|
||||
WPS6_11_JR1
|
||||
EPCPS5_13_EPC2
|
||||
EPCPS6_13_EPC1RBB
|
||||
W
|
||||
PS5_10_JR1
|
||||
BBA
|
||||
WPS5_11_JR1
|
||||
RBB
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
X-SQ-96_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-180-P4.0
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-41.5_43-180-P4.0
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-96_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
X-SQ-96_43-90-P2.5+
|
||||
ST 4.0kW 1.4375
|
||||
STOP THE EPC AT 8'-3"
|
||||
STOP THE EPC AT 8'-3"
|
||||
V
|
||||
UL13_10_TPE1
|
||||
UL13_2_FIO1
|
||||
UL14_3_FIO1
|
||||
UL15_3_FIO1
|
||||
UL16_2_FIO1
|
||||
UL17_3_FIO1
|
||||
UL18_3_FIO1
|
||||
UL19_2_FIO1
|
||||
PS7_DPM3MCM02
|
||||
PS5_DPM1MCM02
|
||||
UL13_DPM1MCM02
|
||||
UL14_DPM1MCM02
|
||||
UL15_DPM1MCM02
|
||||
PS6_DPM1MCM02
|
||||
PS7_DPM1MCM02 PS7_DPM2MCM02
|
||||
UL16_DPM1MCM02
|
||||
UL18_DPM1MCM02
|
||||
UL19_DPM1MCM02
|
||||
UL20_DPM1MCM02
|
||||
MCM02
|
||||
UL17_DPM1MCM02
|
||||
UL21_DPM1MCM02
|
||||
UL13_1_VFD12HP120 FPM
|
||||
UL13_1_TPE1
|
||||
RBBEPCUL13_1_EPC2EPCUL13_1_EPC1
|
||||
RGUL13_1_SS1
|
||||
UL13_2_TPE1UL13_2_LPE2
|
||||
UL13_2_LPE1RBB
|
||||
EPCUL13_4_EPC2
|
||||
EPCUL13_4_EPC1
|
||||
RBBGUL13_4_S2
|
||||
RBBGUL13_4_S1UL13_4_VFD13HP300 FPMUL13_5_VFD13HP300 FPMUL13_6_VFD3HP300 FPM
|
||||
UL13_7_VFD13HP300 FPM
|
||||
UL13_4_ENC1UL13_5_ENC1UL13_6_ENC1UL13_4_TPE1UL13_5_TPE1UL13_6_TPE1
|
||||
UL13_3_TPE1
|
||||
UL13_7_ENC1UL13_7_TPE1UL13_3_VFD13HP280 FPMUL13_2_VFD17.5HP280 FPM UL13_8_VFD15HP280 FPMUL13_9A_VFD13HP300 FPMUL13_9B_VFD13HP300 FPMUL13_10_VFD12HP280 FPMUL13_11_VFD12HP280 FPMUL13_12_VFD15HP280 FPM
|
||||
PS5_2_TPE1
|
||||
RGPS5_13_SS1
|
||||
PS5_12_FIO1
|
||||
EPCUL14_3_EPC2
|
||||
EPCUL14_3_EPC1
|
||||
UL14_3_TPE1
|
||||
UL14_3_LPE1
|
||||
UL14_3_LPE2RBBGUL14_3_S2
|
||||
RBBGUL14_3_S1
|
||||
RBB
|
||||
UL14_3_VFD15HP280 FPM UL14_4_VFD15HP280 FPM
|
||||
UL14_5_VFD13HP280 FPMUL14_6_VFD13HP420 FPMUL14_8_VFD13HP420 FPMUL14_9_VFD13HP420 FPMUL14_10_VFD13HP420 FPMUL14_9_ENC1UL14_8_ENC1UL14_7_ENC1UL14_6_ENC1UL14_4_ENC1
|
||||
UL14_4_TPE1UL14_9_TPE1
|
||||
UL14_8_TPE1
|
||||
UL14_7_TPE2UL14_7_TPE1UL14_5_TPE1
|
||||
EPCUL14_4_EPC2
|
||||
EPCUL14_4_EPC1
|
||||
RBBGUL14_4_S2
|
||||
RBBGUL14_4_S1
|
||||
UL14_5_ENC1
|
||||
EPCUL15_3_EPC2
|
||||
EPCUL15_3_EPC1
|
||||
UL15_3_TPE1
|
||||
UL15_3_LPE1
|
||||
UL15_3_LPE2RBBGUL15_3_S2
|
||||
RBBGUL15_3_S1UL15_3_VFD15HP280 FPM UL15_4_VFD15HP280 FPM
|
||||
UL15_5_VFD12HP280 FPMUL15_5_ENC1
|
||||
UL15_6_VFD13HP420 FPMUL15_7_VFD13HP420 FPMUL15_8_VFD13HP420 FPMUL15_9_VFD13HP420 FPMUL15_10_VFD13HP420 FPMUL15_11_VFD12HP420 FPM
|
||||
UL15_6_TPE2UL15_7_ENC1UL15_7_TPE1UL15_8_TPE1UL15_9_TPE1
|
||||
UL15_10_TPE1
|
||||
UL15_8_ENC1UL15_9_ENC1UL15_10_ENC1
|
||||
UL16_1_VFD12HP120 FPM
|
||||
UL16_1_TPE1
|
||||
RBBEPCUL16_1_EPC2EPCUL16_1_EPC1
|
||||
RGUL16_1_SS1
|
||||
UL16_2_TPE1UL16_2_LPE2
|
||||
UL16_2_LPE1RBB UL16_2_VFD17.5HP280 FPMUL16_3_VFD13HP280 FPM
|
||||
UL16_4_VFD13HP280 FPMUL16_5_VFD12HP280 FPM
|
||||
UL16_6_ENC1UL16_7_ENC1UL16_8_ENC1UL16_6_TPE2UL16_7_TPE1UL16_8_TPE1UL16_6_VFD13HP280 FPMUL16_7_VFD13HP280 FPMUL16_8_VFD13HP280 FPMUL16_9_VFD12HP280 FPM
|
||||
EPCUL17_3_EPC2
|
||||
EPCUL17_3_EPC1
|
||||
UL17_3_TPE1
|
||||
UL17_3_LPE1
|
||||
UL17_3_LPE2RBBGUL17_3_S2
|
||||
RBBGUL17_3_S1UL17_3_VFD15HP120 FPM UL17_4_VFD15HP280 FPM
|
||||
UL17_5_VFD13HP420 FPMUL17_6_VFD12HP280 FPMUL17_7_VFD13HP420 FPMUL17_8_VFD13HP420 FPM
|
||||
UL17_10_VFD12HP420 FPMUL17_9_VFD13HP420 FPM
|
||||
EPCUL18_3_EPC2
|
||||
EPCUL18_3_EPC1
|
||||
UL18_3_TPE1
|
||||
UL18_3_LPE1
|
||||
UL18_3_LPE2RBBGUL18_3_S2
|
||||
RBBGUL18_3_S1UL18_3_VFD15HP120 FPM
|
||||
UL18_3_TPE2 UL18_4_TPE1
|
||||
UL18_4_ENC1
|
||||
UL18_5_TPE1UL18_5_ENC1
|
||||
EPCUL18_4_EPC2
|
||||
EPCUL18_4_EPC1
|
||||
RBBGUL18_4_S2
|
||||
RBBGUL18_4_S1UL18_4_VFD15HP280 FPM
|
||||
UL18_5_VFD13HP420 FPMUL18_6_VFD15HP280 FPMUL18_6_ENC1UL18_7_TPE1UL18_7_ENC1UL18_7_TPE2UL18_8_TPE1UL18_9_TPE1
|
||||
UL18_8_ENC1UL18_9_ENC1
|
||||
UL18_7_VFD13HP280 FPMUL18_8_VFD13HP280 FPMUL18_9_VFD13HP280 FPM
|
||||
WUL18_10_JR2
|
||||
UL18_10_VFD15HP280 FPM
|
||||
UL18_12_TPE1
|
||||
UL18_11_VFD15HP280 FPMUL18_12_VFD13HP280 FPM
|
||||
UL18_12_ENC1
|
||||
UL18_11_ENC1UL18_13A_VFD13HP280 FPMUL18_13B_VFD13HP280 FPM
|
||||
UL18_14_TPE1
|
||||
UL18_14_TPE2
|
||||
UL18_15_TPE1
|
||||
UL18_14_VFD12HP280 FPMUL18_15_VFD12HP280 FPMUL18_16_VFD15HP280 FPM
|
||||
UL19_1_VFD12HP120 FPM
|
||||
UL19_1_TPE1
|
||||
RBBEPCUL19_1_EPC2EPCUL19_1_EPC1
|
||||
RGUL19_1_SS1
|
||||
UL19_2_TPE1UL19_2_LPE2
|
||||
UL19_2_LPE1RBB
|
||||
UL20_3_ENC1UL20_3_FIO1EPCUL20_3_EPC2
|
||||
EPCUL20_3_EPC1
|
||||
UL20_3_TPE1
|
||||
UL20_3_LPE1
|
||||
UL20_3_LPE2RBBGUL20_3_S2
|
||||
RBBGUL20_3_S1UL20_3_VFD15HP120 FPM
|
||||
UL20_3_TPE2
|
||||
UL21_3_ENC1UL21_3_FIO1EPCUL21_3_EPC2
|
||||
EPCUL21_3_EPC1
|
||||
UL21_3_TPE1
|
||||
UL21_3_LPE1
|
||||
UL21_3_LPE2RBBGUL21_3_S2
|
||||
RBBGUL21_3_S1UL21_3_VFD15HP120 FPM
|
||||
UL21_3_TPE2
|
||||
UL19_2_ENC1EPCUL19_2_EPC2
|
||||
EPCUL19_2_EPC1
|
||||
RBBGUL19_2_S2
|
||||
RBBGUL19_2_S1UL19_2_VFD17.5HP280 FPMUL19_2_TPE2
|
||||
UL19_3_VFD12HP280 FPMUL19_3_ENC1
|
||||
UL19_4_TPE1
|
||||
UL19_4_TPE2
|
||||
UL19_4_ENC1UL19_4_VFD12HP280 FPMUL19_5_ENC1UL19_6_ENC1UL19_7_ENC1UL19_8_ENC1UL19_5_TPE1UL19_6_TPE1UL19_7_TPE1UL19_8_TPE1UL19_9_VFD12HP420 FPMUL19_8_VFD13HP420 FPM
|
||||
UL19_7_VFD13HP420 FPMUL19_6_VFD13HP420 FPMUL19_5_VFD13HP420 FPM
|
||||
UL20_4_ENC1EPCUL20_4_EPC2
|
||||
EPCUL20_4_EPC1
|
||||
RBBGUL20_4_S2
|
||||
RBBGUL20_4_S1UL20_4_VFD15HP280 FPMUL20_44_TPE1
|
||||
UL20_5_VFD12HP280 FPMUL20_5_ENC1
|
||||
UL20_6_TPE1UL20_6_ENC1
|
||||
UL20_11_VFD12HP420 FPMUL20_10_VFD13HP420 FPMUL20_9_VFD13HP420 FPM
|
||||
UL20_7_VFD13HP420 FPMUL20_8_VFD13HP420 FPM
|
||||
UL20_6_VFD13HP420 FPM
|
||||
UL20_6_TPE2UL20_7_TPE1UL20_8_TPE1UL20_9_TPE1UL20_10_TPE1
|
||||
UL20_7_ENC1UL20_8_ENC1UL20_9_ENC1UL20_10_ENC1
|
||||
UL21_4_ENC1EPCUL21_4_EPC2
|
||||
EPCUL21_4_EPC1
|
||||
RBBGUL21_4_S2
|
||||
RBBGUL21_4_S1UL21_4_VFD15HP280 FPMUL21_4_TPE1UL21_6_TPE1
|
||||
UL21_5_VFD15HP280 FPM
|
||||
UL21_5_ENC1UL21_6_ENC1UL21_7_ENC1UL21_8_ENC1UL21_9_ENC1UL21_10_ENC1
|
||||
UL21_6_TPE2UL21_7_TPE1UL21_8_TPE1UL21_9_TPE1UL21_10_TPE1UL21_11_TPE1
|
||||
UL21_6_VFD13HP300 FPMUL21_7_VFD13HP300 FPMUL21_8_VFD13HP300 FPMUL21_9_VFD13HP300 FPMUL21_10_VFD13HP300 FPM
|
||||
WUL21_11_JR2
|
||||
UL21_11_VFD17.5HP280 FPM
|
||||
UL21_11_TPE5
|
||||
UL21_12_VFD15HP280 FPM UL21_13_VFD12HP280 FPMUL21_14A_VFD13HP280 FPMUL21_14B_VFD13HP280 FPMUL21_15_VFD12HP280 FPM
|
||||
UL21_16_VFD12HP280 FPM
|
||||
UL21_17_VFD15HP280 FPMPS6_2_JPE1PS6_2_TPE1
|
||||
PS6_3_VFD12HP300 FPM
|
||||
PS6_4_TPE2
|
||||
PS6_4_VFD13HP300 FPM PS6_6_VFD15HP300 FPM
|
||||
PS6_5_JPE1
|
||||
PS6_7_TPE1BBA
|
||||
WPS6_6_JR1
|
||||
PS6_8_VFD15HP300 FPMPS6_10_TPE1
|
||||
PS6_10_JPE1PS6_12_TPE1
|
||||
RGPS6_13_SS1
|
||||
PS7_2_TPE1PS7_2_JPE1PS7_4_TPE1PS7_4_TPE2 PS7_5_TPE1 PS7_6_TPE1 PS7_7_TPE1 PS7_8_TPE1 PS7_9_TPE1PS7_10_JPE1BBA
|
||||
WPS7_11_JR1
|
||||
PS7_11_VFD13HP300 FPM
|
||||
PS7_12_TPE1
|
||||
PS7_12_VFD13HP300 FPM
|
||||
PS7_12_JPE1PS7_13_VFD13HP300 FPMPS7_14_TPE1
|
||||
RGPS7_14_SS1PS7_14_FIO1
|
||||
BBA
|
||||
MCM02
|
||||
181
projects/MTN6/extracted_texts/MTN6_SYSDL-MCM03.txt
Normal file
181
projects/MTN6/extracted_texts/MTN6_SYSDL-MCM03.txt
Normal file
@ -0,0 +1,181 @@
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
UL1_14_VFD13HP420 FPMUL1_15_VFD13HP420 FPMUL1_16_VFD13HP420 FPMUL1_17_VFD13HP420 FPM
|
||||
UL1_18_VFD15HP420 FPM
|
||||
UL1_19_VFD13HP420 FPM
|
||||
UL1_20_VFD12HP420 FPM
|
||||
UL1_18_ENC1
|
||||
UL1_14_TPE1
|
||||
UL1_15_TPE1
|
||||
UL1_16_TPE1
|
||||
UL1_17_TPE1
|
||||
UL1_19_TPE2UL1_19_TPE1EPCUL1_14_EPC1
|
||||
EPCUL1_14_EPC2
|
||||
BBGUL1_14_S1RA
|
||||
UL7_14_VFD13HP420 FPMUL7_15_VFD13HP420 FPMUL7_16_VFD13HP420 FPM
|
||||
UL7_17_VFD13HP420 FPM
|
||||
UL7_18_VFD15HP420 FPM
|
||||
UL7_19_VFD13HP420 FPM
|
||||
UL7_20_VFD13HP420 FPM
|
||||
UL11_15_VFD13HP420 FPMUL11_16_VFD13HP420 FPMUL11_17_VFD13HP420 FPMUL11_18_VFD13HP420 FPM
|
||||
UL11_19_VFD15HP420 FPM
|
||||
UL11_20_VFD13HP420 FPM
|
||||
UL11_21_VFD13HP420 FPM
|
||||
EPCUL7_14_EPC1
|
||||
EPCUL7_14_EPC2
|
||||
EPCUL11_15_EPC1
|
||||
EPCXXXX_EPC1
|
||||
RBBGUL7_14_S2
|
||||
BBGUL11_15_S1RA
|
||||
RBBGUL1_14_S2A
|
||||
RBBGUL11_15_S2
|
||||
RBBGUL7_14_S1
|
||||
A
|
||||
NCP1_1_VFD7.5HP300 FPM
|
||||
NCP1_2_VFD17.5HP300 FPM
|
||||
NCP1_3_VFD17.5HP300 FPM
|
||||
NCP1_4_VFD15HP300 FPM
|
||||
NCP1_5_VFD17.5HP350 FPM NCP1_6_VFD15HP350 FPM NCP1_7_VFD17.5HP350 FPM NCP1_8_VFD17.5HP350 FPM
|
||||
NCP_005_ENW1
|
||||
EPCNCP1_1_EPC1RBB
|
||||
EPCNCP1_1_EPC2
|
||||
RBBA
|
||||
A
|
||||
EPCNCP1_2_EPC1
|
||||
RBB
|
||||
EPCNCP1_2_EPC2
|
||||
RBB
|
||||
A
|
||||
EPCNCP1_3_EPC1RBB
|
||||
EPCNCP1_3_EPC2
|
||||
RBB
|
||||
WNCP1_3_JR3ABB
|
||||
EPCNCP1_8_EPC1
|
||||
EPCNCP1_8_EPC2
|
||||
V
|
||||
GNCP1_1_S2
|
||||
GNCP1_1_S1
|
||||
GNCP1_2_S2GNCP1_2_S1
|
||||
GNCP1_3_S2GNCP1_3_S1
|
||||
NCP1_1_ENC1
|
||||
NCP1_2_ENC1
|
||||
NCP1_3_ENC1
|
||||
NCP1_1_TPE1
|
||||
NCP1_5_TPE1 NCP1_5_TPE2NCP1_6_TPE1
|
||||
UL13_DPM2MCM03
|
||||
UL1_DPM2MCM03
|
||||
UL7_DPM2MCM03
|
||||
MCM03
|
||||
NCP_DPM1MCM03
|
||||
UL4_14_VFD12HP420 FPMUL4_15_VFD13HP420 FPMUL4_16_VFD13HP420 FPMUL4_17_VFD13HP420 FPM
|
||||
UL4_18_VFD15HP420 FPM
|
||||
UL4_19_VFD13HP420 FPM
|
||||
UL4_20_VFD12HP420 FPM
|
||||
UL4_18_ENC1
|
||||
UL4_14_TPE1
|
||||
UL4_15_TPE1
|
||||
UL4_16_TPE1
|
||||
UL4_17_TPE1
|
||||
UL4_19_TPE2UL4_19_TPE1BBGUL4_14_S1RA
|
||||
RBBGUL4_14_S2A
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
ST 1.5kW 1.4375
|
||||
UL13_13_TPE1
|
||||
UL13_13_ENC1
|
||||
EPCUL21_18_EPC1
|
||||
EPCUL21_18_EPC2
|
||||
EPCUL18_17_EPC1
|
||||
EPCUL18_17_EPC2
|
||||
EPCUL13_13_EPC1
|
||||
EPCUL13_13_EPC2
|
||||
RBBGUL21_18_S2
|
||||
RBBGUL18_17_S2
|
||||
RBBGUL13_13_S2
|
||||
A
|
||||
A
|
||||
RBBGUL18_17_S1
|
||||
RBBGUL21_18_S1
|
||||
ARBBGUL13_13_S1
|
||||
EPCUL4_14_EPC2
|
||||
EPCUL4_14_EPC1
|
||||
UL7_18_ENC1
|
||||
UL7_14_TPE1
|
||||
UL7_15_TPE1
|
||||
UL7_16_TPE1
|
||||
UL7_17_TPE1
|
||||
UL7_19_TPE2UL7_19_TPE1
|
||||
UL11_15_TPE1
|
||||
UL11_16_TPE1
|
||||
UL11_17_TPE1
|
||||
UL11_18_TPE1
|
||||
UL11_19_ENC1
|
||||
UL11_20_TPE2UL11_20_TPE1
|
||||
UL13_13_VFD13HP420 FPM
|
||||
UL1_14_ENC1UL1_15_ENC1UL1_16_ENC1UL1_17_ENC1
|
||||
UL1_19_ENC1
|
||||
UL4_14_ENC1UL4_15_ENC1UL4_16_ENC1UL4_17_ENC1
|
||||
UL4_19_ENC1
|
||||
UL7_14_ENC1UL7_15_ENC1UL7_16_ENC1UL7_17_ENC1
|
||||
UL7_19_ENC1
|
||||
UL11_15_ENC1UL11_16_ENC1UL11_17_ENC1UL11_18_ENC1
|
||||
UL11_20_ENC1
|
||||
UL13_14_VFD13HP420 FPMUL13_15_VFD13HP420 FPMUL13_16_VFD13HP420 FPMUL13_17_VFD15HP420 FPM
|
||||
UL13_18_VFD13HP420 FPM
|
||||
UL13_19_VFD12HP420 FPM
|
||||
UL13_14_TPE1
|
||||
UL13_15_TPE1
|
||||
UL13_16_TPE1
|
||||
UL13_18_TPE2
|
||||
UL13_18_TPE1UL13_18_ENC1
|
||||
UL13_14_ENC1UL13_15_ENC1UL13_16_ENC1
|
||||
UL13_17_ENC1
|
||||
UL18_17_TPE1
|
||||
UL18_17_ENC1UL18_17_VFD13HP420 FPMUL18_18_VFD13HP420 FPMUL18_19_VFD13HP420 FPMUL18_20_VFD13HP420 FPMUL18_21_VFD15HP420 FPM
|
||||
UL18_18_TPE1
|
||||
UL18_19_TPE1
|
||||
UL18_20_TPE1
|
||||
UL18_18_ENC1UL18_19_ENC1UL18_20_ENC1
|
||||
UL18_21_ENC1
|
||||
UL18_22_VFD13HP420 FPM
|
||||
UL18_23_VFD12HP420 FPMUL18_22_TPE2
|
||||
UL18_22_TPE1UL18_22_ENC1
|
||||
UL21_18_TPE1
|
||||
UL21_18_ENC1
|
||||
UL21_18_VFD13HP420 FPMUL21_19_VFD13HP420 FPMUL21_20_VFD13HP420 FPMUL21_21_VFD13HP420 FPMUL21_22_VFD15HP420 FPM
|
||||
UL21_19_TPE1
|
||||
UL21_20_TPE1
|
||||
UL21_21_TPE1
|
||||
UL21_19_ENC1UL21_20_ENC1UL21_21_ENC1
|
||||
UL21_22_ENC1
|
||||
UL21_23_VFD13HP420 FPM
|
||||
UL21_24_VFD12HP420 FPMUL21_23_TPE2
|
||||
UL21_23_TPE1UL21_23_ENC1
|
||||
NCP1_1_TPE2
|
||||
NCP1_1_TPE3
|
||||
NCP1_1_TPE4
|
||||
WNCP1_1_JR1BBA
|
||||
NCP1_1_TPE5
|
||||
NCP1_2_TPE1
|
||||
NCP1_2_TPE2
|
||||
NCP1_2_TPE3
|
||||
NCP1_2_TPE4
|
||||
WNCP1_2_JR1BBA
|
||||
NCP1_2_TPE5
|
||||
WNCP1_3_JR1BBA
|
||||
WNCP1_3_JR2BBA
|
||||
NCP1_3_TPE1
|
||||
NCP1_3_TPE2
|
||||
NCP1_3_TPE3
|
||||
NCP1_3_TPE4
|
||||
NCP1_3_TPE5
|
||||
NCP1_3_TPE6
|
||||
NCP1_3_TPE7
|
||||
NCP1_7_TPE1 RBB
|
||||
RBB
|
||||
GNCP1_8_S1
|
||||
GNCP1_8_S2
|
||||
NCP1_8_TPE1NCP1_8_FIO1
|
||||
MCM03
|
||||
587
projects/MTN6/extracted_texts/MTN6_SYSDL-MCM04.txt
Normal file
587
projects/MTN6/extracted_texts/MTN6_SYSDL-MCM04.txt
Normal file
@ -0,0 +1,587 @@
|
||||
2'-1.5" EL
|
||||
2'-3" EL
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
ERSCERSCERSCERSCERSCERSCERSCERSCERSCERSCERSCERSCERSCERSCERSC MDR POWER SUPPLY80AMDR POWER SUPPLY80A
|
||||
V
|
||||
11'-2" EL
|
||||
1'-4" EL
|
||||
FL_DPM1MCM04
|
||||
FL_DPM2MCM04
|
||||
ULGLB_DPM1MCM04
|
||||
ULGLC_DPM1MCM04
|
||||
MCM04
|
||||
PRS1_DPM1MCM04
|
||||
CH_DPM2MCM04
|
||||
FL1038_2_PE1ABBB
|
||||
FL1038_1CH_PE1
|
||||
FL1038_2_PE2
|
||||
FL1038_2_VFD15HP350FPM
|
||||
FL1038_3CH_PE1BBBWFL1038_2_JR2WFL1038_2_JR1
|
||||
WFL1038_1_JR1
|
||||
ULC8_3_VFD12HP80FPMULC7_3_VFD12HP80FPMULC6_3_VFD12HP80FPMULC5_3_VFD12HP80FPM
|
||||
PS10_1_VFD15HP150FPMPS10_2_VFD115HP200FPM
|
||||
PS10_5_VFD115HP240FPM
|
||||
PS11_1_VFD15HP150FPMPS11_2_VFD15HP200FPMPS11_3_VFD110HP240FPM
|
||||
PS11_4_VFD110HP240FPM
|
||||
PS11_6_VFD110HP240FPM PS11_7_VFD120HP240FPM PS11_8_VFD115HP240FPM PS11_9_VFD115HP240FPM
|
||||
PS11_11_VFD115HP240FPMULC8_3_JPE2ULC7_3_JPE2ULC6_3_JPE2ULC5_3_JPE2
|
||||
PS10_1_JPE2
|
||||
PS10_1_JPE1PS10_1_JPE3PS11_1_JPE1
|
||||
PS11_1_JPE2
|
||||
PS11_1_JPE3PS10_3_JPE1 PS11_2_JPE1
|
||||
PS10_5CH2_FPE1PS10_5CH2_JPE1
|
||||
PS10_5CH5_FPE2
|
||||
PS10_6CH_FPE1
|
||||
PS10_5_JPE4
|
||||
PS10_5_JPE5
|
||||
PS10_5_JPE3
|
||||
PS10_5_JPE2
|
||||
PS10_5_JPE1
|
||||
PS11_3_JPE2
|
||||
PS11_4_JPE1
|
||||
PS11_11_JPE1
|
||||
PS11_11_JPE2
|
||||
PS11_11_JPE3
|
||||
PS11_11_JPE4
|
||||
PS11_11_JPE5
|
||||
PS11_11CH1_JPE1
|
||||
EPCULC5_3_EPC1
|
||||
EPCULC5_3_EPC2
|
||||
EPCULC6_3_EPC1
|
||||
EPCULC7_3_EPC1
|
||||
EPCULC7_3_EPC2
|
||||
EPCULC8_3_EPC1
|
||||
EPCPS10_1_EPC1EPCPS11_1_EPC1
|
||||
EPCPS10_5_EPC1
|
||||
EPCPS11_11_EPC1
|
||||
WPS10_1_JR1
|
||||
WULC8_3_JR1
|
||||
WULC7_3_JR1
|
||||
WULC6_3_JR1
|
||||
WULC5_3_JR1W
|
||||
PS11_1_JR2
|
||||
PS11_9_JPE1
|
||||
WPS11_11_JR1
|
||||
WPS11_11_JR2
|
||||
WPS10_5_JR1
|
||||
WPS10_5_JR2ABB
|
||||
ABB
|
||||
ABBR
|
||||
GPS10_3_JR1
|
||||
GPS11_11_S1
|
||||
RABB RABB RABB RABB
|
||||
ABBABBR ABBR
|
||||
ABBR
|
||||
ABB
|
||||
ABB
|
||||
PS11_1_FIO1PS10_1_FIO2
|
||||
PS10_5_FIO1
|
||||
PS10_5_FIO3
|
||||
PS11_11_FIO1
|
||||
PS10_5DIV1_LS1LSPS10_5DIV1_LS2LS
|
||||
PS10_5DIV2_LS1LSPS10_5DIV2_LS2LS
|
||||
PS10_5DIV3_LS1LSPS10_5DIV3_LS2LS
|
||||
PS10_5DIV5_LS1LSPS10_5DIV5_LS2LS
|
||||
PS11_11DIV1_LS1LSPS11_11DIV1_LS2LS
|
||||
PS11_11DIV2_LS1LSPS11_11DIV2_LS2LS
|
||||
PS11_11DIV3_LS1LSPS11_11DIV3_LS2LS
|
||||
PS11_11DIV4_LS1LSPS11_11DIV4_LS2LS
|
||||
PS11_11DIV5_LS1LSPS11_11DIV5_LS2LS
|
||||
PS11_11DIV6_LS1LSPS11_11DIV6_LS2LS
|
||||
SOLPS10_5DIV5_SOL1SOLPS10_5DIV5_SOL2
|
||||
SOLPS10_5DIV3_SOL1SOLPS10_5DIV3_SOL2
|
||||
SOLPS10_5DIV2_SOL1SOLPS10_5DIV2_SOL2SOLPS10_5DIV1_SOL1SOLPS10_5DIV1_SOL2
|
||||
SOLPS11_11DIV1_SOL1SOLPS11_11DIV1_SOL2
|
||||
SOLPS11_11DIV2_SOL1SOLPS11_11DIV2_SOL2
|
||||
SOLPS11_11DIV3_SOL1SOLPS11_11DIV3_SOL2
|
||||
SOLPS11_11DIV4_SOL1SOLPS11_11DIV4_SOL2
|
||||
SOLPS11_11DIV5_SOL1SOLPS11_11DIV5_SOL2
|
||||
SOLPS11_11DIV6_SOL1SOLPS11_11DIV6_SOL2
|
||||
PS10_5CH2_FPE2PS10_5CH1_JPE1PS10_5CH1_FPE1PS10_5CH1_FPE2
|
||||
PS10_5CH5_FPE1PS10_5CH5_JPE1
|
||||
PS10_1_JPE4
|
||||
PS11_11CH1_FPE1PS11_11CH1_FPE2PS11_11CH2_JPE1
|
||||
PS11_12CH_FPE1ULC8_3_JPE1ULC7_3_JPE1ULC6_3_JPE1
|
||||
ULC5_3_JPE1
|
||||
PS11_1_JPE4
|
||||
PRS3_2B_VFD12HP120 FPMPRS3_3B_VFD13HP120 FPM
|
||||
PRS3_2A_VFD12HP120 FPMPRS3_3A_VFD12HP120 FPM
|
||||
PRS3_5_VFD12HP120 FPM
|
||||
ERSCPRS3_6_ERSC1ERSCPRS3_6_ERSC2ERSCPRS3_6_ERSC3ERSCPRS3_6_ERSC4ERSCPRS3_6_ERSC5ERSCPRS3_6_ERSC6ERSCPRS3_6_ERSC7ERSCPRS3_6_ERSC8ERSCPRS3_6_ERSC9ERSCPRS3_6_ERSC10ERSCPRS3_6_ERSC11ERSCPRS3_6_ERSC12ERSCPRS3_6_ERSC13ERSCPRS3_6_ERSC14ERSCPRS3_6_ERSC15 MDR POWER SUPPLYPRS3_6_PSU140AMDR POWER SUPPLYPRS3_6_PSU240A
|
||||
PRS3_6_PE1PRS3_6_PE2PRS3_6_PE3PRS3_6_PE4PRS3_6_PE5PRS3_6_PE6PRS3_6_PE7PRS3_6_PE8PRS3_6_PE9PRS3_6_PE10PRS3_6_PE11PRS3_6_PE12PRS3_6_PE13PRS3_6_PE14PRS3_6_PE15PRS3_6_PE16PRS3_6_PE17PRS3_6_PE18PRS3_6_PE19PRS3_6_PE20PRS3_6_PE21PRS3_6_PE22PRS3_6_PE23PRS3_6_PE24PRS3_6_PE25PRS3_6_PE26PRS3_6_PE27PRS3_6_PE28PRS3_6_PE29PRS3_6_PE30
|
||||
PRS3_2B_JPE1 PRS3_2A_JPE1
|
||||
PRS3_1BCH_JPE1 PRS3_1ACH_JPE1
|
||||
PRS3_5_JPE1
|
||||
PRS3_3B_JPE1PRS3_3B_JPE2PRS3_3A_JPE2 PRS3_3A_JPE1
|
||||
PRS3_5_JPE2
|
||||
PRS4_1_JPE1PRS4_2_JPE1 EPCPRS3_5_EPC1
|
||||
EPCPRS3_5_EPC2
|
||||
EPCPRS4_1_EPC2
|
||||
EPCPRS4_1_EPC1
|
||||
EPCPRS4_2_EPC1
|
||||
EPCPRS4_2_EPC2
|
||||
GPRS4_2_S2ABBRGPRS4_1_S2GPRS4_1_S1
|
||||
GPRS4_2_S1
|
||||
GPRS3_5_S1GPRS3_5_S2
|
||||
BBR
|
||||
BBR
|
||||
ABBR BBR
|
||||
ABB ABB
|
||||
WPRS3_3B_JR1
|
||||
WPRS3_3A_JR1WPRS3_2B_JR1
|
||||
WPRS3_1BCH_JR1 WPRS3_1ACH_JR1
|
||||
WPRS3_2A_JR1
|
||||
ABB
|
||||
ABB
|
||||
ABB
|
||||
ABB
|
||||
BABB
|
||||
PRS3_4CH_FPE1
|
||||
PRS3_4CH_FPE2B B
|
||||
BB
|
||||
GBBAB
|
||||
GBBABGBBAB
|
||||
GBBABGBBAB
|
||||
GBBAB
|
||||
GPS11_11CH1_S1
|
||||
GPS11_11CH2_S1
|
||||
GPS11_11CH3_S1
|
||||
GPS11_11CH4_S1
|
||||
GPS11_11CH5_S1
|
||||
GPS11_11CH6_S1
|
||||
GPS10_5CH2_S1
|
||||
GPS10_5CH1_S1
|
||||
GPS10_5CH5_S1
|
||||
GPS10_5CH3_S1
|
||||
GBBAB
|
||||
GBBAB
|
||||
GBBAB
|
||||
GBBAB
|
||||
PS10_1_ENC1PS10_2_ENC1
|
||||
PS10_5_ENC1
|
||||
PS11_3_ENC1
|
||||
PS11_6_ENC1 PS11_7_ENC1 PS11_8_ENC1 PS11_9_ENC1
|
||||
PS11_11_ENC1
|
||||
EPCPS11_7_EPC2
|
||||
EPCPS11_7_EPC1
|
||||
BBR
|
||||
BBR
|
||||
G
|
||||
PS11_7_S2
|
||||
GPS11_7_S1
|
||||
ULC8_3_ENC1ULC7_3_ENC1ULC6_3_ENC1ULC5_3_ENC1
|
||||
PRS4_2_ENC1
|
||||
PRS4_1_ENC1
|
||||
PS10_5_PS1PS
|
||||
PS11_11_PS1PS
|
||||
PS10_5CH3_JPE1PS10_5CH3_FPE1PS10_5CH3_FPE2
|
||||
PS11_11CH2_FPE1PS11_11CH2_FPE2
|
||||
EPCPS11_8_EPC1BBR
|
||||
G
|
||||
PRS4_2_JPE2PS11_3_JPE1
|
||||
EPCPS11_4_EPC2
|
||||
EPCPS11_4_EPC1EPCPS11_3_EPC1
|
||||
EPCPS11_3_EPC2
|
||||
ABBR
|
||||
BBR
|
||||
BBR
|
||||
GPS11_3_S1ABBR
|
||||
GPS11_3_S2
|
||||
PS11_2_ENC1PS10_3_VFD115HP240FPMPS10_3_ENC1 PS11_1_ENC1
|
||||
PS11_4_ENC1
|
||||
PS11_11_JPE6WPS11_11_JR3ABB
|
||||
PRS4_1_VFD17.5HP120FPM
|
||||
PRS4_2_VFD15HP120FPM
|
||||
RGULC5_3_SS1RGULC5_3_SS2
|
||||
PS11_1_FIO2
|
||||
RGULC6_3_SS2
|
||||
PS10_1_FIO1
|
||||
RGPS10_1_SS1
|
||||
PS10_2_TPE
|
||||
PS10_5_FIO2
|
||||
PS10_5_FIO4PS10_5_FIO5
|
||||
WPS11_1_JR1
|
||||
PS11_3_FIO1
|
||||
GPS11_4_S2
|
||||
GPS11_4_S1
|
||||
PS11_4_FIO1
|
||||
PS11_7_FIO1
|
||||
PS11_11_FIO2
|
||||
PS11_11_FIO3
|
||||
PS11_11_FIO4
|
||||
PS11_11_FIO5
|
||||
PS11_11_FIO6
|
||||
PRS3_2B_FIO1 PRS3_2A_FIOM1
|
||||
PRS3_4CH_FIO1
|
||||
PRS4_2_FIO1
|
||||
WPRS4_2_JR1
|
||||
RGULC7_3_SS1
|
||||
RGULC7_3_SS2RGULC8_3_SS1
|
||||
PS10_5_TPE1
|
||||
PS11_6_TPE1
|
||||
PS11_6_TPE2
|
||||
PS11_7_TPE1
|
||||
PS11_8_TPE1 PS11_11_TPE1
|
||||
PS11_11CH3_JPE1PS11_11CH3_FPE1PS11_11CH3_FPE2PS11_11CH4_JPE1PS11_11CH4_FPE1PS11_11CH4_FPE2
|
||||
PS11_11CH5_JPE1PS11_11CH5_FPE1PS11_11CH5_FPE2PS11_11CH6_JPE1PS11_11CH6_FPE1PS11_11CH6_FPE2
|
||||
GDTC_NCH1_EN1
|
||||
CH_DPM1_FIOM1
|
||||
GDTC_NCH2_EN1
|
||||
GDTC_NCH3_EN1
|
||||
GDTC_NCH4_EN1CH_DPM1MCM04
|
||||
GDTC_NCH5_EN1
|
||||
CH_DPM1_FIOM2
|
||||
GDTC_NCH6_EN1
|
||||
GDTC_NCH7_EN1
|
||||
GDTC_NCH8_EN1
|
||||
GDTC_NCH9_EN1
|
||||
CH_DPM1_FIOM3
|
||||
GDTC_NCH10_EN1
|
||||
GDTC_NCH11_EN1
|
||||
GDTC_NCH12_EN1
|
||||
GDTC_NCH13_EN1
|
||||
CH_DPM1_FIOM4
|
||||
GDTC_NCH14_EN1
|
||||
GDTC_NCH15_EN1
|
||||
GDTC_NCH16_EN1
|
||||
CH_DPM1_FIOM5
|
||||
GDTC_NCH17_EN1
|
||||
FL1034_2_PE1ABBBFL1034_1CH_PE1
|
||||
FL1034_2_PE2
|
||||
FL1034_2_VFD15HP350FPM
|
||||
FL1034_3CH_PE1BBBWFL1034_2_JR2WFL1034_2_JR1
|
||||
WFL1034_1_JR1FL1026_2_PE1ABBB
|
||||
FL1026_1CH_PE1
|
||||
FL1026_2_PE2FL1026_3CH_PE1BBBWFL1026_2_JR2WFL1026_2_JR1
|
||||
WFL1026_1_JR1FL1022_2_PE1
|
||||
ABBB
|
||||
FL1022_1CH_PE1
|
||||
FL1022_2_PE2FL1022_3CH_PE1BBBWFL1022_2_JR2WFL1022_2_JR1
|
||||
WFL1022_1_JR1FL1018_2_PE1ABBB
|
||||
FL1018_1CH_PE1
|
||||
FL1018_2_PE2FL1018_3CH_PE1BBBWFL1018_2_JR2WFL1018_2_JR1
|
||||
WFL1018_1_JR1
|
||||
FL1014_2_PE1ABBB
|
||||
FL1014_1CH_PE1
|
||||
FL1014_2_PE2FL1014_3CH_PE1BBBWFL1014_2_JR2WFL1014_2_JR1
|
||||
WFL1014_1_JR1 FL3012_2_PE1
|
||||
ABBB
|
||||
FL3012_1CH_PE1
|
||||
FL3012_2_PE2FL3012_3CH_PE1BBBWFL3012_2_JR2WFL3012_2_JR1
|
||||
WFL3012_1_JR1FL3016_2_PE1
|
||||
ABBB
|
||||
FL3016_1CH_PE1
|
||||
FL3016_2_PE2FL3016_3CH_PE1BBBWFL3016_2_JR2WFL3016_2_JR1
|
||||
WFL3016_1_JR1FL3020_2_PE1
|
||||
ABBB
|
||||
FL3020_1CH_PE1
|
||||
FL3020_2_PE2FL3020_3CH_PE1BBBWFL3020_2_JR2WFL3020_2_JR1
|
||||
WFL3020_1_JR1FL3024_2_PE1
|
||||
ABBB
|
||||
FL3024_1CH_PE1
|
||||
FL3024_2_PE2FL3024_3CH_PE1BBBWFL3024_2_JR2WFL3024_2_JR1
|
||||
WFL3024_1_JR1
|
||||
FL1026_2_VFD15HP350FPMFL1022_2_VFD15HP350FPMFL1018_2_VFD15HP350FPMFL1014_2_VFD15HP350FPM FL3012_2_VFD15HP350FPMFL3016_2_VFD15HP350FPMFL3020_2_VFD15HP350FPMFL3024_2_VFD15HP350FPM
|
||||
CH_DPM2_FIOM2CH_DPM2_FIOM1
|
||||
CH_DPM2_FIOM4CH_DPM2_FIOM3CH_DPM2_FIOM6CH_DPM2_FIOM5
|
||||
BBGABBBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGB BBGBBBGAB BBGAB BBGAB BBGAB
|
||||
BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB
|
||||
CH_DPM3MCM04 CH_DPM4MCM04 CH_DPM5MCM04 CH_DPM6MCM04
|
||||
PB_NCH1_FIOH1PB_NCH3_FIOH1PB_NCH5_FIOH1PB_NCH7_FIOH1PB_NCH9_FIOH1PB_NCH10_FIOH1PB_NCH11_FIOH1PB_NCH12_FIOH1PB_NCH13_FIOH1PB_NCH14_FIOH1PB_NCH15_FIOH1PB_NCH16_FIOH1PB_NCH18_FIOH1PB_NCH20_FIOH1
|
||||
CH_DPM3_FIOM2CH_DPM3_FIOM1CH_DPM3_FIOM4CH_DPM3_FIOM3CH_DPM3_FIOM6CH_DPM3_FIOM5CH_DPM3_FIOM8CH_DPM3_FIOM7
|
||||
PB_NCH21_FIOH1PB_NCH24_FIOH1PB_NCH25_FIOH1PB_NCH26_FIOH1PB_NCH27_FIOH1PB_NCH28_FIOH1PB_NCH29_FIOH1PB_NCH31_FIOH1PB_NCH33_FIOH1PB_NCH35_FIOH1PB_NCH37_FIOH1PB_NCH39_FIOH1PB_NCH41_FIOH1PB_NCH43_FIOH1PB_NCH45_FIOH1PB_NCH46_FIOH1PB_NCH48_FIOH1PB_NCH50_FIOH1PB_NCH52_FIOH1PB_NCH54_FIOH1PB_NCH56_FIOH1PB_NCH58_FIOH1PB_NCH60_FIOH1
|
||||
CH_DPM4_FIOM1CH_DPM4_FIOM3CH_DPM4_FIOM2CH_DPM4_FIOM5CH_DPM4_FIOM4CH_DPM4_FIOM7CH_DPM4_FIOM6CH_DPM5_FIOM2CH_DPM5_FIOM1CH_DPM5_FIOM4CH_DPM5_FIOM3CH_DPM5_FIOM6CH_DPM5_FIOM5CH_DPM5_FIOM8CH_DPM5_FIOM7CH_DPM6_FIOM2CH_DPM6_FIOM1CH_DPM6_FIOM4CH_DPM6_FIOM3CH_DPM6_FIOM6CH_DPM6_FIOM5CH_DPM6_FIOM8CH_DPM6_FIOM7
|
||||
BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGABBBGBBBGBBBGB BBGBBBGBBBGB BBGB BBGB BBGB BBGB BBGB BBGBBBGBBBGB BBGB BBGBBBGB BBGB BBGB BBGB BBGB BBGB BBGB BBGBBBGB BBGBBBGBBBGB BBGBBBGB BBGB BBGBBBGB BBGBBBGB BBGBBBGBBBGB BBGBBBGB BBGB
|
||||
GDTC_NCH18_EN1
|
||||
GDTC_NCH19_EN1
|
||||
GDTC_NCH20_EN1
|
||||
GDTC_NCH21_EN1
|
||||
GDTC_NCH22_EN1
|
||||
GDTC_NCH23_EN1
|
||||
GDTC_NCH24_EN1
|
||||
GDTC_NCH25_EN1
|
||||
GDTC_NCH26_EN1
|
||||
GDTC_NCH27_EN1
|
||||
GDTC_NCH28_EN1
|
||||
GDTC_NCH29_EN1
|
||||
GDTC_NCH30_EN1
|
||||
GDTC_NCH31_EN1
|
||||
GDTC_NCH32_EN1
|
||||
GDTC_NCH33_EN1
|
||||
GDTC_NCH34_EN1
|
||||
GDTC_NCH35_EN1
|
||||
GDTC_NCH36_EN1
|
||||
GDTC_NCH37_EN1
|
||||
GDTC_NCH38_EN1
|
||||
GDTC_NCH39_EN1
|
||||
GDTC_CH40_EN1
|
||||
GDTC_CH41_EN1
|
||||
GDTC_CH42_EN1
|
||||
GDTC_CH43_EN1
|
||||
GDTC_CH44_EN1
|
||||
GDTC_CH45_EN1
|
||||
GDTC_CH46_EN1
|
||||
GDTC_CH47_EN1
|
||||
GDTC_CH48_EN1
|
||||
GDTC_CH49_EN1
|
||||
GDTC_CH50_EN1
|
||||
GDTC_NCH51_EN1
|
||||
GDTC_NCH52_EN1
|
||||
GDTC_NCH53_EN1
|
||||
GDTC_NCH54_EN1
|
||||
GDTC_NCH55_EN1
|
||||
GDTC_NCH56_EN1
|
||||
GDTC_NCH57_EN1
|
||||
GDTC_NCH58_EN1
|
||||
GDTC_NCH59_EN1
|
||||
GDTC_NCH60_EN1
|
||||
GDTC_NCH61_EN1
|
||||
GDTC_NCH62_EN1
|
||||
GDTC_NCH63_EN1
|
||||
GDTC_NCH64_EN1
|
||||
GDTC_NCH65_EN1
|
||||
GDTC_NCH66_EN1
|
||||
GDTC_NCH67_EN1
|
||||
GDTC_NCH68_EN1
|
||||
GDTC_NCH69_EN1
|
||||
GDTC_NCH70_EN1
|
||||
GDTC_NCH71_EN1
|
||||
GDTC_NCH72_EN1
|
||||
GDTC_NCH73_EN1
|
||||
GDTC_NCH74_EN1
|
||||
GDTC_NCH75_EN1
|
||||
GDTC_NCH76_EN1
|
||||
PB_NCH1_PE1
|
||||
PB_NCH1_PE2
|
||||
BBGABBBGB
|
||||
WPB_NCH1_PKGREL_PB1SOLPB_NCH1_PKGREL_SOL1
|
||||
PB_NCH2_PE1
|
||||
PB_NCH2_PE2
|
||||
WPB_NCH2_PKGREL_PB1SOLPB_NCH2_PKGREL_SOL1
|
||||
PB_NCH3_PE1
|
||||
PB_NCH3_PE2
|
||||
WPB_NCH3_PKGREL_PB1SOLPB_NCH3_PKGREL_SOL1
|
||||
PB_NCH4_PE1
|
||||
PB_NCH4_PE2
|
||||
WPB_NCH4_PKGREL_PB1SOLPB_NCH4_PKGREL_SOL1
|
||||
PB_NCH5_PE1
|
||||
PB_NCH5_PE2
|
||||
WPB_NCH5_PKGREL_PB1SOLPB_NCH5_PKGREL_SOL1
|
||||
PB_NCH6_PE1
|
||||
PB_NCH6_PE2
|
||||
WPB_NCH6_PKGREL_PB1SOLPB_NCH6_PKGREL_SOL1
|
||||
PB_NCH7_PE1
|
||||
PB_NCH7_PE2
|
||||
WPB_NCH7_PKGREL_PB1SOLPB_NCH7_PKGREL_SOL1
|
||||
PB_NCH8_PE1
|
||||
PB_NCH8_PE2
|
||||
WPB_NCH8_PKGREL_PB1SOLPB_NCH8_PKGREL_SOL1
|
||||
PB_NCH9_PE1
|
||||
PB_NCH9_PE2
|
||||
WPB_NCH9_PKGREL_PB1SOLPB_NCH9_PKGREL_SOL1
|
||||
PB_NCH10_PE1
|
||||
PB_NCH10_PE2
|
||||
WPB_NCH10_PKGREL_PB1SOLPB_NCH10_PKGREL_SOL1
|
||||
PB_NCH11_PE1
|
||||
PB_NCH11_PE2
|
||||
WPB_NCH11_PKGREL_PB1SOLPB_NCH11_PKGREL_SOL1
|
||||
PB_NCH12_PE1
|
||||
PB_NCH12_PE2
|
||||
WPB_NCH12_PKGREL_PB1SOLPB_NCH12_PKGREL_SOL1
|
||||
PB_NCH13_PE1
|
||||
PB_NCH13_PE2
|
||||
WPB_NCH13_PKGREL_PB1SOLPB_NCH13_PKGREL_SOL1
|
||||
PB_NCH14_PE1
|
||||
PB_NCH14_PE2
|
||||
WPB_NCH14_PKGREL_PB1SOLPB_NCH14_PKGREL_SOL1
|
||||
PB_NCH15_PE1
|
||||
PB_NCH15_PE2
|
||||
WPB_NCH15_PKGREL_PB1SOLPB_NCH15_PKGREL_SOL1
|
||||
PB_NCH16_PE1
|
||||
PB_NCH16_PE2
|
||||
WPB_NCH16_PKGREL_PB1SOLPB_NCH16_PKGREL_SOL1
|
||||
PB_NCH17_PE1
|
||||
PB_NCH17_PE2
|
||||
WPB_NCH17_PKGREL_PB1SOLPB_NCH17_PKGREL_SOL1
|
||||
PB_NCH18_PE1
|
||||
PB_NCH18_PE2
|
||||
WPB_NCH18_PKGREL_PB1SOLPB_NCH18_PKGREL_SOL1
|
||||
PB_NCH19_PE1
|
||||
PB_NCH19_PE2
|
||||
WPB_NCH19_PKGREL_PB1SOLPB_NCH19_PKGREL_SOL1
|
||||
PB_NCH20_PE1
|
||||
PB_NCH20_PE2
|
||||
WPB_NCH20_PKGREL_PB1SOLPB_NCH20_PKGREL_SOL1
|
||||
PB_NCH21_PE1
|
||||
PB_NCH21_PE2
|
||||
WPB_NCH21_PKGREL_PB1SOLPB_NCH21_PKGREL_SOL1
|
||||
PB_NCH22_PE1
|
||||
PB_NCH22_PE2
|
||||
WPB_NCH22_PKGREL_PB1SOLPB_NCH22_PKGREL_SOL1
|
||||
PB_NCH23_PE1
|
||||
PB_NCH23_PE2
|
||||
WPB_NCH23_PKGREL_PB1SOLPB_NCH23_PKGREL_SOL1
|
||||
PB_NCH24_PE1
|
||||
PB_NCH24_PE2
|
||||
WPB_NCH24_PKGREL_PB1SOLPB_NCH24_PKGREL_SOL1
|
||||
PB_NCH25_PE1
|
||||
PB_NCH25_PE2
|
||||
WPB_NCH25_PKGREL_PB1SOLPB_NCH25_PKGREL_SOL1
|
||||
PB_NCH26_PE1
|
||||
PB_NCH26_PE2
|
||||
WPB_NCH26_PKGREL_PB1SOLPB_NCH26_PKGREL_SOL1
|
||||
PB_NCH27_PE1
|
||||
PB_NCH27_PE2
|
||||
WPB_NCH27_PKGREL_PB1SOLPB_NCH27_PKGREL_SOL1
|
||||
PB_NCH28_PE1
|
||||
PB_NCH28_PE2
|
||||
WPB_NCH28_PKGREL_PB1SOLPB_NCH28_PKGREL_SOL1
|
||||
PB_NCH29_PE1
|
||||
PB_NCH29_PE2
|
||||
WPB_NCH29_PKGREL_PB1SOLPB_NCH29_PKGREL_SOL1
|
||||
PB_NCH30_PE1
|
||||
PB_NCH30_PE2
|
||||
WPB_NCH30_PKGREL_PB1SOLPB_NCH30_PKGREL_SOL1
|
||||
PB_NCH31_PE1
|
||||
PB_NCH31_PE2
|
||||
WPB_NCH31_PKGREL_PB1SOLPB_NCH31_PKGREL_SOL1
|
||||
PB_NCH32_PE1
|
||||
PB_NCH32_PE2
|
||||
WPB_NCH32_PKGREL_PB1SOLPB_NCH32_PKGREL_SOL1
|
||||
PB_NCH33_PE1
|
||||
PB_NCH33_PE2
|
||||
WPB_NCH33_PKGREL_PB1SOLPB_NCH33_PKGREL_SOL1
|
||||
PB_NCH34_PE1
|
||||
PB_NCH34_PE2
|
||||
WPB_NCH34_PKGREL_PB1SOLPB_NCH34_PKGREL_SOL1
|
||||
PB_NCH35_PE1
|
||||
PB_NCH35_PE2
|
||||
WPB_NCH35_PKGREL_PB1SOLPB_NCH35_PKGREL_SOL1
|
||||
PB_NCH36_PE1
|
||||
PB_NCH36_PE2
|
||||
WPB_NCH36_PKGREL_PB1SOLPB_NCH36_PKGREL_SOL1
|
||||
PB_NCH37_PE1
|
||||
PB_NCH37_PE2
|
||||
WPB_NCH37_PKGREL_PB1SOLPB_NCH37_PKGREL_SOL1
|
||||
PB_NCH38_PE1
|
||||
PB_NCH38_PE2
|
||||
WPB_NCH38_PKGREL_PB1SOLPB_NCH38_PKGREL_SOL1
|
||||
PB_NCH39_PE1
|
||||
PB_NCH39_PE2
|
||||
WPB_NCH39_PKGREL_PB1SOLPB_NCH39_PKGREL_SOL1
|
||||
PB_NCH40_PE1
|
||||
PB_NCH40_PE2
|
||||
WPB_NCH40_PKGREL_PB1SOLPB_NCH40_PKGREL_SOL1
|
||||
PB_NCH41_PE1
|
||||
PB_NCH41_PE2
|
||||
WPB_NCH41_PKGREL_PB1SOLPB_NCH41_PKGREL_SOL1
|
||||
PB_NCH42_PE1
|
||||
PB_NCH42_PE2
|
||||
WPB_NCH42_PKGREL_PB1SOLPB_NCH42_PKGREL_SOL1
|
||||
PB_NCH43_PE1
|
||||
PB_NCH43_PE2
|
||||
WPB_NCH43_PKGREL_PB1SOLPB_NCH43_PKGREL_SOL1
|
||||
PB_NCH44_PE1
|
||||
PB_NCH44_PE2
|
||||
WPB_NCH44_PKGREL_PB1SOLPB_NCH44_PKGREL_SOL1
|
||||
PB_NCH45_PE1
|
||||
PB_NCH45_PE2
|
||||
WPB_NCH45_PKGREL_PB1SOLPB_NCH45_PKGREL_SOL1
|
||||
PB_NCH46_PE1
|
||||
PB_NCH46_PE2
|
||||
WPB_NCH46_PKGREL_PB1SOLPB_NCH46_PKGREL_SOL1
|
||||
PB_NCH47_PE1
|
||||
PB_NCH47_PE2
|
||||
WPB_NCH47_PKGREL_PB1SOLPB_NCH47_PKGREL_SOL1
|
||||
PB_NCH48_PE1
|
||||
PB_NCH48_PE2
|
||||
WPB_NCH48_PKGREL_PB1SOLPB_NCH48_PKGREL_SOL1
|
||||
PB_NCH49_PE1
|
||||
PB_NCH49_PE2
|
||||
WPB_NCH49_PKGREL_PB1SOLPB_NCH49_PKGREL_SOL1
|
||||
PB_NCH50_PE1
|
||||
PB_NCH50_PE2
|
||||
WPB_NCH50_PKGREL_PB1SOLPB_NCH50_PKGREL_SOL1
|
||||
PB_NCH51_PE1
|
||||
PB_NCH51_PE2
|
||||
WPB_NCH51_PKGREL_PB1SOLPB_NCH51_PKGREL_SOL1
|
||||
PB_NCH52_PE1
|
||||
PB_NCH52_PE2
|
||||
WPB_NCH52_PKGREL_PB1SOLPB_NCH52_PKGREL_SOL1
|
||||
PB_NCH53_PE1
|
||||
PB_NCH53_PE2
|
||||
WPB_NCH53_PKGREL_PB1SOLPB_NCH53_PKGREL_SOL1
|
||||
PB_NCH54_PE1
|
||||
PB_NCH54_PE2
|
||||
WPB_NCH54_PKGREL_PB1SOLPB_NCH54_PKGREL_SOL1
|
||||
PB_NCH55_PE1
|
||||
PB_NCH55_PE2
|
||||
WPB_NCH55_PKGREL_PB1SOLPB_NCH55_PKGREL_SOL1
|
||||
PB_NCH56_PE1
|
||||
PB_NCH56_PE2
|
||||
WPB_NCH56_PKGREL_PB1SOLPB_NCH56_PKGREL_SOL1
|
||||
PB_NCH57_PE1
|
||||
PB_NCH57_PE2
|
||||
WPB_NCH57_PKGREL_PB1SOLPB_NCH57_PKGREL_SOL1
|
||||
PB_NCH58_PE1
|
||||
PB_NCH58_PE2
|
||||
WPB_NCH58_PKGREL_PB1SOLPB_NCH58_PKGREL_SOL1
|
||||
PB_NCH59_PE1
|
||||
PB_NCH59_PE2
|
||||
WPB_NCH59_PKGREL_PB1SOLPB_NCH59_PKGREL_SOL1
|
||||
PB_NCH60_PE1
|
||||
PB_NCH60_PE2
|
||||
WPB_NCH60_PKGREL_PB1SOLPB_NCH60_PKGREL_SOL1
|
||||
PB_NCH61_PE1
|
||||
PB_NCH61_PE2
|
||||
WPB_NCH61_PKGREL_PB1SOLPB_NCH61_PKGREL_SOL1
|
||||
BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGABBBGBBBGB BBGBBBGBBBGB BBGB BBGB BBGB BBGBBBGB BBGBBBGB BBGBBBGBBBGB BBGB BBGB BBGB BBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGB BBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGBBBGB
|
||||
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM01.pdf
Normal file
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM01.pdf
Normal file
Binary file not shown.
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM02.pdf
Normal file
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM02.pdf
Normal file
Binary file not shown.
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM03.pdf
Normal file
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM03.pdf
Normal file
Binary file not shown.
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM04.pdf
Normal file
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM04.pdf
Normal file
Binary file not shown.
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM05.pdf
Normal file
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM05.pdf
Normal file
Binary file not shown.
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM06.pdf
Normal file
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM06.pdf
Normal file
Binary file not shown.
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM07.pdf
Normal file
BIN
projects/MTN6/pdfs/MTN6_SYSDL-MCM07.pdf
Normal file
Binary file not shown.
1
projects/MTN6/repo
Submodule
1
projects/MTN6/repo
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 456de12cca56c09bc1881660b163ac3b5dff593a
|
||||
1738
projects/MTN6_Test/MTN6_Equipment_Manifest_REV6Conveyor_List.csv
Normal file
1738
projects/MTN6_Test/MTN6_Equipment_Manifest_REV6Conveyor_List.csv
Normal file
File diff suppressed because it is too large
Load Diff
587
projects/MTN6_Test/extracted_texts/MTN6_SYSDL-MCM04.txt
Normal file
587
projects/MTN6_Test/extracted_texts/MTN6_SYSDL-MCM04.txt
Normal file
@ -0,0 +1,587 @@
|
||||
2'-1.5" EL
|
||||
2'-3" EL
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
TRASH
|
||||
PALLETSTAGINGAREA
|
||||
PROBLEM SOLV.CART 80/20
|
||||
PROB. SOLV. CART
|
||||
TRASH
|
||||
ERSCERSCERSCERSCERSCERSCERSCERSCERSCERSCERSCERSCERSCERSCERSC MDR POWER SUPPLY80AMDR POWER SUPPLY80A
|
||||
V
|
||||
11'-2" EL
|
||||
1'-4" EL
|
||||
FL_DPM1MCM04
|
||||
FL_DPM2MCM04
|
||||
ULGLB_DPM1MCM04
|
||||
ULGLC_DPM1MCM04
|
||||
MCM04
|
||||
PRS1_DPM1MCM04
|
||||
CH_DPM2MCM04
|
||||
FL1038_2_PE1ABBB
|
||||
FL1038_1CH_PE1
|
||||
FL1038_2_PE2
|
||||
FL1038_2_VFD15HP350FPM
|
||||
FL1038_3CH_PE1BBBWFL1038_2_JR2WFL1038_2_JR1
|
||||
WFL1038_1_JR1
|
||||
ULC8_3_VFD12HP80FPMULC7_3_VFD12HP80FPMULC6_3_VFD12HP80FPMULC5_3_VFD12HP80FPM
|
||||
PS10_1_VFD15HP150FPMPS10_2_VFD115HP200FPM
|
||||
PS10_5_VFD115HP240FPM
|
||||
PS11_1_VFD15HP150FPMPS11_2_VFD15HP200FPMPS11_3_VFD110HP240FPM
|
||||
PS11_4_VFD110HP240FPM
|
||||
PS11_6_VFD110HP240FPM PS11_7_VFD120HP240FPM PS11_8_VFD115HP240FPM PS11_9_VFD115HP240FPM
|
||||
PS11_11_VFD115HP240FPMULC8_3_JPE2ULC7_3_JPE2ULC6_3_JPE2ULC5_3_JPE2
|
||||
PS10_1_JPE2
|
||||
PS10_1_JPE1PS10_1_JPE3PS11_1_JPE1
|
||||
PS11_1_JPE2
|
||||
PS11_1_JPE3PS10_3_JPE1 PS11_2_JPE1
|
||||
PS10_5CH2_FPE1PS10_5CH2_JPE1
|
||||
PS10_5CH5_FPE2
|
||||
PS10_6CH_FPE1
|
||||
PS10_5_JPE4
|
||||
PS10_5_JPE5
|
||||
PS10_5_JPE3
|
||||
PS10_5_JPE2
|
||||
PS10_5_JPE1
|
||||
PS11_3_JPE2
|
||||
PS11_4_JPE1
|
||||
PS11_11_JPE1
|
||||
PS11_11_JPE2
|
||||
PS11_11_JPE3
|
||||
PS11_11_JPE4
|
||||
PS11_11_JPE5
|
||||
PS11_11CH1_JPE1
|
||||
EPCULC5_3_EPC1
|
||||
EPCULC5_3_EPC2
|
||||
EPCULC6_3_EPC1
|
||||
EPCULC7_3_EPC1
|
||||
EPCULC7_3_EPC2
|
||||
EPCULC8_3_EPC1
|
||||
EPCPS10_1_EPC1EPCPS11_1_EPC1
|
||||
EPCPS10_5_EPC1
|
||||
EPCPS11_11_EPC1
|
||||
WPS10_1_JR1
|
||||
WULC8_3_JR1
|
||||
WULC7_3_JR1
|
||||
WULC6_3_JR1
|
||||
WULC5_3_JR1W
|
||||
PS11_1_JR2
|
||||
PS11_9_JPE1
|
||||
WPS11_11_JR1
|
||||
WPS11_11_JR2
|
||||
WPS10_5_JR1
|
||||
WPS10_5_JR2ABB
|
||||
ABB
|
||||
ABBR
|
||||
GPS10_3_JR1
|
||||
GPS11_11_S1
|
||||
RABB RABB RABB RABB
|
||||
ABBABBR ABBR
|
||||
ABBR
|
||||
ABB
|
||||
ABB
|
||||
PS11_1_FIO1PS10_1_FIO2
|
||||
PS10_5_FIO1
|
||||
PS10_5_FIO3
|
||||
PS11_11_FIO1
|
||||
PS10_5DIV1_LS1LSPS10_5DIV1_LS2LS
|
||||
PS10_5DIV2_LS1LSPS10_5DIV2_LS2LS
|
||||
PS10_5DIV3_LS1LSPS10_5DIV3_LS2LS
|
||||
PS10_5DIV5_LS1LSPS10_5DIV5_LS2LS
|
||||
PS11_11DIV1_LS1LSPS11_11DIV1_LS2LS
|
||||
PS11_11DIV2_LS1LSPS11_11DIV2_LS2LS
|
||||
PS11_11DIV3_LS1LSPS11_11DIV3_LS2LS
|
||||
PS11_11DIV4_LS1LSPS11_11DIV4_LS2LS
|
||||
PS11_11DIV5_LS1LSPS11_11DIV5_LS2LS
|
||||
PS11_11DIV6_LS1LSPS11_11DIV6_LS2LS
|
||||
SOLPS10_5DIV5_SOL1SOLPS10_5DIV5_SOL2
|
||||
SOLPS10_5DIV3_SOL1SOLPS10_5DIV3_SOL2
|
||||
SOLPS10_5DIV2_SOL1SOLPS10_5DIV2_SOL2SOLPS10_5DIV1_SOL1SOLPS10_5DIV1_SOL2
|
||||
SOLPS11_11DIV1_SOL1SOLPS11_11DIV1_SOL2
|
||||
SOLPS11_11DIV2_SOL1SOLPS11_11DIV2_SOL2
|
||||
SOLPS11_11DIV3_SOL1SOLPS11_11DIV3_SOL2
|
||||
SOLPS11_11DIV4_SOL1SOLPS11_11DIV4_SOL2
|
||||
SOLPS11_11DIV5_SOL1SOLPS11_11DIV5_SOL2
|
||||
SOLPS11_11DIV6_SOL1SOLPS11_11DIV6_SOL2
|
||||
PS10_5CH2_FPE2PS10_5CH1_JPE1PS10_5CH1_FPE1PS10_5CH1_FPE2
|
||||
PS10_5CH5_FPE1PS10_5CH5_JPE1
|
||||
PS10_1_JPE4
|
||||
PS11_11CH1_FPE1PS11_11CH1_FPE2PS11_11CH2_JPE1
|
||||
PS11_12CH_FPE1ULC8_3_JPE1ULC7_3_JPE1ULC6_3_JPE1
|
||||
ULC5_3_JPE1
|
||||
PS11_1_JPE4
|
||||
PRS3_2B_VFD12HP120 FPMPRS3_3B_VFD13HP120 FPM
|
||||
PRS3_2A_VFD12HP120 FPMPRS3_3A_VFD12HP120 FPM
|
||||
PRS3_5_VFD12HP120 FPM
|
||||
ERSCPRS3_6_ERSC1ERSCPRS3_6_ERSC2ERSCPRS3_6_ERSC3ERSCPRS3_6_ERSC4ERSCPRS3_6_ERSC5ERSCPRS3_6_ERSC6ERSCPRS3_6_ERSC7ERSCPRS3_6_ERSC8ERSCPRS3_6_ERSC9ERSCPRS3_6_ERSC10ERSCPRS3_6_ERSC11ERSCPRS3_6_ERSC12ERSCPRS3_6_ERSC13ERSCPRS3_6_ERSC14ERSCPRS3_6_ERSC15 MDR POWER SUPPLYPRS3_6_PSU140AMDR POWER SUPPLYPRS3_6_PSU240A
|
||||
PRS3_6_PE1PRS3_6_PE2PRS3_6_PE3PRS3_6_PE4PRS3_6_PE5PRS3_6_PE6PRS3_6_PE7PRS3_6_PE8PRS3_6_PE9PRS3_6_PE10PRS3_6_PE11PRS3_6_PE12PRS3_6_PE13PRS3_6_PE14PRS3_6_PE15PRS3_6_PE16PRS3_6_PE17PRS3_6_PE18PRS3_6_PE19PRS3_6_PE20PRS3_6_PE21PRS3_6_PE22PRS3_6_PE23PRS3_6_PE24PRS3_6_PE25PRS3_6_PE26PRS3_6_PE27PRS3_6_PE28PRS3_6_PE29PRS3_6_PE30
|
||||
PRS3_2B_JPE1 PRS3_2A_JPE1
|
||||
PRS3_1BCH_JPE1 PRS3_1ACH_JPE1
|
||||
PRS3_5_JPE1
|
||||
PRS3_3B_JPE1PRS3_3B_JPE2PRS3_3A_JPE2 PRS3_3A_JPE1
|
||||
PRS3_5_JPE2
|
||||
PRS4_1_JPE1PRS4_2_JPE1 EPCPRS3_5_EPC1
|
||||
EPCPRS3_5_EPC2
|
||||
EPCPRS4_1_EPC2
|
||||
EPCPRS4_1_EPC1
|
||||
EPCPRS4_2_EPC1
|
||||
EPCPRS4_2_EPC2
|
||||
GPRS4_2_S2ABBRGPRS4_1_S2GPRS4_1_S1
|
||||
GPRS4_2_S1
|
||||
GPRS3_5_S1GPRS3_5_S2
|
||||
BBR
|
||||
BBR
|
||||
ABBR BBR
|
||||
ABB ABB
|
||||
WPRS3_3B_JR1
|
||||
WPRS3_3A_JR1WPRS3_2B_JR1
|
||||
WPRS3_1BCH_JR1 WPRS3_1ACH_JR1
|
||||
WPRS3_2A_JR1
|
||||
ABB
|
||||
ABB
|
||||
ABB
|
||||
ABB
|
||||
BABB
|
||||
PRS3_4CH_FPE1
|
||||
PRS3_4CH_FPE2B B
|
||||
BB
|
||||
GBBAB
|
||||
GBBABGBBAB
|
||||
GBBABGBBAB
|
||||
GBBAB
|
||||
GPS11_11CH1_S1
|
||||
GPS11_11CH2_S1
|
||||
GPS11_11CH3_S1
|
||||
GPS11_11CH4_S1
|
||||
GPS11_11CH5_S1
|
||||
GPS11_11CH6_S1
|
||||
GPS10_5CH2_S1
|
||||
GPS10_5CH1_S1
|
||||
GPS10_5CH5_S1
|
||||
GPS10_5CH3_S1
|
||||
GBBAB
|
||||
GBBAB
|
||||
GBBAB
|
||||
GBBAB
|
||||
PS10_1_ENC1PS10_2_ENC1
|
||||
PS10_5_ENC1
|
||||
PS11_3_ENC1
|
||||
PS11_6_ENC1 PS11_7_ENC1 PS11_8_ENC1 PS11_9_ENC1
|
||||
PS11_11_ENC1
|
||||
EPCPS11_7_EPC2
|
||||
EPCPS11_7_EPC1
|
||||
BBR
|
||||
BBR
|
||||
G
|
||||
PS11_7_S2
|
||||
GPS11_7_S1
|
||||
ULC8_3_ENC1ULC7_3_ENC1ULC6_3_ENC1ULC5_3_ENC1
|
||||
PRS4_2_ENC1
|
||||
PRS4_1_ENC1
|
||||
PS10_5_PS1PS
|
||||
PS11_11_PS1PS
|
||||
PS10_5CH3_JPE1PS10_5CH3_FPE1PS10_5CH3_FPE2
|
||||
PS11_11CH2_FPE1PS11_11CH2_FPE2
|
||||
EPCPS11_8_EPC1BBR
|
||||
G
|
||||
PRS4_2_JPE2PS11_3_JPE1
|
||||
EPCPS11_4_EPC2
|
||||
EPCPS11_4_EPC1EPCPS11_3_EPC1
|
||||
EPCPS11_3_EPC2
|
||||
ABBR
|
||||
BBR
|
||||
BBR
|
||||
GPS11_3_S1ABBR
|
||||
GPS11_3_S2
|
||||
PS11_2_ENC1PS10_3_VFD115HP240FPMPS10_3_ENC1 PS11_1_ENC1
|
||||
PS11_4_ENC1
|
||||
PS11_11_JPE6WPS11_11_JR3ABB
|
||||
PRS4_1_VFD17.5HP120FPM
|
||||
PRS4_2_VFD15HP120FPM
|
||||
RGULC5_3_SS1RGULC5_3_SS2
|
||||
PS11_1_FIO2
|
||||
RGULC6_3_SS2
|
||||
PS10_1_FIO1
|
||||
RGPS10_1_SS1
|
||||
PS10_2_TPE
|
||||
PS10_5_FIO2
|
||||
PS10_5_FIO4PS10_5_FIO5
|
||||
WPS11_1_JR1
|
||||
PS11_3_FIO1
|
||||
GPS11_4_S2
|
||||
GPS11_4_S1
|
||||
PS11_4_FIO1
|
||||
PS11_7_FIO1
|
||||
PS11_11_FIO2
|
||||
PS11_11_FIO3
|
||||
PS11_11_FIO4
|
||||
PS11_11_FIO5
|
||||
PS11_11_FIO6
|
||||
PRS3_2B_FIO1 PRS3_2A_FIOM1
|
||||
PRS3_4CH_FIO1
|
||||
PRS4_2_FIO1
|
||||
WPRS4_2_JR1
|
||||
RGULC7_3_SS1
|
||||
RGULC7_3_SS2RGULC8_3_SS1
|
||||
PS10_5_TPE1
|
||||
PS11_6_TPE1
|
||||
PS11_6_TPE2
|
||||
PS11_7_TPE1
|
||||
PS11_8_TPE1 PS11_11_TPE1
|
||||
PS11_11CH3_JPE1PS11_11CH3_FPE1PS11_11CH3_FPE2PS11_11CH4_JPE1PS11_11CH4_FPE1PS11_11CH4_FPE2
|
||||
PS11_11CH5_JPE1PS11_11CH5_FPE1PS11_11CH5_FPE2PS11_11CH6_JPE1PS11_11CH6_FPE1PS11_11CH6_FPE2
|
||||
GDTC_NCH1_EN1
|
||||
CH_DPM1_FIOM1
|
||||
GDTC_NCH2_EN1
|
||||
GDTC_NCH3_EN1
|
||||
GDTC_NCH4_EN1CH_DPM1MCM04
|
||||
GDTC_NCH5_EN1
|
||||
CH_DPM1_FIOM2
|
||||
GDTC_NCH6_EN1
|
||||
GDTC_NCH7_EN1
|
||||
GDTC_NCH8_EN1
|
||||
GDTC_NCH9_EN1
|
||||
CH_DPM1_FIOM3
|
||||
GDTC_NCH10_EN1
|
||||
GDTC_NCH11_EN1
|
||||
GDTC_NCH12_EN1
|
||||
GDTC_NCH13_EN1
|
||||
CH_DPM1_FIOM4
|
||||
GDTC_NCH14_EN1
|
||||
GDTC_NCH15_EN1
|
||||
GDTC_NCH16_EN1
|
||||
CH_DPM1_FIOM5
|
||||
GDTC_NCH17_EN1
|
||||
FL1034_2_PE1ABBBFL1034_1CH_PE1
|
||||
FL1034_2_PE2
|
||||
FL1034_2_VFD15HP350FPM
|
||||
FL1034_3CH_PE1BBBWFL1034_2_JR2WFL1034_2_JR1
|
||||
WFL1034_1_JR1FL1026_2_PE1ABBB
|
||||
FL1026_1CH_PE1
|
||||
FL1026_2_PE2FL1026_3CH_PE1BBBWFL1026_2_JR2WFL1026_2_JR1
|
||||
WFL1026_1_JR1FL1022_2_PE1
|
||||
ABBB
|
||||
FL1022_1CH_PE1
|
||||
FL1022_2_PE2FL1022_3CH_PE1BBBWFL1022_2_JR2WFL1022_2_JR1
|
||||
WFL1022_1_JR1FL1018_2_PE1ABBB
|
||||
FL1018_1CH_PE1
|
||||
FL1018_2_PE2FL1018_3CH_PE1BBBWFL1018_2_JR2WFL1018_2_JR1
|
||||
WFL1018_1_JR1
|
||||
FL1014_2_PE1ABBB
|
||||
FL1014_1CH_PE1
|
||||
FL1014_2_PE2FL1014_3CH_PE1BBBWFL1014_2_JR2WFL1014_2_JR1
|
||||
WFL1014_1_JR1 FL3012_2_PE1
|
||||
ABBB
|
||||
FL3012_1CH_PE1
|
||||
FL3012_2_PE2FL3012_3CH_PE1BBBWFL3012_2_JR2WFL3012_2_JR1
|
||||
WFL3012_1_JR1FL3016_2_PE1
|
||||
ABBB
|
||||
FL3016_1CH_PE1
|
||||
FL3016_2_PE2FL3016_3CH_PE1BBBWFL3016_2_JR2WFL3016_2_JR1
|
||||
WFL3016_1_JR1FL3020_2_PE1
|
||||
ABBB
|
||||
FL3020_1CH_PE1
|
||||
FL3020_2_PE2FL3020_3CH_PE1BBBWFL3020_2_JR2WFL3020_2_JR1
|
||||
WFL3020_1_JR1FL3024_2_PE1
|
||||
ABBB
|
||||
FL3024_1CH_PE1
|
||||
FL3024_2_PE2FL3024_3CH_PE1BBBWFL3024_2_JR2WFL3024_2_JR1
|
||||
WFL3024_1_JR1
|
||||
FL1026_2_VFD15HP350FPMFL1022_2_VFD15HP350FPMFL1018_2_VFD15HP350FPMFL1014_2_VFD15HP350FPM FL3012_2_VFD15HP350FPMFL3016_2_VFD15HP350FPMFL3020_2_VFD15HP350FPMFL3024_2_VFD15HP350FPM
|
||||
CH_DPM2_FIOM2CH_DPM2_FIOM1
|
||||
CH_DPM2_FIOM4CH_DPM2_FIOM3CH_DPM2_FIOM6CH_DPM2_FIOM5
|
||||
BBGABBBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGB BBGBBBGAB BBGAB BBGAB BBGAB
|
||||
BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB
|
||||
CH_DPM3MCM04 CH_DPM4MCM04 CH_DPM5MCM04 CH_DPM6MCM04
|
||||
PB_NCH1_FIOH1PB_NCH3_FIOH1PB_NCH5_FIOH1PB_NCH7_FIOH1PB_NCH9_FIOH1PB_NCH10_FIOH1PB_NCH11_FIOH1PB_NCH12_FIOH1PB_NCH13_FIOH1PB_NCH14_FIOH1PB_NCH15_FIOH1PB_NCH16_FIOH1PB_NCH18_FIOH1PB_NCH20_FIOH1
|
||||
CH_DPM3_FIOM2CH_DPM3_FIOM1CH_DPM3_FIOM4CH_DPM3_FIOM3CH_DPM3_FIOM6CH_DPM3_FIOM5CH_DPM3_FIOM8CH_DPM3_FIOM7
|
||||
PB_NCH21_FIOH1PB_NCH24_FIOH1PB_NCH25_FIOH1PB_NCH26_FIOH1PB_NCH27_FIOH1PB_NCH28_FIOH1PB_NCH29_FIOH1PB_NCH31_FIOH1PB_NCH33_FIOH1PB_NCH35_FIOH1PB_NCH37_FIOH1PB_NCH39_FIOH1PB_NCH41_FIOH1PB_NCH43_FIOH1PB_NCH45_FIOH1PB_NCH46_FIOH1PB_NCH48_FIOH1PB_NCH50_FIOH1PB_NCH52_FIOH1PB_NCH54_FIOH1PB_NCH56_FIOH1PB_NCH58_FIOH1PB_NCH60_FIOH1
|
||||
CH_DPM4_FIOM1CH_DPM4_FIOM3CH_DPM4_FIOM2CH_DPM4_FIOM5CH_DPM4_FIOM4CH_DPM4_FIOM7CH_DPM4_FIOM6CH_DPM5_FIOM2CH_DPM5_FIOM1CH_DPM5_FIOM4CH_DPM5_FIOM3CH_DPM5_FIOM6CH_DPM5_FIOM5CH_DPM5_FIOM8CH_DPM5_FIOM7CH_DPM6_FIOM2CH_DPM6_FIOM1CH_DPM6_FIOM4CH_DPM6_FIOM3CH_DPM6_FIOM6CH_DPM6_FIOM5CH_DPM6_FIOM8CH_DPM6_FIOM7
|
||||
BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGABBBGBBBGBBBGB BBGBBBGBBBGB BBGB BBGB BBGB BBGB BBGB BBGBBBGBBBGB BBGB BBGBBBGB BBGB BBGB BBGB BBGB BBGB BBGB BBGBBBGB BBGBBBGBBBGB BBGBBBGB BBGB BBGBBBGB BBGBBBGB BBGBBBGBBBGB BBGBBBGB BBGB
|
||||
GDTC_NCH18_EN1
|
||||
GDTC_NCH19_EN1
|
||||
GDTC_NCH20_EN1
|
||||
GDTC_NCH21_EN1
|
||||
GDTC_NCH22_EN1
|
||||
GDTC_NCH23_EN1
|
||||
GDTC_NCH24_EN1
|
||||
GDTC_NCH25_EN1
|
||||
GDTC_NCH26_EN1
|
||||
GDTC_NCH27_EN1
|
||||
GDTC_NCH28_EN1
|
||||
GDTC_NCH29_EN1
|
||||
GDTC_NCH30_EN1
|
||||
GDTC_NCH31_EN1
|
||||
GDTC_NCH32_EN1
|
||||
GDTC_NCH33_EN1
|
||||
GDTC_NCH34_EN1
|
||||
GDTC_NCH35_EN1
|
||||
GDTC_NCH36_EN1
|
||||
GDTC_NCH37_EN1
|
||||
GDTC_NCH38_EN1
|
||||
GDTC_NCH39_EN1
|
||||
GDTC_CH40_EN1
|
||||
GDTC_CH41_EN1
|
||||
GDTC_CH42_EN1
|
||||
GDTC_CH43_EN1
|
||||
GDTC_CH44_EN1
|
||||
GDTC_CH45_EN1
|
||||
GDTC_CH46_EN1
|
||||
GDTC_CH47_EN1
|
||||
GDTC_CH48_EN1
|
||||
GDTC_CH49_EN1
|
||||
GDTC_CH50_EN1
|
||||
GDTC_NCH51_EN1
|
||||
GDTC_NCH52_EN1
|
||||
GDTC_NCH53_EN1
|
||||
GDTC_NCH54_EN1
|
||||
GDTC_NCH55_EN1
|
||||
GDTC_NCH56_EN1
|
||||
GDTC_NCH57_EN1
|
||||
GDTC_NCH58_EN1
|
||||
GDTC_NCH59_EN1
|
||||
GDTC_NCH60_EN1
|
||||
GDTC_NCH61_EN1
|
||||
GDTC_NCH62_EN1
|
||||
GDTC_NCH63_EN1
|
||||
GDTC_NCH64_EN1
|
||||
GDTC_NCH65_EN1
|
||||
GDTC_NCH66_EN1
|
||||
GDTC_NCH67_EN1
|
||||
GDTC_NCH68_EN1
|
||||
GDTC_NCH69_EN1
|
||||
GDTC_NCH70_EN1
|
||||
GDTC_NCH71_EN1
|
||||
GDTC_NCH72_EN1
|
||||
GDTC_NCH73_EN1
|
||||
GDTC_NCH74_EN1
|
||||
GDTC_NCH75_EN1
|
||||
GDTC_NCH76_EN1
|
||||
PB_NCH1_PE1
|
||||
PB_NCH1_PE2
|
||||
BBGABBBGB
|
||||
WPB_NCH1_PKGREL_PB1SOLPB_NCH1_PKGREL_SOL1
|
||||
PB_NCH2_PE1
|
||||
PB_NCH2_PE2
|
||||
WPB_NCH2_PKGREL_PB1SOLPB_NCH2_PKGREL_SOL1
|
||||
PB_NCH3_PE1
|
||||
PB_NCH3_PE2
|
||||
WPB_NCH3_PKGREL_PB1SOLPB_NCH3_PKGREL_SOL1
|
||||
PB_NCH4_PE1
|
||||
PB_NCH4_PE2
|
||||
WPB_NCH4_PKGREL_PB1SOLPB_NCH4_PKGREL_SOL1
|
||||
PB_NCH5_PE1
|
||||
PB_NCH5_PE2
|
||||
WPB_NCH5_PKGREL_PB1SOLPB_NCH5_PKGREL_SOL1
|
||||
PB_NCH6_PE1
|
||||
PB_NCH6_PE2
|
||||
WPB_NCH6_PKGREL_PB1SOLPB_NCH6_PKGREL_SOL1
|
||||
PB_NCH7_PE1
|
||||
PB_NCH7_PE2
|
||||
WPB_NCH7_PKGREL_PB1SOLPB_NCH7_PKGREL_SOL1
|
||||
PB_NCH8_PE1
|
||||
PB_NCH8_PE2
|
||||
WPB_NCH8_PKGREL_PB1SOLPB_NCH8_PKGREL_SOL1
|
||||
PB_NCH9_PE1
|
||||
PB_NCH9_PE2
|
||||
WPB_NCH9_PKGREL_PB1SOLPB_NCH9_PKGREL_SOL1
|
||||
PB_NCH10_PE1
|
||||
PB_NCH10_PE2
|
||||
WPB_NCH10_PKGREL_PB1SOLPB_NCH10_PKGREL_SOL1
|
||||
PB_NCH11_PE1
|
||||
PB_NCH11_PE2
|
||||
WPB_NCH11_PKGREL_PB1SOLPB_NCH11_PKGREL_SOL1
|
||||
PB_NCH12_PE1
|
||||
PB_NCH12_PE2
|
||||
WPB_NCH12_PKGREL_PB1SOLPB_NCH12_PKGREL_SOL1
|
||||
PB_NCH13_PE1
|
||||
PB_NCH13_PE2
|
||||
WPB_NCH13_PKGREL_PB1SOLPB_NCH13_PKGREL_SOL1
|
||||
PB_NCH14_PE1
|
||||
PB_NCH14_PE2
|
||||
WPB_NCH14_PKGREL_PB1SOLPB_NCH14_PKGREL_SOL1
|
||||
PB_NCH15_PE1
|
||||
PB_NCH15_PE2
|
||||
WPB_NCH15_PKGREL_PB1SOLPB_NCH15_PKGREL_SOL1
|
||||
PB_NCH16_PE1
|
||||
PB_NCH16_PE2
|
||||
WPB_NCH16_PKGREL_PB1SOLPB_NCH16_PKGREL_SOL1
|
||||
PB_NCH17_PE1
|
||||
PB_NCH17_PE2
|
||||
WPB_NCH17_PKGREL_PB1SOLPB_NCH17_PKGREL_SOL1
|
||||
PB_NCH18_PE1
|
||||
PB_NCH18_PE2
|
||||
WPB_NCH18_PKGREL_PB1SOLPB_NCH18_PKGREL_SOL1
|
||||
PB_NCH19_PE1
|
||||
PB_NCH19_PE2
|
||||
WPB_NCH19_PKGREL_PB1SOLPB_NCH19_PKGREL_SOL1
|
||||
PB_NCH20_PE1
|
||||
PB_NCH20_PE2
|
||||
WPB_NCH20_PKGREL_PB1SOLPB_NCH20_PKGREL_SOL1
|
||||
PB_NCH21_PE1
|
||||
PB_NCH21_PE2
|
||||
WPB_NCH21_PKGREL_PB1SOLPB_NCH21_PKGREL_SOL1
|
||||
PB_NCH22_PE1
|
||||
PB_NCH22_PE2
|
||||
WPB_NCH22_PKGREL_PB1SOLPB_NCH22_PKGREL_SOL1
|
||||
PB_NCH23_PE1
|
||||
PB_NCH23_PE2
|
||||
WPB_NCH23_PKGREL_PB1SOLPB_NCH23_PKGREL_SOL1
|
||||
PB_NCH24_PE1
|
||||
PB_NCH24_PE2
|
||||
WPB_NCH24_PKGREL_PB1SOLPB_NCH24_PKGREL_SOL1
|
||||
PB_NCH25_PE1
|
||||
PB_NCH25_PE2
|
||||
WPB_NCH25_PKGREL_PB1SOLPB_NCH25_PKGREL_SOL1
|
||||
PB_NCH26_PE1
|
||||
PB_NCH26_PE2
|
||||
WPB_NCH26_PKGREL_PB1SOLPB_NCH26_PKGREL_SOL1
|
||||
PB_NCH27_PE1
|
||||
PB_NCH27_PE2
|
||||
WPB_NCH27_PKGREL_PB1SOLPB_NCH27_PKGREL_SOL1
|
||||
PB_NCH28_PE1
|
||||
PB_NCH28_PE2
|
||||
WPB_NCH28_PKGREL_PB1SOLPB_NCH28_PKGREL_SOL1
|
||||
PB_NCH29_PE1
|
||||
PB_NCH29_PE2
|
||||
WPB_NCH29_PKGREL_PB1SOLPB_NCH29_PKGREL_SOL1
|
||||
PB_NCH30_PE1
|
||||
PB_NCH30_PE2
|
||||
WPB_NCH30_PKGREL_PB1SOLPB_NCH30_PKGREL_SOL1
|
||||
PB_NCH31_PE1
|
||||
PB_NCH31_PE2
|
||||
WPB_NCH31_PKGREL_PB1SOLPB_NCH31_PKGREL_SOL1
|
||||
PB_NCH32_PE1
|
||||
PB_NCH32_PE2
|
||||
WPB_NCH32_PKGREL_PB1SOLPB_NCH32_PKGREL_SOL1
|
||||
PB_NCH33_PE1
|
||||
PB_NCH33_PE2
|
||||
WPB_NCH33_PKGREL_PB1SOLPB_NCH33_PKGREL_SOL1
|
||||
PB_NCH34_PE1
|
||||
PB_NCH34_PE2
|
||||
WPB_NCH34_PKGREL_PB1SOLPB_NCH34_PKGREL_SOL1
|
||||
PB_NCH35_PE1
|
||||
PB_NCH35_PE2
|
||||
WPB_NCH35_PKGREL_PB1SOLPB_NCH35_PKGREL_SOL1
|
||||
PB_NCH36_PE1
|
||||
PB_NCH36_PE2
|
||||
WPB_NCH36_PKGREL_PB1SOLPB_NCH36_PKGREL_SOL1
|
||||
PB_NCH37_PE1
|
||||
PB_NCH37_PE2
|
||||
WPB_NCH37_PKGREL_PB1SOLPB_NCH37_PKGREL_SOL1
|
||||
PB_NCH38_PE1
|
||||
PB_NCH38_PE2
|
||||
WPB_NCH38_PKGREL_PB1SOLPB_NCH38_PKGREL_SOL1
|
||||
PB_NCH39_PE1
|
||||
PB_NCH39_PE2
|
||||
WPB_NCH39_PKGREL_PB1SOLPB_NCH39_PKGREL_SOL1
|
||||
PB_NCH40_PE1
|
||||
PB_NCH40_PE2
|
||||
WPB_NCH40_PKGREL_PB1SOLPB_NCH40_PKGREL_SOL1
|
||||
PB_NCH41_PE1
|
||||
PB_NCH41_PE2
|
||||
WPB_NCH41_PKGREL_PB1SOLPB_NCH41_PKGREL_SOL1
|
||||
PB_NCH42_PE1
|
||||
PB_NCH42_PE2
|
||||
WPB_NCH42_PKGREL_PB1SOLPB_NCH42_PKGREL_SOL1
|
||||
PB_NCH43_PE1
|
||||
PB_NCH43_PE2
|
||||
WPB_NCH43_PKGREL_PB1SOLPB_NCH43_PKGREL_SOL1
|
||||
PB_NCH44_PE1
|
||||
PB_NCH44_PE2
|
||||
WPB_NCH44_PKGREL_PB1SOLPB_NCH44_PKGREL_SOL1
|
||||
PB_NCH45_PE1
|
||||
PB_NCH45_PE2
|
||||
WPB_NCH45_PKGREL_PB1SOLPB_NCH45_PKGREL_SOL1
|
||||
PB_NCH46_PE1
|
||||
PB_NCH46_PE2
|
||||
WPB_NCH46_PKGREL_PB1SOLPB_NCH46_PKGREL_SOL1
|
||||
PB_NCH47_PE1
|
||||
PB_NCH47_PE2
|
||||
WPB_NCH47_PKGREL_PB1SOLPB_NCH47_PKGREL_SOL1
|
||||
PB_NCH48_PE1
|
||||
PB_NCH48_PE2
|
||||
WPB_NCH48_PKGREL_PB1SOLPB_NCH48_PKGREL_SOL1
|
||||
PB_NCH49_PE1
|
||||
PB_NCH49_PE2
|
||||
WPB_NCH49_PKGREL_PB1SOLPB_NCH49_PKGREL_SOL1
|
||||
PB_NCH50_PE1
|
||||
PB_NCH50_PE2
|
||||
WPB_NCH50_PKGREL_PB1SOLPB_NCH50_PKGREL_SOL1
|
||||
PB_NCH51_PE1
|
||||
PB_NCH51_PE2
|
||||
WPB_NCH51_PKGREL_PB1SOLPB_NCH51_PKGREL_SOL1
|
||||
PB_NCH52_PE1
|
||||
PB_NCH52_PE2
|
||||
WPB_NCH52_PKGREL_PB1SOLPB_NCH52_PKGREL_SOL1
|
||||
PB_NCH53_PE1
|
||||
PB_NCH53_PE2
|
||||
WPB_NCH53_PKGREL_PB1SOLPB_NCH53_PKGREL_SOL1
|
||||
PB_NCH54_PE1
|
||||
PB_NCH54_PE2
|
||||
WPB_NCH54_PKGREL_PB1SOLPB_NCH54_PKGREL_SOL1
|
||||
PB_NCH55_PE1
|
||||
PB_NCH55_PE2
|
||||
WPB_NCH55_PKGREL_PB1SOLPB_NCH55_PKGREL_SOL1
|
||||
PB_NCH56_PE1
|
||||
PB_NCH56_PE2
|
||||
WPB_NCH56_PKGREL_PB1SOLPB_NCH56_PKGREL_SOL1
|
||||
PB_NCH57_PE1
|
||||
PB_NCH57_PE2
|
||||
WPB_NCH57_PKGREL_PB1SOLPB_NCH57_PKGREL_SOL1
|
||||
PB_NCH58_PE1
|
||||
PB_NCH58_PE2
|
||||
WPB_NCH58_PKGREL_PB1SOLPB_NCH58_PKGREL_SOL1
|
||||
PB_NCH59_PE1
|
||||
PB_NCH59_PE2
|
||||
WPB_NCH59_PKGREL_PB1SOLPB_NCH59_PKGREL_SOL1
|
||||
PB_NCH60_PE1
|
||||
PB_NCH60_PE2
|
||||
WPB_NCH60_PKGREL_PB1SOLPB_NCH60_PKGREL_SOL1
|
||||
PB_NCH61_PE1
|
||||
PB_NCH61_PE2
|
||||
WPB_NCH61_PKGREL_PB1SOLPB_NCH61_PKGREL_SOL1
|
||||
BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGAB BBGABBBGBBBGB BBGBBBGBBBGB BBGB BBGB BBGB BBGBBBGB BBGBBBGB BBGBBBGBBBGB BBGB BBGB BBGB BBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGB BBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGBBBGB BBGBBBGBBBGB
|
||||
BIN
projects/MTN6_Test/pdfs/MTN6_SYSDL-MCM04.pdf
Normal file
BIN
projects/MTN6_Test/pdfs/MTN6_SYSDL-MCM04.pdf
Normal file
Binary file not shown.
2
projects/MTN6_Test/project_info.txt
Normal file
2
projects/MTN6_Test/project_info.txt
Normal file
@ -0,0 +1,2 @@
|
||||
ProjectName: MTN6_Test
|
||||
RepoURL: http://192.168.5.191:3000/ilia-gurielidze-autstand/MTN6_SCADA.git
|
||||
1
projects/MTN6_Test/repo
Submodule
1
projects/MTN6_Test/repo
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 456de12cca56c09bc1881660b163ac3b5dff593a
|
||||
@ -1,2 +1,3 @@
|
||||
Flask
|
||||
GitPython
|
||||
pypdf
|
||||
59
scada_checker.py
Normal file
59
scada_checker.py
Normal file
@ -0,0 +1,59 @@
|
||||
import os
|
||||
import json
|
||||
from utils import normalize, get_views_dir_path
|
||||
|
||||
def check_scada(project_name, manifest_data):
|
||||
"""
|
||||
Checks for aliases in SCADA JSON view files for a specific project.
|
||||
Updates the 'found_scada' flag in the manifest_data items directly.
|
||||
"""
|
||||
if not manifest_data:
|
||||
print(f"[{project_name}] SCADA Check: No manifest data provided.")
|
||||
return
|
||||
views_dir = get_views_dir_path(project_name)
|
||||
print(f"[{project_name}] Starting SCADA check in directory: {views_dir}...")
|
||||
found_count = 0
|
||||
processed_files = 0
|
||||
|
||||
if not os.path.exists(views_dir):
|
||||
print(f"Warning: SCADA Views directory not found at {views_dir}. Skipping SCADA check.")
|
||||
# No need to mark all as False, they default to False
|
||||
return
|
||||
|
||||
# Create a quick lookup map of normalized_alias -> list of manifest items (handles duplicate aliases)
|
||||
alias_map = {}
|
||||
for item in manifest_data:
|
||||
na = item['normalized_alias']
|
||||
if na not in alias_map:
|
||||
alias_map[na] = []
|
||||
alias_map[na].append(item)
|
||||
|
||||
try:
|
||||
for root, _, files in os.walk(views_dir):
|
||||
for filename in files:
|
||||
if filename == 'view.json':
|
||||
filepath = os.path.join(root, filename)
|
||||
processed_files += 1
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
# Read the whole file, normalize it for substring search
|
||||
# Consider JSON loading for more robust checks? For now, string search.
|
||||
content = f.read()
|
||||
normalized_content = normalize(content)
|
||||
|
||||
# Check manifest aliases against this file's normalized content
|
||||
for norm_alias, items in alias_map.items():
|
||||
# Use 'in' for substring check
|
||||
if norm_alias and norm_alias in normalized_content:
|
||||
for item in items:
|
||||
if not item['found_scada']: # Update only if not already found elsewhere
|
||||
item['found_scada'] = True
|
||||
# Count unique aliases found the *first* time
|
||||
found_count += 1
|
||||
except Exception as e:
|
||||
print(f" Warning: Could not read or process JSON file {filepath}: {e}")
|
||||
except Exception as e:
|
||||
print(f"Error walking SCADA views directory {views_dir}: {e}")
|
||||
|
||||
print(f"[{project_name}] SCADA check finished. Processed {processed_files} view.json files. Found {found_count} unique manifest aliases.")
|
||||
# No return value needed as manifest_data is modified in-place
|
||||
51
static/css/style.css
Normal file
51
static/css/style.css
Normal file
@ -0,0 +1,51 @@
|
||||
body { padding: 20px; padding-bottom: 60px; /* Account for status bar */ }
|
||||
.progress-container, .chart-container {
|
||||
margin-bottom: 25px;
|
||||
text-align: center; /* Center chart labels */
|
||||
}
|
||||
.chart-label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
display: block;
|
||||
}
|
||||
.status-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: #f8f9fa;
|
||||
border-top: 1px solid #dee2e6;
|
||||
padding: 5px 15px;
|
||||
font-size: 0.9em;
|
||||
z-index: 1000;
|
||||
}
|
||||
/* Style for the overall progress bar - Removed as using Pie chart */
|
||||
|
||||
/* Style for panel charts */
|
||||
.panel-chart-canvas {
|
||||
max-width: 150px; /* Control pie chart size */
|
||||
max-height: 150px;
|
||||
margin: 0 auto; /* Center the canvas */
|
||||
cursor: pointer; /* Indicate clickable */
|
||||
}
|
||||
#scada-panels-progress, #drawing-panels-progress {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* Responsive grid */
|
||||
gap: 20px;
|
||||
}
|
||||
.modal-body table { width: 100%; }
|
||||
.modal-body th, .modal-body td { padding: 5px 10px; border-bottom: 1px solid #eee; vertical-align: middle; }
|
||||
.modal-body th { background-color: #f8f9fa; text-align: left; }
|
||||
.status-yes { color: green; font-weight: bold; }
|
||||
.status-no { color: red; font-weight: bold; }
|
||||
nav { margin-bottom: 20px; } /* Added for nav spacing */
|
||||
|
||||
.chart-container > canvas,
|
||||
.chart-container > div:not(.processing-indicator) {
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.content-hidden-by-loader {
|
||||
display: none !important; /* Use important to override potential inline styles */
|
||||
opacity: 0;
|
||||
}
|
||||
877
static/js/script.js
Normal file
877
static/js/script.js
Normal file
@ -0,0 +1,877 @@
|
||||
// --- Global State Variables ---
|
||||
let chartInstancesScada = {}; // Separate instances for SCADA
|
||||
let chartInstancesDrawing = {}; // Separate instances for Drawing
|
||||
let currentProjectData = {}; // Stores the LATEST full data received from SSE { project: {status, commit, progress}, ... }
|
||||
let selectedProjectName = null; // Track the currently selected project
|
||||
let detailsModalInstance = null;
|
||||
let currentVisibleSection = 'scada'; // Track visible section: 'scada', 'drawing', 'conflicts'
|
||||
|
||||
// --- Chart Configurations ---
|
||||
const scadaChartLabels = ['Found in SCADA', 'Not Found in SCADA'];
|
||||
const scadaChartColors = ['rgb(13, 110, 253)', 'rgb(220, 53, 69)'];
|
||||
const drawingChartLabels = ['Found in Drawing', 'Not Found in Drawing'];
|
||||
const drawingChartColors = ['rgb(25, 135, 84)', 'rgb(220, 53, 69)'];
|
||||
|
||||
// Map backend list keys for modal clicks (can be combined or kept separate if needed)
|
||||
const scadaListKeysMap = {
|
||||
found: ['found_both_list', 'found_scada_only_list'],
|
||||
notFound: ['found_drawing_only_list', 'missing_list']
|
||||
};
|
||||
const drawingListKeysMap = {
|
||||
found: ['found_both_list', 'found_drawing_only_list'],
|
||||
notFound: ['found_scada_only_list', 'missing_list']
|
||||
};
|
||||
|
||||
// --- Debounce Utility (Only need one) ---
|
||||
function debounce(func, wait) {
|
||||
let timeout;
|
||||
return function executedFunction(...args) {
|
||||
const later = () => {
|
||||
clearTimeout(timeout);
|
||||
func(...args);
|
||||
};
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
}
|
||||
|
||||
// --- NEW: Helper Functions for Processing State ---
|
||||
|
||||
// Checks if the status message indicates ongoing processing
|
||||
function isProcessing(statusMsg) {
|
||||
if (!statusMsg) return false; // Handle undefined/null status
|
||||
const lowerStatus = statusMsg.toLowerCase();
|
||||
// Keywords indicating processing (adjust as needed based on app.py status messages)
|
||||
return lowerStatus.includes('initializ') || // initializing, initial...
|
||||
lowerStatus.includes('cloning') ||
|
||||
lowerStatus.includes('fetching') ||
|
||||
lowerStatus.includes('pulling') ||
|
||||
lowerStatus.includes('checking') || // checking repo, checking scada, checking drawings
|
||||
lowerStatus.includes('reading manifest') ||
|
||||
lowerStatus.includes('calculating') ||
|
||||
lowerStatus.includes('extracting') || // If PDF extraction status is sent
|
||||
lowerStatus.includes('loading data'); // From handleProjectChange initial state
|
||||
}
|
||||
|
||||
// Displays a loading indicator in a container element
|
||||
function showLoadingIndicator(containerElement, message = "Processing project data...") {
|
||||
if (!containerElement) return;
|
||||
|
||||
// Hide existing content
|
||||
for (const child of containerElement.children) {
|
||||
if (!child.classList.contains('processing-indicator')) {
|
||||
child.classList.add('content-hidden-by-loader');
|
||||
}
|
||||
}
|
||||
|
||||
let indicatorDiv = containerElement.querySelector('.processing-indicator');
|
||||
if (!indicatorDiv) {
|
||||
indicatorDiv = document.createElement('div');
|
||||
indicatorDiv.className = 'text-center p-4 processing-indicator';
|
||||
indicatorDiv.innerHTML = `
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
<p class="mt-2 fst-italic"></p>
|
||||
`;
|
||||
// Prepend to ensure it's visible even if container had position: relative children
|
||||
containerElement.prepend(indicatorDiv);
|
||||
}
|
||||
|
||||
// Update message
|
||||
const messageElement = indicatorDiv.querySelector('p');
|
||||
if (messageElement) {
|
||||
// Sanitize message slightly before displaying
|
||||
const safeMessage = message.replace(/</g, "<").replace(/>/g, ">");
|
||||
messageElement.textContent = safeMessage;
|
||||
}
|
||||
indicatorDiv.style.display = 'block'; // Ensure indicator is visible
|
||||
}
|
||||
|
||||
// Removes the loading indicator from a container
|
||||
function clearLoadingIndicator(containerElement) {
|
||||
if (!containerElement) return;
|
||||
|
||||
// Remove indicator
|
||||
const indicatorDiv = containerElement.querySelector('.processing-indicator');
|
||||
if (indicatorDiv) {
|
||||
// indicatorDiv.remove(); // Or hide it if preferred
|
||||
indicatorDiv.style.display = 'none';
|
||||
}
|
||||
|
||||
// Show original content
|
||||
for (const child of containerElement.children) {
|
||||
child.classList.remove('content-hidden-by-loader');
|
||||
}
|
||||
|
||||
// Remove default "Loading panel data..." placeholders if they still exist
|
||||
const placeholderP = Array.from(containerElement.querySelectorAll('p.fst-italic')).find(p =>
|
||||
p.textContent.toLowerCase().includes('loading') &&
|
||||
!p.closest('.processing-indicator')
|
||||
);
|
||||
if (placeholderP) {
|
||||
placeholderP.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the entire UI to reflect a processing state
|
||||
function showProcessingStateUI(projectData) {
|
||||
const statusMsg = projectData ? projectData.status : "Loading data...";
|
||||
const containers = [
|
||||
document.getElementById('overall-scada-progress'),
|
||||
document.getElementById('scada-panels-progress'),
|
||||
document.getElementById('overall-drawing-progress'),
|
||||
document.getElementById('drawing-panels-progress'),
|
||||
document.getElementById('panels-conflicts')
|
||||
];
|
||||
|
||||
console.log(`[UI State] Setting processing state: "${statusMsg}"`);
|
||||
|
||||
// Destroy all existing charts immediately to prevent rendering issues
|
||||
Object.values(chartInstancesScada).forEach(chart => chart?.destroy());
|
||||
chartInstancesScada = {};
|
||||
Object.values(chartInstancesDrawing).forEach(chart => chart?.destroy());
|
||||
chartInstancesDrawing = {};
|
||||
|
||||
// Show loading indicator in all content containers
|
||||
containers.forEach(container => {
|
||||
if (container) {
|
||||
showLoadingIndicator(container, statusMsg); // Show the actual status message
|
||||
}
|
||||
});
|
||||
|
||||
// Clear text content that is updated directly (like overall percentages)
|
||||
const overallScadaText = document.getElementById('overall-scada-text');
|
||||
if (overallScadaText) overallScadaText.textContent = '';
|
||||
const overallDrawingText = document.getElementById('overall-drawing-text');
|
||||
if (overallDrawingText) overallDrawingText.textContent = '';
|
||||
const conflictCount = document.getElementById('conflict-count');
|
||||
if (conflictCount) {
|
||||
conflictCount.textContent = '...';
|
||||
conflictCount.style.display = 'inline-block'; // Show it while loading
|
||||
}
|
||||
|
||||
// Ensure the correct section's container is visible if it was hidden
|
||||
// (showSection handles visibility, but this prevents blank screens if called directly)
|
||||
const scadaContent = document.getElementById('scada-content');
|
||||
const drawingsContent = document.getElementById('drawings-content');
|
||||
const conflictsContent = document.getElementById('conflicts-content');
|
||||
if (scadaContent && currentVisibleSection === 'scada') scadaContent.style.display = 'block';
|
||||
if (drawingsContent && currentVisibleSection === 'drawings') drawingsContent.style.display = 'block';
|
||||
if (conflictsContent && currentVisibleSection === 'conflicts') conflictsContent.style.display = 'block';
|
||||
}
|
||||
|
||||
// Clears loading indicators and triggers the actual UI rendering
|
||||
function showReadyStateUI(projectData) {
|
||||
console.log(`[UI State] Setting ready state for project: ${selectedProjectName}`);
|
||||
const containers = [
|
||||
document.getElementById('overall-scada-progress'),
|
||||
document.getElementById('scada-panels-progress'),
|
||||
document.getElementById('overall-drawing-progress'),
|
||||
document.getElementById('drawing-panels-progress'),
|
||||
document.getElementById('panels-conflicts')
|
||||
];
|
||||
// Clear loading indicators from all containers
|
||||
containers.forEach(container => {
|
||||
if(container) clearLoadingIndicator(container);
|
||||
});
|
||||
|
||||
// Call core update functions (wrapped in setTimeout for smooth rendering)
|
||||
console.log(`Project state is ready. Queueing core redraw.`);
|
||||
setTimeout(() => {
|
||||
console.log(`Passing project data to UI updates:`, projectData);
|
||||
updateUIScadaCore(projectData);
|
||||
updateUIDrawingCore(projectData);
|
||||
updateUIConflictsCore(projectData);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
// --- Chart Click Handler (Needs PROJECT CONTEXT) ---
|
||||
function handleChartClick(event, elements, chart, context) {
|
||||
if (elements.length > 0 && selectedProjectName) { // Check if a project is selected
|
||||
const clickedElementIndex = elements[0].index;
|
||||
const isOverallChart = chart.canvas.id.startsWith('overall-');
|
||||
const identifier = isOverallChart ? '__overall__' : chart.canvas.id.replace(`chart-${context}-`, '');
|
||||
const categoryType = clickedElementIndex === 0 ? 'found' : 'notFound';
|
||||
|
||||
// Pass selectedProjectName to the modal function
|
||||
showDetailsModal(selectedProjectName, identifier, categoryType, context);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Core UI Update Functions (Need selected project data) ---
|
||||
|
||||
function updateUIScadaCore(projectData) { // Accepts data for the selected project
|
||||
console.log(`Running core SCADA UI redraw logic for project: ${selectedProjectName}`);
|
||||
const progressDetails = (projectData && projectData.progress) ? projectData.progress : { overall: {}, panels: {} };
|
||||
const overallData = progressDetails.overall || {};
|
||||
|
||||
const overallTotal = overallData.total_csv || 0;
|
||||
const overallFoundScada = (overallData.found_both || 0) + (overallData.found_scada_only || 0);
|
||||
const overallNotFoundScada = (overallData.found_drawing_only || 0) + (overallData.missing_both || 0);
|
||||
const overallPercentageFound = overallTotal > 0 ? ((overallFoundScada / overallTotal) * 100).toFixed(1) : 0;
|
||||
const overallChartCounts = [overallFoundScada, overallNotFoundScada];
|
||||
|
||||
// Update project name display in headers
|
||||
document.querySelectorAll('.project-name-display').forEach(el => el.textContent = selectedProjectName || '...');
|
||||
|
||||
const overallScadaTextElement = document.getElementById('overall-scada-text');
|
||||
if (overallScadaTextElement) {
|
||||
overallScadaTextElement.textContent = `Found in SCADA: ${overallFoundScada}/${overallTotal} (${overallPercentageFound}%)`;
|
||||
} else {
|
||||
console.warn("Element with ID 'overall-scada-text' not found when trying to update SCADA text.");
|
||||
}
|
||||
|
||||
const isSectionVisible = (currentVisibleSection === 'scada');
|
||||
if (isSectionVisible) {
|
||||
const overallScadaCanvas = document.getElementById('overall-scada-chart-canvas');
|
||||
if (chartInstancesScada['overall']) {
|
||||
if (JSON.stringify(chartInstancesScada['overall'].data.datasets[0].data) !== JSON.stringify(overallChartCounts)) {
|
||||
chartInstancesScada['overall'].data.datasets[0].data = overallChartCounts;
|
||||
chartInstancesScada['overall'].update('none');
|
||||
}
|
||||
} else if (overallScadaCanvas) {
|
||||
console.log("Creating overall SCADA chart (visible).");
|
||||
const ctxOverall = overallScadaCanvas.getContext('2d');
|
||||
// Pass selectedProjectName to identify data context for clicks/tooltips
|
||||
chartInstancesScada['overall'] = new Chart(ctxOverall, createChartConfig(overallChartCounts, overallTotal, 'scada', 'overall', selectedProjectName));
|
||||
}
|
||||
} else {
|
||||
if (chartInstancesScada['overall']) {
|
||||
console.log("Destroying hidden overall SCADA chart.");
|
||||
chartInstancesScada['overall'].destroy();
|
||||
delete chartInstancesScada['overall'];
|
||||
}
|
||||
}
|
||||
|
||||
const panelsContainer = document.getElementById('scada-panels-progress');
|
||||
const panelsData = progressDetails.panels || {};
|
||||
updatePanelCharts(panelsContainer, panelsData, chartInstancesScada, 'scada');
|
||||
|
||||
console.log("Finished SCADA UI core redraw.");
|
||||
}
|
||||
|
||||
function updateUIDrawingCore(projectData) { // Accepts data for the selected project
|
||||
console.log(`Running core Drawing UI redraw logic for project: ${selectedProjectName}`);
|
||||
const progressDetails = (projectData && projectData.progress) ? projectData.progress : { overall: {}, panels: {} };
|
||||
const overallData = progressDetails.overall || {};
|
||||
|
||||
const overallTotal = overallData.total_csv || 0;
|
||||
const overallFoundDrawing = (overallData.found_both || 0) + (overallData.found_drawing_only || 0);
|
||||
const overallNotFoundDrawing = (overallData.found_scada_only || 0) + (overallData.missing_both || 0);
|
||||
const overallPercentageFound = overallTotal > 0 ? ((overallFoundDrawing / overallTotal) * 100).toFixed(1) : 0;
|
||||
const overallChartCounts = [overallFoundDrawing, overallNotFoundDrawing];
|
||||
|
||||
document.querySelectorAll('.project-name-display').forEach(el => el.textContent = selectedProjectName || '...');
|
||||
|
||||
const overallDrawingTextElement = document.getElementById('overall-drawing-text');
|
||||
if (overallDrawingTextElement) {
|
||||
overallDrawingTextElement.textContent = `Found in Drawing: ${overallFoundDrawing}/${overallTotal} (${overallPercentageFound}%)`;
|
||||
} else {
|
||||
console.warn("Element with ID 'overall-drawing-text' not found when trying to update Drawing text.");
|
||||
}
|
||||
|
||||
const isSectionVisible = (currentVisibleSection === 'drawings');
|
||||
if (isSectionVisible) {
|
||||
const overallDrawingCanvas = document.getElementById('overall-drawing-chart-canvas');
|
||||
if (chartInstancesDrawing['overall']) {
|
||||
if (JSON.stringify(chartInstancesDrawing['overall'].data.datasets[0].data) !== JSON.stringify(overallChartCounts)) {
|
||||
chartInstancesDrawing['overall'].data.datasets[0].data = overallChartCounts;
|
||||
chartInstancesDrawing['overall'].update('none');
|
||||
}
|
||||
} else if (overallDrawingCanvas) {
|
||||
console.log("Creating overall drawing chart (visible).");
|
||||
const ctxOverall = overallDrawingCanvas.getContext('2d');
|
||||
chartInstancesDrawing['overall'] = new Chart(ctxOverall, createChartConfig(overallChartCounts, overallTotal, 'drawing', 'overall', selectedProjectName));
|
||||
}
|
||||
} else {
|
||||
if (chartInstancesDrawing['overall']) {
|
||||
console.log("Destroying hidden overall Drawing chart.");
|
||||
chartInstancesDrawing['overall'].destroy();
|
||||
delete chartInstancesDrawing['overall'];
|
||||
}
|
||||
}
|
||||
|
||||
const panelsContainer = document.getElementById('drawing-panels-progress');
|
||||
const panelsData = progressDetails.panels || {};
|
||||
updatePanelCharts(panelsContainer, panelsData, chartInstancesDrawing, 'drawings');
|
||||
|
||||
console.log("Finished Drawing UI core redraw.");
|
||||
}
|
||||
|
||||
function updateUIConflictsCore(projectData) { // Accepts data for the selected project
|
||||
console.log(`Running core Conflicts UI redraw logic for project: ${selectedProjectName}`);
|
||||
const progressDetails = (projectData && projectData.progress) ? projectData.progress : { overall: {}, panels: {} };
|
||||
|
||||
const panelsContainer = document.getElementById('panels-conflicts');
|
||||
panelsContainer.innerHTML = '';
|
||||
|
||||
document.querySelectorAll('.project-name-display').forEach(el => el.textContent = selectedProjectName || '...');
|
||||
|
||||
const panelsData = progressDetails.panels || {};
|
||||
let totalConflicts = 0;
|
||||
let panelsWithConflicts = 0;
|
||||
|
||||
if (!panelsData || Object.keys(panelsData).length === 0) {
|
||||
panelsContainer.innerHTML = '<p class="text-center fst-italic">No panel data available yet.</p>';
|
||||
} else {
|
||||
const sortedPanels = Object.keys(panelsData).sort();
|
||||
sortedPanels.forEach(panelName => {
|
||||
const panel = panelsData[panelName];
|
||||
const conflictsList = panel.found_scada_only_list || [];
|
||||
if (conflictsList.length > 0) {
|
||||
panelsWithConflicts++;
|
||||
totalConflicts += conflictsList.length;
|
||||
// ... (Create header and table as in conflicts.html) ...
|
||||
const panelHeader = document.createElement('h4');
|
||||
panelHeader.className = 'mt-4 mb-2';
|
||||
panelHeader.textContent = `${panelName} (${conflictsList.length} conflicts)`;
|
||||
panelsContainer.appendChild(panelHeader);
|
||||
|
||||
const table = document.createElement('table');
|
||||
table.className = 'table table-sm table-striped table-hover table-bordered';
|
||||
const thead = table.createTHead();
|
||||
thead.innerHTML = `<tr><th>Alias</th><th>Panel</th><th>SCADA Status</th><th>Drawing Status</th><th>Equipment Type</th><th>Type of Conveyor</th></tr>`;
|
||||
const tbody = table.createTBody();
|
||||
conflictsList.sort((a, b) => a.alias.localeCompare(b.alias)).forEach(item => {
|
||||
const row = tbody.insertRow();
|
||||
row.classList.add('table-warning');
|
||||
row.insertCell().textContent = item.alias;
|
||||
row.insertCell().textContent = item.control_panel;
|
||||
row.insertCell().innerHTML = '<span class="status-yes">Yes</span>';
|
||||
row.insertCell().innerHTML = '<span class="status-no">No</span>';
|
||||
row.insertCell().textContent = item.equipment_type || 'N/A';
|
||||
row.insertCell().textContent = item.conveyor_type || 'N/A';
|
||||
});
|
||||
panelsContainer.appendChild(table);
|
||||
}
|
||||
});
|
||||
if (panelsWithConflicts === 0) {
|
||||
panelsContainer.innerHTML = '<p class="text-center fst-italic">No conflicts found across all panels.</p>';
|
||||
}
|
||||
}
|
||||
// Update total count badge
|
||||
const countBadge = document.getElementById('conflict-count');
|
||||
if (countBadge) {
|
||||
countBadge.textContent = totalConflicts;
|
||||
countBadge.style.display = totalConflicts > 0 ? 'inline-block' : 'none';
|
||||
}
|
||||
console.log("Finished Conflicts UI core redraw.");
|
||||
}
|
||||
|
||||
// --- Generic Panel Chart Update Logic ---
|
||||
function updatePanelCharts(panelsContainer, panelsData, chartInstances, context) { // context: 'scada' or 'drawing'
|
||||
const incomingPanelNames = new Set(Object.keys(panelsData).sort());
|
||||
const existingInstanceNames = new Set(Object.keys(chartInstances).filter(k => k !== 'overall'));
|
||||
|
||||
// --- Check if the context matches the currently visible section ---
|
||||
const isSectionVisible = (context === currentVisibleSection);
|
||||
if (!isSectionVisible) {
|
||||
// If section is not visible, destroy existing panel chart instances for this context
|
||||
console.log(`Destroying hidden panel charts for context: ${context}`);
|
||||
existingInstanceNames.forEach(panelName => {
|
||||
if (chartInstances[panelName]) {
|
||||
chartInstances[panelName].destroy();
|
||||
delete chartInstances[panelName];
|
||||
}
|
||||
});
|
||||
// Don't proceed further if the section is hidden
|
||||
return;
|
||||
}
|
||||
|
||||
if (incomingPanelNames.size > 0) {
|
||||
const loadingMsg = panelsContainer.querySelector('p');
|
||||
if (loadingMsg) { loadingMsg.remove(); }
|
||||
|
||||
incomingPanelNames.forEach(panelName => {
|
||||
const panel = panelsData[panelName];
|
||||
const panelTotal = (panel && panel.total) || 0;
|
||||
let panelChartCounts = [0, 0]; // Default to [0, 0]
|
||||
|
||||
if (panel) { // Only calculate if panel data exists
|
||||
if (context === 'scada') {
|
||||
panelChartCounts = [(panel.found_both || 0) + (panel.found_scada_only || 0), (panel.found_drawing_only || 0) + (panel.missing_both || 0)];
|
||||
} else { // drawing
|
||||
panelChartCounts = [(panel.found_both || 0) + (panel.found_drawing_only || 0), (panel.found_scada_only || 0) + (panel.missing_both || 0)];
|
||||
}
|
||||
}
|
||||
|
||||
// --- Only update/create chart if section is visible ---
|
||||
if (isSectionVisible) {
|
||||
if (chartInstances[panelName]) {
|
||||
if (JSON.stringify(chartInstances[panelName].data.datasets[0].data) !== JSON.stringify(panelChartCounts)) {
|
||||
chartInstances[panelName].data.datasets[0].data = panelChartCounts;
|
||||
chartInstances[panelName].update('none');
|
||||
}
|
||||
} else {
|
||||
let canvas = document.getElementById(`chart-${context}-${panelName}`); // Use context in ID
|
||||
if (canvas) {
|
||||
console.log(`Recreating ${context} chart instance for panel (visible): ${panelName}`);
|
||||
const ctx = canvas.getContext('2d');
|
||||
chartInstances[panelName] = new Chart(ctx, createChartConfig(panelChartCounts, panelTotal, context, panelName, selectedProjectName));
|
||||
} else {
|
||||
console.log(`Creating new ${context} panel elements and chart (visible) for: ${panelName}`);
|
||||
const chartContainer = document.createElement('div');
|
||||
chartContainer.id = `chart-container-${context}-${panelName}`; // Use context in ID
|
||||
chartContainer.className = 'chart-container';
|
||||
const label = document.createElement('span');
|
||||
label.className = 'chart-label'; label.textContent = panelName;
|
||||
canvas = document.createElement('canvas'); // Reassign canvas variable
|
||||
canvas.id = `chart-${context}-${panelName}`; // Use context in ID
|
||||
canvas.className = 'panel-chart-canvas';
|
||||
chartContainer.appendChild(label);
|
||||
chartContainer.appendChild(canvas);
|
||||
// Added Log before append
|
||||
console.log(`[updatePanelCharts] Appending chartContainer (${chartContainer.id}) to panelsContainer (${panelsContainer ? panelsContainer.id : 'null'})`);
|
||||
panelsContainer.appendChild(chartContainer); // Append to the main panels progress div
|
||||
const ctx = canvas.getContext('2d');
|
||||
chartInstances[panelName] = new Chart(ctx, createChartConfig(panelChartCounts, panelTotal, context, panelName, selectedProjectName));
|
||||
}
|
||||
}
|
||||
}
|
||||
// --- End visibility check ---
|
||||
});
|
||||
} else {
|
||||
if (!panelsContainer.querySelector('p')) {
|
||||
panelsContainer.innerHTML = '<p class="text-center fst-italic">No panel data available yet.</p>';
|
||||
}
|
||||
}
|
||||
|
||||
existingInstanceNames.forEach(panelName => {
|
||||
if (!incomingPanelNames.has(panelName)) {
|
||||
console.log(`Removing ${context} panel elements and chart for: ${panelName}`);
|
||||
// Ensure chart is destroyed before removing element
|
||||
if (chartInstances[panelName]) {
|
||||
chartInstances[panelName].destroy();
|
||||
delete chartInstances[panelName];
|
||||
}
|
||||
const chartElement = document.getElementById(`chart-container-${context}-${panelName}`); // Use context
|
||||
if (chartElement) {
|
||||
chartElement.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// --- Generic Helper to create chart config --- Needs PROJECT context ---
|
||||
function createChartConfig(chartCounts, total, context, identifier, projectName) { // Added projectName
|
||||
const labels = context === 'scada' ? scadaChartLabels : drawingChartLabels;
|
||||
const colors = context === 'scada' ? scadaChartColors : drawingChartColors;
|
||||
const datasetLabel = context === 'scada' ? 'SCADA Match' : 'Drawing Match';
|
||||
|
||||
// Retrieve the correct project's progress data for tooltip calculation
|
||||
const projectProgress = (currentProjectData[projectName] && currentProjectData[projectName].progress) ? currentProjectData[projectName].progress : {};
|
||||
|
||||
return {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: [{
|
||||
label: datasetLabel,
|
||||
data: chartCounts,
|
||||
backgroundColor: colors,
|
||||
hoverOffset: 4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
onClick: (event, elements, chart) => handleChartClick(event, elements, chart, context), // Pass context
|
||||
plugins: {
|
||||
legend: { display: false },
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(ctxTooltip) {
|
||||
let label = ctxTooltip.label || '';
|
||||
if (label) label += ': ';
|
||||
const value = ctxTooltip.parsed;
|
||||
if (value !== null) label += value;
|
||||
// Workaround: Use total passed to function for panel charts, access stored data for overall
|
||||
const chartTotal = (identifier === 'overall' && projectProgress.overall)
|
||||
? projectProgress.overall.total_csv
|
||||
: total; // Use the 'total' passed in for panel charts
|
||||
if (chartTotal && chartTotal > 0 && value !== null) { // Add null check for value
|
||||
label += ` (${((value / chartTotal) * 100).toFixed(1)}%)`;
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// --- Process Update: Extracts data for selected project ---
|
||||
function processUpdate(fullData) {
|
||||
console.log("SSE Received Full Data:", fullData); // Log the raw data
|
||||
|
||||
// Store the latest full data
|
||||
currentProjectData = {}; // Reset first
|
||||
fullData.projects.forEach(projName => {
|
||||
currentProjectData[projName] = {
|
||||
status: fullData.status ? fullData.status[projName] : 'Unknown',
|
||||
last_commit: fullData.last_commit ? fullData.last_commit[projName] : 'N/A',
|
||||
progress: fullData.progress ? fullData.progress[projName] : { overall: {}, panels: {} }
|
||||
};
|
||||
});
|
||||
|
||||
// Get current selection AFTER storing data
|
||||
selectedProjectName = document.getElementById('projectSelector').value;
|
||||
console.log(`Selected project: ${selectedProjectName}`);
|
||||
|
||||
if (!selectedProjectName || !currentProjectData[selectedProjectName]) {
|
||||
console.log("No project selected or no data for selected project. UI updates skipped.");
|
||||
// Optionally clear the UI or show a message
|
||||
updateStatusBar('N/A', 'No project selected or no data');
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract data for the selected project
|
||||
const projectData = currentProjectData[selectedProjectName];
|
||||
const currentCommit = projectData.last_commit;
|
||||
|
||||
// Update status bar immediately for the selected project
|
||||
updateStatusBar(selectedProjectName, projectData.status, projectData.last_commit);
|
||||
|
||||
// Check the processing state and update UI accordingly
|
||||
if (isProcessing(projectData.status)) {
|
||||
console.log(`Project ${selectedProjectName} is processing. Showing loading state.`);
|
||||
showProcessingStateUI(projectData);
|
||||
} else {
|
||||
console.log(`Project ${selectedProjectName} is ready/error. Showing final state.`);
|
||||
// TODO: Add check here if commit hash changed? Or just always update?
|
||||
// For now, always update the UI if the state is not 'processing'.
|
||||
showReadyStateUI(projectData);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Debounced version of the processing function ---
|
||||
const debouncedProcessUpdate = debounce(processUpdate, 250); // Single debouncer
|
||||
|
||||
// --- Modal Display Function (Needs PROJECT context) ---
|
||||
function showDetailsModal(projectName, identifier, categoryType, context) { // Added projectName
|
||||
let sourceData = null;
|
||||
let panelNameDisplay = "";
|
||||
const listKeysMap = context === 'scada' ? scadaListKeysMap : drawingListKeysMap;
|
||||
const listTypeLabel = categoryType === 'found'
|
||||
? (context === 'scada' ? 'Found in SCADA' : 'Found in Drawing')
|
||||
: (context === 'scada' ? 'Not Found in SCADA' : 'Not Found in Drawing');
|
||||
|
||||
// Get the specific project's progress data
|
||||
const projectProgress = (currentProjectData[projectName] && currentProjectData[projectName].progress) ? currentProjectData[projectName].progress : {};
|
||||
|
||||
if (identifier === '__overall__') {
|
||||
sourceData = projectProgress.overall || null;
|
||||
panelNameDisplay = `Overall (${projectName})`;
|
||||
} else {
|
||||
sourceData = (projectProgress.panels) ? projectProgress.panels[identifier] : null;
|
||||
panelNameDisplay = `${identifier} (${projectName})`;
|
||||
}
|
||||
|
||||
if (!sourceData) {
|
||||
console.error(`Could not find source data for modal. Project: ${projectName}, Identifier: ${identifier}, Context: ${context}`);
|
||||
alert("Error: Could not load details data.");
|
||||
return;
|
||||
}
|
||||
|
||||
const backendListKeys = listKeysMap[categoryType];
|
||||
if (!backendListKeys) { /* ... error handling ... */ return; }
|
||||
|
||||
let combinedDataList = [];
|
||||
backendListKeys.forEach(key => {
|
||||
if (sourceData[key]) {
|
||||
combinedDataList = combinedDataList.concat(sourceData[key]);
|
||||
}
|
||||
});
|
||||
|
||||
if (combinedDataList.length === 0) { /* ... alert handling ... */ return; }
|
||||
|
||||
const modalTitleElement = document.getElementById('detailsModalLabel');
|
||||
const modalTableBody = document.querySelector('#detailsModal .modal-body tbody');
|
||||
|
||||
modalTitleElement.innerHTML = `${listTypeLabel} Items for ${panelNameDisplay} <span class="badge bg-secondary ms-2">${combinedDataList.length}</span>`;
|
||||
modalTableBody.innerHTML = '';
|
||||
|
||||
combinedDataList.sort((a, b) => a.alias.localeCompare(b.alias)).forEach(item => {
|
||||
const row = document.createElement('tr');
|
||||
row.insertCell().textContent = item.alias;
|
||||
row.insertCell().textContent = item.control_panel;
|
||||
const scadaCell = row.insertCell(); scadaCell.innerHTML = item.found_scada ? '<span class="status-yes">Yes</span>' : '<span class="status-no">No</span>';
|
||||
const drawingCell = row.insertCell(); drawingCell.innerHTML = item.found_drawing ? '<span class="status-yes">Yes</span>' : '<span class="status-no">No</span>';
|
||||
row.insertCell().textContent = item.equipment_type || 'N/A';
|
||||
row.insertCell().textContent = item.conveyor_type || 'N/A';
|
||||
if (item.found_scada && !item.found_drawing) { row.classList.add('table-warning'); }
|
||||
modalTableBody.appendChild(row);
|
||||
});
|
||||
|
||||
if (!detailsModalInstance) {
|
||||
detailsModalInstance = new bootstrap.Modal(document.getElementById('detailsModal'));
|
||||
}
|
||||
detailsModalInstance.show();
|
||||
}
|
||||
|
||||
// --- Update Status Bar Helper ---
|
||||
function updateStatusBar(projectName, statusMsg, commitHash) {
|
||||
document.getElementById('selected-project-status-name').textContent = projectName || '...';
|
||||
document.getElementById('status-message').textContent = statusMsg || 'N/A';
|
||||
document.getElementById('last-commit').textContent = commitHash || 'N/A';
|
||||
}
|
||||
|
||||
// --- Navigation Handling ---
|
||||
function showSection(sectionId) {
|
||||
console.log("Showing section:", sectionId);
|
||||
document.getElementById('scada-content').style.display = 'none';
|
||||
document.getElementById('drawings-content').style.display = 'none';
|
||||
document.getElementById('conflicts-content').style.display = 'none';
|
||||
|
||||
const elementToShow = document.getElementById(`${sectionId}-content`);
|
||||
if (elementToShow) {
|
||||
elementToShow.style.display = 'block';
|
||||
currentVisibleSection = sectionId;
|
||||
|
||||
// --- Update content based on current project state ---
|
||||
const projectData = currentProjectData[selectedProjectName];
|
||||
if (projectData) {
|
||||
const statusMsg = projectData.status;
|
||||
console.log(`[ShowSection] Updating visible section ${sectionId} for project ${selectedProjectName}. Status: ${statusMsg}`);
|
||||
if (isProcessing(statusMsg)) {
|
||||
// Project is processing, ensure loading indicator is shown in the relevant containers for this section
|
||||
console.log(`[ShowSection] Project processing, showing loading indicator for ${sectionId}.`);
|
||||
if (sectionId === 'scada') {
|
||||
showLoadingIndicator(document.getElementById('overall-scada-progress'), statusMsg);
|
||||
showLoadingIndicator(document.getElementById('scada-panels-progress'), statusMsg);
|
||||
} else if (sectionId === 'drawings') {
|
||||
showLoadingIndicator(document.getElementById('overall-drawing-progress'), statusMsg);
|
||||
showLoadingIndicator(document.getElementById('drawing-panels-progress'), statusMsg);
|
||||
} else if (sectionId === 'conflicts') {
|
||||
showLoadingIndicator(document.getElementById('panels-conflicts'), statusMsg);
|
||||
}
|
||||
// Destroy any charts that might have been left over (belt and braces)
|
||||
if (sectionId === 'scada') {
|
||||
Object.values(chartInstancesScada).forEach(chart => chart?.destroy());
|
||||
chartInstancesScada = {};
|
||||
} else if (sectionId === 'drawings') {
|
||||
Object.values(chartInstancesDrawing).forEach(chart => chart?.destroy());
|
||||
chartInstancesDrawing = {};
|
||||
}
|
||||
} else {
|
||||
// Project is ready, trigger the specific update function for the visible section
|
||||
console.log(`[ShowSection] Project ready, calling update function for ${sectionId}.`);
|
||||
// Use setTimeout to ensure DOM update (display: block) is processed first
|
||||
setTimeout(() => {
|
||||
// Re-fetch projectData in case it changed slightly between checks
|
||||
const currentData = currentProjectData[selectedProjectName];
|
||||
if (currentData && !isProcessing(currentData.status)) { // Double check status
|
||||
if (sectionId === 'scada') {
|
||||
updateUIScadaCore(currentData);
|
||||
} else if (sectionId === 'drawings') {
|
||||
updateUIDrawingCore(currentData);
|
||||
} else if (sectionId === 'conflicts') {
|
||||
updateUIConflictsCore(currentData);
|
||||
}
|
||||
} else {
|
||||
console.log(`[ShowSection] Status changed to processing before UI update could run for ${sectionId}.`)
|
||||
// If it became processing again, show indicator
|
||||
showProcessingStateUI(currentData);
|
||||
}
|
||||
}, 0); // Delay slightly
|
||||
}
|
||||
} else {
|
||||
console.log(`[ShowSection] Section ${sectionId} shown, but no data currently available for project ${selectedProjectName}.`);
|
||||
// Show loading indicator in the visible section as data is missing
|
||||
const msg = "Loading data...";
|
||||
if (sectionId === 'scada') { showLoadingIndicator(document.getElementById('overall-scada-progress'), msg); showLoadingIndicator(document.getElementById('scada-panels-progress'), msg); }
|
||||
else if (sectionId === 'drawings') { showLoadingIndicator(document.getElementById('overall-drawing-progress'), msg); showLoadingIndicator(document.getElementById('drawing-panels-progress'), msg); }
|
||||
else if (sectionId === 'conflicts') { showLoadingIndicator(document.getElementById('panels-conflicts'), msg); }
|
||||
}
|
||||
// --- End section update trigger ---
|
||||
|
||||
} else {
|
||||
console.error("Attempted to show unknown section:", sectionId);
|
||||
document.getElementById('scada-content').style.display = 'block'; // Default back to SCADA
|
||||
currentVisibleSection = 'scada';
|
||||
}
|
||||
|
||||
// Update active nav link
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
link.classList.remove('active');
|
||||
// Match link's data-view attribute to sectionId
|
||||
if (link.getAttribute('data-view') === sectionId) {
|
||||
link.classList.add('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
console.log("DOM Loaded, setting up navigation and project selector...");
|
||||
|
||||
const projectSelector = document.getElementById('projectSelector');
|
||||
if(projectSelector) {
|
||||
// Set initial selection based on first option (or potentially embedded initial data)
|
||||
selectedProjectName = projectSelector.value;
|
||||
projectSelector.addEventListener('change', handleProjectChange);
|
||||
console.log(`Initial project selected: ${selectedProjectName}`);
|
||||
// Update initial status bar text
|
||||
const initialStatus = (initialServerData && initialServerData.status && initialServerData.status[selectedProjectName])
|
||||
? initialServerData.status[selectedProjectName]
|
||||
: 'Initializing...';
|
||||
updateStatusBar(selectedProjectName, initialStatus, 'N/A');
|
||||
}
|
||||
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
// Get the target section directly from the data-view attribute
|
||||
const targetSection = link.getAttribute('data-view');
|
||||
|
||||
if (targetSection) { // Ensure the attribute exists
|
||||
link.addEventListener('click', (event) => {
|
||||
event.preventDefault(); // Prevent page reload
|
||||
// Use the targetSection directly when calling showSection
|
||||
showSection(targetSection);
|
||||
});
|
||||
} else {
|
||||
console.warn("Nav link found without data-view attribute:", link);
|
||||
}
|
||||
});
|
||||
|
||||
// Show initial section (SCADA by default)
|
||||
showSection('scada');
|
||||
|
||||
setupAddProjectForm(); // Call the setup function for the new form
|
||||
});
|
||||
|
||||
// --- Connect to SSE stream (Single connection) ---
|
||||
console.log("Initializing SSE connection...");
|
||||
const eventSource = new EventSource("/stream");
|
||||
|
||||
eventSource.onmessage = function(event) {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
debouncedProcessUpdate(data); // Call the single debounced processor
|
||||
} catch (error) {
|
||||
console.error("Error parsing SSE data:", error);
|
||||
document.getElementById('status-message').textContent = 'Error processing update from server.';
|
||||
}
|
||||
};
|
||||
|
||||
eventSource.onerror = function(err) {
|
||||
console.error("EventSource failed:", err);
|
||||
document.getElementById('status-message').textContent = 'Connection to server lost. Retrying...';
|
||||
};
|
||||
|
||||
console.log("SSE handler set up.");
|
||||
|
||||
// --- Project Selector Change Handler ---
|
||||
function handleProjectChange() {
|
||||
selectedProjectName = document.getElementById('projectSelector').value;
|
||||
console.log(`Project selection changed to: ${selectedProjectName}`);
|
||||
|
||||
// Immediately update status bar for the selected project using stored data
|
||||
const projectData = currentProjectData[selectedProjectName];
|
||||
if (projectData) {
|
||||
console.log(`[Project Change] Data found for ${selectedProjectName}. Status: ${projectData.status}`);
|
||||
updateStatusBar(selectedProjectName, projectData.status, projectData.last_commit);
|
||||
|
||||
// Update UI based on the current state of the selected project
|
||||
if (isProcessing(projectData.status)) {
|
||||
showProcessingStateUI(projectData);
|
||||
} else {
|
||||
// Trigger a UI redraw using the stored data for the newly selected project
|
||||
console.log(`[Project Change] Triggering redraw for newly selected project: ${selectedProjectName}`);
|
||||
showReadyStateUI(projectData); // Use the new function
|
||||
}
|
||||
} else {
|
||||
// Handle case where data might not be available yet for the selected project
|
||||
const loadingStatus = 'Loading data...';
|
||||
console.log(`[Project Change] No data found yet for selected project: ${selectedProjectName}. Showing loading state.`);
|
||||
updateStatusBar(selectedProjectName, loadingStatus, 'N/A');
|
||||
// Show processing/loading indicators in all sections
|
||||
showProcessingStateUI(null); // Pass null to show generic loading message
|
||||
}
|
||||
}
|
||||
|
||||
// --- Initialize Add Project Form ---
|
||||
function setupAddProjectForm() {
|
||||
const form = document.getElementById('addProjectForm');
|
||||
const statusDiv = document.getElementById('addProjectStatus');
|
||||
const submitButton = form.querySelector('button[type="submit"]');
|
||||
|
||||
if (!form) {
|
||||
console.log("Add Project form not found on this page.");
|
||||
return; // Exit if the form isn't present
|
||||
}
|
||||
|
||||
form.addEventListener('submit', async (event) => {
|
||||
event.preventDefault(); // Prevent default HTML form submission
|
||||
statusDiv.style.display = 'none';
|
||||
statusDiv.textContent = '';
|
||||
statusDiv.className = 'mt-3 alert'; // Reset classes
|
||||
submitButton.disabled = true;
|
||||
statusDiv.classList.add('alert-info');
|
||||
statusDiv.textContent = 'Uploading project data...';
|
||||
statusDiv.style.display = 'block';
|
||||
|
||||
const formData = new FormData(form);
|
||||
const projectNameInput = document.getElementById('projectName');
|
||||
|
||||
// Basic validation for project name (allow letters, numbers, underscore, hyphen)
|
||||
const projectName = projectNameInput.value.trim();
|
||||
if (!/^[a-zA-Z0-9_-]+$/.test(projectName)) {
|
||||
statusDiv.classList.remove('alert-info');
|
||||
statusDiv.classList.add('alert-danger');
|
||||
statusDiv.textContent = 'Invalid Project Name. Use only letters, numbers, underscores, or hyphens.';
|
||||
statusDiv.style.display = 'block';
|
||||
submitButton.disabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Additional Client-Side Validation (Optional but recommended)
|
||||
const manifestFile = document.getElementById('manifestFile').files[0];
|
||||
const pdfFiles = document.getElementById('pdfFiles').files;
|
||||
|
||||
if (!manifestFile) {
|
||||
statusDiv.classList.remove('alert-info');
|
||||
statusDiv.classList.add('alert-danger');
|
||||
statusDiv.textContent = 'Manifest CSV file is required.';
|
||||
statusDiv.style.display = 'block';
|
||||
submitButton.disabled = false;
|
||||
return;
|
||||
}
|
||||
if (pdfFiles.length === 0) {
|
||||
statusDiv.classList.remove('alert-info');
|
||||
statusDiv.classList.add('alert-danger');
|
||||
statusDiv.textContent = 'At least one Drawing PDF file is required.';
|
||||
statusDiv.style.display = 'block';
|
||||
submitButton.disabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/add_project', {
|
||||
method: 'POST',
|
||||
body: formData // FormData handles multipart/form-data encoding
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
statusDiv.classList.remove('alert-info');
|
||||
if (response.ok && result.success) {
|
||||
statusDiv.classList.add('alert-success');
|
||||
statusDiv.textContent = result.message + ' Please restart the server for the new project to appear.';
|
||||
form.reset(); // Clear the form on success
|
||||
// Keep button disabled after successful submission
|
||||
} else {
|
||||
statusDiv.classList.add('alert-danger');
|
||||
statusDiv.textContent = 'Error: ' + (result.message || 'Unknown error occurred.');
|
||||
submitButton.disabled = false; // Re-enable button on error
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error submitting add project form:', error);
|
||||
statusDiv.classList.remove('alert-info');
|
||||
statusDiv.classList.add('alert-danger');
|
||||
statusDiv.textContent = 'Network error or server unavailable. Please try again.';
|
||||
submitButton.disabled = false; // Re-enable button on network error
|
||||
}
|
||||
statusDiv.style.display = 'block'; // Ensure status is visible
|
||||
});
|
||||
}
|
||||
@ -3,65 +3,49 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SCADA Progress Monitor</title>
|
||||
<title>Multi-Project Progress Monitor</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<style>
|
||||
body { padding: 20px; padding-bottom: 60px; /* Account for status bar */ }
|
||||
.progress-container, .chart-container {
|
||||
margin-bottom: 25px;
|
||||
text-align: center; /* Center chart labels */
|
||||
}
|
||||
.chart-label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
display: block;
|
||||
}
|
||||
.status-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: #f8f9fa;
|
||||
border-top: 1px solid #dee2e6;
|
||||
padding: 5px 15px;
|
||||
font-size: 0.9em;
|
||||
z-index: 1000;
|
||||
}
|
||||
/* Style for the overall progress bar - Removed as using Pie chart */
|
||||
|
||||
/* Style for panel charts */
|
||||
.panel-chart-canvas {
|
||||
max-width: 150px; /* Control pie chart size */
|
||||
max-height: 150px;
|
||||
margin: 0 auto; /* Center the canvas */
|
||||
cursor: pointer; /* Indicate clickable */
|
||||
}
|
||||
#scada-panels-progress, #drawing-panels-progress {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* Responsive grid */
|
||||
gap: 20px;
|
||||
}
|
||||
.modal-body table { width: 100%; }
|
||||
.modal-body th, .modal-body td { padding: 5px 10px; border-bottom: 1px solid #eee; vertical-align: middle; }
|
||||
.modal-body th { background-color: #f8f9fa; text-align: left; }
|
||||
.status-yes { color: green; font-weight: bold; }
|
||||
.status-no { color: red; font-weight: bold; }
|
||||
nav { margin-bottom: 20px; } /* Added for nav spacing */
|
||||
</style>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Added Navigation -->
|
||||
<nav class="nav nav-pills">
|
||||
<a class="nav-link active" aria-current="page" href="/">SCADA Progress</a>
|
||||
<a class="nav-link" href="/drawings">Drawing Progress</a>
|
||||
<a class="nav-link" href="/conflicts">Conflicts</a>
|
||||
<!-- Project Selector -->
|
||||
<div class="row mb-3 align-items-center">
|
||||
<div class="col-auto">
|
||||
<label for="projectSelector" class="col-form-label">Select Project:</label>
|
||||
</div>
|
||||
<div class="col">
|
||||
<select class="form-select" id="projectSelector">
|
||||
{% if projects %}
|
||||
{% for project in projects %}
|
||||
<option value="{{ project }}">{{ project }}</option>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<option value="" disabled>No projects found</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
</div>
|
||||
<!-- Add Project Button -->
|
||||
<div class="col-auto">
|
||||
<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#addProjectModal">
|
||||
Add Project
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Navigation between views (remains the same) -->
|
||||
<nav class="nav nav-pills mb-3" id="viewTabs">
|
||||
<a class="nav-link active" aria-current="page" href="#" data-view="scada">SCADA Progress</a>
|
||||
<a class="nav-link" href="#" data-view="drawings">Drawing Progress</a>
|
||||
<a class="nav-link" href="#" data-view="conflicts">Conflicts</a>
|
||||
</nav>
|
||||
|
||||
<!-- Dynamic Content Area -->
|
||||
<div id="project-content">
|
||||
<!-- SCADA Content Section -->
|
||||
<div id="scada-content">
|
||||
<h1 class="mb-4">SCADA Device Placement Progress</h1>
|
||||
<div id="scada-content" class="view-content">
|
||||
<h1 class="mb-4">SCADA Device Placement Progress (<span class="project-name-display"></span>)</h1>
|
||||
<p>Compares the Equipment Manifest against the SCADA view.json files.</p>
|
||||
|
||||
<div id="overall-scada-progress" class="chart-container">
|
||||
@ -79,8 +63,8 @@
|
||||
</div>
|
||||
|
||||
<!-- Drawing Content Section (Initially Hidden) -->
|
||||
<div id="drawings-content" style="display: none;">
|
||||
<h1 class="mb-4">Drawing Device Placement Progress</h1>
|
||||
<div id="drawings-content" class="view-content" style="display: none;">
|
||||
<h1 class="mb-4">Drawing Device Placement Progress (<span class="project-name-display"></span>)</h1>
|
||||
<p>Compares the Equipment Manifest against the extracted text from drawing files (.txt).</p>
|
||||
|
||||
<div id="overall-drawing-progress" class="chart-container">
|
||||
@ -98,23 +82,24 @@
|
||||
</div>
|
||||
|
||||
<!-- Conflicts Content Section (Initially Hidden) -->
|
||||
<div id="conflicts-content" style="display: none;">
|
||||
<h1 class="mb-4">SCADA/Drawing Conflicts <span id="conflict-count" class="badge bg-warning ms-2">0</span></h1>
|
||||
<div id="conflicts-content" class="view-content" style="display: none;">
|
||||
<h1 class="mb-4">SCADA/Drawing Conflicts (<span class="project-name-display"></span>) <span id="conflict-count" class="badge bg-warning ms-2">0</span></h1>
|
||||
<p>Items found in SCADA views but <strong>not</strong> found in the extracted drawing text files.</p>
|
||||
|
||||
<div id="panels-conflicts">
|
||||
<p>Loading conflict data...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- End project-content -->
|
||||
|
||||
</div>
|
||||
</div> <!-- End container -->
|
||||
|
||||
<!-- Status Bar -->
|
||||
<div class="status-bar">
|
||||
<span id="status-message">Initializing...</span> | Last Commit: <span id="last-commit">N/A</span>
|
||||
Status (<span id="selected-project-status-name">...</span>): <span id="status-message">Initializing...</span> | Last Commit: <span id="last-commit">N/A</span>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap Modal for Details -->
|
||||
<!-- Bootstrap Modal for Details (remains the same structure, content filled by JS) -->
|
||||
<div class="modal fade" id="detailsModal" tabindex="-1" aria-labelledby="detailsModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
@ -146,517 +131,53 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- NEW: Add Project Modal -->
|
||||
<div class="modal fade" id="addProjectModal" tabindex="-1" aria-labelledby="addProjectModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="addProjectModalLabel">Add New Project</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="addProjectForm" enctype="multipart/form-data">
|
||||
<div class="mb-3">
|
||||
<label for="projectName" class="form-label">Project Name</label>
|
||||
<input type="text" class="form-control" id="projectName" name="projectName" required>
|
||||
<div class="form-text">Use only letters, numbers, underscores, or hyphens.</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="repoUrl" class="form-label">Git Repository URL</label>
|
||||
<input type="url" class="form-control" id="repoUrl" name="repoUrl" required>
|
||||
<div class="form-text">The URL will be used for cloning after restart.</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="manifestFile" class="form-label">Manifest CSV File</label>
|
||||
<input class="form-control" type="file" id="manifestFile" name="manifestFile" accept=".csv" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="pdfFiles" class="form-label">Drawing PDF Files</label>
|
||||
<input class="form-control" type="file" id="pdfFiles" name="pdfFiles" accept=".pdf" multiple required>
|
||||
</div>
|
||||
<div id="addProjectStatus" class="mt-3" style="display: none;"></div>
|
||||
<button type="submit" class="btn btn-primary">Add Project & Prepare for Restart</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Add Project Modal -->
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<!-- Pass initial data to JavaScript -->
|
||||
<script>
|
||||
// --- Global State Variables ---
|
||||
let chartInstancesScada = {}; // Separate instances for SCADA
|
||||
let chartInstancesDrawing = {}; // Separate instances for Drawing
|
||||
let progressDetailsData = {}; // Stores the raw data from SSE (shared)
|
||||
let previousCommitHash = null; // Single hash for the whole page
|
||||
let detailsModalInstance = null;
|
||||
let currentVisibleSection = 'scada'; // Track visible section: 'scada', 'drawing', 'conflicts'
|
||||
|
||||
// --- Chart Configurations ---
|
||||
const scadaChartLabels = ['Found in SCADA', 'Not Found in SCADA'];
|
||||
const scadaChartColors = ['rgb(13, 110, 253)', 'rgb(220, 53, 69)'];
|
||||
const drawingChartLabels = ['Found in Drawing', 'Not Found in Drawing'];
|
||||
const drawingChartColors = ['rgb(25, 135, 84)', 'rgb(220, 53, 69)'];
|
||||
|
||||
// Map backend list keys for modal clicks (can be combined or kept separate if needed)
|
||||
const scadaListKeysMap = {
|
||||
found: ['found_both_list', 'found_scada_only_list'],
|
||||
notFound: ['found_drawing_only_list', 'missing_list']
|
||||
// Embed initial data directly into the page for faster initial load
|
||||
const initialServerData = {
|
||||
projects: {{ projects | tojson }},
|
||||
status: {{ initial_statuses | tojson }}
|
||||
// Note: Full progress data is not embedded initially, fetched via SSE
|
||||
};
|
||||
const drawingListKeysMap = {
|
||||
found: ['found_both_list', 'found_drawing_only_list'],
|
||||
notFound: ['found_scada_only_list', 'missing_list']
|
||||
};
|
||||
|
||||
// --- Debounce Utility (Only need one) ---
|
||||
function debounce(func, wait) {
|
||||
let timeout;
|
||||
return function executedFunction(...args) {
|
||||
const later = () => {
|
||||
clearTimeout(timeout);
|
||||
func(...args);
|
||||
};
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
}
|
||||
|
||||
// --- Chart Click Handler (Needs context: SCADA or Drawing?) ---
|
||||
function handleChartClick(event, elements, chart, context) { // Added context
|
||||
if (elements.length > 0) {
|
||||
const clickedElementIndex = elements[0].index;
|
||||
const isOverallChart = chart.canvas.id.startsWith('overall-'); // More robust check
|
||||
const identifier = isOverallChart ? '__overall__' : chart.canvas.id.replace(`chart-${context}-`, ''); // Use context
|
||||
const categoryType = clickedElementIndex === 0 ? 'found' : 'notFound';
|
||||
|
||||
showDetailsModal(identifier, categoryType, context); // Pass context to modal
|
||||
}
|
||||
}
|
||||
|
||||
// --- Core UI Update Functions (One for each section) ---
|
||||
|
||||
function updateUIScadaCore(data) {
|
||||
console.log("Running core SCADA UI redraw logic for commit:", data.last_commit);
|
||||
progressDetailsData = data.progress; // Update shared raw data
|
||||
|
||||
// --- Overall SCADA Chart ---
|
||||
const overallData = progressDetailsData.overall;
|
||||
const overallTotal = overallData.total_csv;
|
||||
const overallFoundScada = overallData.found_both + overallData.found_scada_only;
|
||||
const overallNotFoundScada = overallData.found_drawing_only + overallData.missing_both;
|
||||
const overallPercentageFound = overallTotal > 0 ? ((overallFoundScada / overallTotal) * 100).toFixed(1) : 0;
|
||||
const overallChartCounts = [overallFoundScada, overallNotFoundScada];
|
||||
|
||||
document.getElementById('overall-scada-text').textContent = `Found in SCADA: ${overallFoundScada}/${overallTotal} (${overallPercentageFound}%)`;
|
||||
|
||||
// --- Only update/create chart if section is visible ---
|
||||
const isSectionVisible = (currentVisibleSection === 'scada');
|
||||
if (isSectionVisible) {
|
||||
const overallScadaCanvas = document.getElementById('overall-scada-chart-canvas');
|
||||
if (chartInstancesScada['overall']) {
|
||||
if (JSON.stringify(chartInstancesScada['overall'].data.datasets[0].data) !== JSON.stringify(overallChartCounts)) {
|
||||
chartInstancesScada['overall'].data.datasets[0].data = overallChartCounts;
|
||||
chartInstancesScada['overall'].update('none');
|
||||
}
|
||||
} else if (overallScadaCanvas) {
|
||||
console.log("Creating overall SCADA chart (visible).");
|
||||
const ctxOverall = overallScadaCanvas.getContext('2d');
|
||||
chartInstancesScada['overall'] = new Chart(ctxOverall, createChartConfig(overallChartCounts, overallTotal, 'scada', 'overall'));
|
||||
}
|
||||
} else {
|
||||
// If section is not visible, destroy the chart instance if it exists
|
||||
if (chartInstancesScada['overall']) {
|
||||
console.log("Destroying hidden overall SCADA chart.");
|
||||
chartInstancesScada['overall'].destroy();
|
||||
delete chartInstancesScada['overall'];
|
||||
}
|
||||
}
|
||||
|
||||
// --- SCADA Panel Charts ---
|
||||
const panelsContainer = document.getElementById('scada-panels-progress');
|
||||
const panelsData = progressDetailsData.panels || {};
|
||||
updatePanelCharts(panelsContainer, panelsData, chartInstancesScada, 'scada');
|
||||
|
||||
console.log("Finished SCADA UI core redraw.");
|
||||
}
|
||||
|
||||
function updateUIDrawingCore(data) {
|
||||
console.log("Running core Drawing UI redraw logic for commit:", data.last_commit);
|
||||
progressDetailsData = data.progress; // Update shared raw data
|
||||
|
||||
// --- Overall Drawing Chart ---
|
||||
const overallData = progressDetailsData.overall;
|
||||
const overallTotal = overallData.total_csv;
|
||||
const overallFoundDrawing = overallData.found_both + overallData.found_drawing_only;
|
||||
const overallNotFoundDrawing = overallData.found_scada_only + overallData.missing_both;
|
||||
const overallPercentageFound = overallTotal > 0 ? ((overallFoundDrawing / overallTotal) * 100).toFixed(1) : 0;
|
||||
const overallChartCounts = [overallFoundDrawing, overallNotFoundDrawing];
|
||||
|
||||
document.getElementById('overall-drawing-text').textContent = `Found in Drawing: ${overallFoundDrawing}/${overallTotal} (${overallPercentageFound}%)`;
|
||||
|
||||
// --- Only update/create chart if section is visible ---
|
||||
const isSectionVisible = (currentVisibleSection === 'drawings');
|
||||
if (isSectionVisible) {
|
||||
const overallDrawingCanvas = document.getElementById('overall-drawing-chart-canvas');
|
||||
if (chartInstancesDrawing['overall']) {
|
||||
if (JSON.stringify(chartInstancesDrawing['overall'].data.datasets[0].data) !== JSON.stringify(overallChartCounts)) {
|
||||
chartInstancesDrawing['overall'].data.datasets[0].data = overallChartCounts;
|
||||
chartInstancesDrawing['overall'].update('none');
|
||||
}
|
||||
} else if (overallDrawingCanvas) {
|
||||
console.log("Creating overall drawing chart (visible).");
|
||||
const ctxOverall = overallDrawingCanvas.getContext('2d');
|
||||
chartInstancesDrawing['overall'] = new Chart(ctxOverall, createChartConfig(overallChartCounts, overallTotal, 'drawing', 'overall'));
|
||||
}
|
||||
} else {
|
||||
// If section is not visible, destroy the chart instance if it exists
|
||||
if (chartInstancesDrawing['overall']) {
|
||||
console.log("Destroying hidden overall Drawing chart.");
|
||||
chartInstancesDrawing['overall'].destroy();
|
||||
delete chartInstancesDrawing['overall'];
|
||||
}
|
||||
}
|
||||
|
||||
// --- Drawing Panel Charts (call updatePanelCharts, which also checks visibility/destroys) ---
|
||||
const panelsContainer = document.getElementById('drawing-panels-progress');
|
||||
const panelsData = progressDetailsData.panels || {};
|
||||
console.log(`[updateUIDrawingCore] Found drawing panels container:`, panelsContainer ? panelsContainer.id : 'Not Found'); // Added Log
|
||||
updatePanelCharts(panelsContainer, panelsData, chartInstancesDrawing, 'drawings'); // Changed context to plural 'drawings'
|
||||
|
||||
console.log("Finished Drawing UI core redraw.");
|
||||
}
|
||||
|
||||
function updateUIConflictsCore(data) {
|
||||
console.log("Running core Conflicts UI redraw logic for commit:", data.last_commit);
|
||||
progressDetailsData = data.progress; // Update shared raw data
|
||||
|
||||
const panelsContainer = document.getElementById('panels-conflicts');
|
||||
panelsContainer.innerHTML = ''; // Clear previous
|
||||
|
||||
const panelsData = progressDetailsData.panels;
|
||||
let totalConflicts = 0;
|
||||
let panelsWithConflicts = 0;
|
||||
|
||||
if (!panelsData || Object.keys(panelsData).length === 0) {
|
||||
panelsContainer.innerHTML = '<p class="text-center fst-italic">No panel data available yet.</p>';
|
||||
} else {
|
||||
const sortedPanels = Object.keys(panelsData).sort();
|
||||
sortedPanels.forEach(panelName => {
|
||||
const panel = panelsData[panelName];
|
||||
const conflictsList = panel.found_scada_only_list || [];
|
||||
if (conflictsList.length > 0) {
|
||||
panelsWithConflicts++;
|
||||
totalConflicts += conflictsList.length;
|
||||
// ... (Create header and table as in conflicts.html) ...
|
||||
const panelHeader = document.createElement('h4');
|
||||
panelHeader.className = 'mt-4 mb-2';
|
||||
panelHeader.textContent = `${panelName} (${conflictsList.length} conflicts)`;
|
||||
panelsContainer.appendChild(panelHeader);
|
||||
|
||||
const table = document.createElement('table');
|
||||
table.className = 'table table-sm table-striped table-hover table-bordered';
|
||||
const thead = table.createTHead();
|
||||
thead.innerHTML = `<tr><th>Alias</th><th>Panel</th><th>SCADA Status</th><th>Drawing Status</th><th>Equipment Type</th><th>Type of Conveyor</th></tr>`;
|
||||
const tbody = table.createTBody();
|
||||
conflictsList.sort((a, b) => a.alias.localeCompare(b.alias)).forEach(item => {
|
||||
const row = tbody.insertRow();
|
||||
row.classList.add('table-warning');
|
||||
row.insertCell().textContent = item.alias;
|
||||
row.insertCell().textContent = item.control_panel;
|
||||
row.insertCell().innerHTML = '<span class="status-yes">Yes</span>';
|
||||
row.insertCell().innerHTML = '<span class="status-no">No</span>';
|
||||
row.insertCell().textContent = item.equipment_type || 'N/A';
|
||||
row.insertCell().textContent = item.conveyor_type || 'N/A';
|
||||
});
|
||||
panelsContainer.appendChild(table);
|
||||
}
|
||||
});
|
||||
if (panelsWithConflicts === 0) {
|
||||
panelsContainer.innerHTML = '<p class="text-center fst-italic">No conflicts found across all panels.</p>';
|
||||
}
|
||||
}
|
||||
// Update total count badge
|
||||
const countBadge = document.getElementById('conflict-count');
|
||||
if (countBadge) {
|
||||
countBadge.textContent = totalConflicts;
|
||||
countBadge.style.display = totalConflicts > 0 ? 'inline-block' : 'none';
|
||||
}
|
||||
console.log("Finished Conflicts UI core redraw.");
|
||||
}
|
||||
|
||||
// --- Generic Panel Chart Update Logic ---
|
||||
function updatePanelCharts(panelsContainer, panelsData, chartInstances, context) { // context: 'scada' or 'drawing'
|
||||
const incomingPanelNames = new Set(Object.keys(panelsData).sort());
|
||||
const existingInstanceNames = new Set(Object.keys(chartInstances).filter(k => k !== 'overall'));
|
||||
|
||||
// --- Check if the context matches the currently visible section ---
|
||||
const isSectionVisible = (context === currentVisibleSection);
|
||||
if (!isSectionVisible) {
|
||||
// If section is not visible, destroy existing panel chart instances for this context
|
||||
console.log(`Destroying hidden panel charts for context: ${context}`);
|
||||
existingInstanceNames.forEach(panelName => {
|
||||
if (chartInstances[panelName]) {
|
||||
chartInstances[panelName].destroy();
|
||||
delete chartInstances[panelName];
|
||||
}
|
||||
});
|
||||
// Don't proceed further if the section is hidden
|
||||
return;
|
||||
}
|
||||
|
||||
if (incomingPanelNames.size > 0) {
|
||||
const loadingMsg = panelsContainer.querySelector('p');
|
||||
if (loadingMsg) { loadingMsg.remove(); }
|
||||
|
||||
incomingPanelNames.forEach(panelName => {
|
||||
const panel = panelsData[panelName];
|
||||
const panelTotal = panel.total;
|
||||
let panelChartCounts;
|
||||
if (context === 'scada') {
|
||||
panelChartCounts = [panel.found_both + panel.found_scada_only, panel.found_drawing_only + panel.missing_both];
|
||||
} else { // drawing
|
||||
panelChartCounts = [panel.found_both + panel.found_drawing_only, panel.found_scada_only + panel.missing_both];
|
||||
}
|
||||
|
||||
// --- Only update/create chart if section is visible ---
|
||||
if (isSectionVisible) {
|
||||
if (chartInstances[panelName]) {
|
||||
if (JSON.stringify(chartInstances[panelName].data.datasets[0].data) !== JSON.stringify(panelChartCounts)) {
|
||||
chartInstances[panelName].data.datasets[0].data = panelChartCounts;
|
||||
chartInstances[panelName].update('none');
|
||||
}
|
||||
} else {
|
||||
let canvas = document.getElementById(`chart-${context}-${panelName}`); // Use context in ID
|
||||
if (canvas) {
|
||||
console.log(`Recreating ${context} chart instance for panel (visible): ${panelName}`);
|
||||
const ctx = canvas.getContext('2d');
|
||||
chartInstances[panelName] = new Chart(ctx, createChartConfig(panelChartCounts, panelTotal, context, panelName));
|
||||
} else {
|
||||
console.log(`Creating new ${context} panel elements and chart (visible) for: ${panelName}`);
|
||||
const chartContainer = document.createElement('div');
|
||||
chartContainer.id = `chart-container-${context}-${panelName}`; // Use context in ID
|
||||
chartContainer.className = 'chart-container';
|
||||
const label = document.createElement('span');
|
||||
label.className = 'chart-label'; label.textContent = panelName;
|
||||
canvas = document.createElement('canvas'); // Reassign canvas variable
|
||||
canvas.id = `chart-${context}-${panelName}`; // Use context in ID
|
||||
canvas.className = 'panel-chart-canvas';
|
||||
chartContainer.appendChild(label);
|
||||
chartContainer.appendChild(canvas);
|
||||
// Added Log before append
|
||||
console.log(`[updatePanelCharts] Appending chartContainer (${chartContainer.id}) to panelsContainer (${panelsContainer ? panelsContainer.id : 'null'})`);
|
||||
panelsContainer.appendChild(chartContainer); // Append to the main panels progress div
|
||||
const ctx = canvas.getContext('2d');
|
||||
chartInstances[panelName] = new Chart(ctx, createChartConfig(panelChartCounts, panelTotal, context, panelName));
|
||||
}
|
||||
}
|
||||
}
|
||||
// --- End visibility check ---
|
||||
});
|
||||
} else {
|
||||
if (!panelsContainer.querySelector('p')) {
|
||||
panelsContainer.innerHTML = '<p class="text-center fst-italic">No panel data available yet.</p>';
|
||||
}
|
||||
}
|
||||
|
||||
existingInstanceNames.forEach(panelName => {
|
||||
if (!incomingPanelNames.has(panelName)) {
|
||||
console.log(`Removing ${context} panel elements and chart for: ${panelName}`);
|
||||
// Ensure chart is destroyed before removing element
|
||||
if (chartInstances[panelName]) {
|
||||
chartInstances[panelName].destroy();
|
||||
delete chartInstances[panelName];
|
||||
}
|
||||
const chartElement = document.getElementById(`chart-container-${context}-${panelName}`); // Use context
|
||||
if (chartElement) {
|
||||
chartElement.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// --- Generic Helper to create chart config --- Needs context ---
|
||||
function createChartConfig(chartCounts, total, context, identifier) { // identifier is 'overall' or panelName
|
||||
const labels = context === 'scada' ? scadaChartLabels : drawingChartLabels;
|
||||
const colors = context === 'scada' ? scadaChartColors : drawingChartColors;
|
||||
const datasetLabel = context === 'scada' ? 'SCADA Match' : 'Drawing Match';
|
||||
|
||||
return {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: [{
|
||||
label: datasetLabel,
|
||||
data: chartCounts,
|
||||
backgroundColor: colors,
|
||||
hoverOffset: 4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
onClick: (event, elements, chart) => handleChartClick(event, elements, chart, context), // Pass context
|
||||
plugins: {
|
||||
legend: { display: false },
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(ctxTooltip) {
|
||||
let label = ctxTooltip.label || '';
|
||||
if (label) label += ': ';
|
||||
const value = ctxTooltip.parsed;
|
||||
if (value !== null) label += value;
|
||||
// Use overallTotal for overall chart, panelTotal otherwise (How to get panelTotal here? Needs rethinking)
|
||||
// Workaround: Don't show percentage on panel tooltips for now
|
||||
const chartTotal = (identifier === 'overall' && progressDetailsData.overall) ? progressDetailsData.overall.total_csv : null;
|
||||
if (chartTotal && chartTotal > 0) {
|
||||
label += ` (${((value / chartTotal) * 100).toFixed(1)}%)`;
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// --- Wrapper function called by debouncer (Handles all sections) ---
|
||||
function processUpdate(data) {
|
||||
console.log("Processing update for commit:", data.last_commit);
|
||||
|
||||
// Always update status bar and commit hash text immediately
|
||||
document.getElementById('status-message').textContent = data.status;
|
||||
document.getElementById('last-commit').textContent = data.last_commit || 'N/A';
|
||||
|
||||
// *** Strict Check: Only proceed if commit hash has changed ***
|
||||
if (data.last_commit && data.last_commit !== previousCommitHash) {
|
||||
console.log("Commit hash changed (" + (previousCommitHash || 'None') + " -> " + data.last_commit + ") or initial load. Queueing core redraw.");
|
||||
previousCommitHash = data.last_commit;
|
||||
// Defer the core UI update calls
|
||||
setTimeout(() => {
|
||||
// Update all sections - they have internal checks/efficiency
|
||||
updateUIScadaCore(data);
|
||||
updateUIDrawingCore(data);
|
||||
updateUIConflictsCore(data);
|
||||
}, 0);
|
||||
} else {
|
||||
console.log("Commit hash unchanged (" + previousCommitHash + "), skipping core UI redraw.");
|
||||
}
|
||||
}
|
||||
|
||||
// --- Debounced version of the processing function ---
|
||||
const debouncedProcessUpdate = debounce(processUpdate, 250); // Single debouncer
|
||||
|
||||
// --- Modal Display Function (Needs context) ---
|
||||
function showDetailsModal(identifier, categoryType, context) { // Added context
|
||||
let sourceData = null;
|
||||
let panelNameDisplay = "";
|
||||
const listKeysMap = context === 'scada' ? scadaListKeysMap : drawingListKeysMap;
|
||||
const listTypeLabel = categoryType === 'found'
|
||||
? (context === 'scada' ? 'Found in SCADA' : 'Found in Drawing')
|
||||
: (context === 'scada' ? 'Not Found in SCADA' : 'Not Found in Drawing');
|
||||
|
||||
if (identifier === '__overall__') {
|
||||
sourceData = progressDetailsData.overall;
|
||||
panelNameDisplay = "Overall";
|
||||
} else {
|
||||
sourceData = progressDetailsData.panels ? progressDetailsData.panels[identifier] : null;
|
||||
panelNameDisplay = identifier;
|
||||
}
|
||||
|
||||
if (!sourceData) { /* ... error handling ... */ return; }
|
||||
|
||||
const backendListKeys = listKeysMap[categoryType];
|
||||
if (!backendListKeys) { /* ... error handling ... */ return; }
|
||||
|
||||
let combinedDataList = [];
|
||||
backendListKeys.forEach(key => {
|
||||
if (sourceData[key]) {
|
||||
combinedDataList = combinedDataList.concat(sourceData[key]);
|
||||
}
|
||||
});
|
||||
|
||||
if (combinedDataList.length === 0) { /* ... alert handling ... */ return; }
|
||||
|
||||
const modalTitleElement = document.getElementById('detailsModalLabel');
|
||||
const modalTableBody = document.querySelector('#detailsModal .modal-body tbody');
|
||||
|
||||
modalTitleElement.innerHTML = `${listTypeLabel} Items for ${panelNameDisplay} <span class="badge bg-secondary ms-2">${combinedDataList.length}</span>`;
|
||||
modalTableBody.innerHTML = '';
|
||||
|
||||
combinedDataList.sort((a, b) => a.alias.localeCompare(b.alias)).forEach(item => {
|
||||
const row = document.createElement('tr');
|
||||
row.insertCell().textContent = item.alias;
|
||||
row.insertCell().textContent = item.control_panel;
|
||||
const scadaCell = row.insertCell(); scadaCell.innerHTML = item.found_scada ? '<span class="status-yes">Yes</span>' : '<span class="status-no">No</span>';
|
||||
const drawingCell = row.insertCell(); drawingCell.innerHTML = item.found_drawing ? '<span class="status-yes">Yes</span>' : '<span class="status-no">No</span>';
|
||||
row.insertCell().textContent = item.equipment_type || 'N/A';
|
||||
row.insertCell().textContent = item.conveyor_type || 'N/A';
|
||||
if (item.found_scada && !item.found_drawing) { row.classList.add('table-warning'); }
|
||||
modalTableBody.appendChild(row);
|
||||
});
|
||||
|
||||
if (!detailsModalInstance) {
|
||||
detailsModalInstance = new bootstrap.Modal(document.getElementById('detailsModal'));
|
||||
}
|
||||
detailsModalInstance.show();
|
||||
}
|
||||
|
||||
// --- Navigation Handling ---
|
||||
function showSection(sectionId) {
|
||||
console.log("Showing section:", sectionId);
|
||||
document.getElementById('scada-content').style.display = 'none';
|
||||
document.getElementById('drawings-content').style.display = 'none';
|
||||
document.getElementById('conflicts-content').style.display = 'none';
|
||||
|
||||
const elementToShow = document.getElementById(`${sectionId}-content`);
|
||||
if (elementToShow) {
|
||||
elementToShow.style.display = 'block';
|
||||
currentVisibleSection = sectionId;
|
||||
|
||||
// --- Trigger update for the now-visible section ---
|
||||
// The update function will check visibility internally before drawing charts.
|
||||
if (progressDetailsData && Object.keys(progressDetailsData).length > 0) {
|
||||
const updateData = { progress: progressDetailsData }; // Pass existing data
|
||||
console.log(`Calling update function for now-visible section: ${sectionId}`);
|
||||
// Use setTimeout to ensure DOM update (display: block) is processed first
|
||||
if (sectionId === 'scada') {
|
||||
updateUIScadaCore(updateData);
|
||||
} else if (sectionId === 'drawings') {
|
||||
updateUIDrawingCore(updateData);
|
||||
} else if (sectionId === 'conflicts') {
|
||||
updateUIConflictsCore(updateData);
|
||||
}
|
||||
} else {
|
||||
console.log(`Section ${sectionId} shown, but no progress data yet.`);
|
||||
// If data arrives later, the debouncedProcessUpdate will handle drawing
|
||||
// for the currently visible section.
|
||||
}
|
||||
// --- End section update trigger ---
|
||||
|
||||
} else {
|
||||
console.error("Attempted to show unknown section:", sectionId);
|
||||
document.getElementById('scada-content').style.display = 'block'; // Default back to SCADA
|
||||
currentVisibleSection = 'scada';
|
||||
}
|
||||
|
||||
// Update active nav link
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
link.classList.remove('active');
|
||||
// Use href attribute to match sectionId
|
||||
const targetSection = link.getAttribute('data-target-section');
|
||||
if (targetSection === sectionId) {
|
||||
link.classList.add('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
console.log("DOM Loaded, setting up navigation...");
|
||||
document.querySelectorAll('.nav-link').forEach(link => {
|
||||
// Store target section ID in a data attribute from href
|
||||
const href = link.getAttribute('href');
|
||||
let targetSection = 'scada'; // Default
|
||||
if (href === '/drawings') targetSection = 'drawings'; // Use plural to match ID
|
||||
else if (href === '/conflicts') targetSection = 'conflicts'; // Use plural to match ID
|
||||
link.setAttribute('data-target-section', targetSection);
|
||||
|
||||
link.addEventListener('click', (event) => {
|
||||
event.preventDefault(); // Prevent page reload
|
||||
const sectionId = link.getAttribute('data-target-section');
|
||||
showSection(sectionId);
|
||||
});
|
||||
});
|
||||
|
||||
// Show initial section (SCADA by default)
|
||||
showSection('scada');
|
||||
});
|
||||
|
||||
// --- Connect to SSE stream (Single connection) ---
|
||||
console.log("Initializing SSE connection...");
|
||||
const eventSource = new EventSource("/stream");
|
||||
|
||||
eventSource.onmessage = function(event) {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
debouncedProcessUpdate(data); // Call the single debounced processor
|
||||
} catch (error) {
|
||||
console.error("Error parsing SSE data:", error);
|
||||
document.getElementById('status-message').textContent = 'Error processing update from server.';
|
||||
}
|
||||
};
|
||||
|
||||
eventSource.onerror = function(err) {
|
||||
console.error("EventSource failed:", err);
|
||||
document.getElementById('status-message').textContent = 'Connection to server lost. Retrying...';
|
||||
};
|
||||
|
||||
console.log("SSE handler set up.");
|
||||
|
||||
</script>
|
||||
<script src="/static/js/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
174
utils.py
Normal file
174
utils.py
Normal file
@ -0,0 +1,174 @@
|
||||
import os
|
||||
import re
|
||||
import glob # Import glob for finding CSV files
|
||||
import config
|
||||
# Need pypdf for text extraction
|
||||
from pypdf import PdfReader
|
||||
|
||||
def discover_projects():
|
||||
"""Discovers projects by listing subdirectories in the PROJECTS_ROOT_DIR."""
|
||||
projects = []
|
||||
if not os.path.exists(config.PROJECTS_ROOT_DIR):
|
||||
print(f"Warning: Projects root directory not found: {config.PROJECTS_ROOT_DIR}")
|
||||
return []
|
||||
|
||||
for item in os.listdir(config.PROJECTS_ROOT_DIR):
|
||||
item_path = os.path.join(config.PROJECTS_ROOT_DIR, item)
|
||||
if os.path.isdir(item_path):
|
||||
# Simple check: assume any directory is a project
|
||||
# More robust check could look for specific files/folders inside
|
||||
projects.append(item)
|
||||
print(f"Discovered projects: {projects}")
|
||||
return projects
|
||||
|
||||
def get_project_base_path(project_name):
|
||||
"""Returns the absolute path to a specific project's directory."""
|
||||
return os.path.join(config.PROJECTS_ROOT_DIR, project_name)
|
||||
|
||||
def get_repo_path(project_name):
|
||||
"""Returns the absolute path to the repository directory for a given project."""
|
||||
# Assume repo is always in a subdir named 'repo' within the project base
|
||||
return os.path.join(get_project_base_path(project_name), "repo")
|
||||
|
||||
def find_csv_path(project_name):
|
||||
"""Finds the first CSV file within the project's base directory."""
|
||||
project_base = get_project_base_path(project_name)
|
||||
csv_files = glob.glob(os.path.join(project_base, '*.csv'))
|
||||
if csv_files:
|
||||
if len(csv_files) > 1:
|
||||
print(f"Warning: Multiple CSV files found in {project_base}. Using the first one: {csv_files[0]}")
|
||||
return csv_files[0]
|
||||
else:
|
||||
print(f"Error: No CSV file found in project directory: {project_base}")
|
||||
return None
|
||||
|
||||
def get_views_dir_path(project_name):
|
||||
"""Returns the absolute path to the SCADA views directory within the project's repo."""
|
||||
repo_path = get_repo_path(project_name)
|
||||
# Dynamically find the SCADA data directory (e.g., 'MTN6_SCADA')
|
||||
scada_data_dir = None
|
||||
try:
|
||||
for item in os.listdir(repo_path):
|
||||
item_path = os.path.join(repo_path, item)
|
||||
# Simple check: find first directory ending with '_SCADA' (case-insensitive)
|
||||
if os.path.isdir(item_path) and item.upper().endswith('_SCADA'):
|
||||
scada_data_dir = item_path
|
||||
print(f"[{project_name}] Found SCADA data directory: {scada_data_dir}")
|
||||
break # Use the first one found
|
||||
except FileNotFoundError:
|
||||
print(f"Warning: Repo path not found for project '{project_name}' at '{repo_path}' when searching for SCADA dir.")
|
||||
# Fall through to return a potentially invalid path
|
||||
except Exception as e:
|
||||
print(f"Warning: Error searching for SCADA dir in '{repo_path}': {e}")
|
||||
# Fall through
|
||||
|
||||
if not scada_data_dir:
|
||||
print(f"Warning: Could not automatically find a *_SCADA directory in {repo_path}. Using fallback path structure.")
|
||||
# Fallback: Reconstruct a path assuming a fixed name (less ideal)
|
||||
# Or simply return None or let it fail? Returning the best guess path:
|
||||
scada_data_dir = os.path.join(repo_path, f"{project_name}_SCADA") # Guess the folder name
|
||||
|
||||
# Append the common relative path from config
|
||||
return os.path.join(scada_data_dir, config.VIEWS_DIR_RELATIVE)
|
||||
|
||||
def get_text_output_dir_path(project_name):
|
||||
"""Returns the absolute path to the extracted drawing text output directory for a project."""
|
||||
# Uses the relative folder name from config
|
||||
return os.path.join(get_project_base_path(project_name), config.TEXT_OUTPUT_FOLDER_RELATIVE)
|
||||
|
||||
def get_pdf_dir_path(project_name):
|
||||
"""Returns the absolute path to the source PDF directory for a project."""
|
||||
# ASSUMPTION: PDFs are stored in a 'pdfs' subdirectory within the project base path
|
||||
# Adjust 'pdfs' if the actual directory name is different.
|
||||
return os.path.join(get_project_base_path(project_name), 'pdfs')
|
||||
|
||||
def normalize(text):
|
||||
"""Normalize string for comparison: lowercase, treat '-' and '_' the same, remove all whitespace."""
|
||||
if not isinstance(text, str):
|
||||
return ""
|
||||
text = text.lower() # Convert to lowercase
|
||||
text = text.replace('-', '_') # Replace hyphens with underscores
|
||||
text = re.sub(r'\s+', '', text) # Remove ALL whitespace characters (including newlines)
|
||||
return text
|
||||
|
||||
def extract_text_from_pdf(pdf_path, txt_path):
|
||||
"""
|
||||
Extracts text from a single PDF file and saves it to a TXT file.
|
||||
Returns True on success (incl. writing empty file), False on failure.
|
||||
"""
|
||||
base_filename = os.path.basename(pdf_path)
|
||||
print(f" [Extractor] Attempting to process: {base_filename}")
|
||||
extracted_text = ""
|
||||
success = False # Track overall success
|
||||
reader = None # Initialize reader to None
|
||||
|
||||
try:
|
||||
# --- Step 1: Open and Decrypt (if necessary) ---
|
||||
try:
|
||||
print(f" [Extractor] Opening PDF: {base_filename}")
|
||||
reader = PdfReader(pdf_path)
|
||||
print(f" [Extractor] PDF opened successfully: {base_filename}")
|
||||
except Exception as open_err:
|
||||
print(f" [Extractor] CRITICAL ERROR opening PDF {base_filename}: {open_err}")
|
||||
# Log traceback for detailed debugging
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False # Cannot proceed
|
||||
|
||||
if reader.is_encrypted:
|
||||
print(f" [Extractor] PDF is encrypted: {base_filename}. Attempting decryption...")
|
||||
try:
|
||||
# Try decrypting with empty password - adjust if needed
|
||||
reader.decrypt('')
|
||||
print(f" [Extractor] Decryption successful (or not needed) for {base_filename}")
|
||||
except Exception as decrypt_err:
|
||||
print(f" [Extractor] WARNING: Could not decrypt PDF {base_filename}: {decrypt_err}. Skipping.")
|
||||
return False # Treat decryption failure as critical for this file
|
||||
|
||||
# --- Step 2: Extract Text Page by Page ---
|
||||
print(f" [Extractor] Starting page-by-page text extraction for: {base_filename} ({len(reader.pages)} pages)")
|
||||
page_texts = []
|
||||
for i, page in enumerate(reader.pages):
|
||||
try:
|
||||
# print(f" [Extractor] Extracting text from page {i+1}") # Can be verbose
|
||||
page_text = page.extract_text()
|
||||
if page_text:
|
||||
page_texts.append(page_text)
|
||||
# else: print(f" [Extractor] No text found on page {i+1}")
|
||||
except Exception as page_err:
|
||||
# Log page-specific errors but continue if possible
|
||||
print(f" [Extractor] WARNING: Error extracting text from page {i+1} in {base_filename}: {page_err}")
|
||||
# Decide if this is fatal for the file? For now, we continue.
|
||||
|
||||
extracted_text = "\n".join(page_texts)
|
||||
print(f" [Extractor] Finished text extraction for {base_filename}. Total chars extracted: {len(extracted_text)}")
|
||||
|
||||
# Handle case where no text is extracted - write empty file to prevent re-attempts
|
||||
if not extracted_text:
|
||||
print(f" [Extractor] WARNING: No text extracted from {base_filename}. An empty TXT file will be created.")
|
||||
|
||||
# --- Step 3: Write to TXT File ---
|
||||
print(f" [Extractor] Attempting to write TXT file: {os.path.basename(txt_path)}")
|
||||
try:
|
||||
with open(txt_path, 'w', encoding='utf-8') as txt_file:
|
||||
txt_file.write(extracted_text)
|
||||
print(f" [Extractor] Successfully wrote TXT file: {os.path.basename(txt_path)}")
|
||||
success = True # Mark as successful
|
||||
except Exception as write_err:
|
||||
print(f" [Extractor] ERROR writing text file {os.path.basename(txt_path)}: {write_err}")
|
||||
success = False # Failed to write
|
||||
|
||||
except FileNotFoundError:
|
||||
# This should technically be caught by the initial open_err block now
|
||||
print(f" [Extractor] ERROR: PDF file not found at {pdf_path}.")
|
||||
success = False
|
||||
except Exception as e:
|
||||
# Catch-all for unexpected errors during the process
|
||||
print(f" [Extractor] UNEXPECTED CRITICAL ERROR processing PDF {base_filename}: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
success = False
|
||||
# --- No finally block needed as we return directly ---
|
||||
|
||||
print(f" [Extractor] Finished processing {base_filename}. Result: {'Success' if success else 'Failure'}")
|
||||
return success
|
||||
Loading…
x
Reference in New Issue
Block a user