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):
|
||||
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):
|
||||
def test_assign_default_position_hierarchy(self):
|
||||
|
|
|
|||
|
|
@ -64,15 +64,17 @@ def parse_cross_plan(excel_path):
|
|||
|
||||
|
||||
# 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 = []
|
||||
max_row = sheet.max_row
|
||||
max_col = sheet.max_column
|
||||
|
||||
for r in range(1, max_row + 1):
|
||||
val = sheet.cell(row=r, column=1).value
|
||||
if val and isinstance(val, str) and ("câble" in val.lower() or "cable" in val.lower()):
|
||||
cable_sections.append((r, val.strip()))
|
||||
for c in range(1, max_col + 1):
|
||||
val = sheet.cell(row=r, column=c).value
|
||||
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
|
||||
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_model_name = m.group(2).strip() if m else "SVAVB 61x1,5mm²"
|
||||
|
||||
# Count number of strands
|
||||
strands = 61
|
||||
if "10x2x0,8" in cable_model_name:
|
||||
strands = 20
|
||||
elif "61x1,5" in cable_model_name:
|
||||
# Count number of strands dynamically
|
||||
m_double = re.search(r'(\d+)\s*x\s*(\d+)\s*x\s*[\d,.]+', cable_model_name, re.IGNORECASE)
|
||||
m_multi = re.search(r'(\d+)\s*x[^\d]+(\d+)\s*x\s*[\d,.]+', cable_model_name, re.IGNORECASE)
|
||||
m_single = re.search(r'(\d+)\s*x\s*[\d,.]+', cable_model_name, re.IGNORECASE)
|
||||
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
|
||||
elif "14x1,5" in cable_model_name:
|
||||
strands = 14
|
||||
|
||||
# Find which poles are associated with this cable_label
|
||||
connected_poles = sorted(list(set([
|
||||
|
|
@ -283,7 +289,7 @@ def parse_cross_plan(excel_path):
|
|||
|
||||
if conn.get("is_detector", False):
|
||||
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
|
||||
|
||||
if is_detector:
|
||||
|
|
|
|||
Loading…
Reference in a new issue