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 @@
+ + +

Your station

- +
@@ -477,7 +480,7 @@
@@ -485,7 +488,7 @@
@@ -497,9 +500,41 @@ } ?>
+ + - + + + + +
diff --git a/application/views/satellite/skedtable.php b/application/views/satellite/skedtable.php new file mode 100644 index 000000000..2a42ee9c4 --- /dev/null +++ b/application/views/satellite/skedtable.php @@ -0,0 +1,102 @@ +'; + echo ' + + ' . __("Grid") . ' + ' . __("Satellite") . ' + ' . __("AOS Time") . ' + ' . __("Duration") . ' + ' . __("AOS Azimuth") . ' + ' . __("Max Elevation") . ' + ' . __("LOS Time") . ' + ' . __("LOS Azimuth") . ' + + + '; + + foreach ($overlaps as $overlap) { + echo ''; + echo '' . $yourgrid . ''; + echo '' . $overlap['grid1']->satname . ''; + echo '' . Predict_Time::daynum2readable($overlap['grid1']->visible_aos, $zone, $format) . ''; + echo '' . returntimediff(Predict_Time::daynum2readable($overlap['grid1']->visible_aos, $zone, $format), Predict_Time::daynum2readable($overlap['grid1']->visible_los, $zone, $format), $format) . ''; + $aos_az = round($overlap['grid1']->visible_aos_az); + echo '' . $aos_az . ' ° (' . azDegreesToDirection($overlap['grid1']->visible_aos_az) . ')'; + $max_el = round($overlap['grid1']->max_el); + echo '' . $max_el . ' °'; + echo '' . Predict_Time::daynum2readable($overlap['grid1']->visible_los, $zone, $format) . ''; + $los_az = round($overlap['grid1']->visible_los_az); + echo '' . $los_az . ' ° (' . azDegreesToDirection($overlap['grid1']->visible_los_az) . ')'; + echo ''; + + echo ''; + echo '' . $skedgrid . ''; + echo '' . $overlap['grid2']->satname . ''; + echo '' . Predict_Time::daynum2readable($overlap['grid2']->visible_aos, $zone, $format) . ''; + echo '' . returntimediff(Predict_Time::daynum2readable($overlap['grid2']->visible_aos, $zone, $format), Predict_Time::daynum2readable($overlap['grid2']->visible_los, $zone, $format), $format) . ''; + $aos_az = round($overlap['grid2']->visible_aos_az); + echo '' . $aos_az . ' ° (' . azDegreesToDirection($overlap['grid2']->visible_aos_az) . ')'; + $max_el = round($overlap['grid2']->max_el); + echo '' . $max_el . ' °'; + echo '' . Predict_Time::daynum2readable($overlap['grid2']->visible_los, $zone, $format) . ''; + $los_az = round($overlap['grid2']->visible_los_az); + echo '' . $los_az . ' ° (' . azDegreesToDirection($overlap['grid2']->visible_los_az) . ')'; + echo ''; + + echo "---"; // Separator row + } + + echo ""; + echo ""; +} else { + echo "

No overlapping passes found.

"; +} + +echo ''; + echo ' + + + + + + + + + '; + +foreach ($overlaps as $overlap) { + // Example data (replace these with real calculations or data from the arrays) + $satellite = $overlap['grid1']->satname; // Replace with your satellite name + $skedDate = Predict_Time::daynum2readable($overlap['grid1']->visible_aos, $zone, $format); // Example sked date + + $skedAOS = $overlap['grid1']->visible_aos < $overlap['grid2']->visible_aos ? $overlap['grid2']->visible_aos : $overlap['grid1']->visible_aos; + $skedLOS = $overlap['grid1']->visible_los < $overlap['grid2']->visible_los ? $overlap['grid1']->visible_los : $overlap['grid2']->visible_los; + + echo ''; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + 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(); + } + +}
' . __("Satellite") . '' . __("Date") . '' . __("Sked AOS Time") . '' . __("Sked LOS Time") . '' . __("Duration") . '
". $satellite . "" . Predict_Time::daynum2readable($skedAOS, $zone, $format) . "" . Predict_Time::daynum2readable($skedLOS, $zone, $format) . "" . returntimediff(Predict_Time::daynum2readable($skedAOS, $zone, $format), Predict_Time::daynum2readable($skedLOS, $zone, $format), $format) . "