1
0
mirror of https://github.com/craigerl/aprsd.git synced 2026-06-02 22:24:42 -04:00

reworked Documentation

The documenation now has a new theme and updated apidocs.
Also the main index is built from the README.md contents.
This commit is contained in:
2025-12-11 09:33:22 -05:00
parent 61126289df
commit eb0818af65
41 changed files with 1727 additions and 1163 deletions
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

@@ -0,0 +1,21 @@
aprsd.client.drivers.lib package
================================
Submodules
----------
aprsd.client.drivers.lib.aprslib module
---------------------------------------
.. automodule:: aprsd.client.drivers.lib.aprslib
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.client.drivers.lib
:members:
:show-inheritance:
:undoc-members:
@@ -0,0 +1,69 @@
aprsd.client.drivers package
============================
Subpackages
-----------
.. toctree::
:maxdepth: 4
aprsd.client.drivers.lib
Submodules
----------
aprsd.client.drivers.aprsis module
----------------------------------
.. automodule:: aprsd.client.drivers.aprsis
:members:
:show-inheritance:
:undoc-members:
aprsd.client.drivers.fake module
--------------------------------
.. automodule:: aprsd.client.drivers.fake
:members:
:show-inheritance:
:undoc-members:
aprsd.client.drivers.kiss\_common module
----------------------------------------
.. automodule:: aprsd.client.drivers.kiss_common
:members:
:show-inheritance:
:undoc-members:
aprsd.client.drivers.registry module
------------------------------------
.. automodule:: aprsd.client.drivers.registry
:members:
:show-inheritance:
:undoc-members:
aprsd.client.drivers.serialkiss module
--------------------------------------
.. automodule:: aprsd.client.drivers.serialkiss
:members:
:show-inheritance:
:undoc-members:
aprsd.client.drivers.tcpkiss module
-----------------------------------
.. automodule:: aprsd.client.drivers.tcpkiss
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.client.drivers
:members:
:show-inheritance:
:undoc-members:
+37
View File
@@ -0,0 +1,37 @@
aprsd.client package
====================
Subpackages
-----------
.. toctree::
:maxdepth: 4
aprsd.client.drivers
Submodules
----------
aprsd.client.client module
--------------------------
.. automodule:: aprsd.client.client
:members:
:show-inheritance:
:undoc-members:
aprsd.client.stats module
-------------------------
.. automodule:: aprsd.client.stats
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.client
:members:
:show-inheritance:
:undoc-members:
+77
View File
@@ -0,0 +1,77 @@
aprsd.cmds package
==================
Submodules
----------
aprsd.cmds.completion module
----------------------------
.. automodule:: aprsd.cmds.completion
:members:
:show-inheritance:
:undoc-members:
aprsd.cmds.dev module
---------------------
.. automodule:: aprsd.cmds.dev
:members:
:show-inheritance:
:undoc-members:
aprsd.cmds.fetch\_stats module
------------------------------
.. automodule:: aprsd.cmds.fetch_stats
:members:
:show-inheritance:
:undoc-members:
aprsd.cmds.healthcheck module
-----------------------------
.. automodule:: aprsd.cmds.healthcheck
:members:
:show-inheritance:
:undoc-members:
aprsd.cmds.list\_plugins module
-------------------------------
.. automodule:: aprsd.cmds.list_plugins
:members:
:show-inheritance:
:undoc-members:
aprsd.cmds.listen module
------------------------
.. automodule:: aprsd.cmds.listen
:members:
:show-inheritance:
:undoc-members:
aprsd.cmds.send\_message module
-------------------------------
.. automodule:: aprsd.cmds.send_message
:members:
:show-inheritance:
:undoc-members:
aprsd.cmds.server module
------------------------
.. automodule:: aprsd.cmds.server
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.cmds
:members:
:show-inheritance:
:undoc-members:
+53
View File
@@ -0,0 +1,53 @@
aprsd.conf package
==================
Submodules
----------
aprsd.conf.client module
------------------------
.. automodule:: aprsd.conf.client
:members:
:show-inheritance:
:undoc-members:
aprsd.conf.common module
------------------------
.. automodule:: aprsd.conf.common
:members:
:show-inheritance:
:undoc-members:
aprsd.conf.log module
---------------------
.. automodule:: aprsd.conf.log
:members:
:show-inheritance:
:undoc-members:
aprsd.conf.opts module
----------------------
.. automodule:: aprsd.conf.opts
:members:
:show-inheritance:
:undoc-members:
aprsd.conf.plugin\_common module
--------------------------------
.. automodule:: aprsd.conf.plugin_common
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.conf
:members:
:show-inheritance:
:undoc-members:
+21
View File
@@ -0,0 +1,21 @@
aprsd.log package
=================
Submodules
----------
aprsd.log.log module
--------------------
.. automodule:: aprsd.log.log
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.log
:members:
:show-inheritance:
:undoc-members:
@@ -0,0 +1,29 @@
aprsd.packets.filters package
=============================
Submodules
----------
aprsd.packets.filters.dupe\_filter module
-----------------------------------------
.. automodule:: aprsd.packets.filters.dupe_filter
:members:
:show-inheritance:
:undoc-members:
aprsd.packets.filters.packet\_type module
-----------------------------------------
.. automodule:: aprsd.packets.filters.packet_type
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.packets.filters
:members:
:show-inheritance:
:undoc-members:
+85
View File
@@ -0,0 +1,85 @@
aprsd.packets package
=====================
Subpackages
-----------
.. toctree::
:maxdepth: 4
aprsd.packets.filters
Submodules
----------
aprsd.packets.collector module
------------------------------
.. automodule:: aprsd.packets.collector
:members:
:show-inheritance:
:undoc-members:
aprsd.packets.core module
-------------------------
.. automodule:: aprsd.packets.core
:members:
:show-inheritance:
:undoc-members:
aprsd.packets.filter module
---------------------------
.. automodule:: aprsd.packets.filter
:members:
:show-inheritance:
:undoc-members:
aprsd.packets.log module
------------------------
.. automodule:: aprsd.packets.log
:members:
:show-inheritance:
:undoc-members:
aprsd.packets.packet\_list module
---------------------------------
.. automodule:: aprsd.packets.packet_list
:members:
:show-inheritance:
:undoc-members:
aprsd.packets.seen\_list module
-------------------------------
.. automodule:: aprsd.packets.seen_list
:members:
:show-inheritance:
:undoc-members:
aprsd.packets.tracker module
----------------------------
.. automodule:: aprsd.packets.tracker
:members:
:show-inheritance:
:undoc-members:
aprsd.packets.watch\_list module
--------------------------------
.. automodule:: aprsd.packets.watch_list
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.packets
:members:
:show-inheritance:
:undoc-members:
+61
View File
@@ -0,0 +1,61 @@
aprsd.plugins package
=====================
Submodules
----------
aprsd.plugins.fortune module
----------------------------
.. automodule:: aprsd.plugins.fortune
:members:
:show-inheritance:
:undoc-members:
aprsd.plugins.notify module
---------------------------
.. automodule:: aprsd.plugins.notify
:members:
:show-inheritance:
:undoc-members:
aprsd.plugins.ping module
-------------------------
.. automodule:: aprsd.plugins.ping
:members:
:show-inheritance:
:undoc-members:
aprsd.plugins.time module
-------------------------
.. automodule:: aprsd.plugins.time
:members:
:show-inheritance:
:undoc-members:
aprsd.plugins.version module
----------------------------
.. automodule:: aprsd.plugins.version
:members:
:show-inheritance:
:undoc-members:
aprsd.plugins.weather module
----------------------------
.. automodule:: aprsd.plugins.weather
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.plugins
:members:
:show-inheritance:
:undoc-members:
+69
View File
@@ -0,0 +1,69 @@
aprsd package
=============
Subpackages
-----------
.. toctree::
:maxdepth: 4
aprsd.client
aprsd.cmds
aprsd.conf
aprsd.log
aprsd.packets
aprsd.plugins
aprsd.stats
aprsd.threads
aprsd.utils
Submodules
----------
aprsd.cli\_helper module
------------------------
.. automodule:: aprsd.cli_helper
:members:
:show-inheritance:
:undoc-members:
aprsd.exception module
----------------------
.. automodule:: aprsd.exception
:members:
:show-inheritance:
:undoc-members:
aprsd.main module
-----------------
.. automodule:: aprsd.main
:members:
:show-inheritance:
:undoc-members:
aprsd.plugin module
-------------------
.. automodule:: aprsd.plugin
:members:
:show-inheritance:
:undoc-members:
aprsd.plugin\_utils module
--------------------------
.. automodule:: aprsd.plugin_utils
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd
:members:
:show-inheritance:
:undoc-members:
+29
View File
@@ -0,0 +1,29 @@
aprsd.stats package
===================
Submodules
----------
aprsd.stats.app module
----------------------
.. automodule:: aprsd.stats.app
:members:
:show-inheritance:
:undoc-members:
aprsd.stats.collector module
----------------------------
.. automodule:: aprsd.stats.collector
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.stats
:members:
:show-inheritance:
:undoc-members:
+69
View File
@@ -0,0 +1,69 @@
aprsd.threads package
=====================
Submodules
----------
aprsd.threads.aprsd module
--------------------------
.. automodule:: aprsd.threads.aprsd
:members:
:show-inheritance:
:undoc-members:
aprsd.threads.keepalive module
------------------------------
.. automodule:: aprsd.threads.keepalive
:members:
:show-inheritance:
:undoc-members:
aprsd.threads.registry module
-----------------------------
.. automodule:: aprsd.threads.registry
:members:
:show-inheritance:
:undoc-members:
aprsd.threads.rx module
-----------------------
.. automodule:: aprsd.threads.rx
:members:
:show-inheritance:
:undoc-members:
aprsd.threads.service module
----------------------------
.. automodule:: aprsd.threads.service
:members:
:show-inheritance:
:undoc-members:
aprsd.threads.stats module
--------------------------
.. automodule:: aprsd.threads.stats
:members:
:show-inheritance:
:undoc-members:
aprsd.threads.tx module
-----------------------
.. automodule:: aprsd.threads.tx
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.threads
:members:
:show-inheritance:
:undoc-members:
+77
View File
@@ -0,0 +1,77 @@
aprsd.utils package
===================
Submodules
----------
aprsd.utils.counter module
--------------------------
.. automodule:: aprsd.utils.counter
:members:
:show-inheritance:
:undoc-members:
aprsd.utils.fuzzyclock module
-----------------------------
.. automodule:: aprsd.utils.fuzzyclock
:members:
:show-inheritance:
:undoc-members:
aprsd.utils.json module
-----------------------
.. automodule:: aprsd.utils.json
:members:
:show-inheritance:
:undoc-members:
aprsd.utils.keepalive\_collector module
---------------------------------------
.. automodule:: aprsd.utils.keepalive_collector
:members:
:show-inheritance:
:undoc-members:
aprsd.utils.objectstore module
------------------------------
.. automodule:: aprsd.utils.objectstore
:members:
:show-inheritance:
:undoc-members:
aprsd.utils.package module
--------------------------
.. automodule:: aprsd.utils.package
:members:
:show-inheritance:
:undoc-members:
aprsd.utils.ring\_buffer module
-------------------------------
.. automodule:: aprsd.utils.ring_buffer
:members:
:show-inheritance:
:undoc-members:
aprsd.utils.trace module
------------------------
.. automodule:: aprsd.utils.trace
:members:
:show-inheritance:
:undoc-members:
Module contents
---------------
.. automodule:: aprsd.utils
:members:
:show-inheritance:
:undoc-members:
+7
View File
@@ -0,0 +1,7 @@
aprsd
=====
.. toctree::
:maxdepth: 4
aprsd
+346
View File
@@ -0,0 +1,346 @@
Built-in APRSD Plugins
======================
APRSD comes with several built-in plugins that provide various functionality out of the box.
These plugins are automatically available when you install APRSD and can be enabled or disabled
through the configuration file.
Message Command Plugins
------------------------
These plugins respond to APRS messages sent to your APRSD callsign.
PingPlugin
~~~~~~~~~~
**Command:** ``ping``, ``p``, or ``p`` followed by a space
**Description:** Responds with "Pong!" and the current time.
**Usage:** Send a message containing "ping" to your APRSD callsign.
**Example:**
::
You: ping
APRSD: Pong! 14:30:05
**Configuration:** No configuration required.
**Plugin Path:** ``aprsd.plugins.ping.PingPlugin``
FortunePlugin
~~~~~~~~~~~~~
**Command:** ``fortune``, ``f``, or ``f`` followed by a space
**Description:** Returns a random fortune cookie message using the system's ``fortune`` command.
**Usage:** Send a message containing "fortune" to your APRSD callsign.
**Requirements:** Requires the ``fortune`` command to be installed on the system. The plugin
will automatically search common installation paths and disable itself if not found.
**Example:**
::
You: fortune
APRSD: A journey of a thousand miles begins with a single step.
**Configuration:** No configuration required.
**Plugin Path:** ``aprsd.plugins.fortune.FortunePlugin``
TimePlugin
~~~~~~~~~~
**Command:** ``time``, ``t``, or ``t`` followed by a space
**Description:** Returns the current local time of the APRSD server in a human-readable format
with timezone information.
**Usage:** Send a message containing "time" to your APRSD callsign.
**Example:**
::
You: time
APRSD: half past two (14:30 PDT)
**Configuration:** No configuration required. Uses the system's local timezone.
**Plugin Path:** ``aprsd.plugins.time.TimePlugin``
TimeOWMPlugin
~~~~~~~~~~~~~
**Command:** ``time``, ``t``, or ``t`` followed by a space
**Description:** Returns the current time based on the GPS beacon location of the calling
callsign (or optionally a specified callsign). Uses OpenWeatherMap API to determine the
timezone for the location.
**Usage:**
::
You: time
APRSD: quarter to three (14:45 EST)
You: time WB4BOR
APRSD: half past two (14:30 PDT)
**Requirements:**
- Requires an ``aprs_fi.apiKey`` configuration option
- Requires an ``owm_weather_plugin.apiKey`` configuration option
**Configuration:**
- ``aprs_fi.apiKey`` - API key from aprs.fi account
- ``owm_weather_plugin.apiKey`` - OpenWeatherMap API key
**Plugin Path:** ``aprsd.plugins.time.TimeOWMPlugin``
VersionPlugin
~~~~~~~~~~~~~
**Command:** ``version``, ``v``, or ``v`` followed by a space
**Description:** Returns the APRSD version number and server uptime.
**Usage:** Send a message containing "version" to your APRSD callsign.
**Example:**
::
You: version
APRSD: APRSD ver:4.2.4 uptime:2 days, 5:30:15
**Configuration:** No configuration required.
**Plugin Path:** ``aprsd.plugins.version.VersionPlugin``
USWeatherPlugin
~~~~~~~~~~~~~~~
**Command:** ``weather``, ``w``, or ``W`` (w or W at start of message)
**Description:** Provides weather information for locations within the United States only.
Uses the forecast.weather.gov API to fetch weather data based on the GPS beacon location
of the calling callsign (or optionally a specified callsign).
**Usage:**
::
You: weather
APRSD: 72F(68F/75F) Partly cloudy. Tonight, Clear.
You: weather WB4BOR
APRSD: 65F(60F/70F) Sunny. Tonight, Partly cloudy.
**Requirements:** Requires an ``aprs_fi.apiKey`` configuration option.
**Configuration:**
- ``aprs_fi.apiKey`` - API key from aprs.fi account
**Note:** This plugin does not require an API key for the weather service itself, only
for aprs.fi to get the GPS location.
**Plugin Path:** ``aprsd.plugins.weather.USWeatherPlugin``
USMetarPlugin
~~~~~~~~~~~~~
**Command:** ``metar``, ``m``, ``M``, or ``m`` followed by a space (m or M at start of message)
**Description:** Provides METAR (Meteorological Aerodrome Report) weather reports for
stations within the United States only. Uses the forecast.weather.gov API.
**Usage:**
::
You: metar
APRSD: KORD 101451Z 28010KT 10SM FEW250 22/12 A3001
You: metar KORD
APRSD: KORD 101451Z 28010KT 10SM FEW250 22/12 A3001
**Requirements:** Requires an ``aprs_fi.apiKey`` configuration option (when querying
by callsign location).
**Configuration:**
- ``aprs_fi.apiKey`` - API key from aprs.fi account
**Note:** When specifying a station identifier directly (e.g., "metar KORD"), the
aprs.fi API key is not required.
**Plugin Path:** ``aprsd.plugins.weather.USMetarPlugin``
OWMWeatherPlugin
~~~~~~~~~~~~~~~~
**Command:** ``weather``, ``w``, or ``W`` (w or W at start of message)
**Description:** Provides weather information using the OpenWeatherMap API. Works worldwide
and provides current weather conditions including temperature, dew point, wind speed and
direction, and humidity.
**Usage:**
::
You: weather
APRSD: clear sky 72.1F/65.2F Wind 5@270 45%
You: weather WB4BOR
APRSD: partly cloudy 68.5F/62.1F Wind 8@180G12 52%
**Requirements:**
- Requires an ``aprs_fi.apiKey`` configuration option
- Requires an ``owm_weather_plugin.apiKey`` configuration option
**Configuration:**
- ``aprs_fi.apiKey`` - API key from aprs.fi account
- ``owm_weather_plugin.apiKey`` - OpenWeatherMap API key (get one at https://home.openweathermap.org/api_keys)
- ``units`` - Set to "imperial" or "metric" (default: "imperial")
**Plugin Path:** ``aprsd.plugins.weather.OWMWeatherPlugin``
AVWXWeatherPlugin
~~~~~~~~~~~~~~~~~
**Command:** ``metar``, ``m``, or ``m`` followed by a space (m at start of message)
**Description:** Provides METAR weather reports using the AVWX API service. Fetches METAR
data from the nearest weather station to the GPS beacon location of the calling callsign
(or optionally a specified callsign).
**Usage:**
::
You: metar
APRSD: KORD 101451Z 28010KT 10SM FEW250 22/12 A3001 RMK AO2 SLP168 T02220122
You: metar WB4BOR
APRSD: KSFO 101500Z 25015KT 10SM FEW030 18/14 A2998 RMK AO2
**Requirements:**
- Requires an ``aprs_fi.apiKey`` configuration option
- Requires an ``avwx_plugin.apiKey`` configuration option
- Requires an ``avwx_plugin.base_url`` configuration option
**Configuration:**
- ``aprs_fi.apiKey`` - API key from aprs.fi account
- ``avwx_plugin.apiKey`` - API key for AVWX service
- ``avwx_plugin.base_url`` - Base URL for AVWX API (default: https://avwx.rest)
**Note:** AVWX is an open-source project. You can use the hosted service at https://avwx.rest/
or host your own instance. See the plugin code comments for instructions on running your
own AVWX API server.
**Plugin Path:** ``aprsd.plugins.weather.AVWXWeatherPlugin``
HelpPlugin
~~~~~~~~~~
**Command:** ``help``, ``h``, or ``H`` (h or H at start of message)
**Description:** Provides help information about available plugins. Can list all available
plugins or provide specific help for a named plugin.
**Usage:**
::
You: help
APRSD: Send APRS MSG of 'help' or 'help <plugin>'
plugins: fortune ping time version weather
You: help weather
APRSD: openweathermap: Send ^[wW] to get weather from your location
openweathermap: Send ^[wW] <callsign> to get weather from <callsign>
**Configuration:** Can be disabled by setting ``load_help_plugin = false`` in the configuration.
**Plugin Path:** ``aprsd.plugin.HelpPlugin``
WatchList Plugins
-----------------
These plugins monitor APRS traffic and can send notifications based on watch list criteria.
NotifySeenPlugin
~~~~~~~~~~~~~~~~
**Type:** WatchList Plugin
**Description:** Monitors callsigns in the watch list and sends a notification message when
a callsign that hasn't been seen recently (based on the configured age limit) appears on
the APRS network.
**How it works:**
- Tracks callsigns configured in the watch list
- Monitors all incoming APRS packets
- When a callsign in the watch list is seen and hasn't been seen recently (exceeds
the age limit), sends a notification message to the configured alert callsign
**Configuration:**
- ``watch_list.enabled`` - Must be set to ``true``
- ``watch_list.callsigns`` - List of callsigns to watch for
- ``watch_list.alert_callsign`` - Callsign to send notifications to
- ``watch_list.alert_time_seconds`` - Time threshold in seconds (default: 3600)
**Example Notification:**
::
APRSD -> WB4BOR: KM6LYW was just seen by type:'BeaconPacket'
**Plugin Path:** ``aprsd.plugins.notify.NotifySeenPlugin``
Enabling Built-in Plugins
--------------------------
Built-in plugins are enabled through the ``enabled_plugins`` configuration option in your
APRSD configuration file. List the full Python path to each plugin class you want to enable.
**Example Configuration:**
::
[DEFAULT]
enabled_plugins = aprsd.plugins.fortune.FortunePlugin,aprsd.plugins.ping.PingPlugin,aprsd.plugins.time.TimePlugin,aprsd.plugins.weather.OWMWeatherPlugin,aprsd.plugins.version.VersionPlugin,aprsd.plugins.notify.NotifySeenPlugin
**Note:** The HelpPlugin is enabled by default and does not need to be listed in
``enabled_plugins``. It can be disabled by setting ``load_help_plugin = false``.
**Note:** Some plugins may require additional configuration (API keys, etc.) and will
automatically disable themselves if required configuration is missing.
**Note:** Weather plugins (USWeatherPlugin, OWMWeatherPlugin, AVWXWeatherPlugin) all use
the same command pattern (``w`` or ``W`` at the start). Only one should be enabled at a time
to avoid conflicts. Similarly, METAR plugins (USMetarPlugin, AVWXWeatherPlugin) use the
same pattern (``m`` or ``M`` at the start).
Listing Available Plugins
--------------------------
You can see all available built-in plugins, along with their descriptions and command patterns,
by running:
.. code-block:: shell
aprsd list-plugins
This command will show:
- Built-in plugins included with APRSD
- Available plugins on PyPI that can be installed
- Currently installed third-party plugins
.. include:: links.rst
File diff suppressed because it is too large Load Diff
+206
View File
@@ -0,0 +1,206 @@
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
import os
import sys
from importlib.metadata import Distribution
sys.path.insert(0, os.path.abspath('../src'))
# -- Project information -----------------------------------------------------
project = 'APRSD'
copyright = ''
author = 'Walter A. Boring IV'
# The short X.Y version
# version = "v4.2.5"
# The full version, including alpha/beta/rc tags
release = Distribution.from_name('aprsd').version
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosectionlabel',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.napoleon',
'sphinx.ext.viewcode',
'sphinx_copybutton',
'sphinx_rtd_theme',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
# html_theme = "alabaster"
html_theme = 'sphinx_rtd_theme'
# html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {
# # Override the default alabaster line wrap, which wraps tightly at 940px.
# "page_width": "auto",
# }
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
intersphninx_mapping = {'python': ('https://docs.python.org/3', None)}
autodoc_typehints = 'description'
html_css_files = [
'https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/fira_code.min.css'
]
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'adoc'
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'a.tex', 'a Documentation', 'a', 'manual'),
]
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, 'a', 'a Documentation', [author], 1)]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
master_doc,
'a',
'a Documentation',
author,
'a',
'One line description of project.',
'Miscellaneous',
),
]
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''
# A unique identification for the text.
#
# epub_uid = ''
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# -- Extension configuration -------------------------------------------------
# -- Options for autosectionlabel extension ----------------------------------
# Prefix document path to section labels to avoid duplicate labels
autosectionlabel_prefix_document = True
# -- Options for todo extension ----------------------------------------------
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
+343
View File
@@ -0,0 +1,343 @@
APRSD Configure
===============
Configure APRSD
------------------------
Once APRSD is :doc:`installed <install>` You will need to configure the config file
for running.
Generate config file
---------------------
If you have never run the server, running it the first time will generate
a sample config file in the default location of ~/.config/aprsd/aprsd.yml
.. code-block:: shell
└─> aprsd server
12/28/2022 04:26:31 PM MainThread ERROR No config file found!! run 'aprsd sample-config' cli_helper.py:90
12/28/2022 04:26:31 PM MainThread ERROR Config aprs_network.password not set. client.py:105
12/28/2022 04:26:31 PM MainThread ERROR Option 'aprs_network.password is not set.' was not in config file client.py:268
12/28/2022 04:26:31 PM MainThread ERROR APRS client is not properly configured in config file. server.py:58
You can see the sample config file output
Sample config file
------------------
.. code-block:: shell
└─> aprsd sample-config
[DEFAULT]
#
# From aprsd.conf
#
# Callsign to use for messages sent by APRSD (string value)
#callsign = NOCALL
# Enable saving of watch list, packet tracker between restarts.
# (boolean value)
#enable_save = true
# Save location for packet tracking files. (string value)
#save_location = /Users/I530566/.config/aprsd/
# Enable code tracing (boolean value)
#trace_enabled = false
# Units for display, imperial or metric (string value)
#units = imperial
# The wait period in seconds per Ack packet being sent.1 means 1 ack
# packet per second allowed.2 means 1 pack packet every 2 seconds
# allowed (integer value)
#ack_rate_limit_period = 1
# Wait period in seconds per non AckPacket being sent.2 means 1 packet
# every 2 seconds allowed.5 means 1 pack packet every 5 seconds
# allowed (integer value)
#msg_rate_limit_period = 2
# The number of seconds before a packet is not considered a duplicate.
# (integer value)
#packet_dupe_timeout = 300
# Enable sending of a GPS Beacon packet to locate this service.
# Requires latitude and longitude to be set. (boolean value)
#enable_beacon = false
# The number of seconds between beacon packets. (integer value)
#beacon_interval = 1800
# The symbol to use for the GPS Beacon packet. See:
# http://www.aprs.net/vm/DOS/SYMBOLS.HTM (string value)
#beacon_symbol = /
# Latitude for the GPS Beacon button. If not set, the button will not
# be enabled. (string value)
#latitude = <None>
# Longitude for the GPS Beacon button. If not set, the button will
# not be enabled. (string value)
#longitude = <None>
# When logging packets 'compact' will use a single line formatted for
# each packet.'multiline' will use multiple lines for each packet and
# is the traditional format.both will log both compact and multiline.
# (string value)
# Possible values:
# compact - <No description provided>
# multiline - <No description provided>
# both - <No description provided>
#log_packet_format = compact
# The number of times to send a non ack packet before giving up.
# (integer value)
#default_packet_send_count = 3
# The number of times to send an ack packet in response to recieving a
# packet. (integer value)
#default_ack_send_count = 3
# The maximum number of packets to store in the packet list. (integer
# value)
#packet_list_maxlen = 100
# The maximum number of packets to send in the stats dict for admin
# ui. -1 means no max. (integer value)
#packet_list_stats_maxlen = 20
# Enable the Callsign seen list tracking feature. This allows aprsd
# to keep track of callsigns that have been seen and when they were
# last seen. (boolean value)
#enable_seen_list = true
# Set this to False, to disable logging of packets to the log file.
# (boolean value)
#enable_packet_logging = true
# Set this to False to disable the help plugin. (boolean value)
#load_help_plugin = true
# Set this to False, to disable sending of ack packets. This will
# entirely stopAPRSD from sending ack packets. (boolean value)
#enable_sending_ack_packets = true
# Set this to True, if APRSD is running on a Digipi.This is useful for
# changing the behavior of APRSD to work with Digipi. (boolean value)
#is_digipi = false
# Comma separated list of enabled plugins for APRSD.To enable
# installed external plugins add them here.The full python path to the
# class name must be used (list value)
#enabled_plugins = aprsd.plugins.fortune.FortunePlugin,aprsd.plugins.location.LocationPlugin,aprsd.plugins.ping.PingPlugin,aprsd.plugins.time.TimePlugin,aprsd.plugins.weather.OWMWeatherPlugin,aprsd.plugins.version.VersionPlugin,aprsd.plugins.notify.NotifySeenPlugin
[aprs_fi]
#
# From aprsd.conf
#
# Get the apiKey from your aprs.fi account here:http://aprs.fi/account
# (string value)
#apiKey = <None>
[aprs_network]
#
# From aprsd.conf
#
# Set enabled to False if there is no internet connectivity.This is
# useful for a direwolf KISS aprs connection only. (boolean value)
#enabled = true
# APRS Username (string value)
#login = NOCALL
# APRS Password Get the passcode for your callsign here:
# https://apps.magicbug.co.uk/passcode (string value)
#password = <None>
# The APRS-IS hostname (host address value)
#host = noam.aprs2.net
# APRS-IS port (port value)
# Minimum value: 0
# Maximum value: 65535
#port = 14580
[aprs_registry]
#
# From aprsd.conf
#
# Enable sending aprs registry information. This will let the APRS
# registry know about your service and it's uptime. No personal
# information is sent, just the callsign, uptime and description. The
# service callsign is the callsign set in [DEFAULT] section. (boolean
# value)
#enabled = false
# Description of the service to send to the APRS registry. This is
# what will show up in the APRS registry.If not set, the description
# will be the same as the callsign. (string value)
#description = <None>
# The APRS registry domain name to send the information to. (string
# value)
#registry_url = https://aprs.hemna.com/api/v1/registry
# The website for your APRS service to send to the APRS registry.
# (string value)
#service_website = <None>
# The frequency in seconds to send the APRS registry information.
# (integer value)
#frequency_seconds = 3600
[avwx_plugin]
#
# From aprsd.conf
#
# avwx-api is an opensource project that hasa hosted service here:
# https://avwx.rest/You can launch your own avwx-api in a containerby
# cloning the githug repo here:https://github.com/avwx-rest/AVWX-API
# (string value)
#apiKey = <None>
# The base url for the avwx API. If you are hosting your ownHere is
# where you change the url to point to yours. (string value)
#base_url = https://avwx.rest
[fake_client]
#
# From aprsd.conf
#
# Enable fake client connection. (boolean value)
#enabled = false
[kiss_serial]
#
# From aprsd.conf
#
# Enable Serial KISS interface connection. (boolean value)
#enabled = false
# Serial Device file to use. /dev/ttyS0 (string value)
#device = <None>
# The Serial device baud rate for communication (integer value)
#baudrate = 9600
# The APRS path to use for wide area coverage. (list value)
#path = WIDE1-1,WIDE2-1
[kiss_tcp]
#
# From aprsd.conf
#
# Enable Serial KISS interface connection. (boolean value)
#enabled = false
# The KISS TCP Host to connect to. (host address value)
#host = <None>
# The KISS TCP/IP network port (port value)
# Minimum value: 0
# Maximum value: 65535
#port = 8001
# The APRS path to use for wide area coverage. (list value)
#path = WIDE1-1,WIDE2-1
[logging]
#
# From aprsd.conf
#
# File to log to (string value)
#logfile = <None>
# Log file format, unless rich_logging enabled. (string value)
#logformat = <green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <yellow>{thread.name: <18}</yellow> | <level>{level: <8}</level> | <level>{message}</level> | <cyan>{name}</cyan>:<cyan>{function:}</cyan>:<magenta>{line:}</magenta>
# Log level for logging of events. (string value)
# Possible values:
# CRITICAL - <No description provided>
# ERROR - <No description provided>
# WARNING - <No description provided>
# INFO - <No description provided>
# DEBUG - <No description provided>
#log_level = INFO
# Enable ANSI color codes in logging (boolean value)
#enable_color = true
# Enable logging to the console/stdout. (boolean value)
#enable_console_stdout = true
[owm_weather_plugin]
#
# From aprsd.conf
#
# OWMWeatherPlugin api key to OpenWeatherMap's API.This plugin uses
# the openweathermap API to fetchlocation and weather information.To
# use this plugin you need to get an openweathermapaccount and
# apikey.https://home.openweathermap.org/api_keys (string value)
#apiKey = <None>
[watch_list]
#
# From aprsd.conf
#
# Enable the watch list feature. Still have to enable the correct
# plugin. Built-in plugin to use is aprsd.plugins.notify.NotifyPlugin
# (boolean value)
#enabled = false
# Callsigns to watch for messsages (list value)
#callsigns = <None>
# The Ham Callsign to send messages to for watch list alerts. (string
# value)
#alert_callsign = <None>
# The number of packets to store. (integer value)
#packet_keep_count = 10
# Time to wait before alert is sent on new message for users in
# callsigns. (integer value)
#alert_time_seconds = 3600
Note, You must edit the config file and change the ham callsign to your
legal FCC HAM callsign, or aprsd server will not start.
.. include:: links.rst
+234
View File
@@ -0,0 +1,234 @@
APRSD Extension Development
============================
APRSD extensions are more comprehensive than plugins and can add new functionality
to the APRSD daemon beyond simple command plugins. Extensions can include:
* New command-line commands
* Configuration options
* Background threads
* Statistics collectors
* Custom packet processors
* And more
Creating an Extension Project
-------------------------------
The recommended way to create a new APRSD extension project is to use the
`cookiecutter-aprsd-extension`_ template. This template provides a complete project
structure with all the necessary files, testing infrastructure, and documentation setup.
Installation
~~~~~~~~~~~~
First, install cookiecutter if you haven't already::
pip install cookiecutter
Creating a New Extension Project
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run cookiecutter with the APRSD extension template::
cookiecutter gh:hemna/cookiecutter-aprsd-extension
Cookiecutter will prompt you for several pieces of information:
* **extension_name**: The name of your extension (e.g., ``aprsd-my-extension``)
* **extension_module_name**: The Python module name (e.g., ``aprsd_my_extension``)
* **author_name**: Your name or organization name
* **author_email**: Your email address
* **description**: A brief description of your extension
* **version**: Initial version (default: ``0.1.0``)
Project Structure
~~~~~~~~~~~~~~~~~
The cookiecutter template creates a complete project structure including:
* **Test automation** with Tox
* **Linting** with pre-commit and Flake8
* **Continuous integration** with GitHub Actions
* **Documentation** with Sphinx and Read the Docs
* **Automated uploads** to PyPI and TestPyPI
* **Automated dependency updates** with Dependabot
* **Code formatting** with Gray
* **Testing** with pytest
* **Code coverage** with Coverage.py
* **Coverage reporting** with Codecov
The generated project follows Python packaging best practices and includes:
* Proper ``setup.py`` and ``pyproject.toml`` configuration
* Entry point registration for APRSD extension discovery (``aprsd.extension``)
* Configuration entry points for oslo.config (``oslo.config.opts``)
* Test suite structure
* Documentation templates
* CI/CD pipeline configuration
Extension Registration
~~~~~~~~~~~~~~~~~~~~~~
Extensions are registered using Python entry points in your ``pyproject.toml`` or
``setup.py`` file. The entry point group is ``aprsd.extension``::
[project.entry-points."aprsd.extension"]
"my_extension" = "aprsd_my_extension.extension"
Configuration Options
~~~~~~~~~~~~~~~~~~~~~
Extensions can add their own configuration options using oslo.config. Register
your configuration options using the ``oslo.config.opts`` entry point::
[project.entry-points."oslo.config.opts"]
"aprsd_my_extension.conf" = "aprsd_my_extension.conf.opts:list_opts"
Example Extension Structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~
A typical extension project structure looks like this::
aprsd-my-extension/
├── aprsd_my_extension/
│ ├── __init__.py
│ ├── extension.py # Main extension entry point
│ ├── cmds/ # Command-line commands
│ │ ├── __init__.py
│ │ └── show.py
│ ├── conf/ # Configuration options
│ │ ├── __init__.py
│ │ ├── opts.py
│ │ └── main.py
│ ├── threads/ # Background threads
│ │ ├── __init__.py
│ │ └── MyThread.py
│ └── stats.py # Statistics collectors
├── tests/
├── docs/
├── pyproject.toml
├── setup.py
└── README.md
Example Extension: WebChat
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The `aprsd-webchat-extension`_ is a real-world example of an APRSD extension that
adds a web-based chat interface to APRSD. Let's examine how it's structured:
Entry Point Registration
^^^^^^^^^^^^^^^^^^^^^^^^^
In ``pyproject.toml``, the extension registers itself::
[project.entry-points."aprsd.extension"]
"webchat" = "aprsd_webchat_extension.extension"
[project.entry-points."oslo.config.opts"]
"aprsd_webchat_extension.conf" = "aprsd_webchat_extension.conf.opts:list_opts"
Extension Entry Point
^^^^^^^^^^^^^^^^^^^^^^
The ``extension.py`` file imports the command module to register it::
from aprsd_webchat_extension.cmds import webchat # noqa: F401
This import causes the command to be registered with APRSD's CLI system.
Command Implementation
^^^^^^^^^^^^^^^^^^^^^^
The webchat extension adds a new command ``aprsd webchat`` that starts a Flask-based
web server. The command is implemented in ``cmds/webchat.py`` and uses Click for
command-line interface::
import click
from aprsd.main import cli
@cli.command()
@click.option('--host', default='0.0.0.0', help='Host to bind to')
@click.option('--port', default=8080, help='Port to bind to')
def webchat(host, port):
"""Start the webchat interface."""
# Implementation here
pass
WebChat Configuration Options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The extension adds configuration options through ``conf/opts.py``::
from oslo_config import cfg
webchat_group = cfg.OptGroup(name='webchat',
title='WebChat Options')
webchat_opts = [
cfg.StrOpt('host',
default='0.0.0.0',
help='WebChat server host'),
cfg.IntOpt('port',
default=8080,
help='WebChat server port'),
]
def list_opts():
return [
(webchat_group, webchat_opts),
]
The configuration can then be used in the extension code::
from oslo_config import cfg
CONF = cfg.CONF
host = CONF.webchat.host
port = CONF.webchat.port
WebChat Project Structure
^^^^^^^^^^^^^^^^^^^^^^^^^
The webchat extension has the following structure::
aprsd-webchat-extension/
├── aprsd_webchat_extension/
│ ├── __init__.py
│ ├── extension.py # Entry point that imports commands
│ ├── cmds/
│ │ ├── __init__.py
│ │ └── webchat.py # Command implementation
│ ├── conf/
│ │ ├── __init__.py
│ │ ├── opts.py # Configuration option definitions
│ │ └── main.py # Configuration group definitions
│ ├── web/ # Web assets (HTML, CSS, JS)
│ │ └── chat/
│ │ ├── static/
│ │ └── templates/
│ └── utils.py # Utility functions
├── tests/
├── docs/
├── pyproject.toml
└── README.md
Usage
^^^^^
Once installed, users can run the webchat command::
$ aprsd webchat --loglevel DEBUG
This demonstrates how extensions can add new functionality beyond simple plugins,
including web interfaces, background services, and complex integrations.
For more information about the cookiecutter template, visit the
`cookiecutter-aprsd-extension repository`_.
For the complete source code of the webchat extension, see the
`aprsd-webchat-extension repository`_.
.. _cookiecutter-aprsd-extension: https://github.com/hemna/cookiecutter-aprsd-extension
.. _cookiecutter-aprsd-extension repository: https://github.com/hemna/cookiecutter-aprsd-extension
.. _aprsd-webchat-extension: https://github.com/hemna/aprsd-webchat-extension
.. _aprsd-webchat-extension repository: https://github.com/hemna/aprsd-webchat-extension
+34
View File
@@ -0,0 +1,34 @@
.. a documentation master file, created by
sphinx-quickstart on Wed Dec 19 18:34:22 2018.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
``APRSD`` Documentation
=======================
.. include:: readme.rst
.. toctree::
:maxdepth: 2
:caption: Contents:
readme
changelog
install
configure
server
listen
builtin_plugins
plugin
extension
apidoc/modules.rst
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
.. include:: links.rst
+67
View File
@@ -0,0 +1,67 @@
APRSD installation
==================
Install info in a nutshell
--------------------------
**Pythons**: Python 3.6 or later
**Operating systems**: Linux, OSX, Unix
**Installer Requirements**: setuptools_
**License**: Apache license
**git repository**: https://github.com/craigerl/aprsd
Installation with pip
--------------------------------------
Use the following command:
.. code-block:: shell
pip install aprsd
It is fine to install ``aprsd`` itself into a virtualenv_ environment.
Install from clone
-------------------------
Consult the GitHub page how to clone the git repository:
https://github.com/craigerl/aprsd
and then install in your environment with something like:
.. code-block:: shell
$ cd <path/to/clone>
$ pip install .
or install it `editable <https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs>`_ if you want code changes to propagate automatically:
.. code-block:: shell
$ cd <path/to/clone>
$ pip install --editable .
so that you can do changes and submit patches.
Install for development
----------------------------
For developers you should clone the repo from github, then use the Makefile
.. code-block:: shell
$ cd <path/to/clone>
$ make
This creates a virtualenv_ directory, install all the requirements for
development as well as aprsd in `editable <https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs>`_ mode.
It will install all of the pre-commit git hooks required to test prior to committing code.
.. include:: links.rst
+31
View File
@@ -0,0 +1,31 @@
.. _`Cookiecutter`: https://cookiecutter.readthedocs.io
.. _`pluggy`: https://pluggy.readthedocs.io
.. _`cookiecutter-tox-plugin`: https://github.com/tox-dev/cookiecutter-tox-plugin
.. _devpi: https://doc.devpi.net
.. _Python: https://www.python.org
.. _virtualenv: https://pypi.org/project/virtualenv
.. _`pytest`: https://pytest.org
.. _nosetests:
.. _`nose`: https://pypi.org/project/nose
.. _`Holger Krekel`: https://twitter.com/hpk42
.. _`pytest-xdist`: https://pypi.org/project/pytest-xdist
.. _ConfigParser: https://docs.python.org/3/library/configparser.html
.. _`easy_install`: http://peak.telecommunity.com/DevCenter/EasyInstall
.. _pip: https://pypi.org/project/pip
.. _setuptools: https://pypi.org/project/setuptools
.. _`jenkins`: https://jenkins.io/index.html
.. _sphinx: https://pypi.org/project/Sphinx
.. _discover: https://pypi.org/project/discover
.. _unittest2: https://pypi.org/project/unittest2
.. _mock: https://pypi.org/project/mock/
.. _flit: https://flit.readthedocs.io/en/latest/
.. _poetry: https://poetry.eustace.io/
.. _pypy: https://pypy.org
.. _`Python Packaging Guide`: https://packaging.python.org/tutorials/packaging-projects/
.. _`tox.ini`: :doc:configfile
.. _`PEP-508`: https://www.python.org/dev/peps/pep-0508/
.. _`PEP-517`: https://www.python.org/dev/peps/pep-0517/
.. _`PEP-518`: https://www.python.org/dev/peps/pep-0518/
+325
View File
@@ -0,0 +1,325 @@
APRSD listen
============
Running the APRSD listen command
---------------------------------
The ``aprsd listen`` command allows you to listen to packets on the APRS-IS Network based on a FILTER.
This is useful for monitoring specific APRS traffic without running the full server.
Once APRSD is :doc:`installed <install>` and :doc:`configured <configure>`, the listen command can be started by running:
.. code-block:: shell
aprsd listen [FILTER]
The FILTER parameter is optional and follows the APRS-IS filter format. For example, ``m/300`` filters for
messages within 300 miles of your configured location.
Example usage
-------------
.. code-block:: text
aprsd listen m/300
2025-12-11 09:44:33.349 | Python version: 3.14.0rc1 free-threading build (main, Aug 8 2025, 16:53:07) [Clang 20.1.4 ]
2025-12-11 09:44:33.349 | APRSD Listen Started version: 4.2.5.dev17+g0ef131678.d20251211
2025-12-11 09:44:33.365 | Creating aprslib client(155.138.131.1:14580) and logging in WB4BOR-1. try #1
2025-12-11 09:44:33.365 | Attempting connection to 155.138.131.1:14580
2025-12-11 09:44:33.391 | Connected to ('155.138.131.1', 14580)
2025-12-11 09:44:33.469 | Login successful
2025-12-11 09:44:33.469 | Connected to T2CAEAST
2025-12-11 09:44:33.469 | Creating client connection
2025-12-11 09:44:33.469 | <aprsd.client.client.APRSDClient object at 0x57a5c7bc310>
2025-12-11 09:44:33.469 | Setting filter to: ('m/300',)
2025-12-11 09:44:33.469 | No packet filtering enabled.
2025-12-11 09:44:33.469 | Not Loading any plugins use --load-plugins to load what's defined in the config file.
2025-12-11 09:44:35.458 | RX(1)↓ BeaconPacket:None KQ4INX-D →TCPIP*→qAC→KQ4INX-DS→ APDG03 : Lat:37.598 Lon:-77.323 70cm MMDVM Voice (DMR) 440.52500MHz +5.0000MHz, APRS for DMRGateway : East-Northeast@85.57miles
2025-12-11 09:44:35.472 | RX(2)↓ StatusPacket:None KQ4INX-D →qAS→KQ4INX→ APDG03 : Powered by WPSD (https://wpsd.radio)
2025-12-11 09:44:36.599 | RX(3)↓ BeaconPacket:None WX4EMC-1 →qAR→W4KEL-12→ ID : Lat:0.000 Lon:0.000 None : East@5607.38miles
2025-12-11 09:44:38.306 | RX(4)↓ BeaconPacket:None KC4JGC-10 →TCPIP*→qAC→T2BIO→ APDR16 : Lat:38.043 Lon:-78.722 : North@48.78miles
2025-12-11 09:44:39.472 | RX(5)↓ WeatherPacket:None K9MJM-1 →TCPIP*→qAC→T2SYDNEY→ SKY : Temp -04F Humidity 92% Wind 000MPH@96 Pressure 1013.3mb Rain 0.0in/24hr : West-Southwest@175.80miles
2025-12-11 09:44:39.524 | RX(6)↓ BeaconPacket:None KA6LOW →TCPIP*→qAC→T2RDU→ APDPRS : Lat:39.126 Lon:-77.574 : North-Northeast@141.21miles
2025-12-11 09:44:41.392 | RX(7)↓ MicEPacket:None KM4HFB-9 →WIDE1-1→WIDE2-1→qAR→W4KEL-12→ SX1U5Y : Lat:38.260 Lon:-77.550 Altitude 078 Speed 015MPH Course 248 110 mbits : Northeast@95.08miles
2025-12-11 09:44:41.418 | RX(8)↓ BeaconPacket:None K8WVU-9 →W8SP-1→WIDE1*→WIDE2-1→qAR→KF8LO-1→ APAT81 : Lat:39.580 Lon:-79.957 using Radioddity DB25-D : North-Northwest@165.67miles
2025-12-11 09:44:42.131 | RX(9)↓ MicEPacket:None N0OEP-9 →WIDE1-1→WIDE2-1→qAR→KB4ZIN-1→ S7QW6Y : Lat:37.295 Lon:-76.716 Altitude 028 Course 063 101 mbits : East@117.30miles
2025-12-11 09:44:42.723 | RX(10)↓ ObjectPacket:None KJ4ACB-S →TCPIP*→qAC→KJ4ACB-GS→ APDG01 : Lat:35.444 Lon:-78.515 Altitude 003 RNG 002 70cm Voice (D-Star) 434.60000MHz +0.0000MHz : South@132.62miles
2025-12-11 09:44:43.158 | RX(11)↓ WeatherPacket:None KO4FR →TCPIP*→qAC→T2SPAIN→ APRS : Temp 005F Humidity 54% Wind 000MPH@146 Pressure 1011.9mb Rain 0.09in/24hr : Southeast@45.96miles
2025-12-11 09:44:43.249 | RX(12)↓ BeaconPacket:None AA4HI-4 →TCPIP*→qAS→N4UED-4→ APMI06 : Lat:36.449 Lon:-77.636 WX3in1Plus2.0 U=12.5V,T=??.?C/??.?F : Southeast@91.24miles
The listen command connects to the APRS-IS network and displays packets matching the specified filter.
In the example above, packets within 300 miles are displayed, showing various packet types including MicEPacket,
BeaconPacket, and WeatherPacket.
APRS-IS Filter Syntax
----------------------
The ``aprsd listen`` command supports the full APRS-IS server-side filter syntax. For complete documentation
on all available filter types and options, see the `APRS-IS Filter Documentation <http://www.aprs-is.net/javAPRSFilter.aspx>`_.
Filters allow you to subscribe to specific APRS traffic based on various criteria. Multiple filter specifications
can be combined, separated by spaces. If any filter matches, the packet is passed.
You can also exclude packets by prefixing a filter parameter with a hyphen (-). This tells the filter to
approve packets that match the include filters **except** those that match the exclude filters.
For example, to get all stations within 200 km except stations with the prefix "CW":
.. code-block:: shell
aprsd listen m/200 -p/CW
The following filter types are available:
Range Filter (r/lat/lon/dist)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes position packets and objects within ``dist`` km from the specified latitude/longitude.
Latitude and longitude are signed decimal degrees (negative for West/South, positive for East/North).
Up to 9 range filters can be defined simultaneously for better coverage. Messages addressed to stations
within the range are also passed.
**Example:**
.. code-block:: shell
aprsd listen r/33/-97/200
This filters for packets within 200 km of latitude 33, longitude -97 (Dallas, Texas area).
My Range Filter (m/dist)
~~~~~~~~~~~~~~~~~~~~~~~~
Same as the range filter, except the center is defined as the last known position of the logged-in client
(as configured in your APRSD config file).
**Example:**
.. code-block:: shell
aprsd listen m/300
This filters for packets within 300 miles of your configured location.
Friend Range Filter (f/call/dist)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Same as the range filter, except the center is defined as the last known position of the specified callsign.
Up to 9 friend filters can be defined simultaneously.
**Example:**
.. code-block:: shell
aprsd listen f/WB4BOR-1/50
This filters for packets within 50 km of the last known position of WB4BOR-1.
Area Filter (a/latN/lonW/latS/lonE)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Works like the range filter but defines a rectangular box of coordinates. Coordinates can be seen as
upper-left and lower-right corners. Latitude/longitude are decimal degrees (South and West are negative).
Up to 9 area filters can be defined simultaneously.
**Example:**
.. code-block:: shell
aprsd listen a/40/-80/35/-75
This filters for packets in a box from latitude 40N, longitude 80W to latitude 35N, longitude 75W.
Prefix Filter (p/aa/bb/cc...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes traffic with fromCall that starts with any of the specified prefixes.
**Example:**
.. code-block:: shell
aprsd listen p/WB4/KM6
This filters for packets from callsigns starting with "WB4" or "KM6".
Budlist Filter (b/call1/call2...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes all traffic from exact callsigns: call1, call2, etc. The asterisk (*) wildcard is allowed.
**Example:**
.. code-block:: shell
aprsd listen b/WB4BOR-1/KM6LYW
This filters for packets from exactly WB4BOR-1 or KM6LYW.
Object Filter (o/obj1/obj2...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes all objects with the exact name of obj1, obj2, etc. The asterisk (*) wildcard is allowed.
Spaces are not allowed. Use ``|`` for ``/`` and ``~`` for ``*`` in object names.
**Example:**
.. code-block:: shell
aprsd listen o/APRS*/WEATHER
This filters for objects named "APRS*" or "WEATHER".
Strict Object Filter (os/obj1/obj2...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes all objects with the exact name of obj1, obj2, etc. Objects are always 9 characters and Items
are 3 to 9 characters. There can only be one ``os`` filter and it must be at the end of the filter line.
The asterisk (*) wildcard is allowed. Use ``|`` for ``/`` and ``~`` for ``*`` in object names.
Type Filter (t/poimqstunw or t/poimqstuw/call/km)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes all traffic based on packet type. One or more types can be defined:
- ``p`` = Position packets
- ``o`` = Objects
- ``i`` = Items
- ``m`` = Message
- ``q`` = Query
- ``s`` = Status
- ``t`` = Telemetry
- ``u`` = User-defined
- ``n`` = NWS format messages and objects
- ``w`` = Weather
The weather type filter also passes position packets for positionless weather packets.
The second format allows putting a radius limit around a callsign (station callsign-SSID or object name)
for the requested station types.
**Examples:**
.. code-block:: shell
aprsd listen t/mw
aprsd listen t/poimqstuw/WB4BOR-1/50
The first example filters for messages and weather packets. The second filters for all packet types
within 50 km of WB4BOR-1.
Symbol Filter (s/pri/alt/over)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Filters by symbol. ``pri`` = symbols in primary table, ``alt`` = symbols in alternate table,
``over`` = overlay character (case sensitive). Use ``|`` for ``/`` in symbol specifications.
**Examples:**
.. code-block:: shell
aprsd listen s/->
aprsd listen s//#
aprsd listen s//#/T
The first passes all House and Car symbols (primary table). The second passes all Digi with or without
overlay. The third passes all Digi with overlay of capital "T".
Digipeater Filter (d/digi1/digi2...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes all packets that have been digipeated by a particular station(s) (the station's call is in the path).
The asterisk (*) wildcard is allowed.
**Example:**
.. code-block:: shell
aprsd listen d/WIDE1-1/WIDE2-1
This filters for packets digipeated by WIDE1-1 or WIDE2-1.
Entry Station Filter (e/call1/call2/...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes all packets with the specified callsign-SSID(s) immediately following the q construct. This allows
filtering based on receiving IGate, etc. Supports asterisk (*) wildcard.
**Example:**
.. code-block:: shell
aprsd listen e/T2CAEAST/T2SYDNEY
This filters for packets received by T2CAEAST or T2SYDNEY IGates.
Group Message Filter (g/call1/call2/...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes all message packets with the specified callsign-SSID(s) as the addressee of the message.
Supports asterisk (*) wildcard.
**Example:**
.. code-block:: shell
aprsd listen g/REPEAT/APRS
This filters for messages addressed to REPEAT or APRS.
Unproto Filter (u/unproto1/unproto2/...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes all packets with the specified destination callsign-SSID(s) (also known as the To call or unproto call).
Supports asterisk (*) wildcard.
**Example:**
.. code-block:: shell
aprsd listen u/APRS*/CQ
This filters for packets with destination callsigns starting with "APRS" or "CQ".
q Construct Filter (q/con/I)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Filters by q Construct command. ``con`` = list of q Constructs to pass (case sensitive),
``I`` = Pass positions from IGATES identified by qAr, qAo, or qAR.
**Examples:**
.. code-block:: shell
aprsd listen q/C
aprsd listen q/rR
aprsd listen q//I
The first passes all traffic with qAC. The second passes all traffic with qAr or qAR.
The third passes all position packets from IGATES identified in other packets by qAr or qAR.
Filter Notes
~~~~~~~~~~~~
- Multiple filter definitions can be combined, separated by spaces
- If any filter matches, the packet is passed (OR logic)
- Exclude filters (prefixed with ``-``) block specified packets from include filters
- Standard port functionality such as messaging for IGates is not affected
- Filters only affect data going to the client; packets from the client or gated by the client are not filtered
- The filter command can be set as part of the login line or as a separate command
- Use ``filter default`` to reset to the predefined filter for that port
For more information, see the `APRS-IS Filter Documentation <http://www.aprs-is.net/javAPRSFilter.aspx>`_.
Key differences from the server command
----------------------------------------
Unlike the ``aprsd server`` command, the listen command:
- Does not load plugins by default (use ``--load-plugins`` to enable them)
- Does not respond to messages
- Is designed for monitoring and logging APRS traffic
- Supports APRS-IS filter syntax for targeted packet monitoring
.. include:: links.rst
+112
View File
@@ -0,0 +1,112 @@
APRSD Command Plugin Development
================================
Creating a Plugin Project
-------------------------
The recommended way to create a new APRSD plugin project is to use the `cookiecutter-aprsd-plugin`_ template. This template provides a complete project structure with all the necessary files, testing infrastructure, and documentation setup.
Installation
~~~~~~~~~~~~
First, install cookiecutter if you haven't already::
pip install cookiecutter
Creating a New Plugin Project
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run cookiecutter with the APRSD plugin template::
cookiecutter gh:hemna/cookiecutter-aprsd-plugin
Cookiecutter will prompt you for several pieces of information:
* **plugin_name**: The name of your plugin (e.g., ``aprsd-my-plugin``)
* **plugin_module_name**: The Python module name (e.g., ``aprsd_my_plugin``)
* **author_name**: Your name or organization name
* **author_email**: Your email address
* **description**: A brief description of your plugin
* **version**: Initial version (default: ``0.1.0``)
Project Structure
~~~~~~~~~~~~~~~~~
The cookiecutter template creates a complete project structure including:
* **Test automation** with Tox
* **Linting** with pre-commit and Flake8
* **Continuous integration** with GitHub Actions
* **Documentation** with Sphinx and Read the Docs
* **Automated uploads** to PyPI and TestPyPI
* **Automated dependency updates** with Dependabot
* **Code formatting** with Gray
* **Testing** with pytest
* **Code coverage** with Coverage.py
* **Coverage reporting** with Codecov
The generated project follows Python packaging best practices and includes:
* Proper ``setup.py`` and ``pyproject.toml`` configuration
* Entry point registration for APRSD plugin discovery
* Test suite structure
* Documentation templates
* CI/CD pipeline configuration
For more information about the cookiecutter template, visit the `cookiecutter-aprsd-plugin repository`_.
.. _cookiecutter-aprsd-plugin: https://github.com/hemna/cookiecutter-aprsd-plugin
.. _cookiecutter-aprsd-plugin repository: https://github.com/hemna/cookiecutter-aprsd-plugin
APRSDPluginBase
------------------------
Plugins are written as python objects that extend the APRSDPluginBase class.
This is an abstract class that has several properties and a method that must be implemented
by your subclass.
Properties
----------
* name - the Command name
* regex - The regular expression that if matched against the incoming APRS message,
will cause your plugin to be called.
Methods
-------
* command - This method is called when the regex matches the incoming message from APRS.
If you want to send a message back to the sending, just return a string
in your method implementation. If you get called and don't want to reply, then
you should return a messaging.NULL_MESSAGE to signal to the plugin processor
that you got called and processed the message correctly. Otherwise a usage
string may get returned to the sender.
Example Plugin
--------------
There is an example plugin in the aprsd source code here:
aprsd/examples/plugins/example_plugin.py
.. code-block:: python
import logging
from aprsd import plugin
LOG = logging.getLogger("APRSD")
class HelloPlugin(plugin.APRSDRegexCommandPluginBase):
"""Hello World."""
version = "1.0"
# matches any string starting with h or H
command_regex = "^[hH]"
command_name = "hello"
def process(self, packet):
LOG.info("HelloPlugin")
reply = "Hello '{}'".format(packet.from_call)
return reply
+553
View File
@@ -0,0 +1,553 @@
.. role:: raw-html-m2r(raw)
:format: html
APRSD - Ham radio APRS-IS Message platform software
===================================================
KM6LYW and WB4BOR
-----------------
.. image:: https://badge.fury.io/py/aprsd.svg
:target: https://badge.fury.io/py/aprsd
:alt: pypi
.. image:: https://img.shields.io/pypi/pyversions/aprsd.svg
:target: https://pypi.org/pypi/aprsd
:alt: versions
.. image:: https://img.shields.io/badge/slack-@hemna/aprsd-blue.svg?logo=slack
:target: https://hemna.slack.com/app_redirect?channel=C01KQSCP5RP
:alt: slack
.. image:: https://img.shields.io/github/issues/craigerl/aprsd
:target: https://img.shields.io/github/issues/craigerl/aprsd
:alt: issues
.. image:: https://img.shields.io/github/last-commit/craigerl/aprsd
:target: https://img.shields.io/github/last-commit/craigerl/aprsd
:alt: commit
.. image:: https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336
:target: https://timothycrosley.github.io/isort/
:alt: imports
.. image:: https://static.pepy.tech/personalized-badge/aprsd?period=month&units=international_system&left_color=black&right_color=orange&left_text=Downloads
:target: https://pepy.tech/project/aprsd
:alt: down
`APRSD <http://github.com/craigerl/aprsd>`_ is a Ham radio
`APRS <http://aprs.org>`_ message platform built with python.
.. image:: ../images/aprsd_logo.png
:target: ../images/aprsd_logo.png
:alt: APRSD Logo
Table of Contents
=================
#. `APRSD - Ham radio APRS-IS Message platform software <#aprsd---ham-radio-aprs-is-message-platform-software>`_
#. `What is APRSD <#what-is-aprsd>`_
#. `APRSD Plugins/Extensions <#aprsd-pluginsextensions>`_
#. `List of existing plugins - APRS Message processing/responders <#list-of-existing-plugins---aprs-message-processingresponders>`_
#. `List of existing extensions - Add new capabilities to APRSD <#list-of-existing-extensions---add-new-capabilities-to-aprsd>`_
#. `APRSD Overview Diagram <#aprsd-overview-diagram>`_
#. `Typical use case <#typical-use-case>`_
#. `Installation <#installation>`_
#. `Example usage <#example-usage>`_
#. `Help <#help>`_
#. `Commands <#commands>`_
#. `Configuration <#configuration>`_
#. `server <#server>`_
#. `Current list plugins <#current-list-plugins>`_
#. `Current list extensions <#current-list-extensions>`_
#. `send-message <#send-message>`_
#. `Development <#development>`_
#. `Release <#release>`_
#. `Building your own APRSD plugins <#building-your-own-aprsd-plugins>`_
#. `Docker Container <#docker-container>`_
#. `Running the container <#running-the-container>`_
#. `Activity <#activity>`_
#. `Star History <#star-history>`_
----
..
[!WARNING]
Legal operation of this software requires an amateur radio license and a valid call sign.
[!NOTE]
Star this repo to follow our progress! This code is under active development, and contributions are both welcomed and appreciated. See `CONTRIBUTING.md <https://github.com/craigerl/aprsd/blob/master/CONTRIBUTING.md>`_ for details.
What is APRSD
-------------
APRSD is a python application for interacting with the APRS network and Ham radios with KISS interfaces and
providing APRS services for HAM radio operators.
APRSD currently has the following commands to use.
* server - Start the aprsd server gateway process.
* listen - Listen to packets on the APRS-IS Network based on FILTER.
* send-message - Send a message to a callsign via APRS_IS.
* check-version - Check this version against the latest in pypi.org.
* completion - Show the shell completion code
* dev - Development type subcommands
* dump-stats - Dump the current stats from the running APRSD instance.
* fetch-stats - Fetch stats from a APRSD admin web interface.
* healthcheck - Check the health of the running aprsd server.
* list-extensions - List the built in extensions available to APRSD.
* list-plugins - List the built in plugins available to APRSD.
* passcode - Generate an APRS passcode for a callsign.
* sample-config - Generate a sample Config file from aprsd and all...
* version - Show the APRSD version.
Each of those commands can connect to the APRS-IS network if internet
connectivity is available. If internet is not available, then APRS can
be configured to talk to a TCP KISS TNC for radio connectivity directly.
Please `read the docs <https://aprsd.readthedocs.io>`_ to learn more!
APRSD Plugins/Extensions
------------------------
APRSD Has the ability to add plugins and extensions. Plugins add new message filters that can look for specific messages and respond. For example, the aprsd-email-plugin adds the ability to send/recieve email to/from an APRS callsign. Extensions add new unique capabilities to APRSD itself. For example the aprsd-admin-extension adds a web interface command that shows the running status of the aprsd server command. aprsd-webchat-extension is a new web based APRS 'chat' command.
You can see the `available plugins/extensions on pypi here: <https://pypi.org/search/?q=aprsd>`_ `https://pypi.org/search/?q=aprsd <https://pypi.org/search/?q=aprsd>`_
..
[!NOTE]
aprsd admin and webchat commands have been extracted into separate extensions.
* `See admin extension here <https://github.com/hemna/aprsd-admin-extension>`_ :raw-html-m2r:`<div id="admin logo" align="left"><img src="https://raw.githubusercontent.com/hemna/aprsd-admin-extension/refs/heads/master/screenshot.png" alt="Web Admin" width="340"/></div>`
*
`See webchat extension here <https://github.com/hemna/aprsd-webchat-extension>`_ :raw-html-m2r:`<div id="webchat logo" align="left"><img src="https://raw.githubusercontent.com/hemna/aprsd-webchat-extension/master/screenshot.png" alt="Webchat" width="340"/></div>`
*
`See CLI chat extension here <https://github.com/hemna/aprsd-rich-cli-extension>`_ :raw-html-m2r:`<div id="rich_logo" align="left"><img src="https://raw.githubusercontent.com/hemna/aprsd-rich-cli-extension/refs/heads/master/screenshot.png" alt="CLI Chat" width="340"></div>`
List of existing plugins - APRS Message processing/responders
-------------------------------------------------------------
* `aprsd-email-plugin <https://github.com/hemna/aprsd-email-plugin>`_ - send/receive email!
* `aprsd-location-plugin <https://github.com/hemna/aprsd-location-plugin>`_ - get latest GPS location.
* `aprsd-locationdata-plugin <https://github.com/hemna/aprsd-locationdata-plugin>`_ - get latest GPS location
* `aprsd-digipi-plugin <https://github.com/hemna/aprsd-digipi-plugin>`_ - Look for digipi beacon packets
* `aprsd-w3w-plugin <https://github.com/hemna/aprsd-w3w-plugin>`_ - get your w3w coordinates
* `aprsd-mqtt-plugin <https://github.com/hemna/aprsd-mqtt-plugin>`_ - send aprs packets to an MQTT topic
* `aprsd-telegram-plugin <https://github.com/hemna/aprsd-telegram-plugin>`_ - send/receive messages to telegram
* `aprsd-borat-plugin <https://github.com/hemna/aprsd-borat-plugin>`_ - get Borat quotes
* `aprsd-wxnow-plugin <https://github.com/hemna/aprsd-wxnow-plugin>`_ - get closest N weather station reports
* `aprsd-weewx-plugin <https://github.com/hemna/aprsd-weewx-plugin>`_ - get weather from your weewx weather station
* `aprsd-slack-plugin <https://github.com/hemna/aprsd-slack-plugin>`_ - send/receive messages to a slack channel
* `aprsd-sentry-plugin <https://github.com/hemna/aprsd-sentry-plugin>`_ -
* `aprsd-repeat-plugins <https://github.com/hemna/aprsd-repeat-plugins>`_ - plugins for the REPEAT service. Get nearest Ham radio repeaters!
* `aprsd-twitter-plugin <https://github.com/hemna/aprsd-twitter-plugin>`_ - make tweets from your Ham Radio!
* `aprsd-timeopencage-plugin <https://github.com/hemna/aprsd-timeopencage-plugin>`_ - Get local time for a callsign
* `aprsd-stock-plugin <https://github.com/hemna/aprsd-stock-plugin>`_ - get stock quotes from your Ham radio
List of existing extensions - Add new capabilities to APRSD
-----------------------------------------------------------
* `aprsd-admin-extension <https://github.com/hemna/aprsd-admin-extension>`_ - Web Administration page for APRSD
* `aprsd-webchat-extension <https://github.com/hemna/aprsd-webchat-extension>`_ - Web page for APRS Messaging
* `aprsd-rich-cli-extension <https://github.com/hemna/aprsd-rich-cli-extension>`_ - Textual rich CLI versions of aprsd commands
* `aprsd-irc-extension <https://github.com/hemna/aprsd-irc-extension>`_ - an IRC like server command for APRS
APRSD Overview Diagram
----------------------
.. image:: https://raw.githubusercontent.com/craigerl/aprsd/master/docs/_static/aprsd_overview.svg?sanitize=true
:target: https://raw.githubusercontent.com/craigerl/aprsd/master/docs/_static/aprsd_overview.svg?sanitize=true
:alt: APRSD Logo
Typical use case
----------------
APRSD\'s typical use case is that of providing an APRS wide service to
all HAM radio operators. For example the callsign \'REPEAT\' on the APRS
network is actually an instance of APRSD that can provide a list of HAM
repeaters in the area of the callsign that sent the message.
Ham radio operator using an APRS enabled HAM radio sends a message to
check the weather. An APRS message is sent, and then picked up by APRSD.
The APRS packet is decoded, and the message is sent through the list of
plugins for processing. For example, the WeatherPlugin picks up the
message, fetches the weather for the area around the user who sent the
request, and then responds with the weather conditions in that area.
Also includes a watch list of HAM callsigns to look out for. The watch
list can notify you when a HAM callsign in the list is seen and now
available to message on the APRS network.
Installation
------------
**Install uv (recommended):**
``uv`` is a fast Python package installer and resolver. To install ``uv``\ , visit `https://docs.astral.sh/uv/getting-started/installation/ <https://docs.astral.sh/uv/getting-started/installation/>`_
To install ``aprsd``\ , use uv:
``uv pip install aprsd``
Or with the traditional pip:
``pip install aprsd``
Example usage
-------------
``aprsd -h``
Help
----
:
.. code-block::
└─> aprsd -h
Usage: aprsd [OPTIONS] COMMAND [ARGS]...
Options:
--version Show the version and exit.
-h, --help Show this message and exit.
Commands:
check-version Check this version against the latest in pypi.org.
completion Show the shell completion code
dev Development type subcommands
fetch-stats Fetch stats from a APRSD admin web interface.
healthcheck Check the health of the running aprsd server.
list-extensions List the built in plugins available to APRSD.
list-plugins List the built in plugins available to APRSD.
listen Listen to packets on the APRS-IS Network based on FILTER.
sample-config Generate a sample Config file from aprsd and all...
send-message Send a message to a callsign via APRS_IS.
server Start the aprsd server gateway process.
version Show the APRSD version.
Commands
--------
Configuration
^^^^^^^^^^^^^
This command outputs a sample config yml formatted block that you can
edit and use to pass in to ``aprsd`` with ``-c``. By default aprsd looks in
``~/.config/aprsd/aprsd.yml``
``aprsd sample-config``
.. code-block::
└─> aprsd sample-config
...
server
^^^^^^
This is the main server command that will listen to APRS-IS servers and
look for incomming commands to the callsign configured in the config
file
.. code-block::
└─[$] > aprsd server --help
Usage: aprsd server [OPTIONS]
Start the aprsd server gateway process.
Options:
--loglevel [CRITICAL|ERROR|WARNING|INFO|DEBUG]
The log level to use for aprsd.log
[default: INFO]
-c, --config TEXT The aprsd config file to use for options.
[default:
/Users/i530566/.config/aprsd/aprsd.yml]
--quiet Don't log to stdout
-f, --flush Flush out all old aged messages on disk.
[default: False]
-h, --help Show this message and exit.
└─> aprsd server
Registering LogMonitorThread
2025-01-06 16:27:12.398 | MainThread | INFO | APRSD is up to date | aprsd.cmds.server:server:82
2025-01-06 16:27:12.398 | MainThread | INFO | APRSD Started version: 4.2.4 | aprsd.cmds.server:server:83
2025-01-06 16:27:12.398 | MainThread | INFO | Creating client connection | aprsd.cmds.server:server:101
2025-01-06 16:27:12.398 | MainThread | INFO | Creating aprslib client(noam.aprs2.net:14580) and logging in WB4BOR-1. | aprsd.client.aprsis:setup_connection:136
2025-01-06 16:27:12.398 | MainThread | INFO | Attempting connection to noam.aprs2.net:14580 | aprslib.inet:_connect:226
2025-01-06 16:27:12.473 | MainThread | INFO | Connected to ('44.135.208.225', 14580) | aprslib.inet:_connect:233
2025-01-06 16:27:12.617 | MainThread | INFO | Login successful | aprsd.client.drivers.aprsis:_send_login:154
2025-01-06 16:27:12.618 | MainThread | INFO | Connected to T2BC | aprsd.client.drivers.aprsis:_send_login:156
2025-01-06 16:27:12.618 | MainThread | INFO | <aprsd.client.aprsis.APRSISClient object at 0x103a36480> | aprsd.cmds.server:server:103
2025-01-06 16:27:12.618 | MainThread | INFO | Loading Plugin Manager and registering plugins | aprsd.cmds.server:server:117
2025-01-06 16:27:12.619 | MainThread | INFO | Loading APRSD Plugins | aprsd.plugin:setup_plugins:492
Current list plugins
^^^^^^^^^^^^^^^^^^^^
.. code-block::
└─> aprsd list-plugins
🐍 APRSD Built-in Plugins 🐍
┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Plugin Name ┃ Info ┃ Type ┃ Plugin Path ┃
┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ AVWXWeatherPlugin │ AVWX weather of GPS Beacon location │ RegexCommand │ aprsd.plugins.weather.AVWXWeatherPlugin │
│ FortunePlugin │ Give me a fortune │ RegexCommand │ aprsd.plugins.fortune.FortunePlugin │
│ NotifySeenPlugin │ Notify me when a CALLSIGN is recently seen on APRS-IS │ WatchList │ aprsd.plugins.notify.NotifySeenPlugin │
│ OWMWeatherPlugin │ OpenWeatherMap weather of GPS Beacon location │ RegexCommand │ aprsd.plugins.weather.OWMWeatherPlugin │
│ PingPlugin │ reply with a Pong! │ RegexCommand │ aprsd.plugins.ping.PingPlugin │
│ TimeOWMPlugin │ Current time of GPS beacon's timezone. Uses OpenWeatherMap │ RegexCommand │ aprsd.plugins.time.TimeOWMPlugin │
│ TimePlugin │ What is the current local time. │ RegexCommand │ aprsd.plugins.time.TimePlugin │
│ USMetarPlugin │ USA only METAR of GPS Beacon location │ RegexCommand │ aprsd.plugins.weather.USMetarPlugin │
│ USWeatherPlugin │ Provide USA only weather of GPS Beacon location │ RegexCommand │ aprsd.plugins.weather.USWeatherPlugin │
│ VersionPlugin │ What is the APRSD Version │ RegexCommand │ aprsd.plugins.version.VersionPlugin │
└───────────────────┴────────────────────────────────────────────────────────────┴──────────────┴─────────────────────────────────────────┘
Pypi.org APRSD Installable Plugin Packages
Install any of the following plugins with
'uv pip install <Plugin Package Name>'
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Plugin Package Name ┃ Description ┃ Version ┃ Released ┃ Installed? ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ 📂 aprsd-assistant-plugin │ APRSd plugin for hosting the APRS Assistant chatbot │ 0.0.3 │ 2024-10-20T02:59:39 │ No │
│ │ (aprs-assistant) │ │ │ │
│ 📂 aprsd-borat-plugin │ Borat quotes for aprsd plugin │ 0.1.1.dev1 │ 2024-01-19T16:04:38 │ No │
│ 📂 aprsd-locationdata-plugin │ Fetch location information from a callsign │ 0.3.0 │ 2024-02-06T17:20:43 │ No │
│ 📂 aprsd-mqtt-plugin │ APRSD MQTT Plugin sends APRS packets to mqtt queue │ 0.2.0 │ 2023-04-17T16:01:50 │ No │
│ 📂 aprsd-repeat-plugins │ APRSD Plugins for the REPEAT service │ 1.2.0 │ 2023-01-10T17:15:36 │ No │
│ 📂 aprsd-sentry-plugin │ Ham radio APRSD plugin that does.... │ 0.1.2 │ 2022-12-02T19:07:33 │ No │
│ 📂 aprsd-slack-plugin │ Amateur radio APRS daemon which listens for messages and │ 1.2.0 │ 2023-01-10T19:21:33 │ No │
│ │ responds │ │ │ │
│ 📂 aprsd-stock-plugin │ Ham Radio APRSD Plugin for fetching stock quotes │ 0.1.3 │ 2022-12-02T18:56:19 │ Yes │
│ 📂 aprsd-telegram-plugin │ Ham Radio APRS APRSD plugin for Telegram IM service │ 0.1.3 │ 2022-12-02T19:07:15 │ No │
│ 📂 aprsd-timeopencage-plugin │ APRSD plugin for fetching time based on GPS location │ 0.2.0 │ 2023-01-10T17:07:11 │ No │
│ 📂 aprsd-twitter-plugin │ Python APRSD plugin to send tweets │ 0.5.0 │ 2023-01-10T16:51:47 │ No │
│ 📂 aprsd-weewx-plugin │ HAM Radio APRSD that reports weather from a weewx weather │ 0.3.2 │ 2023-04-20T20:16:19 │ No │
│ │ station. │ │ │ │
│ 📂 aprsd-wxnow-plugin │ APRSD Plugin for getting the closest wx reports to last │ 0.2.0 │ 2023-10-08T01:27:29 │ Yes │
│ │ beacon │ │ │ │
└──────────────────────────────┴──────────────────────────────────────────────────────────────┴────────────┴─────────────────────┴────────────┘
🐍 APRSD Installed 3rd party Plugins 🐍
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Package Name ┃ Plugin Name ┃ Version ┃ Type ┃ Plugin Path ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ aprsd-stock-plugin │ YahooStockQuote │ 0.1.3 │ RegexCommand │ aprsd_stock_plugin.stock.YahooStockQuote │
│ aprsd-wxnow-plugin │ WXNowPlugin │ 0.2.0 │ RegexCommand │ aprsd_wxnow_plugin.conf.opts.WXNowPlugin │
└────────────────────┴─────────────────┴─────────┴──────────────┴──────────────────────────────────────────┘
Current list extensions
^^^^^^^^^^^^^^^^^^^^^^^
.. code-block::
└─> aprsd list-extensions
Pypi.org APRSD Installable Extension Packages
Install any of the following extensions by running
'uv pip install <Plugin Package Name>'
┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Extension Package Name ┃ Description ┃ Version ┃ Released ┃ Installed? ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ 📂 aprsd-admin-extension │ Administration extension for the Ham radio APRSD Server │ 1.0.1 │ 2025-01-06T21:57:24 │ Yes │
│ 📂 aprsd-irc-extension │ An Extension to Ham radio APRSD Daemon to act like an irc server │ 0.0.5 │ 2024-04-09T11:28:47 │ No │
│ │ for APRS │ │ │ │
│ 📂 aprsd-rich-cli-extens │ APRSD Extension to create textual rich CLI versions of aprsd │ 0.1.1 │ 2024-12-01T00:00:00 │ No │
│ ion │ commands │ │ │ │
│ 📂 aprsd-webchat-extens │ Web page for APRS Messaging │ 1.2.3 │ 2024-10-01T00:00:00 │ No │
│ ion │ │ │ │ │
└──────────────────────────┴─────────────────────────────────────────────────────────────────────┴─────────┴─────────────────────┴────────────┘
send-message
------------
This command is typically used for development to send another aprsd
instance test messages
.. code-block::
└─[$] > aprsd send-message -h
Usage: aprsd send-message [OPTIONS] TOCALLSIGN COMMAND...
Send a message to a callsign via APRS_IS.
Options:
--loglevel [CRITICAL|ERROR|WARNING|INFO|DEBUG]
The log level to use for aprsd.log
[default: INFO]
-c, --config TEXT The aprsd config file to use for options.
[default:
/Users/i530566/.config/aprsd/aprsd.yml]
--quiet Don't log to stdout
--aprs-login TEXT What callsign to send the message from.
[env var: APRS_LOGIN]
--aprs-password TEXT the APRS-IS password for APRS_LOGIN [env
var: APRS_PASSWORD]
-n, --no-ack Don't wait for an ack, just sent it to APRS-
IS and bail. [default: False]
-w, --wait-response Wait for a response to the message?
[default: False]
--raw TEXT Send a raw message. Implies --no-ack
-h, --help Show this message and exit.
Development
-----------
* ``git clone git@github.com:craigerl/aprsd.git``
* ``cd aprsd``
* ``make``
Workflow
^^^^^^^^
While working aprsd, The workflow is as follows:
*
Checkout a new branch to work on by running
``git checkout -b mybranch``
*
Make your changes to the code
*
Run Tox with the following options:
* ``tox -epep8``
* ``tox -efmt``
* ``tox -p``
*
Commit your changes. This will run the pre-commit hooks which does
checks too
``git commit``
*
Once you are done with all of your commits, then push up the branch
to github with:
``git push -u origin mybranch``
*
Create a pull request from your branch so github tests can run and
we can do a code review.
Release
^^^^^^^
To do release to pypi:
*
Tag release with:
``git tag -v1.XX -m "New release"``
*
Push release tag:
``git push origin master --tags``
*
Do a test build and verify build is valid by running:
``make build``
*
Once twine is happy, upload release to pypi:
``make upload``
Building your own APRSD plugins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For information on building your own APRSD plugins, see the `Plugin Development documentation <https://aprsd.readthedocs.io/en/latest/plugin.html>`_.
Docker Container
----------------
For information on building Docker containers (official and development builds), see the `Docker Container documentation <https://aprsd.readthedocs.io/en/latest/readme.html#docker-container>`_.
Running the container
---------------------
There is a ``docker-compose.yml`` file in the ``docker/`` directory that can
be used to run your container. To provide the container an ``aprsd.conf``
configuration file, change your ``docker-compose.yml`` as shown below:
.. code-block::
volumes:
- $HOME/.config/aprsd:/config
To install plugins at container start time, pass in a list of
comma-separated list of plugins on PyPI using the ``APRSD_PLUGINS``
environment variable in the ``docker-compose.yml`` file. Note that version
constraints may also be provided. For example:
.. code-block::
environment:
- APRSD_PLUGINS=aprsd-slack-plugin>=1.0.2,aprsd-twitter-plugin
Activity
--------
.. image:: https://repobeats.axiom.co/api/embed/8b96657861770a15f0b851a5eebafb34d0e0b3d3.svg
:target: https://repobeats.axiom.co/api/embed/8b96657861770a15f0b851a5eebafb34d0e0b3d3.svg
:alt: Alt
Star History
------------
.. image:: https://api.star-history.com/svg?repos=craigerl/aprsd&type=Date
:target: https://star-history.com/#craigerl/aprsd&Date
:alt: Star History Chart
+164
View File
@@ -0,0 +1,164 @@
APRSD server
============
Running the APRSD server
------------------------
Once APRSD is :doc:`installed <install>` and :doc:`configured <configure>` the server can be started by
running.
.. code-block:: shell
aprsd server
The server will start several threads to deal handle incoming messages, outgoing
messages, checking and sending email.
How APRSD processes messages
-----------------------------
When APRSD receives an APRS message packet, it follows a structured processing flow:
1. **Packet Reception**: The ``RX_PKT`` thread receives packets from the APRS-IS network
and places them into a packet queue.
2. **Packet Processing**: The ``ProcessPKT`` thread processes packets from the queue.
It determines if the packet is:
- An ACK packet destined for APRSD (handled separately)
- A Reject packet (handled separately)
- A MessagePacket destined for APRSD's callsign
- Other packet types (beacons, weather, etc.)
3. **Message Routing**: When a MessagePacket is received that is addressed to APRSD's
callsign, the packet is sent to the ``process_our_message_packet`` method.
4. **Plugin Processing**: The message packet is passed to the PluginManager, which:
- Iterates through all registered plugins in the order they were configured
- For each plugin, checks if the message matches the plugin's regex pattern
- If a match is found, calls the plugin's ``process()`` method with the packet
- Collects any reply messages returned by the plugins
5. **Response Handling**: Any reply messages returned by plugins are sent back to the
original sender via the APRS-IS network. Plugins can return:
- A string message (converted to a MessagePacket)
- A Packet object (sent as-is)
- A list of messages (multiple replies)
- ``NULL_MESSAGE`` (indicates the plugin processed the message but has no reply)
6. **ACK Handling**: After processing, if the message had a message ID, APRSD
automatically sends an ACK packet to acknowledge receipt.
This plugin-based architecture allows APRSD to be extended with custom functionality
without modifying the core codebase. Each plugin can independently process messages
and respond as needed. See the :doc:`plugin <plugin>` documentation for information
on creating your own plugins.
.. code-block:: shell
aprsd server --loglevel DEBUG
2025-12-10 14:30:05.146 | MainThread | INFO | Python version: 3.10.14 (main, Aug 14 2024, 05:14:46) [Clang 18.1.8 ] | aprsd.cmds.server:server:43
2025-12-10 14:30:05.147 | MainThread | INFO | APRSD Started version: 4.2.5.dev8+g9c0695794 | aprsd.cmds.server:server:44
2025-12-10 14:30:05.147 | MainThread | INFO | APRSD is up to date | aprsd.cmds.server:server:49
2025-12-10 14:30:05.167 | MainThread | INFO | Creating aprslib client(155.138.131.1:14580) and logging in WB4BOR-1. try #1 | aprsd.client.drivers.aprsis:setup_connection:103
2025-12-10 14:30:05.167 | MainThread | INFO | Attempting connection to 155.138.131.1:14580 | aprsd.client.drivers.lib.aprslib:_connect:69
2025-12-10 14:30:05.193 | MainThread | INFO | Connected to ('155.138.131.1', 14580) | aprsd.client.drivers.lib.aprslib:_connect:78
2025-12-10 14:30:05.232 | MainThread | DEBUG | Banner: # aprsc 2.1.19-g730c5c0 | aprsd.client.drivers.lib.aprslib:_connect:96
2025-12-10 14:30:05.232 | MainThread | DEBUG | Sending login information | aprsd.client.drivers.lib.aprslib:_send_login:180
2025-12-10 14:30:05.256 | MainThread | DEBUG | Server: '# logresp WB4BOR-1 verified, server T2CAEAST' | aprsd.client.drivers.lib.aprslib:_send_login:190
2025-12-10 14:30:05.256 | MainThread | INFO | Login successful | aprsd.client.drivers.lib.aprslib:_send_login:212
2025-12-10 14:30:05.256 | MainThread | INFO | Connected to T2CAEAST | aprsd.client.drivers.lib.aprslib:_send_login:214
2025-12-10 14:30:05.256 | MainThread | INFO | Creating client connection | aprsd.cmds.server:server:62
2025-12-10 14:30:05.256 | MainThread | INFO | <aprsd.client.client.APRSDClient object at 0x1096ac460> | aprsd.cmds.server:server:64
2025-12-10 14:30:05.256 | MainThread | INFO | Loading Plugin Manager and registering plugins | aprsd.cmds.server:server:78
2025-12-10 14:30:05.257 | MainThread | INFO | Loading APRSD Plugins | aprsd.plugin:setup_plugins:493
2025-12-10 14:30:05.257 | MainThread | INFO | Registering Regex plugin 'aprsd.plugins.weather.AVWXWeatherPlugin'(4.2.5.dev8+g9c0695794) -- ^([m]|[m]|[m]\s|metar) | aprsd.plugin:_load_plugin:452
2025-12-10 14:30:05.257 | MainThread | INFO | Completed Plugin Loading. | aprsd.plugin:setup_plugins:513
2025-12-10 14:30:05.257 | MainThread | DEBUG | ******************************************************************************** | oslo_config.cfg:log_opt_values:2804
2025-12-10 14:30:05.257 | MainThread | DEBUG | Configuration options gathered from: | oslo_config.cfg:log_opt_values:2805
2025-12-10 14:30:05.257 | MainThread | DEBUG | command line args: [] | oslo_config.cfg:log_opt_values:2806
2025-12-10 14:30:05.257 | MainThread | DEBUG | config files: ['/Users/I530566/.config/aprsd/aprsd.conf'] | oslo_config.cfg:log_opt_values:2807
2025-12-10 14:30:05.257 | MainThread | DEBUG | ================================================================================ | oslo_config.cfg:log_opt_values:2809
2025-12-10 14:30:05.257 | MainThread | DEBUG | ack_rate_limit_period = 1 | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | beacon_interval = 60 | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | beacon_symbol = / | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | callsign = WB4BOR-1 | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | config_dir = [] | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | config_file = ['/Users/I530566/.config/aprsd/aprsd.conf'] | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | config_source = [] | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | default_ack_send_count = 3 | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | default_packet_send_count = 3 | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | enable_beacon = True | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | enable_packet_logging = True | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | enable_save = True | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | enable_seen_list = True | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | enable_sending_ack_packets = True | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | enabled_plugins = ['aprsd.plugins.weather.AVWXWeatherPlugin'] | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | is_digipi = False | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | latitude = 37.3443862 | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | load_help_plugin = True | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | log_packet_format = compact | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | longitude = -78.850000 | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | msg_rate_limit_period = 2 | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.258 | MainThread | DEBUG | packet_dupe_timeout = 300 | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.259 | MainThread | DEBUG | packet_list_maxlen = 5000 | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.259 | MainThread | DEBUG | packet_list_stats_maxlen = 20 | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.259 | MainThread | DEBUG | save_location = /Users/I530566/.config/aprsd/ | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.259 | MainThread | DEBUG | shell_completion = None | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.259 | MainThread | DEBUG | trace_enabled = False | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.259 | MainThread | DEBUG | units = imperial | oslo_config.cfg:log_opt_values:2817
2025-12-10 14:30:05.259 | MainThread | DEBUG | logging.enable_color = True | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | logging.enable_console_stdout = True | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | logging.log_level = INFO | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | logging.logfile = /tmp/aprsd.log | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | logging.logformat = <green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <yellow>{thread.name: <18}</yellow> | <level>{level: <8}</level> | <level>{message}</level> | <cyan>{name}</cyan>:<cyan>{function:}</cyan>:<magenta>{line:}</magenta> | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | watch_list.alert_callsign = WB4BOR-1 | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | watch_list.alert_time_seconds = 3600 | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | watch_list.callsigns = ['APPOMX', 'REPEAT', 'KM6LYW', 'WB4BOR', 'M0IAX', 'VE3SCN', 'WA4RTS-5', 'KC9BUH', 'W4SOU-7', 'KD9KAF-7', 'NN4RB-9', 'KN4MLN-9', 'KK4WZS-8', 'K2VIZ-1', 'KE3XE-9', 'WB2UTI-9', 'KO4ARL-7', 'LMS6CAE42', 'WDJ6895', 'PHISVR', 'F1BIS-9', 'M7APR-9', 'Y09INA-5', 'M0PLT-7', 'M0GLJ-14', 'MW6JUY-10', 'M0XZS', 'M0HPP-8', 'ON2BBW-8'] | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | watch_list.enabled = True | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | watch_list.packet_keep_count = 10 | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | aprs_registry.description = None | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | aprs_registry.enabled = False | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | aprs_registry.frequency_seconds = 3600 | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | aprs_registry.registry_url = https://aprs.hemna.com/api/v1/registry | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | aprs_registry.service_website = None | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.259 | MainThread | DEBUG | aprs_network.enabled = True | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | aprs_network.host = 155.138.131.1 | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | aprs_network.login = WB4BOR-1 | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | aprs_network.password = **** | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | aprs_network.port = 14580 | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | kiss_serial.baudrate = 9600 | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | kiss_serial.device = None | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | kiss_serial.enabled = False | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | kiss_serial.path = ['WIDE1-1', 'WIDE2-1'] | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | kiss_tcp.enabled = False | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | kiss_tcp.host = None | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | kiss_tcp.path = ['WIDE1-1', 'WIDE2-1'] | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | kiss_tcp.port = 8001 | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | fake_client.enabled = False | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | aprs_fi.apiKey = 152327.lds79D1bgvlbd | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | owm_weather_plugin.apiKey = e26b403324563f24a290fa1d06459bae | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | avwx_plugin.apiKey = Foo | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | avwx_plugin.base_url = https://avwx.rest | oslo_config.cfg:log_opt_values:2824
2025-12-10 14:30:05.260 | MainThread | DEBUG | ******************************************************************************** | oslo_config.cfg:log_opt_values:2828
2025-12-10 14:30:05.260 | MainThread | INFO | Message Plugins enabled and running: | aprsd.cmds.server:server:86
2025-12-10 14:30:05.260 | MainThread | INFO | <aprsd.plugins.weather.AVWXWeatherPlugin object at 0x109a74c40> | aprsd.cmds.server:server:88
2025-12-10 14:30:05.260 | MainThread | INFO | <aprsd.plugin.HelpPlugin object at 0x109a74ac0> | aprsd.cmds.server:server:88
2025-12-10 14:30:05.260 | MainThread | INFO | Watchlist Plugins enabled and running: | aprsd.cmds.server:server:89
2025-12-10 14:30:05.260 | MainThread | DEBUG | Loading saved packet tracking data. | aprsd.cmds.server:server:103
2025-12-10 14:30:05.261 | MainThread | DEBUG | PacketList::No save file found. | aprsd.utils.objectstore:load:113
2025-12-10 14:30:05.261 | MainThread | DEBUG | SeenList::No save file found. | aprsd.utils.objectstore:load:113
2025-12-10 14:30:05.261 | MainThread | DEBUG | PacketTrack::No save file found. | aprsd.utils.objectstore:load:113
2025-12-10 14:30:05.262 | MainThread | DEBUG | WatchList::Loaded 29 entries from disk. | aprsd.utils.objectstore:load:103
2025-12-10 14:30:05.262 | MainThread | INFO | Beacon Enabled. Starting Beacon thread. | aprsd.cmds.server:server:122
2025-12-10 14:30:05.262 | MainThread | INFO | Beacon thread is running and will send beacons every 60 seconds. | aprsd.threads.tx:__init__:253
2025-12-10 14:30:05.263 | KeepAlive | DEBUG | Starting | aprsd.threads.aprsd:run:64
2025-12-10 14:30:05.263 | StatsStore | DEBUG | Starting | aprsd.threads.aprsd:run:64
2025-12-10 14:30:05.263 | RX_PKT | DEBUG | Starting | aprsd.threads.aprsd:run:64
2025-12-10 14:30:05.264 | ProcessPKT | DEBUG | Starting | aprsd.threads.aprsd:run:64
2025-12-10 14:30:05.264 | BeaconSendThread | DEBUG | Starting | aprsd.threads.aprsd:run:64
.. include:: links.rst