# Hardware Integration Guide

This guide explains how to connect Arduino and Raspberry Pi microcontrollers to the Agriculture Robot Control System.

## Overview

The system supports multiple communication protocols:
- **TCP/IP**: For devices connected via network (Raspberry Pi, ESP32, ESP8266)
- **Serial/USB**: For Arduino and other devices connected via USB
- **MQTT**: For IoT devices using MQTT protocol
- **HTTP**: For devices with REST API endpoints

## Connection Methods

### 1. TCP/IP Connection (Raspberry Pi, ESP32, ESP8266)

**For Raspberry Pi:**
1. Create a Python script that sends sensor data via TCP socket
2. Configure the device in the Hardware page:
   - Device Type: `raspberry_pi`
   - Connection Type: `tcp`
   - IP Address: Your Raspberry Pi's IP (e.g., `192.168.1.100`)
   - Port: TCP port (e.g., `8080`)

**Example Python Code (Raspberry Pi):**
```python
import socket
import json
import time
from sense_hat import SenseHat  # For Raspberry Pi Sense HAT

sense = SenseHat()
HOST = '192.168.1.50'  # Backend server IP
PORT = 8080

def send_sensor_data():
    while True:
        # Read sensors
        temperature = sense.get_temperature()
        humidity = sense.get_humidity()
        pressure = sense.get_pressure()
        
        data = {
            'deviceId': 'raspberry-pi-001',
            'timestamp': time.strftime('%Y-%m-%dT%H:%M:%S'),
            'temperature': temperature,
            'humidity': humidity,
            'pressure': pressure
        }
        
        try:
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                s.connect((HOST, PORT))
                s.sendall(json.dumps(data).encode())
        except Exception as e:
            print(f"Error: {e}")
        
        time.sleep(2)  # Send data every 2 seconds

if __name__ == '__main__':
    send_sensor_data()
```

### 2. Serial/USB Connection (Arduino)

**For Arduino:**
1. Upload Arduino sketch that reads sensors and sends data via Serial
2. Configure the device in the Hardware page:
   - Device Type: `arduino`
   - Connection Type: `serial`
   - COM Port: Your Arduino's COM port (e.g., `COM3` on Windows, `/dev/ttyUSB0` on Linux)
   - Baud Rate: Serial baud rate (e.g., `9600`)

**Example Arduino Code:**
```cpp
#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  dht.begin();
}

void loop() {
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();
  
  // Send JSON formatted data
  Serial.print("{\"deviceId\":\"arduino-001\",");
  Serial.print("\"temperature\":");
  Serial.print(temperature);
  Serial.print(",\"humidity\":");
  Serial.print(humidity);
  Serial.print(",\"timestamp\":\"");
  Serial.print(millis());
  Serial.println("\"}");
  
  delay(2000);  // Send every 2 seconds
}
```

**Backend Serial Connection (Node.js):**
```typescript
// Install: npm install serialport
import { SerialPort } from 'serialport';
import { ReadlineParser } from '@serialport/parser-readline';

const port = new SerialPort({
  path: 'COM3',  // or '/dev/ttyUSB0'
  baudRate: 9600
});

const parser = port.pipe(new ReadlineParser({ delimiter: '\n' }));

parser.on('data', (data: string) => {
  try {
    const reading = JSON.parse(data);
    // Send to hardware service
    hardwareService.updateSensorReading(reading.deviceId, reading);
  } catch (error) {
    console.error('Error parsing serial data:', error);
  }
});
```

### 3. MQTT Connection

**For ESP32/ESP8266 with MQTT:**
1. Configure device in Hardware page:
   - Device Type: `esp32` or `esp8266`
   - Connection Type: `mqtt`
   - MQTT Topic: Topic to subscribe to (e.g., `agri-robot/device1/sensors`)

**Example ESP32 Code (Arduino IDE):**
```cpp
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>

const char* ssid = "YourWiFi";
const char* password = "YourPassword";
const char* mqtt_server = "your-mqtt-broker.com";
const char* topic = "agri-robot/esp32-001/sensors";

WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(2, DHT22);

void setup() {
  Serial.begin(115200);
  dht.begin();
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
  
  client.setServer(mqtt_server, 1883);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  
  float temp = dht.readTemperature();
  float hum = dht.readHumidity();
  
  String payload = "{\"deviceId\":\"esp32-001\",";
  payload += "\"temperature\":" + String(temp) + ",";
  payload += "\"humidity\":" + String(hum) + "}";
  
  client.publish(topic, payload.c_str());
  delay(2000);
}

void reconnect() {
  while (!client.connected()) {
    if (client.connect("ESP32Client")) {
      client.subscribe(topic);
    } else {
      delay(5000);
    }
  }
}
```

### 4. HTTP/REST API Connection

**For devices with HTTP endpoints:**
1. Configure device in Hardware page:
   - Connection Type: `http`
   - IP Address: Device IP
   - Port: HTTP port (usually 80 or 8080)

The backend will poll the device's sensor endpoint:
```
GET http://device-ip:port/api/sensors
```

**Expected Response:**
```json
{
  "deviceId": "device-001",
  "temperature": 25.5,
  "humidity": 60.0,
  "soilMoisture": 45.0
}
```

## Data Format

All sensor data should follow this format:

```json
{
  "deviceId": "unique-device-id",
  "timestamp": "2024-01-01T12:00:00Z",
  "temperature": 25.5,
  "humidity": 60.0,
  "soilMoisture": 45.0,
  "light": 75.0,
  "ph": 6.5,
  "pressure": 1013.25
}
```

## Camera Integration

For devices with cameras (Raspberry Pi Camera Module):

**Raspberry Pi Camera Stream:**
```python
from picamera2 import Picamera2
import socket
import struct

picam2 = Picamera2()
picam2.start()

# Stream via TCP
HOST = '192.168.1.50'
PORT = 8081

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    while True:
        frame = picam2.capture_array()
        # Encode and send frame
        # Implementation depends on encoding format
```

## API Endpoints

### Connect Device
```
POST /api/hardware/devices/connect
Content-Type: application/json

{
  "id": "device-001",
  "name": "Arduino Sensor Node",
  "type": "arduino",
  "connectionType": "serial",
  "address": "COM3",
  "baudRate": 9600
}
```

### Send Sensor Data
```
POST /api/hardware/devices/{deviceId}/sensors
Content-Type: application/json

{
  "temperature": 25.5,
  "humidity": 60.0,
  "soilMoisture": 45.0
}
```

### Get Device Status
```
GET /api/hardware/devices/{deviceId}
```

### Disconnect Device
```
POST /api/hardware/devices/{deviceId}/disconnect
```

## WebSocket Events

The system broadcasts hardware data via WebSocket:

- `hardware_sensor_data`: New sensor reading received
- `hardware_camera_frame`: New camera frame received
- `hardware_device_connected`: Device connected
- `hardware_device_disconnected`: Device disconnected
- `hardware_device_status`: Device status changed

## Troubleshooting

### Device Not Connecting
1. Check IP address/COM port is correct
2. Verify device is powered on and accessible
3. Check firewall settings for TCP connections
4. Verify baud rate matches for serial connections

### No Sensor Data
1. Verify device is sending data in correct format
2. Check device connection status in Hardware page
3. Verify WebSocket connection is active
4. Check backend logs for errors

### Serial Port Issues (Windows)
- Install USB drivers for your Arduino
- Check Device Manager for COM port number
- Close other programs using the serial port

### Serial Port Issues (Linux)
- Add user to dialout group: `sudo usermod -a -G dialout $USER`
- Check permissions: `ls -l /dev/ttyUSB*`
- Use `/dev/ttyUSB0` or `/dev/ttyACM0` format

## Next Steps

1. Connect your device using the Hardware page
2. Monitor sensor data in the Sensors page
3. View camera feed in the Camera page (if available)
4. Check device status in the Hardware page

For more information, see the main README.md and ARCHITECTURE.md files.

