#!/usr/bin/perl -w # NAME: fgtelnet.pl # AIM: Get a TELNET connection to fgfs on host port use strict; use warnings; use Time::HiRes qw( gettimeofday tv_interval ); use Time::gmtime; use IO::Socket; use Math::Trig; # atan() etc use Term::ReadKey; my $os = $^O; my $perl_dir = '/home/geoff/bin'; my $PATH_SEP = '/'; if ($os =~ /win/i) { $perl_dir = 'C:\GTools\perl'; $PATH_SEP = "\\"; } unshift(@INC, $perl_dir); require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl'! Check location and \@INC content.\n"; require 'fg_wsg84.pl' or die "Unable to load 'fg_wsg84.pl' ...\n"; require 'Bucket2.pm' or die "Unable to load 'Bucket2.pm' ...\n"; ### runtime my $HOST = "192.168.1.33"; #my $HOST = "localhost"; my $PORT = 5555; ###my $PORT = 65501; my $TIMEOUT = 3; # seconds to wait for a connect. my ($FGFS_IO); my $send_run_exit = 0; ###my $load_log = 0; my $set_bin_mode = 0; # tried this, but seemed no to do anything my $add_metar = 1; # can NOT seem to get metar string my $try_metar_delay = 0; my $try_metar_repeat = 0; # this BLOCKED ;=(( my $try_metar_second = 0; # DEBUG ONLY STUFF my @intervals = (); my @warnings = (); END { if (defined $FGFS_IO) { prt("WARNING: End with socket open... closing connection...\n"); fgfs_send("run exit") if ($send_run_exit); close $FGFS_IO; undef $FGFS_IO; } #prt("END\n"); ReadMode(0); # restore normal keyboard mode } ### constants my $SGD_PI = 3.1415926535; my $SGD_DEGREES_TO_RADIANS = $SGD_PI / 180.0; my $SGD_RADIANS_TO_DEGREES = 180.0 / $SGD_PI; my $DEF_GS = 3; my $ATAN3 = atan( $DEF_GS * $SGD_DEGREES_TO_RADIANS ); # /** Feet to Meters */ my $SG_FEET_TO_METER = 0.3048; # /** Meters to Feet */ my $SG_METER_TO_FEET = 3.28083989501312335958; my $SG_NM_TO_METER = 1852; my $SG_METER_TO_NM = 0.0005399568034557235; # locations my $a_gil_lat = -31.697287500; my $a_gil_lon = 148.636942500; my $a_dub_lat = -32.2174865; my $a_dub_lon = 148.57727; my $targ_ygil = 1; my $last_show_time = 0; my $begin_show_time = 0; my $show_interval = 10; ### ============================================== my $min_fly_speed = 30; # Knots my $min_upd_position = 5 * 60; # update if older than 5 minutes my $bug_in_bug = 1; my $min_apt_distance_m = 25 * $SG_NM_TO_METER; # interested if within 25 nautical miles my $degs_to_rwy = 35; my $min_agl_height = 500; my $short_time_stg = 1; my $min_targ_dist =1000; # at airport if less than this my $curr_target = ''; my $head_target = 0; my $prev_target = 0; my $requested_hb = 0; my $begin_hb = 0; my $bgn_turn_tm = 0; my $chk_turn_done = 0; my $last_wind_info = ''; # metar info at last update my $mag_deviation = 0; # = difference ($curr_hdg - $curr_mag) at ast update my $mag_variation = 0; # from /environment/magnetic-variation-deg # current hashes - at last update my %m_curr_engine = (); my %m_curr_klocks = (); my %m_curr_posit = (); my %m_curr_env = (); my %m_curr_comms = (); my %m_curr_consumables = (); my %m_curr_gps = (); my %m_curr_sim = (); my %m_curr_gear = (); # fetch the above global - which should not be referred to directly sub get_curr_posit() { return \%m_curr_posit; } sub get_curr_env() { return \%m_curr_env; } sub get_curr_comms() { return \%m_curr_comms; } sub get_curr_consumables() { return \%m_curr_consumables; } sub get_curr_gps() { return \%m_curr_gps; } sub get_curr_engine() { return \%m_curr_engine; } sub get_curr_Klocks() { return \%m_curr_klocks; } sub get_curr_sim() { return \%m_curr_sim; } sub get_curr_gear() { return \%m_curr_gear; } sub local_get_hhmmss_UTC { my ($t) = shift; # sec, min, hour, mday, mon, year, wday, yday, and isdst. my $tm = gmtime($t); my $m = sprintf( "%02d:%02d:%02d", $tm->hour(), $tm->min(), $tm->sec()); return $m; } sub local_prt($) { print shift; } sub prtt($) { my $txt = shift; prt(lu_get_hhmmss_UTC(time()).": $txt"); } sub show_warnings($) { my ($val) = @_; if (@warnings) { prt( "\nGot ".scalar @warnings." WARNINGS...\n" ); foreach my $itm (@warnings) { prt("$itm\n"); } prt("\n"); } else { #prt( "\nNo warnings issued.\n\n" ); } } sub pgm_exit($$) { my ($val,$msg) = @_; if (length($msg)) { $msg .= "\n" if (!($msg =~ /\n$/)); prt($msg); } show_warnings($val); close_fgfs_io(); ###close_log($outfile,$load_log); ReadMode(0); # restore normal mode exit($val); } sub give_help() { prt("Run '$0 HOST PORT' on the command line... like\n"); prt("fgtelnet.pl $HOST $PORT\n"); exit(1); } sub got_keyboard($) { my ($rc) = shift; # -1 = Perform a non-blocked read # when set to 'cbreak' mode (4) if (defined (my $char = ReadKey(-1)) ) { # input was waiting and it was $char ${$rc} = $char; return 1; } return 0; } sub sleep_ms($) { my $usecs = shift; # = $INTERVAL if ($usecs > 0) { my $secs = $usecs / 1000; select(undef,undef,undef,$secs); #usleep($usecs); # sampling interval } } sub is_numeric($) { my $num = shift; return 1 if ($num =~ /^(\d|\.|-|\+)+$/); return 0; } sub significant_diff($$$) { my ($val1,$val2,$sig) = @_; my $diff = abs($val1 - $val2); return 1 if ($diff > $sig); return 0; } sub get_exit($) { my ($val) = shift; pgm_exit($val,"fgfs get FAILED!\n"); } # helpers for display sub set_decimal1_stg($) { my $r = shift; if (is_numeric(${$r})) { ${$r} = int((${$r} + 0.05) * 10) / 10; ${$r} = "0.0" if (${$r} == 0); ${$r} .= ".0" if !(${$r} =~ /\./); } } sub set_dist_stg($) { my ($rd) = @_; my $dist = ${$rd}; my ($sc); if ($dist < 1000) { $dist = int($dist); $sc = 'm'; } else { $dist = (int(($dist / 1000) * 10) / 10); $sc = 'KM'; } ${$rd} = "$dist$sc"; } sub set_hdg_stg1($) { my ($rh) = @_; my $hdg = ${$rh}; $hdg = (int(($hdg+0.05) * 10) / 10); ${$rh} = $hdg; } sub set_lat_stg($) { my ($rl) = @_; ${$rl} = sprintf("%2.7f",${$rl}); } sub set_lon_stg($) { my ($rl) = @_; ${$rl} = sprintf("%3.7f",${$rl}); } sub set_hdg_stg($) { my ($rh) = @_; my $hdg = ${$rh}; $hdg = 360 if ($hdg == 0); # always replace 000 with 360 ;=)) $hdg = sprintf("%03d",int($hdg+0.5)); ${$rh} = $hdg; } sub set_int_stg($) { my $r = shift; ${$r} = int(${$r} + 0.5); } sub get_dist_stg_nm($) { my ($dist) = @_; my $nm = $dist * $SG_METER_TO_NM; set_decimal1_stg(\$nm); $nm .= "nm"; return $nm; } # ============================================================= sub get_hdg_in_range($) { my $rh = shift; if (${$rh} < 0) { ${$rh} += 360; } elsif (${$rh} > 360) { ${$rh} -= 360; } } sub get_mag_hdg_from_true($) { my $hdg = shift; $hdg -= $mag_deviation; get_hdg_in_range(\$hdg); return $hdg; } sub secs_HHMMSS2($) { my ($secs) = @_; my ($mins,$hrs,$stg); $mins = int($secs / 60); $secs -= ($mins * 60); $hrs = int($mins / 60); $mins -= ($hrs * 60); $stg = sprintf("%02d:%02d:%02d", $hrs, $mins, $secs); if ($short_time_stg) { $stg =~ s/^00:// if ($stg =~ /^00:/); $stg =~ s/^00:// if ($stg =~ /^00:/); $stg .= 's' if (length($stg) == 2); # Add seconds if just seconds } return $stg; } # ============================================================= # PATHS my $get_V_ground_speed = "/velocities/groundspeed-kt"; # * $KNOTS_TO_FTS; my $get_V_calibrated_kts = "/velocities/airspeed-kt"; # TELNET STUFF sub fgfs_connect($$$) { my ($host,$port,$timeout) = @_; my $socket; #STDOUT->autoflush(1); prtt("Connect $host, $port, timeout $timeout secs "); while ($timeout--) { if ($socket = IO::Socket::INET->new( Proto => 'tcp', PeerAddr => $host, PeerPort => $port)) { prt(" done.\n"); #$socket->autoflush(1); sleep 1; return $socket; } prt("."); sleep(1); } prt(" FAILED!\n"); return 0; } sub close_fgfs_io { if (defined $FGFS_IO) { prtt("Closing connection...\n"); fgfs_send("run exit") if ($send_run_exit); close $FGFS_IO; undef $FGFS_IO; } } sub fgfs_send($) { print $FGFS_IO shift, "\015\012"; } sub fgfs_set($$) { my ($node,$val) = @_; fgfs_send("set $node $val"); return 1; } sub fgfs_get($$) { my ($txt,$rval) = @_; my $tb = [gettimeofday]; fgfs_send("get $txt"); eof $FGFS_IO and return 0; ${$rval} = <$FGFS_IO>; my $elapsed = tv_interval ( $tb, [gettimeofday]); push(@intervals,$elapsed); ${$rval} =~ s/\015?\012$//; ${$rval} =~ /^-ERR (.*)/ and (prt("WARNING: $1\n") and return 0); return 1; } sub fgfs_get_with_delay($$$) { my ($txt,$rval,$ms) = @_; #my $tb = [gettimeofday]; fgfs_send("get $txt"); sleep_ms($ms); eof $FGFS_IO and return 0; ${$rval} = <$FGFS_IO>; #my $elapsed = tv_interval ( $tb, [gettimeofday]); #push(@intervals,$elapsed); ${$rval} =~ s/\015?\012$//; ${$rval} =~ /^-ERR (.*)/ and (prt("WARNING: $1\n") and return 0); return 1; } sub fgfs_get_repeat($$) { my ($txt,$rval) = @_; #my $tb = [gettimeofday]; fgfs_send("get $txt"); eof $FGFS_IO and return 0; my $val = <$FGFS_IO>; $val =~ s/\015?\012$//; $val =~ /^-ERR (.*)/ and (prt("WARNING: $1\n") and return 0); # while (! eof $FGFS_IO) { # UGH - this BLOCKED my ($line); # try this while (defined($line = <$FGFS_IO>)) { $val .= ' '; $val .= $line; } ${$rval} = $val; return 1; } sub fgfs_get_no_clean($$) { my ($txt,$rval) = @_; fgfs_send("get $txt"); eof $FGFS_IO and return 0; ${$rval} = <$FGFS_IO>; # ${$rval} =~ s/\015?\012$//; ${$rval} =~ /^-ERR (.*)/ and (prt("WARNING: $1\n") and return 0); return 1; } # ========================================================================== sub fgfs_get_coord($$) { my ($rlon,$rlat) = @_; fgfs_get("/position/longitude-deg", $rlon) or get_exit(-2); fgfs_get("/position/latitude-deg", $rlat) or get_exit(-2); return 1; } sub fgfs_get_alt($) { my $ref_alt = shift; fgfs_get("/position/altitude-ft", $ref_alt) or get_exit(-2); return 1; } sub fgfs_get_hdg_true($) { my $ref_hdg = shift; fgfs_get("/orientation/heading-deg", $ref_hdg) or get_exit(-2); return 1; } sub fgfs_get_hdg_mag($) { my $ref_hdg = shift; fgfs_get("/orientation/heading-magnetic-deg", $ref_hdg) or get_exit(-2); return 1; } sub fgfs_get_hdg_bug($) { my $ref_hb = shift; fgfs_get("/autopilot/settings/heading-bug-deg", $ref_hb) or get_exit(-2); return 1; } sub fgfs_set_hdg_bug($) { my $val = shift; fgfs_set("/autopilot/settings/heading-bug-deg", $val) or get_exit(-2); return 1; } sub fgfs_get_agl($) { my $ref_alt = shift; fgfs_get("/position/altitude-agl-ft", $ref_alt) or get_exit(-2); return 1; } # "/velocities/airspeed-kt"; sub fgfs_get_aspd_kts($) { my $ref = shift; fgfs_get($get_V_calibrated_kts, $ref) or get_exit(-2); return 1; } # "/velocities/groundspeed-kt"; # * $KNOTS_TO_FTS; sub fgfs_get_gspd_kts($) { my $ref = shift; fgfs_get($get_V_ground_speed, $ref) or get_exit(-2); return 1; } sub fgfs_get_position() { #my ($lon,$lat,$alt,$hdg,$agl,$hb,$mag); my ($curr_lat,$curr_lon,$curr_alt,$curr_hdg,$curr_mag,$curr_hb,$curr_agl); my ($curr_aspd,$curr_gspd); fgfs_get_coord(\$curr_lon,\$curr_lat); fgfs_get_alt(\$curr_alt); fgfs_get_hdg_true(\$curr_hdg); fgfs_get_hdg_mag(\$curr_mag); fgfs_get_agl(\$curr_agl); fgfs_get_hdg_bug(\$curr_hb); fgfs_get_aspd_kts(\$curr_aspd); fgfs_get_gspd_kts(\$curr_gspd); my $rc = get_curr_posit(); my $gps = get_curr_gps(); my $tm = time(); ${$rc}{'gps-update'} = 0; # if (defined ${$rc}{'time'} && defined ${$gps}{'time'}) { # my $ptm = ${$rc}{'time'}; # my $gtm = ${$gps}{'time'}; # if ($ptm > $gtm) { # my $diff = $ptm - $gtm; # get seconds different # if ($diff > $gps_next_time) { # prtt("Adding a GPS update... Next in ".int($gps_next_time / 60)." mins...\n"); # $gps = fgfs_get_gps(); # get the GPS position of things, check and compare... # ${$rc}{'gps-update'} = 1; # maybe in display, show difference, if ANY... # } # } # } elsif (defined ${$rc}{'time'}) { # prtt("Initial GPS update... next in ".int($gps_next_time / 60)." mins\n"); # $gps = fgfs_get_gps(); # get the GPS position of things, check and compare... # ${$rc}{'gps-update'} = 1; # maybe in display, show difference, if ANY... # } ${$rc}{'time'} = $tm; ${$rc}{'lon'} = $curr_lon; ${$rc}{'lat'} = $curr_lat; ${$rc}{'alt'} = $curr_alt; ${$rc}{'hdg'} = $curr_hdg; ${$rc}{'mag'} = $curr_mag; ${$rc}{'bug'} = $curr_hb; ${$rc}{'agl'} = $curr_agl; ${$rc}{'aspd'} = $curr_aspd; # Knots ${$rc}{'gspd'} = $curr_gspd; # Knots $mag_deviation = ($curr_hdg - $curr_mag); # if ($chk_turn_done) { # if (abs($requested_hb - $curr_mag) <= 1) { # my $ctm = $tm - $bgn_turn_tm; # my $angle = int(abs($requested_hb - $begin_hb)); # my $mag = int($curr_mag + 0.5); # my $dps = ''; # if ($ctm > 0) { # $dps = (int((($angle / $ctm) + 0.05) * 10) / 10).'DPS'; # } # $requested_hb = int($requested_hb + 0.5); # prtt("Completed TURN $angle degrees to $requested_hb($mag) in $ctm seconds... $dps\n"); # $chk_turn_done = 0; # } # } return $rc; } sub show_position($) { my ($rp) = @_; return if (!defined ${$rp}{'time'}); my $ctm = lu_get_hhmmss_UTC(${$rp}{'time'}); my ($lon,$lat,$alt,$hdg,$agl,$hb,$mag,$aspd,$gspd,$cpos); $lon = ${$rp}{'lon'}; $lat = ${$rp}{'lat'}; $alt = ${$rp}{'alt'}; $hdg = ${$rp}{'hdg'}; $agl = ${$rp}{'agl'}; $hb = ${$rp}{'bug'}; $mag = ${$rp}{'mag'}; $aspd = ${$rp}{'aspd'}; # Knots $gspd = ${$rp}{'gspd'}; # Knots my $msg = ''; my $eta = ''; #show_YGIL_route(); # if (${$rp}{'gps-update'} == 1) { # maybe in display, show difference, if ANY... # my $rg = get_curr_gps(); # if (defined ${$rg}{'time'}) { # my $glon = ${$rg}{'lon'}; # my $glat = ${$rg}{'lat'}; # my $galt = ${$rg}{'alt'}; # my $ghdg = ${$rg}{'hdg'}; # # $agl = ${$rp}{'agl'}; # # $hb = ${$rp}{'bug'}; # my $gmag = ${$rg}{'mag'}; # fgfs_get_mag_var(\$mag_variation); # # # display mess # set_lat_stg(\$glat); # set_lon_stg(\$glon); # set_hdg_stg(\$ghdg); # set_hdg_stg(\$gmag); # $galt = int($galt + 0.5); # prt("$ctm: GPS $glat,$glon,$galt ft, hdg=${ghdg}T/${gmag}M \n"); # show_environ(fgfs_get_environ()); # } # } $msg = ''; my ($tlat,$tlon,$az1,$az2,$dist,$rrwys,$targ,$diff); if ($targ_ygil) { $tlat = $a_gil_lat; $tlon = $a_gil_lon; $targ = "YGIL"; } else { # target Dubbo $tlat = $a_dub_lat; $tlon = $a_dub_lon; $targ = "YSDU"; } fg_geo_inverse_wgs_84 ($lat,$lon,$tlat,$tlon,\$az1,\$az2,\$dist); $az2 = get_mag_hdg_from_true($az1); # - $mag_deviation; $diff = int($az2 - $mag+0.5); if ($dist < $min_targ_dist) { set_decimal1_stg(\$dist); $msg = " at $targ $dist meters."; } else { # with GRD SPEED (Knots), and Distance (meters), calculate an ETA (secs) my $secs = int(( $dist / (($gspd * $SG_NM_TO_METER) / 3600)) + 0.5); $eta = "ETA:".secs_HHMMSS2($secs); # display as hh:mm:ss $dist = get_dist_stg_nm($dist); set_hdg_stg(\$az1); set_hdg_stg(\$az2); $msg = " to $targ $dist ${az1}T/${az2}M cc=$diff"; } # if (headed_to_target()) { # my $rl = get_locations(); # $tlat = ${$rl}{$curr_target}[$OL_LAT]; # $tlon = ${$rl}{$curr_target}[$OL_LON]; # $rrwys = ${$rl}{$curr_target}[$OL_RWY]; # fg_geo_inverse_wgs_84 ($lat,$lon,$tlat,$tlon,\$az1,\$az2,\$dist); # $az2 = get_mag_hdg_from_true($az1); # - $mag_deviation; # if ( got_flying_speed() ) { # # with GRD SPEED (Knots), and Distance (meters), calculate an ETA (secs) # my $secs = int(( $dist / (($gspd * $SG_NM_TO_METER) / 3600)) + 0.5); # $eta = "ETA:".secs_HHMMSS2($secs); # display as hh:mm:ss # # Hmmm, Dist, AGL, and GrdSpd would allow assessment of a standard 3 degree Glide SLope (GS) # # my $min_dist = $agl / $ATAN3; # # if (($dist > 0) && ($dist < ($min_dist * 2))) # if (($agl > 0) && ($dist > 0) && ($dist < $min_apt_distance_m)) { # # we are WITHIN min apt distance - get glide from here # $eta .= " *"; # $eta .= "@" if (abs($az1 - $hdg) < 15); # within 15 degrees of the heading to the runway # if ( ($dist > 0) && ($agl > 0) && ( track_to_within_degs($rp,$degs_to_rwy,$az1,$rrwys) ) ) { # $eta .= "+"; # my $fpm = get_feet_per_min($aspd,$dist/1000,$agl,0); # if ($fpm > 2000) { # $fpm = ">2000fpm"; # } else { # set_int_stg(\$fpm); # $fpm .= "fpm"; # } # $eta .= " $fpm"; # #my $gs = atan2($agl,$dist) * $SGD_RADIANS_TO_DEGREES; # #set_int_stg(\$gs); # #$eta .= " ${gs}gs"; # $eta .= ${$rp}{'s_hdg-diff'}; # } # } # } # # display messing # #set_dist_stg(\$dist); # $dist = get_dist_stg_nm($dist); # set_hdg_stg(\$az1); # set_hdg_stg(\$az2); # $msg = "hm:$curr_target $dist ${az1}T/${az2}M"; # } # display stuff - note destroys values - local now only for display # ================================================================= set_hdg_stg(\$hdg); set_hdg_stg(\$mag); # had some trouble with this BUG - seems not initialized!!! until you move it... if ($hb && ($hb =~ /^-*(\d|\.)+$/)) { set_hdg_stg(\$hb); } elsif ((defined $hb) && length($hb)) { $hb = "?$hb?!"; } else { fgfs_set_hdg_bug($mag); } set_int_stg(\$alt); set_lat_stg(\$lat); set_lon_stg(\$lon); $cpos = "$lat,$lon,$alt"; if ($aspd < $min_fly_speed) { $agl = "OnGrd $cpos"; } else { #if ($agl > $min_agl_height) { # $agl = ''; #} else { $agl = 'alt '.int($agl + 0.5)." $cpos"; #} } if ($aspd < $min_fly_speed) { if (fgfs_get_parking_brake()) { $msg .= " parking break on." } else { if ($aspd > 1) { set_decimal1_stg(\$aspd); $msg .= " taxiing $aspd" } else { $msg .= " stopped." } } } else { $aspd = int($aspd + 0.5); if (is_numeric($gspd)) { $gspd = int($gspd + 0.5); } $msg .= " spd=$aspd/${gspd}Kt"; } prt("$ctm: $agl hdg=${hdg}T/${mag}M,b=$hb $msg $eta\n"); } # =========================================== sub fgfs_get_eng_running($) { my $ref = shift; fgfs_get("/engines/engine/running", $ref) or get_exit(-2); # bool true/false return 1; } sub fgfs_get_eng_rpm($) { my $ref = shift; fgfs_get("/engines/engine/rpm", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_eng_throttle($) { # range 0 to 1 my $ref = shift; fgfs_get("/controls/engines/engine/throttle", $ref) or get_exit(-2); return 1; } sub fgfs_get_engine() { my $re = get_curr_engine(); my ($running); fgfs_get_eng_running(\$running); ${$re}{'running'} = $running; my ($rpm); fgfs_get_eng_rpm(\$rpm); ${$re}{'rpm'} = $rpm; my ($throt); fgfs_get_eng_throttle(\$throt); ${$re}{'throttle'} = $throt; ${$re}{'time'} = time(); return $re; } sub show_engine($) { my $re = shift; my $tm = lu_get_hhmmss_UTC(${$re}{'time'}); my $throt = ${$re}{'throttle'}; my $rpm = ${$re}{'rpm'}; my $run = ${$re}{'running'}; prt("$tm Engine: Run $run, rpm $rpm, throt $throt\n"); } sub show_engine_change() { my $ret = 0; my $re = get_curr_engine(); if (defined ${$re}{'time'}) { my %curr = %{$re}; $re = fgfs_get_engine(); # my $chg = 0; #if ($curr{'running'} ne ${$re}{'running'}) { # prt("Change in 'running' - ".$curr{'running'}.' vs '.${$re}{'running'}."\n"); # $chg++; #} #if ( significant_diff($curr{'rpm'},${$re}{'rpm'},1)) { # prt("Change in 'rpm' - ".$curr{'rpm'}.' vs '.${$re}{'rpm'}."\n"); # $chg++; #} #if (significant_diff($curr{'throttle'},${$re}{'throttle'},0.1)) { # prt("Change in 'throttle' - ".$curr{'throttle'}.' vs '.${$re}{'throttle'}."\n"); # $chg++; #} #if ($chg > 0) { # show_engine($re); #} if (($curr{'running'} ne ${$re}{'running'})|| (significant_diff($curr{'rpm'},${$re}{'rpm'},1))|| (significant_diff($curr{'throttle'},${$re}{'throttle'},0.1))) { show_engine($re); $ret = 1; } else { %{$re} = %curr; # restore previous values - avoid creeping change } } else { #prt("Engine: time not defined\n"); show_engine(fgfs_get_engine()); $ret = 1; } return $ret; } # =============================================== # gear my $gear = "/controls/gear"; sub fgfs_get_brake_left($) { my $ref = shift; fgfs_get("$gear/brake-left", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_brake_right($) { my $ref = shift; fgfs_get("$gear/brake-right", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_brake_parking($) { my $ref = shift; fgfs_get("$gear/brake-parking", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_brakes() { my $rg = get_curr_gear(); my ($bl,$br,$bp); fgfs_get_brake_left(\$bl); fgfs_get_brake_right(\$br); fgfs_get_brake_parking(\$bp); ${$rg}{'brake-left'} = $bl; ${$rg}{'brake-right'} = $br; ${$rg}{'brake-parking'} = $bp; ${$rg}{'time'} = time(); #prt("brakes: L [$bl], R [$br], P [$bp]\n"); return $rg; } sub fgfs_get_parking_brake() { my ($pb); fgfs_get_brake_parking(\$pb); return $pb; } sub show_brakes($) { my $rg = shift; my ($tm,$bl,$br,$bp); # my @arr = keys %{$rg}; # prt("Keys: ".join(" ",@arr)."\n"); #foreach my $key (@arr) { # prt(" $key ".${$rg}{$key}); #} #prt("\n"); $tm = lu_get_hhmmss_UTC(${$rg}{'time'}); $bl = ${$rg}{'brake-left'}; $br = ${$rg}{'brake-right'}; $bp = ${$rg}{'brake-parking'}; prt("$tm Brakes: Left $bl, Right $br, parking $bp\n"); } sub show_brakes_change() { my $ret = 0; my $rg = get_curr_gear(); if (defined ${$rg}{'time'}) { my %curr = %{$rg}; # copy hash $rg = fgfs_get_brakes(); if (($curr{'brake-left'} != ${$rg}{'brake-left'})|| ($curr{'brake-right'} != ${$rg}{'brake-right'})|| ($curr{'brake-parking'} != ${$rg}{'brake-parking'})) { show_brakes($rg); $ret = 1; } else { %{$rg} = %curr; # avoid creep } } else { show_brakes(fgfs_get_brakes()); $ret = 1; } return $ret; } # =============================================== sub fgfs_get_aero($) { my $ref = shift; # \$aero fgfs_get("/sim/aero", $ref) or get_exit(-2); # string return 1; } sub fgfs_get_fdm($) { my $ref = shift; # \$aero fgfs_get("/sim/flight-model", $ref) or get_exit(-2); # string return 1; } sub fgfs_get_root($) { my $ref = shift; # \$aero fgfs_get("/sim/fg-root", $ref) or get_exit(-2); # string return 1; } sub fgfs_get_desc($) { my $ref = shift; # \$aero fgfs_get("/sim/decription", $ref) or get_exit(-2); # string return 1; } sub fgfs_get_sim_info() { my ($aero,$fdm,$root,$desc); fgfs_get_aero(\$aero); fgfs_get_fdm(\$fdm); fgfs_get_root(\$root); fgfs_get_desc(\$desc); my $rs = get_curr_sim(); ${$rs}{'aero'} = $aero; ${$rs}{'fdm'} = $fdm; ${$rs}{'root'} = $root; ${$rs}{'desc'} = $desc; ${$rs}{'time'} = time(); return $rs; } sub show_sim_info($) { my $rs = shift; my ($ctm,$aero,$fdm,$root,$desc); $aero = ${$rs}{'aero'}; $fdm = ${$rs}{'fdm'}; $root = ${$rs}{'root'}; $desc = ${$rs}{'desc'}; $ctm = lu_get_hhmmss_UTC(${$rs}{'time'}); prt("$ctm: FDM=[$fdm] aero=[$aero] fg-root=[$root]\n"); prt("$ctm: Desc=$desc\n") if ((defined $desc) && length($desc)); } sub show_sim_info_change() { my $ret = 0; my $rs = get_curr_sim(); if (defined ${$rs}{'time'}) { my %curr = %{$rs}; $rs = fgfs_get_sim_info(); if (($curr{'aero'} ne ${$rs}{'aero'})|| ($curr{'fdm'} ne ${$rs}{'fdm'})|| ($curr{'root'} ne ${$rs}{'root'})|| ($curr{'desc'} ne ${$rs}{'desc'})) { show_sim_info($rs); $ret = 1; } } else { show_sim_info(fgfs_get_sim_info()); $ret = 1; } return $ret; } # =============================================== sub fgfs_get_fuel1_imp($) { my $ref = shift; fgfs_get("/consumables/fuel/tank/level-gal_imp", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_fuel1_us($) { my $ref = shift; fgfs_get("/consumables/fuel/tank/level-gal_us", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_fuel2_imp($) { my $ref = shift; fgfs_get("/consumables/fuel/tank[1]/level-gal_imp", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_fuel2_us($) { my $ref = shift; fgfs_get("/consumables/fuel/tank[1]/level-gal_us", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_fuel_lbs($) { my $ref = shift; fgfs_get("/consumables/fuel/total-fuel-lbs", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_fuel_kgs($) { my $ref = shift; fgfs_get("/consumables/fuel/total-fuel-kg", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_consumables() { my ($t1gi,$t1gus,$t2gi,$t2gus); my ($tlbs,$tkgs); fgfs_get_fuel1_imp(\$t1gi); fgfs_get_fuel1_us(\$t1gus); fgfs_get_fuel2_imp(\$t2gi); fgfs_get_fuel2_us(\$t2gus); fgfs_get_fuel_lbs(\$tlbs); fgfs_get_fuel_kgs(\$tkgs); my $rc = get_curr_consumables(); ${$rc}{'time'} = time(); ${$rc}{'tank1-imp'} = $t1gi; ${$rc}{'tank1-us'} = $t1gus; ${$rc}{'tank2-imp'} = $t2gi; ${$rc}{'tank2-us'} = $t2gus; ${$rc}{'total-imp'} = ($t1gi + $t2gi); ${$rc}{'total-us'} = ($t1gus + $t2gus); ${$rc}{'total-lbs'} = $tlbs; ${$rc}{'total-kgs'} = $tkgs; return $rc; } sub show_consumables($) { my $rc = shift; if (defined ${$rc}{'time'}) { my ($t1gi,$t1gus,$t2gi,$t2gus,$totgi,$totgus); my ($tlbs,$tkgs); my $ctm = lu_get_hhmmss_UTC(${$rc}{'time'}); $t1gi = ${$rc}{'tank1-imp'}; $t1gus = ${$rc}{'tank1-us'}; $t2gi = ${$rc}{'tank2-imp'}; $t2gus = ${$rc}{'tank2-us'}; $totgi = ${$rc}{'total-imp'}; $totgus = ${$rc}{'total-us'}; $tlbs = ${$rc}{'total-lbs'}; $tkgs = ${$rc}{'total-kgs'}; # display fixes set_decimal1_stg(\$t1gi); set_decimal1_stg(\$t1gus); set_decimal1_stg(\$t2gi); set_decimal1_stg(\$t2gus); set_decimal1_stg(\$totgi); set_decimal1_stg(\$totgus); set_decimal1_stg(\$tlbs); set_decimal1_stg(\$tkgs); prt("$ctm: Total $totgi gal.imp ($totgus us), $tlbs lbs ($tkgs kgs). T1 $t1gi($t1gus), T2 $t2gi($t2gus)\n"); } } sub show_consumables_change() { my $ret = 0; my $rc = get_curr_consumables(); if (defined ${$rc}{'time'}) { my %curr = %{$rc}; # copy $rc = fgfs_get_consumables(); # get update if (significant_diff($curr{'total-lbs'},${$rc}{'total-lbs'},1)) { show_consumables($rc); $ret = 1; } else { %{$rc} = %curr; } } else { show_consumables(fgfs_get_consumables()); $ret = 1; } return $ret; } # ================================================ sub fgfs_get_wind_speed($) { my ($ref) = @_; #fgfs_get("/environment/wind-speed-kt", $ref) or get_exit(-2); # double fgfs_get("/environment/metar/base-wind-speed-kt", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_wind_heading($) { my ($ref) = @_; #fgfs_get("/environment/wind-from-heading-deg", $ref) or get_exit(-2); # double #fgfs_get("/environment/metar/base-wind-range-from", $ref) or get_exit(-2); # double fgfs_get("/environment/metar/base-wind-dir-deg", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_wind_east($) { my ($ref) = @_; #fgfs_get("/environment/wind-from-east-fps", $ref) or get_exit(-2); # double fgfs_get("/environment/metar/base-wind-from-east-fps", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_wind_north($) { my ($ref) = @_; #fgfs_get("/environment/wind-from-north-fps", $ref) or get_exit(-2); # double fgfs_get("/environment/metar/base-wind-from-north-fps", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_metar($) { my ($ref) = @_; fgfs_get("/environment/metar/data", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_metar_with_delay($$) { my ($ref,$ms) = @_; fgfs_get_with_delay("/environment/metar/data", $ref, $ms) or get_exit(-2); # double return 1; } sub fgfs_get_metar_repeat($) { my ($ref) = @_; fgfs_get_repeat("/environment/metar/data", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_mag_var($) { my $ref = shift; fgfs_get("/environment/magnetic-variation-deg", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_metar_second($) { my ($ref) = @_; prt("Trying fgfs_get_metar_second...\n"); fgfs_get_metar($ref) or get_exit(-2); # double prt("Got value ".${$ref}." - doing second, 3rd 4th...\n"); my ($aero,$fdm,$root); fgfs_get_aero(\$aero); fgfs_get_fdm(\$fdm); fgfs_get_root(\$root); prt("Got 2nd values [$aero] [$fdm] [$root]\n"); #${$ref} .= " $val"; return 1; } sub fgfs_get_environ() { my ($wspd,$whdg,$weast,$wnor,$metar,$mv); fgfs_get_mag_var(\$mv); fgfs_get_wind_speed(\$wspd); fgfs_get_wind_heading(\$whdg); fgfs_get_wind_east(\$weast); fgfs_get_wind_north(\$wnor); my $renv = get_curr_env(); ${$renv}{'time'} = time(); ${$renv}{'speed-kt'} = $wspd; ${$renv}{'heading-deg'} = $whdg; ${$renv}{'east-fps'} = $weast; ${$renv}{'north-fps'} = $wnor; ${$renv}{'mag-variation'} = $mv; $mag_variation = $mv; # getting this string seems to cause problems if ($add_metar) { if ($try_metar_delay) { fgfs_get_metar_with_delay(\$metar,200); # string } elsif ($try_metar_repeat) { fgfs_get_metar_repeat(\$metar); # string } elsif ($try_metar_second) { fgfs_get_metar_second(\$metar); # string } else { fgfs_get_metar(\$metar); # string } ${$renv}{'metar'} = $metar; } return $renv; } sub show_environ($) { my ($renv) = @_; my ($tm,$wspd,$whdg,$weast,$wnor); my ($tmp1,$tmp2); if (defined ${$renv}{'time'}) { $tm = ${$renv}{'time'}; $wspd = ${$renv}{'speed-kt'}; $whdg = ${$renv}{'heading-deg'}; $weast = ${$renv}{'east-fps'}; $wnor = ${$renv}{'north-fps'}; my $ctm = lu_get_hhmmss_UTC($tm); my $chdg = sprintf("%03d", int($whdg + 0.5)); my $cspd = sprintf("%02d", int($wspd + 0.5)); $tmp1 = $mag_deviation; $tmp2 = $mag_variation; set_decimal1_stg(\$tmp1); set_decimal1_stg(\$tmp2); set_decimal1_stg(\$weast); set_decimal1_stg(\$wnor); $last_wind_info = "$chdg${cspd}KT"; prt("$ctm: WIND: $last_wind_info - fps E=$weast, N=$wnor - MagVar=$tmp1($tmp2)\n"); my $metar = ${$renv}{'metar'}; if ((defined $metar) && length($metar)) { prt("$ctm: METAR: [$metar]\n"); } else { ### prt("$ctm: METAR: not available\n"); } } } sub show_environ_change() { my $ret = 1; my $renv = get_curr_env(); if (defined ${$renv}{'time'}) { my %curr = %{$renv}; $renv = fgfs_get_environ(); if ((significant_diff(${$renv}{'speed-kt'},$curr{'speed-kt'},0.5))|| (significant_diff(${$renv}{'heading-deg'},$curr{'heading-deg'},2))|| (significant_diff(${$renv}{'east-fps'},$curr{'east-fps'},0.5))|| (significant_diff(${$renv}{'north-fps'},$curr{'north-fps'},0.5))) { show_environ($renv); } else { %{$renv} = %curr; $ret = 0; } } else { show_environ(fgfs_get_environ()); } return $ret; } # =============================================== sub fgfs_get_comm1_active($) { my ($ref) = @_; fgfs_get("/instrumentation/comm/frequencies/selected-mhz", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_comm1_stdby($) { my ($ref) = @_; fgfs_get("/instrumentation/comm/frequencies/standby-mhz", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_comm1($$) { my ($rca,$rcs) = @_; fgfs_get_comm1_active($rca); fgfs_get_comm1_stdby($rcs); } sub fgfs_get_comm2_active($) { my ($ref) = @_; fgfs_get("/instrumentation/comm[1]/frequencies/selected-mhz", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_comm2_stdby($) { my ($ref) = @_; fgfs_get("/instrumentation/comm[1]/frequencies/standby-mhz", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_comm2($$) { my ($rca,$rcs) = @_; fgfs_get_comm2_active($rca); fgfs_get_comm2_stdby($rcs); } # NAV1 Display sub fgfs_get_nav1_radial($) { my ($ref) = @_; fgfs_get("/instrumentation/nav/radials/selected-deg", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_nav1_active($) { my ($ref) = @_; fgfs_get("/instrumentation/nav/frequencies/selected-mhz", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_nav1_stdby($) { my ($ref) = @_; fgfs_get("/instrumentation/nav/frequencies/standby-mhz", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_nav1($$) { my ($rna,$rns) = @_; fgfs_get_nav1_active($rna); fgfs_get_nav1_stdby($rns); } sub fgfs_get_nav2_active($) { my ($ref) = @_; fgfs_get("/instrumentation/nav[1]/frequencies/selected-mhz", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_nav2_stdby($) { my ($ref) = @_; fgfs_get("/instrumentation/nav[1]/frequencies/standby-mhz", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_nav2($$) { my ($rna,$rns) = @_; fgfs_get_nav2_active($rna); fgfs_get_nav2_stdby($rns); } sub fgfs_get_adf_active($) { my ($ref) = @_; fgfs_get("/instrumentation/adf/frequencies/selected-khz", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_adf_stdby($) { my ($ref) = @_; fgfs_get("/instrumentation/adf/frequencies/standby-khz", $ref) or get_exit(-2); # double return 1; } sub fgfs_get_adf($$) { my ($radf,$radfs) = @_; fgfs_get_adf_active($radf); fgfs_get_adf_stdby($radfs); } sub fgfs_get_comms() { my ($c1a,$c1s); my ($n1a,$n1s); my ($c2a,$c2s); my ($n2a,$n2s); my ($adf,$adfs); fgfs_get_adf(\$adf,\$adfs); fgfs_get_comm1(\$c1a,\$c1s); fgfs_get_nav1(\$n1a,\$n1s); fgfs_get_comm2(\$c2a,\$c2s); fgfs_get_nav2(\$n2a,\$n2s); my $rc = get_curr_comms(); ${$rc}{'time'} = time(); ${$rc}{'adf-act'} = $adf; ${$rc}{'adf-sby'} = $adfs; ${$rc}{'comm1-act'} = $c1a; ${$rc}{'comm1-sby'} = $c1s; ${$rc}{'nav1-act'} = $n1a; ${$rc}{'nav1-sby'} = $n1s; ${$rc}{'comm2-act'} = $c2a; ${$rc}{'comm2-sby'} = $c2s; ${$rc}{'nav2-act'} = $n2a; ${$rc}{'nav2-sby'} = $n2s; return $rc; } sub show_comms($) { my ($rc) = @_; my ($c1a,$c1s); my ($n1a,$n1s); my ($adf,$adfs); my ($c2a,$c2s); my ($n2a,$n2s); if (defined ${$rc}{'time'}) { my $ctm = lu_get_hhmmss_UTC(${$rc}{'time'}); $adf = ${$rc}{'adf-act'}; $adfs = ${$rc}{'adf-sby'}; $c1a = ${$rc}{'comm1-act'}; $c1s = ${$rc}{'comm1-sby'}; $n1a = ${$rc}{'nav1-act'}; $n1s = ${$rc}{'nav1-sby'}; $c2a = ${$rc}{'comm2-act'}; $c2s = ${$rc}{'comm2-sby'}; $n2a = ${$rc}{'nav2-act'}; $n2s = ${$rc}{'nav2-sby'}; if (is_numeric($adf) && is_numeric($adfs)) { prt("$ctm: ".sprintf("ADF %03d (%03d)",$adf,$adfs)."\n"); } else { prt("$ctm: ADF $adf ($adfs) (NN)\n"); } prt("$ctm: ".sprintf("COMM1 %03.3f (%03.3f) NAV1 %03.3f (%03.3f)",$c1a,$c1s,$n1a,$n1s)."\n"); prt("$ctm: ".sprintf("COMM2 %03.3f (%03.3f) NAV2 %03.3f (%03.3f)",$c2a,$c2s,$n2a,$n2s)."\n"); } } sub show_comms_change() { my $ret = 0; my $rc = get_curr_comms(); if (defined ${$rc}{'time'}) { my %curr = %{$rc}; $rc = fgfs_get_comms(); if ((${$rc}{'adf-act'} != $curr{'adf-act'})|| (${$rc}{'comm1-act'} != $curr{'comm1-act'})|| (${$rc}{'nav1-act'} != $curr{'nav1-act'})|| (${$rc}{'comm2-act'} != $curr{'comm2-act'})|| (${$rc}{'nav2-act'} != $curr{'nav2-act'})) { show_comms($rc); $ret = 1; } else { %{$rc} = %curr; } } else { show_comms(fgfs_get_comms()); $ret = 1; } return $ret; } # =============================================== # Auto-pilot locks sub fgfs_get_K_ah($) { my $ref = shift; fgfs_get("/autopilot/KAP140/locks/alt-hold", $ref) or get_exit(-2); # = true/false return 1; } sub fgfs_get_K_pa($) { my $ref = shift; fgfs_get("/autopilot/KAP140/locks/pitch-axis", $ref) or get_exit(-2); # = true/false return 1; } sub fgfs_get_K_pm($) { my $ref = shift; fgfs_get("/autopilot/KAP140/locks/pitch-mode", $ref) or get_exit(-2); # = 1/0 return 1; } sub fgfs_get_K_ra($) { my $ref = shift; fgfs_get("/autopilot/KAP140/locks/roll-axis", $ref) or get_exit(-2); # = true/false return 1; } sub fgfs_get_K_rm($) { my $ref = shift; fgfs_get("/autopilot/KAP140/locks/roll-mode", $ref) or get_exit(-2); # = 1/0 return 1; } sub fgfs_get_K_locks() { my ($ah,$pa,$pm,$ra,$rm); fgfs_get_K_ah(\$ah); fgfs_get_K_pa(\$pa); fgfs_get_K_pm(\$pm); fgfs_get_K_ra(\$ra); fgfs_get_K_rm(\$rm); my $rk = get_curr_Klocks(); ${$rk}{'time'} = time(); ${$rk}{'ah'} = $ah; ${$rk}{'pa'} = $pa; ${$rk}{'pm'} = $pm; ${$rk}{'ra'} = $ra; ${$rk}{'rm'} = $rm; return $rk; } sub show_K_locks($) { my $rk = shift; my ($tm,$ah,$pa,$pm,$ra,$rm); $tm = lu_get_hhmmss_UTC(${$rk}{'time'}); $ah = ${$rk}{'ah'}; $pa = ${$rk}{'pa'}; $pm = ${$rk}{'pm'}; $ra = ${$rk}{'ra'}; $rm = ${$rk}{'rm'}; prt("$tm: KLOCKS: ah=$ah, pa=$pa, pm=$pm, ra=$ra, rm=$rm\n"); } sub show_K_locks_change() { my $ret = 0; my $rk = get_curr_Klocks(); if (defined ${$rk}{'time'}) { my %curr = %{$rk}; $rk = fgfs_get_K_locks(); # KLOCKS: ah=false, pa=false, pm=0, ra=false, rm=0 if ((${$rk}{'ah'} ne $curr{'ah'})|| (${$rk}{'pa'} ne $curr{'pa'})|| (${$rk}{'pm'} != $curr{'pm'})|| (${$rk}{'ra'} ne $curr{'ra'})|| (${$rk}{'rm'} != $curr{'rm'})) { show_K_locks($rk); $ret = 1; } } else { show_K_locks(fgfs_get_K_locks()); $ret = 1; } return $ret; } # =============================================== sub is_show_time() { my $ct = time(); if ($last_show_time == 0) { $begin_show_time = $ct; $last_show_time = $ct; return 1; } elsif ($ct >= ($last_show_time + $show_interval)) { $last_show_time = $ct; return 1; } return 0; } sub check_keyboard() { my ($char,$val,$pmsg); if (got_keyboard(\$char)) { $val = ord($char); $pmsg = sprintf( "%02X", $val ); if ($val == 27) { prtt("ESC key... Exiting...\n"); return 1; } elsif ($char eq 't') { if ($targ_ygil) { $targ_ygil = 0; prtt("Setting YDSU as target...\n"); } else { $targ_ygil = 1; prtt("Setting YGIL as target...\n"); } } else { prtt("Got keyboard input hex[$pmsg]...\n"); } } return 0; } sub show_items() { while (1) { return if (check_keyboard()); if (is_show_time()) { my $chg = 0; #prtt("Get 'sim' information...\n"); # show_sim_info(fgfs_get_sim_info()); $chg += show_sim_info_change(); # show engine #show_engine(fgfs_get_engine()); $chg += show_engine_change(); #prtt("Get Fuel - comsumables...\n"); #show_consumables(fgfs_get_consumables()); $chg += show_consumables_change(); #prtt("Getting current COMMS...\n"); #show_comms(fgfs_get_comms()); $chg += show_comms_change(); # show brakes #show_brakes(fgfs_get_brakes()); $chg += show_brakes_change(); # position show_position(fgfs_get_position()); # AUTOPILOT #show_K_locks(fgfs_get_K_locks()); $chg += show_K_locks_change(); #prtt("Getting current environment...\n"); #show_environ(fgfs_get_environ()); $chg += show_environ_change(); my $elap = secs_HHMMSS($last_show_time - $begin_show_time); prtt("No significant change in other items. Elap $elap\n") if ($chg == 0); } } } sub show_intervals() { if (@intervals) { my ($ok,$btm,$ntm,$dtm); $ok = scalar @intervals; $btm = 0; foreach $ntm (@intervals) { $btm += $ntm; } $dtm = $btm / $ok; prtt("$ok accesses took $btm secs, av $dtm per access...\n"); # 39 accesses took 15.568619 secs, avarage 0.399195358974359 per access... } else { prtt("What no intervals...\n"); } } ### MAIN ### ================================================ ############################################################# if (scalar @ARGV < 2) { give_help(); } $HOST = $ARGV[0]; $PORT = $ARGV[1]; prtt("Set host $HOST, port $PORT - get connection\n"); $FGFS_IO = fgfs_connect($HOST, $PORT, $TIMEOUT) || (prtt("ERROR: can't open socket! Is FG running, with TELNET enabled?\n") and exit(1)); if ($set_bin_mode) { binmode $FGFS_IO; # try binmode on connection } fgfs_send("data"); # switch exchange to data mode ReadMode('cbreak'); # sets mode 4 for keyboard - could maybe use 5 = raw??? show_items(); # forever loop, until ESC key ReadMode(0); # restore normal mode show_intervals(); close_fgfs_io(); ReadMode(0); # restore normal mode exit(0); ### END ### ================================================= ############################################################# # eof