From Events to Enclosures: Building a Presence Sensor

I want my home automation to handle an ordinary situation well: walk into a room, sit down, and have the lights stay on without periodically waving at a sensor. When I leave, they should turn off. When I disable automation, that decision should take effect immediately.

That sounds straightforward until the system has to decide whether a quiet room is empty or someone is simply sitting still.

In my earlier event-hub project, I explored how sensor events could feed a Go application that controls the response. The Go dashboard work extended that idea to another event consumer. This project pushes the sensing side further. Instead of treating the sensor as a black box that emits a convenient event, I wanted to work through the full path from physical observation to the behavior someone experiences in the room.

That meant bringing embedded firmware, occupancy logic, hardware integration, automation, and enclosure design together in one system.

The hardware combines an ESP32, a millimeter-wave radar sensor, a PIR sensor, and a physical switch. I use the two sensing methods as complementary inputs to an occupancy decision. Reading the sensors is relatively straightforward. The more interesting problem is deciding what their observations mean over time.

Turning Sensor Readings Into Behavior

The firmware interprets sensor observations and reports meaningful state changes. My automation, written in Go, handles the lighting response. That includes allowing a period of uncertainty before switching the lights off, responding to renewed activity, and respecting the physical override. Repeated readings should also not produce a stream of redundant commands to my IoT lights.

I deliberately keep those responsibilities separated. The embedded side understands the hardware and reports useful state. The Go application decides what that state means for the room.

That boundary gives the system room to evolve. I can adjust lighting policy, timing, or downstream behavior without treating every change as a firmware release. Logs around state transitions also provide a trail from what the sensor reported to what the automation decided to do, which becomes important when the behavior differs from what someone in the room expected.

At that point, the project stops being purely a software problem.

The automation can be correct, and the electronics can work perfectly on a bench, but the finished device still has to exist as a physical system. Sensor placement affects what the hardware can observe. The switch has to remain accessible. The USB port still needs to accept an actual cable after the board is enclosed. Wiring needs somewhere to go, and the device needs to come apart cleanly when something eventually needs servicing.

That pulled the project into mechanical design.

Turning Constraints Into Geometry

CAD has become one of my favorite parts of this project because it turns those physical constraints into explicit geometry. A mounting post has a defined center and height. A sensor opening has a measurable position relative to the board behind it. Component placements share a coordinate system, which makes the relationships between them easier to reason about.

Moving one component is no longer an isolated decision. Moving a sensor to improve separation also changes its relationship with the enclosure opening and nearby supports. The switch needs both an accessible actuator and a mounting surface. The USB opening must account for the connector and the space needed to insert a cable. The enclosure also needs enough internal room for wiring while remaining serviceable once everything is assembled.

Those relationships make the mechanical model useful long before anything is printed. I can inspect alignment, revise clearances, and check whether the parts have a plausible assembly path before committing the design to a physical object. Small placement decisions become much easier to evaluate when they exist as dimensions instead of assumptions.

The CAD model also changed how I thought about the system itself. At the software level, a sensor can look like an event source. At the mechanical level, that same sensor has dimensions, mounting requirements, a field of view, connectors, wiring, and a fixed relationship with everything around it. Both views describe the same component, but they expose very different constraints.

That is where the project started to feel less like a collection of individual parts and more like one connected system.

0:00
/0:25

Following a Decision Across the Whole System

The benefit of connecting those layers becomes clearer when you trace a single decision through the system.

A sensor's physical placement affects what it observes. Firmware interprets those observations and turns them into state. The Go application applies the automation policy, and the resulting command affects the room. The person in that room experiences the end result, which may be as simple as whether the lights stay on while they are quietly sitting at a desk.

The project started with a behavioral requirement: the room should understand presence well enough that I do not have to think about the automation. Getting there required carrying that requirement through sensing, embedded firmware, state management, application logic, hardware placement, and mechanical design.

There is not a clean point where one discipline ends and another begins. A mechanical decision can affect sensor behavior. Sensor behavior changes the state the firmware reports. That state changes what the application does. Eventually, all of those engineering decisions collapse into one very ordinary user experience.

If the system works correctly, nobody in the room should need to care about any of them.

That is also what made this project different from most of my software work. I started with a behavioral problem, designed the event flow, wrote the application and firmware, selected and integrated the hardware, modeled the enclosure, and then sent the resulting geometry out for fabrication.

The interesting part was never any single layer. It was carrying the original idea through all of them without losing the intent along the way.

This is still a prototype, and I will almost certainly want to change things after living with the physical device. That is part of what I wanted from the project. The design now has a path from an idea, through code and hardware, into something that can be assembled, tested, observed, and revised.

If you're interested in the design and approach, I may follow up with a more build-focused post once the final material list, enclosure, and behavior have had more time in real-world use.

A Note on AI-Assisted CAD Development

I chose not to use my token quota for this particular CAD build because I wanted to work through the geometry and component relationships directly. There is, however, an interesting tooling layer emerging around CAD.

MCP integrations and other AI-assisted tools already automate parts of the mechanical workflow, including aligning components into assemblies, working through geometric relationships, and translating higher-level design intent into CAD operations. Research on generating CAD programs from visual or higher-level inputs is moving in a similar direction.

I think that becomes especially useful once you understand the constraints of the physical system. Automating the work required to express a design is different from understanding why a component belongs where it does, what another component depends on, or what happens when one dimension changes.

For rapid prototyping, the combination could become particularly powerful: reason through the physical constraints, encode them into a parametric model, and then use automation to reduce some of the repetitive work required to iterate on it.

Further Reading

A better way to turn 2D designs into 3D models for rapid prototyping
“GIFT” is a new system that teaches vision-language generative AI models to produce accurate, computer-aided design (CAD) programs that can be used to simulate and test 3D objects. The method is more accurate than competing techniques, using a fraction of the computation.
AI-guided optimization tool makes product design faster and more accessible | MIT Department of Mechanical Engineering
MIT’s Department of Mechanical Engineering (MechE) offers a world-class education that combines thorough analysis with hands-on discovery. One of the original six courses offered when MIT was founded, MechE faculty and students conduct research that pushes boundaries and provides creative solutions for the world’s problems.
You've successfully subscribed to Amitk.io
Great! Next, complete checkout for full access to Amitk.io
Welcome back! You've successfully signed in.
Unable to sign you in. Please try again.
Success! Your account is fully activated, you now have access to all content.
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.