-
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
804 additions
and
191 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
INRCOT 5.2.0 | ||
------------ | ||
Major updates. | ||
- Updated copyrights, etc. | ||
- Documentation & Readme updates. | ||
- Now supports Data Package server configuration. | ||
- Fixed custom user icon support. | ||
- Added unit tests. | ||
- Now requires PyTAK >= 5.6.1. | ||
- Refactoring, style improvements, linting, black. |
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,4 @@ | ||
Copyright 2022 Greg Albrecht <[email protected]> | ||
Copyright 2023 Greg Albrecht <[email protected]> | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
|
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,5 +1,5 @@ | ||
# | ||
# Copyright 2022 Greg Albrecht <[email protected]> | ||
# Copyright 2023 Greg Albrecht <[email protected]> | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
|
@@ -13,9 +13,7 @@ | |
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# Author:: Greg Albrecht W2GMD <[email protected]> | ||
# Copyright:: Copyright 2022 Greg Albrecht | ||
# License:: Apache License, Version 2.0 | ||
# Author:: Greg Albrecht <[email protected]> | ||
# | ||
|
||
this_app = inrcot | ||
|
@@ -72,7 +70,7 @@ pytest: | |
test: editable install_test_requirements pytest | ||
|
||
test_cov: | ||
pytest --cov=$(this_app) | ||
pytest --cov=$(this_app) --cov-report term-missing | ||
|
||
black: | ||
black . |
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 |
---|---|---|
|
@@ -8,29 +8,25 @@ Garmin inReach to Cursor on Target Gateway | |
* Pictured: Screenshot of INRCOT being used on a Search & Rescue mission in Arizona. | ||
|
||
The inReach to Cursor on Target Gateway (INRCOT) transforms Garmin inReach | ||
position messages into Cursor on Target (CoT) Points for display on TAK Products | ||
like ATAK, WinTAK, iTAK, et al. Single or multi-device feeds are supported. | ||
position messages into Cursor on Target (CoT) for display on TAK Products such as | ||
ATAK, WinTAK, iTAK, et al. Single or multi-device feeds are supported. | ||
|
||
Other situational awareness products, including as RaptorX, TAKX & COPERS have been tested. | ||
Other situational awareness products, including as RaptorX, TAKX & COPERS have been | ||
tested. | ||
|
||
INRCOT requires a `Garmin inReach <https://discover.garmin.com/en-US/inreach/personal/>`_ device with service. | ||
INRCOT requires a `Garmin inReach <https://discover.garmin.com/en-US/inreach/personal/>`_ | ||
device with service. | ||
|
||
.. image:: https://raw.githubusercontent.com/ampledata/inrcot/main/docs/inrcot-conops.png | ||
:alt: Diagram of INRCOT's Concept of Operations (CONOPS). | ||
:target: https://raw.githubusercontent.com/ampledata/inrcot/main/docs/inrcot-conops.png | ||
.. image:: https://raw.githubusercontent.com/ampledata/inrcot/main/docs/inrcot-conop.png | ||
:alt: Diagram of INRCOT's Concept of Operations (CONOP). | ||
:target: https://raw.githubusercontent.com/ampledata/inrcot/main/docs/inrcot-conop.png | ||
|
||
* Pictured: Diagram of INRCOT's Concept of Operations (CONOP). | ||
|
||
* Pictured: Diagram of INRCOT's Concept of Operations (CONOPS). | ||
|
||
Support Development | ||
=================== | ||
|
||
**Tech Support**: Email [email protected] or Signal/WhatsApp: +1-310-621-9598 | ||
|
||
This tool has been developed for the Disaster Response, Public Safety and | ||
Frontline Healthcare community. This software is currently provided at no-cost | ||
to users. Any contribution you can make to further this project's development | ||
efforts is greatly appreciated. | ||
|
||
.. image:: https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png | ||
:target: https://www.buymeacoffee.com/ampledata | ||
:alt: Support Development: Buy me a coffee! | ||
|
@@ -42,14 +38,14 @@ Use Cases | |
There are numerous applications for satellite based position location information, | ||
including: | ||
|
||
1. Blue Force Tracking | ||
2. Search & Rescue (SAR) | ||
3. Partner Forces PLI | ||
4. Asset Tracking | ||
5. Data diode, CDS & cybersecurity considerations | ||
1. Wildland fire unit tracking | ||
2. Blue Force Tracking | ||
3. Search & Rescue (SAR) | ||
4. Partner Forces PLI | ||
5. Asset Tracking | ||
6. Data diode, CDS & cybersecurity considerations | ||
|
||
INRCOT may also be of use in wildland firefighting, see Section 1114.d of | ||
the `Dingell Act <https://www.congress.gov/bill/116th-congress/senate-bill/47/text>`_:: | ||
See also Section 1114.d of the `Dingell Act <https://www.congress.gov/bill/116th-congress/senate-bill/47/text>`_:: | ||
|
||
Location Systems for Wildland Firefighters.-- | ||
(1) In general.--Not later than 2 years after the date of | ||
|
@@ -108,24 +104,38 @@ Usage | |
The ``inrcot`` program has two command-line arguments:: | ||
|
||
$ inrcot -h | ||
usage: inrcot [-h] [-c CONFIG_FILE] | ||
usage: inrcot [-h] [-c CONFIG_FILE] [-p PREF_PACKAGE] | ||
|
||
optional arguments: | ||
-h, --help show this help message and exit | ||
-c CONFIG_FILE, --CONFIG_FILE Sets the path to a config file. Default: config.ini | ||
-h, --help show this help message and exit | ||
-c CONFIG_FILE, --CONFIG_FILE CONFIG_FILE | ||
Optional configuration file. Default: config.ini | ||
-p PREF_PACKAGE, --PREF_PACKAGE PREF_PACKAGE | ||
Optional connection preferences package zip file (aka data package). | ||
|
||
|
||
Configuration | ||
============= | ||
|
||
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. | ||
a INI-stile configuration file. An example configuration file, click here for an | ||
example configuration file `example-config.ini <https://github.com/ampledata/inrcot/blob/main/example-config.ini>`_. | ||
|
||
Global Config Parameters: | ||
|
||
* **POLL_INTERVAL**: How many seconds between checking for new messages at the Spot API? Default: ``120`` (seconds). | ||
* **COT_STALE**: How many seconds until CoT is stale? Default: ``600`` (seconds) | ||
* **COT_TYPE**: CoT Type. Default: ``a-f-g-e-s`` | ||
|
||
Parameters: | ||
For each feed (1 inReach = 1 feed, multiple feeds supported), these config params can be set: | ||
|
||
* **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**: CoT Event Type / 2525 type / SIDC-like. Default: neutral ground | ||
* **FEED_URL**: URL to the MapShare KML. | ||
* **COT_STALE**: How many seconds until CoT is stale? Default: ``600`` (seconds) | ||
* **COT_TYPE**: CoT Type. Default: ``a-f-g-e-s`` | ||
* **COT_NAME**: CoT Callsign. Defaults to the MapShare KML Placemark name. | ||
* **COT_ICON**: CoT User Icon. If set, will set the CoT ``usericon`` element, for use with custom TAK icon sets. | ||
* **FEED_USERNAME**: MapShare username, for use with protected MapShare. | ||
* **FEED_PASSWORD**: MapShare password, for use with protected MapShare. | ||
|
||
TLS & other configuration parameters available via `PyTAK <https://github.com/ampledata/pytak#configuration-parameters>`_. | ||
|
||
|
@@ -194,12 +204,12 @@ https://ampledata.org/ | |
|
||
Copyright | ||
========= | ||
INRCOT is Copyright 2022 Greg Albrecht | ||
INRCOT is Copyright 2023 Greg Albrecht | ||
|
||
|
||
License | ||
======= | ||
Copyright 2022 Greg Albrecht <[email protected]> | ||
Copyright 2023 Greg Albrecht <[email protected]> | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
|
File renamed without changes
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,7 +1,7 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright 2022 Greg Albrecht <[email protected]> | ||
# Copyright 2023 Greg Albrecht <[email protected]> | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
|
@@ -13,25 +13,22 @@ | |
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# Author:: Greg Albrecht W2GMD <[email protected]> | ||
# | ||
|
||
""" | ||
inReach to Cursor-on-Target Gateway. | ||
~~~~ | ||
|
||
:author: Greg Albrecht W2GMD <[email protected]> | ||
:copyright: Copyright 2022 Greg Albrecht | ||
"""inReach to Cursor on Target Gateway. | ||
:author: Greg Albrecht <[email protected]> | ||
:copyright: Copyright 2023 Greg Albrecht | ||
:license: Apache License, Version 2.0 | ||
:source: <https://github.com/ampledata/inrcot> | ||
""" | ||
|
||
from .constants import DEFAULT_POLL_INTERVAL, DEFAULT_COT_STALE, DEFAULT_COT_TYPE | ||
|
||
from .functions import create_tasks, inreach_to_cot, split_feed | ||
from .functions import create_tasks, inreach_to_cot, split_feed, create_feeds | ||
|
||
from .classes import Worker | ||
|
||
__author__ = "Greg Albrecht W2GMD <[email protected]>" | ||
__copyright__ = "Copyright 2022 Greg Albrecht" | ||
__author__ = "Greg Albrecht <[email protected]>" | ||
__copyright__ = "Copyright 2023 Greg Albrecht" | ||
__license__ = "Apache License, Version 2.0" |
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,7 +1,7 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright 2022 Greg Albrecht <[email protected]> | ||
# Copyright 2023 Greg Albrecht <[email protected]> | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
|
@@ -13,94 +13,85 @@ | |
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# Author:: Greg Albrecht W2GMD <[email protected]> | ||
# | ||
|
||
|
||
"""INRCOT Class Definitions.""" | ||
|
||
import asyncio | ||
|
||
from typing import Optional | ||
|
||
import aiohttp | ||
|
||
import pytak | ||
import inrcot | ||
|
||
|
||
__author__ = "Greg Albrecht W2GMD <[email protected]>" | ||
__copyright__ = "Copyright 2022 Greg Albrecht" | ||
__author__ = "Greg Albrecht <[email protected]>" | ||
__copyright__ = "Copyright 2023 Greg Albrecht" | ||
__license__ = "Apache License, Version 2.0" | ||
|
||
|
||
class Worker(pytak.QueueWorker): | ||
"""Read inReach Feed, renders to CoT, and puts on a TX queue.""" | ||
|
||
"""Reads inReach Feed, renders to CoT, and puts on a TX queue.""" | ||
|
||
def __init__(self, queue: asyncio.Queue, config, original_config) -> None: | ||
def __init__(self, queue: asyncio.Queue, config, orig_config) -> None: | ||
super().__init__(queue, config) | ||
self.inreach_feeds: list = [] | ||
self._create_feeds(original_config) | ||
|
||
def _create_feeds(self, config: dict = None) -> None: | ||
"""Creates a list of feed configurations.""" | ||
for feed in config.sections(): | ||
if "inrcot_feed_" in feed: | ||
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_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" | ||
): | ||
feed_conf["feed_auth"] = aiohttp.BasicAuth( | ||
config[feed].get("FEED_USERNAME"), | ||
config[feed].get("FEED_PASSWORD"), | ||
) | ||
|
||
self.inreach_feeds.append(feed_conf) | ||
|
||
async def handle_data(self, data: str, feed_conf: dict) -> None: | ||
"""Handles the response from the inReach API.""" | ||
for feed in inrcot.split_feed(data): | ||
event: str = inrcot.inreach_to_cot(feed, feed_conf) | ||
if event: | ||
await self.put_queue(event) | ||
else: | ||
self._logger.debug("Empty COT Event") | ||
|
||
async def get_inreach_feeds(self): | ||
"""Gets inReach Feed from API.""" | ||
self.inreach_feeds: list = inrcot.create_feeds(orig_config) | ||
|
||
async def handle_data(self, data: bytes, feed_conf: dict) -> None: | ||
"""Handle the response from the inReach API.""" | ||
feeds: Optional[list] = inrcot.split_feed(data) | ||
if not feeds: | ||
return None | ||
for feed in feeds: | ||
event: Optional[bytes] = inrcot.inreach_to_cot(feed, feed_conf) | ||
if not event: | ||
self._logger.debug("Empty CoT Event") | ||
continue | ||
await self.put_queue(event) | ||
|
||
async def get_inreach_feeds(self) -> None: | ||
"""Get inReach Feed from API.""" | ||
for feed_conf in self.inreach_feeds: | ||
feed_auth = feed_conf.get("feed_auth") | ||
if not feed_auth: | ||
self._logger.warning("No feed_auth specified.") | ||
continue | ||
|
||
feed_url = feed_conf.get("feed_url") | ||
if not feed_url: | ||
self._logger.warning("No feed_url specified.") | ||
continue | ||
|
||
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_url | ||
) | ||
except Exception as exc: # NOQA pylint: disable=broad-except | ||
self._logger.error("Exception raised while polling inReach API.") | ||
self._logger.warning("Exception raised while polling inReach API.") | ||
self._logger.exception(exc) | ||
return | ||
continue | ||
|
||
status: int = response.status | ||
if status != 200: | ||
self._logger.warning( | ||
"No valid response from inReach API: status=%s", status | ||
) | ||
self._logger.debug(response) | ||
continue | ||
|
||
if response.status == 200: | ||
await self.handle_data(await response.content.read(), feed_conf) | ||
else: | ||
self._logger.error("No valid response from inReach API.") | ||
await self.handle_data(await response.content.read(), feed_conf) | ||
|
||
async def run(self) -> None: | ||
"""Runs this Worker, Reads from Pollers.""" | ||
async def run(self, number_of_iterations=-1) -> None: | ||
"""Run this Worker, Reads from Pollers.""" | ||
self._logger.info("Run: %s", self.__class__) | ||
|
||
poll_interval: str = self.config.get( | ||
"POLL_INTERVAL", inrcot.DEFAULT_POLL_INTERVAL | ||
poll_interval: int = int( | ||
self.config.get("POLL_INTERVAL", inrcot.DEFAULT_POLL_INTERVAL) | ||
) | ||
|
||
while 1: | ||
await self.get_inreach_feeds() | ||
await asyncio.sleep(int(poll_interval)) | ||
await asyncio.sleep(poll_interval) |
Oops, something went wrong.