2020-10-18 00:00:01 +02:00
< ? php
if ( ! defined ( 'BASEPATH' )) exit ( 'No direct script access allowed' );
class Timeplotter_model extends CI_Model
{
function getTimes ( $postdata ) {
2026-03-25 12:41:18 +01:00
$logbooks_locations_array = $this -> logbooks_model -> list_logbook_relationships ( $this -> session -> userdata ( 'active_station_logbook' ));
2020-10-18 00:00:01 +02:00
2026-03-18 09:00:48 +01:00
if ( $logbooks_locations_array [ 0 ] === - 1 ) {
2021-11-14 17:20:10 +01:00
header ( 'Content-Type: application/json' );
$data [ 'error' ] = 'No QSOs found to plot!' ;
echo json_encode ( $data );
return ;
}
2026-03-28 19:09:09 +01:00
$this -> db -> select ( 'time(col_time_on) time, col_call as callsign, col_band as band, col_mode as mode' );
2020-10-18 00:00:01 +02:00
if ( $postdata [ 'band' ] != 'All' ) {
2020-12-14 23:22:51 -07:00
if ( $postdata [ 'band' ] == 'SAT' ) {
2020-10-18 00:00:01 +02:00
$this -> db -> where ( 'col_prop_mode' , $postdata [ 'band' ]);
}
else {
$this -> db -> where ( 'col_band' , $postdata [ 'band' ]);
}
}
if ( $postdata [ 'dxcc' ] != 'All' ) {
$this -> db -> where ( 'col_dxcc' , $postdata [ 'dxcc' ]);
}
if ( $postdata [ 'cqzone' ] != 'All' ) {
$this -> db -> where ( 'col_cqz' , $postdata [ 'cqzone' ]);
}
2026-03-25 12:41:18 +01:00
if ( ! empty ( $postdata [ 'mode' ]) && $postdata [ 'mode' ] != 'All' ) {
$this -> db -> where ( 'col_mode' , $postdata [ 'mode' ]);
}
2021-09-10 11:44:05 +02:00
$this -> db -> where_in ( 'station_id' , $logbooks_locations_array );
2026-03-28 19:09:09 +01:00
$this -> db -> order_by ( 'col_band' , 'ASC' );
2020-10-18 00:00:01 +02:00
$datearray = $this -> db -> get ( $this -> config -> item ( 'table_name' ));
$this -> plot ( $datearray -> result_array ());
}
/*
* Function generates the array , checks for array entries , and adds them before returning data ready for plot
*/
function plot ( $log ) {
$start = " 00:00 " ;
$end = " 23:59 " ;
$tStart = strtotime ( $start );
$tEnd = strtotime ( $end );
$tNow = $tStart ;
$i = 0 ;
2026-07-11 16:24:19 +02:00
$dataarray = [];
2020-10-18 00:00:01 +02:00
2026-03-28 19:09:09 +01:00
// Initialize time slots
while ( $tNow <= $tEnd ){
2020-10-18 00:00:01 +02:00
$label = date ( " H:i " , $tNow ) . 'z - ' ;
$tNow = strtotime ( '+30 minutes' , $tNow );
$label .= date ( " H:i " , $tNow ) . 'z' ;
2026-03-28 19:09:09 +01:00
$dataarray [ $i ][ 'time' ] = $label ;
$dataarray [ $i ][ 'count' ] = '0' ;
$dataarray [ $i ][ 'calls' ] = '' ;
$dataarray [ $i ][ 'callcount' ] = '0' ;
2020-10-18 00:00:01 +02:00
$i ++ ;
}
2026-03-28 19:09:09 +01:00
// Organize data by band
$byBand = array ();
$bandCounts = array ();
$modeCounts = array ();
$bandsWithCalls = array ();
foreach ( $log as $line ) {
$time = $line [ 'time' ];
$band = ! empty ( $line [ 'band' ]) ? $line [ 'band' ] : 'Unknown' ;
$mode = ! empty ( $line [ 'mode' ]) ? strtoupper ( $line [ 'mode' ]) : 'Unknown' ;
$callsign = $line [ 'callsign' ];
// Overall aggregation
2020-10-18 00:00:01 +02:00
$dt = new DateTime ( " 1970-01-01 $time " , new DateTimeZone ( 'UTC' ));
2026-03-28 19:09:09 +01:00
$arrayplacement = floor (( int ) $dt -> getTimestamp () / 1800 );
2020-10-18 00:00:01 +02:00
$dataarray [ $arrayplacement ][ 'count' ] ++ ;
$callCount = $dataarray [ $arrayplacement ][ 'callcount' ];
2026-03-28 19:09:09 +01:00
if ( $callCount < 5 ) {
2020-10-18 00:00:01 +02:00
if ( $callCount > 0 ) {
$dataarray [ $arrayplacement ][ 'calls' ] .= ', ' ;
}
2026-03-28 19:09:09 +01:00
$dataarray [ $arrayplacement ][ 'calls' ] .= $callsign ;
2020-10-18 00:00:01 +02:00
$dataarray [ $arrayplacement ][ 'callcount' ] ++ ;
}
2026-03-28 19:09:09 +01:00
// Per-band aggregation
if ( ! isset ( $byBand [ $band ])) {
$byBand [ $band ] = array ();
for ( $j = 0 ; $j < 48 ; $j ++ ) {
$byBand [ $band ][ $j ] = 0 ;
}
$bandCounts [ $band ] = 0 ;
$bandsWithCalls [ $band ] = array ();
}
$byBand [ $band ][ $arrayplacement ] ++ ;
$bandCounts [ $band ] ++ ;
// Store callsigns per band (max 5 per band)
if ( count ( $bandsWithCalls [ $band ]) < 5 ) {
if ( ! in_array ( $callsign , $bandsWithCalls [ $band ])) {
$bandsWithCalls [ $band ][] = $callsign ;
}
}
// Mode aggregation
if ( ! isset ( $modeCounts [ $mode ])) {
$modeCounts [ $mode ] = 0 ;
}
$modeCounts [ $mode ] ++ ;
}
// Calculate hourly data per band (for heatmap)
$hourlyByBand = array ();
foreach ( $byBand as $band => $slots ) {
$hourlyByBand [ $band ] = array_fill ( 0 , 24 , 0 );
for ( $h = 0 ; $h < 24 ; $h ++ ) {
// Aggregate two 30-minute slots into one hour
$hourlyByBand [ $band ][ $h ] = $slots [ $h * 2 ] + $slots [ $h * 2 + 1 ];
}
}
// Calculate best band, mode, and time window
$bestBand = array ( 'value' => null , 'total' => 0 );
foreach ( $bandCounts as $band => $count ) {
if ( $count > $bestBand [ 'total' ]) {
$bestBand = array ( 'value' => $band , 'total' => $count );
}
}
$bestMode = array ( 'value' => null , 'total' => 0 );
foreach ( $modeCounts as $mode => $count ) {
if ( $count > $bestMode [ 'total' ]) {
$bestMode = array ( 'value' => $mode , 'total' => $count );
}
}
$bestWindow = null ;
$bestWindowCount = 0 ;
foreach ( $dataarray as $slot ) {
if ( $slot [ 'count' ] > $bestWindowCount ) {
$bestWindowCount = $slot [ 'count' ];
$bestWindow = $slot [ 'time' ];
}
2020-10-18 00:00:01 +02:00
}
2026-03-28 19:09:09 +01:00
if ( count ( $log ) != 0 ) {
2020-10-18 00:00:01 +02:00
header ( 'Content-Type: application/json' );
$data [ 'qsocount' ] = count ( $log );
$data [ 'ok' ] = 'OK' ;
$data [ 'qsodata' ] = $dataarray ;
2026-03-28 19:09:09 +01:00
$data [ 'by_band' ] = $byBand ;
$data [ 'hourly_by_band' ] = $hourlyByBand ;
$data [ 'bands' ] = array_keys ( $byBand );
2026-04-01 08:45:34 +02:00
usort (
$data [ 'bands' ],
function ( $b , $a ) {
sscanf ( $a , '%f%s' , $ac , $ar );
sscanf ( $b , '%f%s' , $bc , $br );
return ( $ar == $br ) ? $ac <=> $bc : $ar <=> $br ;
}
);
// Rebuild hourly_by_band array in sorted band order
$sortedHourlyByBand = array ();
foreach ( $data [ 'bands' ] as $band ) {
$sortedHourlyByBand [ $band ] = $hourlyByBand [ $band ];
}
$data [ 'hourly_by_band' ] = $sortedHourlyByBand ;
2026-03-28 19:09:09 +01:00
$data [ 'band_counts' ] = $bandCounts ;
$data [ 'mode_counts' ] = $modeCounts ;
$data [ 'best_band' ] = $bestBand ;
$data [ 'best_mode' ] = $bestMode ;
$data [ 'best_window' ] = array ( 'label' => $bestWindow , 'total' => $bestWindowCount );
2020-10-18 00:00:01 +02:00
echo json_encode ( $data );
}
else {
header ( 'Content-Type: application/json' );
2020-10-28 18:03:30 +00:00
$data [ 'error' ] = 'No QSOs found to plot!' ;
2020-10-18 00:00:01 +02:00
echo json_encode ( $data );
}
}
2026-03-25 12:41:18 +01:00
/*
* Get ' s the worked modes from the log
*/
function get_worked_modes () {
$this -> load -> model ( 'logbooks_model' );
$logbooks_locations_array = $this -> logbooks_model -> list_logbook_relationships ( $this -> session -> userdata ( 'active_station_logbook' ));
if ( $logbooks_locations_array [ 0 ] === - 1 ) {
return null ;
}
$location_list = " ' " . implode ( " ',' " , $logbooks_locations_array ) . " ' " ;
// get all worked modes from database
$data = $this -> db -> query (
" SELECT distinct LOWER(`COL_MODE`) as `COL_MODE` FROM ` " . $this -> config -> item ( 'table_name' ) . " ` WHERE station_id in ( " . $location_list . " ) order by COL_MODE ASC "
);
$results = array ();
foreach ( $data -> result () as $row ) {
array_push ( $results , $row -> COL_MODE );
}
$data = $this -> db -> query (
" SELECT distinct LOWER(`COL_SUBMODE`) as `COL_SUBMODE` FROM ` " . $this -> config -> item ( 'table_name' ) . " ` WHERE station_id in ( " . $location_list . " ) and coalesce(COL_SUBMODE, '') <> '' order by COL_SUBMODE ASC "
);
foreach ( $data -> result () as $row ) {
if ( ! in_array ( $row , $results )) {
array_push ( $results , $row -> COL_SUBMODE );
}
}
asort ( $results );
return $results ;
}
2021-09-10 11:44:05 +02:00
}