| Server IP : 93.86.61.54 / Your IP : 216.73.216.60 Web Server : Apache/2.4.62 (Ubuntu) System : Linux rasin.ddns.net 6.8.0-124-generic #124~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 21:05:19 UTC x86_64 User : www-data ( 33) PHP Version : 8.4.22 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/html/projects/tempcontrol/backup/ |
Upload File : |
<?php
// temperature_handler.php - Podrška za CLI i HTTP
date_default_timezone_set('Europe/Belgrade');
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', '/tmp/php_debug.log');
// DEBUG: Loguj početak izvršavanja
file_put_contents('/tmp/debug.log', "=== SCRIPT STARTED ===\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "Time: " . date('Y-m-d H:i:s') . "\n", FILE_APPEND);
// DODAJTE OVE LINIJE - pratimo tok izvršavanja
file_put_contents('/tmp/debug.log', "1. Before includes\n", FILE_APPEND);
// ================= KONFIGURACIJA =================
define('API_KEY', 'esp32-secure-key-2024');
// ================= DETEKCIJA OKRUŽENJA =================
$isCli = (php_sapi_name() === 'cli');
// ================= KONFIGURACIJA =================
define('API_KEY', 'esp32-secure-key-2024');
define('LOW_TEMP_THRESHOLD', 18.0);
define('HIGH_TEMP_THRESHOLD', 25.0);
define('HYSTERESIS', 1.0);
define('LOG_FILE', __DIR__ . '/temperature.log');
// Dozvoljeni sensor IDs
$allowedSensors = ['esp32-bme280-01', 'esp32-bme280-02'];
// ================= INICIJALIZACIJA ZA HTTP =================
if (!$isCli) {
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-API-Key');
}
// ================= FUNKCIJE =================
function logEvent($level, $message) {
$logEntry = sprintf(
"[%s] [%s] %s\n",
date('Y-m-d H:i:s'),
$level,
$message
);
@file_put_contents(LOG_FILE, $logEntry, FILE_APPEND | LOCK_EX);
}
function sendJsonError($message, $code = 500) {
global $isCli;
if (!$isCli) {
http_response_code($code);
}
echo json_encode([
'status' => 'error',
'message' => $message,
'timestamp' => date('Y-m-d H:i:s')
], JSON_UNESCAPED_UNICODE);
if ($isCli) {
echo "\n"; // Dodaj novi red za CLI
}
exit;
}
// ================= OBRADA ZA CLI =================
if ($isCli) {
// Proveri da li su prosleđeni argumenti
if ($argc > 1 && $argv[1] === 'test') {
$testData = '{"temperature": 22.5, "sensor_id": "test-sensor", "humidity": 45.0, "pressure": 1013.25}';
processRequest($testData, true);
} else {
echo "Usage: php temperature_handler.php test\n";
echo "Or pipe JSON data: echo '{\"temperature\":22.5}' | php temperature_handler.php\n";
exit;
}
} else {
// ================= OBRADA ZA HTTP =================
// Obradi OPTIONS zahtev za CORS
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
// Provera HTTP metode
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
sendJsonError('Samo POST zahtevi su dozvoljeni', 405);
}
// Autentifikacija za HTTP
$apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
if (empty($apiKey)) {
sendJsonError('API ključ je obavezan', 401);
}
if ($apiKey !== API_KEY) {
sendJsonError('Nevažeći API ključ', 401);
}
// Provera Content-Type
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
if (stripos($contentType, 'application/json') === false) {
sendJsonError('Unsupported Media Type', 415);
}
// Čitanje JSON podataka
$json = file_get_contents('php://input');
processRequest($json, false);
}
// ================= GLAVNA FUNKCIJA ZA OBRADU =================
function processRequest($json, $isTest = false) {
global $allowedSensors;
logEvent('DEBUG', 'ProcessRequest started');
file_put_contents('/tmp/debug.log', "5. processRequest started\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "Raw input: " . file_get_contents('php://input') . "\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "JSON var: " . $json . "\n", FILE_APPEND);
// Debug HTTP headers
file_put_contents('/tmp/debug.log', "Content-Type: " . ($_SERVER['CONTENT_TYPE'] ?? 'NOT SET') . "\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "Request Method: " . ($_SERVER['REQUEST_METHOD'] ?? 'NOT SET') . "\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "JSON length: " . strlen($json) . "\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "JSON content: '" . $json . "'\n", FILE_APPEND);
if (strlen($json) === 0) {
file_put_contents('/tmp/debug.log', "JSON is REALLY empty\n", FILE_APPEND);
sendJsonError('JSON podaci su prazni', 400);
} else {
file_put_contents('/tmp/debug.log', "JSON has data, continuing ...\n", FILE_APPEND);
}
file_put_contents('/tmp/debug.log', "8. Before json_decode\n", FILE_APPEND);
$data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
file_put_contents('/tmp/debug.log', "10. JSON decode error: " . json_last_error_msg() . "\n", FILE_APPEND);
sendJsonError('Nevažeći JSON format: ' . json_last_error_msg(), 400);
}
file_put_contents('/tmp/debug.log', "11. JSON decoded successfully\n", FILE_APPEND);
// Validacija obaveznih polja
file_put_contents('/tmp/debug.log', "12. Before validation - data: " . print_r($data, true) . "\n", FILE_APPEND);
// Proverite tačno šta se dešava u validaciji
$tempExists = isset($data['temperature']);
$sensorExists = isset($data['sensor_id']);
file_put_contents('/tmp/debug.log', "Temperature exists: " . ($tempExists ? 'YES' : 'NO') . "\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "Sensor_id exists: " . ($sensorExists ? 'YES' : 'NO') . "\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "Temperature value: " . ($data['temperature'] ?? 'NULL') . "\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "Sensor_id value: " . ($data['sensor_id'] ?? 'NULL') . "\n", FILE_APPEND);
if (!isset($data['temperature']) || !isset($data['sensor_id'])) {
file_put_contents('/tmp/debug.log', "13. Validation failed\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "Temperature exists: " . (isset($data['temperature']) ? 'YES' : 'NO') . "\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "Sensor_id exists: " . (isset($data['sensor_id']) ? 'YES' : 'NO') . "\n", FILE_APPEND);
sendJsonError('Nedostaje temperatura ili sensor_id', 400);
}
file_put_contents('/tmp/debug.log', "14. Validation passed - extracting values\n", FILE_APPEND);
$sensorId = trim($data['sensor_id']);
$temperature = floatval($data['temperature']);
$humidity = isset($data['humidity']) ? floatval($data['humidity']) : null;
$pressure = isset($data['pressure']) ? floatval($data['pressure']) : null;
file_put_contents('/tmp/debug.log', "15. Extracted - Sensor: '$sensorId', Temp: $temperature, Humidity: " . ($humidity ?? 'NULL') . ", Pressure: " . ($pressure ?? 'NULL') . "\n", FILE_APPEND);
// Provera dozvoljenih senzora
file_put_contents('/tmp/debug.log', "16. Checking allowed sensors\n", FILE_APPEND);
$allowedSensors = ['esp32-bme280-01', 'esp32-bme280-02'];
$isAllowed = in_array($sensorId, $allowedSensors);
if (!$isAllowed) {
file_put_contents('/tmp/debug.log', "18. Sensor not allowed error\n", FILE_APPEND);
sendJsonError('Nedozvoljeni sensor ID: ' . $sensorId, 403);
}
// Za test mode, preskoči proveru senzora
if (!$isTest && !in_array($sensorId, $allowedSensors)) {
sendJsonError('Nedozvoljeni sensor ID: ' . $sensorId, 403);
}
// Validacija temperature
if ($temperature < -50 || $temperature > 100) {
sendJsonError('Temperatura van opsega (-50 do 100)', 400);
}
// ================= LOGIKA ZA GREJANJE =================
$lastHeatingState = 'off'; // Početno stanje
$isCurrentlyHeating = ($lastHeatingState === 'on');
file_put_contents('/tmp/debug.log', "19. Sensor allowed, continuing...\n", FILE_APPEND);
// Konekcija sa bazom
file_put_contents('/tmp/debug.log', "20. Before database connection\n", FILE_APPEND);
$pdo = getDatabaseConnection();
file_put_contents('/tmp/debug.log', "21. After database connection\n", FILE_APPEND);
// Logika za grejanje
file_put_contents('/tmp/debug.log', "22. Before heating logic\n", FILE_APPEND);
$lastHeatingState = getLastHeatingState($pdo, $sensorId);
$isCurrentlyHeating = ($lastHeatingState === 'on');
$heatingCommand = determineHeatingCommand($temperature, $isCurrentlyHeating);
file_put_contents('/tmp/debug.log', "23. Heating command: $heatingCommand (last state: $lastHeatingState, current temp: $temperature)\n", FILE_APPEND);
// Snimanje u bazu
file_put_contents('/tmp/debug.log', "24. Before database insert\n", FILE_APPEND);
$insertId = saveTemperatureData($pdo, $sensorId, $temperature, $humidity, $pressure, $heatingCommand);
file_put_contents('/tmp/debug.log', "25. After database insert, ID: " . ($insertId ?: 'FAILED') . "\n", FILE_APPEND);
// Određivanje komande sa histerezom
$heatingCommand = determineHeatingCommand($temperature, $isCurrentlyHeating);
// Snimanje podataka (simulacija za sada)
// saveTemperatureData($sensorId, $temperature, $humidity, $pressure, $heatingCommand);
// ================= GENERISANJE ODGOVORA =================
$response = [
'status' => 'success',
'received_data' => [
'temperature' => $temperature,
'humidity' => $humidity,
'pressure' => $pressure,
'sensor_id' => $sensorId,
'timestamp' => date('Y-m-d H:i:s')
],
'heating_command' => $heatingCommand,
'message' => getHeatingMessage($heatingCommand, $temperature),
'threshold_info' => [
'low_threshold' => LOW_TEMP_THRESHOLD,
'high_threshold' => HIGH_TEMP_THRESHOLD,
'hysteresis' => HYSTERESIS,
'current_temperature' => $temperature
]
];
if (!$isTest) {
http_response_code(200);
}
echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
if ($isTest) {
echo "\n"; // Dodaj novi red za CLI
}
logEvent('INFO', "Uspeh - Sensor $sensorId: Temp={$temperature}°C, Cmd=$heatingCommand");
}
// ================= POMOĆNE FUNKCIJE =================
function determineHeatingCommand($temperature, $isCurrentlyHeating) {
if ($isCurrentlyHeating) {
return ($temperature > (HIGH_TEMP_THRESHOLD + HYSTERESIS)) ? 'off' : 'on';
} else {
return ($temperature < (LOW_TEMP_THRESHOLD - HYSTERESIS)) ? 'on' : 'off';
}
}
function getHeatingMessage($command, $temperature) {
if ($command === 'on') {
return "Grejanje UKLJUČENO. Temperatura (" . $temperature . "°C) je ispod donjeg praga.";
} else {
return "Grejanje ISKLJUČENO. Temperatura (" . $temperature . "°C) je iznad gornjeg praga.";
}
}
function saveTemperatureData($sensorId, $temperature, $humidity, $pressure, $command) {
$logEntry = sprintf(
"[%s] Sensor: %s, Temp: %.1f°C, Humidity: %.1f%%, Pressure: %.1fhPa, Command: %s\n",
date('Y-m-d H:i:s'),
$sensorId,
$temperature,
$humidity ?? 0,
$pressure ?? 0,
$command
);
@file_put_contents(LOG_FILE, $logEntry, FILE_APPEND | LOCK_EX);
}
function getDatabaseConnection() {
// Dodajte ove linije u getDatabaseConnection()
file_put_contents('/tmp/debug.log', "PHP_SAPI: " . PHP_SAPI . "\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "PHP_VERSION: " . PHP_VERSION . "\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "PDO_DRIVERS: " . implode(', ', PDO::getAvailableDrivers()) . "\n", FILE_APPEND);
try {
file_put_contents('/tmp/debug.log', "DB_CONNECTION: Attempting to connect...\n", FILE_APPEND);
$dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET;
file_put_contents('/tmp/debug.log', "DB_CONNECTION: DSN: $dsn\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "DB_CONNECTION: User: " . DB_USER . "\n", FILE_APPEND);
// Dodajte timeout za PDO konekciju
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_TIMEOUT => 5, // 5 sekundi timeout
];
file_put_contents('/tmp/debug.log', "DB_CONNECTION: Creating PDO instance...\n", FILE_APPEND);
$pdo = new PDO($dsn, DB_USER, DB_PASS, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
file_put_contents('/tmp/debug.log', "DB_CONNECTION: Successfully connected!\n", FILE_APPEND);
logEvent('INFO', 'Uspešna konekcija sa bazom podataka');
return $pdo;
} catch (PDOException $e) {
file_put_contents('/tmp/debug.log', "DB_CONNECTION_ERROR: " . $e->getMessage() . "\n", FILE_APPEND);
file_put_contents('/tmp/debug.log', "DB_CONNECTION_ERROR_CODE: " . $e->getCode() . "\n", FILE_APPEND);
logEvent('ERROR', 'Greška pri konekciji sa bazom: ' . $e->getMessage());
// DODAJTE OVO ZA DEBUG:
error_log("PDO ERROR: " . $e->getMessage());
sendJsonError('Database connection failed: ' . $e->getMessage(), 500);
} catch (Exception $e) {
file_put_contents('/tmp/debug.log', "GENERAL_DB_ERROR: " . $e->getMessage() . "\n", FILE_APPEND);
sendJsonError('Database error: ' . $e->getMessage(), 500);
}
}
?>