โ† Back to Index
Week 15

Interface & Application Programming

Fab Academy Barcelona โ€” May 2026

The live Adoora interface โ€” a face in the camera orb, a keypad ring of digits 0โ€“9, and a subtitle line commenting on the visitor

Overview

Adoora is a sentient door lock you have to emotionally unlock. This week is the application that runs it: the conversation, the trust mechanic, and the interface a visitor actually talks to. The board, the WiFi, and the solenoid it drives are documented under Networking in Week 11 โ†’; this page is the app on top.

The whole thing is a single adoora.html โ€” no build step, no framework โ€” using GPT-4o for conversation and vision, the Web Speech API for the microphone, and a speech voice for Adoora's replies.

The Interface

The screen is deliberately bare: a circular camera orb showing the visitor, a four-dash code display, a subtitle line for what Adoora is saying, and a Talk button. A numeric keypad is visible the whole time โ€” but it does nothing until you've earned the digits through conversation.

The live Adoora interface โ€” a face in the camera orb, the keypad ring, and a subtitle commenting on the visitor's shirt

The interface, live โ€” the keypad orbits the camera orb, and the subtitle is the vision working in real time: "love the striped shirt, very sharp and a little retro."

Interaction is voice-first: you press Talk, the Web Speech API transcribes you, and after a short silence the turn is sent off. Adoora replies in text on the subtitle line and out loud. The keypad is the only way out โ€” but it stays inert until trust unlocks it.

The Application Logic โ€” Earning the Code

The core of the app isn't a passcode check; it's a trust score built across a real conversation. Each message passes through three interlocking systems before Adoora answers.

Phase detection

Every message is read as one of four emotional phases โ€” BEFORE (surface talk), DURING (something personal surfacing), MOMENT (genuine vulnerability), and AFTER (meta-reflection โ€” "weird that I just told a door") โ€” and Adoora's register shifts to match.

Intensity & momentum

Each message gets an intensity score (1โ€“5) from its emotional vocabulary, punctuation, and hedging; momentum tracks whether you're opening up or pulling back. A run of short, mechanical replies makes Adoora slow down and ask something more direct instead of playing along.

Trust scoring

Each GPT reply ends with a hidden [TRUST_SCORE: +N] tag โ€” a reciprocal moment earns a lot, a one-word reply almost nothing, rudeness goes negative. The running total governs the reveal: no digit surfaces until several real exchanges in, and then only as trust crosses thresholds.

Digits are never announced โ€” they're woven into gossip: "I've counted exactly three people who knocked twice today." If the model forgets to embed one, the fallback is a whispered "โ€ฆ3.", as if remembering something small.

The Door Can See You

In the early trust stages, each turn goes to GPT-4o as a multimodal request: a live frame from the webcam is attached with the text, so Adoora notices what you're wearing and speaks to you, not about you โ€” the opening line in testing was literally "Hello, nice sweater." During testing, several people straightened their posture the moment the camera came on, even knowing it was just their own face in a circle.

Interfacing the App to the Lock

This is where the application meets the device I made. When the four entered digits match the session's code, the app fires its unlock state โ€” the on-screen "welcome" โ€” and makes a request to the board to release the bolt. It's the same call the control page uses: a plain HTTP fetch to the board's /on route over its own access point. The board catches it, drives the pin high, and the MOSFET switches the solenoid (the access point, route, and driver circuit are documented in Week 11 โ†’).

// app side โ€” on a correct code, ask the board to open
await fetch("/on");   // board's WiFi AP route

// board side (adoora-control.ino)
void handleOn() {
  digitalWrite(CTRL, HIGH);          // MOSFET on โ†’ bolt retracts
  server.send(200, "text/plain", "open");
}

And here is that request landing โ€” the board moving the solenoid in response:

The unlock request reaching the board โ€” the solenoid retracts and returns. App on one side, bolt on the other, talking over /onยท/off.

One genuinely tricky part lives in the app: the code is invented fresh each session by GPT in the browser, so the board has to learn this session's code before it can validate an entry โ€” the secret is handed over once the story is generated, keeping the talking layer and the switching layer in sync.

What Actually Happened

Three things surprised me in testing. The passive-aggressive idle lines โ€” "It's okay. I'm used to silence. Mostly." โ€” landed hard enough that people apologised to the door. The love-confession branch: without saying what it does, people try it. And the code, because it's different every session and tied to memory fragments, doesn't get written down โ€” people remember it as a feeling, "the third one was about rain", which is strange and exactly right.

A real session โ€” talking to Adoora, the subtitle replies, and the keypad waiting on trust.

Adoora is about access as a social act. Every door, someone is quietly deciding whether to let you through. Adoora makes that evaluation conversational, emotional, and mutual โ€” the door wants to be known too.

Problems & How I Fixed Them

The trust tag leaked into the reply

Each GPT response ends with a hidden [TRUST_SCORE: +N], and early on it showed up on screen as part of Adoora's line. Fix: parse the tag out of the raw response, add the number to the running total, and render only the text that's left.

Digits sometimes never landed

The reveal depends on the model weaving a digit into the conversation, and sometimes it just wouldn't โ€” so the code stayed un-gettable. Fix: a fallback that, once trust is high enough, whispers the digit as a half-remembered "โ€ฆ3." instead of relying on the model to embed it.

Flat replies stalled the climb

A run of short, mechanical answers left trust stuck and the conversation going nowhere. Fix: a counter that, after three short turns, makes Adoora drop the act and ask something more direct rather than politely playing along.

Syncing the code to the board

The code is invented in the browser each session, but the board is what has to validate the entry and release the bolt โ€” so the two have to agree on the secret. The approach: hand the board the code once the story is generated, keeping the talking layer and the switching layer (Week 11 โ†’) in sync.

Design Files & Source

  • adoora.html โ€” the whole application (HTML / CSS / JS, no build step)

The board and firmware this app talks to live in Week 11 โ†’.