# Project export: Sentinel

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 12.0
- Tagline: End to End Embedded Sensors network for Poaching-Detection. Featuring: Gunshot alerting and triangulation, Bluetooth poacher tracking, satellite imagery, AI voice deterrence, and sensor health data.
- Devpost: https://devpost.com/software/poachprotect
- GitHub: https://github.com/aneeshratnala/calhacks12.0
- Video: https://www.youtube.com/embed/jHiMyZex9JQ?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 3 GitHub contributor(s) — Aneesh Ratnala (31 commits), Vishal Dandamudi (20 commits), sanjaydbom (18 commits)

## Devpost submission (written by the team)

### Inspiration

Inspired by the accelerating loss of species and the rise in poaching, we wanted to show how small, inexpensive devices like Arduinos can have outsized conservation impact when combined with creative engineering and AI. What We Built An embedded-sensor AI poaching-detection network that combines edge audio classification, Bluetooth sensing, satellite imagery, and a central dashboard: Gunshot detection: Custom AI model (based on feature extraction from YAMNet) running on edge nodes to detect gunshots and trigger alerts. Bluetooth detection: Nodes scan for nearby Bluetooth devices to help identify human presence in restricted areas. Shot triangulation: Time-of-arrival inputs from multiple nodes are used to triangulate the gunshot location. Satellite imagery: Supplementary area data obtained via the BrightData API to help prioritize monitoring and validate detections. Alerting & dashboard: Nodes send messages wirelessly to a central computer that displays node status and locations on a Leaflet map GUI. How We Built It Custom Classification model: Performed feature extraction using a YAMNet-derived pipeline, then trained a compact classifier on labeled gunshot and ambient audio samples. Embedded deployment: Ported the model to run on the Arduino-compatible edge hardware (audio capture, preprocessing, inference). Networking: Implemented Wi‑Fi communication from nodes to the central server (MQTT/HTTP-based messages). Central system: Built a GUI with Leaflet to show nodes and detections; implemented backend services to receive alerts, store events, and run triangulation. Satellite integration: Used the BrightData API to fetch satellite tiles/imagery for regions of interest and display them in the dashboard. What We Learned Practical experience deploying ML on constrained edge hardware: trade-offs between model size, latency, and accuracy. Real-world networking is messy: pairing many low-power nodes, reliability over Wi‑Fi, and message ordering all matter. Data engineering challenges: labeling audio, handling noisy real-world recordings, and integrating external APIs like BrightData. Rapid prototyping workflow improvements: modular code, smaller repos, and CI helped reduce friction as beginners. Challenges Faced Wi‑Fi communication from nodes to the central dashboard was harder than expected due to initial database and messaging design choices. Managing a large repository and unfamiliar toolchains slowed development. Collecting and labeling diverse gunshot audio samples for robust detection. Synchronizing timestamps for accurate triangulation across nodes with variable network delays. Next Steps and Future Ideas! Improve time synchronization (e.g., GPS or precision time protocol) to tighten triangulation accuracy. Optimize the edge model further for lower power and better false-positive control. Add secure, resilient mesh networking and encrypted messaging. Expand satellite analytics for automated hotspot detection.

## README (from the GitHub repository)

No README available.

## Detected evidence (automated analysis)

Indexed codebase: 109 recognized source files, 417 KB.
- CSS (language) — detected in the code
- Next.js (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Solidity (language) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- C++ (language) — claimed on Devpost, not found in the code
- Hugging Face (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (120 of 140)

```
.DS_Store
.gitignore
.vscode/settings.json
ArduinoWifi/.DS_Store
ArduinoWifi/arduino_reciever/arduino_reciever.ino
ArduinoWifi/ESP32/Bluetooth_Scanner.ino/Bluetooth_Scanner.ino.ino
ArduinoWifi/ESP32/CompToTransmitter.py
ArduinoWifi/ESP32/find_arduino_port.py
ArduinoWifi/ESP32/gunshot_detector_classifier2.h5
ArduinoWifi/ESP32/IntegratedCompDetectionModel
ArduinoWifi/ESP32/IntegratedCompDetectionModel.py
ArduinoWifi/ESP32/IntegratedTransmitter.ino/IntegratedTransmitter.ino.ino
ArduinoWifi/ESP32/README.md
ArduinoWifi/ESP32/Reciever.ino
ArduinoWifi/ESP32/RecieverToComp.py
ArduinoWifi/ESP32/requirements.txt
ArduinoWifi/ESP32/SETUP_COMPLETE.md
ArduinoWifi/ESP32/start_system.py
ArduinoWifi/ESP32/test_database_connection.py
ArduinoWifi/ESP32/Transmitter/Transmitter.ino
GunshotDetectionModel/ambient_gunshot_noise.py
GunshotDetectionModel/ambient_noise_data.py
GunshotDetectionModel/audio_classifier.py
GunshotDetectionModel/data_scrapper.py
GunshotDetectionModel/FishIntegrated.py
GunshotDetectionModel/gunshot_detector_classifier.h5
GunshotDetectionModel/gunshot_detector_classifier2.h5
GunshotDetectionModel/IntegratedScript.py
GunshotDetectionModel/req.txt
GunshotDetectionModel/test_gunshot_detection_audiofile.py
GunshotDetectionModel/test_gunshot_detection_live.py
GunshotDetectionModel/testImports.py
GunshotDetectionModel/train_gunshot_detection.py
GunshotDetectionModel/yamnet_class_map.csv
LICENSE
package.json
poacher-proof-contract/.gitignore
poacher-proof-contract/contracts/Counter.sol
poacher-proof-contract/contracts/Counter.t.sol
poacher-proof-contract/get_wallet_keys.py
poacher-proof-contract/hardhat.config.ts
poacher-proof-contract/ignition/modules/Counter.ts
poacher-proof-contract/package.json
poacher-proof-contract/README.md
poacher-proof-contract/scripts/send-op-tx.ts
poacher-proof-contract/test/Counter.ts
poacher-proof-contract/tsconfig.json
poaching-detection/app/api/add-simulated-detections/route.ts
poaching-detection/app/api/arduino/route.ts
poaching-detection/app/api/arduino/sensors/route.ts
poaching-detection/app/api/arduino/stats/route.ts
poaching-detection/app/api/fish-audio/route.ts
poaching-detection/app/api/gunshot-detections/route.ts
poaching-detection/app/api/random-gunshot/route.ts
poaching-detection/app/api/voice-warning/route.ts
poaching-detection/app/globals.css
poaching-detection/app/layout.tsx
poaching-detection/app/page.tsx
poaching-detection/components.json
poaching-detection/components/detection-map.tsx
poaching-detection/components/sidebar.tsx
poaching-detection/components/theme-provider.tsx
poaching-detection/components/ui/accordion.tsx
poaching-detection/components/ui/alert-dialog.tsx
poaching-detection/components/ui/alert.tsx
poaching-detection/components/ui/aspect-ratio.tsx
poaching-detection/components/ui/avatar.tsx
poaching-detection/components/ui/badge.tsx
poaching-detection/components/ui/breadcrumb.tsx
poaching-detection/components/ui/button-group.tsx
poaching-detection/components/ui/button.tsx
poaching-detection/components/ui/calendar.tsx
poaching-detection/components/ui/card.tsx
poaching-detection/components/ui/carousel.tsx
poaching-detection/components/ui/chart.tsx
poaching-detection/components/ui/checkbox.tsx
poaching-detection/components/ui/collapsible.tsx
poaching-detection/components/ui/command.tsx
poaching-detection/components/ui/context-menu.tsx
poaching-detection/components/ui/dialog.tsx
poaching-detection/components/ui/drawer.tsx
poaching-detection/components/ui/dropdown-menu.tsx
poaching-detection/components/ui/empty.tsx
poaching-detection/components/ui/field.tsx
poaching-detection/components/ui/form.tsx
poaching-detection/components/ui/hover-card.tsx
poaching-detection/components/ui/input-group.tsx
poaching-detection/components/ui/input-otp.tsx
poaching-detection/components/ui/input.tsx
poaching-detection/components/ui/item.tsx
poaching-detection/components/ui/kbd.tsx
poaching-detection/components/ui/label.tsx
poaching-detection/components/ui/menubar.tsx
poaching-detection/components/ui/navigation-menu.tsx
poaching-detection/components/ui/pagination.tsx
poaching-detection/components/ui/popover.tsx
poaching-detection/components/ui/progress.tsx
poaching-detection/components/ui/radio-group.tsx
poaching-detection/components/ui/resizable.tsx
poaching-detection/components/ui/scroll-area.tsx
poaching-detection/components/ui/select.tsx
poaching-detection/components/ui/separator.tsx
poaching-detection/components/ui/sheet.tsx
poaching-detection/components/ui/sidebar.tsx
poaching-detection/components/ui/skeleton.tsx
poaching-detection/components/ui/slider.tsx
poaching-detection/components/ui/sonner.tsx
poaching-detection/components/ui/spinner.tsx
poaching-detection/components/ui/switch.tsx
poaching-detection/components/ui/table.tsx
poaching-detection/components/ui/tabs.tsx
poaching-detection/components/ui/textarea.tsx
poaching-detection/components/ui/toast.tsx
poaching-detection/components/ui/toaster.tsx
poaching-detection/components/ui/toggle-group.tsx
poaching-detection/components/ui/toggle.tsx
poaching-detection/components/ui/tooltip.tsx
poaching-detection/components/ui/use-mobile.tsx
poaching-detection/components/ui/use-toast.ts
poaching-detection/data/gunshot_detections.json
[20 more files omitted for size]
```

### Dependencies

- ArduinoWifi/ESP32/requirements.txt: pyserial@==3.5, requests@==2.32.5
- package.json: @types/dotenv@^6.1.1, dotenv@^17.2.3
- poacher-proof-contract/package.json: @nomicfoundation/hardhat-ignition@^3.0.3, @nomicfoundation/hardhat-toolbox-mocha-ethers@^3.0.0, @types/chai@^4.3.20, @types/chai-as-promised@^8.0.2, @types/mocha@^10.0.10, @types/node@^22.18.12, chai@^5.3.3, ethers@^6.15.0, forge-std@github:foundry-rs/forge-std#v1.9.4, hardhat@^3.0.9, mocha@^11.7.4, typescript@~5.8.0
- poaching-detection/package.json: @hookform/resolvers@^3.10.0, @radix-ui/react-accordion@1.2.2, @radix-ui/react-alert-dialog@1.1.4, @radix-ui/react-aspect-ratio@1.1.1, @radix-ui/react-avatar@1.1.2, @radix-ui/react-checkbox@1.1.3, @radix-ui/react-collapsible@1.1.2, @radix-ui/react-context-menu@2.2.4, @radix-ui/react-dialog@1.1.4, @radix-ui/react-dropdown-menu@2.1.4, @radix-ui/react-hover-card@1.1.4, @radix-ui/react-label@2.1.1, @radix-ui/react-menubar@1.1.4, @radix-ui/react-navigation-menu@1.2.3, @radix-ui/react-popover@1.1.4, @radix-ui/react-progress@1.1.1, @radix-ui/react-radio-group@1.2.2, @radix-ui/react-scroll-area@1.2.2, @radix-ui/react-select@2.1.4, @radix-ui/react-separator@1.1.1, @radix-ui/react-slider@1.2.2, @radix-ui/react-slot@1.1.1, @radix-ui/react-switch@1.1.2, @radix-ui/react-tabs@1.1.2, @radix-ui/react-toast@1.2.4, @radix-ui/react-toggle@1.1.1, @radix-ui/react-toggle-group@1.1.1, @radix-ui/react-tooltip@1.1.6, @tailwindcss/postcss@^4.1.9, @types/leaflet@^1.9.21, @types/node@^22, @types/react@^18, @types/react-dom@^18, @vercel/analytics@1.3.1, autoprefixer@^10.4.20, axios@^1.12.2, better-sqlite3@^12.4.1, class-variance-authority@^0.7.1, clsx@^2.1.1, cmdk@1.0.4, date-fns@4.1.0, embla-carousel-react@8.5.1, input-otp@1.4.1, leaflet@^1.9.4, lucide-react@^0.454.0, next@16.0.0, next-themes@^0.4.6, postcss@^8.5, react@^18.2.0, react-day-picker@9.8.0, react-dom@^18.2.0, react-hook-form@^7.60.0, react-leaflet@^4.2.1, react-resizable-panels@^2.1.7, recharts@2.15.4, sonner@^1.7.4, tailwind-merge@^2.5.5, tailwindcss@^4.1.9, tailwindcss-animate@^1.0.7, tw-animate-css@1.3.3, typescript@^5, vaul@^0.9.9, zod@3.25.76

### Recent commits (newest first)

- pgTitle change
- branding and satellite imagery
- Merge triangulation with main
- shootSim push
- integrated fish audio
- address fix
- Made
- Simulation + Triangulation
- sidebar
- merge
- comment
- adding more nodes
- Fix transmition data from node to other node
- Revert "multiple nodes"
- Add some blockchain stuff
- multiple nodes
- feat: Update poaching detection app and fix .gitignore
- Merge branch 'main' of https://github.com/aneeshratnala/calhacks12.0
- Merge branch 'main' of https://github.com/aneeshratnala/calhacks12.0
- ignore

## Key source files (fetched from GitHub, selected and truncated for size)

### ArduinoWifi/ESP32/SETUP_COMPLETE.md

```markdown
# Arduino Database Integration - Setup Complete ✅

## What's Been Set Up

### 1. Updated `RecieverToComp.py`
- ✅ Removed the `bleStatus` conversion logic as requested
- ✅ Clean, simple data forwarding to database API
- ✅ Proper error handling and logging
- ✅ Auto-port detection functionality

### 2. Database API Integration
- ✅ Tested and confirmed working with Next.js API
- ✅ Handles both sensor data and gunshot detection data
- ✅ Proper JSON parsing and validation
- ✅ Error handling for network issues

### 3. Supporting Files Created

#### `requirements.txt`
- Contains `pyserial` and `requests` dependencies
- Ready for `pip install -r requirements.txt`

#### `test_database_connection.py`
- ✅ **TESTED AND WORKING** - All tests pass
- Tests sensor data transmission
- Tests gunshot detection data transmission  
- Tests data retrieval from database
- Provides detailed success/error reporting

#### `find_arduino_port.py`
- Auto-detects Arduino/ESP32 ports
- Provides helpful troubleshooting tips
- Shows port recommendations

#### `start_system.py`
- Complete system startup helper
- Checks dependencies
- Starts Next.js server if needed
- Finds Arduino ports
- Provides next steps

#### `README.md`
- Complete setup and usage instructions
- Troubleshooting guide
- Data format specifications

## Current Status

### ✅ Database API
- **Status**: WORKING
- **Test Results**: All tests pass
- **Endpoint**: `http://localhost:3000/api/arduino`
- **Data Storage**: JSON files in `poaching-detection/data/`

### ✅ Python Scripts
- **Status**: READY
- **Dependencies**: Listed in `requirements.txt`
- **Port Detection**: Automatic with fallback
- **Error Handling**: Comprehensive

### ✅ Next.js Server
- **Status**: RUNNING
- **Port**: 3000
- **API**: Fully functional
- **Database**: File-based JSON storage

## Quick Start

### 1. Install Dependencies
```bash
cd ArduinoWifi/ESP32
pip install -r requirements.txt
```

### 2. Test Database Connection
```bash
python3 test_database_connection.py
```

### 3. Find Arduino Port
```bash
python3 find_arduino_port.py
```

### 4. Run Arduino Receiver
```bash
python3 RecieverToComp.py
```

### 5. Or Use the Startup Helper
```bash
python3 start_system.py
```

## Data Flow

```
Arduino/ESP32 → Serial Port → RecieverToComp.py → Next.js API → Database
```

## Expected Arduino Data Format

### Sensor Data
```
Data received: {"id": 1, "Temp": 25.5, "bleStatus": "Device_Found"}
```

### Gunshot Detection
```
Data received: {"id": 1, "gunshot": true, "time": "2024-01-15T10:30:00Z", "confidence": 0.85}
```

## Troubleshooting

- **Port Issues**: Run `python3 find_arduino_port.py`
- **Database Issues**: Run `python3 test_database_connection.py`
- **Server Issues**: Check if Next.js is running on port 3000
- **Dependencies**: Run `pip install -r requirements.txt`

## Files Modified/Created

### Modified
- `RecieverToComp.py` - Updated to match your specifications

### Created
- `requirements.txt` - Python dependencies
- `test_database_connecti
[truncated — 496 more characters]
```

### package.json

```
{
  "devDependencies": {
    "@types/dotenv": "^6.1.1",
    "dotenv": "^17.2.3"
  }
}

```

### poacher-proof-contract/package.json

```
{
  "name": "poacher-proof-contract",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "module",
  "devDependencies": {
    "@nomicfoundation/hardhat-ignition": "^3.0.3",
    "@nomicfoundation/hardhat-toolbox-mocha-ethers": "^3.0.0",
    "@types/chai": "^4.3.20",
    "@types/chai-as-promised": "^8.0.2",
    "@types/mocha": "^10.0.10",
    "@types/node": "^22.18.12",
    "chai": "^5.3.3",
    "ethers": "^6.15.0",
    "forge-std": "github:foundry-rs/forge-std#v1.9.4",
    "hardhat": "^3.0.9",
    "mocha": "^11.7.4",
    "typescript": "~5.8.0"
  }
}

```

### poaching-detection/package.json

```
{
  "name": "my-v0-project",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "build": "next build",
    "dev": "next dev",
    "lint": "eslint .",
    "start": "next start"
  },
  "dependencies": {
    "@hookform/resolvers": "^3.10.0",
    "@radix-ui/react-accordion": "1.2.2",
    "@radix-ui/react-alert-dialog": "1.1.4",
    "@radix-ui/react-aspect-ratio": "1.1.1",
    "@radix-ui/react-avatar": "1.1.2",
    "@radix-ui/react-checkbox": "1.1.3",
    "@radix-ui/react-collapsible": "1.1.2",
    "@radix-ui/react-context-menu": "2.2.4",
    "@radix-ui/react-dialog": "1.1.4",
    "@radix-ui/react-dropdown-menu": "2.1.4",
    "@radix-ui/react-hover-card": "1.1.4",
    "@radix-ui/react-label": "2.1.1",
    "@radix-ui/react-menubar": "1.1.4",
    "@radix-ui/react-navigation-menu": "1.2.3",
    "@radix-ui/react-popover": "1.1.4",
    "@radix-ui/react-progress": "1.1.1",
    "@radix-ui/react-radio-group": "1.2.2",
    "@radix-ui/react-scroll-area": "1.2.2",
    "@radix-ui/react-select": "2.1.4",
    "@radix-ui/react-separator": "1.1.1",
    "@radix-ui/react-slider": "1.2.2",
    "@radix-ui/react-slot": "1.1.1",
    "@radix-ui/react-switch": "1.1.2",
    "@radix-ui/react-tabs": "1.1.2",
    "@radix-ui/react-toast": "1.2.4",
    "@radix-ui/react-toggle": "1.1.1",
    "@radix-ui/react-toggle-group": "1.1.1",
    "@radix-ui/react-tooltip": "1.1.6",
    "@types/leaflet": "^1.9.21",
    "@vercel/analytics": "1.3.1",
    "autoprefixer": "^10.4.20",
    "axios": "^1.12.2",
    "better-sqlite3": "^12.4.1",
    "class-variance-authority": "^0.7.1",
    "clsx": "^2.1.1",
    "cmdk": "1.0.4",
    "date-fns": "4.1.0",
    "embla-carousel-react": "8.5.1",
    "input-otp": "1.4.1",
    "leaflet": "^1.9.4",
    "lucide-react": "^0.454.0",
    "next": "16.0.0",
    "next-themes": "^0.4.6",
    "react": "^18.2.0",
    "react-day-picker": "9.8.0",
    "react-dom": "^18.2.0",
    "react-hook-form": "^7.60.0",
    "react-leaflet": "^4.2.1",
    "react-resizable-panels": "^2.1.7",
    "recharts": "2.15.4",
    "sonner": "^1.7.4",
    "tailwind-merge": "^2.5.5",
    "tailwindcss-animate": "^1.0.7",
    "vaul": "^0.9.9",
    "zod": "3.25.76"
  },
  "devDependencies": {
    "@tailwindcss/postcss": "^4.1.9",
    "@types/node": "^22",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "postcss": "^8.5",
    "tailwindcss": "^4.1.9",
    "tw-animate-css": "1.3.3",
    "typescript": "^5"
  }
}

```

### ArduinoWifi/ESP32/requirements.txt

```
pyserial==3.5
requests==2.32.5

```

### poaching-detection/app/page.tsx

```typescript
"use client"

// app/page.tsx
import { Sidebar } from "@/components/sidebar"
import { DetectionMap } from "@/components/detection-map"
import { useState } from "react"

export default function HomePage() {
  const [activePanel, setActivePanel] = useState<string | null>(null)

  return (
    <div className="flex h-screen w-full overflow-hidden bg-background">
      <Sidebar activePanel={activePanel} onPanelChange={setActivePanel} />
      <main className="flex-1 relative">
        <DetectionMap activePanel={activePanel} onPanelClose={() => setActivePanel(null)} />
      </main>
    </div>
  )
}
```

### poaching-detection/app/layout.tsx

```typescript
import type { Metadata } from 'next'
import { Geist, Geist_Mono } from 'next/font/google'
import { Analytics } from '@vercel/analytics/next'
import './globals.css'

const _geist = Geist({ subsets: ["latin"] });
const _geistMono = Geist_Mono({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: 'Sentinel',
  description: 'A system of low-power, interconnected devices that can detect, respond to, and mitigate illegal poaching in low-surveilled areas.',
  generator: 'Sentinel',
}

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode
}>) {
  return (
    <html lang="en">
      <body className={`font-sans antialiased`}>
        {children}
        <Analytics />
      </body>
    </html>
  )
}

```

### poaching-detection/app/api/gunshot-detections/route.ts

```typescript
import { NextResponse } from 'next/server'
import fs from 'fs'
import path from 'path'

// GET /api/gunshot-detections - Get gunshot detections data
export async function GET() {
  try {
    const filePath = path.join(process.cwd(), 'data', 'gunshot_detections.json')
    
    // Read the file dynamically
    const fileContent = fs.readFileSync(filePath, 'utf-8')
    const data = JSON.parse(fileContent)
    
    return NextResponse.json(data, {
      headers: {
        'Cache-Control': 'no-store, no-cache, must-revalidate, proxy-revalidate',
        'Pragma': 'no-cache',
        'Expires': '0'
      }
    })
  } catch (error) {
    console.error('Error reading gunshot_detections.json:', error)
    return NextResponse.json(
      { error: 'Failed to read detections data' },
      { status: 500 }
    )
  }
}


```

### poaching-detection/app/api/add-simulated-detections/route.ts

```typescript
import { NextRequest, NextResponse } from 'next/server'
import fs from 'fs'
import path from 'path'

// POST /api/add-simulated-detections - Add simulated gunshot detections to JSON file
export async function POST(request: NextRequest) {
  try {
    const { detections } = await request.json()
    
    if (!detections || !Array.isArray(detections) || detections.length === 0) {
      return NextResponse.json(
        { error: 'Missing or invalid detections array' },
        { status: 400 }
      )
    }

    const filePath = path.join(process.cwd(), 'data', 'gunshot_detections.json')
    
    // Read existing data
    let existingData = []
    if (fs.existsSync(filePath)) {
      const fileContent = fs.readFileSync(filePath, 'utf-8')
      existingData = JSON.parse(fileContent)
    }

    // Add new detections
    existingData.push(...detections)

    // Write back to file
    fs.writeFileSync(filePath, JSON.stringify(existingData, null, 2))

    console.log(`✅ Added ${detections.length} simulated gunshot detections to gunshot_detections.json`)

    return NextResponse.json({
      success: true,
      message: `Added ${detections.length} simulated detections`,
      detections
    })

  } catch (error) {
    console.error('Error adding simulated detections:', error)
    return NextResponse.json(
      { error: 'Failed to add simulated detections' },
      { status: 500 }
    )
  }
}


```

### poaching-detection/app/api/voice-warning/route.ts

```typescript
import { NextRequest, NextResponse } from 'next/server'
import { ttsService } from '@/lib/tts-service'

// POST /api/voice-warning - Generate voice warning data (client-side TTS)
export async function POST(request: NextRequest) {
  try {
    const { detectionId, coordinates } = await request.json()
    
    if (!detectionId || !coordinates) {
      return NextResponse.json(
        { error: 'Missing required fields: detectionId, coordinates' },
        { status: 400 }
      )
    }

    console.log(`🔊 Generating voice warning data for detection ${detectionId} at coordinates ${coordinates.lat}, ${coordinates.lng}`)

    // Generate voice warning data (client will handle actual TTS)
    const warnings = await ttsService.generateVoiceWarning(detectionId, coordinates)

    return NextResponse.json({
      success: true,
      warnings,
      message: 'Voice warning data generated successfully'
    })

  } catch (error) {
    console.error('Error generating voice warning:', error)
    return NextResponse.json(
      { error: 'Failed to generate voice warning' },
      { status: 500 }
    )
  }
}

// GET /api/voice-warning - Get available voice warning info
export async function GET() {
  try {
    return NextResponse.json({
      success: true,
      message: 'Voice warning service is available',
      supportedLanguages: ['en', 'sw'],
      ttsType: 'Web Speech API (Browser-based)',
      features: [
        'No server-side dependencies',
        'Works across all platforms',
        'Supports multiple languages',
        'Real-time voice synthesis'
      ]
    })
  } catch (error) {
    console.error('Error getting voice warning info:', error)
    return NextResponse.json(
      { error: 'Failed to get voice warning info' },
      { status: 500 }
    )
  }
}

```

[100 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]