diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5d178aa --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +php-server.log +php-server.err.log +php-server-error.log \ No newline at end of file diff --git a/config/telegram_message_footer.php b/config/telegram_message_footer.php new file mode 100644 index 0000000..16e7287 --- /dev/null +++ b/config/telegram_message_footer.php @@ -0,0 +1,23 @@ +getTimestamp() - $lastEruptionUtc->getTimestamp()); +$elapsedIntervals = (int) floor($elapsedSecondsSinceLastEruption / $eruptionIntervalSeconds); +$nextPossibleEruptionUtc = $lastEruptionUtc->modify('+' . (($elapsedIntervals + 1) * $eruptionIntervalSeconds) . ' seconds'); +$daysUntilNextEruption = ($nextPossibleEruptionUtc->getTimestamp() - $todayUtc->getTimestamp()) / $secondsPerDay; function h(?string $value): string { return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8'); } +function formatGermanDate(?string $value, bool $includeTime = true): string +{ + if ($value === null || trim($value) === '') { + return '—'; + } + + try { + $date = new DateTimeImmutable($value, new DateTimeZone('UTC')); + } catch (Exception) { + return $value; + } + + return $date->format($includeTime ? 'd.m.Y H:i:s' : 'd.m.Y'); +} + $filterRows = $pdo->query(" SELECT `filter_code`, COUNT(*) AS `entry_count` FROM `aavso_tcrb_observations` @@ -182,8 +206,8 @@ foreach ($chartDatasets as $dataset) { $customData[] = [ $point['jd'], - $point['observer_code'] !== '' ? $point['observer_code'] : '—', - $point['magnitude_error'] !== null ? number_format((float) $point['magnitude_error'], 3, '.', '') : '—', + $point['observer_code'] !== '' ? $point['observer_code'] : '—', + $point['magnitude_error'] !== null ? number_format((float) $point['magnitude_error'], 3, '.', '') : '—', ]; } @@ -472,17 +496,21 @@ $plotlyPayload = [ Messpunkte
- - Erster UTC-Zeitpunkt + + Erster Beobachtungszeitpunkt
- - Letzter UTC-Zeitpunkt + + Letzter Beobachtungszeitpunkt
bis Magnitudenbereich
+
+ format('d.m.Y')) ?> + Naechster moeglicher Ausbruch
(in Tagen)
+
diff --git a/public/telegram/broadcast_test.php b/public/telegram/broadcast_test.php index b0856bd..b2357d5 100644 --- a/public/telegram/broadcast_test.php +++ b/public/telegram/broadcast_test.php @@ -14,6 +14,7 @@ require_once __DIR__ . '/../auth_helpers.php'; $config = require __DIR__ . '/../../config/database.php'; $telegramConfig = require __DIR__ . '/../../config/telegram.php'; +require_once __DIR__ . '/../../config/telegram_message_footer.php'; $dsn = sprintf( 'mysql:host=%s;dbname=%s;charset=%s', @@ -217,7 +218,7 @@ function sendTelegramMessage(string $botToken, string $chatId, string $messageTe 'https://api.telegram.org/bot' . $botToken . '/sendMessage', [ 'chat_id' => $chatId, - 'text' => $messageText, + 'text' => appendTelegramServiceFooter($messageText), ] ); diff --git a/public/telegram/webhook.php b/public/telegram/webhook.php index 2998314..56a082b 100644 --- a/public/telegram/webhook.php +++ b/public/telegram/webhook.php @@ -6,6 +6,7 @@ error_reporting(E_ALL); $config = require __DIR__ . '/../../config/database.php'; $telegramConfig = require __DIR__ . '/../../config/telegram.php'; +require_once __DIR__ . '/../../config/telegram_message_footer.php'; $dsn = sprintf( 'mysql:host=%s;dbname=%s;charset=%s', @@ -87,7 +88,7 @@ function telegramSendBotMessage(array $telegramConfig, string $chatId, string $m 'https://api.telegram.org/bot' . $botToken . '/sendMessage', [ 'chat_id' => $chatId, - 'text' => $messageText, + 'text' => appendTelegramServiceFooter($messageText), ] ); } diff --git a/scripts/telegram/telegram_cron.php b/scripts/telegram/telegram_cron.php index 719e74f..4f12c30 100644 --- a/scripts/telegram/telegram_cron.php +++ b/scripts/telegram/telegram_cron.php @@ -22,6 +22,7 @@ $rootDir = dirname(__DIR__, 2); $stateFile = __DIR__ . DIRECTORY_SEPARATOR . 'telegram_cron_state.json'; $dbConfig = require $rootDir . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'database.php'; $telegramConfig = require $rootDir . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'telegram.php'; +require_once $rootDir . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'telegram_message_footer.php'; $dsn = sprintf( 'mysql:host=%s;port=%d;dbname=%s;charset=%s', @@ -492,32 +493,58 @@ function fetchTelegramRecipients(PDO $pdo): array function buildTcrbLatestVMessage(array $observation, DateTimeImmutable $nowBerlin): string { $observedUtc = trim((string) ($observation['observed_at_utc'] ?? '')); - $observedText = $observedUtc !== '' ? $observedUtc . ' UTC' : 'unbekannt'; + $observedText = formatGermanDateTime($observedUtc); $magnitude = formatDecimal($observation['magnitude'] ?? null, 3); $magnitudeError = $observation['magnitude_error'] !== null - ? ' +/- ' . formatDecimal($observation['magnitude_error'], 3) + ? ' ± ' . formatDecimal($observation['magnitude_error'], 3) : ''; $jd = formatDecimal($observation['jd'] ?? null, 6); $observerCode = trim((string) ($observation['observer_code'] ?? '')); + $nextPossibleEruptionDate = calculateNextPossibleTcrbEruptionDate($nowBerlin); $lines = [ - 'SkyView T CrB Update', + 'SkyViews TCrBotti mit dem Update', '', 'Magnitude: ' . $magnitude . $magnitudeError, 'Zeitpunkt: ' . $observedText, 'JD: ' . $jd, + 'Nächster möglicher Ausbruch:', + $nextPossibleEruptionDate, ]; - - if ($observerCode !== '') { - $lines[] = 'Beobachter: ' . $observerCode; - } - - $lines[] = ''; - $lines[] = 'Stand: ' . $nowBerlin->format('d.m.Y H:i') . ' Europe/Berlin'; + return implode("\n", $lines); } +function calculateNextPossibleTcrbEruptionDate(DateTimeImmutable $referenceDate): string +{ + $eruptionIntervalDays = 227.5687; + $lastEruptionUtc = new DateTimeImmutable('1946-02-09 00:00:00', new DateTimeZone('UTC')); + $referenceUtc = $referenceDate->setTimezone(new DateTimeZone('UTC')); + $secondsPerDay = 86400; + $eruptionIntervalSeconds = (int) round($eruptionIntervalDays * $secondsPerDay); + $elapsedSecondsSinceLastEruption = max(0, $referenceUtc->getTimestamp() - $lastEruptionUtc->getTimestamp()); + $elapsedIntervals = (int) floor($elapsedSecondsSinceLastEruption / $eruptionIntervalSeconds); + $nextPossibleEruptionUtc = $lastEruptionUtc->modify('+' . (($elapsedIntervals + 1) * $eruptionIntervalSeconds) . ' seconds'); + + return $nextPossibleEruptionUtc->format('d.m.Y'); +} + +function formatGermanDateTime(?string $value): string +{ + if ($value === null || trim($value) === '') { + return 'unbekannt'; + } + + try { + $date = new DateTimeImmutable($value, new DateTimeZone('UTC')); + } catch (Exception) { + return $value; + } + + return $date->format('d.m.Y H:i:s') . ' UTC'; +} + function buildTcrbVChartSvg(array $observations, array $latestObservation): string { $width = 1200; @@ -1051,7 +1078,7 @@ function telegramSendBotMessage(array $telegramConfig, string $chatId, string $m 'https://api.telegram.org/bot' . $botToken . '/sendMessage', [ 'chat_id' => $chatId, - 'text' => $messageText, + 'text' => appendTelegramServiceFooter($messageText), ] ); @@ -1069,7 +1096,7 @@ function telegramSendBotDocument(array $telegramConfig, string $chatId, string $ 'https://api.telegram.org/bot' . $botToken . '/sendDocument', [ 'chat_id' => $chatId, - 'caption' => $caption, + 'caption' => appendTelegramServiceFooter($caption), ], 'document', $filePath, @@ -1090,7 +1117,7 @@ function telegramSendBotPhoto(array $telegramConfig, string $chatId, string $fil 'https://api.telegram.org/bot' . $botToken . '/sendPhoto', [ 'chat_id' => $chatId, - 'caption' => $caption, + 'caption' => appendTelegramServiceFooter($caption), ], 'photo', $filePath,