+eps = 0.01;
+infty = 200;
+
+hole_dist = 87;
+hole_d = 2.5;
+hole_sep = 5;
+
+pcb_side_l = hole_dist+2*hole_sep;
+frame_l = 56;
+frame_w = 6.5;
+frame_wall = 2;
+frame_wall_front = 4;
+
+body_w = 15;
+body_h = 10;
+pcb_h = 7;
+pcb_bot = 3;
+
+frame_open_x = 3;
+frame_open_y = 15;
+
+module body() {
+ // pcb-side arm
+ cube([pcb_side_l, body_h, body_w]);
+ // frame-side arm
+ translate([-frame_w-frame_wall-frame_wall_front, 0, 0])
+ cube([body_h+frame_w+frame_wall, frame_l + 2*frame_wall, body_w]);
+}
+
+difference() {
+ body();
+
+ // pcb hole far
+ translate([pcb_side_l - hole_sep, -eps, body_w-hole_sep])
+ rotate([-90, 0, 0])
+ cylinder(r = hole_d/2, h = body_h + 2*eps);
+ // pcb hole near the corner
+ translate([hole_sep, -eps, body_w-hole_sep])
+ rotate([-90, 0, 0])
+ cylinder(r = hole_d/2, h = body_h + 2*eps);
+ // pcb
+ translate([0, pcb_h, body_w-2*hole_sep])
+ cube([pcb_side_l + eps, frame_l, body_w]);
+ // under the pcb
+ translate([2*hole_sep, pcb_bot, body_w-2*hole_sep])
+ cube([pcb_side_l - 4*hole_sep, body_h, body_w]);
+
+ // frame
+ translate([-frame_w-frame_wall_front, frame_wall, -eps])
+ cube([frame_w, frame_l, body_w + 2*eps]);
+ // frame opening
+ translate([-frame_w-frame_wall_front-frame_open_x, frame_wall+frame_open_y, -eps])
+ cube([frame_w, frame_l, body_w + 2*eps]);
+ // frame mounting hole
+ translate([-frame_wall_front-eps-body_h, frame_wall+hole_sep, body_w/2])
+ rotate([0, 90, 0])
+ rotate([0, 0, 90])
+ cylinder(r = hole_d/2, h = body_h + 2*eps, $fn = 6);
+}
+