Update aprs_comm.py

Added random alphanumeric message ID to each message to get around issue of apps not receiving duplicate messages
This commit is contained in:
TC² 2025-01-15 16:17:53 -05:00
parent 2e97f29419
commit 1489b88bd2

View file

@ -1,22 +1,27 @@
import os
import json
import random
import string
import threading
import time import time
from datetime import datetime
from threading import Lock from threading import Lock
import aprs import aprs
import os
import json
import requests import requests
import commands import commands
import config import config
# Global dictionary to track unacknowledged messages # Global dictionary to track unacknowledged messages
unacknowledged_messages = {} unacknowledged_messages = {}
unack_lock = Lock() unack_lock = Lock()
# Message numbering for ACKS # Message numbering for ACKS
message_counter = 1 message_counter = 1
message_lock = threading.Lock()
from datetime import datetime
JSON_URL = "https://aprs-deviceid.aprsfoundation.org/tocalls.pretty.json" JSON_URL = "https://aprs-deviceid.aprsfoundation.org/tocalls.pretty.json"
@ -86,8 +91,10 @@ def send_ack(ki, aprs_frame):
def send_bulletin(bulletin_id, bulletin_text): def send_bulletin(bulletin_id, bulletin_text):
"""Send an APRS bulletin in BLN format.""" """Send an APRS bulletin in BLN format."""
try: try:
frame_info = f":{bulletin_id:<9}:{bulletin_text}".encode('utf-8') message_number = get_next_message_number()
formatted_bulletin = f"{bulletin_text}{{{message_number}"
frame_info = f":{bulletin_id:<9}:{formatted_bulletin}".encode('utf-8')
frame = aprs.APRSFrame.ui( frame = aprs.APRSFrame.ui(
destination=config.STANDARD_CALL, destination=config.STANDARD_CALL,
source=config.TACTICAL_CALL, source=config.TACTICAL_CALL,
@ -194,8 +201,10 @@ def start():
for response in responses: for response in responses:
dec_timestamp = datetime.now().strftime("%b%d %H:%M") dec_timestamp = datetime.now().strftime("%b%d %H:%M")
message_number = get_next_message_number()
formatted_response = f"{response}{{{message_number}"
response_info = f":{source:<9}:{response}".encode('utf-8') response_info = f":{source:<9}:{formatted_response}".encode('utf-8')
response_frame = aprs.APRSFrame.ui( response_frame = aprs.APRSFrame.ui(
destination=config.STANDARD_CALL, destination=config.STANDARD_CALL,
source=config.TACTICAL_CALL, source=config.TACTICAL_CALL,
@ -214,7 +223,10 @@ def start():
def send_direct_message(recipient, message): def send_direct_message(recipient, message):
"""Send a direct APRS message to a recipient without ACK request.""" """Send a direct APRS message to a recipient without ACK request."""
try: try:
frame_info = f":{recipient:<9}:{message}".encode('utf-8') message_number = get_next_message_number()
formatted_message = f"{message}{{{message_number}"
frame_info = f":{recipient:<9}:{formatted_message}".encode('utf-8')
frame = aprs.APRSFrame.ui( frame = aprs.APRSFrame.ui(
destination=config.STANDARD_CALL, destination=config.STANDARD_CALL,
@ -225,7 +237,7 @@ def send_direct_message(recipient, message):
ki = aprs.TCPKISS(host=config.KISS_HOST, port=config.KISS_PORT) ki = aprs.TCPKISS(host=config.KISS_HOST, port=config.KISS_PORT)
ki.start() ki.start()
ki.write(frame) ki.write(frame)
print(f"Direct message sent to {recipient}: {message}") print(f"Direct message sent to {recipient}: {formatted_message}")
ki.stop() ki.stop()
except Exception as e: except Exception as e:
@ -255,3 +267,12 @@ def wait_for_ack(ki, recipient, message_number, timeout=5):
except Exception as e: except Exception as e:
print(f"Error while waiting for ACK: {e}") print(f"Error while waiting for ACK: {e}")
return False return False
def get_next_message_number():
"""Generates a unique 5-character alphanumeric message number."""
with message_lock:
# Characters: A-Z and 0-9
characters = string.ascii_uppercase + string.digits
# Random 5-character combination
return ''.join(random.choices(characters, k=5))