mirror of
https://github.com/wavelog/wavelog
synced 2026-08-13 18:41:16 -04:00
204 lines
5.9 KiB
PHP
204 lines
5.9 KiB
PHP
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
|
|
|
class Amsatstatus extends CI_Controller {
|
|
|
|
function __construct() {
|
|
parent::__construct();
|
|
|
|
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); }
|
|
}
|
|
|
|
public function index() {
|
|
$this->load->driver('cache', [
|
|
'adapter' => $this->config->item('cache_adapter') ?? 'file',
|
|
'backup' => $this->config->item('cache_backup') ?? 'file',
|
|
'key_prefix' => $this->config->item('cache_key_prefix') ?? ''
|
|
]);
|
|
|
|
$cache_key = 'amsatstatus_reports_24h';
|
|
$json = $this->cache->get($cache_key);
|
|
|
|
if ($json === false) {
|
|
$url = 'https://www.amsat.org/status/api/v1/reports.php?hours=24&limit=500';
|
|
$ctx = stream_context_create(['http' => [
|
|
'method' => 'GET',
|
|
'timeout' => 15,
|
|
'user_agent' => 'Wavelog/'.$this->optionslib->get_option('version')
|
|
]]);
|
|
$fetched = @file_get_contents($url, false, $ctx);
|
|
if ($fetched === false) {
|
|
$this->session->set_flashdata('message', __("The AMSAT status service is currently unavailable. Please try again later."));
|
|
$data['matrix'] = [];
|
|
$data['sat_order'] = [];
|
|
$data['display_names'] = [];
|
|
$data['wl_link'] = [];
|
|
$data['next_pass'] = [];
|
|
$data['now'] = time();
|
|
$data['page_title'] = __("AMSAT Satellite Status");
|
|
$this->load->view('interface_assets/header', $data);
|
|
$this->load->view('/amsatstatus/index', $data);
|
|
$this->load->view('interface_assets/footer', []);
|
|
return;
|
|
}
|
|
$this->cache->save($cache_key, $fetched, 60*15);
|
|
$json = $fetched;
|
|
}
|
|
|
|
$decoded = json_decode($json, true);
|
|
$reports = $decoded['data'] ?? [];
|
|
|
|
$status_priority = [
|
|
'Heard' => 1,
|
|
'Crew Active' => 2,
|
|
'Telemetry Only' => 3,
|
|
'Not Heard' => 4,
|
|
];
|
|
|
|
$now = time();
|
|
$buckets = [];
|
|
$sat_latest = [];
|
|
$display_names = [];
|
|
|
|
foreach ($reports as $r) {
|
|
$name = $r['name'] ?? '';
|
|
if ($name === '') continue;
|
|
if (!empty($r['satellite_display_name'])) {
|
|
$display_names[$name] = $r['satellite_display_name'];
|
|
} elseif (!isset($display_names[$name])) {
|
|
$display_names[$name] = $name;
|
|
}
|
|
|
|
$epoch = strtotime($r['reported_time'] ?? '');
|
|
if ($epoch === false) continue;
|
|
$age_h = (int)floor(($now - $epoch) / 3600);
|
|
if ($age_h < 0 || $age_h > 23) continue;
|
|
|
|
$col = $age_h;
|
|
$status = $r['report'] ?? '';
|
|
$callsign = $r['callsign'] ?? '';
|
|
$grid = $r['grid_square'] ?? '';
|
|
|
|
if (!isset($buckets[$name][$col])) {
|
|
$buckets[$name][$col] = [
|
|
'counts' => [],
|
|
'reporters' => [],
|
|
'winning' => $status,
|
|
'winning_priority' => $status_priority[$status] ?? 99,
|
|
'total' => 0,
|
|
'latest_epoch' => $epoch,
|
|
'latest_callsign' => $callsign,
|
|
'latest_grid' => $grid,
|
|
];
|
|
}
|
|
$cell =& $buckets[$name][$col];
|
|
$cell['counts'][$status] = ($cell['counts'][$status] ?? 0) + 1;
|
|
$cell['total']++;
|
|
$cell['reporters'][] = ['epoch' => $epoch, 'callsign' => $callsign, 'grid' => $grid, 'status' => $status];
|
|
|
|
$p = $status_priority[$status] ?? 99;
|
|
if ($p < $cell['winning_priority']) {
|
|
$cell['winning'] = $status;
|
|
$cell['winning_priority'] = $p;
|
|
}
|
|
if ($epoch > $cell['latest_epoch']) {
|
|
$cell['latest_epoch'] = $epoch;
|
|
$cell['latest_callsign'] = $callsign;
|
|
$cell['latest_grid'] = $grid;
|
|
}
|
|
unset($cell);
|
|
|
|
if (!isset($sat_latest[$name]) || $epoch > $sat_latest[$name]) {
|
|
$sat_latest[$name] = $epoch;
|
|
}
|
|
}
|
|
|
|
foreach ($buckets as $name => &$cells) {
|
|
foreach ($cells as &$cell) {
|
|
usort($cell['reporters'], function($a, $b) { return $b['epoch'] - $a['epoch']; });
|
|
}
|
|
unset($cell);
|
|
}
|
|
unset($cells);
|
|
|
|
$sat_order = array_keys($sat_latest);
|
|
usort($sat_order, fn($a, $b) => strnatcasecmp($display_names[$a] ?? $a, $display_names[$b] ?? $b));
|
|
|
|
$matrix = [];
|
|
foreach ($buckets as $name => $cells) {
|
|
$row = [];
|
|
for ($col = 0; $col < 24; $col++) {
|
|
$row[$col] = $cells[$col] ?? null;
|
|
}
|
|
$matrix[$name] = $row;
|
|
}
|
|
|
|
$this->load->model('satellite_model');
|
|
$this->load->model('stations');
|
|
$this->load->library('satpredict');
|
|
|
|
$wl_map = [];
|
|
foreach ($this->satellite_model->get_all_satellites_with_tle() as $wl) {
|
|
$base = $wl->satname ?: ($wl->displayname ?? '');
|
|
if ($base === '') continue;
|
|
$key = strtoupper(trim(preg_replace('/[\[_].*/', '', $base)));
|
|
if ($key !== '' && !isset($wl_map[$key])) {
|
|
$wl_map[$key] = $wl;
|
|
}
|
|
}
|
|
|
|
$grid = $this->stations->find_gridsquare();
|
|
$have_grid = ($grid && strtoupper((string)$grid) !== '0');
|
|
|
|
$alias = [
|
|
'ISS' => 'ARISS',
|
|
'SONATE-2' => 'SONATE',
|
|
];
|
|
$prefix_alias = [
|
|
'TEVEL2-' => 'TEV2-',
|
|
];
|
|
|
|
$wl_link = [];
|
|
$next_pass = [];
|
|
foreach ($sat_order as $name) {
|
|
$key = strtoupper(trim(preg_replace('/[\[_].*/', '', $name)));
|
|
if (isset($alias[$key])) {
|
|
$key = $alias[$key];
|
|
} else {
|
|
foreach ($prefix_alias as $from => $to) {
|
|
if (str_starts_with($key, $from)) {
|
|
$key = $to . substr($key, strlen($from));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
$wl = $wl_map[$key] ?? null;
|
|
if (!$wl) continue;
|
|
$wl_link[$name] = $wl->satname ?: $wl->displayname;
|
|
if ($have_grid) {
|
|
$pass = $this->satpredict->next_pass($wl, $grid, 0, 1);
|
|
if ($pass) {
|
|
$next_pass[$name] = [
|
|
'aos' => (float) $pass->aos,
|
|
'time' => Predict_Time::daynum2readable($pass->aos, 'UTC', 'H:i'),
|
|
'maxel' => isset($pass->max_el) ? (int)round($pass->max_el) : null,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
$data['matrix'] = $matrix;
|
|
$data['sat_order'] = $sat_order;
|
|
$data['display_names'] = $display_names;
|
|
$data['wl_link'] = $wl_link;
|
|
$data['next_pass'] = $next_pass;
|
|
$data['now'] = $now;
|
|
$data['page_title'] = __("AMSAT Satellite Status");
|
|
|
|
$footerData = [];
|
|
$footerData['scripts'] = ['assets/js/sections/amsatstatus.js'];
|
|
|
|
$this->load->view('interface_assets/header', $data);
|
|
$this->load->view('/amsatstatus/index', $data);
|
|
$this->load->view('interface_assets/footer', $footerData);
|
|
}
|
|
}
|