-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for APRS Service Registry (#57)
* feat: add support for APRS Service Registry This adds support for adding the bot to the APRS Service registry using the standard setup by WB4BOR for his HEMNA registry https://aprs.hemna.com/ By default, registry is off. This PR also adds documentation of all of the config options, including the ones related to enabling registry pings. * ci: ruff format
- Loading branch information
1 parent
d5b57eb
commit 245b2f7
Showing
19 changed files
with
498 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# err-aprs-backend config options | ||
|
||
These options can be set in your errbot config.py to configure the APRS backend. | ||
|
||
* APRS_FROM_CALLSIGN - default is your bot identity callsign, but you can set to reply as a different callsign | ||
* APRS_LISTENED_CALLSIGNS - default (), set of callsigns to listen to | ||
* APRS_HELP_TEXT - default "APRSBot,Errbot & err-aprs-backend", set this to your text. Probably a good idea to set it to website for complex help text due to message character limits | ||
* APRS_MAX_DROPPED_PACKETS - default "25", how many packets we can drop before the bot backend will restart | ||
* APRS_MAX_CACHED_PACKETS - default "2048", how many packets to hold in the cache to dedupe. | ||
* APRS_MAX_AGE_CACHED_PACETS_SECONDS - default "3600", how long to hold onto a package in the cache for deduping | ||
* APRS_MESSAGE_MAX_RETRIES - default "7", how many times to retry sending a message if the bot does do not get an ack or a rej | ||
* APRS_MESSAGE_RETRY_WAIT - default "90", how many seconds to wait between retrying message sending | ||
* APRS_STRIP_NEWLINES - default "true", strip newlines out of plugin responses, probably best to leave it as true | ||
* APRS_LANGUAGE_FILTER - default "true", attempts to strip any profanity out of a message before sending it so the FCC doesn't get mad. Not a smart filter, very brute force. You are still responsible for what you transmit! | ||
* APRS_LANGUAGE_FILTER_EXTRA_WORDS - default [], list of extra words to drop as profanity. | ||
* APRS_REGISTRY_ENABLED - default "false", if true, will enable reporting to the APRS Service Registry https://aprs.hemna.com/ | ||
* APRS_REGISTRY_URL - default "https://aprs.hemna.com/api/v1/registry", the APRS registry to report your service | ||
* APRS_REGISTRY_FREQUENCY_SECONDS - default "3600", how often in seconds to report your service to the APRS registry | ||
* APRS_REGISTRY_DESCRIPTION - default "err-aprs-backend powered bot", description for your bot in the Service Regsitry | ||
* APRS_REGISTRY_WEBSTIRE - default "", website for your service on the APRS registry | ||
* APRS_REGISTRY_SOFTWARE - default "err-aprs-backend {version} errbot {errbot version}", software string for APRS service registry |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
from .aprs import APRSBackend | ||
from .version import __version__ | ||
|
||
__all__ = ["APRSBackend"] | ||
__all__ = ["APRSBackend", "__version__"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
from .aprsis import APRSISClient | ||
from .kiss import KISSClient | ||
from .aprs_registry import APRSRegistryClient, RegistryAppConfig | ||
|
||
__all__ = ["APRSISClient", "KISSClient"] | ||
__all__ = ["APRSISClient", "KISSClient", "APRSRegistryClient", "RegistryAppConfig"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
from dataclasses import dataclass | ||
import httpx | ||
from functools import cached_property | ||
import asyncio | ||
|
||
|
||
@dataclass | ||
class RegistryAppConfig: | ||
description: str | ||
listening_callsigns: list[str] | ||
website: str = "" | ||
software: str = "" | ||
|
||
@cached_property | ||
def post_jsons(self) -> list[dict]: | ||
return [ | ||
{ | ||
"callsign": str(this_call), | ||
"description": self.description, | ||
"service_website": self.website, | ||
"software": self.software, | ||
} | ||
for this_call in self.listening_callsigns | ||
] | ||
|
||
|
||
class APRSRegistryClient: | ||
def __init__(self, registry_url: str, app_config: RegistryAppConfig, log, frequency_seconds: int = 3600) -> None: | ||
self.registry_url = registry_url | ||
self.log = log | ||
self.frequency_seconds = frequency_seconds | ||
self.app_config = app_config | ||
|
||
async def __call__(self) -> None: | ||
"""Posts to the aprs registry url for each listening callsign for the bot | ||
Run as an asyncio task | ||
""" | ||
self.log.debug("Staring APRS Registry Client") | ||
try: | ||
while True: | ||
async with httpx.AsyncClient() as client: | ||
for post_json in self.app_config.post_jsons: | ||
self.log.debug("Posting %s to %s", post_json, self.registry_url) | ||
try: | ||
response = await client.post(self.registry_url, json=post_json) | ||
self.log.debug(response) | ||
response.raise_for_status() | ||
except httpx.RequestError as exc: | ||
self.log.error( | ||
"Request Error while posting %s to %s. Error: %s, response: %s", | ||
post_json, | ||
self.registry_url, | ||
exc, | ||
response, | ||
) | ||
except httpx.HTTPStatusError as exc: | ||
self.log.error( | ||
"Error while posting %s to %s. Error: %s, response: %s", | ||
post_json, | ||
self.registry_url, | ||
exc, | ||
response, | ||
) | ||
# instead of sleeping in one big chunk, sleep in smaller chunks for easier cacnellation | ||
for i in range(self.frequency_seconds * 10): | ||
await asyncio.sleep(0.1) | ||
except asyncio.CancelledError: | ||
self.log.info("APRS client cancelled, stopping") | ||
return |
Oops, something went wrong.