Kode Isi File sensor-data.php
Kode Isi File sensor-data.php
Bantu buatkan kode isi file sensor-data.php
Berikut adalah kode lengkap untuk file sensor-data.php yang menangani penerimaan, validasi, penyimpanan, dan pengambilan data sensor untuk aplikasi FarmerSmartAI:
```php
<?php
/**
* sensor-data.php
* API untuk mengelola data sensor FarmerSmartAI
* Endpoint:
* - POST: /sensor-data.php (menyimpan data sensor)
* - GET: /sensor-data.php?action=get_data (mengambil data sensor)
*/
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
exit(0);
}
// Konfigurasi database
$config = [
'host' => 'localhost',
'dbname' => 'farmersmartai',
'username' => 'root',
'password' => '',
'charset' => 'utf8mb4'
];
class SensorDataHandler {
private $pdo;
private $response;
public function __construct($config) {
$this->response = ['status' => 'error', 'message' => ''];
$this->connectDatabase($config);
}
private function connectDatabase($config) {
try {
$dsn = "mysql:host={$config['host']};dbname={$config['dbname']};charset={$config['charset']}";
$this->pdo = new PDO($dsn, $config['username'], $config['password']);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
$this->response['message'] = "Database connection failed: " . $e->getMessage();
$this->sendResponse();
}
}
public function handleRequest() {
try {
switch ($_SERVER['REQUEST_METHOD']) {
case 'POST':
$this->handlePost();
break;
case 'GET':
$this->handleGet();
break;
default:
$this->response['message'] = 'Method not allowed';
$this->sendResponse();
}
} catch (Exception $e) {
$this->response['message'] = $e->getMessage();
$this->sendResponse();
}
}
private function handlePost() {
// Get JSON input
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
$this->response['message'] = 'Invalid JSON data';
$this->sendResponse();
}
// Validate required fields
$required = ['sensor_id', 'temperature', 'humidity', 'soil_moisture'];
foreach ($required as $field) {
if (!isset($input[$field])) {
$this->response['message'] = "Missing required field: $field";
$this->sendResponse();
}
}
// Sanitize data
$sensorData = [
'sensor_id' => $this->sanitize($input['sensor_id']),
'temperature' => floatval($input['temperature']),
'humidity' => floatval($input['humidity']),
'soil_moisture' => floatval($input['soil_moisture']),
'soil_ph' => isset($input['soil_ph']) ? floatval($input['soil_ph']) : null,
'light_intensity' => isset($input['light_intensity']) ? floatval($input['light_intensity']) : null,
'rainfall' => isset($input['rainfall']) ? floatval($input['rainfall']) : null,
'wind_speed' => isset($input['wind_speed']) ? floatval($input['wind_speed']) : null,
'battery_level' => isset($input['battery_level']) ? floatval($input['battery_level']) : null,
'location_lat' => isset($input['location_lat']) ? floatval($input['location_lat']) : null,
'location_lng' => isset($input['location_lng']) ? floatval($input['location_lng']) : null
];
// Save to database
$this->saveSensorData($sensorData);
$this->response['status'] = 'success';
$this->response['message'] = 'Sensor data saved successfully';
$this->response['data_id'] = $this->pdo->lastInsertId();
$this->sendResponse();
}
private function handleGet() {
$action = $_GET['action'] ?? '';
switch ($action) {
case 'get_data':
$this->getSensorData();
break;
case 'get_latest':
$this->getLatestData();
break;
case 'get_stats':
$this->getStatistics();
break;
case 'get_by_date':
$this->getDataByDate();
break;
default:
$this->response['message'] = 'Invalid action specified';
$this->sendResponse();
}
}
private function saveSensorData($data) {
$sql = "INSERT INTO sensor_data (
sensor_id, temperature, humidity, soil_moisture, soil_ph,
light_intensity, rainfall, wind_speed, battery_level,
location_lat, location_lng, created_at
) VALUES (
:sensor_id, :temperature, :humidity, :soil_moisture, :soil_ph,
:light_intensity, :rainfall, :wind_speed, :battery_level,
:location_lat, :location_lng, NOW()
)";
$stmt = $this->pdo->prepare($sql);
$stmt->execute($data);
}
private function getSensorData() {
$sensorId = $_GET['sensor_id'] ?? null;
$limit = min(intval($_GET['limit'] ?? 100), 1000); // Max 1000 records
$offset = intval($_GET['offset'] ?? 0);
$sql = "SELECT * FROM sensor_data WHERE 1=1";
$params = [];
if ($sensorId) {
$sql .= " AND sensor_id = :sensor_id";
$params[':sensor_id'] = $sensorId;
}
$sql .= " ORDER BY created_at DESC LIMIT :limit OFFSET :offset";
$stmt = $this->pdo->prepare($sql);
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
foreach ($params as $key => $value) {
$stmt->bindValue($key, $value);
}
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$this->response['status'] = 'success';
$this->response['data'] = $data;
$this->response['count'] = count($data);
$this->sendResponse();
}
private function getLatestData() {
$sensorId = $_GET['sensor_id'] ?? null;
$sql = "SELECT * FROM sensor_data WHERE 1=1";
$params = [];
if ($sensorId) {
$sql .= " AND sensor_id = :sensor_id";
$params[':sensor_id'] = $sensorId;
}
$sql .= " ORDER BY created_at DESC LIMIT 1";
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
$data = $stmt->fetch(PDO::FETCH_ASSOC);
$this->response['status'] = 'success';
$this->response['data'] = $data ?: null;
$this->sendResponse();
}
private function getStatistics() {
$sensorId = $_GET['sensor_id'] ?? null;
$days = intval($_GET['days'] ?? 7);
$sql = "SELECT
AVG(temperature) as avg_temperature,
MAX(temperature) as max_temperature,
MIN(temperature) as min_temperature,
AVG(humidity) as avg_humidity,
AVG(soil_moisture) as avg_soil_moisture,
AVG(soil_ph) as avg_soil_ph,
COUNT(*) as total_readings,
DATE(created_at) as date
FROM sensor_data
WHERE created_at >= DATE_SUB(NOW(), INTERVAL :days DAY)";
$params = [':days' => $days];
if ($sensorId) {
$sql .= " AND sensor_id = :sensor_id";
$params[':sensor_id'] = $sensorId;
}
$sql .= " GROUP BY DATE(created_at) ORDER BY date DESC";
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
$stats = $stmt->fetchAll(PDO::FETCH_ASSOC);
$this->response['status'] = 'success';
$this->response['statistics'] = $stats;
$this->response['period_days'] = $days;
$this->sendResponse();
}
private function getDataByDate() {
$date = $_GET['date'] ?? date('Y-m-d');
$sensorId = $_GET['sensor_id'] ?? null;
$sql = "SELECT * FROM sensor_data WHERE DATE(created_at) = :date";
$params = [':date' => $date];
if ($sensorId) {
$sql .= " AND sensor_id = :sensor_id";
$params[':sensor_id'] = $sensorId;
}
$sql .= " ORDER BY created_at ASC";
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$this->response['status'] = 'success';
$this->response['data'] = $data;
$this->response['date'] = $date;
$this->response['count'] = count($data);
$this->sendResponse();
}
private function sanitize($data) {
return htmlspecialchars(strip_tags(trim($data)));
}
private function sendResponse() {
echo json_encode($this->response, JSON_PRETTY_PRINT);
exit;
}
}
// Create table if not exists (for first time setup)
function createTableIfNotExists($pdo) {
$sql = "CREATE TABLE IF NOT EXISTS sensor_data (
id INT AUTO_INCREMENT PRIMARY KEY,
sensor_id VARCHAR(50) NOT NULL,
temperature DECIMAL(5,2) NOT NULL,
humidity DECIMAL(5,2) NOT NULL,
soil_moisture DECIMAL(5,2) NOT NULL,
soil_ph DECIMAL(3,1) NULL,
light_intensity INT NULL,
rainfall DECIMAL(5,2) NULL,
wind_speed DECIMAL(5,2) NULL,
battery_level DECIMAL(5,2) NULL,
location_lat DECIMAL(10,8) NULL,
location_lng DECIMAL(11,8) NULL,
created_at DATETIME NOT NULL,
INDEX idx_sensor_id (sensor_id),
INDEX idx_created_at (created_at),
INDEX idx_sensor_created (sensor_id, created_at)
)";
$pdo->exec($sql);
}
// Initialize and handle request
try {
$handler = new SensorDataHandler($config);
// Auto-create table on first run
createTableIfNotExists($handler->getPdo());
$handler->handleRequest();
} catch (Exception $e) {
$response = [
'status' => 'error',
'message' => 'Server error: ' . $e->getMessage()
];
echo json_encode($response, JSON_PRETTY_PRINT);
}
// Method to get PDO instance (add this to the class)
public function getPdo() {
return $this->pdo;
}
?>
```
SQL Schema untuk Tabel Sensor Data:
```sql
-- File: create_sensor_table.sql
CREATE TABLE IF NOT EXISTS sensor_data (
id INT AUTO_INCREMENT PRIMARY KEY,
sensor_id VARCHAR(50) NOT NULL,
temperature DECIMAL(5,2) NOT NULL COMMENT 'Suhu dalam Celsius',
humidity DECIMAL(5,2) NOT NULL COMMENT 'Kelembaban udara dalam %',
soil_moisture DECIMAL(5,2) NOT NULL COMMENT 'Kelembaban tanah dalam %',
soil_ph DECIMAL(3,1) NULL COMMENT 'pH tanah',
light_intensity INT NULL COMMENT 'Intensitas cahaya dalam lux',
rainfall DECIMAL(5,2) NULL COMMENT 'Curah hujan dalam mm',
wind_speed DECIMAL(5,2) NULL COMMENT 'Kecepatan angin dalam m/s',
battery_level DECIMAL(5,2) NULL COMMENT 'Level baterai sensor dalam %',
location_lat DECIMAL(10,8) NULL COMMENT 'Koordinat latitude',
location_lng DECIMAL(11,8) NULL COMMENT 'Koordinat longitude',
created_at DATETIME NOT NULL,
INDEX idx_sensor_id (sensor_id),
INDEX idx_created_at (created_at),
INDEX idx_sensor_created (sensor_id, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
Cara Penggunaan API:
1. Menyimpan Data Sensor (POST):
```javascript
// Contoh request JavaScript
fetch('/sensor-data.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
sensor_id: 'sensor_001',
temperature: 28.5,
humidity: 75.2,
soil_moisture: 45.8,
soil_ph: 6.2,
light_intensity: 1200,
rainfall: 0.0,
wind_speed: 2.5,
battery_level: 85.5,
location_lat: -6.2088,
location_lng: 106.8456
})
})
.then(response => response.json())
.then(data => console.log(data));
```
2. Mengambil Data Sensor (GET):
Ambil semua data:
```
GET /sensor-data.php?action=get_data&limit=50
```
Ambil data terbaru:
```
GET /sensor-data.php?action=get_latest&sensor_id=sensor_001
```
Ambil statistik:
```
GET /sensor-data.php?action=get_stats&days=7&sensor_id=sensor_001
```
Ambil data berdasarkan tanggal:
```
GET /sensor-data.php?action=get_by_date&date=2024-01-15&sensor_id=sensor_001
```
3. Contoh Response Sukses:
```json
{
"status": "success",
"message": "Sensor data saved successfully",
"data_id": 123
}
```
4. Contoh Response Data:
```json
{
"status": "success",
"data": [
{
"id": 1,
"sensor_id": "sensor_001",
"temperature": 28.5,
"humidity": 75.2,
"soil_moisture": 45.8,
"soil_ph": 6.2,
"light_intensity": 1200,
"rainfall": 0.0,
"wind_speed": 2.5,
"battery_level": 85.5,
"location_lat": -6.2088,
"location_lng": 106.8456,
"created_at": "2024-01-15 10:30:00"
}
],
"count": 1
}
```
Fitur Keamanan:
1. Input Validation - Validasi data wajib
2. SQL Injection Protection - Menggunakan PDO prepared statements
3. XSS Prevention - Sanitasi input dengan htmlspecialchars
4. CORS Headers - Mendukung cross-origin requests
5. Error Handling - Penanganan error yang aman
Konfigurasi Database:
Edit bagian config sesuai dengan setting database Anda:
```php
$config = [
'host' => 'localhost',
'dbname' => 'farmersmartai',
'username' => 'your_username',
'password' => 'your_password',
'charset' => 'utf8mb4'
];
```
File ini siap digunakan untuk menerima dan mengelola data dari sensor IoT di lapangan! 🌱📡
Bersambung ke: Kode Isi File ai-processing.php
Comments
Post a Comment