545 lines
17 KiB
Common Lisp
545 lines
17 KiB
Common Lisp
(defun clearDrawing ( / ss)
|
|
(setq ss (ssget "_X" '((0 . "*"))))
|
|
(if ss (command "_.erase" ss ""))
|
|
(princ "\nDrawing cleared.")
|
|
)
|
|
|
|
(defun getVisibilityFromName (deviceName partNumber)
|
|
(cond
|
|
((wcmatch (strcase deviceName) "*EX*") "Panel")
|
|
((wcmatch (strcase deviceName) "*PMM*") "Panel")
|
|
((wcmatch (strcase deviceName) "*TP*") "Panel")
|
|
((wcmatch (strcase deviceName) "*VSU*") "Panel")
|
|
((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 zoneTag)
|
|
(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 "")
|
|
(setq zoneTag "")
|
|
|
|
(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))
|
|
|
|
;; Preserve full zone tag (e.g., "MCM03") for notes, and also extract zone number digits (e.g., "03")
|
|
(if (and zoneRaw (/= zoneRaw ""))
|
|
(progn
|
|
(setq zoneTag (str-trim zoneRaw))
|
|
;; 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))
|
|
;; Store: (DPM -> (ip zoneNumber zoneTag))
|
|
(setq dpmList (append dpmList (list (cons dpm (list ip zoneNumber zoneTag)))))
|
|
)
|
|
)
|
|
)
|
|
|
|
(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 createEthernetCableScheduleTable (originX originY dpmName deviceGroup / doc ms insPt tbl rowHeight colWidths idx devicePair toName fromName cblTag rowIdx colIdx)
|
|
;; Creates a 3-column x 26-row table:
|
|
;; Row 1 (merged): "<DPM_NAME> ETHERNET CABLE SCHEDULE"
|
|
;; Row 2: headers - "CABLE TAG", "CABLE LABEL TO", "CABLE LABEL FROM"
|
|
;; Rows 3..26 (24 data rows):
|
|
;; Col A: CBL01..CBL24
|
|
;; Col B: device NAMEs from CSV (in order)
|
|
;; Col C: <DPM_NAME>-ETHCBL P5 to P28
|
|
|
|
;; Calculate row height from total table height (12.5450) / 26 rows
|
|
(setq rowHeight (/ 12.5450 26.0))
|
|
|
|
;; Insertion point shifts with layout X offset
|
|
(setq insPt (vlax-3d-point (list (+ originX 31.1911) (+ originY 12.9267) 0.0)))
|
|
|
|
(setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
|
|
(setq ms (vla-get-ModelSpace doc))
|
|
|
|
;; Create table: 26 rows, 3 columns
|
|
;; vla-AddTable params: space, insertionPoint, numRows, numCols, rowHeight, colWidth
|
|
(setq tbl (vla-AddTable ms insPt 26 3 rowHeight 3.9867))
|
|
|
|
;; Set layer
|
|
(vla-put-Layer tbl "0")
|
|
|
|
;; Try to set table style to "AS"
|
|
(vl-catch-all-apply 'vla-put-StyleName (list tbl "AS"))
|
|
|
|
;; Set column widths to achieve total width of 11.9601
|
|
;; Column A (CABLE TAG): ~2.0
|
|
;; Columns B & C: ~4.98 each
|
|
(vl-catch-all-apply 'vla-SetColumnWidth (list tbl 0 2.0))
|
|
(vl-catch-all-apply 'vla-SetColumnWidth (list tbl 1 4.98005))
|
|
(vl-catch-all-apply 'vla-SetColumnWidth (list tbl 2 4.98005))
|
|
|
|
;; Set text height, alignment, text style, and margins for all cells
|
|
;; acMiddleCenter = 5
|
|
(setq rowIdx 0)
|
|
(while (< rowIdx 26)
|
|
(setq colIdx 0)
|
|
(while (< colIdx 3)
|
|
(vl-catch-all-apply 'vla-SetTextHeight (list tbl rowIdx colIdx 0.1805))
|
|
(vl-catch-all-apply 'vla-SetCellAlignment (list tbl rowIdx colIdx 5))
|
|
(vl-catch-all-apply 'vla-SetTextStyle (list tbl rowIdx colIdx "WD"))
|
|
(setq colIdx (1+ colIdx))
|
|
)
|
|
(setq rowIdx (1+ rowIdx))
|
|
)
|
|
|
|
;; Set cell margins: horizontal and vertical = 0.1083
|
|
;; acTableCellMarginHorzSpacing = 1, acTableCellMarginVertSpacing = 2
|
|
(vl-catch-all-apply 'vla-SetMargin (list tbl 1 0.1083)) ;; horizontal
|
|
(vl-catch-all-apply 'vla-SetMargin (list tbl 2 0.1083)) ;; vertical
|
|
|
|
;; Row 1: Merge all columns and set title
|
|
(vl-catch-all-apply 'vla-MergeCells (list tbl 0 0 0 2))
|
|
(vla-SetText tbl 0 0 (strcat dpmName " ETHERNET CABLE SCHEDULE"))
|
|
|
|
;; Row 2: Headers
|
|
(vla-SetText tbl 1 0 "CABLE TAG")
|
|
(vla-SetText tbl 1 1 "CABLE LABEL TO")
|
|
(vla-SetText tbl 1 2 "CABLE LABEL FROM")
|
|
|
|
;; Rows 3..26 (indices 2..25): Data rows
|
|
(setq idx 0)
|
|
(while (< idx 24)
|
|
;; Column A: CBL01 to CBL24
|
|
(setq cblTag (strcat "CBL" (if (< (1+ idx) 10) "0" "") (itoa (1+ idx))))
|
|
|
|
;; Column B: Device name from CSV
|
|
(setq devicePair (nth idx deviceGroup))
|
|
(setq toName (if devicePair (cdr (assoc "NAME" devicePair)) "SPARE"))
|
|
|
|
;; Column C: <DPM_NAME>-ETHCBL P5 to P28
|
|
(setq fromName (strcat dpmName "-ETHCBL P" (itoa (+ 5 idx))))
|
|
|
|
(vla-SetText tbl (+ 2 idx) 0 cblTag)
|
|
(vla-SetText tbl (+ 2 idx) 1 toName)
|
|
(vla-SetText tbl (+ 2 idx) 2 fromName)
|
|
|
|
(setq idx (1+ idx))
|
|
)
|
|
tbl
|
|
)
|
|
|
|
(defun insertDLRNoteMText (originX originY zoneTag / bs notePt noteText)
|
|
;; Creates the note:
|
|
;; SEE DRAWING 2433-AMZ-CDW5-<ZONE>-701 FOR
|
|
;; DLR NETWORK LOOP
|
|
(setq bs (chr 92)) ;; backslash for MText formatting codes
|
|
(setq notePt (list (+ originX 5.5183) (+ originY 10.0751) 0.0))
|
|
(setq noteText
|
|
(strcat
|
|
bs "pxqr;"
|
|
"SEE DRAWING 2433-AMZ-CDW5-"
|
|
zoneTag
|
|
"-701 FOR"
|
|
bs "P"
|
|
"DLR NETWORK LOOP"
|
|
)
|
|
)
|
|
(entmakex
|
|
(list
|
|
(cons 0 "MTEXT")
|
|
(cons 100 "AcDbEntity")
|
|
(cons 8 "0")
|
|
(cons 100 "AcDbMText")
|
|
(cons 10 notePt)
|
|
(cons 40 0.2) ;; text height
|
|
(cons 7 "WD") ;; text style
|
|
(cons 71 1) ;; attachment point: top left
|
|
(cons 41 8.2690) ;; defined width
|
|
(cons 44 1.0) ;; line spacing factor
|
|
(cons 73 1) ;; line spacing style: at least
|
|
(cons 50 0.0) ;; rotation
|
|
(cons 1 noteText) ;; contents
|
|
)
|
|
)
|
|
)
|
|
|
|
(defun c:init-diagrams ( / blockName count offsetX i x y basePt targetPt lastEnt dpmPair dpmName dpmIP deviceGroup dpmUpsPt dpmUpsObj tag ent vlaObj zoneName zoneNumber zoneTag 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
|
|
;; Distance between consecutive layout Base Points (inches)
|
|
(setq offsetX 48.5)
|
|
(setq i 0)
|
|
(while (< i count)
|
|
(setq x (* i offsetX))
|
|
(setq y 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 zoneTag (caddr dpmData))
|
|
(setq deviceGroup (nth i deviceGroups))
|
|
|
|
;; Insert layout
|
|
;; Insert directly at targetPt so the block's Base Point is at the desired XYZ
|
|
(command "_.-INSERT" blockName targetPt 1 1 0)
|
|
(setq lastEnt (entlast))
|
|
(if lastEnt
|
|
(progn
|
|
(setLayoutWireNumbers lastEnt zoneNumber i)
|
|
)
|
|
)
|
|
|
|
;; Insert DLR network loop note (one per layout), offset matches screenshot and shifts with layout
|
|
(if (and zoneTag (/= zoneTag ""))
|
|
(insertDLRNoteMText x y zoneTag)
|
|
)
|
|
|
|
;; 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 Ethernet Cable Schedule table (one per DPM/layout)
|
|
(if (and dpmName (/= dpmName "") deviceGroup)
|
|
(createEthernetCableScheduleTable x y dpmName deviceGroup)
|
|
)
|
|
|
|
;; 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)
|
|
)
|
|
) |