setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Fetch the last 30 records $stmt = $db->query("SELECT timestamp, PM1, PM25, PM10 FROM data_NPM ORDER BY timestamp DESC LIMIT 30"); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); $reversedData = array_reverse($data); // Reverse the order echo json_encode($reversedData); } catch (PDOException $e) { echo json_encode(["error" => $e->getMessage()]); } } /* */ //GETING data from config_table (SQLite DB) if ($type == "get_config_sqlite") { try { $db = new PDO("sqlite:$database_path"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Get all main configuration entries $config_query = $db->query("SELECT key, value, type FROM config_table"); $config_data = $config_query->fetchAll(PDO::FETCH_ASSOC); // Convert data types according to their 'type' field $result = []; foreach ($config_data as $item) { $key = $item['key']; $value = $item['value']; $type = $item['type']; // Convert value based on its type switch ($type) { case 'bool': $parsed_value = ($value == '1' || $value == 'true') ? true : false; break; case 'int': $parsed_value = intval($value); break; case 'float': $parsed_value = floatval($value); break; default: $parsed_value = $value; } $result[$key] = $parsed_value; } // Return JSON response header('Content-Type: application/json'); echo json_encode($result, JSON_PRETTY_PRINT); } catch (PDOException $e) { // Return error as JSON header('Content-Type: application/json'); echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); } } /* */ //GETING data from config_scrips_table (SQLite DB) if ($type == "get_config_scripts_sqlite") { try { $db = new PDO("sqlite:$database_path"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Get all main configuration entries $config_query = $db->query("SELECT * FROM config_scripts_table"); $config_data = $config_query->fetchAll(PDO::FETCH_ASSOC); // Convert data types according to their 'type' field $result = []; foreach ($config_data as $item) { $script_path = $item['script_path']; $enabled = $item['enabled']; // Convert the enabled field to a proper boolean $result[$script_path] = ($enabled == 1); } // Return JSON response header('Content-Type: application/json'); echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); } catch (PDOException $e) { // Return error as JSON header('Content-Type: application/json'); echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); } } /* */ //GETING data from envea_sondes_table (SQLite DB) if ($type == "get_envea_sondes_table_sqlite") { try { $db = new PDO("sqlite:$database_path"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Get all entries from envea_sondes_table $query = $db->query("SELECT id, connected, port, name, coefficient FROM envea_sondes_table"); $data = $query->fetchAll(PDO::FETCH_ASSOC); // Convert data types appropriately $result = []; foreach ($data as $item) { // Create object for each sonde with proper data types $sonde = [ 'id' => (int)$item['id'], 'connected' => $item['connected'] == 1, // Convert to boolean 'port' => $item['port'], 'name' => $item['name'], 'coefficient' => (float)$item['coefficient'] // Convert to float ]; // Add to results array $result[] = $sonde; } // Return JSON response header('Content-Type: application/json'); echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); } catch (PDOException $e) { // Return error as JSON header('Content-Type: application/json'); echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); } } //UPDATING the config_table from SQLite DB if ($type == "update_config_sqlite") { $param = $_GET['param'] ?? null; $value = $_GET['value'] ?? null; if ($param === null || $value === null) { echo json_encode(["error" => "Missing parameter or value"]); exit; } try { $db = new PDO("sqlite:$database_path"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // First, check if parameter exists and get its type $checkStmt = $db->prepare("SELECT type FROM config_table WHERE key = :param"); $checkStmt->bindParam(':param', $param); $checkStmt->execute(); $result = $checkStmt->fetch(PDO::FETCH_ASSOC); if ($result) { // Parameter exists, determine type and update $type = $result['type']; // Convert value according to type if needed $convertedValue = $value; if ($type == "bool") { // Convert various boolean representations to 0/1 $convertedValue = (filter_var($value, FILTER_VALIDATE_BOOLEAN)) ? "1" : "0"; } elseif ($type == "int") { $convertedValue = (string)intval($value); } elseif ($type == "float") { $convertedValue = (string)floatval($value); } // Update the value $updateStmt = $db->prepare("UPDATE config_table SET value = :value WHERE key = :param"); $updateStmt->bindParam(':value', $convertedValue); $updateStmt->bindParam(':param', $param); $updateStmt->execute(); echo json_encode([ "success" => true, "message" => "Configuration updated successfully", "param" => $param, "value" => $convertedValue, "type" => $type ]); } else { echo json_encode([ "error" => "Parameter not found in configuration", "param" => $param ]); } } catch (PDOException $e) { echo json_encode(["error" => $e->getMessage()]); } } //UPDATING the config_scripts table from SQLite DB if ($type == "update_config_scripts_sqlite") { $script_path = $_GET['param'] ?? null; $enabled = $_GET['value'] ?? null; if ($script_path === null || $enabled === null) { echo json_encode(["error" => "Missing parameter or value"]); exit; } try { $db = new PDO("sqlite:$database_path"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // First, check if parameter exists and get its type $checkStmt = $db->prepare("SELECT enabled FROM config_scripts_table WHERE script_path = :script_path"); $checkStmt->bindParam(':script_path', $script_path); $checkStmt->execute(); $result = $checkStmt->fetch(PDO::FETCH_ASSOC); if ($result) { // Convert enabled value to 0 or 1 $enabledValue = (filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) ? 1 : 0; // Update the enabled status $updateStmt = $db->prepare("UPDATE config_scripts_table SET enabled = :enabled WHERE script_path = :script_path"); $updateStmt->bindParam(':enabled', $enabledValue, PDO::PARAM_INT); $updateStmt->bindParam(':script_path', $script_path); $updateStmt->execute(); echo json_encode([ "success" => true, "message" => "Script configuration updated successfully", "script_path" => $script_path, "enabled" => (bool)$enabledValue ], JSON_UNESCAPED_SLASHES); // Prevent escaping forward slashes } else { echo json_encode([ "error" => "Script path not found in configuration", "script_path" => $script_path ], JSON_UNESCAPED_SLASHES); // Prevent escaping forward slashes } } catch (PDOException $e) { echo json_encode(["error" => $e->getMessage()]); } } //UPDATING the envea_sondes_table table from SQLite DB if ($type == "update_sonde") { $id = $_GET['id'] ?? null; $field = $_GET['field'] ?? null; $value = $_GET['value'] ?? null; // Validate parameters if ($id === null || $field === null || $value === null) { echo json_encode([ "success" => false, "error" => "Missing required parameters (id, field, or value)" ]); exit; } // Validate field name (whitelist approach for security) $allowed_fields = ['connected', 'port', 'name', 'coefficient']; if (!in_array($field, $allowed_fields)) { echo json_encode([ "success" => false, "error" => "Invalid field name: " . $field ]); exit; } try { // Connect to the database $db = new PDO("sqlite:$database_path"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Check if the sonde exists $checkStmt = $db->prepare("SELECT id FROM envea_sondes_table WHERE id = :id"); $checkStmt->bindParam(':id', $id, PDO::PARAM_INT); $checkStmt->execute(); if (!$checkStmt->fetch()) { echo json_encode([ "success" => false, "error" => "Sonde with ID $id not found" ]); exit; } // Process value based on field type if ($field == 'connected') { // Convert to integer (0 or 1) $processedValue = filter_var($value, FILTER_VALIDATE_BOOLEAN) ? 1 : 0; $paramType = PDO::PARAM_INT; } else if ($field == 'coefficient') { // Convert to float $processedValue = floatval($value); $paramType = PDO::PARAM_STR; // SQLite doesn't have PARAM_FLOAT } else { // For text fields (port, name) $processedValue = $value; $paramType = PDO::PARAM_STR; } // Update the sonde record $updateStmt = $db->prepare("UPDATE envea_sondes_table SET $field = :value WHERE id = :id"); $updateStmt->bindParam(':value', $processedValue, $paramType); $updateStmt->bindParam(':id', $id, PDO::PARAM_INT); $updateStmt->execute(); // Return success response echo json_encode([ "success" => true, "message" => "Sonde $id updated successfully", "field" => $field, "value" => $processedValue ]); } catch (PDOException $e) { // Return error as JSON echo json_encode([ "success" => false, "error" => "Database error: " . $e->getMessage() ]); } } //update the config (old JSON updating) if ($type == "update_config") { echo "updating.... "; $param=$_GET['param']; $value=$_GET['value']; $configFile = '../config.json'; // Convert value to boolean, integer, or string if ($value === "true") { $value = true; // Convert "true" string to boolean true } elseif ($value === "false") { $value = false; // Convert "false" string to boolean false } elseif (is_numeric($value)) { $value = $value + 0; // Convert numeric strings to int or float } $configData = json_decode(file_get_contents($configFile), true); $configData[$param] = $value; file_put_contents($configFile, json_encode($configData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); echo "Config updated!"; } if ($type == "getModem_busy") { $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/check_running.py'; $output = shell_exec($command); echo $output; } if ($type == "RTC_time") { $time = shell_exec("date '+%d/%m/%Y %H:%M:%S'"); echo $time; } if ($type == "sys_RTC_module_time") { $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/RTC/read.py'; $output = shell_exec($command); echo $output; } if ($type == "sara_ping") { $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_ping.py'; $output = shell_exec($command); echo $output; } if ($type == "git_pull") { $command = 'sudo git pull'; $output = shell_exec($command); echo $output; } if ($type == "set_RTC_withNTP") { $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/RTC/set_with_NTP.py'; $output = shell_exec($command); echo $output; } if ($type == "set_RTC_withBrowser") { $time = $_GET['time']; // Validate time format if (!strtotime($time)) { echo json_encode(['success' => false, 'message' => 'Invalid time format']); exit; } // Convert to RTC-compatible format (e.g., 'YYYY-MM-DD HH:MM:SS') $rtc_time = date('Y-m-d H:i:s', strtotime($time)); // Execute Python script to update the RTC $command = escapeshellcmd("sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/RTC/set_with_browserTime.py '$rtc_time'"); $output = shell_exec($command); if ($output === null) { echo json_encode(['success' => false, 'message' => 'Failed to update RTC']); } else { echo json_encode(['success' => true, 'message' => 'RTC updated successfully']); } } if ($type == "clear_loopLogs") { $command = 'truncate -s 0 /var/www/nebuleair_pro_4g/logs/loop.log'; $output = shell_exec($command); echo $output; } if ($type == "database_size") { // Path to the SQLite database file $databasePath = '/var/www/nebuleair_pro_4g/sqlite/sensors.db'; // Check if the file exists if (file_exists($databasePath)) { try { // Connect to the SQLite database $db = new PDO("sqlite:$databasePath"); // Get the file size in bytes $fileSizeBytes = filesize($databasePath); // Convert the file size to human-readable formats $fileSizeKilobytes = $fileSizeBytes / 1024; // KB $fileSizeMegabytes = $fileSizeKilobytes / 1024; // MB // Prepare the JSON response $data = [ 'path' => $databasePath, 'size_bytes' => $fileSizeBytes, 'size_kilobytes' => round($fileSizeKilobytes, 2), 'size_megabytes' => round($fileSizeMegabytes, 2), ]; // Output the JSON response echo json_encode($data, JSON_PRETTY_PRINT); } catch (PDOException $e) { // Handle database connection errors echo json_encode([ 'error' => 'Database query failed: ' . $e->getMessage() ]); } } else { // Handle error if the file doesn't exist echo json_encode([ 'error' => 'Database file not found', 'path' => $databasePath ]); } } if ($type == "linux_disk") { $command = 'df -h /'; $output = shell_exec($command); echo $output; } if ($type == "linux_memory") { $command = 'free -h'; $output = shell_exec($command); echo $output; } if ($type == "sshTunnel") { $ssh_port=$_GET['ssh_port']; $command = 'sudo ssh -i /var/www/.ssh/id_rsa -f -N -R "'.$ssh_port.':localhost:22" -p 50221 -o StrictHostKeyChecking=no "airlab_server1@aircarto.fr"'; $output = shell_exec($command); echo $output; } if ($type == "reboot") { $command = 'sudo reboot'; $output = shell_exec($command); } if ($type == "npm") { $port=$_GET['port']; $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/NPM/get_data.py ' . $port; $output = shell_exec($command); echo $output; } if ($type == "envea") { $port=$_GET['port']; $name=$_GET['name']; $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/envea/read_value.py ' . $port; $output = shell_exec($command); echo $output; } if ($type == "noise") { $command = '/var/www/nebuleair_pro_4g/sound_meter/sound_meter'; $output = shell_exec($command); echo $output; } if ($type == "BME280") { $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/BME280/read.py'; $output = shell_exec($command); echo $output; } if ($type == "table_mesure") { $table=$_GET['table']; $limit=$_GET['limit']; $download=$_GET['download']; if ($download==="false") { $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/sqlite/read.py '.$table.' '.$limit; $output = shell_exec($command); echo $output; } else{ $start_date=$_GET['start_date']; $end_date=$_GET['end_date']; $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/sqlite/read_select_date.py '.$table.' '.$start_date.' '.$end_date; $output = shell_exec($command); echo $output; } } # SARA R4 COMMANDS if ($type == "sara") { $port=$_GET['port']; $sara_command=$_GET['command']; $sara_command = escapeshellcmd($sara_command); $timeout=$_GET['timeout']; $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara.py ' . $port . ' ' . $sara_command . ' ' . $timeout; $output = shell_exec($command); echo $output; } # SARA R4 COMMANDS (MQTT) if ($type == "sara_getMQTT_config") { $port=$_GET['port']; $timeout=$_GET['timeout']; $command = '/usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/MQTT/get_config.py ' . $port . ' ' . $timeout; $output = shell_exec($command); echo $output; } # SARA R4 COMMANDS (MQTT) if ($type == "sara_getMQTT_login_logout") { $port=$_GET['port']; $timeout=$_GET['timeout']; $login_logout=$_GET['login_logout']; $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/MQTT/login_logout.py ' . $port . ' ' . $login_logout . ' ' . $timeout; $output = shell_exec($command); echo $output; } # SARA R4 COMMANDS (MQTT -> publish) if ($type == "sara_MQTT_publish") { $port=$_GET['port']; $timeout=$_GET['timeout']; $message=$_GET['message']; $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/MQTT/publish.py ' . $port . ' ' . $message . ' ' . $timeout; $output = shell_exec($command); echo $output; } #Connect to network if ($type == "sara_connectNetwork") { $port=$_GET['port']; $timeout=$_GET['timeout']; $networkID=$_GET['networkID']; //echo "updating SARA_R4_networkID in config file"; // Convert `networkID` to an integer (or float if needed) $networkID = is_numeric($networkID) ? (strpos($networkID, '.') !== false ? (float)$networkID : (int)$networkID) : 0; #save to config.json $configFile = '/var/www/nebuleair_pro_4g/config.json'; // Read the JSON file $jsonData = file_get_contents($configFile); // Decode JSON data into an associative array $config = json_decode($jsonData, true); // Check if decoding was successful if ($config === null) { die("Error: Could not decode JSON file."); } // Update the value of SARA_R4_networkID $config['SARA_R4_neworkID'] = $networkID; // Replace 42 with the desired value // Encode the array back to JSON with pretty printing $newJsonData = json_encode($config, JSON_PRETTY_PRINT); // Check if encoding was successful if ($newJsonData === false) { die("Error: Could not encode JSON data."); } // Write the updated JSON back to the file if (file_put_contents($configFile, $newJsonData) === false) { die("Error: Could not write to JSON file."); } //echo "SARA_R4_networkID updated successfully."; //echo "connecting to network... please wait..."; $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_connectNetwork.py ' . $port . ' ' . $networkID . ' ' . $timeout; $output = shell_exec($command); echo $output; } #SET THE URL for messaging (profile id 2) if ($type == "sara_setURL") { $port=$_GET['port']; $url=$_GET['url']; $profile_id = 2; $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_setURL.py ' . $port . ' ' . $url . ' ' . $profile_id; $output = shell_exec($command); echo $output; } #SET APN if ($type == "sara_APN") { $port=$_GET['port']; $timeout=$_GET['timeout']; $APN_address=$_GET['APN_address']; $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_setAPN.py ' . $port . ' ' . $APN_address . ' ' . $timeout; $output = shell_exec($command); echo $output; } #TO WRITE MESSAGE TO MEMORY if ($type == "sara_writeMessage") { $port=$_GET['port']; $message=$_GET['message']; $message = escapeshellcmd($message); $type2=$_GET['type2']; if ($type2 === "write") { $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_writeMessage.py ' . $port . ' ' . $message; $output = shell_exec($command); } if ($type2 === "read") { $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_readMessage.py ' . $port . ' ' . $message; $output = shell_exec($command); } if ($type2 === "erase") { $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_eraseMessage.py ' . $port . ' ' . $message; $output = shell_exec($command); } echo $output; } #Send the typed message to server (for ntfy notification) if ($type == "sara_sendMessage") { $port=$_GET['port']; $endpoint=$_GET['endpoint']; $endpoint = escapeshellcmd($endpoint); $profile_id = 2; $command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_sendMessage.py ' . $port . ' ' . $endpoint. ' ' . $profile_id; $output = shell_exec($command); echo $output; } if ($type == "internet") { //eth0 $command = 'nmcli -g GENERAL.STATE device show eth0'; $eth0_connStatus = shell_exec($command); $eth0_connStatus = str_replace("\n", "", $eth0_connStatus); $command = 'nmcli -g IP4.ADDRESS device show eth0'; $eth0_IPAddr = shell_exec($command); $eth0_IPAddr = str_replace("\n", "", $eth0_IPAddr); //wlan0 $command = 'nmcli -g GENERAL.STATE device show wlan0'; $wlan0_connStatus = shell_exec($command); $wlan0_connStatus = str_replace("\n", "", $wlan0_connStatus); $command = 'nmcli -g IP4.ADDRESS device show wlan0'; $wlan0_IPAddr = shell_exec($command); $wlan0_IPAddr = str_replace("\n", "", $wlan0_IPAddr); $data= array( "ethernet" => array( "connection" => $eth0_connStatus, "IP" => $eth0_IPAddr ), "wifi" => array( "connection" => $wlan0_connStatus, "IP" => $wlan0_IPAddr ) ); $json_data = json_encode($data); echo $json_data; } # IMPORTANT # c'est ici que la connexion vers le WIFI du client s'effectue. if ($type == "wifi_connect") { $SSID=$_GET['SSID']; $PASS=$_GET['pass']; echo "will try to connect to
"; echo "SSID: " . $SSID; echo "
"; echo "Password: " . $PASS; echo "
"; echo "
"; echo "You will be disconnected. If connection is successfull you can find the device on your local network."; $script_path = '/var/www/nebuleair_pro_4g/connexion.sh'; $log_file = '/var/www/nebuleair_pro_4g/logs/app.log'; shell_exec("$script_path $SSID $PASS >> $log_file 2>&1 &"); #$output = shell_exec('sudo nmcli connection down Hotspot'); #$output2 = shell_exec('sudo nmcli device wifi connect "AirLab" password "123plouf"'); } if ($type == "wifi_scan") { // Set the path to your CSV file $csvFile = '/var/www/nebuleair_pro_4g/wifi_list.csv'; // Initialize an array to hold the JSON data $jsonData = []; // Open the CSV file for reading if (($handle = fopen($csvFile, 'r')) !== false) { // Get the headers from the first row $headers = fgetcsv($handle); // Loop through the rest of the rows while (($row = fgetcsv($handle)) !== false) { // Combine headers with row data to create an associative array $jsonData[] = array_combine($headers, $row); } // Close the file handle fclose($handle); } // Set the content type to JSON header('Content-Type: application/json'); // Convert the array to JSON format and output it echo json_encode($jsonData, JSON_PRETTY_PRINT); } if ($type == "wifi_scan_old") { $output = shell_exec('nmcli device wifi list ifname wlan0'); // Split the output into lines $lines = explode("\n", trim($output)); // Initialize an array to hold the results $wifiNetworks = []; // Loop through each line and extract the relevant information foreach ($lines as $index => $line) { // Skip the header line if ($index === 0) { continue; } // Split the line by whitespace and filter empty values $columns = preg_split('/\s+/', $line); // If the line has enough columns, store the relevant data if (count($columns) >= 5) { $wifiNetworks[] = [ 'SSID' => $columns[2], // Network name 'BARS' => $columns[8], 'SIGNAL' => $columns[7], // Signal strength ]; } } $json_data = json_encode($wifiNetworks); echo $json_data; }