<?php
/**
* Solar Flare Monitor Script
* Reads GOES-18 satellite data and generates HTML report
*/
// Configuration
define('JSON_URL', 'https://services.swpc.noaa.gov/json/goes/primary/xray-flares-latest.json');
define('OUTPUT_FILE', '/var/www/html/current_flare.html');
define('STATE_FILE', '/home/hervey/mnnog/solar_flare_state.json');
// Function to fetch JSON data
function fetchFlareData() {
$context = stream_context_create([
'http' => [
'timeout' => 10,
'user_agent' => 'Mozilla/5.0 (Ubuntu; PHP Solar Flare Monitor)'
]
]);
$jsonData = @file_get_contents(JSON_URL, false, $context);
if ($jsonData === false) {
error_log("Failed to fetch solar flare data from " . JSON_URL);
return null;
}
$data = json_decode($jsonData, true);
if (json_last_error() !== JSON_ERROR_NONE) {
error_log("Failed to parse JSON: " . json_last_error_msg());
return null;
}
return $data;
}
// Function to load previous state
function loadState() {
if (!file_exists(STATE_FILE)) {
return ['last_time_tag' => null, 'history' => []];
}
$stateData = @file_get_contents(STATE_FILE);
if ($stateData === false) {
return ['last_time_tag' => null, 'history' => []];
}
$state = json_decode($stateData, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return ['last_time_tag' => null, 'history' => []];
}
return $state;
}
// Function to save state
function saveState($state) {
$jsonState = json_encode($state, JSON_PRETTY_PRINT);
@file_put_contents(STATE_FILE, $jsonState);
}
// Function to generate HTML
function generateHTML($currentClass, $currentTime, $history) {
$html = <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GOES-18 Satellite Current Solar Flare Level</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 40px auto;
padding: 20px;
background-color: #f5f5f5;
}
h1 {
color: #333;
border-bottom: 3px solid #0066cc;
padding-bottom: 10px;
}
.current-reading {
background-color: #e6f2ff;
padding: 20px;
border-radius: 8px;
margin: 30px 0;
font-size: 18px;
border-left: 5px solid #0066cc;
}
.current-value {
font-weight: bold;
color: #0066cc;
font-size: 24px;
}
.history {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.history h2 {
color: #333;
margin-top: 0;
}
ul {
list-style-type: none;
padding-left: 0;
}
li {
padding: 8px 0;
border-bottom: 1px solid #eee;
}
li:last-child {
border-bottom: none;
}
.timestamp {
color: #666;
font-size: 14px;
}
.footer {
margin-top: 30px;
text-align: center;
color: #666;
font-size: 12px;
}
</style>
</head>
<body>
<h1>GOES-18 Satellite Current Solar Flare Level</h1>
<div class="current-reading">
The latest GOES-18 satellite Xray Flare Class level is <span class="current-value">{$currentClass}</span> at <span class="timestamp">{$currentTime} UTC</span>
</div>
<div class="history">
<h2>Historical Readings</h2>
<ul>
HTML;
foreach ($history as $entry) {
$html .= " <li><strong>{$entry['class']}</strong> - <span class=\"timestamp\">{$entry['time']} UTC</span></li>\n";
}
$html .= <<<HTML
</ul>
</div>
<div class="footer">
Last updated: {$currentTime} UTC | Data source: NOAA SWPC
</div>
</body>
</html>
HTML;
return $html;
}
// Main execution
try {
// Fetch current data
$data = fetchFlareData();
if ($data === null || empty($data)) {
error_log("No data retrieved from solar flare service");
exit(1);
}
// Get the first entry (most recent)
$latestEntry = $data[0];
$currentTimeTag = $latestEntry['time_tag'] ?? null;
$currentClass = $latestEntry['current_class'] ?? 'Unknown';
if ($currentTimeTag === null) {
error_log("Missing time_tag in JSON data");
exit(1);
}
// Load previous state
$state = loadState();
// Check if data has changed
if ($state['last_time_tag'] === $currentTimeTag) {
// No change, exit without updating
exit(0);
}
// Data has changed, update history
$newEntry = [
'class' => $currentClass,
'time' => $currentTimeTag
];
// Add new entry to beginning of history
array_unshift($state['history'], $newEntry);
// Keep only last 50 entries
$state['history'] = array_slice($state['history'], 0, 50);
// Update last time tag
$state['last_time_tag'] = $currentTimeTag;
// Generate and save HTML
$html = generateHTML($currentClass, $currentTimeTag, $state['history']);
if (@file_put_contents(OUTPUT_FILE, $html) === false) {
error_log("Failed to write HTML file to " . OUTPUT_FILE);
exit(1);
}
// Save state
saveState($state);
error_log("Successfully updated solar flare data. Current class: {$currentClass}");
} catch (Exception $e) {
error_log("Error in solar flare monitor: " . $e->getMessage());
exit(1);
}
exit(0);