Frost und Schnee Warnung

########################################################
<?php
// frostalarm4.php – 7-Tage Frost- & Schneewarnung mit Open-Meteo API
// Jetzt mit allen 5 Orten inkl. Karlsruhe – 100% kompatibel mit check_warnings.sh

// === SCHWELLENWERTE (direkt hier anpassen!) ===
$FROST_SCHWELLE  = 1.0;   // Frost bei ≤ 1.0 °C
$SCHNEE_SCHWELLE = 1.0;   // Schnee bei ≥ 1.0 cm

// === ORTE – exakt wie im Bash-Script und frostalarm.php ===
$orte = [
   'kitzbuehel' => 'Kitzbühel',
   'ingolstadt' => 'Ingolstadt',
   'muenchen'   => 'München',
   'salzburg'   => 'Salzburg',
   'karlsruhe'  => 'Karlsruhe'    // ← NEU: Karlsruhe hinzugefügt
];

// Koordinaten (werden für API-Abfrage benötigt)
$koordinaten = [
   'kitzbuehel' => ['lat' => 47.4464, 'lon' => 12.3912],
   'ingolstadt' => ['lat' => 48.7665, 'lon' => 11.4258],
   'muenchen'   => ['lat' => 48.1374, 'lon' => 11.5755],
   'salzburg'   => ['lat' => 47.8095, 'lon' => 13.0550],
   'karlsruhe'  => ['lat' => 49.0069, 'lon' =>  8.4037],
];

// === Open-Meteo API abrufen ===
function getWetterData($lat, $lon) {
          "latitude=$lat&longitude=$lon" .
          "&daily=temperature_2m_min,snowfall_sum" .
          "&forecast_days=7&timezone=Europe/Berlin";
 
   $context = stream_context_create(['http' => ['timeout' => 12]]);
   $data = @file_get_contents($url, false, $context);
   if ($data === false) return null;
 
   $json = json_decode($data, true);
   return json_last_error() === JSON_ERROR_NONE ? $json : null;
}

// === Warnungsklasse bestimmen ===
function getWarnung($temp, $schneeCm, $frostSchwelle, $schneeSchwelle) {
   if ($temp <= $frostSchwelle && $schneeCm >= $schneeSchwelle) return ['beides', 'Frost + Schnee'];
   if ($temp <= $frostSchwelle) return ['frost', 'Frost'];
   if ($schneeCm >= $schneeSchwelle) return ['schnee', 'Schnee'];
   return ['no-warning', '—'];
}

// Ortsliste für Überschrift
$orte_liste = implode(' · ', array_values($orte));
?>

<!DOCTYPE html>
<html lang="de">
<head>
 <meta charset="UTF-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
 <title>Frost- & Schneewarnung: 7-Tage-Vorhersage</title>
 <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate, max-age=0">
 <meta http-equiv="Pragma" content="no-cache">
 <meta http-equiv="Expires" content="0">
 <style>
   body {
     font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
     max-width: 1000px;
     margin: 40px auto;
     padding: 20px;
     background: #f8fafc;
     color: #1e293b;
     line-height: 1.6;
   }
   h1 {
     text-align: center;
     color: #1e40af;
     margin-bottom: 10px;
     font-size: 2.2em;
   }
   .subtitle {
     text-align: center;
     font-size: 1.15em;
     color: #475569;
     margin-bottom: 35px;
     padding: 16px;
     background: #f1f5f9;
     border-radius: 12px;
     box-shadow: 0 2px 8px rgba(0,0,0,0.08);
   }
   .subtitle strong { color: #1e40af; font-weight: 600; }
   .warning-table {
     width: 100%;
     border-collapse: separate;
     border-spacing: 0;
     margin-top: 20px;
     background: white;
     box-shadow: 0 8px 25px rgba(0,0,0,0.1);
     border-radius: 12px;
     overflow: hidden;
     font-size: 0.98em;
   }
   .warning-table th {
     background: #1e40af;
     color: white;
     padding: 16px 14px;
     text-align: center;
     font-weight: 600;
     font-size: 1.05em;
   }
   .warning-table td {
     padding: 14px;
     text-align: center;
     border-bottom: 1px solid #e2e8f0;
   }
   .warning-table tr:last-child td { border-bottom: none; }
   .warning-table td:first-child {
     font-weight: bold;
     background: #f8fafc;
     text-align: left;
     padding-left: 20px;
   }
   .frost   { background: #dbeafe !important; color: #1e40af !important; font-weight: bold; }
   .schnee  { background: #fef3c7 !important; color: #d97706 !important; font-weight: bold; }
   .beides  { background: #fecaca !important; color: #991b1b !important; font-weight: bold; }
   .no-warning { color: #64748b; }
   .footer {
     text-align: center;
     margin-top: 50px;
     font-size: 0.95em;
     color: #94a3b8;
   }
   .footer a {
     color: #1e40af;
     text-decoration: none;
     font-weight: 500;
   }
   .footer a:hover { text-decoration: underline; }
   .update { font-size: 0.9em; color: #64748b; text-align: center; margin-top: 15px; }
   @media (max-width: 800px) {
     .warning-table { font-size: 0.88em; }
     .warning-table th, .warning-table td { padding: 10px 6px; }
     h1 { font-size: 1.8em; }
   }
 </style>
</head>
<body>

 <h1>Frost- & Schneewarnung: 7-Tage</h1>

 <p class="subtitle">
   <strong>Orte:</strong> <?= htmlspecialchars($orte_liste) ?><br>
   <strong>Frost:</strong> ≤ <?= $FROST_SCHWELLE ?> °C ·
   <strong>Schnee:</strong> ≥ <?= $SCHNEE_SCHWELLE ?> cm
 </p>

 <table class="warning-table">
   <thead>
     <tr>
       <th>Ort</th>
       <th>Heute</th>
       <th>Morgen</th>
       <th>Übermorgen</th>
       <th>+3 Tage</th>
       <th>+4 Tage</th>
       <th>+5 Tage</th>
       <th>+6 Tage</th>
     </tr>
   </thead>
   <tbody>
     <?php foreach ($orte as $key => $name):
       $data = getWetterData($koordinaten[$key]['lat'], $koordinaten[$key]['lon']);
       $temps = $data['daily']['temperature_2m_min'] ?? [];
       $schnee = $data['daily']['snowfall_sum'] ?? [];
     ?>
       <tr>
         <td><strong><?= htmlspecialchars($name) ?></strong></td>
         <?php for ($i = 0; $i < 7; $i++):
           $temp = $temps[$i] ?? null;
           $schneeCm = isset($schnee[$i]) ? round($schnee[$i], 1) : null;
           [$klasse, $text] = getWarnung($temp ?? 999, $schneeCm ?? 0, $FROST_SCHWELLE, $SCHNEE_SCHWELLE);
         ?>
           <td class="<?= $klasse ?>">
             <?= $text ?>
             <?php if ($temp !== null && $klasse !== 'no-warning'): ?>
               <br><small><?= number_format($temp, 1) ?>°C / <?= $schneeCm ?> cm</small>
             <?php endif; ?>
           </td>
         <?php endfor; ?>
       </tr>
     <?php endforeach; ?>
   </tbody>
 </table>

 <div class="update">
   Aktualisiert: <?= date('d.m.Y H:i') ?> Uhr · Daten: Open-Meteo API (kostenlos & ohne Key)
 </div>

 <div class="footer">
   <p>
     <a href="https://rebelnews.de/frostalarm.php" target="_blank">Alarm abonnieren</a> •
     <a href="> •
     <a href="https://open-meteo.com" target="_blank">Open-Meteo API</a>
   </p>
 </div>

</body>
</html>

########################################################
<?php
// frostalarm3.php – 7-Tage Frost- & Schneewarnung mit Open-Meteo API
// Jetzt mit allen 5 Orten inkl. Karlsruhe – 100% kompatibel mit check_warnings.sh

// === SCHWELLENWERTE (direkt hier anpassen!) ===
$FROST_SCHWELLE  = 1.0;   // Frost bei ≤ 1.0 °C
$SCHNEE_SCHWELLE = 1.0;   // Schnee bei ≥ 1.0 cm

// === ORTE – exakt wie im Bash-Script und frostalarm.php ===
$orte = [
   'kitzbuehel' => 'Kitzbühel',
   'ingolstadt' => 'Ingolstadt',
   'muenchen'   => 'München',
   'salzburg'   => 'Salzburg',
   'karlsruhe'  => 'Karlsruhe'    // ← NEU: Karlsruhe hinzugefügt
];

// Koordinaten (werden für API-Abfrage benötigt)
$koordinaten = [
   'kitzbuehel' => ['lat' => 47.4464, 'lon' => 12.3912],
   'ingolstadt' => ['lat' => 48.7665, 'lon' => 11.4258],
   'muenchen'   => ['lat' => 48.1374, 'lon' => 11.5755],
   'salzburg'   => ['lat' => 47.8095, 'lon' => 13.0550],
   'karlsruhe'  => ['lat' => 49.0069, 'lon' =>  8.4037],
];

// === Open-Meteo API abrufen ===
function getWetterData($lat, $lon) {
          "latitude=$lat&longitude=$lon" .
          "&daily=temperature_2m_min,snowfall_sum" .
          "&forecast_days=7&timezone=Europe/Berlin";
 
   $context = stream_context_create(['http' => ['timeout' => 12]]);
   $data = @file_get_contents($url, false, $context);
   if ($data === false) return null;
 
   $json = json_decode($data, true);
   return json_last_error() === JSON_ERROR_NONE ? $json : null;
}

// === Warnungsklasse bestimmen ===
function getWarnung($temp, $schneeCm, $frostSchwelle, $schneeSchwelle) {
   if ($temp <= $frostSchwelle && $schneeCm >= $schneeSchwelle) return ['beides', 'Frost + Schnee'];
   if ($temp <= $frostSchwelle) return ['frost', 'Frost'];
   if ($schneeCm >= $schneeSchwelle) return ['schnee', 'Schnee'];
   return ['no-warning', '—'];
}

// Ortsliste für Überschrift
$orte_liste = implode(' · ', array_values($orte));
?>

<!DOCTYPE html>
<html lang="de">
<head>
 <meta charset="UTF-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
 <title>Frost- & Schneewarnung: 7-Tage-Vorhersage</title>
 <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate, max-age=0">
 <meta http-equiv="Pragma" content="no-cache">
 <meta http-equiv="Expires" content="0">
 <style>
   body {
     font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
     max-width: 1000px;
     margin: 40px auto;
     padding: 20px;
     background: #f8fafc;
     color: #1e293b;
     line-height: 1.6;
   }
   h1 {
     text-align: center;
     color: #1e40af;
     margin-bottom: 10px;
     font-size: 2.2em;
   }
   .subtitle {
     text-align: center;
     font-size: 1.15em;
     color: #475569;
     margin-bottom: 35px;
     padding: 16px;
     background: #f1f5f9;
     border-radius: 12px;
     box-shadow: 0 2px 8px rgba(0,0,0,0.08);
   }
   .subtitle strong { color: #1e40af; font-weight: 600; }
   .warning-table {
     width: 100%;
     border-collapse: separate;
     border-spacing: 0;
     margin-top: 20px;
     background: white;
     box-shadow: 0 8px 25px rgba(0,0,0,0.1);
     border-radius: 12px;
     overflow: hidden;
     font-size: 0.98em;
   }
   .warning-table th {
     background: #1e40af;
     color: white;
     padding: 16px 14px;
     text-align: center;
     font-weight: 600;
     font-size: 1.05em;
   }
   .warning-table td {
     padding: 14px;
     text-align: center;
     border-bottom: 1px solid #e2e8f0;
   }
   .warning-table tr:last-child td { border-bottom: none; }
   .warning-table td:first-child {
     font-weight: bold;
     background: #f8fafc;
     text-align: left;
     padding-left: 20px;
   }
   .frost   { background: #dbeafe !important; color: #1e40af !important; font-weight: bold; }
   .schnee  { background: #fef3c7 !important; color: #d97706 !important; font-weight: bold; }
   .beides  { background: #fecaca !important; color: #991b1b !important; font-weight: bold; }
   .no-warning { color: #64748b; }
   .footer {
     text-align: center;
     margin-top: 50px;
     font-size: 0.95em;
     color: #94a3b8;
   }
   .footer a {
     color: #1e40af;
     text-decoration: none;
     font-weight: 500;
   }
   .footer a:hover { text-decoration: underline; }
   .update { font-size: 0.9em; color: #64748b; text-align: center; margin-top: 15px; }
   @media (max-width: 800px) {
     .warning-table { font-size: 0.88em; }
     .warning-table th, .warning-table td { padding: 10px 6px; }
     h1 { font-size: 1.8em; }
   }
 </style>
</head>
<body>

 <h1>Frost- & Schneewarnung: 7-Tage</h1>

 <p class="subtitle">
   <strong>Orte:</strong> <?= htmlspecialchars($orte_liste) ?><br>
   <strong>Frost:</strong> ≤ <?= $FROST_SCHWELLE ?> °C ·
   <strong>Schnee:</strong> ≥ <?= $SCHNEE_SCHWELLE ?> cm
 </p>

 <table class="warning-table">
   <thead>
     <tr>
       <th>Ort</th>
       <th>Heute</th>
       <th>Morgen</th>
       <th>Übermorgen</th>
       <th>+3 Tage</th>
       <th>+4 Tage</th>
       <th>+5 Tage</th>
       <th>+6 Tage</th>
     </tr>
   </thead>
   <tbody>
     <?php foreach ($orte as $key => $name):
       $data = getWetterData($koordinaten[$key]['lat'], $koordinaten[$key]['lon']);
       $temps = $data['daily']['temperature_2m_min'] ?? [];
       $schnee = $data['daily']['snowfall_sum'] ?? [];
     ?>
       <tr>
         <td><strong><?= htmlspecialchars($name) ?></strong></td>
         <?php for ($i = 0; $i < 7; $i++):
           $temp = $temps[$i] ?? null;
           $schneeCm = isset($schnee[$i]) ? round($schnee[$i], 1) : null;
           [$klasse, $text] = getWarnung($temp ?? 999, $schneeCm ?? 0, $FROST_SCHWELLE, $SCHNEE_SCHWELLE);
         ?>
           <td class="<?= $klasse ?>">
             <?= $text ?>
             <?php if ($temp !== null && $klasse !== 'no-warning'): ?>
               <br><small><?= number_format($temp, 1) ?>°C / <?= $schneeCm ?> cm</small>
             <?php endif; ?>
           </td>
         <?php endfor; ?>
       </tr>
     <?php endforeach; ?>
   </tbody>
 </table>

 <div class="update">
   Aktualisiert: <?= date('d.m.Y H:i') ?> Uhr · Daten: Open-Meteo API (kostenlos & ohne Key)
 </div>

 <div class="footer">
   <p>
     <a href="https://rebelnews.de/frostalarm.php" target="_blank">Alarm abonnieren</a> •
     <a href="•
     <a href="https://open-meteo.com" target="_blank">Open-Meteo API</a>
   </p>
 </div>

</body>
</html>

anhängende Datei(en)
frostalarm3.html
404kb