# ADS1115 REST API, CLI & Web Panel for Raspberry Pi

Complete solution for controlling the ADS1115 16-bit ADC on Raspberry Pi using `adafruit-circuitpython-ads1x15` library.

**Features:**
- 🌐 **Web Panel** - Modern web interface with live data, I2C scanner, and configuration
- 🔌 **REST API** - FastAPI-based HTTP API for programmatic access
- 💻 **CLI Shell** - Interactive command-line interface with logging
- 🔍 **I2C Detection** - Automatic I2C bus scanning and device detection
- 🐳 **Docker Support** - Run in containers with mock/real hardware modes
- ⚙️ **Configuration** - YAML, .env, and environment variable support

---

## 🚀 Quick Start

### Option 1: Raspberry Pi Native (Recommended for hardware)

```bash
# Copy files to RPi, then:
sudo ./install_rpi.sh

# Access web panel
http://raspberrypi.local:8080
```

### Option 2: Docker with Mock Data (Testing/Development)

```bash
# Start web panel
docker-compose up web

# Access at http://localhost:8080
```

### Option 3: Native Python

```bash
pip install -r requirements.txt
python web_panel.py  # Web panel with I2C scanner
python api.py        # REST API only
python cli.py --help # CLI commands
```

---

## 📁 File Structure

```
.
├── api.py              # FastAPI REST API
├── web_panel.py        # Web panel with I2C scanner
├── cli.py              # Click CLI application
├── ads1115_service.py  # Service layer
├── config.py           # Configuration management
├── run.py              # Launcher script
├── install_rpi.sh      # RPi auto-installer
├── RPI_INSTALL.md      # Detailed RPi installation guide
├── requirements.txt    # Python dependencies
├── Dockerfile          # Docker image
├── docker-compose.yml  # Docker Compose (uses .env)
├── .env                # Environment configuration
├── .env.example        # Environment template
├── config.yaml         # YAML configuration
└── README.md           # This file
```

---

## 🌐 Web Panel

### Features

- **I2C Scanner** - Detect all devices on I2C bus
- **ADC Readings** - Read all 4 channels with voltage
- **Live Mode** - Continuous streaming
- **Configuration** - Change I2C address, gain, data rate
- **Status Monitor** - Hardware connection status

### Web Panel Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/` | GET | Web panel interface |
| `/api/health` | GET | Service health |
| `/api/i2c/scan` | GET | Scan I2C bus |
| `/api/config` | GET/POST | Configuration |
| `/api/read/all` | GET | Read all 4 channels |
| `/api/read/{channel}` | GET | Read single channel |
| `/ws` | WebSocket | Live streaming |

Access at: `http://raspberrypi.local:8080`

---

## 🔌 REST API

### Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/health` | GET | Health status |
| `/config` | GET/POST | Configuration |
| `/read/{channel}` | GET | Read channel (0-3) |
| `/read/all` | GET | Read all channels |

### Example Requests

```bash
# Scan I2C bus
curl http://localhost:8080/api/i2c/scan

# Read all channels
curl http://localhost:8080/api/read/all

# Update configuration
curl -X POST -H "Content-Type: application/json" \
  -d '{"gain": 2, "data_rate": 250}' \
  http://localhost:8080/api/config
```

### API Documentation

Interactive docs available when running:
- Swagger UI: http://localhost:8080/docs
- ReDoc: http://localhost:8080/redoc

---

## 💻 CLI Usage

### Commands

```bash
# Device status
python cli.py status

# Read single channel
python cli.py read 0
python cli.py read 0 --continuous

# Read all channels
python cli.py readall
python cli.py readall --continuous --count 10

# Log to file
python cli.py log --output data.csv --interval 1

# Update config
python cli.py config --gain 2 --data-rate 250
```

---

## 🔧 Configuration

### .env File (Recommended)

```bash
# I2C Settings
ADS1115_I2C_ADDRESS=0x48
ADS1115_GAIN=1.0
ADS1115_DATA_RATE=128
ADS1115_MODE=single
ADS1115_MOCK=false      # 'true' for testing

# API Settings
API_HOST=0.0.0.0
API_PORT=8080

# RPi Network
RPI_IP=192.168.188.212
```

### Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `ADS1115_I2C_ADDRESS` | I2C address | 0x48 |
| `ADS1115_GAIN` | ADC gain | 1.0 |
| `ADS1115_DATA_RATE` | Samples per second | 128 |
| `ADS1115_MOCK` | Mock mode | false |
| `API_HOST` | Bind address | 0.0.0.0 |
| `API_PORT` | Port | 8080 |

---

## 🐳 Docker Usage

### Using docker-compose

```bash
# Start web panel
docker-compose up web

# Start API
docker-compose up api

# Run CLI command
docker-compose run cli python cli.py status
```

### Manual Docker

```bash
# Build image
docker build -t ads1115 .

# Run with mock data
docker run -p 8080:8080 -e ADS1115_MOCK=true ads1115 python web_panel.py

# Run on RPi with hardware
docker run -p 8080:8080 --device /dev/i2c-1 ads1115 python web_panel.py
```

---

## 🍓 Raspberry Pi Installation

### Automated Installation

```bash
# Copy to RPi
scp -r ./* pi@raspberrypi.local:~/ads1115/

# SSH to RPi and install
ssh pi@raspberrypi.local
cd ~/ads1115
sudo ./install_rpi.sh
```

### Hardware Wiring

```
ADS1115          Raspberry Pi
--------         ------------
VDD       ->     3.3V (Pin 1)
GND       ->     GND (Pin 6)
SCL       ->     SCL (Pin 5)
SDA       ->     SDA (Pin 3)
ADDR      ->     GND (address 0x48)
```

### Service Management

```bash
# Check status
sudo systemctl status ads1115-web

# Control service
sudo systemctl start ads1115-web
sudo systemctl stop ads1115-web
sudo systemctl restart ads1115-web

# View logs
sudo journalctl -u ads1115-web -f
```

---

## 📊 API Response Format

### I2C Scan Result

```json
{
  "bus": 1,
  "devices": [
    {"address": "0x48", "description": "ADS1115", "detected": true}
  ],
  "ads1115_detected": true,
  "ads1115_address": "0x48"
}
```

### Channel Readings

```json
{
  "channels": [
    {"channel": 0, "raw_value": 8452, "voltage": 1.0565, "gain": 1.0},
    {"channel": 1, "raw_value": 9234, "voltage": 1.1543, "gain": 1.0},
    {"channel": 2, "raw_value": 7500, "voltage": 0.9375, "gain": 1.0},
    {"channel": 3, "raw_value": 6200, "voltage": 0.7750, "gain": 1.0}
  ],
  "mock_mode": false,
  "i2c_address": "0x48"
}
```

---

## 📐 Hardware Specifications

- **Chip**: ADS1115 16-bit ADC
- **Interface**: I2C (addresses: 0x48, 0x49, 0x4A, 0x4B)
- **Channels**: 4 single-ended or 2 differential
- **Data Rate**: 8 - 860 SPS
- **Gain**: 2/3, 1, 2, 4, 8, 16

### I2C Addresses

| ADDR Pin | Address |
|----------|---------|
| GND | 0x48 |
| VDD | 0x49 |
| SDA | 0x4A |
| SCL | 0x4B |

### Gain Settings

| Gain | Voltage Range |
|------|---------------|
| 2/3 | ±6.144V |
| 1 | ±4.096V |
| 2 | ±2.048V |
| 4 | ±1.024V |
| 8 | ±0.512V |
| 16 | ±0.256V |

---

## 🛠️ Troubleshooting

### I2C Permission Denied

```bash
sudo usermod -a -G i2c pi
newgrp i2c
```

### Enable I2C Manually

```bash
sudo raspi-config
# Interface Options -> I2C -> Enable

# Or edit config
sudo nano /boot/firmware/config.txt
# Add: dtparam=i2c_arm=on

sudo reboot
```

### Check Logs

```bash
# Native installation
sudo journalctl -u ads1115-web -f

# Docker
docker-compose logs -f web
```

---

## 📚 Links

- This README
- [RPI_INSTALL.md](RPI_INSTALL.md) - Detailed RPi installation
- API docs: http://localhost:8080/docs
- Web panel: http://localhost:8080

---

Made for Raspberry Pi with ❤️

## License

Apache License 2.0 - see [LICENSE](LICENSE) for details.

## Author

Created by **Tom Sapletta** - [tom@sapletta.com](mailto:tom@sapletta.com)
