From 2a9c938eaafcdca972e55a1cf8e34ca0a378a1f4 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Fri, 2 Apr 2021 21:41:35 -0500 Subject: [PATCH 1/3] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa7db38..7c13e2f 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Some preliminary but untested support is now included for multiple inReach devic * Just define a single SSID in the configuration file, leave the Devices section undefined, and the software will increment the number on your SSID for each new IMEI it finds in the feed. Mappings generated this way will be consistent within a single run, but may -- or may not -- change if you run the service again. - * Still define the SSID in the APRS section, since it's used for the login to APRS-IS, but also define the Devices section. Each line should have an SSID = IMEI mapping. All devices not present in the Devices section will be ignored. + * Still define the SSID in the APRS section, since it's used for the APRS gate address and the login to APRS-IS, but also define the Devices section. Each line should have an SSID = IMEI mapping. All devices not present in the Devices section will be ignored. * Run multiple instances of the daemon, each with an IMEI specified on the command-line, or each with a new configuration file and a Devices section that includes some but not all of the devices you want to watch. From c49d6298e881b1391c68eaa6136cbf719c77b92d Mon Sep 17 00:00:00 2001 From: Christopher Smith Date: Sat, 3 Apr 2021 04:53:42 -0500 Subject: [PATCH 2/3] Minor clean-up, and added some simple but useful logging to STDOUT. --- ir-aprsisd | 43 +++++++++++++++++++++++++++++++++---------- ir-aprsisd.cfg | 44 -------------------------------------------- 2 files changed, 33 insertions(+), 54 deletions(-) delete mode 100644 ir-aprsisd.cfg diff --git a/ir-aprsisd b/ir-aprsisd index 13d5345..018d9ee 100755 --- a/ir-aprsisd +++ b/ir-aprsisd @@ -137,14 +137,15 @@ urllib.request.install_opener(http) #Handle connection to APRS-IS def reconnect(): global AIS + attempt = 1 while True: AIS = aprslib.IS(conf['APRS']['SSID'],passwd=conf['APRS']['Password'],port=conf['APRS']['Port']) try: AIS.connect() break except Exception as e: - print("Trouble connecting to APRS-IS server.") - print(e) + print("Connection failed. Reconnecting: " + str(attempt)) + attempt += 1 time.sleep(3) continue @@ -153,32 +154,39 @@ SSIDList = {} #We'll store timestamps here lastUpdate = {} +#Packet counts here +transmitted = {} +#Last time stats() was run: +lastStats = calendar.timegm(time.gmtime()) + + #Load any preconfigured mappings if conf.has_section('Devices'): + print("Loading predefined SSID mappings.") for device in conf['Devices'].keys(): SSIDList[conf['Devices'][device]] = device.upper() + print("Static mapping: " + SSIDList[conf['Devices'][device]] + " -> " + device.upper()) #Get an SSID -#An apocryphal concern is that this will happily generate an SSID for None, -# or whatever else might get passed along to it. -# There's a record in the usual set of inReach Placemarks where this happens, -# but because the record has no extended data, no packets are ever generated -# for it. Such a record is generally not interesting and on the end of the list, -# so there has been no reason to explicitly skip it. def getSSID(DID): - global lastUpdate, SSIDList, SSNum, Call + global lastUpdate, SSIDList, transmitted, SSNum, Call + if not DID: # Don't map None + return None #If we have a Devices section, the SSID list is static. if DID not in SSIDList: if conf.has_section('Devices'): return None SSIDList[DID] = ''.join([Call,"-",str(SSNum)]) SSNum = SSNum + 1 + print("Mapping: " + DID + " -> " + SSIDList[DID]) #Add a timestamp on the first call # This prevents us from redelivering an old message, which can stay # in the feed. if DID not in lastUpdate: lastUpdate[DID] = calendar.timegm(time.gmtime()) + if DID not in transmitted: + transmitted[DID] = 0 return SSIDList[DID] @@ -271,7 +279,7 @@ def getEvents(): # float Longitude, float Altitude in feet, int float course in degrees, # float speed in knots, comment def sendAPRS(device, DevID, ARPreamble, tstamp, lat, long, alt, course, speed, comment): - global conf + global conf, transmitted etime = calendar.timegm(tstamp) #Latitude conversion @@ -331,11 +339,26 @@ def sendAPRS(device, DevID, ARPreamble, tstamp, lat, long, alt, course, speed, c pass #Last update in UTC lastUpdate[DevID] = calendar.timegm(tstamp) + transmitted[DevID] += 1 + +def stats(): + global transmitted, lastStats + lastStats = calendar.timegm(time.gmtime()) + print("----------------Packet Forwarding Summary----------------") + print("|\t" + time.strftime("%Y-%m-%d %R",time.localtime())) + print("| SSID DevID Packets forwarded") + for device in transmitted: + print("| " + getSSID(device) + "\t" + device + "\t\t" + str(transmitted[device])) + print("---------------------------------------------------------") + print() #... and here is the main loop. while True: for packet in getEvents(): sendAPRS(*packet) #Otherwise a list of sendAPRS args for the next packet to send. + if "Logstats" in conf["General"]: + if calendar.timegm(time.gmtime()) > lastStats + conf.getint("General","Logstats"): + stats() time.sleep(conf.getfloat('General','Period')) diff --git a/ir-aprsisd.cfg b/ir-aprsisd.cfg deleted file mode 100644 index c561bf4..0000000 --- a/ir-aprsisd.cfg +++ /dev/null @@ -1,44 +0,0 @@ -[inReach] -User = Your inReach feed user -#If this is defined, we will authenticate to the inReach service. -# If it is not, we will assume public access is ok. -#Password = Your inReach feed password, if required - -# This should be the location of your KML feed. -URL = https://share.garmin.com/Feed/Share/%(User)s - -[APRS] -#This SSID is used for logging into APRS-IS, and also as a base ID for -# generating callsigns for devices. The first device found will be this -# SSID, the next will be this ID + 1, and so on. If you define a [Devices] -# section, it is _only_ used for the login, and the device mapping must be -# given in full in the [Devices] section. -SSID = N0CALL -# If you don't have a password, you can use the --genpass command-line -# option to calculate it. -Password = 1234 -Port = 14580 - -#If the separator is /, your icon will come from the primary symbol table. -# if it is \, it will draw from the secondary table. -Separator = / -#This character represents an APRS icon from the table tied to Separator. -Symbol = ( - -#This information is included at the end of each packet, along with some -# other data. -Comment = APRS-IS KML forwarder, by K0SIN - -#Define this section if you'd like to enforce an SSID to IMEI mapping. -# It must contain all devices you want to publish. Anything without a -# mapping defined will be ignored if this section exists. -#[Devices] -#N0CALL-12 = 987654321987654 -#N0CALL-15 = 987654321987656 -#N0CALL-8 = 092847784398753 - -[General] -# KML polling interval in seconds. -Period = 300 - - From c7f0199cddc5116bb15b947ee0d6a8a761e667d3 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Sat, 3 Apr 2021 16:13:32 -0500 Subject: [PATCH 3/3] Configuration file re-added with new, correct form. --- ir-aprsisd.cfg | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 ir-aprsisd.cfg diff --git a/ir-aprsisd.cfg b/ir-aprsisd.cfg new file mode 100644 index 0000000..6934310 --- /dev/null +++ b/ir-aprsisd.cfg @@ -0,0 +1,51 @@ +[inReach] +User = Your inReach feed user +#If this is defined, we will authenticate to the inReach service. +# If it is not, we will assume public access is ok. +#Password = Your inReach feed password, if required + +# This should be the location of your KML feed. +URL = https://share.garmin.com/Feed/Share/%(User)s + +[APRS] +#This SSID is used for logging into APRS-IS, and also as a base ID for +# generating callsigns for devices. The first device found will be this +# SSID, the next will be this ID + 1, and so on. If you define a [Devices] +# section, it is _only_ used for the login, and the device mapping must be +# given in full in the [Devices] section. +SSID = N0CALL +# If you don't have a password, you can use the --genpass command-line +# option to calculate it. +Password = 1234 +Port = 14580 + +#If the separator is /, your icon will come from the primary symbol table. +# if it is \, it will draw from the secondary table. +Separator = / +#This character represents an APRS icon from the table tied to Separator. +Symbol = ( + +#This information is included at the end of each packet, along with some +# other data. +Comment = APRS-IS KML forwarder, by K0SIN + +#Define this section if you'd like to enforce an SSID to IMEI mapping. +# It must contain all devices you want to publish. Anything without a +# mapping defined will be ignored if this section exists. +#[Devices] +#N0CALL-12 = 987654321987654 +#N0CALL-15 = 987654321987656 +#N0CALL-8 = 092847784398753 + +[General] + +# Frequency in seconds with which to log packet forwarding stats to STDOUT +# If this is less than Period, stats will only be logged every Period seconds. +# Comment it out to skip printing packet stats entirely. +Logstats = 300 + +# KML polling interval in seconds. +Period = 300 + + +