Skip to content

sidhantbas/proxiphone

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

ProxiPhone

A silent messaging system where the physical environment — not the sender — determines whether a message is delivered.

Most messaging systems treat the network as a passive carrier: you send, it delivers, the recipient receives regardless of context. ProxiPhone inverts this. The room itself has a voice. A message sent from one phone to another is mediated by ambient WiFi sensing: if the receiving phone's owner is present and active in the space, delivery confidence is high. If the space is empty or the person has left, the message is held or degraded accordingly.

The result is a communication channel where physical co-presence modulates information flow — closer in spirit to a tap on the shoulder than to a text message.


Finding

The core finding is that a Kalman-filtered confidence score derived from WiFi Channel State Information (CSI) packet counts provides a surprisingly clean signal for presence-mediated message delivery. The filter:

  1. Absorbs the natural variance of WiFi packet arrival rates (bursts, retransmissions, quiet periods)
  2. Produces a smooth 0–1 confidence estimate that rises when the ESP32 node detects human presence and falls when the room empties
  3. Drives a streak counter that requires N consecutive above-threshold readings before triggering delivery — preventing spurious messages from radio noise

The secondary finding is about ephemeral room codes: by routing messages through in-memory room state (no database, no persistent storage) keyed on a short code, two phones can share a private channel that vanishes the moment both disconnect. There is nothing to log, nothing to subpoena, nothing to breach.


How It Works

Phone A                    Server                    Phone B
   │                          │                          │
   │  POST /send  ──────────► │                          │
   │  { room, from, text }    │                          │
   │                          │                          │
   │                    ┌─────┴──────┐                   │
   │                    │ Ambient    │                    │
   │                    │ sensing    │  (ESP32 CSI)       │
   │                    │           │                    │
   │                    │ Kalman     │                    │
   │                    │ filter     │                    │
   │                    │           │                    │
   │                    │ confidence │                    │
   │                    │ ≥ 0.75?    │                    │
   │                    └─────┬──────┘                   │
   │                          │ yes                       │
   │                          │ streak ≥ 3?              │
   │                          │ yes → deliver            │
   │                          │ ──────────────────────► │
   │                          │  vibrate                 │

Room states (driven by ambient sensing):

State CSI reading Effect on delivery
EMPTY No packets detected Messages queued, not delivered
SLEEPING Low packet rate, low motion Delivery suppressed
PRESENT Normal packet rate Delivery enabled above threshold
ACTIVE High motion detected High-confidence delivery
CROWDED Multiple device signatures Delivery with attribution

Quick Start

# No dependencies beyond Python stdlib
python3 proxiphone.py
# Opens http://localhost:8767

Open on two phones on the same network. Enter the same room code on both. The interface is a single text field — type a message and send. The recipient's phone vibrates silently. No accounts, no sign-up, no data stored after the session ends.


Ambient Integration

ProxiPhone polls a local ESP32 ambient server (default http://localhost:8770/data) every 2 seconds for CSI-derived presence data. If no ESP32 is connected, the system falls back gracefully to delivery-always mode — the ambient layer is an enhancement, not a requirement.

The Kalman filter state:

# Process noise Q = 0.01 (confidence changes slowly)
# Measurement noise R = 1.0 (individual CSI readings are noisy)
P += Q
K = P / (P + R)       # Kalman gain
x = x + K * (z - x)  # update estimate
P = (1 - K) * P       # update uncertainty

x is the smoothed confidence estimate. z is the raw measurement (0 or 1 based on packet count above threshold). The filter prevents a single dropped packet from suppressing delivery and prevents a single burst from triggering it.


Architecture

proxiphone.py
├── HTTP server  (port 8767, stdlib only)
│   ├── POST /register   — phone announces itself to a room
│   ├── POST /ping       — keepalive, updates last-seen timestamp
│   ├── POST /send       — deliver a message to room peers
│   └── GET  /poll       — long-poll for incoming messages
│
├── Room state machine
│   └── rooms[code] = { phones, pairs, messages, log }
│
├── Kalman filter  (per phone-pair)
│   └── smoothed confidence score → delivery decision
│
└── Ambient poller  (background thread, 2 s interval)
    └── reads ESP32 presence data → updates room_state

Design Decisions

No server-side storage. All room state lives in a Python dict in memory. When the process restarts, everything is gone. This is a feature.

No user accounts. Phones are identified by a random ID generated at first load, stored in localStorage. The server never sees a name, email, or persistent identifier.

Streak confirmation. Delivery requires 3 consecutive confident readings. This adds ~6 seconds of latency but eliminates false triggers from RF noise.

Vibration as the only output. The Web Vibration API (navigator.vibrate()) is the sole notification mechanism. No sound, no notification badge, no lock-screen preview. The message is felt, not seen.


Requirements

  • Python 3.9+ (standard library only)
  • Two devices on the same local network
  • Optional: ESP32-S3 running RuView CSI firmware for ambient-mediated delivery

Stack

  • Python 3 — HTTP server, threading, Kalman filter (pure Python, no numpy)
  • Web Vibration API — haptic delivery on mobile browsers
  • Vanilla JS — no framework, no build step
  • ESP32 / RuView (optional) — CSI-based ambient sensing

About

Haptic messaging system where ambient WiFi sensing determines if a message gets delivered — the room decides

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages