In my previous post I wrote about sending objects and telemetry via command line to APRS-IS server.
You can also do that with Xastir, but as a bonus point, you can do it all via RF if your Xastir setup is already paired to the radio and configured to transmit. You can use the scripts from my previous blog post, you only need to change some commands.
Xastir GUI is lacking options to send multiple different beacons or telemetry data. There is a binary called xastir_udp_client that comes with normal Xastir setup which takes care of that, but you need to run it from a command line and do some custom scripting. To use this feature, you need to enable server ports. Open xastir, go to interface menu and click enable server ports.
The basic commands to create an object with a house icon are:
Send via RF:
xastir_udp_client XastirIP port user passcode -to_rf 'senduser>APN100,WIDEPATH*:=latitude/longtitude-Comment'
xastir_udp_client 192.168.0.140 2023 S55MA-10 22558 -to_rf 'S55MA-10>APN100,WIDE2-1*:=4539.94N/01417.67E-QTH'
Send via Internet only (remove -to_rf):
xastir_udp_client XastirIP port user passcode 'senduser>APN100,TCPIP*:=latitude/longtitude-Comment'
xastir_udp_client 192.168.0.140 2023 S55MA-10 22558 'S55MA-10>APN100,TCPIP*:=4539.94N/01417.67E-QTH'
Why did I write “senduser” in string? Because you can place remote objects on the map that’s not your own call sign – sticking to the protocol rules, you need to change the code to show the correct path if you want to place objects with not your own sign. The only drawback with Xastir in this example is, it overrides your permanent timestamp (111111z). More info about sending objects with not your sign is in my previous post. Why is it so “cool” to collect and send data from another stations to RF? Let’s say you want to transmit critical data to offline users like repeater offset or echolink node number. You can also transmit weather data from other non RF stations to RF. So for example if I’m walking in the forest with my handheld APRS capable station I can receive weather or repeater data directly on my handheld without having the internet.
Example:
I’m collecting data from this weather station: https://www.hobolink.com/p/d0a7b4f0dbc44b973b0a5cce75a0521d and sending it to RF, including telemetry.
Another example is sending repeater and echolink data to RF:
You see that purple lines? That means the object was put on the map via my station (S55MA-10).
You can also see the path at the bottom of a white rectangle “[APN101 via WIDE2-1,qAR,S55MA-10]”
Note that this is actually faking an object, it looks like the transmitter is at the object and it’s
being igated by my station, but it’s actually my station doing the transmissions. This is a good example how to not
stick to the protocol rules 😉 I was unable to do it with xastir_udp_client binary, it rewrites it’s path if you want to send another
object. There is also a “bug” or a feature, I’m not sure yet, that xastir_udp_client inserts additional } in the string. I don’t know
why is that, but it’s unwanted.
If you want to show that remote object is put on the map by your station, you need to change the path as I mentioned above,
stick to the protocol, but I don’t think that’s possible with xastir_udp_client. I neglected this and I’m going to update my scripts
if I find the correct solution.
Example script I’m using to send Echolink data to RF:
#!/bin/bash #Transmit objects via Xastir to RF. #Define login info user=S55MA-10 password=23458 #Define object user info usersend=S55UPO-10 #Define xastir server server=192.168.0.140 port=2023 #Define station location (Echolink Postojna, Pecna Reber) lat=4546.72N lon=01413.80E #Define data comment="Echolink Postojna 438.825Mhz -7.6M T123 Node:609569" data="$usersend>APN101,WIDE2-1:=${lat}E${lon}0${comment}" #Send object to RF /usr/bin/xastir_udp_client $server $port $user $password -to_rf "$data" #Debugging #printf "$data\n"
Example of my hobolink weather collector script. Hobolink to APRS. It’s similar to the script in my previous post so I won’t go into details.
#!/bin/bash #Read data from HOBOlink station and send it to APRS network via Xastir. Server ports option has to be enabled on Xastir. #Create a temporary RAM disk (we don't want to write on a SD card too often). #You need to run this script as sudo (root) or create a temporary ramdisk at boot as root #and run this script as a normal user. if [ ! -d "/mnt/ramdisk/" ]; then mkdir -p /mnt/ramdisk; mount -t tmpfs tmpfs /mnt/ramdisk -o size=10m fi #Check if file exist if [ ! -f "/mnt/ramdisk/sequence_numberjavornik.txt" ]; then touch /mnt/ramdisk/sequence_numberjavornik.txt fi #Read sequence number read num < /mnt/ramdisk/sequence_numberjavornik.txt num=$((num + 1)) if (( num == 1000 )); then num=0 fi #Error log file error=/var/log/wxdata.log #Define login info user=S55MA-10 password=passcode #Insert the same as user. Insert other user sign if you want to put another station not owned by you on the map. Be aware that telemetry #requires 9 char long callsign so you need to add whitespaces after the callsign and telemetry, for example: #t2="$usersend>APN002,WIDE2-1::"$usersend" :PARM.Solar Radiation,Battery" #5 whitespaces between "$usersend" and :PARM because #S51Y is only 4 char long. usersend=S51Y #Define xastir server server=192.168.0.140 port=2023 #Define station location (Veliki Javornik, Postojna) lat=4545.48N lon=01417.72E_ #_ is a symbol for WX station #Download weather data file=/mnt/ramdisk/wxdata.txt file1=/mnt/ramdisk/wxdata1.txt curl -s https://www.hobolink.com/p/d0a7b4f0dbc44b973b0a5cce75a0521d | grep nobr | awk -F\> '{print $6}' | sed 's/<\/nobr//g' > "$file" curl -s https://www.hobolink.com/p/d0a7b4f0dbc44b973b0a5cce75a0521d | grep "Wind Direction" -A 1 | grep "latest-conditions-info-reading" | awk -F\> '{print $5}' | awk '{print $2}' | grep -o '[0-9]\+' > "$file1" if [ -s "$file" ] #If downloaded file is not empty, continue, else quit then #Date in UTC zuludate="$(date -u +%d%H%M)" #APRS needs temperature in F, data is fetched in degress C so we need to convert it. tempC="$(sed -n -e 1p "$file")" tempF="$(echo "((9/5) * $tempC) + 32" | bc -l | awk -F. '{print $1}')" #Relative humidity rh="$(sed -n -e 2p "$file" | awk -F. '{print $1}')" #APRS need windspeed in mph, data is fetched in meters per second so we need to convert it. windspeedms="$(sed -n -e 4p "$file")" windspeedmph="$(echo "(($windspeedms * 3.6) / 1.609344)" | bc -l | awk -F. '{print $1}')" gustsms="$(sed -n -e 5p "$file")" gustsmph="$(echo "(($gustsms * 3.6) / 1.609344)" | bc -l | awk -F. '{print $1}')" rain1h="$(sed -n -e 7p "$file" | awk -F. '{print $1}')" winddirection="$(cat "$file1")" solarradiation="$(sed -n -e 6p "$file")" #For telemetry only batteryvoltage="$(sed -n -e 8p "$file" | tr -d '.' | head -c 3)" #For telemetry only #Station comment aprscomment="Veliki Javornik 1268m asl" #Xastir weather variable with padding zeros for correct APRS format printf -v xastirwx "%03d/%03dg%03dt%03dr%03dh%02d%s" "$winddirection" "$windspeedmph" "$gustsmph" "$tempF" "$rain1h" "$rh" "$aprscomment" #Xastir user and WIDE path data xastirpath="$usersend>APN100,WIDE2-1:=$lat/$lon" #Telemetry printf -v t1 "%s>APN002,WIDE2-1:T#%03d,%03d,%03d,000,000,000,00000000" "$usersend" "$num" "$solarradiation" "$batteryvoltage" t2="$usersend>APN002,WIDE2-1::$usersend :PARM.Solar Radiation,Battery" t3="$usersend>APN002,WIDE2-1::$usersend :UNIT.W/m2,Volts" #Add coefficient in EQNS field to convert real data. t4="$usersend>APN002,WIDE2-1::$usersend :EQNS.0,1,0,0,0.01,0,0,0,0,0,0.0,0,0,0,0" t5="$usersend>APN002,WIDE2-1::$usersend :BITS.00000000,Weather station Veliki Javornik Postojna" #Send data to Xastir /usr/bin/xastir_udp_client $server $port $user $password -to_rf "$xastirpath$xastirwx" #Send telemetry data to Xastir #Send PARAMS, UNITS, EQNS and BITS every 2 hours. #Check if file exist if [ ! -f "/mnt/ramdisk/datejavornik.txt" ]; then echo 0 > /mnt/ramdisk/datejavornik.txt fi #calculate time difference read olddate < /mnt/ramdisk/datejavornik.txt date="$(date +%s)" diff="$(echo "$date - $olddate" | bc)" if [ "$diff" -gt 7200 ]; then /usr/bin/xastir_udp_client $server $port $user $password -to_rf "$t1" /usr/bin/xastir_udp_client $server $port $user $password -to_rf "$t2" /usr/bin/xastir_udp_client $server $port $user $password -to_rf "$t3" /usr/bin/xastir_udp_client $server $port $user $password -to_rf "$t4" /usr/bin/xastir_udp_client $server $port $user $password -to_rf "$t5" echo "$date" > /mnt/ramdisk/datejavornik.txt else /usr/bin/xastir_udp_client $server $port $user $password -to_rf "$t1" fi #Delete old data rm -f /mnt/ramdisk/wxdata.txt /mnt/ramdisk/wxdata1.txt #Write sequence number echo "$num" > /mnt/ramdisk/sequence_numberjavornik.txt else echo ["$(date -u)"] Error downloading data >> "$error" fi
Link to the Hobolink to APRS script: https://pastebin.com/v6cQkm54
This is what i am looking for. Thank you very much! Keep posting.
Did you ever figure how to remove the } character from the transmitted packet?
WB0VGI
The “}” character is not a bug in Xastir, it’s intentional.
Every packet injected into xastir via xastir_udp_client is treated as a third-party packet, which means that Xastir places its own packet header first (indicating the actual transmitting station and software), followed by “}”, followed by the complete packet being injected (the station, object, item, or message packet intended). This identifies to all that Xastir itself is not the source of the packet, only the transmission medium, and the true source of the packet is contained in the information following the “}”
This is exactly what the APRS protocol says should be done for third-party packets (see chapter 17 of the APRS protocol documentation, http://www.aprs.org/doc/APRS101.PDF)
If you create a fully-formed APRS packet (complete with from call, to call, and (possibly null) path), all APRS clients should recognize the format and do the right thing with it.
There was some attempt years ago to make Xastir treat injected data as its own if the callsigns match and send them as a regular packet instead of third-party, but apparently the person who coded that up never got the code to work properly and then just commented it out. So Xastir *always* treats *all* packets injected by xastir_udp_client as third party packets and always inserts the third party header.