diff --git a/README.rst b/README.rst index 5a442a9..6cadb2b 100644 --- a/README.rst +++ b/README.rst @@ -4,6 +4,7 @@ Garmin inReach to Cursor on Target Gateway .. image:: https://raw.githubusercontent.com/ampledata/inrcot/main/docs/az-ccso-sar.jpg :alt: Screenshot of INRCOT being used on a Search & Rescue mission in Arizona. :target: https://raw.githubusercontent.com/ampledata/inrcot/main/docs/az-ccso-sar.jpg + * Pictured: Screenshot of INRCOT being used on a Search & Rescue mission in Arizona. The inReach to Cursor on Target Gateway (INRCOT) transforms Garmin inReach @@ -34,7 +35,7 @@ Use Cases ========= There are numerous applications for satellite based position location information, -including:: +including: 1. Blue Force Tracking 2. Search & Rescue (SAR) @@ -115,11 +116,13 @@ Configuration parameters can be specified either via environment variables or in a INI-stile configuration file. You must create a configuration file, see `example-config.ini` in the source respository. -Parameters:: +Parameters: * **DEFAULT_POLL_INTERVAL**: How many seconds between checking for new messages at the Spot API? Default: 120 (seconds). * **DEFAULT_COT_STALE**: How many seconds until CoT is stale? Default: 600 (seconds) -* **DEFAULT_COT_TYPE**: "a-n-G-E-V-C" # CoT Event Type / 2525 type / SIDC-like. Default: neutral ground +* **DEFAULT_COT_TYPE**: CoT Event Type / 2525 type / SIDC-like. Default: neutral ground + +TLS & other configuration parameters available via `PyTAK `_. Example Configurations @@ -149,7 +152,7 @@ Multiple feeds can be added by creating multiple `inrcot_feed` sections:: Individual feeds CoT output can be customized as well:: [inrcot] - COT_URL = tcp:takserver.example.com:8088 + COT_URL = tcp://takserver.example.com:8088 POLL_INTERVAL = 120 [inrcot_feed_zzz] @@ -162,7 +165,7 @@ Individual feeds CoT output can be customized as well:: Protected feeds are also supported:: [inrcot] - COT_URL = tcp:takserver.example.com:8088 + COT_URL = tcp://takserver.example.com:8088 POLL_INTERVAL = 120 [inrcot_feed_ppp] diff --git a/inrcot/classes.py b/inrcot/classes.py index b14fde3..66298ba 100644 --- a/inrcot/classes.py +++ b/inrcot/classes.py @@ -47,19 +47,20 @@ def _create_feeds(self, config: dict = None) -> None: feed_conf = { "feed_url": config[feed].get("FEED_URL"), "cot_stale": config[feed].get( - "COT_STALE", inrcot.DEFAULT_COT_STALE), - "cot_type": config[feed].get( - "COT_TYPE", inrcot.DEFAULT_COT_TYPE), + "COT_STALE", inrcot.DEFAULT_COT_STALE + ), + "cot_type": config[feed].get("COT_TYPE", inrcot.DEFAULT_COT_TYPE), "cot_icon": config[feed].get("COT_ICON"), "cot_name": config[feed].get("COT_NAME"), } # Support "private" MapShare feeds: - if config[feed].get("FEED_PASSWORD") and \ - config[feed].get("FEED_USERNAME"): + if config[feed].get("FEED_PASSWORD") and config[feed].get( + "FEED_USERNAME" + ): feed_conf["feed_auth"] = aiohttp.BasicAuth( config[feed].get("FEED_USERNAME"), - config[feed].get("FEED_PASSWORD") + config[feed].get("FEED_PASSWORD"), ) self.inreach_feeds.append(feed_conf) @@ -80,19 +81,15 @@ async def get_inreach_feeds(self): async with aiohttp.ClientSession() as session: try: response = await session.request( - method="GET", - auth=feed_auth, - url=feed_conf.get("feed_url") + method="GET", auth=feed_auth, url=feed_conf.get("feed_url") ) except Exception as exc: # NOQA pylint: disable=broad-except - self._logger.error( - "Exception raised while polling inReach API.") + self._logger.error("Exception raised while polling inReach API.") self._logger.exception(exc) return if response.status == 200: - await self.handle_data(await response.content.read(), - feed_conf) + await self.handle_data(await response.content.read(), feed_conf) else: self._logger.error("No valid response from inReach API.") @@ -101,7 +98,8 @@ async def run(self) -> None: self._logger.info("Run: %s", self.__class__) poll_interval: str = self.config.get( - "POLL_INTERVAL", inrcot.DEFAULT_POLL_INTERVAL) + "POLL_INTERVAL", inrcot.DEFAULT_POLL_INTERVAL + ) while 1: await self.get_inreach_feeds() diff --git a/inrcot/commands.py b/inrcot/commands.py index 4e53152..ce0e489 100644 --- a/inrcot/commands.py +++ b/inrcot/commands.py @@ -42,7 +42,9 @@ from asyncio import get_event_loop as get_running_loop -async def main(app_name: str, config: SectionProxy, original_config: ConfigParser) -> None: +async def main( + app_name: str, config: SectionProxy, original_config: ConfigParser +) -> None: """ Abstract implementation of an async main function. @@ -104,6 +106,7 @@ def cli(app_name: str = "inrcot") -> None: debug = config.getboolean("DEBUG") if debug: import pprint # pylint: disable=import-outside-toplevel + # FIXME: This doesn't work with weird bash escape stuff. print("Showing Config: %s", config_file) print("=" * 10) diff --git a/inrcot/functions.py b/inrcot/functions.py index 5803cdf..2f7fe3f 100644 --- a/inrcot/functions.py +++ b/inrcot/functions.py @@ -58,7 +58,7 @@ def create_tasks( def split_feed(content: str) -> list: """Splits an inReach MapShare KML feed by 'Folder'""" tree = ET.parse(io.BytesIO(content)) - document = tree.find('{http://www.opengis.net/kml/2.2}Document') + document = tree.find("{http://www.opengis.net/kml/2.2}Document") folder = document.findall("{http://www.opengis.net/kml/2.2}Folder") return folder @@ -71,8 +71,7 @@ def inreach_to_cot_xml(feed: str, feed_conf: dict = None) -> Union[ET.Element, N placemarks = feed.find("{http://www.opengis.net/kml/2.2}Placemark") _point = placemarks.find("{http://www.opengis.net/kml/2.2}Point") - coordinates = _point.find( - "{http://www.opengis.net/kml/2.2}coordinates").text + coordinates = _point.find("{http://www.opengis.net/kml/2.2}coordinates").text _name = placemarks.find("{http://www.opengis.net/kml/2.2}name").text ts = placemarks.find("{http://www.opengis.net/kml/2.2}TimeStamp") @@ -87,9 +86,10 @@ def inreach_to_cot_xml(feed: str, feed_conf: dict = None) -> Union[ET.Element, N # We want to use localtime + stale instead of lastUpdate time + stale # This means a device could go offline and we might not know it? _cot_stale = feed_conf.get("cot_stale", inrcot.DEFAULT_COT_STALE) - cot_stale = (datetime.datetime.now(datetime.timezone.utc) + - datetime.timedelta( - seconds=int(_cot_stale))).strftime(pytak.ISO_8601_UTC) + cot_stale = ( + datetime.datetime.now(datetime.timezone.utc) + + datetime.timedelta(seconds=int(_cot_stale)) + ).strftime(pytak.ISO_8601_UTC) cot_type = feed_conf.get("cot_type", inrcot.DEFAULT_COT_TYPE) diff --git a/setup.py b/setup.py index a7337ea..1c8b701 100644 --- a/setup.py +++ b/setup.py @@ -64,15 +64,10 @@ def publish(): long_description_content_type="text/x-rst", zip_safe=False, include_package_data=True, - install_requires=[ - "pytak >= 5.0.0", - "aiohttp" - ], + install_requires=["pytak >= 5.0.0", "aiohttp"], classifiers=[ "Programming Language :: Python", - "License :: OSI Approved :: Apache Software License" - ], - keywords=[ - "Satellite", "Cursor on Target", "ATAK", "TAK", "CoT" + "License :: OSI Approved :: Apache Software License", ], + keywords=["Satellite", "Cursor on Target", "ATAK", "TAK", "CoT"], )