← All projects
IGEN 430 Capstone Project · 2026

HAVEN / IGEN Shop Assistant

A smart tool vending system combining Raspberry Pi orchestration, Klipper motion control, FastAPI, React, MQTT, and RFID into a working physical prototype.

Raspberry PiFastAPIReactTypeScriptDockerMQTTKlipperMoonrakerCrowsnestRFIDTailscaleKiCad
HAVEN / IGEN Shop Assistant preview
Full-stack electromechanical system from concept to demo: frontend, backend, machine orchestration, motion macros, RFID auth flows, and admin tooling.
Designed bounded slot allocation and dispense/return state machines for six rotary tool cakes with encoder-based physical verification.
Deployed a Pi-hosted kiosk and remote admin interface via Docker Compose, Tailscale, FastAPI, React, and MQTT, with zero SSH required for operation.

The problem

The IGEN Shop at UBC is a student-run makerspace supporting over 250 users and 30+ capstone projects every year - an environment where tools are frequently misused, misplaced, or stolen. Over the past few years the shop has accumulated over $3,000 in tool losses, and the existing industry solutions are either prohibitively expensive ($95,000+), lack the security features a shared student shop actually needs, or fail to integrate into a makerspace environment. That gap — small shops needing effective, affordable tool tracking and loss prevention — is what HAVEN was built to close.

Solving it takes more than a display and some buttons: the system has to know who is authenticated, which slot is occupied, where the mechanism physically is, whether the machine is homed, whether a tool was actually returned, and whether hardware state agrees with software state at every step.

Demo

Project overview

Haven Shop Assistant capstone project poster

Capstone poster summarising system scope, hardware components, software stack, and design goals.

What we built

HAVEN is a smart tool vending prototype with a Raspberry Pi at the centre. We built it as a capstone team: two mechanical teammates designed and fabricated the machine itself - frame, rotary cakes, gantry, and doors - while I served as the software architect and electrical designer, owning everything from the software system design to the custom PCB.

The Pi runs a Docker Compose stack: a React + TypeScript kiosk frontend, a FastAPI backend, an MQTT event bus, and integrations with Moonraker and Klipper for motion control. A custom encoder-multiplexer PCB reports physical slot positions back to the bridge layer so the software always knows where the mechanism actually is.

Software architecture diagram showing the Docker containers, motion control, and sensor hub layers with the full tech stack

Software architecture. The Pi hosts the Docker containers (FastAPI, SQLite, Mosquitto), the BTT Octopus Max EZ runs Klipper firmware for the stepper motors, and an ESP32 sensor hub aggregates the six encoders.

User / Admin Touchscreen
React + TypeScript frontend
FastAPI backend ←→ MQTT broker
Bridge / orchestration layer
Moonraker REST API
Klipper macros → Raspberry Pi
BTT Octopus Max EZ + steppers + encoders

Cake and slot model

Each rotary dispenser is called a cake. A cake holds indexed slots; slot 0 is permanently reserved as the home/empty position. The backend tracks occupancy, rotation direction, and position independently from the hardware; this separation is what allows recovery when physical and software states diverge.

Cake and slot state diagram

Slot model for a single cake. The system enforces bounded rotation, always taking the shortest path and never wrapping past slot 0, which prevents direction debt from accumulating across cycles.


Dispense flow

A dispense starts with RFID authentication, steps through machine homing, rotation to the target cake and slice, door presentation, explicit user confirmation, and finally a slot model update. The user only sees a few steps; a lot happens in between.

Dispense sequence, simplified view

Simplified view showing the main actors and the state transitions a user experiences.

The zoomed views show what the bridge and Moonraker layers are doing during each phase:

Dispense sequence: authentication and homing phase

Authentication and homing phase

Dispense sequence: rotation, presentation, and confirmation phase

Rotation, presentation, and confirmation phase


Return flow

Returns follow a symmetric but distinct path. The slot model updates before the machine moves, and the encoder must confirm the physical return before the backend closes the transaction. This ordering prevents silent data corruption if the user pulls a tool and the machine loses power mid-flow.

Return sequence, simplified view

Simplified return flow

Return sequence with encoder verification

Detailed return with encoder verification


How a command travels through the stack

Example command travelling from frontend through to Klipper macro

A single admin command moving from the React frontend → FastAPI → MQTT broker → bridge layer → Moonraker REST → Klipper macro. Each hop is explicit and observable.


Hardware

Electrical architecture

Electrical architecture diagram: 24V fuse box feeding the BTT Octopus Max EZ and Raspberry Pi, with the custom encoder PCB closing the loop

Final electrical architecture. A 24V fuse box powers the BTT Octopus Max EZ driving nine motors and the Raspberry Pi orchestrating over serial; the custom PCB (nine encoders → I2C mux → ESP32) reports physical position back to the Pi on its own serial link, closing the verification loop.

Encoder multiplexer PCB

Custom encoder multiplexer PCB

Custom encoder MUX PCB designed in KiCad. Aggregates encoder signals from all six cakes onto a single serial bus back to the Pi, reducing GPIO pressure and keeping the wire harness manageable.

KiCad schematic of the encoder multiplexer board around a TCA9548A I2C multiplexer

Schematic: a TCA9548A I2C multiplexer fans out to nine encoder headers, with the ESP32 header on the left.

KiCad board layout of the encoder multiplexer PCB

Board layout, with the encoder headers arranged around the mux for short traces.

IGEN logo PCB

KiCad render of the UBC IGEN logo as a PCB with an embedded NFC coil

A side quest: the IGEN logo rebuilt as a PCB with an embedded NFC antenna. Half merch idea, half pitch — the shop could hand these out as tap-to-visit keepsakes that link straight to project pages. I would love to see this adopted in the IGEN space for real.


Admin interface

Admin UI manual control panel

Admin control panel. Exposes homing, manual cake rotation, slot status inspection, macro execution, and recovery workflows, all from a browser with no SSH required.


Key technical decisions

Stateful flows over button presses. The UI never fires a motor directly. It queries backend state, stages the requested flow, waits for physical confirmation at the door, and surfaces recovery tools when hardware and software disagree. Named stages (authentication, homing, rotation, presentation, confirmation, model update) make the system debuggable and safe to hand to someone who has never seen it before.

MQTT for observability. All events publish to the broker. This meant any component could subscribe for debugging without coupling the frontend to the backend. It also made adding the admin live-status panel a small addition rather than a refactor.

Encoder verification before model commit. The slot model does not update until the encoder confirms the physical position. This costs a round-trip but prevents ghost occupancy records that would corrupt future dispense routing.


Hard parts

These were the problems that only appeared once the software touched the real machine:

  • Homing logic where one side of the vertical gantry can finish before the other, leaving the carriage skewed
  • Stale frontend alert state surviving across admin login without a full page reload
  • Keeping slot 0 as a permanent home position without breaking the bounded rotation direction math
  • Preventing direction debt from accumulating across many dispense/return cycles on the same cake
  • Aligning asynchronous serial encoder output with the bridge parser under timing jitter
  • Exposing local services over Tailscale without making the kiosk session brittle when the tunnel reconnects

What is next

Automated tests for slot allocation and state transition edge cases, a richer admin event timeline with timestamps and actor labels, and hardware-in-the-loop encoder verification in CI. The sequence diagrams and demo video here are the starting point for documentation that should eventually let someone understand the full system in under five minutes without any of us in the room.