mirror of
https://github.com/craigerl/aprsd.git
synced 2024-12-22 09:31:42 -05:00
Added BeaconPacket
This patch adds the BeaconPacket and BeaconSendThread. This will enable APRSD server to send a beacon if enabled in the config.
This commit is contained in:
parent
275bf67b9e
commit
11f1e9533e
@ -1,9 +1,8 @@
|
|||||||
|
import click
|
||||||
from functools import update_wrapper
|
from functools import update_wrapper
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
import click
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
import aprsd
|
import aprsd
|
||||||
@ -50,9 +49,6 @@ common_options = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
import click
|
|
||||||
|
|
||||||
|
|
||||||
class AliasedGroup(click.Group):
|
class AliasedGroup(click.Group):
|
||||||
def command(self, *args, **kwargs):
|
def command(self, *args, **kwargs):
|
||||||
"""A shortcut decorator for declaring and attaching a command to
|
"""A shortcut decorator for declaring and attaching a command to
|
||||||
|
@ -11,7 +11,7 @@ from aprsd import main as aprsd_main
|
|||||||
from aprsd import packets, plugin, threads, utils
|
from aprsd import packets, plugin, threads, utils
|
||||||
from aprsd.main import cli
|
from aprsd.main import cli
|
||||||
from aprsd.rpc import server as rpc_server
|
from aprsd.rpc import server as rpc_server
|
||||||
from aprsd.threads import rx
|
from aprsd.threads import rx, tx
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
@ -107,6 +107,10 @@ def server(ctx, flush):
|
|||||||
process_thread.start()
|
process_thread.start()
|
||||||
|
|
||||||
packets.PacketTrack().restart()
|
packets.PacketTrack().restart()
|
||||||
|
if CONF.enable_beacon:
|
||||||
|
LOG.info("Beacon Enabled. Starting Beacon thread.")
|
||||||
|
bcn_thread = tx.BeaconSendThread()
|
||||||
|
bcn_thread.start()
|
||||||
|
|
||||||
if CONF.rpc_settings.enabled:
|
if CONF.rpc_settings.enabled:
|
||||||
rpc = rpc_server.APRSDRPCThread()
|
rpc = rpc_server.APRSDRPCThread()
|
||||||
|
@ -70,6 +70,32 @@ aprsd_opts = [
|
|||||||
default=60,
|
default=60,
|
||||||
help="The number of seconds before a packet is not considered a duplicate.",
|
help="The number of seconds before a packet is not considered a duplicate.",
|
||||||
),
|
),
|
||||||
|
cfg.BoolOpt(
|
||||||
|
"enable_beacon",
|
||||||
|
default=False,
|
||||||
|
help="Enable sending of a GPS Beacon packet to locate this service. "
|
||||||
|
"Requires latitude and longitude to be set.",
|
||||||
|
),
|
||||||
|
cfg.IntOpt(
|
||||||
|
"beacon_interval",
|
||||||
|
default=600,
|
||||||
|
help="The number of seconds between beacon packets.",
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"beacon_symbol",
|
||||||
|
default="/",
|
||||||
|
help="The symbol to use for the GPS Beacon packet. See: http://www.aprs.net/vm/DOS/SYMBOLS.HTM",
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"latitude",
|
||||||
|
default=None,
|
||||||
|
help="Latitude for the GPS Beacon button. If not set, the button will not be enabled.",
|
||||||
|
),
|
||||||
|
cfg.StrOpt(
|
||||||
|
"longitude",
|
||||||
|
default=None,
|
||||||
|
help="Longitude for the GPS Beacon button. If not set, the button will not be enabled.",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
watch_list_opts = [
|
watch_list_opts = [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from aprsd.packets.core import ( # noqa: F401
|
from aprsd.packets.core import ( # noqa: F401
|
||||||
AckPacket, GPSPacket, MessagePacket, MicEPacket, Packet, RejectPacket,
|
AckPacket, BeaconPacket, GPSPacket, MessagePacket, MicEPacket, Packet,
|
||||||
StatusPacket, WeatherPacket,
|
RejectPacket, StatusPacket, WeatherPacket,
|
||||||
)
|
)
|
||||||
from aprsd.packets.packet_list import PacketList # noqa: F401
|
from aprsd.packets.packet_list import PacketList # noqa: F401
|
||||||
from aprsd.packets.seen_list import SeenList # noqa: F401
|
from aprsd.packets.seen_list import SeenList # noqa: F401
|
||||||
|
@ -466,6 +466,26 @@ class GPSPacket(Packet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(unsafe_hash=True)
|
||||||
|
class BeaconPacket(GPSPacket):
|
||||||
|
def _build_payload(self):
|
||||||
|
"""The payload is the non headers portion of the packet."""
|
||||||
|
time_zulu = self._build_time_zulu()
|
||||||
|
lat = self.convert_latitude(self.latitude)
|
||||||
|
long = self.convert_longitude(self.longitude)
|
||||||
|
|
||||||
|
self.payload = (
|
||||||
|
f"@{time_zulu}z{lat}{self.symbol_table}"
|
||||||
|
f"{long}{self.symbol}APRSD Beacon"
|
||||||
|
)
|
||||||
|
|
||||||
|
def _build_raw(self):
|
||||||
|
self.raw = (
|
||||||
|
f"{self.from_call}>APZ100:"
|
||||||
|
f"{self.payload}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MicEPacket(GPSPacket):
|
class MicEPacket(GPSPacket):
|
||||||
messagecapable: bool = False
|
messagecapable: bool = False
|
||||||
|
@ -37,7 +37,6 @@ msg_throttle_decorator = decorator.ThrottleDecorator(throttle=msg_t)
|
|||||||
ack_throttle_decorator = decorator.ThrottleDecorator(throttle=ack_t)
|
ack_throttle_decorator = decorator.ThrottleDecorator(throttle=ack_t)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@msg_throttle_decorator.sleep_and_retry
|
@msg_throttle_decorator.sleep_and_retry
|
||||||
def send(packet: core.Packet, direct=False, aprs_client=None):
|
def send(packet: core.Packet, direct=False, aprs_client=None):
|
||||||
"""Send a packet either in a thread or directly to the client."""
|
"""Send a packet either in a thread or directly to the client."""
|
||||||
@ -196,3 +195,38 @@ class SendAckThread(aprsd_threads.APRSDThread):
|
|||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
self.loop_count += 1
|
self.loop_count += 1
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class BeaconSendThread(aprsd_threads.APRSDThread):
|
||||||
|
"""Thread that sends a GPS beacon packet periodically.
|
||||||
|
|
||||||
|
Settings are in the [DEFAULT] section of the config file.
|
||||||
|
"""
|
||||||
|
_loop_cnt: int = 1
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("BeaconSendThread")
|
||||||
|
self._loop_cnt = 1
|
||||||
|
# Make sure Latitude and Longitude are set.
|
||||||
|
if not CONF.latitude or not CONF.longitude:
|
||||||
|
LOG.error(
|
||||||
|
"Latitude and Longitude are not set in the config file."
|
||||||
|
"Beacon will not be sent and thread is STOPPED.",
|
||||||
|
)
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
def loop(self):
|
||||||
|
# Only dump out the stats every N seconds
|
||||||
|
if self._loop_cnt % CONF.beacon_interval == 0:
|
||||||
|
pkt = core.BeaconPacket(
|
||||||
|
from_call=CONF.callsign,
|
||||||
|
to_call="APRS",
|
||||||
|
latitude=float(CONF.latitude),
|
||||||
|
longitude=float(CONF.longitude),
|
||||||
|
comment="APRSD GPS Beacon",
|
||||||
|
symbol=CONF.beacon_symbol,
|
||||||
|
)
|
||||||
|
send(pkt, direct=True)
|
||||||
|
self._loop_cnt += 1
|
||||||
|
time.sleep(1)
|
||||||
|
return True
|
||||||
|
@ -99,7 +99,6 @@ class ObjectStoreMixin:
|
|||||||
LOG.debug(
|
LOG.debug(
|
||||||
f"{self.__class__.__name__}::Loaded {len(self)} entries from disk.",
|
f"{self.__class__.__name__}::Loaded {len(self)} entries from disk.",
|
||||||
)
|
)
|
||||||
#LOG.debug(f"{self.data}")
|
|
||||||
else:
|
else:
|
||||||
LOG.debug(f"{self.__class__.__name__}::No data to load.")
|
LOG.debug(f"{self.__class__.__name__}::No data to load.")
|
||||||
except (pickle.UnpicklingError, Exception) as ex:
|
except (pickle.UnpicklingError, Exception) as ex:
|
||||||
|
Loading…
Reference in New Issue
Block a user