// ============================================ // 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();