Skip to content

owenstuckman/SipSafe

Repository files navigation

SipSafe

Drink Safety System - HackViolet 2026

A cross-platform IoT solution to protect drinks from tampering. When the system detects unauthorized access to a protected drink, it immediately alerts the user and their emergency contacts via push notifications and SMS.

Overview

SipSafe consists of three components that work together:

  1. ESP32 Device - Hardware that detects when a drink container lid is removed
  2. Mobile Apps - iOS and Android apps for device control and alerts
  3. Supabase Backend - Database, authentication, and notification delivery

Alternatives/Thought Process

See Alternatives to see the thought process/design choices/things we tried.

Architecture

┌─────────────────┐     BLE      ┌─────────────────┐
│   ESP32 Device  │◄────────────►│   Mobile App    │
│  (Capacitive    │              │  (iOS/Android)  │
│   Touch + BLE)  │              └────────┬────────┘
└─────────────────┘                       │
                                          │ HTTPS
                                          ▼
                              ┌───────────────────────┐
                              │    Supabase Backend   │
                              ├───────────────────────┤
                              │ • PostgreSQL Database │
                              │ • Auth (Email/Apple)  │
                              │ • Edge Functions      │
                              │   - Push Notifications│
                              │   - SMS via Vonage    │
                              └───────────────────────┘

How It Works

  1. Setup: User pairs ESP32 device with mobile app via Bluetooth
  2. Protection: User places drink under device and taps "Arm" in app
  3. Detection: ESP32 monitors capacitive touch sensor for lid removal
  4. Alert: If lid removed while armed:
    • ESP32 sounds buzzer alarm
    • BLE notification sent to app
    • App logs incident to Supabase
    • Edge function sends iOS push notification
    • Edge function sends SMS to emergency contacts
  5. Review: User can view alert history and drink tracking in app

Project Structure

SipSafe/
├── SipSafe/                    # iOS App (SwiftUI)
│   ├── SipSafeApp.swift        # App entry point
│   ├── MainTabView.swift       # Tab navigation
│   ├── SupabaseClient.swift    # Supabase singleton
│   ├── Env.swift               # Environment config
│   ├── AppDelegate.swift       # Push notification handling
│   ├── auth/                   # Authentication views
│   ├── bluetooth/              # BLE manager
│   ├── device/                 # Device pairing UI
│   ├── home/                   # Emergency contacts
│   ├── friends/                # Friend management
│   ├── drinks/                 # Drink tracking
│   ├── notifications/          # Alert history
│   ├── account/                # User settings
│   └── location/               # GPS for alerts
│
├── app/                        # Android App (Kotlin/Compose)
│   └── src/main/java/com/sipsafe/app/
│       ├── MainActivity.kt     # App entry point
│       ├── MainTabView.kt      # Tab navigation
│       ├── SipSafeApp.kt       # Application class
│       ├── SupabaseClient.kt   # Supabase singleton
│       ├── auth/               # Authentication
│       ├── bluetooth/          # BLE manager
│       ├── device/             # Device pairing UI
│       ├── home/               # Home screen
│       └── account/            # User settings
│
└── Esp32Files/                 # ESP32 Firmware
    └── drinkguard/
        └── drinkguard.ino      # Main firmware

Setup Instructions

Prerequisites

  • Xcode 15+ (iOS)
  • Android Studio Hedgehog+ (Android)
  • Arduino IDE with ESP32 board support
  • Supabase project with Edge Functions enabled

iOS App Setup

  1. Open SipSafe/SipSafe.xcodeproj in Xcode

  2. Configure Supabase credentials in scheme environment variables:

    • Product > Scheme > Edit Scheme > Run > Arguments > Environment Variables
    • Add SUPABASE_URL = your Supabase project URL
    • Add SUPABASE_KEY = your Supabase anon key
  3. Configure push notifications:

    • Enable Push Notifications capability
    • Create APNs key in Apple Developer portal
    • Upload key to Supabase project settings
  4. Build and run on device (BLE requires physical device)

Android App Setup

  1. Copy local.properties.example to local.properties

  2. Add Supabase credentials:

    SUPABASE_URL=https://your-project.supabase.co
    SUPABASE_KEY=your-anon-key
  3. Open project in Android Studio

  4. Build and run:

    ./gradlew installDebug

ESP32 Setup

  1. Install Arduino IDE with ESP32 board support

  2. Open Esp32Files/drinkguard/drinkguard.ino

  3. Wire hardware:

    • GPIO 4: Capacitive touch sensor (aluminum foil)
    • GPIO 5: Buzzer
    • GPIO 15: Physical button (INPUT_PULLUP)
  4. Upload to ESP32 DevKit board

  5. Device will advertise as "SipSafe" via BLE

Detailed Documentation:

BLE Protocol

The ESP32 exposes a BLE GATT service with three characteristics:

Characteristic UUID Properties Description
Service 12345678-1234-5678-1234-56789abcdef0 - SipSafe service
Armed 12345678-1234-5678-1234-56789abcdef1 R/W/N Arm state (0x00/0x01)
Lid 12345678-1234-5678-1234-56789abcdef2 R/N Lid state (0x01=on, 0x00=off)
Status 12345678-1234-5678-1234-56789abcdef3 R/N Combined bitmask

Status byte format:

  • Bit 0: Armed (1=armed)
  • Bit 1: Lid on (1=lid present)

Alert condition: Armed=1 AND Lid=0 (lid removed while armed)

Database Schema

Tables

-- User profiles (linked to Supabase Auth)
users
├── userId (uuid, PK)     -- Same as auth.users.id
├── auth_userId (uuid)    -- Foreign key to auth.users
├── email (text)
├── first_name (text)
├── last_name (text)
├── device_token (text)   -- APNs/FCM token for push
└── platform (text)       -- 'ios' or 'android'

-- Emergency contacts for SMS alerts
emergency_contacts
├── id (serial, PK)
├── user (uuid, FK)       -- Owner's userId
└── contact_number (text) -- Phone number

-- Incident log (all state changes)
incident_table
├── incident_id (uuid, PK)
├── userId (uuid, FK)
├── armed (boolean)
├── covered (boolean)
├── battery (text)        -- Device battery level
├── latitude (text)       -- GPS if available
├── longitude (text)
└── created_at (timestamptz)

-- Friend relationships for alert sharing
friends_table
├── friend_id (uuid, PK)
├── friender_id (uuid, FK) -- User who added friend
├── friendee_id (uuid, FK) -- User being added
└── created_at (timestamptz)

-- Notification log
notification_table
├── notification_id (uuid, PK)
├── incident_id (uuid, FK)
├── victim_id (uuid, FK)
├── sent_id (uuid, FK)
└── created_at (timestamptz)

Edge Functions

ios-send-push-noti

Triggered by database webhook on incident_table INSERT when armed=true AND covered=false.

Actions:

  1. Fetches user details and device token
  2. Sends APNs push notification to user
  3. Invokes Twillio-Test for SMS to emergency contacts
  4. Logs notification to notification_table
  5. Notifies user's friends

Twillio-Test

Sends SMS alerts via Vonage API.

Request body:

{
  "number": "XXXXXXXXXXX",
  "userName": "John Doe"
}

auth-to-public-user-creation

Triggered on auth.users INSERT. Creates corresponding record in public users table.

Environment Variables

Edge Functions

SUPABASE_URL
SUPABASE_SERVICE_ROLE_KEY
APNS_KEY_B64          # Base64 .p8 key
APNS_KEY_ID           # Apple key ID
APNS_TEAM_ID          # Apple team ID
APNS_TOPIC            # Bundle ID
VONAGE_API_KEY
VONAGE_API_SECRET
VONAGE_FROM_NUMBER

Supabase

Inside of the repo you will need to update the corresponding keys to match your own supabase instance.

Features

Implemented

  • BLE device pairing and control (iOS/Android)
  • Email/password authentication
  • Apple Sign In (iOS)
  • Emergency contacts management (iOS)
  • Push notifications (iOS)
  • SMS alerts via Vonage
  • Friend alert sharing
  • Drink tracking
  • Alert history
  • Offline event queue (ESP32)
  • Auto-reconnection

Planned

  • Android push notifications
  • Location sharing in alerts
  • Multiple device support
  • Drink type categorization

Future Progression

  • ultrasonic addition to determne fluid level
  • BAC estimator with drink level/quantity of drinks
  • multiple levels of capacitive touch
  • can/drink guesser based off diameter (can/glass/etc.)

Development

Code Style

  • iOS: SwiftUI with MVVM pattern
  • Android: Jetpack Compose with MVI pattern
  • ESP32: Arduino with state machine

Key Design Decisions

  1. Singleton BLE managers - Ensures single connection across app
  2. StateFlow/Published - Reactive UI updates
  3. Offline queue - ESP32 stores alerts when disconnected
  4. Edge functions - Server-side notification logic

Devpost:

Go to: (Devpost)[https://devpost.com/software/sipsafe?ref_content=user-portfolio&ref_feature=in_progress]

Or see Devpost.md

License

GPL-2 License. See the License tab.

About

HackViolet 2026

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors