Created Project

This commit is contained in:
gigi.mamaladze 2025-12-06 19:16:58 +04:00
commit 40c46d6433
41 changed files with 14428 additions and 0 deletions

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,314 @@
import argparse
import re
import sys
from pathlib import Path
import pandas as pd
# ==== CONFIG YOU CAN TWEAK IF NEEDED ====
# IO rows matching these regex patterns will be ignored
SKIP_PATTERNS = [
r"^PDP.*_CB", # PDP*_CB* pattern
r"^PDP.*_FWM", # PDP*_FWM* pattern
r"^PDP.*_PWM", # PDP*_PWM* pattern
]
def canonical(tag: str) -> str:
"""
Apply all agreed normalization rules to a device/assigned tag.
"""
if not isinstance(tag, str):
return None
t = tag.strip()
if not t:
return None
# 1) EPC: keep up to ..._EPC<number>
# Examples:
# NCP1_3_EPC1_1 -> NCP1_3_EPC1
# NCP1_3_EPC2_99 -> NCP1_3_EPC2
m = re.search(r"(.*_EPC\d+)_.*", t)
if m:
t = m.group(1)
# 2) VFD variants -> base _VFD
# UL23_25_VFD_DISC -> UL23_25_VFD
# S02_1_VFD_STO1 -> S02_1_VFD
t = re.sub(r"_VFD_DISC$", "_VFD", t)
t = re.sub(r"_VFD_DSIC$", "_VFD", t)
t = re.sub(r"_VFD_STO\d*$", "_VFD", t)
# 3) SS buttons: SPB_LT / SPB / STPB -> base SS
# NCS2_12_SS2_SPB_LT -> NCS2_12_SS2
# NCR1_2_SS1_SPB -> NCR1_2_SS1
# NCR1_2_SS1_STPB -> NCR1_2_SS1
t = re.sub(r"_SPB_LT$", "", t)
t = re.sub(r"_STPB$", "", t)
t = re.sub(r"_SPB$", "", t)
# 4) Generic PB: PB_LT / PB -> base
# NCP1_3_JR1_PB -> NCP1_3_JR1
# NCP1_3_JR1_PB_LT -> NCP1_3_JR1
t = re.sub(r"_PB_LT$", "", t)
t = re.sub(r"_PB$", "", t)
# 5) STO suffix on SR tags -> base SR
# _SR1_STO1 -> _SR1
t = re.sub(r"(_SR\d+)_STO\d+$", r"\1", t)
# 6) R/S endings -> base
# S02_2_LRPE6_R -> S02_2_LRPE6
# S02_2_LRPE6_S -> S02_2_LRPE6
t = re.sub(r"_(R|S)$", "", t)
return t or None
def load_io_series(io_path: Path, io_column: str | None) -> pd.Series:
"""
Load IO Excel and return a cleaned Series of Assigned Device strings.
If io_column is None, uses the first column.
"""
df = pd.read_excel(io_path)
if io_column:
if io_column not in df.columns:
raise SystemExit(
f"ERROR: IO column '{io_column}' not found. Available: {list(df.columns)}"
)
series = df[io_column]
else:
# Use first column
first_col = df.columns[0]
series = df[first_col]
series = series.astype(str).str.strip()
# Drop SPARE rows
mask_spare = series.str.contains("SPARE", case=False, na=False)
# Drop rows matching SKIP_PATTERNS (e.g. PDP*_CB*, PDP*_FWM*)
mask_skip_pattern = False
for pattern in SKIP_PATTERNS:
mask_skip_pattern = mask_skip_pattern | series.str.match(pattern, na=False)
filtered = series[~(mask_spare | mask_skip_pattern)]
return filtered
def load_device_tags(dev_path: Path, dev_column: str | None) -> pd.Series:
"""
Load device Excel and return Series of device tags.
Default column is 'P_TAG1' if exists, else first column.
"""
df = pd.read_excel(dev_path)
if dev_column:
if dev_column not in df.columns:
raise SystemExit(
f"ERROR: Device column '{dev_column}' not found. Available: {list(df.columns)}"
)
series = df[dev_column]
else:
if "P_TAG1" in df.columns:
series = df["P_TAG1"]
else:
first_col = df.columns[0]
series = df[first_col]
return series.astype(str).str.strip()
def build_io_map(assigned_series: pd.Series) -> dict[str, set[str]]:
"""
Build mapping: canonical_tag -> set of raw IO assigned device strings.
"""
io_canon = assigned_series.map(canonical)
io_map: dict[str, set[str]] = {}
for raw, c in zip(assigned_series, io_canon):
if not c:
continue
io_map.setdefault(c, set()).add(raw)
return io_map
def detect_duplicate_assignments(assigned_series: pd.Series) -> pd.DataFrame:
"""
Return dataframe of raw IO assigned device strings that appear more than once.
This keeps PB/PB_LT, EPC variants, etc. separate and only flags exact duplicates.
"""
cleaned = assigned_series.dropna().str.strip()
cleaned = cleaned[cleaned != ""]
counts = cleaned.value_counts()
duplicates = counts[counts > 1]
if duplicates.empty:
return pd.DataFrame(columns=["Assigned_Device", "Occurrences"])
rows = []
for tag_value, occ in duplicates.items():
rows.append({"Assigned_Device": tag_value, "Occurrences": occ})
return pd.DataFrame(rows)
def find_io_without_devices(io_map: dict[str, set[str]], dev_canon: pd.Series) -> pd.DataFrame:
"""
Return dataframe of IO canonical tags that do not exist in the device list.
"""
dev_canon_set = set(dev_canon.dropna())
rows = []
for canon_tag, raw_values in sorted(io_map.items()):
if canon_tag not in dev_canon_set:
rows.append(
{
"Canonical_Tag": canon_tag,
"IO_Assigned_Devices": ", ".join(sorted(raw_values)),
"Occurrences": len(raw_values),
}
)
return pd.DataFrame(rows)
def compare(io_path: Path,
dev_path: Path,
out_path: Path,
io_column: str | None = None,
dev_column: str | None = None) -> None:
"""
Main compare routine: IO vs Devices, export Excel, print summary.
"""
print(f"IO file: {io_path}")
print(f"Devices file: {dev_path}")
print(f"Output file: {out_path}")
print("Loading data...")
assigned_series = load_io_series(io_path, io_column)
dev_tags = load_device_tags(dev_path, dev_column)
print(f"IO rows after filters: {len(assigned_series)}")
print(f"Device tags: {len(dev_tags)}")
io_map = build_io_map(assigned_series)
duplicate_df = detect_duplicate_assignments(assigned_series)
dev_canon = dev_tags.map(canonical)
io_only_df = find_io_without_devices(io_map, dev_canon)
present_flags: list[str] = []
matching_assigned: list[str] = []
for d_tag, d_c in zip(dev_tags, dev_canon):
if d_c in io_map:
present_flags.append("YES")
matching_assigned.append(", ".join(sorted(io_map[d_c])))
else:
present_flags.append("NO")
matching_assigned.append("")
res_df = pd.DataFrame({
"Device_Tag": dev_tags,
"Canonical_Tag_Used_For_Check": dev_canon,
"Present_In_IO": present_flags,
"Matching_IO_Assigned_Devices": matching_assigned,
})
# Save result (main sheet + duplicates if any)
out_path = out_path.with_suffix(".xlsx")
with pd.ExcelWriter(out_path, engine="openpyxl") as writer:
res_df.to_excel(writer, index=False, sheet_name="Devices_vs_IO")
if not duplicate_df.empty:
duplicate_df.to_excel(
writer, index=False, sheet_name="Duplicate_IO_Assignments"
)
if not io_only_df.empty:
io_only_df.to_excel(
writer, index=False, sheet_name="IO_Only_Assignments"
)
print(f"\nResult saved to: {out_path}")
# Summary
missing_df = res_df[res_df["Present_In_IO"] == "NO"]
total_devices = len(res_df)
missing_count = len(missing_df)
found_count = total_devices - missing_count
print("\n===== SUMMARY =====")
print(f"Total devices: {total_devices}")
print(f"Found in IO: {found_count}")
print(f"Missing: {missing_count}")
print(f"IO-only tags: {len(io_only_df)}")
if missing_count > 0:
print("\nDevices NOT found in IO (after all rules):")
for tag in sorted(missing_df["Device_Tag"].tolist()):
print(" -", tag)
if duplicate_df.empty:
print("\nDuplicate IO assignments: none detected.")
else:
print("\nDuplicate IO assignments detected (same raw value repeated):")
for _, row in duplicate_df.sort_values("Assigned_Device").iterrows():
print(
f" - {row['Assigned_Device']} ({row['Occurrences']} occurrences)"
)
if io_only_df.empty:
print("\nIO-only assignments: none detected.")
else:
print("\nIO-only assignments (no matching device tag):")
for _, row in io_only_df.iterrows():
print(
f" - {row['Canonical_Tag']} ({row['Occurrences']} occurrences): "
f"{row['IO_Assigned_Devices']}"
)
def main(argv=None):
parser = argparse.ArgumentParser(
description="Check that all devices from device list are present in IO file, "
"using EPC/VFD/PB/SS/R-S rules."
)
parser.add_argument("io_file", help="Input/Output Excel file (IO)")
parser.add_argument("devices_file", help="Devices Excel file")
parser.add_argument("output_file", help="Output Excel file path (will be .xlsx)")
parser.add_argument(
"--io-column",
help="Column name in IO file to use as Assigned Device (default: first column)",
default=None,
)
parser.add_argument(
"--dev-column",
help="Column name in devices file (default: P_TAG1 if exists, else first column)",
default=None,
)
args = parser.parse_args(argv)
io_path = Path(args.io_file)
dev_path = Path(args.devices_file)
out_path = Path(args.output_file)
if not io_path.is_file():
raise SystemExit(f"ERROR: IO file not found: {io_path}")
if not dev_path.is_file():
raise SystemExit(f"ERROR: Devices file not found: {dev_path}")
compare(
io_path=io_path,
dev_path=dev_path,
out_path=out_path,
io_column=args.io_column,
dev_column=args.dev_column,
)
if __name__ == "__main__":
main()

Binary file not shown.

Binary file not shown.

BIN
AutoCAD/DPM/OUTPUT.xlsx Normal file

Binary file not shown.

View File

@ -0,0 +1,310 @@
#!/usr/bin/env python
"""
Generate DPM network tables from a Summary sheet.
Usage:
python build_network_tables.py INPUT.xlsx OUTPUT.xlsx
python build_network_tables.py INPUT.xlsx OUTPUT.xlsx --net2 DPM1,DPM2,...
Examples:
python build_network_tables.py MCM08_Network.xlsx MCM08_Network_NET1_NET2.xlsx
python build_network_tables.py Amazon_CDW5_Bypass.xlsx Bypass_NET1_NET2.xlsx --net2 BYAD_6_DPM1,BYCD_14_DPM1,BYDB_6_DPM1
Requirements: pip install pandas openpyxl
"""
import argparse
import re
from itertools import groupby
import pandas as pd
from openpyxl import Workbook
from openpyxl.styles import PatternFill, Alignment, Border, Side, Font
# ---------- CONSTANTS YOU PROBABLY KEEP THE SAME ----------
SUMMARY_SHEET = "Summary" # name of sheet with DPM / P_TAG1 / HP
RING_BASE = "11.200.1." # ring IPs: 11.200.1.2, 11.200.1.3, ...
STAR_NET1_BASE = "11.200.1." # NET1 STAR base
STAR_NET2_BASE = "11.200.2." # NET2 STAR base
STAR_START = 20 # first STAR IP is *.20
# VFD HP -> part number
HP_TO_PN = {
"2HP": "35S-6D2-P101",
"3HP": "35S-6D3-P101",
"5HP": "35S-6D4-P111",
"7.5HP": "35S-6D5-P111",
"10HP": "35S-6D6-P111",
"30HP": "25B-D043N114"
}
# ---------- HELPERS ----------
def pick_column(colnames, candidates):
"""Pick first matching column name by case-insensitive list of options."""
cand_upper = [c.upper() for c in candidates]
for c in colnames:
if str(c).strip().upper() in cand_upper:
return c
return None
def dpm_sort_key(dpm):
"""Natural sort: prefix (letters/underscore) + list of all numbers."""
s = str(dpm).strip()
m = re.match(r"^([A-Za-z_]+)", s)
prefix = m.group(1) if m else ""
nums = [int(x) for x in re.findall(r"\d+", s)]
return prefix, nums
def device_sort_key(tag):
"""
Sort devices inside a DPM:
1) FIO Masters/hubs (FIOM/FIOH/FIO/MASTER) first
2) Then by numbers inside name
3) VFD before others among non-masters
"""
s = str(tag).strip()
u = s.upper()
is_master = ("FIOM" in u) or ("FIOH" in u) or ("FIO" in u) or ("MASTER" in u)
master_prio = 0 if is_master else 1
nums = [int(x) for x in re.findall(r"\d+", s)]
typ_match = re.search(r"_([A-Za-z]+)\d*$", s)
typ = typ_match.group(1).upper() if typ_match else ""
if typ == "VFD":
t_order = 0
elif typ in ("FIOM", "FIO", "FIOH"):
t_order = 1
else:
t_order = 2
return (master_prio, nums, t_order, typ, s)
def part_number_for(device_name, rating_map):
"""Return part number string for a device."""
if not isinstance(device_name, str):
return ""
u = device_name.upper()
if "SPARE" in u:
return ""
# FIO masters / hubs
if ("FIOM" in u) or ("FIO" in u) or ("FIOH" in u) or ("MASTER" in u):
return "Murr 54631"
hp = rating_map.get(device_name, "")
return HP_TO_PN.get(hp, "")
def build_assignments(df, col_dpm, col_tag, col_rating):
"""Build sorted DPM list, device assignments and rating map."""
df = df[~df[col_dpm].isna()].copy()
unique_dpms = sorted(
{str(x).strip() for x in df[col_dpm].tolist()},
key=dpm_sort_key,
)
assign = {dpm: [] for dpm in unique_dpms}
rating_map = {}
for _, row in df.iterrows():
dpm = str(row[col_dpm]).strip()
tag = (
str(row[col_tag]).strip()
if col_tag and not pd.isna(row[col_tag])
else None
)
rating = (
str(row[col_rating]).strip()
if col_rating and not pd.isna(row[col_rating])
else ""
)
if tag:
assign.setdefault(dpm, []).append(tag)
rating_map[tag] = rating
for dpm in assign:
assign[dpm] = sorted(assign[dpm], key=device_sort_key)
return unique_dpms, assign, rating_map
def generate_rows(unique_dpms, assign, rating_map, net2_dpms):
"""
Generate rows for NET1 and NET2.
Each row: (dpm, ring_ip, assigned_dev, part_num, star_ip, dpm_port)
"""
# ring IP per DPM
ring_ip_map = {}
ring_counter = 2
for dpm in unique_dpms:
ring_ip_map[dpm] = f"{RING_BASE}{ring_counter}"
ring_counter += 1
rows_net1 = []
rows_net2 = []
star1_counter = STAR_START
star2_counter = STAR_START
for dpm in unique_dpms:
ring_ip = ring_ip_map[dpm]
tags = assign.get(dpm, [])
tags = tags[:24] + ["SPARE"] * (24 - len(tags[:24]))
for idx, port in enumerate(range(5, 29)):
dev = tags[idx]
pn = part_number_for(dev, rating_map)
if dpm in net2_dpms:
star_ip = f"{STAR_NET2_BASE}{star2_counter}"
star2_counter += 1
rows_net2.append(
(dpm, ring_ip, dev, pn, star_ip, f"{dpm}_P{port}")
)
else:
star_ip = f"{STAR_NET1_BASE}{star1_counter}"
star1_counter += 1
rows_net1.append(
(dpm, ring_ip, dev, pn, star_ip, f"{dpm}_P{port}")
)
return rows_net1, rows_net2
def write_sheet(ws, rows, title):
"""Write one NET sheet with merged yellow bands, D..I layout."""
ws.title = title
headers = ["DPM", "IP", "Assigned Device", "Part Number", "IP", "DPM PORT"]
for col, h in enumerate(headers, start=4):
c = ws.cell(row=3, column=col, value=h)
c.font = Font(bold=True)
c.alignment = Alignment(horizontal="center", vertical="center")
c.border = Border(
left=Side(style="thin"),
right=Side(style="thin"),
top=Side(style="thin"),
bottom=Side(style="thin"),
)
yellow = PatternFill("solid", fgColor="FFC000")
thin = Side(style="thin", color="000000")
border = Border(left=thin, right=thin, top=thin, bottom=thin)
center = Alignment(horizontal="center", vertical="center")
left = Alignment(horizontal="left", vertical="center")
widths = {4: 18, 5: 16, 6: 30, 7: 18, 8: 16, 9: 22}
for col, w in widths.items():
ws.column_dimensions[chr(64 + col)].width = w
row_idx = 4
if not rows:
ws.freeze_panes = "D4"
return
for dpm, group in groupby(rows, key=lambda x: x[0]):
g = list(group)
# should already be 24 rows per DPM
g = g[:24]
start = row_idx
end = row_idx + 24 - 1
ws.merge_cells(start_row=start, start_column=4, end_row=end, end_column=4)
ws.merge_cells(start_row=start, start_column=5, end_row=end, end_column=5)
cD = ws.cell(row=start, column=4, value=g[0][0])
cE = ws.cell(row=start, column=5, value=g[0][1])
for cell in (cD, cE):
cell.fill = yellow
cell.alignment = center
cell.border = border
cell.font = Font(bold=False)
for i in range(24):
row_vals = {
6: g[i][2], # Assigned Device
7: g[i][3], # Part Number
8: g[i][4], # IP
9: g[i][5], # DPM PORT
}
for col, val in row_vals.items():
c = ws.cell(row=start + i, column=col, value=val)
c.alignment = left if col in (6, 7, 9) else center
c.border = border
for r in range(start + 1, end + 1):
for col in (4, 5):
c = ws.cell(row=r, column=col)
c.fill = yellow
c.border = border
row_idx = end + 1
ws.freeze_panes = "D4"
def main():
parser = argparse.ArgumentParser(description="Build DPM network tables.")
parser.add_argument("input_file", help="Input Excel file (with Summary sheet)")
parser.add_argument("output_file", help="Output Excel file")
parser.add_argument(
"--net2",
help="Comma-separated list of DPM names that should go to NET2 (.2 subnet)",
default="",
)
args = parser.parse_args()
net2_dpms = {
x.strip()
for x in args.net2.split(",")
if x.strip()
}
# Load Summary
df = pd.read_excel(args.input_file, sheet_name=SUMMARY_SHEET)
df.columns = [str(c).strip() for c in df.columns]
col_dpm = pick_column(df.columns, ["DPM"])
col_tag = pick_column(df.columns, ["P_TAG1", "P TAG1", "ASSIGNED DEVICE"])
col_rating = pick_column(df.columns, ["RATING", "HP", "POWER", "RATED"])
if not col_dpm or not col_tag:
raise RuntimeError(
f"Could not find DPM or P_TAG1/Assigned Device columns in sheet '{SUMMARY_SHEET}'"
)
unique_dpms, assign, rating_map = build_assignments(
df, col_dpm, col_tag, col_rating
)
rows_net1, rows_net2 = generate_rows(unique_dpms, assign, rating_map, net2_dpms)
# Build workbook
wb = Workbook()
ws1 = wb.active
write_sheet(ws1, rows_net1, "NET1 STRUCTURE")
ws2 = wb.create_sheet()
write_sheet(ws2, rows_net2, "NET2 STRUCTURE")
wb.save(args.output_file)
print(f"Saved: {args.output_file}")
if __name__ == "__main__":
main()

BIN
AutoCAD/DPM/~$OUTPUT.xlsx Normal file

Binary file not shown.

BIN
AutoCAD/IO/IOrrrr.xlsx Normal file

Binary file not shown.

BIN
AutoCAD/IO/MCM_IO.xlsx Normal file

Binary file not shown.

View File

@ -0,0 +1,186 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# (script content truncated in preview; full content below)
import argparse, re
from pathlib import Path
from typing import List, Dict
import pandas as pd
ORDER_VFD = ["I0","I1","I2","I3","IO0","IO1","SI0","SI1","SI2","SI3","SO0"]
ORDER_FIOM = [f"X{i}_{j}" for i in [3,2,1,0,7,6,5,4] for j in (0,1)]
ORDER_FIOH = [f"C{i}_{j}" for i in [7,5,3,1,8,6,4,2] for j in ("A","B")]
def load_canon(paths: List[Path]) -> Dict[str, str]:
canon = {}
for p in paths:
if not p or not Path(p).exists():
continue
c = pd.read_excel(p, dtype=str).rename(columns=lambda x: str(x).strip())
cols = [col for col in c.columns if col.lower() in ("assigned device","assigned_device","device","name")]
descs = [col for col in c.columns if col.lower() in ("description","desc")]
if not cols or not descs:
continue
c = c[[cols[0], descs[0]]].dropna()
c[cols[0]] = c[cols[0]].astype(str).str.strip().str.upper()
c[descs[0]] = c[descs[0]].astype(str).str.strip().str.upper()
canon.update(dict(zip(c[cols[0]], c[descs[0]])))
return canon
def strip_digits(tok: str) -> str:
if tok.startswith(("EPC","FPE")):
return tok
import re as _re
return _re.sub(r'\d+$','', tok)
def family_keys(dev: str):
s = dev.strip().upper()
parts = [p for p in s.split("_") if p]
if not parts: return []
head = "PDP" if s.startswith("PDP") else "CONV"
keys = []
if len(parts) >= 3:
t2, t1 = parts[-2], parts[-1]
t1s = t1 if t1.startswith(("EPC","FPE")) else strip_digits(t1)
keys += [f"{head}_{t2}_{t1}", f"{head}_{t2}_{t1s}"]
import re as _re
last = parts[-1]
if _re.fullmatch(r"(DISC|DSIC|TPE\d*|JPE\d*|ENW\d*|ENSH\d*|PRX1?|PX1|LRPE\d*|TS\d*|BDS\d*|EPC\d+|FPE\d+|CB\d+|PWM\d+|FIOH1|STO1)", last):
keys += [f"{head}_{last}", last]
if "BCN" in s:
if s.endswith("_A"): keys.append("CONV_BCN_A")
elif s.endswith("_R"): keys.append("CONV_BCN_R")
elif s.endswith("_G"): keys.append("CONV_BCN_G")
elif s.endswith("_B"): keys.append("CONV_BCN_B")
elif s.endswith("_W"): keys.append("CONV_BCN_W")
elif s.endswith("_H"): keys.append("CONV_BCN_H")
else: keys.append("CONV_BCN")
seen=set(); out=[]
for k in keys:
if k and k not in seen:
seen.add(k); out.append(k)
return out
def fallback_desc(dev: str) -> str:
import re as _re
d = dev.upper()
if d == "SPARE": return ""
if "VFD" in d and ("DISC" in d or "DSIC" in d): return "DISCONNECT AUX"
if _re.search(r"_TPE\d+|^TPE\d+", d): return "TRACKING PHOTOEYE"
if _re.search(r"_JPE\d+|^JPE\d+", d): return "JAM PHOTOEYE"
if _re.search(r"_EPC\d+|^EPC\d+", d): return "E-STOP PULLCORD"
if "ENSH" in d: return "SHAFT ENCODER"
if "ENW" in d: return "WHEEL ENCODER"
if "LRPE" in d and "_R" in d: return "LONG RANGE PHOTOEYE RCV"
if "LRPE" in d and "_S" in d: return "LONG RANGE PHOTOEYE SND"
if "LRPE" in d: return "LONG RANGE PHOTOEYE"
if any(x in d for x in ["PX1","PRX","PRX1"]): return "PROXIMITY SENSOR"
if any(x in d for x in ["_SOL","_SOV","_SV","_SOLV"]): return "SOLENOID VALVE"
if _re.search(r"_FIOH\d+|^FIOH\d+", d): return "I/O LINK HUB"
if "BCN" in d:
if d.endswith("_A"): return "AMBER BEACON LIGHT"
if d.endswith("_R"): return "RED BEACON LIGHT"
if d.endswith("_G"): return "GREEN BEACON LIGHT"
if d.endswith("_B"): return "BLUE BEACON LIGHT"
if d.endswith("_W"): return "WHITE BEACON LIGHT"
if d.endswith("_H"): return "HORN BEACON"
return "BEACON LIGHT"
if d.endswith("_FPE1"): return "FULL PHOTOEYE 100%"
if d.endswith("_FPE2"): return "FULL PHOTOEYE 50%"
if _re.search(r"_PS\d+$", d): return "PRESSURE SENSOR"
if _re.search(r"_BDS\d+_R$", d): return "BELT DISENGAGEMENT SENSOR RCV"
if _re.search(r"_BDS\d+_S$", d): return "BELT DISENGAGEMENT SENSOR SND"
if _re.search(r"_TS\d+_R$", d): return "TRASH SENSOR RCV"
if _re.search(r"_TS\d+_S$", d): return "TRASH SENSOR SND"
if "STO1" in d: return "SAFETY TORQUE OFF"
if d.startswith("PDP") and "_CB" in d: return "CIRCUIT BREAKER MONITORING"
if d.startswith("PDP") and "_PWM" in d: return "PHASE MONITOR"
return "DEVICE"
def desc_for(dev: str, canon: dict) -> str:
s = str(dev).strip().upper()
if not s: return ""
if s in canon: return canon[s]
for k in family_keys(s):
if k in canon: return canon[k]
return fallback_desc(s)
def choose_order(controller_name: str, available_columns):
s = str(controller_name).upper()
if "VFD" in s:
return [c for c in ORDER_VFD if c in available_columns]
if "FIOM" in s:
return [c for c in ORDER_FIOM if c in available_columns]
if "FIOH" in s:
return [c for c in ORDER_FIOH if c in available_columns]
return [c for c in available_columns if c in set(ORDER_FIOM+ORDER_FIOH+ORDER_VFD)]
def priority_for_controller(controller_name: str) -> int:
s = str(controller_name).upper()
if s.startswith("PDP") and "FIOM" in s: return 0
if s.startswith("PDP") and "FIOH" in s: return 1
return 2
def main():
import pandas as pd
import argparse, re
from pathlib import Path
ap = argparse.ArgumentParser(description="Build 5-column IO mapping Excel from source workbook.")
ap.add_argument("input", help="Input Excel workbook.")
ap.add_argument("output", help="Output Excel path.")
ap.add_argument("--sheet", default="Summary", help="Sheet to read (default Summary; falls back to first sheet).")
ap.add_argument("--canon", nargs="*", default=[], help="Optional canon Excel(s) with Assigned device/Description columns.")
args = ap.parse_args()
inp = Path(args.input)
xls = pd.ExcelFile(inp)
sheet = args.sheet if args.sheet in xls.sheet_names else xls.sheet_names[0]
df = pd.read_excel(inp, sheet_name=sheet, dtype=str).rename(columns=lambda c: str(c).strip())
if "P_TAG1" not in df.columns:
raise SystemExit("P_TAG1 column not found in the selected sheet.")
sig_cols_available = [c for c in df.columns if re.fullmatch(r"(I0|I1|I2|I3|IO0|IO1|SI0|SI1|SI2|SI3|SO0|X[0-7]_[01]|C[1-8]_[AB])", c)]
canon_map = load_canon([Path(p) for p in args.canon])
rows = []
for _, r in df.iterrows():
ctrl = str(r.get("P_TAG1","")).strip()
if not ctrl:
continue
order = choose_order(ctrl, sig_cols_available)
for sig in order:
val = r.get(sig)
dev = (str(val).strip() if pd.notna(val) else "")
if dev == "":
dev = "SPARE"
addr = f"{ctrl}_{sig}"
desc = "" if dev.upper()=="SPARE" else desc_for(dev, canon_map)
dU = dev.upper()
if re.search(r'_ESTOP1$', dU): desc = "ESTOP OK"
elif re.search(r'_SS\d+_SPB_LT$', dU): desc = "SS STATION START PUSHBUTTON LIGHT"
elif re.search(r'_SS\d+_SPB$', dU): desc = "SS STATION START PUSHBUTTON"
elif re.search(r'_SS\d+_STPB$', dU): desc = "SS STATION STOP PUSHBUTTON"
elif re.search(r'_S\d+_PB_LT$', dU): desc = "START PUSHBUTTON LIGHT"
elif re.search(r'_S\d+_PB$', dU): desc = "START PUSHBUTTON"
elif re.search(r'_JR\d+_PB_LT$', dU): desc = "JAM RESET PUSHBUTTON LIGHT"
elif re.search(r'_JR\d+_PB$', dU): desc = "JAM RESET PUSHBUTTON"
elif re.search(r'_EN\d*_PB_LT$', dU): desc = "ENABLE PUSHBUTTON LIGHT"
elif re.search(r'_EN\d*_PB$', dU): desc = "ENABLE PUSHBUTTON"
rows.append({
"Controller name": ctrl,
"Signal type": sig,
"Address name": addr,
"Assigned device": dev,
"Description": desc
})
out = pd.DataFrame(rows)
out["_p"] = out["Controller name"].map(priority_for_controller)
out = out.sort_values(["_p","Controller name"], kind="mergesort").drop(columns=["_p"]).reset_index(drop=True)
out.to_excel(Path(args.output), index=False)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,26 @@
import pandas as pd
df1 = pd.read_excel('output.xlsx')
df2 = pd.read_excel('Amazon CDW5_Devices IO.xlsx')
print('=== Sample comparisons ===')
dev_rows = df1[df1['Description'].str.upper() == 'DEVICE'].head(20)
for idx, row in dev_rows.iterrows():
src = df2[(df2['Controller name'] == row['Controller name']) &
(df2['Signal type'] == row['Signal type']) &
(df2['Assigned device'] == row['Assigned device'])]
if not src.empty:
print(f"Device: {row['Assigned device']}")
print(f" Output desc: {row['Description']}")
print(f" Source desc: {src.iloc[0]['Description']}")
print()
else:
# Try partial match
src = df2[(df2['Assigned device'] == row['Assigned device'])]
if not src.empty:
print(f"Device: {row['Assigned device']}")
print(f" Output desc: {row['Description']}")
print(f" Source desc (found by device only): {src.iloc[0]['Description']}")
print()

View File

@ -0,0 +1,410 @@
(defun clearDrawing ( / ss)
(setq ss (ssget "_X" '((0 . "*"))))
(if ss (command "_.erase" ss ""))
(princ "\nDrawing cleared.")
)
(defun getVisibilityFromName (deviceName partNumber)
(cond
((wcmatch (strcase deviceName) "*APF*") "APF")
((and (wcmatch (strcase deviceName) "*VFD*")
partNumber
(wcmatch (strcase partNumber) "35S*")) "APF")
((wcmatch (strcase deviceName) "*VFD*") "VFD")
((wcmatch (strcase deviceName) "*SIO*") "SIO")
((wcmatch (strcase deviceName) "*FIO*") "FIO")
((wcmatch (strcase deviceName) "*SPARE*") "")
(T "DEFAULT")
)
)
(defun str-trim (s)
(vl-string-trim " \t\n\r" s)
)
(defun setDeviceAttributes (blk ip device port / tag2 tag3 isVFD spacePos slashPos baseName part2 tag ip1 ip2 spacePosIP)
(setq tag2 device)
(setq tag3 "")
(setq ip1 ip)
(setq ip2 "")
;; === VFD logic ===
(if (and device (vl-string-search "VFD" (strcase device)))
(progn
(setq spacePos (vl-string-search " " device))
(if spacePos
(progn
(setq part1 (substr device 1 spacePos))
(setq part2 (substr device (+ spacePos 2)))
(setq slashPos (vl-string-search "/VFD" part1))
(if slashPos
(setq baseName (substr part1 1 slashPos))
(setq baseName part1)
)
(setq tag2 (str-trim part1))
(setq tag3 (strcat (str-trim baseName) "/" (str-trim part2)))
)
)
)
)
;; === IP splitting ===
(setq spacePosIP (vl-string-search " " ip))
(if spacePosIP
(progn
(setq ip1 (str-trim (substr ip 1 spacePosIP)))
(setq ip2 (str-trim (substr ip (+ spacePosIP 2))))
)
)
(foreach att (vlax-invoke blk 'GetAttributes)
(setq tag (strcase (vla-get-tagstring att)))
(cond
((= tag "IP") (vla-put-textstring att ip1))
((= tag "IP2") (vla-put-textstring att ip2))
((= tag "TAG2") (vla-put-textstring att tag2))
((= tag "PORT") (vla-put-textstring att port))
((= tag "TAG3") (if (> (strlen tag3) 0) (vla-put-textstring att tag3)))
)
)
)
(defun place-enet-devices (originX originY deviceGroup / blockName width count i x y basePt lastEnt targetPt blk visibilityValue deviceName device ip fullBlockName port)
(setq blockName "HDV2_ENET_DEVICE_")
(setq width 1.2)
(setq count (length deviceGroup))
(setq i 0)
(setq y 20.4718)
(while (< i count)
(setq blockSpacing 1.2)
(setq groupWidth (* blockSpacing (1- count)))
(setq centerX 21.2)
(setq startX (- centerX (/ groupWidth 2.0)))
(setq x (+ startX (* i blockSpacing) 0.3))
(setq basePt '(0 0 0))
(setq targetPt (list (+ originX x) (+ originY y) 0))
(setq devicePair (nth i deviceGroup))
(setq device (cdr (assoc "NAME" devicePair)))
(setq ip (cdr (assoc "IP" devicePair)))
(setq port (cdr (assoc "PORT" devicePair)))
(setq partNumber (cdr (assoc "PARTNUM" devicePair)))
(setq deviceName (getVisibilityFromName device partNumber))
(setq fullBlockName (strcat blockName deviceName))
(command "_.-INSERT" fullBlockName basePt 0.8 0.8 0.8 0)
(if (setq lastEnt (entlast))
(progn
(setq blk (vlax-ename->vla-object lastEnt))
(vla-move blk
(vlax-3d-point basePt)
(vlax-3d-point targetPt)
)
(vla-put-rotation blk 0.0)
(setDeviceAttributes blk ip device port)
)
(princ "\nFailed to get last entity.")
)
(setq i (1+ i))
)
)
(defun labelZone32Lines (ent / vlaBlock att basePt labelPt labelStr height index rotation)
(if (and ent (eq (cdr (assoc 0 (entget ent))) "INSERT"))
(progn
(setq vlaBlock (vlax-ename->vla-object ent))
(setq index 1)
(foreach att (vlax-invoke vlaBlock 'GetAttributes)
(if (wcmatch (strcase (vla-get-tagstring att)) "LINE*")
(progn
(setq labelStr (if (< index 10) (strcat "0" (itoa index)) (itoa index)))
(setq basePt (vlax-get att 'InsertionPoint))
(setq height (vla-get-height att))
(setq rotation (vla-get-rotation att))
(setq labelPt
(list (- (car basePt) 0.05)
(+ (cadr basePt) 0.65)
(caddr basePt)))
(entmake
(list
(cons 0 "TEXT")
(cons 8 "0")
(cons 7 "WD")
(cons 62 7)
(cons 10 labelPt)
(cons 11 labelPt)
(cons 40 height)
(cons 72 1)
(cons 73 2)
(cons 1 labelStr)
(cons 50 rotation)
(cons 100 "AcDbEntity")
(cons 100 "AcDbText")
)
)
(setq index (1+ index))
)
)
)
)
(princ "\nInvalid entity passed to labelZone32Lines.")
)
(princ)
)
(defun setLayoutWireNumbers (layoutEnt zoneNumber layoutIndex / vlaBlock att tag wireNumber cblIndex layoutNum)
(if (and layoutEnt (eq (cdr (assoc 0 (entget layoutEnt))) "INSERT"))
(progn
(setq vlaBlock (vlax-ename->vla-object layoutEnt))
(setq cblIndex 5)
;; Format layout number as 3-digit string (702, 703, 704, etc.)
(setq layoutNum (itoa (+ 702 layoutIndex)))
(foreach att (vlax-invoke vlaBlock 'GetAttributes)
(setq tag (strcase (vla-get-tagstring att)))
(if (= tag "WIRENO")
(progn
;; Concatenate: zone + layoutNum + "-CBL" + cblNum
(setq wireNumber
(strcat
zoneNumber
layoutNum
"-CBL"
(if (< cblIndex 10)
(strcat "0" (itoa cblIndex))
(itoa cblIndex)
)
)
)
(vla-put-textstring att wireNumber)
(setq cblIndex (1+ cblIndex))
)
)
)
)
(princ "\nInvalid layout entity passed to setLayoutWireNumbers.")
)
(princ)
)
(defun parseCSVLine (line / pos result)
(setq result '())
(while (setq pos (vl-string-search "," line))
(setq result (append result (list (substr line 1 pos))))
(setq line (substr line (+ pos 2)))
)
(append result (list line))
)
(defun getDPMDataFromCSV ( / file filename line headers row dpm ip name deviceIP port partNumber dpmList deviceGroups currentGroup zoneRaw zoneNumber)
(setq filename (getfiled "Select CSV File" (strcat (getenv "USERPROFILE") "\\Desktop\\") "csv" 0))
(if (not filename)
(progn (princ "\nNo file selected.") (exit))
)
(setq file (open filename "r"))
(if (not file)
(progn (princ "\nFailed to open file.") (exit))
)
;; Skip metadata lines and header row (first 3 lines)
(read-line file)
(read-line file)
(read-line file)
(setq dpmList '())
(setq deviceGroups '())
(setq currentGroup '())
(setq zoneNumber "")
(while (setq line (read-line file))
(setq row (parseCSVLine line))
;; Ensure row has enough columns
(if (>= (length row) 10)
(progn
(setq dpm (nth 3 row))
(setq ip (nth 4 row))
(setq name (nth 5 row))
(setq partNumber (nth 6 row))
(setq deviceIP (nth 7 row))
(setq port (nth 8 row))
(setq zoneRaw (nth 9 row))
;; Extract zone number - preserve it as-is with leading zeros
(if (and zoneRaw (/= zoneRaw ""))
(progn
;; Extract only digits from zone string (e.g., "MCM01" -> "01")
(setq zoneNumber
(str-trim
(vl-list->string
(vl-remove-if-not
'(lambda (c) (<= 48 c 57))
(vl-string->list zoneRaw)
)
)
)
)
)
)
(if (and dpm (/= dpm ""))
(progn
(if (> (length currentGroup) 0)
(progn
(while (< (length currentGroup) 24)
(setq currentGroup
(append currentGroup
(list (list
(cons "NAME" "SPARE")
(cons "IP" "")
(cons "PORT" "")
(cons "ZONE" zoneNumber)
(cons "PARTNUM" "")
))
)
)
)
(setq deviceGroups (append deviceGroups (list currentGroup)))
(setq currentGroup '())
)
)
(if (not (assoc dpm dpmList))
(setq dpmList (append dpmList (list (cons dpm (list ip zoneNumber)))))
)
)
)
(if (and name (/= name ""))
(setq currentGroup
(append currentGroup
(list (list
(cons "NAME" name)
(cons "IP" deviceIP)
(cons "PORT" port)
(cons "ZONE" zoneNumber)
(cons "PARTNUM" partNumber)
))
)
)
)
(if (= (length currentGroup) 24)
(progn
(setq deviceGroups (append deviceGroups (list currentGroup)))
(setq currentGroup '())
)
)
)
)
)
(if (> (length currentGroup) 0)
(progn
(while (< (length currentGroup) 24)
(setq currentGroup
(append currentGroup
(list (list
(cons "NAME" "SPARE")
(cons "IP" "")
(cons "PORT" "")
(cons "ZONE" zoneNumber)
(cons "PARTNUM" "")
))
)
)
)
(setq deviceGroups (append deviceGroups (list currentGroup)))
)
)
(close file)
(list dpmList deviceGroups)
)
(defun c:init-diagrams ( / blockName count offsetX i x y basePt targetPt lastEnt dpmPair dpmName dpmIP deviceGroup dpmUpsPt dpmUpsObj tag ent vlaObj zoneName zoneNumber dpmData)
(clearDrawing)
(setq blockName "layout")
(setq csvData (getDPMDataFromCSV))
(setq dpmList (car csvData))
(setq deviceGroups (cadr csvData))
(setq count (length dpmList))
(if (and blockName (> count 0))
(progn
(setq offsetX 43.5)
(setq i 0)
(while (< i count)
(setq x (* i offsetX))
(setq y 0)
(setq basePt '(0 0 0))
(setq targetPt (list x y 0))
;; Get DPM data and zone number
(setq dpmPair (nth i dpmList))
(setq dpmName (car dpmPair))
(setq dpmData (cdr dpmPair))
(setq dpmIP (car dpmData))
(setq zoneNumber (cadr dpmData))
(setq deviceGroup (nth i deviceGroups))
;; Insert layout
(command "_.-INSERT" blockName basePt 1 1 0)
(setq lastEnt (entlast))
(if lastEnt
(progn
(vla-move
(vlax-ename->vla-object lastEnt)
(vlax-3d-point basePt)
(vlax-3d-point targetPt)
)
(setLayoutWireNumbers lastEnt zoneNumber i)
)
)
;; Insert DPM-UPS
(setq dpmUpsPt (list (+ x 16.1) (+ y 2.1173) 0))
(command "_.-INSERT" "DPM-UPS" dpmUpsPt 1 1 0)
(setq lastEnt (entlast))
(if lastEnt
(progn
(setq dpmUpsObj (vlax-ename->vla-object lastEnt))
(foreach att (vlax-invoke dpmUpsObj 'GetAttributes)
(setq tag (strcase (vla-get-tagstring att)))
(cond
((= tag "IPADDRESS") (vla-put-textstring att dpmIP))
((= tag "TAG2") (vla-put-textstring att dpmName))
)
)
)
)
;; Insert ZONE_32H
(setq desiredX (+ x 0.7658))
(setq desiredY (+ y 25.6873))
(command "_.-INSERT" "ZONE_32H" '(0 0 0) 1 1 0)
(setq ent (entlast))
(if ent
(progn
(setq vlaObj (vlax-ename->vla-object ent))
(vla-move vlaObj (vlax-3d-point 0 0 0) (vlax-3d-point desiredX desiredY 0))
(setq zoneName (strcat zoneNumber (itoa (+ 702 i)) "."))
(foreach att (vlax-invoke vlaObj 'GetAttributes)
(vla-put-textstring att zoneName)
)
(labelZone32Lines ent)
)
)
;; layout label
(setq labelPt (list (+ desiredX 14.0) 32.0 0.0))
(command "_.text" labelPt 1.5 0 (strcat "Layout " (itoa (1+ i))))
(place-enet-devices x y deviceGroup)
(setq i (1+ i))
)
(princ (strcat "\nInserted " (itoa count) " layouts side-by-side."))
)
(princ "\nInvalid input.")
)
(princ)
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,330 @@
(defun parseCSVLine (line / pos result)
(setq result '())
(while (setq pos (vl-string-search "," line))
(setq result (cons (substr line 1 pos) result))
(setq line (substr line (+ pos 2)))
)
(reverse (cons line result))
)
(defun readDPMNamesAndZoneFromCSV ( / file filename line zone dpmList counter row name)
;; Ask user to select CSV
(setq filename (getfiled "Select CSV File" (strcat (getenv "USERPROFILE") "\\Desktop\\") "csv" 0))
(if (not filename)
(progn (princ "\nNo file selected.") nil)
(progn
(setq file (open filename "r"))
(if (not file)
(progn (princ "\nFailed to open file.") nil)
(progn
;; Skip first line (header)
(read-line file)
;; Read first line (A2..F2) to get zone
(setq line (read-line file))
(setq row (parseCSVLine line))
(setq zone (nth 5 row)) ;; F2
;; Keep only digits from zone
(setq zone (vl-list->string (vl-remove-if-not '(lambda (c) (<= 48 c 57)) (vl-string->list zone))))
;; Initialize DPM list
(setq dpmList '())
(setq counter 1)
;; Read rest of the file
(while (setq line (read-line file))
(setq row (parseCSVLine line))
(setq name (nth 0 row)) ;; Column A
;; Only take every 24th row starting from first
(if (= (rem counter 24) 1)
(if (and name (/= name ""))
(setq dpmList (append dpmList (list (list (cons "NAME" name) (cons "ZONE" zone)))))
)
)
(setq counter (1+ counter))
)
(close file)
dpmList
)
)
)
)
)
(defun updateTagAttribute (ent tagValue / obj attribs att)
;; Convert entity to VLA object
(setq obj (vlax-ename->vla-object ent))
(if (and obj (eq (vla-get-hasattributes obj) :vlax-true))
(progn
(setq attribs (vlax-invoke obj 'GetAttributes))
(foreach att attribs
(if (eq (strcase (vla-get-TagString att)) "TAG1")
(vla-put-TextString att tagValue)
)
)
)
)
)
(defun addTextLabel (pt1 pt2 labelText / midPt textHeight alignPt)
;; Calculate midpoint of horizontal line
(setq midPt (list (/ (+ (car pt1) (car pt2)) 2.0) (cadr pt1)))
(setq textHeight 0.3) ;; Adjust text height as needed
(setq alignPt (list (car midPt) (+ (cadr midPt) 0.2))) ;; 0.3 units above line
;; Create text entity above the line with center alignment
(entmakex (list
'(0 . "TEXT")
(cons 10 alignPt) ;; Insertion point
(cons 11 alignPt) ;; Alignment point (required for centered text)
(cons 40 textHeight)
(cons 1 labelText)
(cons 72 1) ;; Center horizontal alignment
(cons 73 0) ;; Baseline vertical alignment
'(8 . "AS_ENET_CABLE") ;; Same layer as cables
'(62 . 7) ;; White color
))
)
(defun c:Init_Network ( / dpmCount rowCount colCount i row col x y spacingX spacingY blkName scaleFactor
startPt endPt zigzagStart secondCableEnds zigzagStarts cableCounter )
(setq firstHorizontalLabeled nil)
(setq cableCounter 2)
(setq blkName "DPM")
(setq hdvBlkName "HDV2_1756-EN4TR_CHILD")
(setq scaleFactor 0.45)
(setq spacingX 15.0)
(setq spacingY 9.0)
(setq dpmOffsetX 5.0)
(setq hdvY 4.0)
(setq secondCableEnds '())
(setq zigzagStarts '())
(command "_.ERASE" "ALL" "")
(setq filename (getfiled "Select CSV File" (strcat (getenv "USERPROFILE") "\\Desktop\\") "csv" 0))
(if (not filename)
(progn (princ "\nNo file selected.") (exit))
(progn
(setq file (open filename "r"))
(if (not file)
(progn (princ "\nFailed to open file.") (exit))
(progn
;; Skip header line
(read-line file)
;; Read first data line for zone
(setq line (read-line file)) ;; <-- assign to line
(setq row (parseCSVLine line))
(setq devices '())
(setq zone (nth 5 row)) ;; column F
;; extract digits only
(setq zone (vl-list->string
(vl-remove-if-not
'(lambda (c) (<= 48 c 57))
(vl-string->list zone)
)
))
;; Read rest of the lines for DPM names (column D, index 3)
(while (and (setq line (read-line file)) (/= line ""))
(setq row (parseCSVLine line))
(setq name (nth 3 row)) ;; Column D contains DPM names
;; Only include actual DPM names (must contain DPM and underscore, exclude header "DPM")
(if (and name (/= name "") (/= (strcase name) "DPM") (wcmatch (strcase name) "*_DPM*"))
(setq devices (append devices (list name)))
)
)
(close file)
)
)
)
)
(setq dpmCount (length devices))
;; Calculate grid size
(setq colCount (fix (sqrt dpmCount)))
(if (< (* colCount colCount) dpmCount)
(setq colCount (+ colCount 1))
)
(setq rowCount (fix (/ (+ dpmCount colCount -1) colCount)))
(setq gridWidth (* (- colCount 1) spacingX))
(setq centerOffsetX (- (/ gridWidth 2.0)))
(command "_.LAYER" "S" "0" "")
(command "_.INSERT" hdvBlkName (list 0 hdvY) scaleFactor scaleFactor 0)
(setq i 0)
(repeat dpmCount
(setq row (fix (/ i colCount)))
(setq col (rem i colCount))
(setq x (+ (* col spacingX) dpmOffsetX))
(setq y (* -1 row spacingY))
(setq dpmName (nth i devices))
(command "_.LAYER" "S" "0" "")
(command "_.INSERT" blkName (list x y) scaleFactor scaleFactor 0)
(setq ent (entlast))
(updateTagAttribute ent dpmName)
;; First cable: vertical up
(setq startPt (list (+ x 7.3656) (+ y 4.4406)))
(setq endPt (list (car startPt) (+ (cadr startPt) 2.0)))
(entmakex (list '(0 . "LINE") (cons 10 startPt) (cons 11 endPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(setq secondCableEnds (append secondCableEnds (list endPt)))
(if (or (= (rem (1+ i) colCount) 0) (= i (- dpmCount 1)))
(progn
(setq startPt (list (+ x 7.2677) (+ y 3.6094)))
(setq elbowPt (list (- (car startPt) 0.2) (- (cadr startPt) 0.2)))
(entmakex (list '(0 . "LINE") (cons 10 startPt) (cons 11 elbowPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(setq endPt (list (car elbowPt) (- (cadr elbowPt) 4.5)))
(entmakex (list '(0 . "LINE") (cons 10 elbowPt) (cons 11 endPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(setq zigzagStarts (append zigzagStarts (list nil)))
)
(progn
(setq zigzagStart (list (+ x 7.3656) (+ y 3.7852)))
(setq elbowPt (list (+ x 7.8585) (+ y 5.1262)))
(entmakex (list '(0 . "LINE") (cons 10 zigzagStart) (cons 11 elbowPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(setq startPt elbowPt)
(setq endPt (list (car startPt) (+ (cadr startPt) 1.3144)))
(entmakex (list '(0 . "LINE") (cons 10 startPt) (cons 11 endPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(setq zigzagStarts (append zigzagStarts (list endPt)))
)
)
(setq i (1+ i))
)
;; Combined loop
(setq i 0)
(repeat rowCount
(setq j (* i colCount))
(repeat (- colCount 1)
(if (< (1+ j) dpmCount)
(progn
(setq pt1 (nth j zigzagStarts))
(setq pt2 (nth (1+ j) secondCableEnds))
(if (and pt1 pt2 (listp pt1) (listp pt2))
(progn
(entmakex
(list
'(0 . "LINE")
(cons 10 pt1)
(cons 11 pt2)
'(62 . 256)
'(8 . "AS_ENET_CABLE")
)
)
(addTextLabel pt1 pt2 (strcat zone "701-CBL" (itoa cableCounter)))
(setq cableCounter (1+ cableCounter))
)
)
)
)
(setq j (1+ j))
)
;; Connect last in row to first in next row
(setq lastInRowIndex (- (* (1+ i) colCount) 1))
(setq firstInNextRowIndex (* (1+ i) colCount))
(if (and (< lastInRowIndex dpmCount) (< firstInNextRowIndex dpmCount))
(progn
(setq row i)
(setq col (- colCount 1))
(setq x (+ (* col spacingX) dpmOffsetX))
(setq y (* -1 row spacingY))
(setq downwardEndPt (list (- (+ x 7.2677) 0.2) (- (- (+ y 3.6094) 0.2) 4.5)))
(setq nextRow (1+ i))
(setq nextCol 0)
(setq nextX (+ (* nextCol spacingX) dpmOffsetX))
(setq nextY (* -1 nextRow spacingY))
(setq nextBlockFirstLineEnd (list (+ nextX 7.3656) (+ (+ nextY 4.4406) 2.0)))
(setq horizontalEndPt (list (car nextBlockFirstLineEnd) (cadr downwardEndPt)))
(entmakex (list '(0 . "LINE") (cons 10 downwardEndPt) (cons 11 horizontalEndPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(addTextLabel downwardEndPt horizontalEndPt (strcat zone "701-CBL" (itoa cableCounter)))
(setq cableCounter (1+ cableCounter))
(entmakex (list '(0 . "LINE") (cons 10 horizontalEndPt) (cons 11 nextBlockFirstLineEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
)
)
(setq i (1+ i))
)
;; Connect first block to HDV
(if (> dpmCount 0)
(progn
(setq firstX (+ (* 0 spacingX) dpmOffsetX))
(setq firstY (* -1 0 spacingY))
(setq firstBlockEnd (list (+ firstX 7.3656) (+ (+ firstY 4.4406) 2.0)))
(setq hdvEndPt (list (+ 0 1.4) (- hdvY 4.4)))
(setq horizontalEnd (list (+ (car hdvEndPt) 0.5) (cadr firstBlockEnd)))
(entmakex (list '(0 . "LINE") (cons 10 firstBlockEnd) (cons 11 horizontalEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
;; This is intentionally first cable: label as first
(addTextLabel firstBlockEnd horizontalEnd (strcat zone "701-CBL1"))
(setq verticalEnd (list (car horizontalEnd) (+ (cadr hdvEndPt) 0.5)))
(entmakex (list '(0 . "LINE") (cons 10 horizontalEnd) (cons 11 verticalEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(entmakex (list '(0 . "LINE") (cons 10 verticalEnd) (cons 11 hdvEndPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
)
)
;; Connect last block to HDV
(if (> dpmCount 0)
(progn
(setq lastBlockIndex (- dpmCount 1))
(setq lastRow (fix (/ lastBlockIndex colCount)))
(setq lastCol (rem lastBlockIndex colCount))
(setq lastX (+ (* lastCol spacingX) dpmOffsetX))
(setq lastY (* -1 lastRow spacingY))
(setq hdvLastEndPt (list (+ 0 1.1) (- hdvY 5.83)))
(if (= rowCount 1)
(progn
(setq startPt (list (- (+ lastX 7.2677) 0.2) (- (+ lastY 3.6094) 0.2)))
(setq extendedVerticalEnd (list (car startPt) (- (cadr hdvLastEndPt) 1.5)))
(entmakex (list '(0 . "LINE") (cons 10 startPt) (cons 11 extendedVerticalEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
;; Reduce final horizontal length by 1 unit
(setq horizontalEnd (list (car hdvLastEndPt) (cadr extendedVerticalEnd)))
(entmakex (list '(0 . "LINE") (cons 10 extendedVerticalEnd) (cons 11 horizontalEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
;; Single-row: last cable label (uses cableCounter)
(addTextLabel extendedVerticalEnd horizontalEnd (strcat zone "701-CBL" (itoa cableCounter)))
(entmakex (list '(0 . "LINE") (cons 10 horizontalEnd) (cons 11 hdvLastEndPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
)
(progn
;; Multiple rows:
(setq lastBlockVerticalEnd (list (- (+ lastX 7.2677) 0.2) (- (- (+ lastY 3.6094) 0.2) 4.5)))
(setq horizontalEnd (list (car hdvLastEndPt) (cadr lastBlockVerticalEnd)))
(entmakex (list '(0 . "LINE") (cons 10 lastBlockVerticalEnd) (cons 11 horizontalEnd) '(62 . 256) '(8 . "AS_ENET_CABLE")))
(addTextLabel lastBlockVerticalEnd horizontalEnd (strcat zone "701-CBL" (itoa cableCounter)))
(entmakex (list '(0 . "LINE") (cons 10 horizontalEnd) (cons 11 hdvLastEndPt) '(62 . 256) '(8 . "AS_ENET_CABLE")))
)
)
)
)
(princ)
)

Binary file not shown.

View File

@ -0,0 +1,77 @@
# Splitter Detection Logic in IO.lsp
## Overview
The script decides whether to create a **single cable** or **two cables + splitter** based on the DESCA values in each pair.
## Decision Flow
### Step 1: Check if both DESCA values are filled
```
If val1 = "" OR val2 = ""
→ Go to Case 2 (single value handling)
Else (both val1 and val2 have values)
→ Go to Case 1 (pair handling)
```
### Step 2: Case 1 - Both values filled (Pair handling)
#### For FIO/FIOH blocks (special handling at lines 318-427):
**SPLITTER CREATED** if:
- Both values contain "TPE" AND they're different names (e.g., TPE2 vs TPE3)
- One contains "RCV" and other contains "SND" (or vice versa)
**SINGLE CABLE** if:
- None of the splitter conditions above match → default to single cable
#### For all other blocks (VFD, SIO, etc. at lines 432-445):
**SINGLE CABLE** if values match any of these patterns:
- Both contain "SEL"
- Both contain "DPM"
- Both contain "VFD" AND both contain "STO"
- One contains "_PB" and other contains "_PB_LT" (pushbutton + light)
- Both contain "BCN" (beacon stack)
- Both contain "EPC"
- Both contain "SSP"
**TWO CABLES + SPLITTER** if:
- None of the single-cable conditions match → default to splitter
## Summary Table
| DESCA1 Pattern | DESCA2 Pattern | Result |
|----------------|----------------|--------|
| `*_SEL*` | `*_SEL*` | ✅ Single cable |
| `*_DPM*` | `*_DPM*` | ✅ Single cable |
| `*VFD*STO*` | `*VFD*STO*` | ✅ Single cable |
| `*_PB*` | `*_PB_LT*` | ✅ Single cable |
| `*_PB_LT*` | `*_PB*` | ✅ Single cable |
| `*BCN*` | `*BCN*` | ✅ Single cable |
| `*EPC*` | `*EPC*` | ✅ Single cable |
| `*SSP*` | `*SSP*` | ✅ Single cable |
| `*TPE*` (different) | `*TPE*` (different) | ⚠️ **SPLITTER** (FIO only) |
| `*RCV*` | `*SND*` | ⚠️ **SPLITTER** (FIO only) |
| `*SND*` | `*RCV*` | ⚠️ **SPLITTER** (FIO only) |
| Anything else | Anything else | ⚠️ **SPLITTER** |
## Key Code Locations
- **Lines 318-332**: FIO/FIOH splitter conditions (TPE pairs, RCV/SND pairs)
- **Lines 432-445**: All other blocks - single cable conditions
- **Lines 505-519**: Default ELSE branch - creates splitter for unmatched pairs
## Example Scenarios
1. **Beacon stack** (`BYDC_6_BCN1_A` + `BYDC_6_BCN1_H`):
- Both contain "BCN" → ✅ Single cable (line 443)
2. **Pushbutton + light** (`*_PB` + `*_PB_LT`):
- Pattern match → ✅ Single cable (lines 440-441)
3. **TPE pairs** (`*TPE1` + `*TPE2`):
- For FIO blocks → ⚠️ Splitter (lines 322-324)
- For other blocks → ⚠️ Splitter (default)
4. **Two different devices** (e.g., `*DEVICE1` + `*DEVICE2`):
- No pattern match → ⚠️ Splitter (default)

View File

@ -0,0 +1,498 @@
TAGNAME,ADDR,TERM,TERMDESC,DESCA,DESCB,DESCC,DESCD,DESCE,INST,LOC
PDP01_FIOM1,PDP01_FIOM1_X3_0,X3_0,,PDP01_CB1,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOM1,PDP01_FIOM1_X3_1,X3_1,,PDP01_CB2,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOM1,PDP01_FIOM1_X2_0,X2_0,,PDP01_CB3,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOM1,PDP01_FIOM1_X2_1,X2_1,,PDP01_CB4,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOM1,PDP01_FIOM1_X1_0,X1_0,,PDP01_CB5,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOM1,PDP01_FIOM1_X1_1,X1_1,,SPARE,,,,,,
PDP01_FIOM1,PDP01_FIOM1_X0_0,X0_0,,PDP01_CB6,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOM1,PDP01_FIOM1_X0_1,X0_1,,SPARE,,,,,,
PDP01_FIOM1,PDP01_FIOM1_X7_0,X7_0,,PDP01_CB7,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOM1,PDP01_FIOM1_X7_1,X7_1,,PDP01_CB8,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOM1,PDP01_FIOM1_X6_0,X6_0,,PDP01_CB9,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOM1,PDP01_FIOM1_X6_1,X6_1,,PDP01_CB10,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOM1,PDP01_FIOM1_X5_0,X5_0,,PDP01_PWM1,PHASE MONITOR,,,,,
PDP01_FIOM1,PDP01_FIOM1_X5_1,X5_1,,SPARE,,,,,,
PDP01_FIOM1,PDP01_FIOM1_X4_0,X4_0,,PDP01_FIOH1,I/O LINK HUB,,,,,
PDP01_FIOM1,PDP01_FIOM1_X4_1,X4_1,,SPARE,,,,,,
PDP01_FIOH1,PDP01_FIOH1_C7_A,C7_A,,PDP01_CB11,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C7_B,C7_B,,PDP01_CB12,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C5_A,C5_A,,PDP01_CB13,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C5_B,C5_B,,PDP01_CB14,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C3_A,C3_A,,PDP01_CB15,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C3_B,C3_B,,PDP01_CB16,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C1_A,C1_A,,PDP01_CB17,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C1_B,C1_B,,PDP01_CB18,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C8_A,C8_A,,PDP01_CB19,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C8_B,C8_B,,PDP01_CB20,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C6_A,C6_A,,PDP01_CB21,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C6_B,C6_B,,PDP01_CB22,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C4_A,C4_A,,PDP01_CB23,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C4_B,C4_B,,PDP01_CB24,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C2_A,C2_A,,PDP01_CB25,CIRCUIT BREAKER MONITORING,,,,,
PDP01_FIOH1,PDP01_FIOH1_C2_B,C2_B,,PDP01_CB26,CIRCUIT BREAKER MONITORING,,,,,
UL27_10_VFD,UL27_10_VFD_I0,I0,,UL27_10_VFD_DISC,DISCONNECT AUX,,,,,
UL27_10_VFD,UL27_10_VFD_I1,I1,,SPARE,,,,,,
UL27_10_VFD,UL27_10_VFD_I2,I2,,SPARE,,,,,,
UL27_10_VFD,UL27_10_VFD_I3,I3,,SPARE,,,,,,
UL27_10_VFD,UL27_10_VFD_IO0,IO0,,UL29_8_S2_PB,START PUSHBUTTON,,,,,
UL27_10_VFD,UL27_10_VFD_IO1,IO1,,UL29_8_S2_PB_LT,START PUSHBUTTON LIGHT,,,,,
UL27_10_VFD,UL27_10_VFD_SI0,SI0,,SPARE,,,,,,
UL27_10_VFD,UL27_10_VFD_SI1,SI1,,SPARE,,,,,,
UL27_10_VFD,UL27_10_VFD_SI2,SI2,,SPARE,,,,,,
UL27_10_VFD,UL27_10_VFD_SI3,SI3,,SPARE,,,,,,
UL27_10_VFD,UL27_10_VFD_SO0,SO0,,SPARE,,,,,,
UL27_2_VFD,UL27_2_VFD_I0,I0,,UL27_2_VFD_DISC,DISCONNECT AUX,,,,,
UL27_2_VFD,UL27_2_VFD_I1,I1,,SPARE,,,,,,
UL27_2_VFD,UL27_2_VFD_I2,I2,,UL27_2_TPE2,TRACKING PHOTOEYE,,,,,
UL27_2_VFD,UL27_2_VFD_I3,I3,,SPARE,,,,,,
UL27_2_VFD,UL27_2_VFD_IO0,IO0,,UL27_2_ENW1,WHEEL ENCODER,,,,,
UL27_2_VFD,UL27_2_VFD_IO1,IO1,,SPARE,,,,,,
UL27_2_VFD,UL27_2_VFD_SI0,SI0,,UL27_2_EPC1,E-STOP PULLCORD,,,,,
UL27_2_VFD,UL27_2_VFD_SI1,SI1,,UL27_2_EPC1_2,E-STOP PULLCORD,,,,,
UL27_2_VFD,UL27_2_VFD_SI2,SI2,,UL27_2_EPC2,E-STOP PULLCORD,,,,,
UL27_2_VFD,UL27_2_VFD_SI3,SI3,,UL27_2_EPC2_2,E-STOP PULLCORD,,,,,
UL27_2_VFD,UL27_2_VFD_SO0,SO0,,UL27_2_SR1_STO1,SAFETY TORQUE OFF,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X3_0,X3_0,,UL27_2_SS1_SPB,SS STATION START PUSHBUTTON,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X3_1,X3_1,,UL27_2_SS1_SPB_LT,SS STATION START PUSHBUTTON LIGHT,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X2_0,X2_0,,UL27_2_SS1_STPB,SS STATION STOP PUSHBUTTON,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X2_1,X2_1,,SPARE,,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X1_0,X1_0,,UL27_2_SS2_SPB,SS STATION START PUSHBUTTON,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X1_1,X1_1,,UL27_2_SS2_SPB_LT,SS STATION START PUSHBUTTON LIGHT,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X0_0,X0_0,,UL27_2_SS2_STPB,SS STATION STOP PUSHBUTTON,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X0_1,X0_1,,SPARE,,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X7_0,X7_0,,UL27_2_BCN1_R,RED BEACON LIGHT,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X7_1,X7_1,,SPARE,,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X6_0,X6_0,,UL27_2_BCN2_R,RED BEACON LIGHT,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X6_1,X6_1,,SPARE,,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X5_0,X5_0,,UL27_2_TPE1,TRACKING PHOTOEYE,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X5_1,X5_1,,SPARE,,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X4_0,X4_0,,SPARE,,,,,,
UL27_2_FIOM1,UL27_2_FIOM1_X4_1,X4_1,,SPARE,,,,,,
UL27_3_VFD,UL27_3_VFD_I0,I0,,UL27_3_VFD_DISC,DISCONNECT AUX,,,,,
UL27_3_VFD,UL27_3_VFD_I1,I1,,SPARE,,,,,,
UL27_3_VFD,UL27_3_VFD_I2,I2,,UL27_3_TPE1,TRACKING PHOTOEYE,,,,,
UL27_3_VFD,UL27_3_VFD_I3,I3,,SPARE,,,,,,
UL27_3_VFD,UL27_3_VFD_IO0,IO0,,UL27_3_ENSH1,SHAFT ENCODER,,,,,
UL27_3_VFD,UL27_3_VFD_IO1,IO1,,SPARE,,,,,,
UL27_3_VFD,UL27_3_VFD_SI0,SI0,,SPARE,,,,,,
UL27_3_VFD,UL27_3_VFD_SI1,SI1,,SPARE,,,,,,
UL27_3_VFD,UL27_3_VFD_SI2,SI2,,SPARE,,,,,,
UL27_3_VFD,UL27_3_VFD_SI3,SI3,,SPARE,,,,,,
UL27_3_VFD,UL27_3_VFD_SO0,SO0,,SPARE,,,,,,
UL27_4_VFD,UL27_4_VFD_I0,I0,,UL27_4_VFD_DISC,DISCONNECT AUX,,,,,
UL27_4_VFD,UL27_4_VFD_I1,I1,,SPARE,,,,,,
UL27_4_VFD,UL27_4_VFD_I2,I2,,UL27_4_TPE1,TRACKING PHOTOEYE,,,,,
UL27_4_VFD,UL27_4_VFD_I3,I3,,SPARE,,,,,,
UL27_4_VFD,UL27_4_VFD_IO0,IO0,,UL27_4_ENW1,WHEEL ENCODER,,,,,
UL27_4_VFD,UL27_4_VFD_IO1,IO1,,SPARE,,,,,,
UL27_4_VFD,UL27_4_VFD_SI0,SI0,,SPARE,,,,,,
UL27_4_VFD,UL27_4_VFD_SI1,SI1,,SPARE,,,,,,
UL27_4_VFD,UL27_4_VFD_SI2,SI2,,SPARE,,,,,,
UL27_4_VFD,UL27_4_VFD_SI3,SI3,,SPARE,,,,,,
UL27_4_VFD,UL27_4_VFD_SO0,SO0,,SPARE,,,,,,
UL27_5_VFD,UL27_5_VFD_I0,I0,,UL27_5_VFD_DISC,DISCONNECT AUX,,,,,
UL27_5_VFD,UL27_5_VFD_I1,I1,,SPARE,,,,,,
UL27_5_VFD,UL27_5_VFD_I2,I2,,UL27_5_TPE1,TRACKING PHOTOEYE,,,,,
UL27_5_VFD,UL27_5_VFD_I3,I3,,UL27_5_ENW1,WHEEL ENCODER,,,,,
UL27_5_VFD,UL27_5_VFD_IO0,IO0,,UL27_5_S2_PB,START PUSHBUTTON,,,,,
UL27_5_VFD,UL27_5_VFD_IO1,IO1,,UL27_5_S2_PB_LT,START PUSHBUTTON LIGHT,,,,,
UL27_5_VFD,UL27_5_VFD_SI0,SI0,,UL27_5_EPC1,E-STOP PULLCORD,,,,,
UL27_5_VFD,UL27_5_VFD_SI1,SI1,,UL27_5_EPC1_2,E-STOP PULLCORD,,,,,
UL27_5_VFD,UL27_5_VFD_SI2,SI2,,UL27_5_EPC2,E-STOP PULLCORD,,,,,
UL27_5_VFD,UL27_5_VFD_SI3,SI3,,UL27_5_EPC2_2,E-STOP PULLCORD,,,,,
UL27_5_VFD,UL27_5_VFD_SO0,SO0,,UL27_5_BCN2_R,RED BEACON LIGHT,,,,,
UL27_6_VFD,UL27_6_VFD_I0,I0,,UL27_6_VFD_DISC,DISCONNECT AUX,,,,,
UL27_6_VFD,UL27_6_VFD_I1,I1,,SPARE,,,,,,
UL27_6_VFD,UL27_6_VFD_I2,I2,,UL27_6_TPE1,TRACKING PHOTOEYE,,,,,
UL27_6_VFD,UL27_6_VFD_I3,I3,,UL27_6_ENSH1,SHAFT ENCODER,,,,,
UL27_6_VFD,UL27_6_VFD_IO0,IO0,,UL27_5_S1_PB,START PUSHBUTTON,,,,,
UL27_6_VFD,UL27_6_VFD_IO1,IO1,,UL27_5_S1_PB_LT,START PUSHBUTTON LIGHT,,,,,
UL27_6_VFD,UL27_6_VFD_SI0,SI0,,SPARE,,,,,,
UL27_6_VFD,UL27_6_VFD_SI1,SI1,,SPARE,,,,,,
UL27_6_VFD,UL27_6_VFD_SI2,SI2,,SPARE,,,,,,
UL27_6_VFD,UL27_6_VFD_SI3,SI3,,SPARE,,,,,,
UL27_6_VFD,UL27_6_VFD_SO0,SO0,,SPARE,,,,,,
UL27_7_VFD,UL27_7_VFD_I0,I0,,UL27_7_VFD_DISC,DISCONNECT AUX,,,,,
UL27_7_VFD,UL27_7_VFD_I1,I1,,SPARE,,,,,,
UL27_7_VFD,UL27_7_VFD_I2,I2,,UL27_7_TPE1,TRACKING PHOTOEYE,,,,,
UL27_7_VFD,UL27_7_VFD_I3,I3,,UL27_7_ENSH1,SHAFT ENCODER,,,,,
UL27_7_VFD,UL27_7_VFD_IO0,IO0,,UL27_5_BCN1_A,AMBER BEACON LIGHT,,,,,
UL27_7_VFD,UL27_7_VFD_IO1,IO1,,UL27_5_BCN1_R,RED BEACON LIGHT,,,,,
UL27_7_VFD,UL27_7_VFD_SI0,SI0,,SPARE,,,,,,
UL27_7_VFD,UL27_7_VFD_SI1,SI1,,SPARE,,,,,,
UL27_7_VFD,UL27_7_VFD_SI2,SI2,,SPARE,,,,,,
UL27_7_VFD,UL27_7_VFD_SI3,SI3,,SPARE,,,,,,
UL27_7_VFD,UL27_7_VFD_SO0,SO0,,SPARE,,,,,,
UL27_8_VFD,UL27_8_VFD_I0,I0,,UL27_8_VFD_DISC,DISCONNECT AUX,,,,,
UL27_8_VFD,UL27_8_VFD_I1,I1,,SPARE,,,,,,
UL27_8_VFD,UL27_8_VFD_I2,I2,,UL27_8_TPE1,TRACKING PHOTOEYE,,,,,
UL27_8_VFD,UL27_8_VFD_I3,I3,,SPARE,,,,,,
UL27_8_VFD,UL27_8_VFD_IO0,IO0,,UL27_8_ENSH1,SHAFT ENCODER,,,,,
UL27_8_VFD,UL27_8_VFD_IO1,IO1,,SPARE,,,,,,
UL27_8_VFD,UL27_8_VFD_SI0,SI0,,SPARE,,,,,,
UL27_8_VFD,UL27_8_VFD_SI1,SI1,,SPARE,,,,,,
UL27_8_VFD,UL27_8_VFD_SI2,SI2,,SPARE,,,,,,
UL27_8_VFD,UL27_8_VFD_SI3,SI3,,SPARE,,,,,,
UL27_8_VFD,UL27_8_VFD_SO0,SO0,,SPARE,,,,,,
UL27_9_VFD,UL27_9_VFD_I0,I0,,UL27_9_VFD_DISC,DISCONNECT AUX,,,,,
UL27_9_VFD,UL27_9_VFD_I1,I1,,SPARE,,,,,,
UL27_9_VFD,UL27_9_VFD_I2,I2,,UL27_9_TPE1,TRACKING PHOTOEYE,,,,,
UL27_9_VFD,UL27_9_VFD_I3,I3,,SPARE,,,,,,
UL27_9_VFD,UL27_9_VFD_IO0,IO0,,UL27_9_ENSH1,SHAFT ENCODER,,,,,
UL27_9_VFD,UL27_9_VFD_IO1,IO1,,SPARE,,,,,,
UL27_9_VFD,UL27_9_VFD_SI0,SI0,,SPARE,,,,,,
UL27_9_VFD,UL27_9_VFD_SI1,SI1,,SPARE,,,,,,
UL27_9_VFD,UL27_9_VFD_SI2,SI2,,SPARE,,,,,,
UL27_9_VFD,UL27_9_VFD_SI3,SI3,,SPARE,,,,,,
UL27_9_VFD,UL27_9_VFD_SO0,SO0,,SPARE,,,,,,
UL28_2_VFD,UL28_2_VFD_I0,I0,,UL28_2_VFD_DISC,DISCONNECT AUX,,,,,
UL28_2_VFD,UL28_2_VFD_I1,I1,,SPARE,,,,,,
UL28_2_VFD,UL28_2_VFD_I2,I2,,UL28_2_TPE2,TRACKING PHOTOEYE,,,,,
UL28_2_VFD,UL28_2_VFD_I3,I3,,SPARE,,,,,,
UL28_2_VFD,UL28_2_VFD_IO0,IO0,,UL28_2_ENW1,WHEEL ENCODER,,,,,
UL28_2_VFD,UL28_2_VFD_IO1,IO1,,SPARE,,,,,,
UL28_2_VFD,UL28_2_VFD_SI0,SI0,,UL28_2_EPC1,E-STOP PULLCORD,,,,,
UL28_2_VFD,UL28_2_VFD_SI1,SI1,,UL28_2_EPC1_2,E-STOP PULLCORD,,,,,
UL28_2_VFD,UL28_2_VFD_SI2,SI2,,UL28_2_EPC2,E-STOP PULLCORD,,,,,
UL28_2_VFD,UL28_2_VFD_SI3,SI3,,UL28_2_EPC2_2,E-STOP PULLCORD,,,,,
UL28_2_VFD,UL28_2_VFD_SO0,SO0,,UL28_2_SR1_STO1,SAFETY TORQUE OFF,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X3_0,X3_0,,UL28_2_SS1_SPB,SS STATION START PUSHBUTTON,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X3_1,X3_1,,UL28_2_SS1_SPB_LT,SS STATION START PUSHBUTTON LIGHT,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X2_0,X2_0,,UL28_2_SS1_STPB,SS STATION STOP PUSHBUTTON,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X2_1,X2_1,,SPARE,,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X1_0,X1_0,,UL28_2_SS2_SPB,SS STATION START PUSHBUTTON,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X1_1,X1_1,,UL28_2_SS2_SPB_LT,SS STATION START PUSHBUTTON LIGHT,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X0_0,X0_0,,UL28_2_SS2_STPB,SS STATION STOP PUSHBUTTON,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X0_1,X0_1,,SPARE,,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X7_0,X7_0,,UL28_2_BCN1_R,RED BEACON LIGHT,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X7_1,X7_1,,SPARE,,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X6_0,X6_0,,UL28_2_BCN2_R,RED BEACON LIGHT,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X6_1,X6_1,,SPARE,,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X5_0,X5_0,,UL28_2_TPE1,TRACKING PHOTOEYE,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X5_1,X5_1,,SPARE,,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X4_0,X4_0,,SPARE,,,,,,
UL28_2_FIOM1,UL28_2_FIOM1_X4_1,X4_1,,SPARE,,,,,,
UL28_3_VFD,UL28_3_VFD_I0,I0,,UL28_3_VFD_DISC,DISCONNECT AUX,,,,,
UL28_3_VFD,UL28_3_VFD_I1,I1,,SPARE,,,,,,
UL28_3_VFD,UL28_3_VFD_I2,I2,,UL28_3_TPE1,TRACKING PHOTOEYE,,,,,
UL28_3_VFD,UL28_3_VFD_I3,I3,,UL28_3_ENW1,WHEEL ENCODER,,,,,
UL28_3_VFD,UL28_3_VFD_IO0,IO0,,UL28_3_S2_PB,START PUSHBUTTON,,,,,
UL28_3_VFD,UL28_3_VFD_IO1,IO1,,UL28_3_S2_PB_LT,START PUSHBUTTON LIGHT,,,,,
UL28_3_VFD,UL28_3_VFD_SI0,SI0,,UL28_3_EPC1,E-STOP PULLCORD,,,,,
UL28_3_VFD,UL28_3_VFD_SI1,SI1,,UL28_3_EPC1_2,E-STOP PULLCORD,,,,,
UL28_3_VFD,UL28_3_VFD_SI2,SI2,,UL28_3_EPC2,E-STOP PULLCORD,,,,,
UL28_3_VFD,UL28_3_VFD_SI3,SI3,,UL28_3_EPC2_2,E-STOP PULLCORD,,,,,
UL28_3_VFD,UL28_3_VFD_SO0,SO0,,UL28_3_BCN2_R,RED BEACON LIGHT,,,,,
UL28_4_VFD,UL28_4_VFD_I0,I0,,UL28_4_VFD_DISC,DISCONNECT AUX,,,,,
UL28_4_VFD,UL28_4_VFD_I1,I1,,SPARE,,,,,,
UL28_4_VFD,UL28_4_VFD_I2,I2,,UL28_4_TPE1,TRACKING PHOTOEYE,,,,,
UL28_4_VFD,UL28_4_VFD_I3,I3,,UL28_4_ENSH1,SHAFT ENCODER,,,,,
UL28_4_VFD,UL28_4_VFD_IO0,IO0,,UL28_3_S1_PB,START PUSHBUTTON,,,,,
UL28_4_VFD,UL28_4_VFD_IO1,IO1,,UL28_3_S1_PB_LT,START PUSHBUTTON LIGHT,,,,,
UL28_4_VFD,UL28_4_VFD_SI0,SI0,,SPARE,,,,,,
UL28_4_VFD,UL28_4_VFD_SI1,SI1,,SPARE,,,,,,
UL28_4_VFD,UL28_4_VFD_SI2,SI2,,SPARE,,,,,,
UL28_4_VFD,UL28_4_VFD_SI3,SI3,,SPARE,,,,,,
UL28_4_VFD,UL28_4_VFD_SO0,SO0,,SPARE,,,,,,
UL28_5_VFD,UL28_5_VFD_I0,I0,,UL28_5_VFD_DISC,DISCONNECT AUX,,,,,
UL28_5_VFD,UL28_5_VFD_I1,I1,,SPARE,,,,,,
UL28_5_VFD,UL28_5_VFD_I2,I2,,UL28_5_TPE1,TRACKING PHOTOEYE,,,,,
UL28_5_VFD,UL28_5_VFD_I3,I3,,UL28_5_ENSH1,SHAFT ENCODER,,,,,
UL28_5_VFD,UL28_5_VFD_IO0,IO0,,UL28_3_BCN1_A,AMBER BEACON LIGHT,,,,,
UL28_5_VFD,UL28_5_VFD_IO1,IO1,,UL28_3_BCN1_R,RED BEACON LIGHT,,,,,
UL28_5_VFD,UL28_5_VFD_SI0,SI0,,SPARE,,,,,,
UL28_5_VFD,UL28_5_VFD_SI1,SI1,,SPARE,,,,,,
UL28_5_VFD,UL28_5_VFD_SI2,SI2,,SPARE,,,,,,
UL28_5_VFD,UL28_5_VFD_SI3,SI3,,SPARE,,,,,,
UL28_5_VFD,UL28_5_VFD_SO0,SO0,,SPARE,,,,,,
UL28_6_VFD,UL28_6_VFD_I0,I0,,UL28_6_VFD_DISC,DISCONNECT AUX,,,,,
UL28_6_VFD,UL28_6_VFD_I1,I1,,SPARE,,,,,,
UL28_6_VFD,UL28_6_VFD_I2,I2,,UL28_6_TPE1,TRACKING PHOTOEYE,,,,,
UL28_6_VFD,UL28_6_VFD_I3,I3,,SPARE,,,,,,
UL28_6_VFD,UL28_6_VFD_IO0,IO0,,UL28_6_ENSH1,SHAFT ENCODER,,,,,
UL28_6_VFD,UL28_6_VFD_IO1,IO1,,SPARE,,,,,,
UL28_6_VFD,UL28_6_VFD_SI0,SI0,,SPARE,,,,,,
UL28_6_VFD,UL28_6_VFD_SI1,SI1,,SPARE,,,,,,
UL28_6_VFD,UL28_6_VFD_SI2,SI2,,SPARE,,,,,,
UL28_6_VFD,UL28_6_VFD_SI3,SI3,,SPARE,,,,,,
UL28_6_VFD,UL28_6_VFD_SO0,SO0,,SPARE,,,,,,
UL28_7_VFD,UL28_7_VFD_I0,I0,,UL28_7_VFD_DISC,DISCONNECT AUX,,,,,
UL28_7_VFD,UL28_7_VFD_I1,I1,,SPARE,,,,,,
UL28_7_VFD,UL28_7_VFD_I2,I2,,UL28_7_TPE1,TRACKING PHOTOEYE,,,,,
UL28_7_VFD,UL28_7_VFD_I3,I3,,SPARE,,,,,,
UL28_7_VFD,UL28_7_VFD_IO0,IO0,,UL28_7_ENSH1,SHAFT ENCODER,,,,,
UL28_7_VFD,UL28_7_VFD_IO1,IO1,,SPARE,,,,,,
UL28_7_VFD,UL28_7_VFD_SI0,SI0,,SPARE,,,,,,
UL28_7_VFD,UL28_7_VFD_SI1,SI1,,SPARE,,,,,,
UL28_7_VFD,UL28_7_VFD_SI2,SI2,,SPARE,,,,,,
UL28_7_VFD,UL28_7_VFD_SI3,SI3,,SPARE,,,,,,
UL28_7_VFD,UL28_7_VFD_SO0,SO0,,SPARE,,,,,,
UL28_8_VFD,UL28_8_VFD_I0,I0,,UL28_8_VFD_DISC,DISCONNECT AUX,,,,,
UL28_8_VFD,UL28_8_VFD_I1,I1,,SPARE,,,,,,
UL28_8_VFD,UL28_8_VFD_I2,I2,,UL28_8_TPE1,TRACKING PHOTOEYE,,,,,
UL28_8_VFD,UL28_8_VFD_I3,I3,,SPARE,,,,,,
UL28_8_VFD,UL28_8_VFD_IO0,IO0,,UL28_8_ENSH1,SHAFT ENCODER,,,,,
UL28_8_VFD,UL28_8_VFD_IO1,IO1,,SPARE,,,,,,
UL28_8_VFD,UL28_8_VFD_SI0,SI0,,SPARE,,,,,,
UL28_8_VFD,UL28_8_VFD_SI1,SI1,,SPARE,,,,,,
UL28_8_VFD,UL28_8_VFD_SI2,SI2,,SPARE,,,,,,
UL28_8_VFD,UL28_8_VFD_SI3,SI3,,SPARE,,,,,,
UL28_8_VFD,UL28_8_VFD_SO0,SO0,,SPARE,,,,,,
UL28_9_VFD,UL28_9_VFD_I0,I0,,UL28_9_VFD_DISC,DISCONNECT AUX,,,,,
UL28_9_VFD,UL28_9_VFD_I1,I1,,SPARE,,,,,,
UL28_9_VFD,UL28_9_VFD_I2,I2,,SPARE,,,,,,
UL28_9_VFD,UL28_9_VFD_I3,I3,,SPARE,,,,,,
UL28_9_VFD,UL28_9_VFD_IO0,IO0,,UL29_8_BCN1_A,AMBER BEACON LIGHT,,,,,
UL28_9_VFD,UL28_9_VFD_IO1,IO1,,UL29_8_BCN1_R,RED BEACON LIGHT,,,,,
UL28_9_VFD,UL28_9_VFD_SI0,SI0,,SPARE,,,,,,
UL28_9_VFD,UL28_9_VFD_SI1,SI1,,SPARE,,,,,,
UL28_9_VFD,UL28_9_VFD_SI2,SI2,,SPARE,,,,,,
UL28_9_VFD,UL28_9_VFD_SI3,SI3,,SPARE,,,,,,
UL28_9_VFD,UL28_9_VFD_SO0,SO0,,SPARE,,,,,,
UL29_1_VFD,UL29_1_VFD_I0,I0,,UL29_1_VFD_DISC,DISCONNECT AUX,,,,,
UL29_1_VFD,UL29_1_VFD_I1,I1,,SPARE,,,,,,
UL29_1_VFD,UL29_1_VFD_I2,I2,,UL29_1_TPE1,TRACKING PHOTOEYE,,,,,
UL29_1_VFD,UL29_1_VFD_I3,I3,,SPARE,,,,,,
UL29_1_VFD,UL29_1_VFD_IO0,IO0,,UL29_1_ENW1,WHEEL ENCODER,,,,,
UL29_1_VFD,UL29_1_VFD_IO1,IO1,,SPARE,,,,,,
UL29_1_VFD,UL29_1_VFD_SI0,SI0,,UL29_1_EPC1,E-STOP PULLCORD,,,,,
UL29_1_VFD,UL29_1_VFD_SI1,SI1,,UL29_1_EPC1_2,E-STOP PULLCORD,,,,,
UL29_1_VFD,UL29_1_VFD_SI2,SI2,,UL29_1_EPC2,E-STOP PULLCORD,,,,,
UL29_1_VFD,UL29_1_VFD_SI3,SI3,,UL29_1_EPC2_2,E-STOP PULLCORD,,,,,
UL29_1_VFD,UL29_1_VFD_SO0,SO0,,SPARE,,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X3_0,X3_0,,UL29_1_SS1_SPB,SS STATION START PUSHBUTTON,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X3_1,X3_1,,UL29_1_SS1_SPB_LT,SS STATION START PUSHBUTTON LIGHT,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X2_0,X2_0,,UL29_1_SS1_STPB,SS STATION STOP PUSHBUTTON,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X2_1,X2_1,,SPARE,,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X1_0,X1_0,,UL29_1_SS2_SPB,SS STATION START PUSHBUTTON,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X1_1,X1_1,,UL29_1_SS2_SPB_LT,SS STATION START PUSHBUTTON LIGHT,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X0_0,X0_0,,UL29_1_SS2_STPB,SS STATION STOP PUSHBUTTON,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X0_1,X0_1,,SPARE,,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X7_0,X7_0,,UL29_1_BCN1_R,RED BEACON LIGHT,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X7_1,X7_1,,SPARE,,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X6_0,X6_0,,UL29_1_BCN2_R,RED BEACON LIGHT,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X6_1,X6_1,,SPARE,,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X5_0,X5_0,,SPARE,,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X5_1,X5_1,,SPARE,,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X4_0,X4_0,,SPARE,,,,,,
UL29_1_FIOM1,UL29_1_FIOM1_X4_1,X4_1,,SPARE,,,,,,
UL29_10_VFD,UL29_10_VFD_I0,I0,,UL29_10_VFD_DISC,DISCONNECT AUX,,,,,
UL29_10_VFD,UL29_10_VFD_I1,I1,,SPARE,,,,,,
UL29_10_VFD,UL29_10_VFD_I2,I2,,UL29_10_TPE2,TRACKING PHOTOEYE,,,,,
UL29_10_VFD,UL29_10_VFD_I3,I3,,SPARE,,,,,,
UL29_10_VFD,UL29_10_VFD_IO0,IO0,,UL29_10_ENW1,WHEEL ENCODER,,,,,
UL29_10_VFD,UL29_10_VFD_IO1,IO1,,SPARE,,,,,,
UL29_10_VFD,UL29_10_VFD_SI0,SI0,,SPARE,,,,,,
UL29_10_VFD,UL29_10_VFD_SI1,SI1,,SPARE,,,,,,
UL29_10_VFD,UL29_10_VFD_SI2,SI2,,SPARE,,,,,,
UL29_10_VFD,UL29_10_VFD_SI3,SI3,,SPARE,,,,,,
UL29_10_VFD,UL29_10_VFD_SO0,SO0,,SPARE,,,,,,
UL29_11_VFD,UL29_11_VFD_I0,I0,,UL29_11_VFD_DISC,DISCONNECT AUX,,,,,
UL29_11_VFD,UL29_11_VFD_I1,I1,,SPARE,,,,,,
UL29_11_VFD,UL29_11_VFD_I2,I2,,UL29_11_TPE1,TRACKING PHOTOEYE,,,,,
UL29_11_VFD,UL29_11_VFD_I3,I3,,SPARE,,,,,,
UL29_11_VFD,UL29_11_VFD_IO0,IO0,,UL29_11_ENW1,WHEEL ENCODER,,,,,
UL29_11_VFD,UL29_11_VFD_IO1,IO1,,SPARE,,,,,,
UL29_11_VFD,UL29_11_VFD_SI0,SI0,,SPARE,,,,,,
UL29_11_VFD,UL29_11_VFD_SI1,SI1,,SPARE,,,,,,
UL29_11_VFD,UL29_11_VFD_SI2,SI2,,SPARE,,,,,,
UL29_11_VFD,UL29_11_VFD_SI3,SI3,,SPARE,,,,,,
UL29_11_VFD,UL29_11_VFD_SO0,SO0,,SPARE,,,,,,
UL29_12_VFD,UL29_12_VFD_I0,I0,,UL29_12_VFD_DISC,DISCONNECT AUX,,,,,
UL29_12_VFD,UL29_12_VFD_I1,I1,,SPARE,,,,,,
UL29_12_VFD,UL29_12_VFD_I2,I2,,UL29_12_TPE1,TRACKING PHOTOEYE,,,,,
UL29_12_VFD,UL29_12_VFD_I3,I3,,SPARE,,,,,,
UL29_12_VFD,UL29_12_VFD_IO0,IO0,,SPARE,,,,,,
UL29_12_VFD,UL29_12_VFD_IO1,IO1,,SPARE,,,,,,
UL29_12_VFD,UL29_12_VFD_SI0,SI0,,SPARE,,,,,,
UL29_12_VFD,UL29_12_VFD_SI1,SI1,,SPARE,,,,,,
UL29_12_VFD,UL29_12_VFD_SI2,SI2,,SPARE,,,,,,
UL29_12_VFD,UL29_12_VFD_SI3,SI3,,SPARE,,,,,,
UL29_12_VFD,UL29_12_VFD_SO0,SO0,,SPARE,,,,,,
UL29_13_VFD,UL29_13_VFD_I0,I0,,UL29_13_VFD_DISC,DISCONNECT AUX,,,,,
UL29_13_VFD,UL29_13_VFD_I1,I1,,SPARE,,,,,,
UL29_13_VFD,UL29_13_VFD_I2,I2,,UL29_13_TPE1,TRACKING PHOTOEYE,,,,,
UL29_13_VFD,UL29_13_VFD_I3,I3,,UL29_13_ENW1,WHEEL ENCODER,,,,,
UL29_13_VFD,UL29_13_VFD_IO0,IO0,,UL29_13_BCN1_H,HORN BEACON,,,,,
UL29_13_VFD,UL29_13_VFD_IO1,IO1,,SPARE,,,,,,
UL29_13_VFD,UL29_13_VFD_SI0,SI0,,SPARE,,,,,,
UL29_13_VFD,UL29_13_VFD_SI1,SI1,,SPARE,,,,,,
UL29_13_VFD,UL29_13_VFD_SI2,SI2,,SPARE,,,,,,
UL29_13_VFD,UL29_13_VFD_SI3,SI3,,SPARE,,,,,,
UL29_13_VFD,UL29_13_VFD_SO0,SO0,,SPARE,,,,,,
UL29_15_VFD,UL29_15_VFD_I0,I0,,UL29_15_VFD_DISC,DISCONNECT AUX,,,,,
UL29_15_VFD,UL29_15_VFD_I1,I1,,SPARE,,,,,,
UL29_15_VFD,UL29_15_VFD_I2,I2,,UL29_15_TPE1,TRACKING PHOTOEYE,,,,,
UL29_15_VFD,UL29_15_VFD_I3,I3,,SPARE,,,,,,
UL29_15_VFD,UL29_15_VFD_IO0,IO0,,UL29_15_ENSH1,SHAFT ENCODER,,,,,
UL29_15_VFD,UL29_15_VFD_IO1,IO1,,SPARE,,,,,,
UL29_15_VFD,UL29_15_VFD_SI0,SI0,,UL29_15_EPC1,E-STOP PULLCORD,,,,,
UL29_15_VFD,UL29_15_VFD_SI1,SI1,,UL29_15_EPC1_2,E-STOP PULLCORD,,,,,
UL29_15_VFD,UL29_15_VFD_SI2,SI2,,UL29_15_EPC2,E-STOP PULLCORD,,,,,
UL29_15_VFD,UL29_15_VFD_SI3,SI3,,UL29_15_EPC2_2,E-STOP PULLCORD,,,,,
UL29_15_VFD,UL29_15_VFD_SO0,SO0,,SPARE,,,,,,
UL29_16_VFD,UL29_16_VFD_I0,I0,,UL29_16_VFD_DISC,DISCONNECT AUX,,,,,
UL29_16_VFD,UL29_16_VFD_I1,I1,,SPARE,,,,,,
UL29_16_VFD,UL29_16_VFD_I2,I2,,UL29_16_TPE1,TRACKING PHOTOEYE,,,,,
UL29_16_VFD,UL29_16_VFD_I3,I3,,SPARE,,,,,,
UL29_16_VFD,UL29_16_VFD_IO0,IO0,,UL29_16_ENSH1,SHAFT ENCODER,,,,,
UL29_16_VFD,UL29_16_VFD_IO1,IO1,,SPARE,,,,,,
UL29_16_VFD,UL29_16_VFD_SI0,SI0,,SPARE,,,,,,
UL29_16_VFD,UL29_16_VFD_SI1,SI1,,SPARE,,,,,,
UL29_16_VFD,UL29_16_VFD_SI2,SI2,,SPARE,,,,,,
UL29_16_VFD,UL29_16_VFD_SI3,SI3,,SPARE,,,,,,
UL29_16_VFD,UL29_16_VFD_SO0,SO0,,UL29_17_SR1_STO1,SAFETY TORQUE OFF,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X3_0,X3_0,,UL29_15_SS1_SPB,SS STATION START PUSHBUTTON,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X3_1,X3_1,,UL29_15_SS1_SPB_LT,SS STATION START PUSHBUTTON LIGHT,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X2_0,X2_0,,UL29_15_SS1_STPB,SS STATION STOP PUSHBUTTON,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X2_1,X2_1,,SPARE,,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X1_0,X1_0,,UL29_15_SS2_SPB,SS STATION START PUSHBUTTON,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X1_1,X1_1,,UL29_15_SS2_SPB_LT,SS STATION START PUSHBUTTON LIGHT,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X0_0,X0_0,,UL29_15_SS2_STPB,SS STATION STOP PUSHBUTTON,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X0_1,X0_1,,SPARE,,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X7_0,X7_0,,UL29_15_BCN1_A,AMBER BEACON LIGHT,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X7_1,X7_1,,UL29_15_BCN1_R,RED BEACON LIGHT,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X6_0,X6_0,,UL29_15_BCN2_R,RED BEACON LIGHT,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X6_1,X6_1,,SPARE,,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X5_0,X5_0,,SPARE,,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X5_1,X5_1,,SPARE,,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X4_0,X4_0,,SPARE,,,,,,
UL29_17_FIOM1,UL29_17_FIOM1_X4_1,X4_1,,SPARE,,,,,,
UL29_18_VFD,UL29_18_VFD_I0,I0,,UL29_18_VFD_DISC,DISCONNECT AUX,,,,,
UL29_18_VFD,UL29_18_VFD_I1,I1,,SPARE,,,,,,
UL29_18_VFD,UL29_18_VFD_I2,I2,,UL29_18_TPE1,TRACKING PHOTOEYE,,,,,
UL29_18_VFD,UL29_18_VFD_I3,I3,,UL29_17_TPE1,TRACKING PHOTOEYE,,,,,
UL29_18_VFD,UL29_18_VFD_IO0,IO0,,UL29_18_ENW1,WHEEL ENCODER,,,,,
UL29_18_VFD,UL29_18_VFD_IO1,IO1,,SPARE,,,,,,
UL29_18_VFD,UL29_18_VFD_SI0,SI0,,SPARE,,,,,,
UL29_18_VFD,UL29_18_VFD_SI1,SI1,,SPARE,,,,,,
UL29_18_VFD,UL29_18_VFD_SI2,SI2,,SPARE,,,,,,
UL29_18_VFD,UL29_18_VFD_SI3,SI3,,SPARE,,,,,,
UL29_18_VFD,UL29_18_VFD_SO0,SO0,,SPARE,,,,,,
UL29_2_VFD,UL29_2_VFD_I0,I0,,UL29_2_VFD_DISC,DISCONNECT AUX,,,,,
UL29_2_VFD,UL29_2_VFD_I1,I1,,SPARE,,,,,,
UL29_2_VFD,UL29_2_VFD_I2,I2,,UL29_2_TPE1,TRACKING PHOTOEYE,,,,,
UL29_2_VFD,UL29_2_VFD_I3,I3,,SPARE,,,,,,
UL29_2_VFD,UL29_2_VFD_IO0,IO0,,UL29_2_ENW1,WHEEL ENCODER,,,,,
UL29_2_VFD,UL29_2_VFD_IO1,IO1,,SPARE,,,,,,
UL29_2_VFD,UL29_2_VFD_SI0,SI0,,SPARE,,,,,,
UL29_2_VFD,UL29_2_VFD_SI1,SI1,,SPARE,,,,,,
UL29_2_VFD,UL29_2_VFD_SI2,SI2,,SPARE,,,,,,
UL29_2_VFD,UL29_2_VFD_SI3,SI3,,SPARE,,,,,,
UL29_2_VFD,UL29_2_VFD_SO0,SO0,,SPARE,,,,,,
UL29_3_VFD,UL29_3_VFD_I0,I0,,UL29_3_VFD_DISC,DISCONNECT AUX,,,,,
UL29_3_VFD,UL29_3_VFD_I1,I1,,SPARE,,,,,,
UL29_3_VFD,UL29_3_VFD_I2,I2,,UL29_3_TPE1,TRACKING PHOTOEYE,,,,,
UL29_3_VFD,UL29_3_VFD_I3,I3,,SPARE,,,,,,
UL29_3_VFD,UL29_3_VFD_IO0,IO0,,UL29_3_ENSH1,SHAFT ENCODER,,,,,
UL29_3_VFD,UL29_3_VFD_IO1,IO1,,SPARE,,,,,,
UL29_3_VFD,UL29_3_VFD_SI0,SI0,,SPARE,,,,,,
UL29_3_VFD,UL29_3_VFD_SI1,SI1,,SPARE,,,,,,
UL29_3_VFD,UL29_3_VFD_SI2,SI2,,SPARE,,,,,,
UL29_3_VFD,UL29_3_VFD_SI3,SI3,,SPARE,,,,,,
UL29_3_VFD,UL29_3_VFD_SO0,SO0,,SPARE,,,,,,
UL29_30_VFD,UL29_30_VFD_I0,I0,,UL29_30_VFD_DISC,DISCONNECT AUX,,,,,
UL29_30_VFD,UL29_30_VFD_I1,I1,,SPARE,,,,,,
UL29_30_VFD,UL29_30_VFD_I2,I2,,UL29_30_TPE1,TRACKING PHOTOEYE,,,,,
UL29_30_VFD,UL29_30_VFD_I3,I3,,SPARE,,,,,,
UL29_30_VFD,UL29_30_VFD_IO0,IO0,,UL29_30_ENW1,WHEEL ENCODER,,,,,
UL29_30_VFD,UL29_30_VFD_IO1,IO1,,SPARE,,,,,,
UL29_30_VFD,UL29_30_VFD_SI0,SI0,,UL29_30_EPC1,E-STOP PULLCORD,,,,,
UL29_30_VFD,UL29_30_VFD_SI1,SI1,,UL29_30_EPC1_2,E-STOP PULLCORD,,,,,
UL29_30_VFD,UL29_30_VFD_SI2,SI2,,UL29_30_EPC2,E-STOP PULLCORD,,,,,
UL29_30_VFD,UL29_30_VFD_SI3,SI3,,UL29_30_EPC2_2,E-STOP PULLCORD,,,,,
UL29_30_VFD,UL29_30_VFD_SO0,SO0,,SPARE,,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X3_0,X3_0,,UL29_30_S1_PB,START PUSHBUTTON,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X3_1,X3_1,,UL29_30_S1_PB_LT,START PUSHBUTTON LIGHT,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X2_0,X2_0,,UL29_30_S2_PB,START PUSHBUTTON,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X2_1,X2_1,,UL29_30_S2_PB_LT,START PUSHBUTTON LIGHT,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X1_0,X1_0,,UL29_30_BCN1_B,BLUE BEACON LIGHT,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X1_1,X1_1,,UL29_30_BCN1_R,RED BEACON LIGHT,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X0_0,X0_0,,UL29_30_BCN2_R,RED BEACON LIGHT,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X0_1,X0_1,,SPARE,,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X7_0,X7_0,,UL29_14_TPE1,TRACKING PHOTOEYE,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X7_1,X7_1,,SPARE,,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X6_0,X6_0,,UL29_31_TPE1,TRACKING PHOTOEYE,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X6_1,X6_1,,SPARE,,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X5_0,X5_0,,SPARE,,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X5_1,X5_1,,SPARE,,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X4_0,X4_0,,SPARE,,,,,,
UL29_30_FIOM1,UL29_30_FIOM1_X4_1,X4_1,,SPARE,,,,,,
UL29_4_VFD,UL29_4_VFD_I0,I0,,UL29_4_VFD_DISC,DISCONNECT AUX,,,,,
UL29_4_VFD,UL29_4_VFD_I1,I1,,SPARE,,,,,,
UL29_4_VFD,UL29_4_VFD_I2,I2,,UL29_4_TPE1,TRACKING PHOTOEYE,,,,,
UL29_4_VFD,UL29_4_VFD_I3,I3,,SPARE,,,,,,
UL29_4_VFD,UL29_4_VFD_IO0,IO0,,UL29_4_ENSH1,SHAFT ENCODER,,,,,
UL29_4_VFD,UL29_4_VFD_IO1,IO1,,SPARE,,,,,,
UL29_4_VFD,UL29_4_VFD_SI0,SI0,,SPARE,,,,,,
UL29_4_VFD,UL29_4_VFD_SI1,SI1,,SPARE,,,,,,
UL29_4_VFD,UL29_4_VFD_SI2,SI2,,SPARE,,,,,,
UL29_4_VFD,UL29_4_VFD_SI3,SI3,,SPARE,,,,,,
UL29_4_VFD,UL29_4_VFD_SO0,SO0,,SPARE,,,,,,
UL29_5_VFD,UL29_5_VFD_I0,I0,,UL29_5_VFD_DISC,DISCONNECT AUX,,,,,
UL29_5_VFD,UL29_5_VFD_I1,I1,,SPARE,,,,,,
UL29_5_VFD,UL29_5_VFD_I2,I2,,UL29_5_TPE1,TRACKING PHOTOEYE,,,,,
UL29_5_VFD,UL29_5_VFD_I3,I3,,SPARE,,,,,,
UL29_5_VFD,UL29_5_VFD_IO0,IO0,,UL29_5_ENSH1,SHAFT ENCODER,,,,,
UL29_5_VFD,UL29_5_VFD_IO1,IO1,,SPARE,,,,,,
UL29_5_VFD,UL29_5_VFD_SI0,SI0,,SPARE,,,,,,
UL29_5_VFD,UL29_5_VFD_SI1,SI1,,SPARE,,,,,,
UL29_5_VFD,UL29_5_VFD_SI2,SI2,,SPARE,,,,,,
UL29_5_VFD,UL29_5_VFD_SI3,SI3,,SPARE,,,,,,
UL29_5_VFD,UL29_5_VFD_SO0,SO0,,SPARE,,,,,,
UL29_6_VFD,UL29_6_VFD_I0,I0,,UL29_6_VFD_DISC,DISCONNECT AUX,,,,,
UL29_6_VFD,UL29_6_VFD_I1,I1,,SPARE,,,,,,
UL29_6_VFD,UL29_6_VFD_I2,I2,,UL29_6_TPE1,TRACKING PHOTOEYE,,,,,
UL29_6_VFD,UL29_6_VFD_I3,I3,,SPARE,,,,,,
UL29_6_VFD,UL29_6_VFD_IO0,IO0,,UL29_6_ENSH1,SHAFT ENCODER,,,,,
UL29_6_VFD,UL29_6_VFD_IO1,IO1,,SPARE,,,,,,
UL29_6_VFD,UL29_6_VFD_SI0,SI0,,SPARE,,,,,,
UL29_6_VFD,UL29_6_VFD_SI1,SI1,,SPARE,,,,,,
UL29_6_VFD,UL29_6_VFD_SI2,SI2,,SPARE,,,,,,
UL29_6_VFD,UL29_6_VFD_SI3,SI3,,SPARE,,,,,,
UL29_6_VFD,UL29_6_VFD_SO0,SO0,,SPARE,,,,,,
UL29_7_VFD,UL29_7_VFD_I0,I0,,UL29_7_VFD_DISC,DISCONNECT AUX,,,,,
UL29_7_VFD,UL29_7_VFD_I1,I1,,SPARE,,,,,,
UL29_7_VFD,UL29_7_VFD_I2,I2,,UL29_7_TPE1,TRACKING PHOTOEYE,,,,,
UL29_7_VFD,UL29_7_VFD_I3,I3,,UL29_7_ENSH1,SHAFT ENCODER,,,,,
UL29_7_VFD,UL29_7_VFD_IO0,IO0,,UL29_8_S1_PB,START PUSHBUTTON,,,,,
UL29_7_VFD,UL29_7_VFD_IO1,IO1,,UL29_8_S1_PB_LT,START PUSHBUTTON LIGHT,,,,,
UL29_7_VFD,UL29_7_VFD_SI0,SI0,,UL29_8_EPC1,E-STOP PULLCORD,,,,,
UL29_7_VFD,UL29_7_VFD_SI1,SI1,,UL29_8_EPC1_2,E-STOP PULLCORD,,,,,
UL29_7_VFD,UL29_7_VFD_SI2,SI2,,SPARE,,,,,,
UL29_7_VFD,UL29_7_VFD_SI3,SI3,,SPARE,,,,,,
UL29_7_VFD,UL29_7_VFD_SO0,SO0,,SPARE,,,,,,
UL29_8_VFD,UL29_8_VFD_I0,I0,,UL29_8_VFD_DISC,DISCONNECT AUX,,,,,
UL29_8_VFD,UL29_8_VFD_I1,I1,,SPARE,,,,,,
UL29_8_VFD,UL29_8_VFD_I2,I2,,UL29_8_TPE1,TRACKING PHOTOEYE,,,,,
UL29_8_VFD,UL29_8_VFD_I3,I3,,UL29_8_TPE2,TRACKING PHOTOEYE,,,,,
UL29_8_VFD,UL29_8_VFD_IO0,IO0,,UL29_8_ENW1,WHEEL ENCODER,,,,,
UL29_8_VFD,UL29_8_VFD_IO1,IO1,,SPARE,,,,,,
UL29_8_VFD,UL29_8_VFD_SI0,SI0,,UL29_8_EPC2,E-STOP PULLCORD,,,,,
UL29_8_VFD,UL29_8_VFD_SI1,SI1,,UL29_8_EPC2_2,E-STOP PULLCORD,,,,,
UL29_8_VFD,UL29_8_VFD_SI2,SI2,,SPARE,,,,,,
UL29_8_VFD,UL29_8_VFD_SI3,SI3,,SPARE,,,,,,
UL29_8_VFD,UL29_8_VFD_SO0,SO0,,SPARE,,,,,,
UL29_9A_VFD,UL29_9A_VFD_I0,I0,,UL29_9A_VFD_DISC,DISCONNECT AUX,,,,,
UL29_9A_VFD,UL29_9A_VFD_I1,I1,,SPARE,,,,,,
UL29_9A_VFD,UL29_9A_VFD_I2,I2,,UL29_10_TPE1,TRACKING PHOTOEYE,,,,,
UL29_9A_VFD,UL29_9A_VFD_I3,I3,,SPARE,,,,,,
UL29_9A_VFD,UL29_9A_VFD_IO0,IO0,,SPARE,,,,,,
UL29_9A_VFD,UL29_9A_VFD_IO1,IO1,,SPARE,,,,,,
UL29_9A_VFD,UL29_9A_VFD_SI0,SI0,,SPARE,,,,,,
UL29_9A_VFD,UL29_9A_VFD_SI1,SI1,,SPARE,,,,,,
UL29_9A_VFD,UL29_9A_VFD_SI2,SI2,,SPARE,,,,,,
UL29_9A_VFD,UL29_9A_VFD_SI3,SI3,,SPARE,,,,,,
UL29_9A_VFD,UL29_9A_VFD_SO0,SO0,,SPARE,,,,,,
UL29_9B_VFD,UL29_9B_VFD_I0,I0,,UL29_9B_VFD_DISC,DISCONNECT AUX,,,,,
UL29_9B_VFD,UL29_9B_VFD_I1,I1,,SPARE,,,,,,
UL29_9B_VFD,UL29_9B_VFD_I2,I2,,SPARE,,,,,,
UL29_9B_VFD,UL29_9B_VFD_I3,I3,,SPARE,,,,,,
UL29_9B_VFD,UL29_9B_VFD_IO0,IO0,,UL29_8_BCN1_R,RED BEACON LIGHT,,,,,
UL29_9B_VFD,UL29_9B_VFD_IO1,IO1,,SPARE,,,,,,
UL29_9B_VFD,UL29_9B_VFD_SI0,SI0,,SPARE,,,,,,
UL29_9B_VFD,UL29_9B_VFD_SI1,SI1,,SPARE,,,,,,
UL29_9B_VFD,UL29_9B_VFD_SI2,SI2,,SPARE,,,,,,
UL29_9B_VFD,UL29_9B_VFD_SI3,SI3,,SPARE,,,,,,
UL29_9B_VFD,UL29_9B_VFD_SO0,SO0,,SPARE,,,,,,
1 TAGNAME ADDR TERM TERMDESC DESCA DESCB DESCC DESCD DESCE INST LOC
2 PDP01_FIOM1 PDP01_FIOM1_X3_0 X3_0 PDP01_CB1 CIRCUIT BREAKER MONITORING
3 PDP01_FIOM1 PDP01_FIOM1_X3_1 X3_1 PDP01_CB2 CIRCUIT BREAKER MONITORING
4 PDP01_FIOM1 PDP01_FIOM1_X2_0 X2_0 PDP01_CB3 CIRCUIT BREAKER MONITORING
5 PDP01_FIOM1 PDP01_FIOM1_X2_1 X2_1 PDP01_CB4 CIRCUIT BREAKER MONITORING
6 PDP01_FIOM1 PDP01_FIOM1_X1_0 X1_0 PDP01_CB5 CIRCUIT BREAKER MONITORING
7 PDP01_FIOM1 PDP01_FIOM1_X1_1 X1_1 SPARE
8 PDP01_FIOM1 PDP01_FIOM1_X0_0 X0_0 PDP01_CB6 CIRCUIT BREAKER MONITORING
9 PDP01_FIOM1 PDP01_FIOM1_X0_1 X0_1 SPARE
10 PDP01_FIOM1 PDP01_FIOM1_X7_0 X7_0 PDP01_CB7 CIRCUIT BREAKER MONITORING
11 PDP01_FIOM1 PDP01_FIOM1_X7_1 X7_1 PDP01_CB8 CIRCUIT BREAKER MONITORING
12 PDP01_FIOM1 PDP01_FIOM1_X6_0 X6_0 PDP01_CB9 CIRCUIT BREAKER MONITORING
13 PDP01_FIOM1 PDP01_FIOM1_X6_1 X6_1 PDP01_CB10 CIRCUIT BREAKER MONITORING
14 PDP01_FIOM1 PDP01_FIOM1_X5_0 X5_0 PDP01_PWM1 PHASE MONITOR
15 PDP01_FIOM1 PDP01_FIOM1_X5_1 X5_1 SPARE
16 PDP01_FIOM1 PDP01_FIOM1_X4_0 X4_0 PDP01_FIOH1 I/O LINK HUB
17 PDP01_FIOM1 PDP01_FIOM1_X4_1 X4_1 SPARE
18 PDP01_FIOH1 PDP01_FIOH1_C7_A C7_A PDP01_CB11 CIRCUIT BREAKER MONITORING
19 PDP01_FIOH1 PDP01_FIOH1_C7_B C7_B PDP01_CB12 CIRCUIT BREAKER MONITORING
20 PDP01_FIOH1 PDP01_FIOH1_C5_A C5_A PDP01_CB13 CIRCUIT BREAKER MONITORING
21 PDP01_FIOH1 PDP01_FIOH1_C5_B C5_B PDP01_CB14 CIRCUIT BREAKER MONITORING
22 PDP01_FIOH1 PDP01_FIOH1_C3_A C3_A PDP01_CB15 CIRCUIT BREAKER MONITORING
23 PDP01_FIOH1 PDP01_FIOH1_C3_B C3_B PDP01_CB16 CIRCUIT BREAKER MONITORING
24 PDP01_FIOH1 PDP01_FIOH1_C1_A C1_A PDP01_CB17 CIRCUIT BREAKER MONITORING
25 PDP01_FIOH1 PDP01_FIOH1_C1_B C1_B PDP01_CB18 CIRCUIT BREAKER MONITORING
26 PDP01_FIOH1 PDP01_FIOH1_C8_A C8_A PDP01_CB19 CIRCUIT BREAKER MONITORING
27 PDP01_FIOH1 PDP01_FIOH1_C8_B C8_B PDP01_CB20 CIRCUIT BREAKER MONITORING
28 PDP01_FIOH1 PDP01_FIOH1_C6_A C6_A PDP01_CB21 CIRCUIT BREAKER MONITORING
29 PDP01_FIOH1 PDP01_FIOH1_C6_B C6_B PDP01_CB22 CIRCUIT BREAKER MONITORING
30 PDP01_FIOH1 PDP01_FIOH1_C4_A C4_A PDP01_CB23 CIRCUIT BREAKER MONITORING
31 PDP01_FIOH1 PDP01_FIOH1_C4_B C4_B PDP01_CB24 CIRCUIT BREAKER MONITORING
32 PDP01_FIOH1 PDP01_FIOH1_C2_A C2_A PDP01_CB25 CIRCUIT BREAKER MONITORING
33 PDP01_FIOH1 PDP01_FIOH1_C2_B C2_B PDP01_CB26 CIRCUIT BREAKER MONITORING
34 UL27_10_VFD UL27_10_VFD_I0 I0 UL27_10_VFD_DISC DISCONNECT AUX
35 UL27_10_VFD UL27_10_VFD_I1 I1 SPARE
36 UL27_10_VFD UL27_10_VFD_I2 I2 SPARE
37 UL27_10_VFD UL27_10_VFD_I3 I3 SPARE
38 UL27_10_VFD UL27_10_VFD_IO0 IO0 UL29_8_S2_PB START PUSHBUTTON
39 UL27_10_VFD UL27_10_VFD_IO1 IO1 UL29_8_S2_PB_LT START PUSHBUTTON LIGHT
40 UL27_10_VFD UL27_10_VFD_SI0 SI0 SPARE
41 UL27_10_VFD UL27_10_VFD_SI1 SI1 SPARE
42 UL27_10_VFD UL27_10_VFD_SI2 SI2 SPARE
43 UL27_10_VFD UL27_10_VFD_SI3 SI3 SPARE
44 UL27_10_VFD UL27_10_VFD_SO0 SO0 SPARE
45 UL27_2_VFD UL27_2_VFD_I0 I0 UL27_2_VFD_DISC DISCONNECT AUX
46 UL27_2_VFD UL27_2_VFD_I1 I1 SPARE
47 UL27_2_VFD UL27_2_VFD_I2 I2 UL27_2_TPE2 TRACKING PHOTOEYE
48 UL27_2_VFD UL27_2_VFD_I3 I3 SPARE
49 UL27_2_VFD UL27_2_VFD_IO0 IO0 UL27_2_ENW1 WHEEL ENCODER
50 UL27_2_VFD UL27_2_VFD_IO1 IO1 SPARE
51 UL27_2_VFD UL27_2_VFD_SI0 SI0 UL27_2_EPC1 E-STOP PULLCORD
52 UL27_2_VFD UL27_2_VFD_SI1 SI1 UL27_2_EPC1_2 E-STOP PULLCORD
53 UL27_2_VFD UL27_2_VFD_SI2 SI2 UL27_2_EPC2 E-STOP PULLCORD
54 UL27_2_VFD UL27_2_VFD_SI3 SI3 UL27_2_EPC2_2 E-STOP PULLCORD
55 UL27_2_VFD UL27_2_VFD_SO0 SO0 UL27_2_SR1_STO1 SAFETY TORQUE OFF
56 UL27_2_FIOM1 UL27_2_FIOM1_X3_0 X3_0 UL27_2_SS1_SPB SS STATION START PUSHBUTTON
57 UL27_2_FIOM1 UL27_2_FIOM1_X3_1 X3_1 UL27_2_SS1_SPB_LT SS STATION START PUSHBUTTON LIGHT
58 UL27_2_FIOM1 UL27_2_FIOM1_X2_0 X2_0 UL27_2_SS1_STPB SS STATION STOP PUSHBUTTON
59 UL27_2_FIOM1 UL27_2_FIOM1_X2_1 X2_1 SPARE
60 UL27_2_FIOM1 UL27_2_FIOM1_X1_0 X1_0 UL27_2_SS2_SPB SS STATION START PUSHBUTTON
61 UL27_2_FIOM1 UL27_2_FIOM1_X1_1 X1_1 UL27_2_SS2_SPB_LT SS STATION START PUSHBUTTON LIGHT
62 UL27_2_FIOM1 UL27_2_FIOM1_X0_0 X0_0 UL27_2_SS2_STPB SS STATION STOP PUSHBUTTON
63 UL27_2_FIOM1 UL27_2_FIOM1_X0_1 X0_1 SPARE
64 UL27_2_FIOM1 UL27_2_FIOM1_X7_0 X7_0 UL27_2_BCN1_R RED BEACON LIGHT
65 UL27_2_FIOM1 UL27_2_FIOM1_X7_1 X7_1 SPARE
66 UL27_2_FIOM1 UL27_2_FIOM1_X6_0 X6_0 UL27_2_BCN2_R RED BEACON LIGHT
67 UL27_2_FIOM1 UL27_2_FIOM1_X6_1 X6_1 SPARE
68 UL27_2_FIOM1 UL27_2_FIOM1_X5_0 X5_0 UL27_2_TPE1 TRACKING PHOTOEYE
69 UL27_2_FIOM1 UL27_2_FIOM1_X5_1 X5_1 SPARE
70 UL27_2_FIOM1 UL27_2_FIOM1_X4_0 X4_0 SPARE
71 UL27_2_FIOM1 UL27_2_FIOM1_X4_1 X4_1 SPARE
72 UL27_3_VFD UL27_3_VFD_I0 I0 UL27_3_VFD_DISC DISCONNECT AUX
73 UL27_3_VFD UL27_3_VFD_I1 I1 SPARE
74 UL27_3_VFD UL27_3_VFD_I2 I2 UL27_3_TPE1 TRACKING PHOTOEYE
75 UL27_3_VFD UL27_3_VFD_I3 I3 SPARE
76 UL27_3_VFD UL27_3_VFD_IO0 IO0 UL27_3_ENSH1 SHAFT ENCODER
77 UL27_3_VFD UL27_3_VFD_IO1 IO1 SPARE
78 UL27_3_VFD UL27_3_VFD_SI0 SI0 SPARE
79 UL27_3_VFD UL27_3_VFD_SI1 SI1 SPARE
80 UL27_3_VFD UL27_3_VFD_SI2 SI2 SPARE
81 UL27_3_VFD UL27_3_VFD_SI3 SI3 SPARE
82 UL27_3_VFD UL27_3_VFD_SO0 SO0 SPARE
83 UL27_4_VFD UL27_4_VFD_I0 I0 UL27_4_VFD_DISC DISCONNECT AUX
84 UL27_4_VFD UL27_4_VFD_I1 I1 SPARE
85 UL27_4_VFD UL27_4_VFD_I2 I2 UL27_4_TPE1 TRACKING PHOTOEYE
86 UL27_4_VFD UL27_4_VFD_I3 I3 SPARE
87 UL27_4_VFD UL27_4_VFD_IO0 IO0 UL27_4_ENW1 WHEEL ENCODER
88 UL27_4_VFD UL27_4_VFD_IO1 IO1 SPARE
89 UL27_4_VFD UL27_4_VFD_SI0 SI0 SPARE
90 UL27_4_VFD UL27_4_VFD_SI1 SI1 SPARE
91 UL27_4_VFD UL27_4_VFD_SI2 SI2 SPARE
92 UL27_4_VFD UL27_4_VFD_SI3 SI3 SPARE
93 UL27_4_VFD UL27_4_VFD_SO0 SO0 SPARE
94 UL27_5_VFD UL27_5_VFD_I0 I0 UL27_5_VFD_DISC DISCONNECT AUX
95 UL27_5_VFD UL27_5_VFD_I1 I1 SPARE
96 UL27_5_VFD UL27_5_VFD_I2 I2 UL27_5_TPE1 TRACKING PHOTOEYE
97 UL27_5_VFD UL27_5_VFD_I3 I3 UL27_5_ENW1 WHEEL ENCODER
98 UL27_5_VFD UL27_5_VFD_IO0 IO0 UL27_5_S2_PB START PUSHBUTTON
99 UL27_5_VFD UL27_5_VFD_IO1 IO1 UL27_5_S2_PB_LT START PUSHBUTTON LIGHT
100 UL27_5_VFD UL27_5_VFD_SI0 SI0 UL27_5_EPC1 E-STOP PULLCORD
101 UL27_5_VFD UL27_5_VFD_SI1 SI1 UL27_5_EPC1_2 E-STOP PULLCORD
102 UL27_5_VFD UL27_5_VFD_SI2 SI2 UL27_5_EPC2 E-STOP PULLCORD
103 UL27_5_VFD UL27_5_VFD_SI3 SI3 UL27_5_EPC2_2 E-STOP PULLCORD
104 UL27_5_VFD UL27_5_VFD_SO0 SO0 UL27_5_BCN2_R RED BEACON LIGHT
105 UL27_6_VFD UL27_6_VFD_I0 I0 UL27_6_VFD_DISC DISCONNECT AUX
106 UL27_6_VFD UL27_6_VFD_I1 I1 SPARE
107 UL27_6_VFD UL27_6_VFD_I2 I2 UL27_6_TPE1 TRACKING PHOTOEYE
108 UL27_6_VFD UL27_6_VFD_I3 I3 UL27_6_ENSH1 SHAFT ENCODER
109 UL27_6_VFD UL27_6_VFD_IO0 IO0 UL27_5_S1_PB START PUSHBUTTON
110 UL27_6_VFD UL27_6_VFD_IO1 IO1 UL27_5_S1_PB_LT START PUSHBUTTON LIGHT
111 UL27_6_VFD UL27_6_VFD_SI0 SI0 SPARE
112 UL27_6_VFD UL27_6_VFD_SI1 SI1 SPARE
113 UL27_6_VFD UL27_6_VFD_SI2 SI2 SPARE
114 UL27_6_VFD UL27_6_VFD_SI3 SI3 SPARE
115 UL27_6_VFD UL27_6_VFD_SO0 SO0 SPARE
116 UL27_7_VFD UL27_7_VFD_I0 I0 UL27_7_VFD_DISC DISCONNECT AUX
117 UL27_7_VFD UL27_7_VFD_I1 I1 SPARE
118 UL27_7_VFD UL27_7_VFD_I2 I2 UL27_7_TPE1 TRACKING PHOTOEYE
119 UL27_7_VFD UL27_7_VFD_I3 I3 UL27_7_ENSH1 SHAFT ENCODER
120 UL27_7_VFD UL27_7_VFD_IO0 IO0 UL27_5_BCN1_A AMBER BEACON LIGHT
121 UL27_7_VFD UL27_7_VFD_IO1 IO1 UL27_5_BCN1_R RED BEACON LIGHT
122 UL27_7_VFD UL27_7_VFD_SI0 SI0 SPARE
123 UL27_7_VFD UL27_7_VFD_SI1 SI1 SPARE
124 UL27_7_VFD UL27_7_VFD_SI2 SI2 SPARE
125 UL27_7_VFD UL27_7_VFD_SI3 SI3 SPARE
126 UL27_7_VFD UL27_7_VFD_SO0 SO0 SPARE
127 UL27_8_VFD UL27_8_VFD_I0 I0 UL27_8_VFD_DISC DISCONNECT AUX
128 UL27_8_VFD UL27_8_VFD_I1 I1 SPARE
129 UL27_8_VFD UL27_8_VFD_I2 I2 UL27_8_TPE1 TRACKING PHOTOEYE
130 UL27_8_VFD UL27_8_VFD_I3 I3 SPARE
131 UL27_8_VFD UL27_8_VFD_IO0 IO0 UL27_8_ENSH1 SHAFT ENCODER
132 UL27_8_VFD UL27_8_VFD_IO1 IO1 SPARE
133 UL27_8_VFD UL27_8_VFD_SI0 SI0 SPARE
134 UL27_8_VFD UL27_8_VFD_SI1 SI1 SPARE
135 UL27_8_VFD UL27_8_VFD_SI2 SI2 SPARE
136 UL27_8_VFD UL27_8_VFD_SI3 SI3 SPARE
137 UL27_8_VFD UL27_8_VFD_SO0 SO0 SPARE
138 UL27_9_VFD UL27_9_VFD_I0 I0 UL27_9_VFD_DISC DISCONNECT AUX
139 UL27_9_VFD UL27_9_VFD_I1 I1 SPARE
140 UL27_9_VFD UL27_9_VFD_I2 I2 UL27_9_TPE1 TRACKING PHOTOEYE
141 UL27_9_VFD UL27_9_VFD_I3 I3 SPARE
142 UL27_9_VFD UL27_9_VFD_IO0 IO0 UL27_9_ENSH1 SHAFT ENCODER
143 UL27_9_VFD UL27_9_VFD_IO1 IO1 SPARE
144 UL27_9_VFD UL27_9_VFD_SI0 SI0 SPARE
145 UL27_9_VFD UL27_9_VFD_SI1 SI1 SPARE
146 UL27_9_VFD UL27_9_VFD_SI2 SI2 SPARE
147 UL27_9_VFD UL27_9_VFD_SI3 SI3 SPARE
148 UL27_9_VFD UL27_9_VFD_SO0 SO0 SPARE
149 UL28_2_VFD UL28_2_VFD_I0 I0 UL28_2_VFD_DISC DISCONNECT AUX
150 UL28_2_VFD UL28_2_VFD_I1 I1 SPARE
151 UL28_2_VFD UL28_2_VFD_I2 I2 UL28_2_TPE2 TRACKING PHOTOEYE
152 UL28_2_VFD UL28_2_VFD_I3 I3 SPARE
153 UL28_2_VFD UL28_2_VFD_IO0 IO0 UL28_2_ENW1 WHEEL ENCODER
154 UL28_2_VFD UL28_2_VFD_IO1 IO1 SPARE
155 UL28_2_VFD UL28_2_VFD_SI0 SI0 UL28_2_EPC1 E-STOP PULLCORD
156 UL28_2_VFD UL28_2_VFD_SI1 SI1 UL28_2_EPC1_2 E-STOP PULLCORD
157 UL28_2_VFD UL28_2_VFD_SI2 SI2 UL28_2_EPC2 E-STOP PULLCORD
158 UL28_2_VFD UL28_2_VFD_SI3 SI3 UL28_2_EPC2_2 E-STOP PULLCORD
159 UL28_2_VFD UL28_2_VFD_SO0 SO0 UL28_2_SR1_STO1 SAFETY TORQUE OFF
160 UL28_2_FIOM1 UL28_2_FIOM1_X3_0 X3_0 UL28_2_SS1_SPB SS STATION START PUSHBUTTON
161 UL28_2_FIOM1 UL28_2_FIOM1_X3_1 X3_1 UL28_2_SS1_SPB_LT SS STATION START PUSHBUTTON LIGHT
162 UL28_2_FIOM1 UL28_2_FIOM1_X2_0 X2_0 UL28_2_SS1_STPB SS STATION STOP PUSHBUTTON
163 UL28_2_FIOM1 UL28_2_FIOM1_X2_1 X2_1 SPARE
164 UL28_2_FIOM1 UL28_2_FIOM1_X1_0 X1_0 UL28_2_SS2_SPB SS STATION START PUSHBUTTON
165 UL28_2_FIOM1 UL28_2_FIOM1_X1_1 X1_1 UL28_2_SS2_SPB_LT SS STATION START PUSHBUTTON LIGHT
166 UL28_2_FIOM1 UL28_2_FIOM1_X0_0 X0_0 UL28_2_SS2_STPB SS STATION STOP PUSHBUTTON
167 UL28_2_FIOM1 UL28_2_FIOM1_X0_1 X0_1 SPARE
168 UL28_2_FIOM1 UL28_2_FIOM1_X7_0 X7_0 UL28_2_BCN1_R RED BEACON LIGHT
169 UL28_2_FIOM1 UL28_2_FIOM1_X7_1 X7_1 SPARE
170 UL28_2_FIOM1 UL28_2_FIOM1_X6_0 X6_0 UL28_2_BCN2_R RED BEACON LIGHT
171 UL28_2_FIOM1 UL28_2_FIOM1_X6_1 X6_1 SPARE
172 UL28_2_FIOM1 UL28_2_FIOM1_X5_0 X5_0 UL28_2_TPE1 TRACKING PHOTOEYE
173 UL28_2_FIOM1 UL28_2_FIOM1_X5_1 X5_1 SPARE
174 UL28_2_FIOM1 UL28_2_FIOM1_X4_0 X4_0 SPARE
175 UL28_2_FIOM1 UL28_2_FIOM1_X4_1 X4_1 SPARE
176 UL28_3_VFD UL28_3_VFD_I0 I0 UL28_3_VFD_DISC DISCONNECT AUX
177 UL28_3_VFD UL28_3_VFD_I1 I1 SPARE
178 UL28_3_VFD UL28_3_VFD_I2 I2 UL28_3_TPE1 TRACKING PHOTOEYE
179 UL28_3_VFD UL28_3_VFD_I3 I3 UL28_3_ENW1 WHEEL ENCODER
180 UL28_3_VFD UL28_3_VFD_IO0 IO0 UL28_3_S2_PB START PUSHBUTTON
181 UL28_3_VFD UL28_3_VFD_IO1 IO1 UL28_3_S2_PB_LT START PUSHBUTTON LIGHT
182 UL28_3_VFD UL28_3_VFD_SI0 SI0 UL28_3_EPC1 E-STOP PULLCORD
183 UL28_3_VFD UL28_3_VFD_SI1 SI1 UL28_3_EPC1_2 E-STOP PULLCORD
184 UL28_3_VFD UL28_3_VFD_SI2 SI2 UL28_3_EPC2 E-STOP PULLCORD
185 UL28_3_VFD UL28_3_VFD_SI3 SI3 UL28_3_EPC2_2 E-STOP PULLCORD
186 UL28_3_VFD UL28_3_VFD_SO0 SO0 UL28_3_BCN2_R RED BEACON LIGHT
187 UL28_4_VFD UL28_4_VFD_I0 I0 UL28_4_VFD_DISC DISCONNECT AUX
188 UL28_4_VFD UL28_4_VFD_I1 I1 SPARE
189 UL28_4_VFD UL28_4_VFD_I2 I2 UL28_4_TPE1 TRACKING PHOTOEYE
190 UL28_4_VFD UL28_4_VFD_I3 I3 UL28_4_ENSH1 SHAFT ENCODER
191 UL28_4_VFD UL28_4_VFD_IO0 IO0 UL28_3_S1_PB START PUSHBUTTON
192 UL28_4_VFD UL28_4_VFD_IO1 IO1 UL28_3_S1_PB_LT START PUSHBUTTON LIGHT
193 UL28_4_VFD UL28_4_VFD_SI0 SI0 SPARE
194 UL28_4_VFD UL28_4_VFD_SI1 SI1 SPARE
195 UL28_4_VFD UL28_4_VFD_SI2 SI2 SPARE
196 UL28_4_VFD UL28_4_VFD_SI3 SI3 SPARE
197 UL28_4_VFD UL28_4_VFD_SO0 SO0 SPARE
198 UL28_5_VFD UL28_5_VFD_I0 I0 UL28_5_VFD_DISC DISCONNECT AUX
199 UL28_5_VFD UL28_5_VFD_I1 I1 SPARE
200 UL28_5_VFD UL28_5_VFD_I2 I2 UL28_5_TPE1 TRACKING PHOTOEYE
201 UL28_5_VFD UL28_5_VFD_I3 I3 UL28_5_ENSH1 SHAFT ENCODER
202 UL28_5_VFD UL28_5_VFD_IO0 IO0 UL28_3_BCN1_A AMBER BEACON LIGHT
203 UL28_5_VFD UL28_5_VFD_IO1 IO1 UL28_3_BCN1_R RED BEACON LIGHT
204 UL28_5_VFD UL28_5_VFD_SI0 SI0 SPARE
205 UL28_5_VFD UL28_5_VFD_SI1 SI1 SPARE
206 UL28_5_VFD UL28_5_VFD_SI2 SI2 SPARE
207 UL28_5_VFD UL28_5_VFD_SI3 SI3 SPARE
208 UL28_5_VFD UL28_5_VFD_SO0 SO0 SPARE
209 UL28_6_VFD UL28_6_VFD_I0 I0 UL28_6_VFD_DISC DISCONNECT AUX
210 UL28_6_VFD UL28_6_VFD_I1 I1 SPARE
211 UL28_6_VFD UL28_6_VFD_I2 I2 UL28_6_TPE1 TRACKING PHOTOEYE
212 UL28_6_VFD UL28_6_VFD_I3 I3 SPARE
213 UL28_6_VFD UL28_6_VFD_IO0 IO0 UL28_6_ENSH1 SHAFT ENCODER
214 UL28_6_VFD UL28_6_VFD_IO1 IO1 SPARE
215 UL28_6_VFD UL28_6_VFD_SI0 SI0 SPARE
216 UL28_6_VFD UL28_6_VFD_SI1 SI1 SPARE
217 UL28_6_VFD UL28_6_VFD_SI2 SI2 SPARE
218 UL28_6_VFD UL28_6_VFD_SI3 SI3 SPARE
219 UL28_6_VFD UL28_6_VFD_SO0 SO0 SPARE
220 UL28_7_VFD UL28_7_VFD_I0 I0 UL28_7_VFD_DISC DISCONNECT AUX
221 UL28_7_VFD UL28_7_VFD_I1 I1 SPARE
222 UL28_7_VFD UL28_7_VFD_I2 I2 UL28_7_TPE1 TRACKING PHOTOEYE
223 UL28_7_VFD UL28_7_VFD_I3 I3 SPARE
224 UL28_7_VFD UL28_7_VFD_IO0 IO0 UL28_7_ENSH1 SHAFT ENCODER
225 UL28_7_VFD UL28_7_VFD_IO1 IO1 SPARE
226 UL28_7_VFD UL28_7_VFD_SI0 SI0 SPARE
227 UL28_7_VFD UL28_7_VFD_SI1 SI1 SPARE
228 UL28_7_VFD UL28_7_VFD_SI2 SI2 SPARE
229 UL28_7_VFD UL28_7_VFD_SI3 SI3 SPARE
230 UL28_7_VFD UL28_7_VFD_SO0 SO0 SPARE
231 UL28_8_VFD UL28_8_VFD_I0 I0 UL28_8_VFD_DISC DISCONNECT AUX
232 UL28_8_VFD UL28_8_VFD_I1 I1 SPARE
233 UL28_8_VFD UL28_8_VFD_I2 I2 UL28_8_TPE1 TRACKING PHOTOEYE
234 UL28_8_VFD UL28_8_VFD_I3 I3 SPARE
235 UL28_8_VFD UL28_8_VFD_IO0 IO0 UL28_8_ENSH1 SHAFT ENCODER
236 UL28_8_VFD UL28_8_VFD_IO1 IO1 SPARE
237 UL28_8_VFD UL28_8_VFD_SI0 SI0 SPARE
238 UL28_8_VFD UL28_8_VFD_SI1 SI1 SPARE
239 UL28_8_VFD UL28_8_VFD_SI2 SI2 SPARE
240 UL28_8_VFD UL28_8_VFD_SI3 SI3 SPARE
241 UL28_8_VFD UL28_8_VFD_SO0 SO0 SPARE
242 UL28_9_VFD UL28_9_VFD_I0 I0 UL28_9_VFD_DISC DISCONNECT AUX
243 UL28_9_VFD UL28_9_VFD_I1 I1 SPARE
244 UL28_9_VFD UL28_9_VFD_I2 I2 SPARE
245 UL28_9_VFD UL28_9_VFD_I3 I3 SPARE
246 UL28_9_VFD UL28_9_VFD_IO0 IO0 UL29_8_BCN1_A AMBER BEACON LIGHT
247 UL28_9_VFD UL28_9_VFD_IO1 IO1 UL29_8_BCN1_R RED BEACON LIGHT
248 UL28_9_VFD UL28_9_VFD_SI0 SI0 SPARE
249 UL28_9_VFD UL28_9_VFD_SI1 SI1 SPARE
250 UL28_9_VFD UL28_9_VFD_SI2 SI2 SPARE
251 UL28_9_VFD UL28_9_VFD_SI3 SI3 SPARE
252 UL28_9_VFD UL28_9_VFD_SO0 SO0 SPARE
253 UL29_1_VFD UL29_1_VFD_I0 I0 UL29_1_VFD_DISC DISCONNECT AUX
254 UL29_1_VFD UL29_1_VFD_I1 I1 SPARE
255 UL29_1_VFD UL29_1_VFD_I2 I2 UL29_1_TPE1 TRACKING PHOTOEYE
256 UL29_1_VFD UL29_1_VFD_I3 I3 SPARE
257 UL29_1_VFD UL29_1_VFD_IO0 IO0 UL29_1_ENW1 WHEEL ENCODER
258 UL29_1_VFD UL29_1_VFD_IO1 IO1 SPARE
259 UL29_1_VFD UL29_1_VFD_SI0 SI0 UL29_1_EPC1 E-STOP PULLCORD
260 UL29_1_VFD UL29_1_VFD_SI1 SI1 UL29_1_EPC1_2 E-STOP PULLCORD
261 UL29_1_VFD UL29_1_VFD_SI2 SI2 UL29_1_EPC2 E-STOP PULLCORD
262 UL29_1_VFD UL29_1_VFD_SI3 SI3 UL29_1_EPC2_2 E-STOP PULLCORD
263 UL29_1_VFD UL29_1_VFD_SO0 SO0 SPARE
264 UL29_1_FIOM1 UL29_1_FIOM1_X3_0 X3_0 UL29_1_SS1_SPB SS STATION START PUSHBUTTON
265 UL29_1_FIOM1 UL29_1_FIOM1_X3_1 X3_1 UL29_1_SS1_SPB_LT SS STATION START PUSHBUTTON LIGHT
266 UL29_1_FIOM1 UL29_1_FIOM1_X2_0 X2_0 UL29_1_SS1_STPB SS STATION STOP PUSHBUTTON
267 UL29_1_FIOM1 UL29_1_FIOM1_X2_1 X2_1 SPARE
268 UL29_1_FIOM1 UL29_1_FIOM1_X1_0 X1_0 UL29_1_SS2_SPB SS STATION START PUSHBUTTON
269 UL29_1_FIOM1 UL29_1_FIOM1_X1_1 X1_1 UL29_1_SS2_SPB_LT SS STATION START PUSHBUTTON LIGHT
270 UL29_1_FIOM1 UL29_1_FIOM1_X0_0 X0_0 UL29_1_SS2_STPB SS STATION STOP PUSHBUTTON
271 UL29_1_FIOM1 UL29_1_FIOM1_X0_1 X0_1 SPARE
272 UL29_1_FIOM1 UL29_1_FIOM1_X7_0 X7_0 UL29_1_BCN1_R RED BEACON LIGHT
273 UL29_1_FIOM1 UL29_1_FIOM1_X7_1 X7_1 SPARE
274 UL29_1_FIOM1 UL29_1_FIOM1_X6_0 X6_0 UL29_1_BCN2_R RED BEACON LIGHT
275 UL29_1_FIOM1 UL29_1_FIOM1_X6_1 X6_1 SPARE
276 UL29_1_FIOM1 UL29_1_FIOM1_X5_0 X5_0 SPARE
277 UL29_1_FIOM1 UL29_1_FIOM1_X5_1 X5_1 SPARE
278 UL29_1_FIOM1 UL29_1_FIOM1_X4_0 X4_0 SPARE
279 UL29_1_FIOM1 UL29_1_FIOM1_X4_1 X4_1 SPARE
280 UL29_10_VFD UL29_10_VFD_I0 I0 UL29_10_VFD_DISC DISCONNECT AUX
281 UL29_10_VFD UL29_10_VFD_I1 I1 SPARE
282 UL29_10_VFD UL29_10_VFD_I2 I2 UL29_10_TPE2 TRACKING PHOTOEYE
283 UL29_10_VFD UL29_10_VFD_I3 I3 SPARE
284 UL29_10_VFD UL29_10_VFD_IO0 IO0 UL29_10_ENW1 WHEEL ENCODER
285 UL29_10_VFD UL29_10_VFD_IO1 IO1 SPARE
286 UL29_10_VFD UL29_10_VFD_SI0 SI0 SPARE
287 UL29_10_VFD UL29_10_VFD_SI1 SI1 SPARE
288 UL29_10_VFD UL29_10_VFD_SI2 SI2 SPARE
289 UL29_10_VFD UL29_10_VFD_SI3 SI3 SPARE
290 UL29_10_VFD UL29_10_VFD_SO0 SO0 SPARE
291 UL29_11_VFD UL29_11_VFD_I0 I0 UL29_11_VFD_DISC DISCONNECT AUX
292 UL29_11_VFD UL29_11_VFD_I1 I1 SPARE
293 UL29_11_VFD UL29_11_VFD_I2 I2 UL29_11_TPE1 TRACKING PHOTOEYE
294 UL29_11_VFD UL29_11_VFD_I3 I3 SPARE
295 UL29_11_VFD UL29_11_VFD_IO0 IO0 UL29_11_ENW1 WHEEL ENCODER
296 UL29_11_VFD UL29_11_VFD_IO1 IO1 SPARE
297 UL29_11_VFD UL29_11_VFD_SI0 SI0 SPARE
298 UL29_11_VFD UL29_11_VFD_SI1 SI1 SPARE
299 UL29_11_VFD UL29_11_VFD_SI2 SI2 SPARE
300 UL29_11_VFD UL29_11_VFD_SI3 SI3 SPARE
301 UL29_11_VFD UL29_11_VFD_SO0 SO0 SPARE
302 UL29_12_VFD UL29_12_VFD_I0 I0 UL29_12_VFD_DISC DISCONNECT AUX
303 UL29_12_VFD UL29_12_VFD_I1 I1 SPARE
304 UL29_12_VFD UL29_12_VFD_I2 I2 UL29_12_TPE1 TRACKING PHOTOEYE
305 UL29_12_VFD UL29_12_VFD_I3 I3 SPARE
306 UL29_12_VFD UL29_12_VFD_IO0 IO0 SPARE
307 UL29_12_VFD UL29_12_VFD_IO1 IO1 SPARE
308 UL29_12_VFD UL29_12_VFD_SI0 SI0 SPARE
309 UL29_12_VFD UL29_12_VFD_SI1 SI1 SPARE
310 UL29_12_VFD UL29_12_VFD_SI2 SI2 SPARE
311 UL29_12_VFD UL29_12_VFD_SI3 SI3 SPARE
312 UL29_12_VFD UL29_12_VFD_SO0 SO0 SPARE
313 UL29_13_VFD UL29_13_VFD_I0 I0 UL29_13_VFD_DISC DISCONNECT AUX
314 UL29_13_VFD UL29_13_VFD_I1 I1 SPARE
315 UL29_13_VFD UL29_13_VFD_I2 I2 UL29_13_TPE1 TRACKING PHOTOEYE
316 UL29_13_VFD UL29_13_VFD_I3 I3 UL29_13_ENW1 WHEEL ENCODER
317 UL29_13_VFD UL29_13_VFD_IO0 IO0 UL29_13_BCN1_H HORN BEACON
318 UL29_13_VFD UL29_13_VFD_IO1 IO1 SPARE
319 UL29_13_VFD UL29_13_VFD_SI0 SI0 SPARE
320 UL29_13_VFD UL29_13_VFD_SI1 SI1 SPARE
321 UL29_13_VFD UL29_13_VFD_SI2 SI2 SPARE
322 UL29_13_VFD UL29_13_VFD_SI3 SI3 SPARE
323 UL29_13_VFD UL29_13_VFD_SO0 SO0 SPARE
324 UL29_15_VFD UL29_15_VFD_I0 I0 UL29_15_VFD_DISC DISCONNECT AUX
325 UL29_15_VFD UL29_15_VFD_I1 I1 SPARE
326 UL29_15_VFD UL29_15_VFD_I2 I2 UL29_15_TPE1 TRACKING PHOTOEYE
327 UL29_15_VFD UL29_15_VFD_I3 I3 SPARE
328 UL29_15_VFD UL29_15_VFD_IO0 IO0 UL29_15_ENSH1 SHAFT ENCODER
329 UL29_15_VFD UL29_15_VFD_IO1 IO1 SPARE
330 UL29_15_VFD UL29_15_VFD_SI0 SI0 UL29_15_EPC1 E-STOP PULLCORD
331 UL29_15_VFD UL29_15_VFD_SI1 SI1 UL29_15_EPC1_2 E-STOP PULLCORD
332 UL29_15_VFD UL29_15_VFD_SI2 SI2 UL29_15_EPC2 E-STOP PULLCORD
333 UL29_15_VFD UL29_15_VFD_SI3 SI3 UL29_15_EPC2_2 E-STOP PULLCORD
334 UL29_15_VFD UL29_15_VFD_SO0 SO0 SPARE
335 UL29_16_VFD UL29_16_VFD_I0 I0 UL29_16_VFD_DISC DISCONNECT AUX
336 UL29_16_VFD UL29_16_VFD_I1 I1 SPARE
337 UL29_16_VFD UL29_16_VFD_I2 I2 UL29_16_TPE1 TRACKING PHOTOEYE
338 UL29_16_VFD UL29_16_VFD_I3 I3 SPARE
339 UL29_16_VFD UL29_16_VFD_IO0 IO0 UL29_16_ENSH1 SHAFT ENCODER
340 UL29_16_VFD UL29_16_VFD_IO1 IO1 SPARE
341 UL29_16_VFD UL29_16_VFD_SI0 SI0 SPARE
342 UL29_16_VFD UL29_16_VFD_SI1 SI1 SPARE
343 UL29_16_VFD UL29_16_VFD_SI2 SI2 SPARE
344 UL29_16_VFD UL29_16_VFD_SI3 SI3 SPARE
345 UL29_16_VFD UL29_16_VFD_SO0 SO0 UL29_17_SR1_STO1 SAFETY TORQUE OFF
346 UL29_17_FIOM1 UL29_17_FIOM1_X3_0 X3_0 UL29_15_SS1_SPB SS STATION START PUSHBUTTON
347 UL29_17_FIOM1 UL29_17_FIOM1_X3_1 X3_1 UL29_15_SS1_SPB_LT SS STATION START PUSHBUTTON LIGHT
348 UL29_17_FIOM1 UL29_17_FIOM1_X2_0 X2_0 UL29_15_SS1_STPB SS STATION STOP PUSHBUTTON
349 UL29_17_FIOM1 UL29_17_FIOM1_X2_1 X2_1 SPARE
350 UL29_17_FIOM1 UL29_17_FIOM1_X1_0 X1_0 UL29_15_SS2_SPB SS STATION START PUSHBUTTON
351 UL29_17_FIOM1 UL29_17_FIOM1_X1_1 X1_1 UL29_15_SS2_SPB_LT SS STATION START PUSHBUTTON LIGHT
352 UL29_17_FIOM1 UL29_17_FIOM1_X0_0 X0_0 UL29_15_SS2_STPB SS STATION STOP PUSHBUTTON
353 UL29_17_FIOM1 UL29_17_FIOM1_X0_1 X0_1 SPARE
354 UL29_17_FIOM1 UL29_17_FIOM1_X7_0 X7_0 UL29_15_BCN1_A AMBER BEACON LIGHT
355 UL29_17_FIOM1 UL29_17_FIOM1_X7_1 X7_1 UL29_15_BCN1_R RED BEACON LIGHT
356 UL29_17_FIOM1 UL29_17_FIOM1_X6_0 X6_0 UL29_15_BCN2_R RED BEACON LIGHT
357 UL29_17_FIOM1 UL29_17_FIOM1_X6_1 X6_1 SPARE
358 UL29_17_FIOM1 UL29_17_FIOM1_X5_0 X5_0 SPARE
359 UL29_17_FIOM1 UL29_17_FIOM1_X5_1 X5_1 SPARE
360 UL29_17_FIOM1 UL29_17_FIOM1_X4_0 X4_0 SPARE
361 UL29_17_FIOM1 UL29_17_FIOM1_X4_1 X4_1 SPARE
362 UL29_18_VFD UL29_18_VFD_I0 I0 UL29_18_VFD_DISC DISCONNECT AUX
363 UL29_18_VFD UL29_18_VFD_I1 I1 SPARE
364 UL29_18_VFD UL29_18_VFD_I2 I2 UL29_18_TPE1 TRACKING PHOTOEYE
365 UL29_18_VFD UL29_18_VFD_I3 I3 UL29_17_TPE1 TRACKING PHOTOEYE
366 UL29_18_VFD UL29_18_VFD_IO0 IO0 UL29_18_ENW1 WHEEL ENCODER
367 UL29_18_VFD UL29_18_VFD_IO1 IO1 SPARE
368 UL29_18_VFD UL29_18_VFD_SI0 SI0 SPARE
369 UL29_18_VFD UL29_18_VFD_SI1 SI1 SPARE
370 UL29_18_VFD UL29_18_VFD_SI2 SI2 SPARE
371 UL29_18_VFD UL29_18_VFD_SI3 SI3 SPARE
372 UL29_18_VFD UL29_18_VFD_SO0 SO0 SPARE
373 UL29_2_VFD UL29_2_VFD_I0 I0 UL29_2_VFD_DISC DISCONNECT AUX
374 UL29_2_VFD UL29_2_VFD_I1 I1 SPARE
375 UL29_2_VFD UL29_2_VFD_I2 I2 UL29_2_TPE1 TRACKING PHOTOEYE
376 UL29_2_VFD UL29_2_VFD_I3 I3 SPARE
377 UL29_2_VFD UL29_2_VFD_IO0 IO0 UL29_2_ENW1 WHEEL ENCODER
378 UL29_2_VFD UL29_2_VFD_IO1 IO1 SPARE
379 UL29_2_VFD UL29_2_VFD_SI0 SI0 SPARE
380 UL29_2_VFD UL29_2_VFD_SI1 SI1 SPARE
381 UL29_2_VFD UL29_2_VFD_SI2 SI2 SPARE
382 UL29_2_VFD UL29_2_VFD_SI3 SI3 SPARE
383 UL29_2_VFD UL29_2_VFD_SO0 SO0 SPARE
384 UL29_3_VFD UL29_3_VFD_I0 I0 UL29_3_VFD_DISC DISCONNECT AUX
385 UL29_3_VFD UL29_3_VFD_I1 I1 SPARE
386 UL29_3_VFD UL29_3_VFD_I2 I2 UL29_3_TPE1 TRACKING PHOTOEYE
387 UL29_3_VFD UL29_3_VFD_I3 I3 SPARE
388 UL29_3_VFD UL29_3_VFD_IO0 IO0 UL29_3_ENSH1 SHAFT ENCODER
389 UL29_3_VFD UL29_3_VFD_IO1 IO1 SPARE
390 UL29_3_VFD UL29_3_VFD_SI0 SI0 SPARE
391 UL29_3_VFD UL29_3_VFD_SI1 SI1 SPARE
392 UL29_3_VFD UL29_3_VFD_SI2 SI2 SPARE
393 UL29_3_VFD UL29_3_VFD_SI3 SI3 SPARE
394 UL29_3_VFD UL29_3_VFD_SO0 SO0 SPARE
395 UL29_30_VFD UL29_30_VFD_I0 I0 UL29_30_VFD_DISC DISCONNECT AUX
396 UL29_30_VFD UL29_30_VFD_I1 I1 SPARE
397 UL29_30_VFD UL29_30_VFD_I2 I2 UL29_30_TPE1 TRACKING PHOTOEYE
398 UL29_30_VFD UL29_30_VFD_I3 I3 SPARE
399 UL29_30_VFD UL29_30_VFD_IO0 IO0 UL29_30_ENW1 WHEEL ENCODER
400 UL29_30_VFD UL29_30_VFD_IO1 IO1 SPARE
401 UL29_30_VFD UL29_30_VFD_SI0 SI0 UL29_30_EPC1 E-STOP PULLCORD
402 UL29_30_VFD UL29_30_VFD_SI1 SI1 UL29_30_EPC1_2 E-STOP PULLCORD
403 UL29_30_VFD UL29_30_VFD_SI2 SI2 UL29_30_EPC2 E-STOP PULLCORD
404 UL29_30_VFD UL29_30_VFD_SI3 SI3 UL29_30_EPC2_2 E-STOP PULLCORD
405 UL29_30_VFD UL29_30_VFD_SO0 SO0 SPARE
406 UL29_30_FIOM1 UL29_30_FIOM1_X3_0 X3_0 UL29_30_S1_PB START PUSHBUTTON
407 UL29_30_FIOM1 UL29_30_FIOM1_X3_1 X3_1 UL29_30_S1_PB_LT START PUSHBUTTON LIGHT
408 UL29_30_FIOM1 UL29_30_FIOM1_X2_0 X2_0 UL29_30_S2_PB START PUSHBUTTON
409 UL29_30_FIOM1 UL29_30_FIOM1_X2_1 X2_1 UL29_30_S2_PB_LT START PUSHBUTTON LIGHT
410 UL29_30_FIOM1 UL29_30_FIOM1_X1_0 X1_0 UL29_30_BCN1_B BLUE BEACON LIGHT
411 UL29_30_FIOM1 UL29_30_FIOM1_X1_1 X1_1 UL29_30_BCN1_R RED BEACON LIGHT
412 UL29_30_FIOM1 UL29_30_FIOM1_X0_0 X0_0 UL29_30_BCN2_R RED BEACON LIGHT
413 UL29_30_FIOM1 UL29_30_FIOM1_X0_1 X0_1 SPARE
414 UL29_30_FIOM1 UL29_30_FIOM1_X7_0 X7_0 UL29_14_TPE1 TRACKING PHOTOEYE
415 UL29_30_FIOM1 UL29_30_FIOM1_X7_1 X7_1 SPARE
416 UL29_30_FIOM1 UL29_30_FIOM1_X6_0 X6_0 UL29_31_TPE1 TRACKING PHOTOEYE
417 UL29_30_FIOM1 UL29_30_FIOM1_X6_1 X6_1 SPARE
418 UL29_30_FIOM1 UL29_30_FIOM1_X5_0 X5_0 SPARE
419 UL29_30_FIOM1 UL29_30_FIOM1_X5_1 X5_1 SPARE
420 UL29_30_FIOM1 UL29_30_FIOM1_X4_0 X4_0 SPARE
421 UL29_30_FIOM1 UL29_30_FIOM1_X4_1 X4_1 SPARE
422 UL29_4_VFD UL29_4_VFD_I0 I0 UL29_4_VFD_DISC DISCONNECT AUX
423 UL29_4_VFD UL29_4_VFD_I1 I1 SPARE
424 UL29_4_VFD UL29_4_VFD_I2 I2 UL29_4_TPE1 TRACKING PHOTOEYE
425 UL29_4_VFD UL29_4_VFD_I3 I3 SPARE
426 UL29_4_VFD UL29_4_VFD_IO0 IO0 UL29_4_ENSH1 SHAFT ENCODER
427 UL29_4_VFD UL29_4_VFD_IO1 IO1 SPARE
428 UL29_4_VFD UL29_4_VFD_SI0 SI0 SPARE
429 UL29_4_VFD UL29_4_VFD_SI1 SI1 SPARE
430 UL29_4_VFD UL29_4_VFD_SI2 SI2 SPARE
431 UL29_4_VFD UL29_4_VFD_SI3 SI3 SPARE
432 UL29_4_VFD UL29_4_VFD_SO0 SO0 SPARE
433 UL29_5_VFD UL29_5_VFD_I0 I0 UL29_5_VFD_DISC DISCONNECT AUX
434 UL29_5_VFD UL29_5_VFD_I1 I1 SPARE
435 UL29_5_VFD UL29_5_VFD_I2 I2 UL29_5_TPE1 TRACKING PHOTOEYE
436 UL29_5_VFD UL29_5_VFD_I3 I3 SPARE
437 UL29_5_VFD UL29_5_VFD_IO0 IO0 UL29_5_ENSH1 SHAFT ENCODER
438 UL29_5_VFD UL29_5_VFD_IO1 IO1 SPARE
439 UL29_5_VFD UL29_5_VFD_SI0 SI0 SPARE
440 UL29_5_VFD UL29_5_VFD_SI1 SI1 SPARE
441 UL29_5_VFD UL29_5_VFD_SI2 SI2 SPARE
442 UL29_5_VFD UL29_5_VFD_SI3 SI3 SPARE
443 UL29_5_VFD UL29_5_VFD_SO0 SO0 SPARE
444 UL29_6_VFD UL29_6_VFD_I0 I0 UL29_6_VFD_DISC DISCONNECT AUX
445 UL29_6_VFD UL29_6_VFD_I1 I1 SPARE
446 UL29_6_VFD UL29_6_VFD_I2 I2 UL29_6_TPE1 TRACKING PHOTOEYE
447 UL29_6_VFD UL29_6_VFD_I3 I3 SPARE
448 UL29_6_VFD UL29_6_VFD_IO0 IO0 UL29_6_ENSH1 SHAFT ENCODER
449 UL29_6_VFD UL29_6_VFD_IO1 IO1 SPARE
450 UL29_6_VFD UL29_6_VFD_SI0 SI0 SPARE
451 UL29_6_VFD UL29_6_VFD_SI1 SI1 SPARE
452 UL29_6_VFD UL29_6_VFD_SI2 SI2 SPARE
453 UL29_6_VFD UL29_6_VFD_SI3 SI3 SPARE
454 UL29_6_VFD UL29_6_VFD_SO0 SO0 SPARE
455 UL29_7_VFD UL29_7_VFD_I0 I0 UL29_7_VFD_DISC DISCONNECT AUX
456 UL29_7_VFD UL29_7_VFD_I1 I1 SPARE
457 UL29_7_VFD UL29_7_VFD_I2 I2 UL29_7_TPE1 TRACKING PHOTOEYE
458 UL29_7_VFD UL29_7_VFD_I3 I3 UL29_7_ENSH1 SHAFT ENCODER
459 UL29_7_VFD UL29_7_VFD_IO0 IO0 UL29_8_S1_PB START PUSHBUTTON
460 UL29_7_VFD UL29_7_VFD_IO1 IO1 UL29_8_S1_PB_LT START PUSHBUTTON LIGHT
461 UL29_7_VFD UL29_7_VFD_SI0 SI0 UL29_8_EPC1 E-STOP PULLCORD
462 UL29_7_VFD UL29_7_VFD_SI1 SI1 UL29_8_EPC1_2 E-STOP PULLCORD
463 UL29_7_VFD UL29_7_VFD_SI2 SI2 SPARE
464 UL29_7_VFD UL29_7_VFD_SI3 SI3 SPARE
465 UL29_7_VFD UL29_7_VFD_SO0 SO0 SPARE
466 UL29_8_VFD UL29_8_VFD_I0 I0 UL29_8_VFD_DISC DISCONNECT AUX
467 UL29_8_VFD UL29_8_VFD_I1 I1 SPARE
468 UL29_8_VFD UL29_8_VFD_I2 I2 UL29_8_TPE1 TRACKING PHOTOEYE
469 UL29_8_VFD UL29_8_VFD_I3 I3 UL29_8_TPE2 TRACKING PHOTOEYE
470 UL29_8_VFD UL29_8_VFD_IO0 IO0 UL29_8_ENW1 WHEEL ENCODER
471 UL29_8_VFD UL29_8_VFD_IO1 IO1 SPARE
472 UL29_8_VFD UL29_8_VFD_SI0 SI0 UL29_8_EPC2 E-STOP PULLCORD
473 UL29_8_VFD UL29_8_VFD_SI1 SI1 UL29_8_EPC2_2 E-STOP PULLCORD
474 UL29_8_VFD UL29_8_VFD_SI2 SI2 SPARE
475 UL29_8_VFD UL29_8_VFD_SI3 SI3 SPARE
476 UL29_8_VFD UL29_8_VFD_SO0 SO0 SPARE
477 UL29_9A_VFD UL29_9A_VFD_I0 I0 UL29_9A_VFD_DISC DISCONNECT AUX
478 UL29_9A_VFD UL29_9A_VFD_I1 I1 SPARE
479 UL29_9A_VFD UL29_9A_VFD_I2 I2 UL29_10_TPE1 TRACKING PHOTOEYE
480 UL29_9A_VFD UL29_9A_VFD_I3 I3 SPARE
481 UL29_9A_VFD UL29_9A_VFD_IO0 IO0 SPARE
482 UL29_9A_VFD UL29_9A_VFD_IO1 IO1 SPARE
483 UL29_9A_VFD UL29_9A_VFD_SI0 SI0 SPARE
484 UL29_9A_VFD UL29_9A_VFD_SI1 SI1 SPARE
485 UL29_9A_VFD UL29_9A_VFD_SI2 SI2 SPARE
486 UL29_9A_VFD UL29_9A_VFD_SI3 SI3 SPARE
487 UL29_9A_VFD UL29_9A_VFD_SO0 SO0 SPARE
488 UL29_9B_VFD UL29_9B_VFD_I0 I0 UL29_9B_VFD_DISC DISCONNECT AUX
489 UL29_9B_VFD UL29_9B_VFD_I1 I1 SPARE
490 UL29_9B_VFD UL29_9B_VFD_I2 I2 SPARE
491 UL29_9B_VFD UL29_9B_VFD_I3 I3 SPARE
492 UL29_9B_VFD UL29_9B_VFD_IO0 IO0 UL29_8_BCN1_R RED BEACON LIGHT
493 UL29_9B_VFD UL29_9B_VFD_IO1 IO1 SPARE
494 UL29_9B_VFD UL29_9B_VFD_SI0 SI0 SPARE
495 UL29_9B_VFD UL29_9B_VFD_SI1 SI1 SPARE
496 UL29_9B_VFD UL29_9B_VFD_SI2 SI2 SPARE
497 UL29_9B_VFD UL29_9B_VFD_SI3 SI3 SPARE
498 UL29_9B_VFD UL29_9B_VFD_SO0 SO0 SPARE

View File

@ -0,0 +1,147 @@
Bypass,MCM15,,,,,,,,
SLOT0,1756-L83ES,IP,RING,,STAR,,,,
SLOT1,1756-N2,,DPM,IP,NAME,Part Number,IP,DPM PORT,ZONE
SLOT2,1756-EN4TR,11.200.0.15,BYAB_12_DPM1,11.200.1.2,BYCA_2_FIOM1,Murr 54631,11.200.1.20,BYAB_12_DPM1_P5,MCM15
SLOT3,1756-N2,,,,BYCD_2_FIOM1,Murr 54631,11.200.1.21,BYAB_12_DPM1_P6,
SLOT4,1756-N2,,,,BYCD_3_FIOM1,Murr 54631,11.200.1.22,BYAB_12_DPM1_P7,
SLOT5,1756-IB16,,,,BYCA_1_VFD,35S-6D3-P101,11.200.1.23,BYAB_12_DPM1_P8,
SLOT6,1756-OB16E,,,,BYCB_1_VFD,35S-6D3-P101,11.200.1.24,BYAB_12_DPM1_P9,
SLOT7,1756-IB16S,,,,BYCD_1_VFD,35S-6D3-P101,11.200.1.25,BYAB_12_DPM1_P10,
SLOT8,1756-N2,,,,BYCA_2_VFD,35S-6D3-P101,11.200.1.26,BYAB_12_DPM1_P11,
SLOT9,1756-N2,,,,BYCB_2_VFD,35S-6D3-P101,11.200.1.27,BYAB_12_DPM1_P12,
,,,,,BYCD_2_VFD,35S-6D2-P101,11.200.1.28,BYAB_12_DPM1_P13,
,,,,,BYCA_3_VFD,35S-6D3-P101,11.200.1.29,BYAB_12_DPM1_P14,
DPM COUND SLOT 3,6,,,,BYCB_3_VFD,35S-6D3-P101,11.200.1.30,BYAB_12_DPM1_P15,
FIO COUND SLOT 3,22,,,,BYCD_3_VFD,35S-6D4-P111,11.200.1.31,BYAB_12_DPM1_P16,
,,,,,BYCA_4_VFD,35S-6D2-P101,11.200.1.32,BYAB_12_DPM1_P17,
,,,,,BYCB_4_VFD,35S-6D3-P101,11.200.1.33,BYAB_12_DPM1_P18,
,,,,,BYCA_5_VFD,35S-6D4-P111,11.200.1.34,BYAB_12_DPM1_P19,
,,,,,BYCD_7_VFD,35S-6D3-P101,11.200.1.35,BYAB_12_DPM1_P20,
,,,,,BYCD_8_VFD,35S-6D3-P101,11.200.1.36,BYAB_12_DPM1_P21,
,,,,,BYCD_9_VFD,35S-6D2-P101,11.200.1.37,BYAB_12_DPM1_P22,
,,,,,BYAB_10_VFD,35S-6D2-P101,11.200.1.38,BYAB_12_DPM1_P23,
,,,,,BYBD_10_VFD,35S-6D4-P111,11.200.1.39,BYAB_12_DPM1_P24,
,,,,,BYCD_10_VFD,35S-6D2-P101,11.200.1.40,BYAB_12_DPM1_P25,
,,,,,BYAB_11_VFD,35S-6D4-P111,11.200.1.41,BYAB_12_DPM1_P26,
,,,,,BYBC_14_VFD,35S-6D3-P101,11.200.1.42,BYAB_12_DPM1_P27,
,,,,,SPARE, ,11.200.1.43,BYAB_12_DPM1_P28,
,,,BYAC_10_DPM1,11.200.1.3,BYAC_10_FIOM1,Murr 54631,11.200.1.44,BYAC_10_DPM1_P5,
,,,,,BYAC_14_FIOM1,Murr 54631,11.200.1.45,BYAC_10_DPM1_P6,
,,,,,BYBC_16_FIOM1,Murr 54631,11.200.1.46,BYAC_10_DPM1_P7,
,,,,,BYDC_20_FIOM1,Murr 54631,11.200.1.47,BYAC_10_DPM1_P8,
,,,,,BYCA_6_VFD,35S-6D4-P111,11.200.1.48,BYAC_10_DPM1_P9,
,,,,,BYCA_7_VFD,35S-6D4-P111,11.200.1.49,BYAC_10_DPM1_P10,
,,,,,BYAC_10_VFD,35S-6D5-P111,11.200.1.50,BYAC_10_DPM1_P11,
,,,,,BYAC_11_VFD,35S-6D3-P101,11.200.1.51,BYAC_10_DPM1_P12,
,,,,,BYBA_11_VFD,35S-6D3-P101,11.200.1.52,BYAC_10_DPM1_P13,
,,,,,BYAC_12_VFD,35S-6D3-P101,11.200.1.53,BYAC_10_DPM1_P14,
,,,,,BYBA_12_VFD,35S-6D3-P101,11.200.1.54,BYAC_10_DPM1_P15,
,,,,,BYAC_13_VFD,35S-6D3-P101,11.200.1.55,BYAC_10_DPM1_P16,
,,,,,BYBA_13_VFD,35S-6D5-P111,11.200.1.56,BYAC_10_DPM1_P17,
,,,,,BYAC_14_VFD,35S-6D2-P101,11.200.1.57,BYAC_10_DPM1_P18,
,,,,,BYBC_15_VFD,35S-6D2-P101,11.200.1.58,BYAC_10_DPM1_P19,
,,,,,BYBC_16_VFD,35S-6D3-P101,11.200.1.59,BYAC_10_DPM1_P20,
,,,,,BYDC_16_VFD,35S-6D5-P111,11.200.1.60,BYAC_10_DPM1_P21,
,,,,,BYDC_17_VFD,35S-6D3-P101,11.200.1.61,BYAC_10_DPM1_P22,
,,,,,BYDC_18_VFD,35S-6D3-P101,11.200.1.62,BYAC_10_DPM1_P23,
,,,,,BYDC_19_VFD,35S-6D3-P101,11.200.1.63,BYAC_10_DPM1_P24,
,,,,,BYDC_20_VFD,35S-6D2-P101,11.200.1.64,BYAC_10_DPM1_P25,
,,,,,SPARE, ,11.200.1.65,BYAC_10_DPM1_P26,
,,,,,SPARE, ,11.200.1.66,BYAC_10_DPM1_P27,
,,,,,SPARE, ,11.200.1.67,BYAC_10_DPM1_P28,
,,,BYCB_6_DPM1,11.200.1.4,BYBA_9_FIOM1,Murr 54631,11.200.1.68,BYCB_6_DPM1_P5,
,,,,,BYBD_9_FIOM1,Murr 54631,11.200.1.69,BYCB_6_DPM1_P6,
,,,,,BYAB_12_FIOM1,Murr 54631,11.200.1.70,BYCB_6_DPM1_P7,
,,,,,PDP19_FIOM1,Murr 54631,11.200.1.71,BYCB_6_DPM1_P8,
,,,,,BYCD_4_VFD,35S-6D4-P111,11.200.1.72,BYCB_6_DPM1_P9,
,,,,,BYCB_5_VFD,35S-6D2-P101,11.200.1.73,BYCB_6_DPM1_P10,
,,,,,BYCD_5_VFD,35S-6D2-P101,11.200.1.74,BYCB_6_DPM1_P11,
,,,,,BYCB_6_VFD,35S-6D3-P101,11.200.1.75,BYCB_6_DPM1_P12,
,,,,,BYCD_6_VFD,35S-6D4-P111,11.200.1.76,BYCB_6_DPM1_P13,
,,,,,BYCB_7_VFD,35S-6D5-P111,11.200.1.77,BYCB_6_DPM1_P14,
,,,,,BYBA_8_VFD,35S-6D4-P111,11.200.1.78,BYCB_6_DPM1_P15,
,,,,,BYBD_8_VFD,35S-6D4-P111,11.200.1.79,BYCB_6_DPM1_P16,
,,,,,BYBA_9_VFD,35S-6D4-P111,11.200.1.80,BYCB_6_DPM1_P17,
,,,,,BYBD_9_VFD,35S-6D4-P111,11.200.1.81,BYCB_6_DPM1_P18,
,,,,,BYBA_10_VFD,35S-6D3-P101,11.200.1.82,BYCB_6_DPM1_P19,
,,,,,BYAB_12_VFD,35S-6D4-P111,11.200.1.83,BYCB_6_DPM1_P20,
,,,,,BYBC_12_VFD,35S-6D4-P111,11.200.1.84,BYCB_6_DPM1_P21,
,,,,,BYDB_12_VFD,35S-6D5-P111,11.200.1.85,BYCB_6_DPM1_P22,
,,,,,BYAB_13_VFD,35S-6D5-P111,11.200.1.86,BYCB_6_DPM1_P23,
,,,,,BYBC_13_VFD,35S-6D3-P101,11.200.1.87,BYCB_6_DPM1_P24,
,,,,,BYDB_13_VFD,35S-6D5-P111,11.200.1.88,BYCB_6_DPM1_P25,
,,,,,SPARE, ,11.200.1.89,BYCB_6_DPM1_P26,
,,,,,SPARE, ,11.200.1.90,BYCB_6_DPM1_P27,
,,,,,SPARE, ,11.200.1.91,BYCB_6_DPM1_P28,
,,,BYCB_9_DPM1,11.200.1.5,BYBA_2_FIOM1,Murr 54631,11.200.1.92,BYCB_9_DPM1_P5,
,,,,,BYBD_2_FIOM1,Murr 54631,11.200.1.93,BYCB_9_DPM1_P6,
,,,,,BYCB_16_FIOM1,Murr 54631,11.200.1.94,BYCB_9_DPM1_P7,
,,,,,PDP20_FIOM1,Murr 54631,11.200.1.95,BYCB_9_DPM1_P8,
,,,,,BYBA_1_VFD,35S-6D3-P101,11.200.1.96,BYCB_9_DPM1_P9,
,,,,,BYBA_2_VFD,35S-6D3-P101,11.200.1.97,BYCB_9_DPM1_P10,
,,,,,BYBA_3_VFD,35S-6D3-P101,11.200.1.98,BYCB_9_DPM1_P11,
,,,,,BYBA_4_VFD,35S-6D3-P101,11.200.1.99,BYCB_9_DPM1_P12,
,,,,,BYBA_5_VFD,35S-6D2-P101,11.200.1.100,BYCB_9_DPM1_P13,
,,,,,BYBC_5_VFD,35S-6D3-P101,11.200.1.101,BYCB_9_DPM1_P14,
,,,,,BYBA_6_VFD,35S-6D2-P101,11.200.1.102,BYCB_9_DPM1_P15,
,,,,,BYBC_6_VFD,35S-6D2-P101,11.200.1.103,BYCB_9_DPM1_P16,
,,,,,BYBC_7_VFD,35S-6D2-P101,11.200.1.104,BYCB_9_DPM1_P17,
,,,,,BYCB_9_VFD,35S-6D3-P101,11.200.1.105,BYCB_9_DPM1_P18,
,,,,,BYCB_10_VFD,35S-6D3-P101,11.200.1.106,BYCB_9_DPM1_P19,
,,,,,BYAB_16_VFD,35S-6D3-P101,11.200.1.107,BYCB_9_DPM1_P20,
,,,,,BYDB_16_VFD,35S-6D3-P101,11.200.1.108,BYCB_9_DPM1_P21,
,,,,,SPARE, ,11.200.1.109,BYCB_9_DPM1_P22,
,,,,,SPARE, ,11.200.1.110,BYCB_9_DPM1_P23,
,,,,,SPARE, ,11.200.1.111,BYCB_9_DPM1_P24,
,,,,,SPARE, ,11.200.1.112,BYCB_9_DPM1_P25,
,,,,,SPARE, ,11.200.1.113,BYCB_9_DPM1_P26,
,,,,,SPARE, ,11.200.1.114,BYCB_9_DPM1_P27,
,,,,,SPARE, ,11.200.1.115,BYCB_9_DPM1_P28,
,,,BYCB_10_DPM1,11.200.1.6,BYBC_10_FIOM1,Murr 54631,11.200.1.116,BYCB_10_DPM1_P5,
,,,,,BYAB_15_FIOM1,Murr 54631,11.200.1.117,BYCB_10_DPM1_P6,
,,,,,BYDB_15_FIOM1,Murr 54631,11.200.1.118,BYCB_10_DPM1_P7,
,,,,,BYBA_7_VFD,35S-6D4-P111,11.200.1.119,BYCB_10_DPM1_P8,
,,,,,BYBD_7_VFD,35S-6D4-P111,11.200.1.120,BYCB_10_DPM1_P9,
,,,,,BYBC_8_VFD,35S-6D4-P111,11.200.1.121,BYCB_10_DPM1_P10,
,,,,,BYCB_8_VFD,35S-6D5-P111,11.200.1.122,BYCB_10_DPM1_P11,
,,,,,BYBC_9_VFD,35S-6D3-P101,11.200.1.123,BYCB_10_DPM1_P12,
,,,,,BYBC_10_VFD,35S-6D3-P101,11.200.1.124,BYCB_10_DPM1_P13,
,,,,,BYBC_11_VFD,35S-6D4-P111,11.200.1.125,BYCB_10_DPM1_P14,
,,,,,BYAB_14_VFD,35S-6D5-P111,11.200.1.126,BYCB_10_DPM1_P15,
,,,,,BYDB_14_VFD,35S-6D5-P111,11.200.1.127,BYCB_10_DPM1_P16,
,,,,,BYAB_15_VFD,35S-6D4-P111,11.200.1.128,BYCB_10_DPM1_P17,
,,,,,BYDB_15_VFD,35S-6D3-P101,11.200.1.129,BYCB_10_DPM1_P18,
,,,,,SPARE, ,11.200.1.130,BYCB_10_DPM1_P19,
,,,,,SPARE, ,11.200.1.131,BYCB_10_DPM1_P20,
,,,,,SPARE, ,11.200.1.132,BYCB_10_DPM1_P21,
,,,,,SPARE, ,11.200.1.133,BYCB_10_DPM1_P22,
,,,,,SPARE, ,11.200.1.134,BYCB_10_DPM1_P23,
,,,,,SPARE, ,11.200.1.135,BYCB_10_DPM1_P24,
,,,,,SPARE, ,11.200.1.136,BYCB_10_DPM1_P25,
,,,,,SPARE, ,11.200.1.137,BYCB_10_DPM1_P26,
,,,,,SPARE, ,11.200.1.138,BYCB_10_DPM1_P27,
,,,,,SPARE, ,11.200.1.139,BYCB_10_DPM1_P28,
,,,BYCB_11_DPM1,11.200.1.7,BYBC_2_FIOM1,Murr 54631,11.200.1.140,BYCB_11_DPM1_P5,
,,,,,BYCB_13_FIOM1,Murr 54631,11.200.1.141,BYCB_11_DPM1_P6,
,,,,,BYAB_19_FIOM1,Murr 54631,11.200.1.142,BYCB_11_DPM1_P7,
,,,,,BYDB_19_FIOM1,Murr 54631,11.200.1.143,BYCB_11_DPM1_P8,
,,,,,BYBC_1_VFD,35S-6D3-P101,11.200.1.144,BYCB_11_DPM1_P9,
,,,,,BYBD_1_VFD,35S-6D3-P101,11.200.1.145,BYCB_11_DPM1_P10,
,,,,,BYBC_2_VFD,35S-6D3-P101,11.200.1.146,BYCB_11_DPM1_P11,
,,,,,BYBD_2_VFD,35S-6D3-P101,11.200.1.147,BYCB_11_DPM1_P12,
,,,,,BYBC_3_VFD,35S-6D4-P111,11.200.1.148,BYCB_11_DPM1_P13,
,,,,,BYBD_3_VFD,35S-6D2-P101,11.200.1.149,BYCB_11_DPM1_P14,
,,,,,BYBC_4_VFD,35S-6D4-P111,11.200.1.150,BYCB_11_DPM1_P15,
,,,,,BYBD_4_VFD,35S-6D2-P101,11.200.1.151,BYCB_11_DPM1_P16,
,,,,,BYBD_5_VFD,35S-6D2-P101,11.200.1.152,BYCB_11_DPM1_P17,
,,,,,BYBD_6_VFD,35S-6D3-P101,11.200.1.153,BYCB_11_DPM1_P18,
,,,,,BYCB_11_VFD,35S-6D4-P111,11.200.1.154,BYCB_11_DPM1_P19,
,,,,,BYCB_12_VFD,35S-6D3-P101,11.200.1.155,BYCB_11_DPM1_P20,
,,,,,BYCB_13_VFD,35S-6D2-P101,11.200.1.156,BYCB_11_DPM1_P21,
,,,,,BYAB_17_VFD,35S-6D3-P101,11.200.1.157,BYCB_11_DPM1_P22,
,,,,,BYDB_17_VFD,35S-6D4-P111,11.200.1.158,BYCB_11_DPM1_P23,
,,,,,BYAB_18_VFD,35S-6D3-P101,11.200.1.159,BYCB_11_DPM1_P24,
,,,,,BYDB_18_VFD,35S-6D3-P101,11.200.1.160,BYCB_11_DPM1_P25,
,,,,,BYAB_19_VFD,35S-6D2-P101,11.200.1.161,BYCB_11_DPM1_P26,
,,,,,BYDB_19_VFD,35S-6D2-P101,11.200.1.162,BYCB_11_DPM1_P27,
,,,,,SPARE, ,11.200.1.163,BYCB_11_DPM1_P28,
1 Bypass MCM15
2 SLOT0 1756-L83ES IP RING STAR
3 SLOT1 1756-N2 DPM IP NAME Part Number IP DPM PORT ZONE
4 SLOT2 1756-EN4TR 11.200.0.15 BYAB_12_DPM1 11.200.1.2 BYCA_2_FIOM1 Murr 54631 11.200.1.20 BYAB_12_DPM1_P5 MCM15
5 SLOT3 1756-N2 BYCD_2_FIOM1 Murr 54631 11.200.1.21 BYAB_12_DPM1_P6
6 SLOT4 1756-N2 BYCD_3_FIOM1 Murr 54631 11.200.1.22 BYAB_12_DPM1_P7
7 SLOT5 1756-IB16 BYCA_1_VFD 35S-6D3-P101 11.200.1.23 BYAB_12_DPM1_P8
8 SLOT6 1756-OB16E BYCB_1_VFD 35S-6D3-P101 11.200.1.24 BYAB_12_DPM1_P9
9 SLOT7 1756-IB16S BYCD_1_VFD 35S-6D3-P101 11.200.1.25 BYAB_12_DPM1_P10
10 SLOT8 1756-N2 BYCA_2_VFD 35S-6D3-P101 11.200.1.26 BYAB_12_DPM1_P11
11 SLOT9 1756-N2 BYCB_2_VFD 35S-6D3-P101 11.200.1.27 BYAB_12_DPM1_P12
12 BYCD_2_VFD 35S-6D2-P101 11.200.1.28 BYAB_12_DPM1_P13
13 BYCA_3_VFD 35S-6D3-P101 11.200.1.29 BYAB_12_DPM1_P14
14 DPM COUND SLOT 3 6 BYCB_3_VFD 35S-6D3-P101 11.200.1.30 BYAB_12_DPM1_P15
15 FIO COUND SLOT 3 22 BYCD_3_VFD 35S-6D4-P111 11.200.1.31 BYAB_12_DPM1_P16
16 BYCA_4_VFD 35S-6D2-P101 11.200.1.32 BYAB_12_DPM1_P17
17 BYCB_4_VFD 35S-6D3-P101 11.200.1.33 BYAB_12_DPM1_P18
18 BYCA_5_VFD 35S-6D4-P111 11.200.1.34 BYAB_12_DPM1_P19
19 BYCD_7_VFD 35S-6D3-P101 11.200.1.35 BYAB_12_DPM1_P20
20 BYCD_8_VFD 35S-6D3-P101 11.200.1.36 BYAB_12_DPM1_P21
21 BYCD_9_VFD 35S-6D2-P101 11.200.1.37 BYAB_12_DPM1_P22
22 BYAB_10_VFD 35S-6D2-P101 11.200.1.38 BYAB_12_DPM1_P23
23 BYBD_10_VFD 35S-6D4-P111 11.200.1.39 BYAB_12_DPM1_P24
24 BYCD_10_VFD 35S-6D2-P101 11.200.1.40 BYAB_12_DPM1_P25
25 BYAB_11_VFD 35S-6D4-P111 11.200.1.41 BYAB_12_DPM1_P26
26 BYBC_14_VFD 35S-6D3-P101 11.200.1.42 BYAB_12_DPM1_P27
27 SPARE 11.200.1.43 BYAB_12_DPM1_P28
28 BYAC_10_DPM1 11.200.1.3 BYAC_10_FIOM1 Murr 54631 11.200.1.44 BYAC_10_DPM1_P5
29 BYAC_14_FIOM1 Murr 54631 11.200.1.45 BYAC_10_DPM1_P6
30 BYBC_16_FIOM1 Murr 54631 11.200.1.46 BYAC_10_DPM1_P7
31 BYDC_20_FIOM1 Murr 54631 11.200.1.47 BYAC_10_DPM1_P8
32 BYCA_6_VFD 35S-6D4-P111 11.200.1.48 BYAC_10_DPM1_P9
33 BYCA_7_VFD 35S-6D4-P111 11.200.1.49 BYAC_10_DPM1_P10
34 BYAC_10_VFD 35S-6D5-P111 11.200.1.50 BYAC_10_DPM1_P11
35 BYAC_11_VFD 35S-6D3-P101 11.200.1.51 BYAC_10_DPM1_P12
36 BYBA_11_VFD 35S-6D3-P101 11.200.1.52 BYAC_10_DPM1_P13
37 BYAC_12_VFD 35S-6D3-P101 11.200.1.53 BYAC_10_DPM1_P14
38 BYBA_12_VFD 35S-6D3-P101 11.200.1.54 BYAC_10_DPM1_P15
39 BYAC_13_VFD 35S-6D3-P101 11.200.1.55 BYAC_10_DPM1_P16
40 BYBA_13_VFD 35S-6D5-P111 11.200.1.56 BYAC_10_DPM1_P17
41 BYAC_14_VFD 35S-6D2-P101 11.200.1.57 BYAC_10_DPM1_P18
42 BYBC_15_VFD 35S-6D2-P101 11.200.1.58 BYAC_10_DPM1_P19
43 BYBC_16_VFD 35S-6D3-P101 11.200.1.59 BYAC_10_DPM1_P20
44 BYDC_16_VFD 35S-6D5-P111 11.200.1.60 BYAC_10_DPM1_P21
45 BYDC_17_VFD 35S-6D3-P101 11.200.1.61 BYAC_10_DPM1_P22
46 BYDC_18_VFD 35S-6D3-P101 11.200.1.62 BYAC_10_DPM1_P23
47 BYDC_19_VFD 35S-6D3-P101 11.200.1.63 BYAC_10_DPM1_P24
48 BYDC_20_VFD 35S-6D2-P101 11.200.1.64 BYAC_10_DPM1_P25
49 SPARE 11.200.1.65 BYAC_10_DPM1_P26
50 SPARE 11.200.1.66 BYAC_10_DPM1_P27
51 SPARE 11.200.1.67 BYAC_10_DPM1_P28
52 BYCB_6_DPM1 11.200.1.4 BYBA_9_FIOM1 Murr 54631 11.200.1.68 BYCB_6_DPM1_P5
53 BYBD_9_FIOM1 Murr 54631 11.200.1.69 BYCB_6_DPM1_P6
54 BYAB_12_FIOM1 Murr 54631 11.200.1.70 BYCB_6_DPM1_P7
55 PDP19_FIOM1 Murr 54631 11.200.1.71 BYCB_6_DPM1_P8
56 BYCD_4_VFD 35S-6D4-P111 11.200.1.72 BYCB_6_DPM1_P9
57 BYCB_5_VFD 35S-6D2-P101 11.200.1.73 BYCB_6_DPM1_P10
58 BYCD_5_VFD 35S-6D2-P101 11.200.1.74 BYCB_6_DPM1_P11
59 BYCB_6_VFD 35S-6D3-P101 11.200.1.75 BYCB_6_DPM1_P12
60 BYCD_6_VFD 35S-6D4-P111 11.200.1.76 BYCB_6_DPM1_P13
61 BYCB_7_VFD 35S-6D5-P111 11.200.1.77 BYCB_6_DPM1_P14
62 BYBA_8_VFD 35S-6D4-P111 11.200.1.78 BYCB_6_DPM1_P15
63 BYBD_8_VFD 35S-6D4-P111 11.200.1.79 BYCB_6_DPM1_P16
64 BYBA_9_VFD 35S-6D4-P111 11.200.1.80 BYCB_6_DPM1_P17
65 BYBD_9_VFD 35S-6D4-P111 11.200.1.81 BYCB_6_DPM1_P18
66 BYBA_10_VFD 35S-6D3-P101 11.200.1.82 BYCB_6_DPM1_P19
67 BYAB_12_VFD 35S-6D4-P111 11.200.1.83 BYCB_6_DPM1_P20
68 BYBC_12_VFD 35S-6D4-P111 11.200.1.84 BYCB_6_DPM1_P21
69 BYDB_12_VFD 35S-6D5-P111 11.200.1.85 BYCB_6_DPM1_P22
70 BYAB_13_VFD 35S-6D5-P111 11.200.1.86 BYCB_6_DPM1_P23
71 BYBC_13_VFD 35S-6D3-P101 11.200.1.87 BYCB_6_DPM1_P24
72 BYDB_13_VFD 35S-6D5-P111 11.200.1.88 BYCB_6_DPM1_P25
73 SPARE 11.200.1.89 BYCB_6_DPM1_P26
74 SPARE 11.200.1.90 BYCB_6_DPM1_P27
75 SPARE 11.200.1.91 BYCB_6_DPM1_P28
76 BYCB_9_DPM1 11.200.1.5 BYBA_2_FIOM1 Murr 54631 11.200.1.92 BYCB_9_DPM1_P5
77 BYBD_2_FIOM1 Murr 54631 11.200.1.93 BYCB_9_DPM1_P6
78 BYCB_16_FIOM1 Murr 54631 11.200.1.94 BYCB_9_DPM1_P7
79 PDP20_FIOM1 Murr 54631 11.200.1.95 BYCB_9_DPM1_P8
80 BYBA_1_VFD 35S-6D3-P101 11.200.1.96 BYCB_9_DPM1_P9
81 BYBA_2_VFD 35S-6D3-P101 11.200.1.97 BYCB_9_DPM1_P10
82 BYBA_3_VFD 35S-6D3-P101 11.200.1.98 BYCB_9_DPM1_P11
83 BYBA_4_VFD 35S-6D3-P101 11.200.1.99 BYCB_9_DPM1_P12
84 BYBA_5_VFD 35S-6D2-P101 11.200.1.100 BYCB_9_DPM1_P13
85 BYBC_5_VFD 35S-6D3-P101 11.200.1.101 BYCB_9_DPM1_P14
86 BYBA_6_VFD 35S-6D2-P101 11.200.1.102 BYCB_9_DPM1_P15
87 BYBC_6_VFD 35S-6D2-P101 11.200.1.103 BYCB_9_DPM1_P16
88 BYBC_7_VFD 35S-6D2-P101 11.200.1.104 BYCB_9_DPM1_P17
89 BYCB_9_VFD 35S-6D3-P101 11.200.1.105 BYCB_9_DPM1_P18
90 BYCB_10_VFD 35S-6D3-P101 11.200.1.106 BYCB_9_DPM1_P19
91 BYAB_16_VFD 35S-6D3-P101 11.200.1.107 BYCB_9_DPM1_P20
92 BYDB_16_VFD 35S-6D3-P101 11.200.1.108 BYCB_9_DPM1_P21
93 SPARE 11.200.1.109 BYCB_9_DPM1_P22
94 SPARE 11.200.1.110 BYCB_9_DPM1_P23
95 SPARE 11.200.1.111 BYCB_9_DPM1_P24
96 SPARE 11.200.1.112 BYCB_9_DPM1_P25
97 SPARE 11.200.1.113 BYCB_9_DPM1_P26
98 SPARE 11.200.1.114 BYCB_9_DPM1_P27
99 SPARE 11.200.1.115 BYCB_9_DPM1_P28
100 BYCB_10_DPM1 11.200.1.6 BYBC_10_FIOM1 Murr 54631 11.200.1.116 BYCB_10_DPM1_P5
101 BYAB_15_FIOM1 Murr 54631 11.200.1.117 BYCB_10_DPM1_P6
102 BYDB_15_FIOM1 Murr 54631 11.200.1.118 BYCB_10_DPM1_P7
103 BYBA_7_VFD 35S-6D4-P111 11.200.1.119 BYCB_10_DPM1_P8
104 BYBD_7_VFD 35S-6D4-P111 11.200.1.120 BYCB_10_DPM1_P9
105 BYBC_8_VFD 35S-6D4-P111 11.200.1.121 BYCB_10_DPM1_P10
106 BYCB_8_VFD 35S-6D5-P111 11.200.1.122 BYCB_10_DPM1_P11
107 BYBC_9_VFD 35S-6D3-P101 11.200.1.123 BYCB_10_DPM1_P12
108 BYBC_10_VFD 35S-6D3-P101 11.200.1.124 BYCB_10_DPM1_P13
109 BYBC_11_VFD 35S-6D4-P111 11.200.1.125 BYCB_10_DPM1_P14
110 BYAB_14_VFD 35S-6D5-P111 11.200.1.126 BYCB_10_DPM1_P15
111 BYDB_14_VFD 35S-6D5-P111 11.200.1.127 BYCB_10_DPM1_P16
112 BYAB_15_VFD 35S-6D4-P111 11.200.1.128 BYCB_10_DPM1_P17
113 BYDB_15_VFD 35S-6D3-P101 11.200.1.129 BYCB_10_DPM1_P18
114 SPARE 11.200.1.130 BYCB_10_DPM1_P19
115 SPARE 11.200.1.131 BYCB_10_DPM1_P20
116 SPARE 11.200.1.132 BYCB_10_DPM1_P21
117 SPARE 11.200.1.133 BYCB_10_DPM1_P22
118 SPARE 11.200.1.134 BYCB_10_DPM1_P23
119 SPARE 11.200.1.135 BYCB_10_DPM1_P24
120 SPARE 11.200.1.136 BYCB_10_DPM1_P25
121 SPARE 11.200.1.137 BYCB_10_DPM1_P26
122 SPARE 11.200.1.138 BYCB_10_DPM1_P27
123 SPARE 11.200.1.139 BYCB_10_DPM1_P28
124 BYCB_11_DPM1 11.200.1.7 BYBC_2_FIOM1 Murr 54631 11.200.1.140 BYCB_11_DPM1_P5
125 BYCB_13_FIOM1 Murr 54631 11.200.1.141 BYCB_11_DPM1_P6
126 BYAB_19_FIOM1 Murr 54631 11.200.1.142 BYCB_11_DPM1_P7
127 BYDB_19_FIOM1 Murr 54631 11.200.1.143 BYCB_11_DPM1_P8
128 BYBC_1_VFD 35S-6D3-P101 11.200.1.144 BYCB_11_DPM1_P9
129 BYBD_1_VFD 35S-6D3-P101 11.200.1.145 BYCB_11_DPM1_P10
130 BYBC_2_VFD 35S-6D3-P101 11.200.1.146 BYCB_11_DPM1_P11
131 BYBD_2_VFD 35S-6D3-P101 11.200.1.147 BYCB_11_DPM1_P12
132 BYBC_3_VFD 35S-6D4-P111 11.200.1.148 BYCB_11_DPM1_P13
133 BYBD_3_VFD 35S-6D2-P101 11.200.1.149 BYCB_11_DPM1_P14
134 BYBC_4_VFD 35S-6D4-P111 11.200.1.150 BYCB_11_DPM1_P15
135 BYBD_4_VFD 35S-6D2-P101 11.200.1.151 BYCB_11_DPM1_P16
136 BYBD_5_VFD 35S-6D2-P101 11.200.1.152 BYCB_11_DPM1_P17
137 BYBD_6_VFD 35S-6D3-P101 11.200.1.153 BYCB_11_DPM1_P18
138 BYCB_11_VFD 35S-6D4-P111 11.200.1.154 BYCB_11_DPM1_P19
139 BYCB_12_VFD 35S-6D3-P101 11.200.1.155 BYCB_11_DPM1_P20
140 BYCB_13_VFD 35S-6D2-P101 11.200.1.156 BYCB_11_DPM1_P21
141 BYAB_17_VFD 35S-6D3-P101 11.200.1.157 BYCB_11_DPM1_P22
142 BYDB_17_VFD 35S-6D4-P111 11.200.1.158 BYCB_11_DPM1_P23
143 BYAB_18_VFD 35S-6D3-P101 11.200.1.159 BYCB_11_DPM1_P24
144 BYDB_18_VFD 35S-6D3-P101 11.200.1.160 BYCB_11_DPM1_P25
145 BYAB_19_VFD 35S-6D2-P101 11.200.1.161 BYCB_11_DPM1_P26
146 BYDB_19_VFD 35S-6D2-P101 11.200.1.162 BYCB_11_DPM1_P27
147 SPARE 11.200.1.163 BYCB_11_DPM1_P28

View File

@ -0,0 +1,396 @@
import pandas as pd
import re
from pathlib import Path
def sort_key_fiom(term):
"""
Sort key for FIOM controllers with X format (X0_0, X0_1, etc.)
Sort order: X3_0, X3_1, X2_0, X2_1, X1_0, X1_1, X0_0, X0_1,
X7_0, X7_1, X6_0, X6_1, X5_0, X5_1, X4_0, X4_1
"""
if pd.isna(term) or not isinstance(term, str):
return (999, 999)
match = re.match(r'X(\d+)_([01])', term)
if not match:
return (999, term)
x_num = int(match.group(1))
suffix = int(match.group(2)) # 0 or 1
# Sort priority: X3->1, X2->2, X1->3, X0->4, X7->5, X6->6, X5->7, X4->8
sort_priority = {
3: 1, 2: 2, 1: 3, 0: 4, # First group
7: 5, 6: 6, 5: 7, 4: 8 # Second group
}
priority = sort_priority.get(x_num, 999)
# suffix 0 should come before suffix 1
return (priority, suffix)
def sort_key_fioh(term):
"""
Sort key for FIOH controllers with C format (C1_A, C1_B, etc.)
Sort order: C7_A, C7_B, C5_A, C5_B, C3_A, C3_B, C1_A, C1_B,
C8_A, C8_B, C6_A, C6_B, C4_A, C4_B, C2_A, C2_B
"""
if pd.isna(term) or not isinstance(term, str):
return (999, 999)
match = re.match(r'C(\d+)_([AB])', term)
if not match:
return (999, term)
num = int(match.group(1))
letter = match.group(2)
# Sort priority: C7->1, C5->2, C3->3, C1->4, C8->5, C6->6, C4->7, C2->8
sort_priority = {
7: 1, 5: 2, 3: 3, 1: 4, # Odd descending first
8: 5, 6: 6, 4: 7, 2: 8 # Even descending second
}
priority = sort_priority.get(num, 999)
letter_priority = 0 if letter == 'A' else 1 # A before B
return (priority, letter_priority)
def is_fiom_controller(tagname):
"""Check if controller name contains FIOM"""
if pd.isna(tagname) or not isinstance(tagname, str):
return False
return 'FIOM' in str(tagname).upper()
def is_fioh_controller(tagname):
"""Check if controller name contains FIOH"""
if pd.isna(tagname) or not isinstance(tagname, str):
return False
return 'FIOH' in str(tagname).upper()
def is_vfd_controller(tagname):
"""Check if controller name contains VFD"""
if pd.isna(tagname) or not isinstance(tagname, str):
return False
return 'VFD' in str(tagname).upper()
def get_base_prefix(tagname):
"""
Extract base prefix from controller name (before the controller type).
Examples:
PDP17_FIOM1 -> PDP17
PDP17_FIOH -> PDP17
BYAD_3_VFD -> BYAD_3
BYAD_3_FIOM -> BYAD_3
"""
if pd.isna(tagname) or not isinstance(tagname, str):
return ''
tagname_upper = str(tagname).upper()
# Try to find controller type markers
for controller_type in ['_FIOM', '_FIOH', '_VFD']:
if controller_type in tagname_upper:
idx = tagname_upper.index(controller_type)
return str(tagname)[:idx]
# If no controller type found, return the whole name
return str(tagname)
def get_column_mapping(xlsx_df):
"""
Map original XLSX columns to new CSV column names.
Attempts to find columns by common name variations.
"""
column_mapping = {}
# Find source columns (case-insensitive search)
cols_lower = {col.lower().strip(): col for col in xlsx_df.columns}
# Controller name -> TAGNAME
tagname_sources = ['controller name', 'controller', 'tagname', 'tag name']
column_mapping['TAGNAME'] = None
# First check if TAGNAME already exists (exact match, case-insensitive)
for col in xlsx_df.columns:
if col.upper().strip() == 'TAGNAME':
column_mapping['TAGNAME'] = col
break
# If not found, search by variations
if column_mapping['TAGNAME'] is None:
for src in tagname_sources:
if src in cols_lower:
column_mapping['TAGNAME'] = cols_lower[src]
break
# Address name -> ADDR
addr_sources = ['address name', 'address', 'addr']
column_mapping['ADDR'] = None
# Check if ADDR already exists
for col in xlsx_df.columns:
if col.upper().strip() == 'ADDR':
column_mapping['ADDR'] = col
break
if column_mapping['ADDR'] is None:
for src in addr_sources:
if src in cols_lower:
column_mapping['ADDR'] = cols_lower[src]
break
# Signal Type -> TERM
term_sources = ['signal type', 'signal', 'term']
column_mapping['TERM'] = None
# Check if TERM already exists
for col in xlsx_df.columns:
if col.upper().strip() == 'TERM':
column_mapping['TERM'] = col
break
if column_mapping['TERM'] is None:
for src in term_sources:
if src in cols_lower:
column_mapping['TERM'] = cols_lower[src]
break
# Assigned device -> DESCA
desca_sources = ['assigned device', 'assigned', 'device']
column_mapping['DESCA'] = None
# Check if DESCA already exists
for col in xlsx_df.columns:
if col.upper().strip() == 'DESCA':
column_mapping['DESCA'] = col
break
if column_mapping['DESCA'] is None:
for src in desca_sources:
if src in cols_lower:
column_mapping['DESCA'] = cols_lower[src]
break
# Description -> DESCB
descb_sources = ['description', 'desc']
column_mapping['DESCB'] = None
# Check if DESCB already exists
for col in xlsx_df.columns:
if col.upper().strip() == 'DESCB':
column_mapping['DESCB'] = col
break
if column_mapping['DESCB'] is None:
for src in descb_sources:
if src in cols_lower:
column_mapping['DESCB'] = cols_lower[src]
break
return column_mapping
def convert_xlsx_to_csv(xlsx_path, csv_path=None, sheet_name=None):
"""
Convert XLSX file to CSV with specified column mappings and transformations.
Args:
xlsx_path: Path to input XLSX file
csv_path: Path to output CSV file (default: same name as XLSX but .csv extension)
sheet_name: Name of the sheet to read (if None, tries 'MCM03' first, then first sheet)
"""
# Read XLSX file
print(f"Reading XLSX file: {xlsx_path}")
# Try to find the right sheet - look for any MCM sheet (MCM02, MCM03, MCM14, etc.)
if sheet_name is None:
xls = pd.ExcelFile(xlsx_path)
# Find any sheet that starts with 'MCM'
mcm_sheets = [s for s in xls.sheet_names if s.upper().startswith('MCM')]
if mcm_sheets:
# Prioritize MCM14 if it exists, otherwise use the highest numbered MCM sheet
if 'MCM14' in mcm_sheets:
sheet_name = 'MCM14'
print(f"Found MCM14 sheet, reading from it...")
else:
# Sort MCM sheets and use the one with highest number
def extract_mcm_number(sheet):
match = re.match(r'MCM(\d+)', sheet.upper())
return int(match.group(1)) if match else 0
mcm_sheets_sorted = sorted(mcm_sheets, key=extract_mcm_number, reverse=True)
sheet_name = mcm_sheets_sorted[0]
print(f"Found MCM sheet: '{sheet_name}', reading from it...")
else:
# If no MCM sheet, try to find sheet with expected columns
for s in xls.sheet_names:
test_df = pd.read_excel(xlsx_path, sheet_name=s, nrows=1)
cols_lower = [c.lower().strip() for c in test_df.columns]
# Check if it has any of our expected column names
if any(key in ' '.join(cols_lower) for key in ['controller', 'signal', 'address', 'assigned', 'description']):
sheet_name = s
print(f"Found sheet with expected columns: '{sheet_name}', reading from it...")
break
else:
# Fallback to first sheet
sheet_name = xls.sheet_names[0]
print(f"No MCM sheet found, reading from first sheet: '{sheet_name}'...")
df = pd.read_excel(xlsx_path, sheet_name=sheet_name)
print(f"Original columns: {list(df.columns)}")
print(f"Total rows: {len(df)}")
# Get column mapping
column_mapping = get_column_mapping(df)
print(f"Column mapping: {column_mapping}")
# Create new DataFrame - preserve exact row order from Excel
new_df = pd.DataFrame()
new_df.index = df.index # Preserve original index order
# Map and copy data - preserve all rows in original order
if column_mapping['TAGNAME']:
new_df['TAGNAME'] = df[column_mapping['TAGNAME']].values
else:
print("Warning: TAGNAME column not found, using first column")
new_df['TAGNAME'] = df.iloc[:, 0].values if len(df.columns) > 0 else ''
if column_mapping['ADDR']:
new_df['ADDR'] = df[column_mapping['ADDR']].values
else:
new_df['ADDR'] = ''
if column_mapping['TERM']:
new_df['TERM'] = df[column_mapping['TERM']].values # Use .values to preserve exact order
else:
new_df['TERM'] = ''
# Empty column TERMDESC
new_df['TERMDESC'] = ''
if column_mapping['DESCA']:
new_df['DESCA'] = df[column_mapping['DESCA']].values
else:
new_df['DESCA'] = ''
if column_mapping['DESCB']:
new_df['DESCB'] = df[column_mapping['DESCB']].values
else:
new_df['DESCB'] = ''
# Empty columns: DESCC, DESCD, DESCE, INST, LOC
new_df['DESCC'] = ''
new_df['DESCD'] = ''
new_df['DESCE'] = ''
new_df['INST'] = ''
new_df['LOC'] = ''
# Reorder columns to match required output format (doesn't change row order)
new_df = new_df[['TAGNAME', 'ADDR', 'TERM', 'TERMDESC', 'DESCA', 'DESCB',
'DESCC', 'DESCD', 'DESCE', 'INST', 'LOC']]
# Reset index to ensure clean sequential order, but preserve row sequence
new_df = new_df.reset_index(drop=True)
print("Sorting data by controller groups and TERM order...")
# Add base prefix column for grouping
new_df['_base_prefix'] = new_df['TAGNAME'].apply(get_base_prefix)
# Add base prefix priority to sort PDPs first
def get_base_prefix_priority(base_prefix):
"""Return priority: PDP=1, others=2 (sorted alphabetically)"""
if base_prefix.upper().startswith('PDP'):
return (1, base_prefix) # PDPs first, then sorted by name
else:
return (2, base_prefix) # Others after PDPs, sorted by name
new_df['_base_priority'] = new_df['_base_prefix'].apply(get_base_prefix_priority)
# Add controller type priority for ordering within each base prefix group
def get_controller_type_priority(tagname):
"""Return priority: VFD=1, FIOM=2, FIOH=3, Other=4"""
if is_vfd_controller(tagname):
return 1
elif is_fiom_controller(tagname):
return 2
elif is_fioh_controller(tagname):
return 3
else:
return 4
new_df['_ctrl_type_priority'] = new_df['TAGNAME'].apply(get_controller_type_priority)
# Separate rows by controller type for TERM sorting
fiom_mask = new_df['TAGNAME'].apply(is_fiom_controller)
fioh_mask = new_df['TAGNAME'].apply(is_fioh_controller)
vfd_mask = new_df['TAGNAME'].apply(is_vfd_controller)
other_mask = ~(fiom_mask | fioh_mask | vfd_mask)
# Sort FIOM by X format: X3_0, X3_1, X2_0, X2_1, X1_0, X1_1, X0_0, X0_1,
# X7_0, X7_1, X6_0, X6_1, X5_0, X5_1, X4_0, X4_1
if fiom_mask.any():
new_df.loc[fiom_mask, '_sort_priority'] = new_df.loc[fiom_mask, 'TERM'].apply(lambda x: sort_key_fiom(x)[0])
new_df.loc[fiom_mask, '_sort_suffix'] = new_df.loc[fiom_mask, 'TERM'].apply(lambda x: sort_key_fiom(x)[1])
print(f"Sorted {fiom_mask.sum()} FIOM rows by TERM")
else:
new_df['_sort_priority'] = 0
new_df['_sort_suffix'] = 0
# Sort FIOH by C format: C7_A, C7_B, C5_A, C5_B, C3_A, C3_B, C1_A, C1_B,
# C8_A, C8_B, C6_A, C6_B, C4_A, C4_B, C2_A, C2_B
if fioh_mask.any():
new_df.loc[fioh_mask, '_sort_priority'] = new_df.loc[fioh_mask, 'TERM'].apply(lambda x: sort_key_fioh(x)[0])
new_df.loc[fioh_mask, '_sort_suffix'] = new_df.loc[fioh_mask, 'TERM'].apply(lambda x: sort_key_fioh(x)[1])
print(f"Sorted {fioh_mask.sum()} FIOH rows by TERM")
# Fill NaN values in sort columns for non-FIOM/FIOH rows
new_df['_sort_priority'] = new_df['_sort_priority'].fillna(999)
new_df['_sort_suffix'] = new_df['_sort_suffix'].fillna(999)
# Final sort: PDPs first, then by base prefix, then by controller type (VFD, FIOM, FIOH),
# then by TAGNAME, then by TERM sort order
final_df = new_df.sort_values([
'_base_priority', # PDPs first, then others alphabetically
'_ctrl_type_priority', # VFD first, then FIOM, then FIOH
'TAGNAME', # Keep same controller together
'_sort_priority', # Sort TERM by custom order
'_sort_suffix'
])
# Drop temporary sorting columns
final_df = final_df.drop(columns=['_base_prefix', '_base_priority', '_ctrl_type_priority', '_sort_priority', '_sort_suffix'])
final_df = final_df.reset_index(drop=True)
print(f"Grouped controllers by base prefix and sorted within groups")
# Determine output path
if csv_path is None:
xlsx_path_obj = Path(xlsx_path)
csv_path = xlsx_path_obj.with_suffix('.csv')
# Write to CSV
print(f"Writing CSV file: {csv_path}")
try:
final_df.to_csv(csv_path, index=False)
print(f"Conversion complete! Total rows: {len(final_df)}")
except PermissionError:
print(f"\nERROR: Cannot write to '{csv_path}' - file is likely open in another program.")
print("Please close the CSV file in Excel or any other program and try again.")
raise
except Exception as e:
print(f"\nERROR writing CSV file: {e}")
raise
return final_df
if __name__ == "__main__":
import sys
# Get input file and optional sheet name from command line arguments
input_file = None
sheet_name_arg = None
if len(sys.argv) > 1:
input_file = sys.argv[1]
if len(sys.argv) > 2:
sheet_name_arg = sys.argv[2]
if input_file is None:
input_file = "Amazon CDW5_Devices IO (1).xlsx"
# Check if file exists
if Path(input_file).exists():
result_df = convert_xlsx_to_csv(input_file, sheet_name=sheet_name_arg)
print(f"\nSummary:")
print(f"- Total rows in output: {len(result_df)}")
else:
print(f"Error: File '{input_file}' not found!")
print("Please ensure the XLSX file is in the same directory as this script.")
print("\nUsage: python xlsx_to_csv.py [filename.xlsx] [sheet_name]")
print("Example: python xlsx_to_csv.py 'file.xlsx' 'MCM14'")

Binary file not shown.

3069
SCADA/Undrscore/output.json Normal file

File diff suppressed because it is too large Load Diff

3069
SCADA/Undrscore/test.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
#!/usr/bin/env python3
import json
import sys
def fix_names(obj):
"""
Recursively traverse obj (which may be a dict or list),
and whenever we find obj['meta']['name'], replace '-' with '_'.
"""
if isinstance(obj, dict):
# if this dict has a 'meta' sub-dict with a 'name' key, fix it
meta = obj.get("meta")
if isinstance(meta, dict) and "name" in meta:
name = meta["name"]
if isinstance(name, str) and "-" in name:
meta["name"] = name.replace("-", "_")
# recurse into all values
for v in obj.values():
fix_names(v)
elif isinstance(obj, list):
for item in obj:
fix_names(item)
def main():
if len(sys.argv) < 2:
print("Usage: python3 process_json.py input.json [output.json]")
sys.exit(1)
in_path = sys.argv[1]
out_path = sys.argv[2] if len(sys.argv) >= 3 else None
# load
with open(in_path, "r", encoding="utf-8") as f:
data = json.load(f)
# process
fix_names(data)
# write
if out_path:
with open(out_path, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
print(f"Processed JSON written to {out_path}")
else:
print(json.dumps(data, indent=2, ensure_ascii=False))
if __name__ == "__main__":
main()

View File

@ -0,0 +1,38 @@
DPM,DPM_IP,Name,IP
DPM01_VS01C,11.200.1.2,VS01C_FIOM1,11.200.1.101
DPM01_VS01C,11.200.1.2,VS01C_FIOM3,11.200.1.102
DPM01_VS01C,11.200.1.2,VS01C_FIOM5,11.200.1.103
DPM01_VS01C,11.200.1.2,VS01C_FIOM7,11.200.1.104
DPM01_VS01C,11.200.1.2,VS01C_FIOM9,11.200.1.105
DPM01_VS01C,11.200.1.2,VS01C_FIOM2,11.200.1.106
DPM01_VS01C,11.200.1.2,VS01C_FIOM4,11.200.1.107
DPM01_VS01C,11.200.1.2,VS01C_FIOM6,11.200.1.108
DPM01_VS01C,11.200.1.2,VS01C_FIOM8,11.200.1.109
DPM01_VS01C,11.200.1.2,VS01C_FIOM10,11.200.1.110
DPM01_VS01C,11.200.1.2,VS01C_FIOM11,11.200.1.111
DPM01_VS01C,11.200.1.2,VS01C_FIOM13,11.200.1.112
DPM01_VS01C,11.200.1.2,VS01C_FIOM15,11.200.1.113
DPM01_VS01C,11.200.1.2,VS01C_FIOM17,11.200.1.114
DPM01_VS01C,11.200.1.2,VS01C_FIOM18,11.200.1.115
DPM01_VS01C,11.200.1.2,VS01C_FIOM12,11.200.1.116
DPM01_VS01C,11.200.1.2,VS01C_FIOM14,11.200.1.117
DPM01_VS01C,11.200.1.2,VS01C_FIOM16,11.200.1.118
DPM01_VS01B,11.200.1.3,VS01B_FIOM1,11.200.1.121
DPM01_VS01B,11.200.1.3,VS01B_FIOM3,11.200.1.122
DPM01_VS01B,11.200.1.3,VS01B_FIOM5,11.200.1.123
DPM01_VS01B,11.200.1.3,VS01B_FIOM7,11.200.1.124
DPM01_VS01B,11.200.1.3,VS01B_FIOM9,11.200.1.125
DPM01_VS01B,11.200.1.3,VS01B_FIOM2,11.200.1.126
DPM01_VS01B,11.200.1.3,VS01B_FIOM4,11.200.1.127
DPM01_VS01B,11.200.1.3,VS01B_FIOM6,11.200.1.128
DPM01_VS01B,11.200.1.3,VS01B_FIOM8,11.200.1.129
DPM01_VS01B,11.200.1.3,VS01B_FIOM10,11.200.1.130
DPM01_VS01B,11.200.1.3,VS01B_FIOM11,11.200.1.131
DPM01_VS01B,11.200.1.3,VS01B_FIOM13,11.200.1.132
DPM01_VS01B,11.200.1.3,VS01B_FIOM15,11.200.1.133
DPM01_VS01B,11.200.1.3,VS01B_FIOM17,11.200.1.134
DPM01_VS01B,11.200.1.3,VS01B_FIOM19,11.200.1.135
DPM01_VS01B,11.200.1.3,VS01B_FIOM12,11.200.1.136
DPM01_VS01B,11.200.1.3,VS01B_FIOM14,11.200.1.137
DPM01_VS01B,11.200.1.3,VS01B_FIOM16,11.200.1.138
DPM01_VS01B,11.200.1.3,VS01B_FIOM18,11.200.1.139
1 DPM DPM_IP Name IP
2 DPM01_VS01C 11.200.1.2 VS01C_FIOM1 11.200.1.101
3 DPM01_VS01C 11.200.1.2 VS01C_FIOM3 11.200.1.102
4 DPM01_VS01C 11.200.1.2 VS01C_FIOM5 11.200.1.103
5 DPM01_VS01C 11.200.1.2 VS01C_FIOM7 11.200.1.104
6 DPM01_VS01C 11.200.1.2 VS01C_FIOM9 11.200.1.105
7 DPM01_VS01C 11.200.1.2 VS01C_FIOM2 11.200.1.106
8 DPM01_VS01C 11.200.1.2 VS01C_FIOM4 11.200.1.107
9 DPM01_VS01C 11.200.1.2 VS01C_FIOM6 11.200.1.108
10 DPM01_VS01C 11.200.1.2 VS01C_FIOM8 11.200.1.109
11 DPM01_VS01C 11.200.1.2 VS01C_FIOM10 11.200.1.110
12 DPM01_VS01C 11.200.1.2 VS01C_FIOM11 11.200.1.111
13 DPM01_VS01C 11.200.1.2 VS01C_FIOM13 11.200.1.112
14 DPM01_VS01C 11.200.1.2 VS01C_FIOM15 11.200.1.113
15 DPM01_VS01C 11.200.1.2 VS01C_FIOM17 11.200.1.114
16 DPM01_VS01C 11.200.1.2 VS01C_FIOM18 11.200.1.115
17 DPM01_VS01C 11.200.1.2 VS01C_FIOM12 11.200.1.116
18 DPM01_VS01C 11.200.1.2 VS01C_FIOM14 11.200.1.117
19 DPM01_VS01C 11.200.1.2 VS01C_FIOM16 11.200.1.118
20 DPM01_VS01B 11.200.1.3 VS01B_FIOM1 11.200.1.121
21 DPM01_VS01B 11.200.1.3 VS01B_FIOM3 11.200.1.122
22 DPM01_VS01B 11.200.1.3 VS01B_FIOM5 11.200.1.123
23 DPM01_VS01B 11.200.1.3 VS01B_FIOM7 11.200.1.124
24 DPM01_VS01B 11.200.1.3 VS01B_FIOM9 11.200.1.125
25 DPM01_VS01B 11.200.1.3 VS01B_FIOM2 11.200.1.126
26 DPM01_VS01B 11.200.1.3 VS01B_FIOM4 11.200.1.127
27 DPM01_VS01B 11.200.1.3 VS01B_FIOM6 11.200.1.128
28 DPM01_VS01B 11.200.1.3 VS01B_FIOM8 11.200.1.129
29 DPM01_VS01B 11.200.1.3 VS01B_FIOM10 11.200.1.130
30 DPM01_VS01B 11.200.1.3 VS01B_FIOM11 11.200.1.131
31 DPM01_VS01B 11.200.1.3 VS01B_FIOM13 11.200.1.132
32 DPM01_VS01B 11.200.1.3 VS01B_FIOM15 11.200.1.133
33 DPM01_VS01B 11.200.1.3 VS01B_FIOM17 11.200.1.134
34 DPM01_VS01B 11.200.1.3 VS01B_FIOM19 11.200.1.135
35 DPM01_VS01B 11.200.1.3 VS01B_FIOM12 11.200.1.136
36 DPM01_VS01B 11.200.1.3 VS01B_FIOM14 11.200.1.137
37 DPM01_VS01B 11.200.1.3 VS01B_FIOM16 11.200.1.138
38 DPM01_VS01B 11.200.1.3 VS01B_FIOM18 11.200.1.139

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,697 @@
#!/usr/bin/env python3
"""
Script to generate Ignition MCM view JSON from CSV input.
CSV format: DPM,DPM_IP,Name,IP
"""
import csv
import json
import sys
import re
from typing import List, Dict, Any
from collections import defaultdict
def create_plc_device(mcm_name: str, x: float, y: float) -> Dict[str, Any]:
"""Create PLC device component."""
return {
"type": "ia.display.view",
"version": 0,
"props": {
"path": "Windows/Tabs/Enternet Windows/Components/Device",
"params": {
"name": mcm_name,
"type": "PLC"
}
},
"meta": {
"name": "PLC"
},
"position": {
"x": x,
"y": y,
"height": 0.1032,
"width": 0.0522
},
"custom": {},
"propConfig": {
"props.params.tag": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"fc": "{session.custom.fc}"
},
"tagPath": f"[{{fc}}_SCADA_TAG_PROVIDER]System/{mcm_name}/Rack/Communication_Faulted"
},
"transforms": [
{
"expression": "coalesce({value},{view.params.forceFaultStatus},\"comm\")",
"type": "expression"
},
{
"fallback": False,
"inputType": "scalar",
"mappings": [
{
"input": True,
"output": True
},
{
"input": "comm",
"output": "comm"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "tag"
}
}
}
}
def create_plc_switch(x: float, y: float, down: bool = True, up: bool = True,
left: bool = False, right: bool = False, name: str = "PLC_Switch") -> Dict[str, Any]:
"""Create PLC Switch component."""
return {
"type": "ia.display.view",
"version": 0,
"props": {
"path": "Windows/Tabs/Enternet Windows/Components/PLC_Switch",
"params": {
"down": down,
"left": left,
"right": right,
"up": up
}
},
"meta": {
"name": name
},
"position": {
"x": x,
"y": y,
"height": 0.1032,
"width": 0.0522
},
"custom": {}
}
def create_switch(x: float, y: float, down: bool = True, up: bool = True,
left: bool = False, right: bool = False, name: str = "Switch") -> Dict[str, Any]:
"""Create Switch component."""
return {
"type": "ia.display.view",
"version": 0,
"props": {
"path": "Windows/Tabs/Enternet Windows/Components/Switch",
"params": {
"down": down,
"left": left,
"right": right,
"up": up
}
},
"meta": {
"name": name
},
"position": {
"x": x,
"y": y,
"height": 0.1032,
"width": 0.0522
},
"custom": {}
}
def create_line(x: float, y: float, down: bool = True, up: bool = True,
left: bool = False, right: bool = False, name: str = "Line") -> Dict[str, Any]:
"""Create Line component."""
return {
"type": "ia.display.view",
"version": 0,
"props": {
"path": "Windows/Tabs/Enternet Windows/Components/Line",
"params": {
"down": down,
"left": left,
"right": right,
"up": up
}
},
"meta": {
"name": name
},
"position": {
"x": x,
"y": y,
"height": 0.1032,
"width": 0.0522
},
"custom": {}
}
def create_dpm_device(mcm_name: str, dpm_name: str, dpm_ip: str, x: float, y: float) -> Dict[str, Any]:
"""Create DPM device component."""
return {
"type": "ia.display.view",
"version": 0,
"props": {
"path": "Windows/Tabs/Enternet Windows/Components/Device",
"params": {
"ip": dpm_ip,
"name": dpm_name,
"type": "DPM_BLOCK"
}
},
"meta": {
"name": dpm_name
},
"position": {
"x": x,
"y": y,
"height": 0.1032,
"width": 0.0522
},
"custom": {},
"propConfig": {
"props.params.tag": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"fc": "{session.custom.fc}"
},
"tagPath": f"[{{fc}}_SCADA_TAG_PROVIDER]System/{mcm_name}/IO_BLOCK/DPM/{dpm_name}/Communication_Faulted"
},
"transforms": [
{
"expression": "coalesce({value},{view.params.forceFaultStatus},\"comm\")",
"type": "expression"
},
{
"fallback": False,
"inputType": "scalar",
"mappings": [
{
"input": True,
"output": True
},
{
"input": "comm",
"output": "comm"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "tag"
}
}
}
}
def determine_device_type(device_name: str) -> str:
"""Determine device type from name."""
name_upper = device_name.upper()
if '_VFD' in name_upper:
return 'APF'
elif '_EX' in name_upper:
return 'EXTENDO'
elif '_FIO' in name_upper or '_SIO' in name_upper or '_FIOM' in name_upper:
return 'FIO_SIO'
elif '_TIPPER' in name_upper:
return 'TIPPER'
elif '_PMM' in name_upper:
return 'PMM'
elif '_ZMX' in name_upper:
return 'ZMX'
else:
return 'APF' # Default
def determine_device_category(device_name: str, device_type: str) -> str:
"""Determine device category for tag path."""
if device_type == 'APF':
return 'Conveyor/VFD'
elif device_type == 'EXTENDO':
return 'Conveyor/EXTENDO'
elif device_type == 'TIPPER':
return 'Conveyor/TIPPER'
elif device_type == 'FIO_SIO':
return 'IO_BLOCK/FIO'
elif device_type == 'PMM':
return 'PMM'
elif device_type == 'ZMX':
return 'Chute/D2C'
else:
return 'Conveyor/VFD'
def create_device(mcm_name: str, device_name: str, device_ip: str,
x: float, y: float) -> Dict[str, Any]:
"""Create a device component."""
device_type = determine_device_type(device_name)
category = determine_device_category(device_name, device_type)
# For ZMX devices, replace _ZMX* suffix with _D2C_CHUTE in the tag path
tag_device_name = device_name
if device_type == 'ZMX':
# Replace _ZMX followed by any digits with _D2C_CHUTE
tag_device_name = re.sub(r'_ZMX\d*', '_D2C_CHUTE', device_name)
return {
"type": "ia.display.view",
"version": 0,
"props": {
"path": "Windows/Tabs/Enternet Windows/Components/Device",
"params": {
"ip": device_ip,
"name": device_name,
"type": device_type
}
},
"meta": {
"name": device_name
},
"position": {
"x": x,
"y": y,
"height": 0.1032,
"width": 0.0522
},
"custom": {},
"propConfig": {
"props.params.tag": {
"binding": {
"config": {
"fallbackDelay": 2.5,
"mode": "indirect",
"references": {
"fc": "{session.custom.fc}"
},
"tagPath": f"[{{fc}}_SCADA_TAG_PROVIDER]System/{mcm_name}/{category}/{tag_device_name}/Communication_Faulted"
},
"transforms": [
{
"expression": "coalesce({value},{view.params.forceFaultStatus},\"comm\")",
"type": "expression"
},
{
"fallback": False,
"inputType": "scalar",
"mappings": [
{
"input": True,
"output": True
},
{
"input": "comm",
"output": "comm"
}
],
"outputType": "scalar",
"type": "map"
}
],
"type": "tag"
}
}
}
}
def extract_mcm_number(full_name: str) -> str:
"""Extract MCM number from full name (e.g., 'SAT9_MCM02' -> 'MCM02')."""
# Look for MCM followed by digits
match = re.search(r'MCM\d+', full_name, re.IGNORECASE)
if match:
return match.group().upper()
return full_name
def generate_mcm_view(mcm_name: str, dpm_data: Dict[str, Dict]) -> List[Dict[str, Any]]:
"""
Generate the complete MCM view structure with multi-row support.
Args:
mcm_name: Name of the MCM (e.g., "MCM02")
dpm_data: Dictionary mapping DPM names to their info and devices
Returns:
List containing the root container with all children
"""
children = []
switch_counter = 1
# Layout constants
start_x = 0.0188
plc_y = 0.0024
plc_switch_y = 0.1028
dpm_start_y = 0.2034
vertical_switch_offset = 0.0966 # Distance from DPM to vertical switch between DPMs
base_dpm_spacing = 0.1974 # Base vertical spacing between DPMs
horizontal_spacing = 0.0527 # Horizontal spacing between devices
device_below_switch = 0.0997 # Distance from switch to device below it
row_height = 0.20 # Height for each row (switch + device + gap)
# Maximum devices per row (fits in 1920px width)
max_devices_per_row = 17
# Add PLC at the top
children.append(create_plc_device(mcm_name, start_x, plc_y))
# Add PLC Switch connecting to DPMs
children.append(create_plc_switch(start_x, plc_switch_y, down=True, up=True))
# Track cumulative Y offset for variable DPM spacing
cumulative_y = dpm_start_y
# Add DPMs with their devices
for dpm_idx, (dpm_name, dpm_info) in enumerate(dpm_data.items()):
dpm_y = cumulative_y
# Add DPM
children.append(create_dpm_device(
mcm_name,
dpm_name,
dpm_info['dpm_ip'],
start_x,
dpm_y
))
# Add devices horizontally from this DPM (with multi-row support)
devices = dpm_info.get('devices', [])
num_rows = max(1, (len(devices) + max_devices_per_row - 1) // max_devices_per_row) if devices else 1
# If multiple rows, create vertical chain from DPM (Lines + Switch)
# Position vertical chain at DPM location to avoid overlap with first row
row_connector_x = start_x
if num_rows > 1:
# Calculate position of last device in first row
first_row_device_count = min(max_devices_per_row, len(devices))
last_device_pos_in_row = first_row_device_count - 1
first_row_last_device_x = start_x + ((last_device_pos_in_row + 1) * horizontal_spacing)
# Add 3 Lines connecting last device of first row to vertical chain
first_row_switch_y = dpm_y # Y position of first row switches
first_row_device_y = first_row_switch_y + device_below_switch # Y position of first row devices
second_row_switch_y = dpm_y + row_height # Y position of second row switches
# Position lines to the right - full spacing away (same distance as between switches)
lines_x = first_row_last_device_x + horizontal_spacing
# Line 1: At same height as first row switch, connects left to switch and down
line1_y = first_row_switch_y
children.append(create_line(
lines_x,
line1_y,
down=True,
up=False,
left=True,
right=False,
name="FirstRowLine1"
))
# Line 2: At same height as first row devices, vertical line up and down
line2_y = first_row_device_y
children.append(create_line(
lines_x,
line2_y,
down=True,
up=True,
left=False,
right=False,
name="FirstRowLine2"
))
# Line 3: At same height as second row switches, connects up and left to vertical chain
line3_y = second_row_switch_y
children.append(create_line(
lines_x,
line3_y,
down=False,
up=True,
left=True,
right=False,
name="FirstRowLine3"
))
# Create vertical connectors: Line - Switch - Line pattern
# Need 3 connectors for proper connection: Line, Switch (branches), Line
num_vertical_connectors = 3 if num_rows == 2 else (num_rows - 1) * 2 + 1
for v_idx in range(num_vertical_connectors):
v_y = dpm_y + ((v_idx + 1) * row_height / 2)
# Determine which row this connector branches to (if any)
connects_to_row = None
if num_rows == 2 and v_idx == 1:
connects_to_row = 1 # Second connector (Switch) connects to second row
elif num_rows > 2:
# For more rows, connect at appropriate intervals
for r in range(1, num_rows):
if v_idx == (r * 2 - 1):
connects_to_row = r
break
# All connectors connect upward and downward in the chain
has_up = True
has_down = True
# Pattern: Line (idx 0), Switch (idx 1), Line (idx 2)
if v_idx == 1:
# Middle is Switch (vertical only, no branching)
children.append(create_switch(
row_connector_x,
v_y,
down=has_down,
up=has_up,
left=False,
right=False, # No branching
name=f"Switch{switch_counter}"
))
switch_counter += 1
else:
# First and third are Lines
line_num = 1 if v_idx == 0 else 2
children.append(create_line(
row_connector_x,
v_y,
down=has_down,
up=has_up,
left=False,
right=False, # Lines don't branch
name=f"VerticalLine{line_num}"
))
for dev_idx, device in enumerate(devices):
# Calculate which row and position in row
row_num = dev_idx // max_devices_per_row
pos_in_row = dev_idx % max_devices_per_row
# Calculate position
if row_num == 0:
# First row: left to right, starting after DPM
device_x = start_x + ((pos_in_row + 1) * horizontal_spacing)
else:
# Additional rows: right to left, starting from first row's last switch position
# Start at same X as last switch of first row and go backwards (leftward)
if num_rows > 1:
device_x = first_row_last_device_x - (pos_in_row * horizontal_spacing)
else:
device_x = start_x + ((pos_in_row + 1) * horizontal_spacing)
switch_y = dpm_y + (row_num * row_height)
device_y = switch_y + device_below_switch
# Determine switch connections
is_first_in_row = (pos_in_row == 0)
is_last_in_row = (pos_in_row == max_devices_per_row - 1) or (dev_idx == len(devices) - 1)
is_last_device_of_first_row = (row_num == 0 and is_last_in_row and num_rows > 1)
# Switch connections
if row_num == 0:
# First row: left to right
connects_left = True
connects_right = (not is_last_in_row) or (num_rows > 1) # Last switch connects right if multiple rows
else:
# Additional rows: right to left (reversed)
connects_right = True
connects_left = not is_last_in_row
# Add switch above device
children.append(create_switch(
device_x,
switch_y,
down=True,
up=False,
left=connects_left,
right=connects_right,
name=f"Switch{switch_counter}"
))
switch_counter += 1
# Add device
children.append(create_device(
mcm_name,
device['name'],
device['ip'],
device_x,
device_y
))
# Calculate total height used by this DPM including all rows
if devices and num_rows > 1:
# Multi-row: With vertical connectors, height includes the vertical Line/Switch chain
num_vertical_connectors = 3 if num_rows == 2 else (num_rows - 1) * 2 + 1
# Vertical connectors start at (v_idx + 1) * row_height / 2
# Last connector position will be where next DPM connects
dpm_total_height = ((num_vertical_connectors + 1) * row_height / 2)
cumulative_y += dpm_total_height
else:
# Single row or no devices - use original simple spacing
# Just add base DPM spacing, vertical switch will be added separately
cumulative_y += base_dpm_spacing
# Add vertical switch below DPM to connect to next DPM (except for the last DPM)
# Only needed if single row or no devices - vertical chain already handles multi-row
if dpm_idx < len(dpm_data) - 1 and (num_rows == 1 or not devices):
switch_y = dpm_y + vertical_switch_offset
children.append(create_switch(
start_x,
switch_y,
down=True,
up=True,
left=False,
right=False,
name=f"Switch{switch_counter}"
))
switch_counter += 1
# Create root container
root = {
"type": "ia.container.coord",
"version": 0,
"props": {
"mode": "percent"
},
"meta": {
"name": mcm_name
},
"position": {},
"custom": {},
"children": children
}
return [root]
def read_csv_file(csv_path: str) -> Dict[str, Dict]:
"""
Read CSV file and extract DPM and device information.
CSV format: DPM,DPM_IP,Name,IP
Returns:
Dictionary mapping DPM names to their info and devices
"""
dpm_data = defaultdict(lambda: {'dpm_ip': None, 'devices': []})
with open(csv_path, 'r', encoding='utf-8-sig') as f: # utf-8-sig handles BOM
reader = csv.DictReader(f)
# Debug: print available columns
first_row = True
for row in reader:
if first_row:
print(f"CSV columns found: {list(row.keys())}")
first_row = False
# Handle potential column name variations
dpm_key = 'DPM' if 'DPM' in row else next((k for k in row.keys() if 'DPM' in k.upper()), None)
dpm_ip_key = 'DPM_IP' if 'DPM_IP' in row else next((k for k in row.keys() if 'DPM_IP' in k.upper() or 'DPM IP' in k.upper()), None)
name_key = 'Name' if 'Name' in row else next((k for k in row.keys() if k.upper() == 'NAME'), None)
ip_key = 'IP' if 'IP' in row else next((k for k in row.keys() if k.upper() == 'IP' and k != dpm_ip_key), None)
if not dpm_key or not dpm_ip_key:
print(f"Warning: Could not find DPM columns. Available: {list(row.keys())}")
continue
dpm_name = row[dpm_key].strip()
dpm_ip = row[dpm_ip_key].strip()
# Skip empty rows
if not dpm_name or not dpm_ip:
continue
# Set DPM IP if not already set
if dpm_data[dpm_name]['dpm_ip'] is None:
dpm_data[dpm_name]['dpm_ip'] = dpm_ip
# Add device if name and IP are provided
if name_key and ip_key:
device_name = row[name_key].strip()
device_ip = row[ip_key].strip()
if device_name and device_ip:
dpm_data[dpm_name]['devices'].append({
'name': device_name,
'ip': device_ip
})
return dict(dpm_data)
def main():
if len(sys.argv) < 3:
print("Usage: python generate_network_topology.py <csv_file> <mcm_name> [output_file]")
print("\nCSV format: DPM,DPM_IP,Name,IP")
print("Example: python generate_network_topology.py dpms.csv SAT9_MCM02 output.json")
sys.exit(1)
csv_file = sys.argv[1]
mcm_name_input = sys.argv[2]
# Extract just the MCM number (e.g., "SAT9_MCM02" -> "MCM02")
mcm_name = extract_mcm_number(mcm_name_input)
output_file = sys.argv[3] if len(sys.argv) > 3 else f"{mcm_name}_view.json"
print(f"Processing {csv_file}...")
print(f"MCM Name: {mcm_name}")
# Read CSV
dpm_data = read_csv_file(csv_file)
# Count total devices
total_devices = sum(len(dpm_info['devices']) for dpm_info in dpm_data.values())
# Generate view
view = generate_mcm_view(mcm_name, dpm_data)
# Write output
with open(output_file, 'w') as f:
json.dump(view, f, indent=2)
print(f"\n✓ Generated view for {mcm_name}")
print(f" - {len(dpm_data)} DPMs")
print(f" - {total_devices} total devices")
print(f"✓ Output written to: {output_file}")
if __name__ == "__main__":
main()

1
SCADA/tag_props_scada Submodule

@ -0,0 +1 @@
Subproject commit 4b861e5b9fe44d233218b53a13acda650797dfe9