Test new packet serialization

This commit is contained in:
Hemna 2023-10-13 15:35:41 -04:00
parent c01037d398
commit fe1ebf2ec1
6 changed files with 73 additions and 22 deletions

View File

@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11"]
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}

View File

@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11"]
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}

View File

@ -1,7 +1,6 @@
import abc
from dataclasses import asdict, dataclass, field
import datetime
import json
from datetime import datetime
import logging
import re
import time
@ -9,9 +8,9 @@ import time
from typing import List
import dacite
from dataclasses_json import dataclass_json
from aprsd.utils import counter
from aprsd.utils import json as aprsd_json
LOG = logging.getLogger("APRSD")
@ -28,12 +27,20 @@ PACKET_TYPE_BEACON = "beacon"
PACKET_TYPE_THIRDPARTY = "thirdparty"
PACKET_TYPE_UNCOMPRESSED = "uncompressed"
NO_DATE = datetime(1900, 10, 24)
def _init_timestamp():
"""Build a unix style timestamp integer"""
return int(round(time.time()))
def _init_send_time():
# We have to use a datetime here, or the json encoder
# Fails on a NoneType.
return NO_DATE
def _init_msgNo(): # noqa: N802
"""For some reason __post__init doesn't get called.
@ -45,6 +52,32 @@ def _init_msgNo(): # noqa: N802
return c.value
def factory_from_dict(packet_dict):
pkt_type = get_packet_type(packet_dict)
# print(f"pkt_type {pkt_type}")
if pkt_type:
# if pkt_type == 'unknown':
# # try to determine it by the raw
# raw = packet_dict.get('raw')
# if raw:
# import aprslib
# type = get_packet_type(aprslib.parse(raw))
# print(f"raw type {type}")
cls = TYPE_LOOKUP[pkt_type]
# print(f"CLS {cls}")
return cls.from_dict(packet_dict)
def factory_from_json(packet_dict):
pkt_type = get_packet_type(packet_dict)
if pkt_type:
return TYPE_LOOKUP[pkt_type].from_json(packet_dict)
@dataclass_json
@dataclass(unsafe_hash=True)
class Packet(metaclass=abc.ABCMeta):
from_call: str = field(default=None)
@ -64,7 +97,17 @@ class Packet(metaclass=abc.ABCMeta):
# Fields related to sending packets out
send_count: int = field(repr=False, default=0, compare=False, hash=False)
retry_count: int = field(repr=False, default=3, compare=False, hash=False)
last_send_time: datetime.timedelta = field(repr=False, default=None, compare=False, hash=False)
#last_send_time: datetime = field(
# metadata=dc_json_config(
# encoder=datetime.isoformat,
# decoder=datetime.fromisoformat,
# ),
# repr=True,
# default_factory=_init_send_time,
# compare=False,
# hash=False
#)
last_send_time: float = field(repr=False, default=0, compare=False, hash=False)
# Do we allow this packet to be saved to send later?
allow_delay: bool = field(repr=False, default=True, compare=False, hash=False)
path: List[str] = field(default_factory=list, compare=False, hash=False)
@ -73,16 +116,13 @@ class Packet(metaclass=abc.ABCMeta):
def __post__init__(self):
LOG.warning(f"POST INIT {self}")
@property
def __dict__(self):
return asdict(self)
@property
def json(self):
"""
get the json formated string
"""
return json.dumps(self.__dict__, cls=aprsd_json.EnhancedJSONEncoder)
#return json.dumps(self.__dict__, cls=aprsd_json.EnhancedJSONEncoder)
return self.to_json()
def get(self, key, default=None):
"""Emulate a getter on a dict."""
@ -288,7 +328,7 @@ class RejectPacket(Packet):
def _build_payload(self):
self.payload = f":{self.to_call.ljust(9)} :rej{self.msgNo}"
@dataclass_json
@dataclass(unsafe_hash=True)
class MessagePacket(Packet):
message_text: str = field(default=None)
@ -436,6 +476,13 @@ class GPSPacket(Packet):
)
@dataclass
class StatusPacket(Packet):
status: str = None
messagecapable: bool = False
comment: str = None
@dataclass
class MicEPacket(GPSPacket):
messagecapable: bool = False
@ -567,7 +614,7 @@ class WeatherPacket(GPSPacket):
class ThirdParty(Packet):
# Holds the encapsulated packet
subpacket: Packet = None
subpacket: Packet = field(default=None, compare=True, hash=False)
def __repr__(self):
"""Build the repr version of the packet."""
@ -600,7 +647,7 @@ def get_packet_type(packet: dict):
pkt_format = packet.get("format", None)
msg_response = packet.get("response", None)
packet_type = "unknown"
packet_type = PACKET_TYPE_UNKNOWN
if pkt_format == "message" and msg_response == "ack":
packet_type = PACKET_TYPE_ACK
elif pkt_format == "message" and msg_response == "rej":
@ -620,6 +667,10 @@ def get_packet_type(packet: dict):
packet_type = PACKET_TYPE_WX
elif pkt_format == PACKET_TYPE_THIRDPARTY:
packet_type = PACKET_TYPE_THIRDPARTY
if packet_type == PACKET_TYPE_UNKNOWN:
if "latitude" in packet:
packet_type = PACKET_TYPE_BEACON
return packet_type

View File

@ -1,4 +1,3 @@
import datetime
import logging
import time
@ -128,10 +127,10 @@ class SendPacketThread(aprsd_threads.APRSDThread):
# Message is still outstanding and needs to be acked.
if packet.last_send_time:
# Message has a last send time tracking
now = datetime.datetime.now()
now = int(round(time.time()))
sleeptime = (packet.send_count + 1) * 31
delta = now - packet.last_send_time
if delta > datetime.timedelta(seconds=sleeptime):
if delta > sleeptime:
# It's time to try to send it again
send_now = True
else:
@ -140,7 +139,7 @@ class SendPacketThread(aprsd_threads.APRSDThread):
if send_now:
# no attempt time, so lets send it, and start
# tracking the time.
packet.last_send_time = datetime.datetime.now()
packet.last_send_time = int(round(time.time()))
send(packet, direct=True)
packet.send_count += 1
@ -173,13 +172,13 @@ class SendAckThread(aprsd_threads.APRSDThread):
if self.packet.last_send_time:
# Message has a last send time tracking
now = datetime.datetime.now()
now = int(round(time.time()))
# aprs duplicate detection is 30 secs?
# (21 only sends first, 28 skips middle)
sleep_time = 31
delta = now - self.packet.last_send_time
if delta > datetime.timedelta(seconds=sleep_time):
if delta > sleep_time:
# It's time to try to send it again
send_now = True
elif self.loop_count % 10 == 0:
@ -190,7 +189,7 @@ class SendAckThread(aprsd_threads.APRSDThread):
if send_now:
send(self.packet, direct=True)
self.packet.send_count += 1
self.packet.last_send_time = datetime.datetime.now()
self.packet.last_send_time = int(round(time.time()))
time.sleep(1)
self.loop_count += 1

View File

@ -4,6 +4,7 @@
#
# pip-compile --annotation-style=line requirements.in
#
dataclasses-json
aprslib==0.7.2
# via -r requirements.in
attrs==23.1.0

View File

@ -2,7 +2,7 @@
minversion = 2.9.0
skipdist = True
skip_missing_interpreters = true
envlist = pep8,py{39,310}
envlist = pep8,py{39,310,311,312}
#requires = tox-pipenv
# pip==22.0.4
# pip-tools==5.4.0