Files
presence-sensor/poe-variant/enclosure-poe.scad
root c131a97ac4 Add PoE variant with W5500 Ethernet and 802.3af power
- W5500 SPI Ethernet controller for wired connectivity
- Silvertel Ag9905MT PoE PD module (48V to 5V)
- RJ45 connector with integrated magnetics
- Higher camera resolution (1024x768 vs 800x600) using wired bandwidth
- WiFi fallback if Ethernet disconnected
- Separate BOM, pin mapping, ESPHome config
- 3D-printable enclosure (50x40mm, larger for RJ45)
2026-03-29 13:00:07 -05:00

134 lines
4.0 KiB
OpenSCAD

// ============================================
// Presence Sensor PoE - Wall-Mount Enclosure
// Board: 50 x 40 mm (larger for RJ45 + PoE module)
// ============================================
pcb_w = 50;
pcb_h = 40;
pcb_t = 1.6;
wall = 1.8;
tolerance = 0.3;
bottom_gap = 3;
top_gap = 14; // Extra height for RJ45 jack
lid_lip = 1.5;
inner_w = pcb_w + tolerance * 2;
inner_h = pcb_h + tolerance * 2;
inner_d = bottom_gap + pcb_t + top_gap;
outer_w = inner_w + wall * 2;
outer_h = inner_h + wall * 2;
outer_d = inner_d + wall;
post_d = 4.5;
screw_d = 2.2;
post_h = bottom_gap;
// Component windows
cam_hole_w = 10;
cam_hole_h = 10;
pir_hole_d = 10;
light_hole_d = 4;
rj45_w = 16;
rj45_h = 14;
module rounded_box(w, h, d, r) {
hull() {
translate([r, r, 0]) cylinder(h=d, r=r, $fn=20);
translate([w-r, r, 0]) cylinder(h=d, r=r, $fn=20);
translate([r, h-r, 0]) cylinder(h=d, r=r, $fn=20);
translate([w-r, h-r, 0]) cylinder(h=d, r=r, $fn=20);
}
}
module wall_mount_keyhole() {
cylinder(h=wall+2, d=7, $fn=24);
translate([0, -5, 0])
hull() {
cylinder(h=wall+2, d=4, $fn=24);
translate([0, 5, 0]) cylinder(h=wall+2, d=4, $fn=24);
}
}
module body() {
difference() {
rounded_box(outer_w, outer_h, outer_d, 3);
translate([wall, wall, wall])
rounded_box(inner_w, inner_h, inner_d + 1, 2);
// Camera window (top center)
translate([wall + tolerance + pcb_w/2 - cam_hole_w/2,
wall + tolerance + pcb_h - 7,
-1])
rounded_box(cam_hole_w, cam_hole_h, wall + 2, 2);
// PIR window (left)
translate([wall + tolerance + 12,
wall + tolerance + pcb_h - 22,
-1])
cylinder(h=wall+2, d=pir_hole_d, $fn=32);
// Light sensor window
translate([wall + tolerance + 24,
wall + tolerance + pcb_h - 22,
-1])
cylinder(h=wall+2, d=light_hole_d, $fn=32);
// RJ45 cutout (bottom edge)
translate([wall + tolerance + pcb_w/2 - rj45_w/2,
-1,
wall + bottom_gap - 1])
cube([rj45_w, wall + 2, rj45_h]);
// Ventilation slots (sides)
for (i = [0:3]) {
translate([-1, wall + 5 + i * 10, wall + bottom_gap + pcb_t + 2])
cube([wall + 2, 8, 1.5]);
translate([outer_w - wall - 1, wall + 5 + i * 10, wall + bottom_gap + pcb_t + 2])
cube([wall + 2, 8, 1.5]);
}
// mmWave slot (back)
translate([wall + tolerance + pcb_w - 10,
wall + tolerance + 5,
outer_d - wall - 0.5])
rounded_box(8, 36, wall + 1, 1);
// Wall mount keyholes (back)
translate([outer_w/2, outer_h * 0.3, outer_d - wall - 1])
wall_mount_keyhole();
translate([outer_w/2, outer_h * 0.7, outer_d - wall - 1])
wall_mount_keyhole();
}
// PCB support posts
for (pos = [[wall + tolerance + 2.5, wall + tolerance + 2.5],
[wall + tolerance + pcb_w - 2.5, wall + tolerance + 2.5],
[wall + tolerance + 2.5, wall + tolerance + pcb_h - 2.5],
[wall + tolerance + pcb_w - 2.5, wall + tolerance + pcb_h - 2.5]]) {
translate([pos[0], pos[1], wall])
difference() {
cylinder(h=post_h, d=post_d, $fn=20);
cylinder(h=post_h + 1, d=screw_d, $fn=20);
}
}
}
module lid() {
difference() {
union() {
rounded_box(outer_w, outer_h, wall, 3);
translate([wall - lid_lip/2, wall - lid_lip/2, wall])
rounded_box(inner_w + lid_lip, inner_h + lid_lip, 2, 2);
}
// LED windows
translate([wall + tolerance + 42, wall + tolerance + 30, -1])
cylinder(h=wall+2, d=2, $fn=16);
translate([wall + tolerance + 44, wall + tolerance + 30, -1])
cylinder(h=wall+2, d=2, $fn=16);
}
}
// Render
body();
translate([outer_w + 10, 0, 0]) lid();