Beacon your hotspot(s) to APRS with linked refelectors/TGs in comment.

Post your tips and tricks here
NQ4T
Posts: 46
Joined: Mon Aug 06, 2018 11:48 pm

Beacon your hotspot(s) to APRS with linked refelectors/TGs in comment.

Post by NQ4T » Wed May 01, 2019 4:07 am

So I'm getting ready to drive cross country here in about six weeks for Field Day and in the process of "getting ready" I started planning my radio setup for the drive out. I had already planned on running APRS both over RF and LTE for fun and so my friends could follow me on the trip. Planning on using at least one hotspot while on the road, the thought occurred to me as to how I could somehow "publish" what reflectors/TGs my radio was on without any interaction from me other than operating from my radio as normal. I poked around mmdvmhost and pi-star looking to see what kind of features it may have offered. While I know this setup can pass GPS information from the radios, that essentially won't work for me. The Kenwood doesn't seem to send GPS information in a way I've ever been able to see the hotspot use (and i'm pretty sure I had it turned on in digital options); and my MD380 lacks GPS. My FT2D is going to be hooked up for mobile duty...running APRS and whatever simplex/local analog repeaters I come across.

I realized I would have to build something like this myself and "bolt it on". I'm maybe about 50% of the way there, but it was what I considered to be the toughest 50%; somehow scraping real-time connection data from pi-star and then somehow combining it with GPS data to send it to APRS-IS. So for the impatient...I present this script:

Code: Select all

#!/bin/bash
# erase previous data
rm gps.txt
#rm tg.txt
rm dstar.txt
# get gps info, parse it, write to file
gpspipe -n 8 -r|sed -n '/$GPGGA/{p;q}'|cut -b 19-42|sed 's#N,#N\\#g'|sed 's#,##g'|cut -b 1-7,10-19,22 > gps.txt
# get DMR TG info, parse it, write it to file
#curl -s http://pi-star.local/mmdvmhost/bm_links2.php| sed 's/<[^>]\+>//g' | sed 's/None//g' | sed ':a;N;$!ba;s/\n/ /g'|sed 's/TG/#/g' > tg.txt
# scrape for dstar reflector
curl -s http://pi-dstar.local/mmdvmhost/repeaterinfo.php | egrep "Linked to" | sed 's/<[^>]\+>//g' | sed 's/Linked to //' > dstar.txt
#Define login info
user=<URCALL>
password=*******
#Define object user info
senduser=URCALL-SSID
#Define station location
gps=$(<gps.txt)
#DMR ONLY
#comment="BrandMeister TGs: "$(<tg.txt)
#DSTAR Only
if [ -s dstar.txt ]
then
        comment="D-Star Linked To: "$(<dstar.txt)
else
        comment="D-Star Not Linked"
fi
data="{$senduser}>APN100,TCPIP*:=${gps}> ${comment}"
#Send data to the server
# make sure your packets are correct before piping to ncat
printf "%s\n" "user $user pass $password" "$data"
#| ncat rotate.aprs2.net 14580
So let me try to explain a little of what I'm doing in this hack-job. Currently I have a Pi3B with a GPS configured to be a stratum-1 NTP server; I did this because in case we wanted to run a time-sensitive digital mode at our remote field day location. I did a lot of the development and testing of the script on that Pi as opposed to the hotspot, so there are two ways this will ultimately wind up working; either each hotspot running a copy of this script and physically pushing to APRS-IS, or the Pi3 with the NTP server will be pushing the data out. The limitation right now is getting gpsd to install on the hotspots and getting sockets to stop binding gpsd to localhost on the ntp server.

Either way, we get 8 packets or NEMA messages from gpspipe. Then I filter it for just the GPGA, manually cut out what I need since the length of the sentence is the same every time, then I preparse it for what I want to inject in to my APRS packet; remove the commas from NEMA, add a back-slash between the coordinates (it's part of the icon selection), then trim out what I need. Scraping for active connections happens one of two ways depending on your mode. For D-Star, we just pull the repeater info frame, egrep for Linked To, strip HTML, and just filter out the reflector name. DMR required me hacking the existing bm_links.php file so it displayed just the static and dynamic talk groups. Cut the line breaks, filter out "None", and change TG to #.

The rest of the script just loads the text files and ultimately parses an APRS packet it pushes with ncat..with the car icon. It will catch if the dstar.txt is blank due to not being connected; but I didn't add it to the DMR as I plan on having at least one static TG at all times.

Naturally this will be implemented by simply running the script as a cron-job.

73 de NQ4T

NQ4T
Posts: 46
Joined: Mon Aug 06, 2018 11:48 pm

Re: Beacon your hotspot(s) to APRS with linked refelectors/TGs in comment.

Post by NQ4T » Wed May 01, 2019 2:10 pm

I did a little more playing last night. I stuck a beta of v4 on one my Pis to see about getting gpsd going.

I had some success...but ultimately I hit two snags. One was I couldn't get gpsd to work the way I wanted, the second was I didnt need gpsd working at all. Turns out gpspipe will just connect to whatever gpsd server I specify.

Tonight I'll try this on the hotspots running the stable version now that I have some kind of idea of what needs to be done. Then Ill let it run for a while to see if the script operation makes the rest of the system lag.

NQ4T
Posts: 46
Joined: Mon Aug 06, 2018 11:48 pm

Re: Beacon your hotspot(s) to APRS with linked refelectors/TGs in comment.

Post by NQ4T » Thu May 02, 2019 11:54 pm

After further testing and some refinement, I have a version of this script that will run on the non-beta version of Pi-Star. I now write all data to variables instead of to the disk. In addition, I have added a feature to check if our gps sync is valid; it simply looks for a 0 in that part of the NEMA GPGGA sentence and exits if it finds one. I did not add a network-check as I suspect the script will just fail if ncat can't communicate with the server. I will play around with this later to make sure the exit is somewhat graceful.

TODO:
Optimize?
Modify the APRS routing target (someone said I should)

Code: Select all

#!/bin/bash
# load nema sentence from GPS
gpsr=$(gpspipe -n 8 -r gpsdaddress:2947|sed -n '/$GPGGA/{p;q}')
#GPS Sync Check - if no GPS lock, no run
gpss=$(printf "$gpsr" | cut -d ',' -f7)
test  "$gpss" = "0" && exit
#we didn't exit so we can continue
gps=$(printf "$gpsr" | cut -b 19-42|sed 's#N,#N\\#g'|sed 's#,##g'|cut -b 1-7,10-19,22)
#Define login info
user=URCALL
password=URPASS
#Define object user info
senduser=URCALL-SSID
#Define comment - DMR ONLY
# get DMR TG info, parse it, write it to file
#dmr=$(curl -s http://pi-stardmr.local/mmdvmhost/bm_links2.php| sed 's/<[^>]\+>//g' | sed 's/None//g' | sed ':a;N;$!ba;s/\n/ /g'|sed 's/TG/#/g')
#comment="BrandMeister TGs: $tg"
#Define data - DSTAR Only
dstar=$(curl -s http://pi-dstar.local/mmdvmhost/repeaterinfo.php | egrep "Linked|linked" | sed 's/<[^>]\+>//g' | sed 's/L/l/')
comment="DStar $dstar"
data="$senduser>APN100,TCPIP*:=$gps> $comment"
#Send data to the server
#By default the command to pipe output to ncat is disabled.
#only uncomment and merge the lines when you are sure your
#setup is working. Just delete the # and resulting line break,
#it should all be one line.
printf "%s\n" "user $user pass $password" "$data"
#| ncat rotate.aprs2.net 14580

In order to utilize this script, you need to install the following on your hotspot: gpsd-clients will automatically install gpsd. GPSD WILL THROW AN ERROR DURING INSTALL. I know it is related to being unable to create the .socket due to "address in use". This is not even important, gpsd is dependency for the gpsd-clients package which provides gpspipe.

The modified bm_links2.php file should reside in your /var/www/dashboard/mmdvmhost/ folder and renamed to drop the .txt file. You can copy/paste it in to shell to write it or use wget. If you don't use DMR you can skip this step. It currently only works for Brandmeister as that's pretty much all I use. I also don't really run YSF, P25, or NXDN; so I have no clue how difficult it'd be to add those. YSF can probably use the slightly modified DStar routine since it's one reflector at a time. Brandmeister is done this way since we can have multiple static and dynamic TGs. DStar reflector scraping has also been changed; swapping out the if statement and just pulling the entire field

I have not tested dynamic TGs yet..I'm going on the theory that they will also show up since the script largely just deletes all line-breaks and displays the content, removing the word "None" where Dynamic TGs show up if it's there.

You will need to modify the script with your Callsign/user, APRS-IS passcode, and your APRS object to match what you use. Actual piping to ncat is disabled by default, the output will display on the screen so you can make sure you're getting the expected output before going live. It should look something like this:

Code: Select all

[email protected](rw):~$ ./aprs.sh
user NQ4T pass ****
NQ4T-10>APN100,TCPIP*:=3843.64N\07725.96W> D-Star linked to: REF001 C
When the pipe to ncat is enabled and we send live data, the script will return with this:

Code: Select all

[email protected](rw):~$ ./zzzzliveaprsdontrunzzz.sh
# aprsc 2.1.4-g408ed49
# logresp NQ4T verified, server T2IRELAND
Currently the script displays the overlaid car icon, it is hard-coded to do this. Changing it requires modifying the script in a couple of places. The first is where it extracts and parses the GPS coordinates.

Code: Select all

gps=$(printf "$gpsr" | cut -b 19-42|sed 's#N,#N\\#g'|sed 's#,##g'|cut -b 1-7,10-19,22)
By default this selects the alternative set of icons (\). If you want to change to the "standard" icons, you need to change the line to this:

Code: Select all

gps=$(printf "$gpsr" | cut -b 19-42|sed 's#N,#N/#g'|sed 's#,##g'|cut -b 1-7,10-19,22)
The actual selection of icon is done by using the character immediately following the GPS information:

Code: Select all

data="$senduser>APN100,TCPIP*:=$gps> $comment"
In this case, we send ">" which is the symbol for index 29. You can refer to this APRS Symbol chart for which table and which symbol you should use.

To go through the process each step (for those who are still confused):

First thing we do is we ask gpspipe to connect to our gpsd (in my case a Pi NTP server with GPS) and receive 8 lines of raw NEMA, then exit. At some point in those 8 lines we will have one $GPGGA sentence which contains our location and gps-sync status. We filter out the sentence of interest and stuff it in to a variable.

Now we take the data in the variable we just wrote, treat it like a CSV file, and read the "7th field". This "7th field" should be either 1 if we have GPS lock, or a 0 if we don't. We can have other numbers...but it's unlikely I'll have them without specifically goofing (like activating fakegps). If we have a 0 here, we just leave the script; there's no point in running the rest if GPS is gone.

If the data we did get was valid, we take the GPS coordinate information, drop the last two decimal places (it can't be that critical), then format it for insertion to our APRS packet. The selection of the standard or alternate icons takes place here in the form of the seperator between lat and long.

Now we scrape data for reflector or talkgroup information. In the case of D-Star, we're just going to read the repeaterstatus.php page, grep it for both spellings of "linked", strip the HTML out of that line, and change the capital L to a lowercase one. The case change just looks nicer (to me) since I append stuff in front. An overall case change wasn't desired as I do want REF/XRF/DCS to remain capitalized. With Brandmeister it's a little different. The modified php file basically just displays talkgroup information instead of the entire table. We read this file, remove all line breaks, change "TG" to "#", and remove the word "None" that appears if you have no dynamic TG's going. We also slip the entire comment in to it's variable.

From there we simply parse our dynamic information in with the pieces of the header that remain static and write that do a variable.

Last step is to parse the information we'll pipe through ncat, and pipe through ncat.

NQ4T
Posts: 46
Joined: Mon Aug 06, 2018 11:48 pm

Re: Beacon your hotspot(s) to APRS with linked refelectors/TGs in comment.

Post by NQ4T » Fri May 03, 2019 2:28 pm

"Remote" activation:

It occurred to me that scheduling the script to run could easily be done with cron running it every so many minutes. This would fit within my requirements of a "hand-off" approach due to driving as it's one of the things that can be done when stopping for whatever break is required. But I began wondering if I couldn't somehow have some kind of minimal control via WWW. We know this is possible given the fact the pistar interface allows us to make modifications to the system.

For some reason I thought cronjob-ui would be appropriate...it was also the only thing that crept up when looking for remote cron management. It required node.js and while I did have it installed; I began realizing with the ro only aspect of the filesystem, this may pose some problems. I'm also not the biggest fan of node.js anyway even though I know nothing about web application development.

So I ran the good ol 'mount utility to see what tempfs mounts I had and how big they were; and while there were a plethora of ones available, the obvious one jumped out at me, /tmp. I couldn't see where anything was set to automatically clean /tmp out except a reboot, and I found full read-write access available to all users. So once again I had this basic piece of information to build from.

So my first tests were to see if I could get PHP to actually do what I wanted. I found some example code on the subject, copied it, and modified it for my purposes:

Code: Select all

<?php
$myfile = fopen("/tmp/aprs", "w") or die("Unable to open file!");
$txt = "1\n";
fwrite($myfile, $txt);
?>
When I load the appropriate file in my browser, aprson.php; I get absolutely no output, just a blank page. But what's important is that php creates the file "aprs" in /tmp filling it with just a "1". I created another one, aprsoff.php, which overwrites /tmp/aprs with absolutely nothing.

My overall idea with this is to set the script to run in cron all the time but control the actual operation with an if statement. If /tmp/aprs exists and is a non-zero value; then the script will continue. If it doesn't exist or is empty, then the script will exit. The file *should* only be empty if I activate the script, and it should only be non-existent after a reboot and before I activate it; so this should work nicely. I guess after I get that done I'll try to code a php page that will give me some buttons to turn the aprs on and off as well as read the status. I've been meaning to learn php for probably 20 years anyway.

NQ4T
Posts: 46
Joined: Mon Aug 06, 2018 11:48 pm

Re: Beacon your hotspot(s) to APRS with linked refelectors/TGs in comment.

Post by NQ4T » Fri May 03, 2019 3:11 pm

Well, that didn't take long. Turns out I had problem with if statements because I didn't have my spaces set properly.

The script now responds to the presence and content of /tmp/aprs, which is written by PHP. If the file is non-existant or blank, we simply exit the script. If it's not blank, then it will continue execution.

Code: Select all

#!/bin/bash
# should we run APRS script?
[ ! -s "/tmp/aprs" ] && exit
# load nema sentence from GPS
gpsr=$(gpspipe -n 8 -r ntpi:2947 |sed -n '/$GPGGA/{p;q}')
#GPS Sync Check - if no GPS lock, no run
gpss=$(printf "$gpsr" | cut -d ',' -f7)
#test  "$gpss" = "0" && exit
gps=$(printf "$gpsr" | cut -b 19-42|sed 's#N,#N\\#g'|sed 's#,##g'|cut -b 1-7,10-19,22)
#Define login info
user=CALL
password=PASS
#Define object user info
senduser=CALL-SSID
#DMR
#tg=$(curl -s http://127.0.0.1/mmdvmhost/bm_links2.php| sed 's/<[^>]\+>//g' | sed 's/None//g' | sed ':a;N;$!ba;s/\n/ /g'|sed 's/TG/#/g')
#comment="BrandMeister TGs: $tg"
#DSTAR
dstar=$(curl -s http://127.0.0.1/mmdvmhost/repeaterinfo.php | egrep "Linked|linked" | sed 's/<[^>]\+>//g' | sed 's/L/l/')
comment="DStar $dstar"
#parse packet
data="$senduser>APN100,TCPIP*:=$gps> $comment"
#Send data to the server
printf "%s\n" "user $user pass $password" "$data"
#| ncat rotate.aprs2.net 14580


NQ4T
Posts: 46
Joined: Mon Aug 06, 2018 11:48 pm

Re: Beacon your hotspot(s) to APRS with linked refelectors/TGs in comment.

Post by NQ4T » Fri May 03, 2019 7:29 pm

So progress is going so fast I hate to ruin the momentum, but while I have a chance to stop and research my next step I'll share what I've got.

I took the PHP control of the script using my hacky way to hack together some status indicator. My idea is to have a single page that will tell me if the APRS script is currently active and then provide links to turn it on or off.

Code: Select all

<?php
$aprs=fopen("/tmp/aprs", "a+");
if (filesize ("/tmp/aprs") == 0){
    echo "APRS is OFF";
} else {
    echo "APRS is ON";
}
fclose($aprs)
?>

NQ4T
Posts: 46
Joined: Mon Aug 06, 2018 11:48 pm

Re: Beacon your hotspot(s) to APRS with linked refelectors/TGs in comment.

Post by NQ4T » Fri May 03, 2019 9:32 pm

My very basic "web-ui" (if you can call it that) is functional. I combined some javascript I borrowed from something I found online and just redirect to the aprs.php page after a small period of time. I also show function of DStar data scraping.

No data was sent to APRS-IS during this.


SP2ONG
Posts: 39
Joined: Fri Aug 10, 2018 5:05 am

Re: Beacon your hotspot(s) to APRS with linked refelectors/TGs in comment.

Post by SP2ONG » Sat May 04, 2019 6:44 am

Hi,

I modified the BM script to send co-ordinates to aprs.fi by downloading co-ordinates from the Pi-star configuration.

http://sp2ong.noip.pl/pl/blog/hotspot-na-aprs-fi

Another description describes how to use GPS and alpine G4KLX MobileGPS which updates the coordinates on BM . The script gets the coordinates from MobileGPS and sends the data to aprs.fi

http://sp2ong.noip.pl/pl/blog/mobile-gps-i-hotspot

Descriptions are in Polish language but you can use google translator

NQ4T
Posts: 46
Joined: Mon Aug 06, 2018 11:48 pm

Re: Beacon your hotspot(s) to APRS with linked refelectors/TGs in comment.

Post by NQ4T » Sat May 04, 2019 1:43 pm

SP2ONG wrote:
Sat May 04, 2019 6:44 am
Hi,

I modified the BM script to send co-ordinates to aprs.fi by downloading co-ordinates from the Pi-star configuration.

http://sp2ong.noip.pl/pl/blog/hotspot-na-aprs-fi

Another description describes how to use GPS and alpine G4KLX MobileGPS which updates the coordinates on BM . The script gets the coordinates from MobileGPS and sends the data to aprs.fi

http://sp2ong.noip.pl/pl/blog/mobile-gps-i-hotspot

Descriptions are in Polish language but you can use google translator
The main reason I didn't use the co-ordinates in Pi-Star is they're mostly static unless you reboot mmdvmhost...and this functionality already seems built in to the system. If you look up NQ4T-R and NQ4T-N on APRS.fi, you'll find packets from august that were sent to aprs by Pi-Star automatically. In fact NQ4T-B is beaconing the wrong information because I forgot to disable APRS in the Pi-Star configuration on my second hotspot. I also seem to recall Brandmeister was also inserting my information in to APRS.FI based on the coordinates in the Pi-star configuration. So while I knew Pi-Star had coordinate information and auto beaconed the hotspot, the problem is that is a largely static location requiring reloading of mmdvmhost to take effect.

I built this to facilitate displaying both my location and my connected talkgroups while driving across the country. So instead of just a static comment saying it's "Pi-Star DMR", it will display "Brandmeister TGs: #whatever #whatever2 #whatevever3" based on my currently connected dynamic and static groups; for D-Star it will display "DStar linked to <reflector module>" or "DStar not linked". It gets that by scraping information I get from the dashboard.

My use of gpsd for location was a matter of convenience; I already had a Pi with a GPS HAT I was taking with me. The MobileGPS portion could be useful for my script if someone wanted to plug a GPS dongle directly in to the hostpot and poll gps data that way. I don't have a GPS dongle to test this so I didn't work on adding it.

But the main thing is the current connections as comments. I'd like my friends who want to "check in with me" to be able to find me on the map and see what groups I'm connected to without me having to constantly manually change a comment...I am going to be driving so I needed to automate this as much as possible. I also didn't want it to consume a lot of time to get going since my Pi's will likely power down when I turn the car off to do things like fill up with gas or take a quick driving break.

SP2ONG
Posts: 39
Joined: Fri Aug 10, 2018 5:05 am

Re: Beacon your hotspot(s) to APRS with linked refelectors/TGs in comment.

Post by SP2ONG » Sat May 04, 2019 2:18 pm

Hi NQ4T

The nice idea put information about own TG in APRS message. I have add to my script to generate a list of TG base on your bm_links2.php and send information about TG as the status aprs message.


73 Waldek SP2ONG

Post Reply