Support cross plan cable headers in any column, dynamic strands, and radar codes
This commit is contained in:
parent
09e684a07c
commit
442469f3e0
2 changed files with 61 additions and 12 deletions
|
|
@ -2060,6 +2060,49 @@ class TrafficLightCrossPlanImportTest(TestCase):
|
||||||
if os.path.exists(tmp_path):
|
if os.path.exists(tmp_path):
|
||||||
os.remove(tmp_path)
|
os.remove(tmp_path)
|
||||||
|
|
||||||
|
def test_parse_cross_plan_cable_header_any_column(self):
|
||||||
|
import openpyxl
|
||||||
|
import tempfile
|
||||||
|
from assets.utils.cross_plan_parser import parse_cross_plan
|
||||||
|
|
||||||
|
wb = openpyxl.Workbook()
|
||||||
|
ws = wb.active
|
||||||
|
ws.title = "kruisjesplan"
|
||||||
|
ws.cell(row=1, column=3, value="sleutel:")
|
||||||
|
ws.cell(row=1, column=4, value="SAT110")
|
||||||
|
# Cable header in column 7
|
||||||
|
ws.cell(row=2, column=7, value="Câble 01 SVAVB 30x1,5mm²")
|
||||||
|
ws.cell(row=4, column=1, value="Klem controller")
|
||||||
|
ws.cell(row=4, column=2, value="Klemnummer")
|
||||||
|
ws.cell(row=4, column=3, value="Richting")
|
||||||
|
ws.cell(row=4, column=4, value="Kringen")
|
||||||
|
ws.cell(row=5, column=5, value="A01")
|
||||||
|
ws.cell(row=5, column=6, value="A02")
|
||||||
|
|
||||||
|
# Row 6: Phase B
|
||||||
|
ws.cell(row=6, column=2, value=1)
|
||||||
|
ws.cell(row=6, column=3, value="B")
|
||||||
|
ws.cell(row=6, column=4, value="RS1")
|
||||||
|
ws.cell(row=6, column=5, value="X")
|
||||||
|
ws.cell(row=6, column=6, value="X")
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile(suffix=".xlsx", delete=False) as tmp:
|
||||||
|
tmp_path = tmp.name
|
||||||
|
wb.save(tmp_path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
deduced = parse_cross_plan(tmp_path)
|
||||||
|
self.assertEqual(deduced["intersection_code"], "SAT110")
|
||||||
|
self.assertEqual(len(deduced["poles"]), 2)
|
||||||
|
self.assertEqual(len(deduced["cables"]), 1)
|
||||||
|
self.assertEqual(deduced["cables"][0]["strands"], 30)
|
||||||
|
self.assertEqual(deduced["cables"][0]["code"], "SAT110_CAB01")
|
||||||
|
self.assertEqual(len(deduced["lanterns"]), 2)
|
||||||
|
finally:
|
||||||
|
import os
|
||||||
|
if os.path.exists(tmp_path):
|
||||||
|
os.remove(tmp_path)
|
||||||
|
|
||||||
|
|
||||||
class AssetDefaultPositionTest(TestCase):
|
class AssetDefaultPositionTest(TestCase):
|
||||||
def test_assign_default_position_hierarchy(self):
|
def test_assign_default_position_hierarchy(self):
|
||||||
|
|
|
||||||
|
|
@ -64,15 +64,17 @@ def parse_cross_plan(excel_path):
|
||||||
|
|
||||||
|
|
||||||
# 2. Scan sheet to identify cable sections
|
# 2. Scan sheet to identify cable sections
|
||||||
# Cable sections start at rows containing 'Câble' or 'Cable' in the first columns
|
# Cable sections start at rows containing 'Câble' or 'Cable' in any column
|
||||||
cable_sections = []
|
cable_sections = []
|
||||||
max_row = sheet.max_row
|
max_row = sheet.max_row
|
||||||
max_col = sheet.max_column
|
max_col = sheet.max_column
|
||||||
|
|
||||||
for r in range(1, max_row + 1):
|
for r in range(1, max_row + 1):
|
||||||
val = sheet.cell(row=r, column=1).value
|
for c in range(1, max_col + 1):
|
||||||
if val and isinstance(val, str) and ("câble" in val.lower() or "cable" in val.lower()):
|
val = sheet.cell(row=r, column=c).value
|
||||||
cable_sections.append((r, val.strip()))
|
if val and isinstance(val, str) and ("câble" in val.lower() or "cable" in val.lower()):
|
||||||
|
cable_sections.append((r, val.strip()))
|
||||||
|
break
|
||||||
|
|
||||||
# Parse each cable section
|
# Parse each cable section
|
||||||
deduced_poles = {} # pole_header -> {code, type}
|
deduced_poles = {} # pole_header -> {code, type}
|
||||||
|
|
@ -184,14 +186,18 @@ def parse_cross_plan(excel_path):
|
||||||
cable_num = int(m.group(1)) if m else (idx + 1)
|
cable_num = int(m.group(1)) if m else (idx + 1)
|
||||||
cable_model_name = m.group(2).strip() if m else "SVAVB 61x1,5mm²"
|
cable_model_name = m.group(2).strip() if m else "SVAVB 61x1,5mm²"
|
||||||
|
|
||||||
# Count number of strands
|
# Count number of strands dynamically
|
||||||
strands = 61
|
m_double = re.search(r'(\d+)\s*x\s*(\d+)\s*x\s*[\d,.]+', cable_model_name, re.IGNORECASE)
|
||||||
if "10x2x0,8" in cable_model_name:
|
m_multi = re.search(r'(\d+)\s*x[^\d]+(\d+)\s*x\s*[\d,.]+', cable_model_name, re.IGNORECASE)
|
||||||
strands = 20
|
m_single = re.search(r'(\d+)\s*x\s*[\d,.]+', cable_model_name, re.IGNORECASE)
|
||||||
elif "61x1,5" in cable_model_name:
|
if m_double:
|
||||||
|
strands = int(m_double.group(1)) * int(m_double.group(2))
|
||||||
|
elif m_multi:
|
||||||
|
strands = int(m_multi.group(1)) * int(m_multi.group(2))
|
||||||
|
elif m_single:
|
||||||
|
strands = int(m_single.group(1))
|
||||||
|
else:
|
||||||
strands = 61
|
strands = 61
|
||||||
elif "14x1,5" in cable_model_name:
|
|
||||||
strands = 14
|
|
||||||
|
|
||||||
# Find which poles are associated with this cable_label
|
# Find which poles are associated with this cable_label
|
||||||
connected_poles = sorted(list(set([
|
connected_poles = sorted(list(set([
|
||||||
|
|
@ -283,7 +289,7 @@ def parse_cross_plan(excel_path):
|
||||||
|
|
||||||
if conn.get("is_detector", False):
|
if conn.get("is_detector", False):
|
||||||
is_detector = True
|
is_detector = True
|
||||||
elif normalized_upper in ("RA", "RAB", "RB", "RC", "RD", "VD", "VC", "VT1", "VT2") or normalized_upper.startswith(("RM", "RP")):
|
elif normalized_upper in ("RA", "RAB", "RB", "RC", "RD", "VD", "VC", "VT1", "VT2") or normalized_upper.startswith(("RM", "RP", "RA", "RB", "RC", "RD", "VD", "VC", "VT")):
|
||||||
is_detector = True
|
is_detector = True
|
||||||
|
|
||||||
if is_detector:
|
if is_detector:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue