ESP32-CAM Example: POST image + sensor data to Laravel API

Requirements
- ESP32-CAM module (with camera)
- DHT22 or similar for air temperature & humidity (optional)
- Soil moisture sensor

Overview
This example captures an image, reads sensors, encodes the image as base64, and sends a JSON POST to `/api/sensor` on your Laravel server.

Fields posted (JSON):
- `suhu` (number): temperature in °C
- `kelembapan` (number): air humidity in %
- `soil` (number): soil moisture in %
- `image_base64` (string): base64-encoded JPEG image (no data URL prefix)

Arduino (ESP32) pseudo-example (use in Arduino IDE with WiFi and camera libs):

```cpp
#include <WiFi.h>
#include "esp_camera.h"
#include <HTTPClient.h>
#include "base64.h" // use an available base64 lib

const char* ssid = "YOUR_SSID";
const char* pass = "YOUR_PASS";
const char* serverUrl = "http://YOUR_SERVER/api/sensor";

void setup(){
  Serial.begin(115200);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  // init camera (board-specific)
}

void loop(){
  // capture frame
  camera_fb_t * fb = esp_camera_fb_get();
  if(!fb) { delay(1000); return; }

  // base64 encode
  String imgBase64 = base64::encode(fb->buf, fb->len);
  esp_camera_fb_return(fb);

  // read sensors (pseudo)
  float suhu = 25.0; // read from DHT
  float kelembapan = 60.0; // read from DHT
  float soil = 45.0; // read from analog sensor, map to %

  // build JSON
  String payload = "{";
  payload += "\"suhu\":" + String(suhu,1) + ",";
  payload += "\"kelembapan\":" + String(kelembapan,1) + ",";
  payload += "\"soil\":" + String(soil,1) + ",";
  payload += "\"image_base64\":\"" + imgBase64 + "\"}";

  HTTPClient http;
  http.begin(serverUrl);
  http.addHeader("Content-Type", "application/json");
  int code = http.POST(payload);
  Serial.println(code);
  http.end();

  delay(60 * 1000); // send every minute
}
```

Notes
- Ensure `serverUrl` points to your Laravel app (use ngrok or port forward during development).
- The Laravel endpoint expects base64 image without data URL prefix. If your encoder adds `data:image/jpeg;base64,` remove that prefix before sending.
- Large images may exceed payload limits; you can resize images on ESP or enable bigger request sizes in PHP/NGINX.

Server side
- Run migrations:

```powershell
php artisan migrate
php artisan storage:link
```

- The API endpoint is `POST /api/sensor` (no auth in example). Adjust middleware as needed.
