Toistinaseman mainostaminen APRS-asemille

Radioamatööriwikistä
Versio hetkellä 19. joulukuuta 2010 kello 18.06 – tehnyt >OH6KTT (bugitfiksi. Etäisyydet kilometreinä mailien sijaan. Plain formaatissa oleviin koordinaatteihin dec.min.min/100 -> dec.desimaali muunnos.)
Siirry navigaatioon Siirry hakuun


Scripti joka OH6RUC:llä tutkii aprs-rf.logia. Jos asema radiolla kuultu asema on lähempänä kuin 30km niin sille mainostetaan ripiitteriä puheella. Puhe tehdään festival puhesyntetisaattorilla. Tämä sivu on täällä koska #RNET kanavalla kysyttiin miten tuo on tehty.

#!/usr/bin/php -q
<?php
/*
    aprs-repeater-advertiser.php v1.03 - repeater advertiser to APRS users
    Copyright (C) 2010  Kari Karvonen <oh6ktt@toimii.net>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/
$aprxrflogfile 	= "/tmp/aprx-rf.log";
$stationdbfile	= "/tmp/oh6ruc-aprs-db.txt";
$repeater_call  = "OH6RUC"; /* need to match aprs-rf.log */
$repeater_lat	= "63.53666";
$repeater_lon	= "23.69180";
$floodprotect	= 60*60*24; /* after this time old station will be notified again. Seconds. */
$maxdistance	= 30; /* km */
$denytxfile	= "/tmp/ptt-on"; /* if this file exist, no announcement will be send */
$debug		= false;
$prefixwave	= "/opt/thelinkbox/wav/aprs-repeater-advertiser-1.wav"; /* wave before callsigns */
$suffixwave	= "/opt/thelinkbox/wav/aprs-repeater-advertiser-2.wav"; /* wave after callsigns */
$tempwavetxt 	= "/tmp/aprs-repeater-advertiser.txt";
$tempwave 	= "/tmp/aprs-repeater-advertiser.wav";

/* code begins */
$parserdb	= array();
$victims	= array();
$stationdb	= unserialize(@file_get_contents($stationdbfile));
if (empty($stationdb)) $stationdb = array();
$aprxrflog 	= @file($aprxrflogfile);
if ($aprxrflog == false) die("Cannot open $aprxrflogfile\n");


function convertDDD($deg, $min, $decsec) {
        if ($deg == "" || $min == "" || $decsec == ""){
                        die("Make a valid entry for DDD, MM and SS.");
        }
        else if ($deg > 180 || $deg < 0){
                        die("Enter a value between 0 and 180 degrees.");
        }
        else if ($min > 60 || $min < 0){
                        die("Enter a value between 0 and 60 minutes.");
        }
        else if ($secsec > 99 || $decsec < 0){
                        die("Enter a value between 0 and 60 seconds.");
        }
        else {
                $dec=intval($deg);
                $decmin = intval($min/60.0*100.0);
                $decsec= intval($decsec);
                return($deg + $decmin/100 + $decsec/(100*100));
        }
}


function decimal_distance($lat1 = "", $lon1 = "", $lat2 = "", $lon2 = "") {
        //$radius is determined using the following formula
        //(360 degrees)*(60 minutes per degree)*(1.852) km per minute
        //give a circumference of 40003.2 km
        //radius is circumference/(2*pi) which gives us 6637km or 3956miles
        $radius = 6637;
        $lat1 = deg2rad ($lat1);
        $lat2 = deg2rad ($lat2);
        $lon1 = deg2rad ($lon1);
        $lon2 = deg2rad ($lon2);
        //Haversine Formula (from R.W. Sinnott, "Virtues of the Haversine",
        //Sky and Telescope, vol. 68, no. 2, 1984, p. 159):
        $dlon = $lon2-$lon1;
        $dlat = $lat2-$lat1;
        $sinlat = sin($dlat/2);
        $sinlon = sin($dlon/2);
        $a = ($sinlat * $sinlat) + cos($lat1) * cos($lat2) * ($sinlon*$sinlon);
        $c = 2 * asin(min(1,sqrt($a)));
        $d = $radius * $c;
        return round($d,2);
}

for ($tmp = 0; $tmp < count($aprxrflog); $tmp++) {
        $line = $aprxrflog[$tmp];
        if (preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{3}) '.$repeater_call.'    R (.+)>(.+),'.$repeater_call.'(.+):\!(.+)/', $line, $matches)) {
                $callsign = strtolower(trim($matches[8]));
                if (preg_match('/([0-9.]{7})N\/([0-9.]{8})E/',$matches[11],$plaincoords)) {
                        /* coordinates are plain format */
                        $coordtype = "plain";
                        $rawlat = $plaincoords[1];
                        $rawlong = $plaincoords[2];
                        if (preg_match('/([0-9]{2})([0-9]{2}).([0-9]{1,})/', $rawlat, $lathits)) {
                                 $lat = convertDDD($lathits[1], $lathits[2], $lathits[3]);
                        }
                        if (preg_match('/([0-9]{3})([0-9]{2}).([0-9]{1,})/', $rawlong, $longhits)) {
                                 $long = convertDDD(intval($longhits[1]), $longhits[2], $longhits[3]);
                        }
                } else {
                        /* coordinates are packet */            
                        $coordtype = "packed";
                        $y1 = ord(substr($matches[11],1,1));
                        $y2 = ord(substr($matches[11],2,1));
                        $y3 = ord(substr($matches[11],3,1));
                        $y4 = ord(substr($matches[11],4,1));
                        $x1 = ord(substr($matches[11],5,1));
                        $x2 = ord(substr($matches[11],6,1));
                        $x3 = ord(substr($matches[11],7,1));
                        $x4 = ord(substr($matches[11],8,1));
                        $lat = 90 - (($y1-33) * 91*91*91 + ($y2-33) * 91*91 + ($y3-33) * 91 + $y4-33) / 380926;
                        $long = -180 + (($x1-33) * 91*91*91 + ($x2-33) * 91*91 + ($x3-33) * 91 + $x4-33) / 190463;
                }
                $distance = decimal_distance($repeater_lat, $repeater_lon, $lat, $long);
                $lastheard  =  mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
                $parserdb[$callsign] = array("lastheard" => $lastheard, "distance" => $distance, "lat" => $lat, "long" => $long, "coordtype" => $coordtype);
        }
}

function callsign2finnish($callsign) {
	$chartospeech = array();
	$chartospeech["-"] = "viiva";
	$chartospeech["a"] = "aa";
	$chartospeech["b"] = "bee";
	$chartospeech["c"] = "see";
	$chartospeech["d"] = "dee";
	$chartospeech["e"] = "ee";
	$chartospeech["f"] = "äf";
	$chartospeech["g"] = "gee";
	$chartospeech["h"] = "hoo";
	$chartospeech["i"] = "hee";
	$chartospeech["j"] = "jii";
	$chartospeech["k"] = "koo";
	$chartospeech["l"] = "äl";
	$chartospeech["m"] = "äm";
	$chartospeech["n"] = "äm";
	$chartospeech["o"] = "oo";
	$chartospeech["p"] = "pee";
	$chartospeech["q"] = "kuu";
	$chartospeech["r"] = "är";
	$chartospeech["s"] = "äs";
	$chartospeech["t"] = "tee";
	$chartospeech["u"] = "uu";
	$chartospeech["v"] = "vee";
	$chartospeech["w"] = "tuplavee";
	$chartospeech["x"] = "äks";
	$chartospeech["y"] = "yy";
	$chartospeech["z"] = "tseta";
	$chartospeech["å"] = "oo";
	$chartospeech["ä"] = "ää";
	$chartospeech["ö"] = "öö";
	$chartospeech["1"] = "yks";
	$chartospeech["2"] = "kaks";
	$chartospeech["3"] = "kol";
	$chartospeech["4"] = "nel";
	$chartospeech["5"] = "viis";
	$chartospeech["6"] = "kuus";
	$chartospeech["7"] = "seiska";
	$chartospeech["8"] = "kasi";
	$chartospeech["9"] = "ysi";
	$chartospeech["0"] = "nolla";
	$msg = "";
	for ($tmp = 0; $tmp<strlen($callsign); $tmp++) {
		$character = substr($callsign,$tmp,1);
                /* don't say -9 */
		if ($character == "-") {
		        return $msg;
                }
		$vocal = $chartospeech[$character];
		$msg.= $vocal;		
	}
	return ($msg);
}

ksort($parserdb);
foreach ($parserdb as $callsign => $attcheddata) {
	$distance = $attcheddata["distance"];
	$lastheard = $attcheddata["lastheard"];
	$lat = $attcheddata["lat"];
	$long = $attcheddata["long"];
	$coordtype = $attcheddata["coordtype"];
	$lastheardtxt = date("r", $lastheard);
	if ($debug) echo "Call $callsign. Distance $distance km. Lat $lat, long $long, coordtype $coordtype. Lastheard $lastheardtxt. ";
	if (array_key_exists($callsign, $stationdb)) {
		if ($debug) echo "Found from stationdb. ";
		if ($stationdb[$callsign]["lastheard"]<(time()-$floodprotect) && $lastheard>$stationdb[$callsign]["lastheard"]) {
		        if ($debug) echo "Floodprotect disabled. ";
		        if ($distance < $maxdistance) {
				/* Exists in stationdb. Too old and inside circle */
				if ($debug) echo "Inside circle $maxdistance km cicle. Update stationdb. Add to victims.";
				$victims[] = $callsign;
				$stationdb[$callsign]["lastheard"] = $lastheard;
				$stationdb[$callsign]["distance"] = $distance;
			} else {
				/* Station too far */
				if ($debug) echo "Outside circle $maxdistance km circle. Update stationdb.";
				$stationdb[$callsign]["lastheard"] = $lastheard;
				$stationdb[$callsign]["distance"] = $distance;
			}
		} else {
		        if ($debug) echo "Floodprotect enabled. Update stationdb. ";
                        $stationdb[$callsign]["lastheard"] = $lastheard;
                        $stationdb[$callsign]["distance"] = $distance;
		}
	} else {
		if ($debug) echo "Not found from stationdb. ";
		if ($distance < $maxdistance) {
			if ($debug) echo "Inside ${maxdistance}km circle. Update stationdb. Add to victims.";
			$victims[] = $callsign;
			$stationdb[$callsign]["lastheard"] = $lastheard;
			$stationdb[$callsign]["distance"] = $distance;
		} else {
			if ($debug) echo "Outside ${maxdistance}km circle. Ignore.";
		}
	}
	if ($debug) echo "\n";
}

file_put_contents($stationdbfile, serialize($stationdb));

$msg = "";
if (count($victims) == 0) {
        /* do nothing */
} else {
        if (!file_exists($denytxfile)) {
                @unlink($tempwavetxt);
                @unlink($tempwave);
                foreach ($victims as $victim) {
                        $msg .= callsign2finnish($victim).", ";
                }
                $msg=substr($msg,0,-2);
                if ($debug) echo "$msg\n";
                if (!$debug) file_put_contents($tempwavetxt, utf8_decode($msg));
                if (!$debug) system("/usr/bin/text2wave -F 8000 < ".$tempwavetxt." -o ".$tempwave);
                if (!$debug) system("/usr/sbin/tlbcmd \"port OH6RUC-Kaustinen; say -c ".$prefixwave."; say -c ".$tempwave."; say -c ".$suffixwave."\"");                
        } else {
                if ($debug) echo "Cannot advertise. Advertises denied by $denytxfile lock file.\n";
        }
}
?>