M7350 Device Status Monitor

✓ Auto-running status check on page load...
'authenticator', 'action' => 0]); $ch = curl_init("http://{$host}/cgi-bin/auth_cgi"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $nonceData, CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded; charset=UTF-8'], CURLOPT_TIMEOUT => 10, ]); $response = curl_exec($ch); if (curl_errno($ch)) { throw new Exception("Connection failed: " . curl_error($ch)); } curl_close($ch); $nonceResult = json_decode($response, true); if (!$nonceResult || !isset($nonceResult['nonce'])) { throw new Exception("Failed to get nonce from router."); } $nonce = $nonceResult['nonce']; $n_out = htmlspecialchars($nonce); // Step 2: Calculate digest and get token $digest = md5($password . ':' . $nonce); $loginData = json_encode([ 'module' => 'authenticator', 'action' => 1, 'digest' => $digest ]); $ch = curl_init("http://{$host}/cgi-bin/auth_cgi"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $loginData, CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded; charset=UTF-8'], CURLOPT_TIMEOUT => 10, ]); $response = curl_exec($ch); if (curl_errno($ch)) { throw new Exception("Login failed: " . curl_error($ch)); } curl_close($ch); $loginResult = json_decode($response, true); if (!$loginResult || !isset($loginResult['token'])) { throw new Exception("Login Failed - check password.txt content."); } $token = $loginResult['token']; $t_out = htmlspecialchars($token); // Step 3: Fetch device status $status = "Fetching device status..."; $deviceData = json_encode([ 'token' => $token, 'module' => 'status', 'action' => 0 ]); $ch = curl_init("http://{$host}/cgi-bin/web_cgi"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $deviceData, CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded; charset=UTF-8'], CURLOPT_TIMEOUT => 10, ]); $rawData = curl_exec($ch); if (curl_errno($ch)) { throw new Exception("Failed to fetch status: " . curl_error($ch)); } curl_close($ch); // Parse the raw data $debugHtml = '
Raw response: ' . htmlspecialchars($rawData) . '
'; // Clean and parse the data (same logic as JS version) $cleanedData = preg_replace('/["{}]/', '', $rawData); // Remove quotes and braces $cleanedData = str_replace("\t", ' ', $cleanedData); // Replace tabs with spaces $lines = explode(',', $cleanedData); // Split by commas $data = []; foreach ($lines as $line) { $parts = explode(':', $line, 2); if (count($parts) >= 2) { $key = trim($parts[0]); $value = trim($parts[1]); $data[$key] = $value; } } if (!empty($data)) { $model = $data['model'] ?? "Unknown"; $ip = $data['ipv4'] ?? "N/A"; $battery = $data['voltage'] ?? "0"; $sdStatus = isset($data['status']) && $data['status'] == "1" ? "Ready" : "Empty/Not Found"; $totalKB = isset($data['volume']) ? (float)$data['volume'] : 0; $usedKB = isset($data['used']) ? (float)$data['used'] : 0; $leftKB = isset($data['left']) ? (float)$data['left'] : 0; $totalGB = $totalKB / 1048576; $usedGB = $usedKB / 1048576; $freeGB = $leftKB / 1048576; $usedPercentage = $totalGB > 0 ? ($usedGB / $totalGB) * 100 : 0; $statusHtml = '
=== DEVICE: ' . htmlspecialchars($model) . ' ===
IP Address: ' . htmlspecialchars($ip) . '
Battery: ' . htmlspecialchars($battery) . '%
'; if ($totalGB > 0) { $statusHtml .= '
SD Card Status: ' . htmlspecialchars($sdStatus) . '
Total Size: ' . number_format($totalGB, 2) . ' GB
Used Space: ' . number_format($usedGB, 2) . ' GB (' . number_format($usedPercentage, 1) . '%)
Free Space: ' . number_format($freeGB, 2) . ' GB
'; } else { $statusHtml .= '
SD Card: Not Found or Unmounted
'; } $statusHtml .= '
'; $output = $statusHtml . $debugHtml . '
Done.
'; $status = "✓ Status fetched successfully"; } else { $status = "No status data received or parsing failed"; $output = $debugHtml; } } catch (Exception $e) { $status = "Error: " . $e->getMessage(); $output = '
' . htmlspecialchars($e->getMessage()) . '
'; } ?>
Reading credentials from password.txt...
Nonce: | Token: