kcl-samplespdu-faceplate

pdu-faceplate

pdu-faceplate

KCL

// Power Distribution Unit (PDU) faceplate with European plug sockets and switch
// Designed for standard 19-inch rack systems with 1U height and 8 sockets

// Set units in millimeters (mm)
@settings(defaultLengthUnit = mm, kclVersion = 1.0)

// Define the dimensions
// Width fits standard 19” rack, height is 1U, depth is variable
faceplateWidth = 482.6 // this is standardized to fit 19-inch racks)
faceplateHeight = 44.45 // usually 1U (44.45 mm), but can be 2U (88.9 mm) or more
faceplateDepth = 100 // varies by manufacturer, but commonly between 100 mm and 300 mm


// Define dimensions of side supports (width and thickness)
supportWidth = 50
supportThickness = 3

// Main body of the PDU faceplate with integrated rack mounting flanges
faceplateShape = startSketchOn(offsetPlane(XY, offset = -faceplateHeight / 2))
  |> startProfile(%, at = [-faceplateWidth / 2 - supportWidth, 0])
  |> yLine(length = supportThickness)
  |> xLine(length = supportWidth)
  |> yLine(length = faceplateDepth - supportThickness)
  |> xLine(length = faceplateWidth)
  |> yLine(length = supportThickness - faceplateDepth)
  |> xLine(length = supportWidth)
  |> yLine(length = -supportThickness)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
  |> close()
faceplateBody = extrude(faceplateShape, length = faceplateHeight)
faceplateFrontFace = startSketchOn(faceplateBody, face = seg01)

// Creates recessed volume within the faceplate for inserting modules
nestWall = 2
nestWidth = faceplateWidth - (nestWall * 2)
nestHeight = faceplateHeight - (nestWall * 2)
nestDepth = faceplateDepth - nestWall
nestShape = startProfile(faceplateFrontFace, at = [-nestWidth / 2, nestHeight / 2])
  |> xLine(length = nestWidth)
  |> yLine(length = -nestHeight)
  |> xLine(length = -nestWidth)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
nestVoid = extrude(nestShape, length = -nestDepth)

// Spacer block on the left side, used to position components correctly
moduleHeight = nestHeight
moduleWidth = nestHeight
moduleDepth = nestHeight

leftSpacerWidth = moduleWidth * 1.5
leftSpacerPosition = leftSpacerWidth / 2 - (nestWidth / 2)

fn boxModuleFn(width) {
  shape = startSketchOn(XZ)
    |> startProfile(%, at = [-width / 2, moduleHeight / 2])
    |> xLine(length = width)
    |> yLine(length = -moduleHeight)
    |> xLine(length = -width)
    |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
    |> close()
  body = extrude(shape, length = -moduleDepth)
  return body
}
leftSpacerShape = boxModuleFn(width = leftSpacerWidth)
  |> translate(
       %,
       x = leftSpacerPosition,
       y = 0,
       z = 0,
     )

// Module for power switch including front plate and red rocker button
switchPosition = leftSpacerPosition + leftSpacerWidth / 2 + moduleWidth / 2
switchWidth = moduleWidth

// Switch Body
switchBody = boxModuleFn(width = moduleWidth)

// Switch Plate
switchPlateWidth = 20
switchPlateHeight = 30
switchPlateThickness = 3
switchPlateShape = startSketchOn(switchBody, face = END)
  |> startProfile(
       %,
       at = [
         -switchPlateWidth / 2,
         -switchPlateHeight / 2
       ],
     )
  |> yLine(length = switchPlateHeight)
  |> xLine(length = switchPlateWidth)
  |> yLine(length = -switchPlateHeight)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
switchPlateBody = extrude(switchPlateShape, length = switchPlateThickness)
  |> translate(
       %,
       x = switchPosition,
       y = 0,
       z = 0,
     )

// Switch Button
switchButtonHeight = 26
switchButtonWidth = 15
switchButtonShape = startSketchOn(offsetPlane(-YZ, offset = -switchButtonWidth / 2))
  |> startProfile(
       %,
       at = [
         switchPlateThickness,
         switchButtonHeight / 2
       ],
     )
  |> line(end = [3, -1])
  |> arc(interiorAbsolute = [6, 0], endAbsolute = [12, -9])
  |> line(endAbsolute = [
       switchPlateThickness,
       -switchButtonHeight / 2
     ])
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
switchButtonBody = extrude(switchButtonShape, length = switchButtonWidth)
  |> translate(
       %,
       x = switchPosition,
       y = 0,
       z = 0,
     )
  |> appearance(%, color = "#ff0000")

// Spacer between switch and plug modules for layout alignment
secondSpacerWidth = moduleWidth / 2
secondSpacerPosition = switchPosition + switchWidth / 2 + secondSpacerWidth / 2
secondSpacerBody = boxModuleFn(width = secondSpacerWidth)
  |> translate(
       %,
       x = secondSpacerPosition,
       y = 0,
       z = 0,
     )

  // European power plug modules with circular sockets and two-pin holes
// 8 identical sockets, each with grounding notch and dual-pin recesses
powerPlugWidth = moduleWidth
powerPlugCount = 8
powerPlugOveralWidth = powerPlugWidth * powerPlugCount
firstPowerPlugPosition = secondSpacerPosition + secondSpacerWidth / 2 + powerPlugWidth / 2
lastPowerPlugPosition = firstPowerPlugPosition + powerPlugWidth * (powerPlugCount - 1)
powerPlugBody = boxModuleFn(width = powerPlugWidth)
  |> translate(
       %,
       x = firstPowerPlugPosition,
       y = 0,
       z = 0,
     )
plugShape = startSketchOn(powerPlugBody, face = END)
  |> circle(%, center = [0, 0], radius = 17)
  |> translate(
       %,
       x = firstPowerPlugPosition,
       y = 0,
       z = 0,
     )
plugBody = extrude(plugShape, length = -20)
plugHoleDistance = 20
plugHoleShape = startSketchOn(plugBody, face = START)
  |> circle(%, center = [-plugHoleDistance / 2, 0], radius = 3)
  |> translate(
       %,
       x = firstPowerPlugPosition,
       y = 0,
       z = 0,
     )
  |> patternLinear2d(
       %,
       instances = 2,
       distance = plugHoleDistance,
       axis = [1, 0],
     )
plugHoleBody = extrude(plugHoleShape, length = -5)
  |> patternLinear3d(
       %,
       instances = powerPlugCount,
       distance = powerPlugWidth,
       axis = [1, 0, 0],
     )

// Rightmost spacer to fill in remaining horizontal space
rightSpacerWidth = nestWidth / 2 - lastPowerPlugPosition - (powerPlugWidth / 2)
rightSpacerPosition = lastPowerPlugPosition + powerPlugWidth / 2 + rightSpacerWidth / 2
rightSpacerBody = boxModuleFn(width = rightSpacerWidth)
  |> translate(
       %,
       x = rightSpacerPosition,
       y = 0,
       z = 0,
     )

// Rack mounting holes on flanges, elongated for alignment flexibility
holeWidth = 25
holeDiameter = 5
holeStraightSegment = holeWidth - holeDiameter
holeVerticalDistance = faceplateHeight * 0.3

holeShapes = startProfile(
       faceplateFrontFace,
       at = [
         -holeStraightSegment / 2,
         holeDiameter / 2
       ],
     )
  |> xLine(length = holeStraightSegment)
  |> tangentialArc(endAbsolute = [
       holeStraightSegment / 2,
       -holeDiameter / 2
     ])
  |> xLine(length = -holeStraightSegment)
  |> tangentialArc(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> translate(
       %,
       x = -faceplateWidth / 2 - (supportWidth / 2),
       y = 0,
       z = -holeVerticalDistance,
     )
  |> patternLinear2d(
       %,
       instances = 3,
       distance = holeVerticalDistance,
       axis = [0, 1],
     )
  |> patternLinear2d(
       %,
       instances = 2,
       distance = faceplateWidth + supportWidth,
       axis = [1, 0],
     )
holeVoid = extrude(holeShapes, length = -supportThickness)