From 486527ed15c40c9f3bebc688ced685ddbdaecc4b Mon Sep 17 00:00:00 2001 From: Andreas Kristiansen <6977712+AndreasK79@users.noreply.github.com> Date: Mon, 9 Dec 2024 09:39:23 +0100 Subject: [PATCH] [Sat Sked] Can now predict sat skeds --- application/controllers/Satellite.php | 108 +++++++++++++++++++--- application/views/satellite/pass.php | 43 ++++++++- application/views/satellite/skedtable.php | 102 ++++++++++++++++++++ assets/js/sections/satpasses.js | 53 ++++++++++- 4 files changed, 287 insertions(+), 19 deletions(-) create mode 100644 application/views/satellite/skedtable.php diff --git a/application/controllers/Satellite.php b/application/controllers/Satellite.php index ab39acb7d..8188a15e5 100644 --- a/application/controllers/Satellite.php +++ b/application/controllers/Satellite.php @@ -234,12 +234,32 @@ class Satellite extends CI_Controller { $this->load->view('interface_assets/footer', $footerData); } - public function searchpasses() { + public function searchPasses() { if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); } try { - $result = $this->get_tle_for_predict(); - $this->calcpass($result); + $tle = $this->get_tle_for_predict(); + $yourgrid = $this->security->xss_clean($this->input->post('yourgrid')); + $altitude = $this->security->xss_clean($this->input->post('altitude')); + $date = $this->security->xss_clean($this->input->post('date')); + $minelevation = $this->security->xss_clean($this->input->post('minelevation')); + $timezone = $this->security->xss_clean($this->input->post('timezone')); + $data = $this->calcPass($tle, $yourgrid, $altitude, $date, $minelevation, $timezone); + + $this->load->view('satellite/passtable', $data); + } + catch (Exception $e) { + header("Content-type: application/json"); + echo json_encode(['ok' => 'Error', 'message' => $e->getMessage() . $e->getCode()]); + } + } + + public function searchSkedPasses() { + if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); } + + try { + $tle = $this->get_tle_for_predict(); + $this->calcSkedPass($tle); } catch (Exception $e) { header("Content-type: application/json"); @@ -255,7 +275,7 @@ class Satellite extends CI_Controller { return $this->satellite_model->get_tle($sat); } - function calcpass($sat_tle) { + function calcPass($sat_tle, $yourgrid, $altitude, $date, $minelevation, $timezone) { if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); } require_once "./src/predict/Predict.php"; @@ -267,9 +287,9 @@ class Satellite extends CI_Controller { // The observer or groundstation is called QTH in ham radio terms $predict = new Predict(); $qth = new Predict_QTH(); - $qth->alt = $this->security->xss_clean($this->input->post('altitude')); // Altitude in meters + $qth->alt = $altitude; // Altitude in meters - $strQRA = $this->security->xss_clean($this->input->post('yourgrid')); + $strQRA = $yourgrid; if ((strlen($strQRA) % 2 == 0) && (strlen($strQRA) <= 10)) { // Check if QRA is EVEN (the % 2 does that) and smaller/equal 8 $strQRA = strtoupper($strQRA); @@ -285,7 +305,7 @@ class Satellite extends CI_Controller { if(!$this->load->is_loaded('Qra')) { $this->load->library('Qra'); } - $homecoordinates = $this->qra->qra2latlong($this->security->xss_clean($this->input->post('yourgrid'))); + $homecoordinates = $this->qra->qra2latlong($yourgrid); $qth->lat = $homecoordinates[0]; $qth->lon = $homecoordinates[1]; @@ -295,11 +315,11 @@ class Satellite extends CI_Controller { $tle = new Predict_TLE($sat_tle->satellite, $temp[0], $temp[1]); // Instantiate it $sat = new Predict_Sat($tle); // Load up the satellite data - $now = $this->get_daynum_from_date($this->security->xss_clean($this->input->post('date'))); // get the current time as Julian Date (daynum) + $now = $this->get_daynum_from_date($date); // get the current time as Julian Date (daynum) // You can modify some preferences in Predict(), the defaults are below // - $predict->minEle = intval($this->security->xss_clean($this->input->post('minelevation'))); // Minimum elevation for a pass + $predict->minEle = intval($minelevation); // Minimum elevation for a pass $predict->timeRes = 1; // Pass details: time resolution in seconds $predict->numEntries = 20; // Pass details: number of entries per pass // $predict->threshold = -6; // Twilight threshold (sun must be at this lat or lower) @@ -308,8 +328,6 @@ class Satellite extends CI_Controller { $results = $predict->get_passes($sat, $qth, $now, 1); $filtered = $predict->filterVisiblePasses($results); - $zone = $this->security->xss_clean($this->input->post('timezone')); - // Get Date format if ($this->session->userdata('user_date_format')) { // If Logged in and session exists @@ -322,9 +340,73 @@ class Satellite extends CI_Controller { $format = $custom_date_format . ' H:i:s'; $data['filtered'] = $filtered; - $data['zone'] = $zone; + $data['zone'] = $timezone; $data['format'] = $format; - $this->load->view('satellite/passtable', $data); + + return $data; + + } + + function calcSkedPass($sat_tle) { + if(!$this->user_model->authorize(3)) { $this->session->set_flashdata('error', __("You're not allowed to do that!")); redirect('dashboard'); } + + $tle = $this->get_tle_for_predict(); + + $yourgrid = $this->security->xss_clean($this->input->post('yourgrid')); + $altitude = $this->security->xss_clean($this->input->post('altitude')); + $date = $this->security->xss_clean($this->input->post('date')); + $minelevation = $this->security->xss_clean($this->input->post('minelevation')); + $timezone = $this->security->xss_clean($this->input->post('timezone')); + + $homePass = $this->calcPass($tle, $yourgrid, $altitude, $date, $minelevation, $timezone); + + $skedgrid = $this->security->xss_clean($this->input->post('skedgrid')); + $minskedelevation = $this->security->xss_clean($this->input->post('minskedelevation')); + + $skedPass = $this->calcPass($tle, $skedgrid, 0, $date, $minskedelevation, $timezone); + + // Get Date format + if ($this->session->userdata('user_date_format')) { + // If Logged in and session exists + $custom_date_format = $this->session->userdata('user_date_format'); + } else { + // Get Default date format from /config/wavelog.php + $custom_date_format = $this->config->item('qso_date_format'); + } + + $data['format'] = $custom_date_format . ' H:i:s'; + + $data['overlaps'] = $this->findOverlaps($homePass, $skedPass); + $data['zone'] = $timezone; + $data['yourgrid'] = $yourgrid; + $data['skedgrid'] = $skedgrid; + + $this->load->view('satellite/skedtable', $data); + } + + function findOverlaps($homePass, $skedPass) { + $overlaps = []; // Store overlapping passes + + foreach ($homePass['filtered'] as $pass1) { + foreach ($skedPass['filtered'] as $pass2) { + if ($this->checkOverlap($pass1, $pass2)) { + $overlaps[] = [ + 'grid1' => $pass1, + 'grid2' => $pass2 + ]; + } + } + } + + return $overlaps; + } + + function checkOverlap($pass1, $pass2) { + // Calculate the overlap condition + $start = max($pass1->visible_aos, $pass2->visible_aos); // Latest start time + $end = min($pass1->visible_los, $pass2->visible_los); // Earliest end time + + return $start <= $end; // True if intervals overlap } public static function get_daynum_from_date($date) { diff --git a/application/views/satellite/pass.php b/application/views/satellite/pass.php index b75814ad1..08e586883 100644 --- a/application/views/satellite/pass.php +++ b/application/views/satellite/pass.php @@ -4,8 +4,11 @@
No overlapping passes found.
"; +} + +echo '| ' . __("Satellite") . ' | +' . __("Date") . ' | +' . __("Sked AOS Time") . ' | +' . __("Sked LOS Time") . ' | +' . __("Duration") . ' | +
|---|---|---|---|---|
| ". $satellite . " | "; + echo ""; + echo " | " . Predict_Time::daynum2readable($skedAOS, $zone, $format) . " | "; + echo "" . Predict_Time::daynum2readable($skedLOS, $zone, $format) . " | "; + echo "" . returntimediff(Predict_Time::daynum2readable($skedAOS, $zone, $format), Predict_Time::daynum2readable($skedLOS, $zone, $format), $format) . " | "; + echo ""; +} + + +function returntimediff($start, $end, $format) { + $datetime1 = DateTime::createFromFormat($format, $end); + $datetime2 = DateTime::createFromFormat($format, $start); + $interval = $datetime1->diff($datetime2); + + $diff = sprintf('%02d', (($interval->h*60)+$interval->i)).':'.sprintf('%02d', $interval->s).' '.__("min"); + + return $diff; +} + +function azDegreesToDirection($az = 0) { + $i = floor($az / 22.5); + $m = (22.5 * (2 * $i + 1)) / 2; + $i = ($az >= $m) ? $i + 1 : $i; + + return trim(substr('N NNENE ENEE ESESE SSES SSWSW WSWW WNWNW NNWN ', $i * 3, 3)); +} diff --git a/assets/js/sections/satpasses.js b/assets/js/sections/satpasses.js index 7515befd1..5e0f12baa 100644 --- a/assets/js/sections/satpasses.js +++ b/assets/js/sections/satpasses.js @@ -1,6 +1,20 @@ function searchpasses() { - $.ajax({ - url: base_url + 'index.php/satellite/searchpasses', + if ($('#addskedpartner').is(':hidden')) { + loadPasses(); + } else { + let skedgrid = $("#skedgrid").val(); + if (skedgrid == '') { + return; + } + loadSkedPasses(); + } + return; + +} + +function loadPasses() { + $.ajax({ + url: base_url + 'index.php/satellite/searchPasses', type: 'post', data: {'sat': $("#satlist").val(), 'yourgrid': $("#yourgrid").val(), @@ -21,3 +35,38 @@ function searchpasses() { } }); } + +function loadSkedPasses() { + $.ajax({ + url: base_url + 'index.php/satellite/searchSkedPasses', + type: 'post', + data: {'sat': $("#satlist").val(), + 'yourgrid': $("#yourgrid").val(), + 'minelevation': $("#minelevation").val(), + 'minazimuth': $("#minazimuth").val(), + 'maxazimuth': $("#maxazimuth").val(), + 'altitude': $("#altitude").val(), + 'timezone': $("#timezone").val(), + 'date': $("#date").val(), + 'mintime': $("#mintime").val(), + 'maxtime': $("#maxtime").val(), + 'skedgrid': $("#skedgrid").val(), + 'minskedelevation': $("#minskedelevation").val(), + }, + success: function (html) { + $("#resultpasses").html(html); + }, + error: function(e) { + modalloading=false; + } + }); +} + +function addskedpartner() { + if ($('#addskedpartner').is(':hidden')) { + $('#addskedpartner').show(); + } else { + $('#addskedpartner').hide(); + } + +}