From faa328396c7ff0320705c90092f580e563a8bdeb Mon Sep 17 00:00:00 2001 From: Walter Boring Date: Sun, 25 Jan 2026 21:50:59 -0500 Subject: [PATCH] update docs and readme --- Makefile | 2 +- README.md | 139 +++++++++++++++++ README.rst | 99 ------------ aprsd_weewx_plugin/__init__.py | 8 +- docs/apidoc/aprsd_weewx_plugin.conf.rst | 37 +++++ docs/apidoc/aprsd_weewx_plugin.rst | 37 +++++ docs/apidoc/modules.rst | 7 + docs/authors.rst | 5 +- docs/changelog.rst | 39 +++++ docs/conf.py | 32 ++-- docs/contributing.rst | 3 + docs/history.rst | 5 +- docs/index.rst | 10 +- docs/installation.rst | 89 ++++++++++- docs/readme.md | 50 ++++++ docs/usage.rst | 145 ++++++++++++++++++ pyproject.toml | 194 +++++++++++++++++------- requirements-dev.txt | 12 -- requirements.txt | 4 - setup.cfg | 44 ------ tox.ini | 5 +- 21 files changed, 725 insertions(+), 241 deletions(-) create mode 100644 README.md delete mode 100644 README.rst create mode 100644 docs/apidoc/aprsd_weewx_plugin.conf.rst create mode 100644 docs/apidoc/aprsd_weewx_plugin.rst create mode 100644 docs/apidoc/modules.rst create mode 100644 docs/changelog.rst create mode 100644 docs/readme.md create mode 100644 docs/usage.rst delete mode 100644 requirements-dev.txt delete mode 100644 requirements.txt delete mode 100644 setup.cfg diff --git a/Makefile b/Makefile index d48dd84..fe0d4e7 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ help: # Help for the Makefile dev: venv ## Create the virtualenv with all the requirements installed docs: build - cp README.rst docs/readme.rst + cp README.md docs/readme.rst cp Changelog docs/changelog.rst tox -edocs diff --git a/README.md b/README.md new file mode 100644 index 0000000..ac85fe9 --- /dev/null +++ b/README.md @@ -0,0 +1,139 @@ +# APRSD Weewx Plugin + +[![PyPI](https://img.shields.io/pypi/v/aprsd-weewx-plugin.svg)](https://pypi.org/project/aprsd-weewx-plugin/) +[![Status](https://img.shields.io/pypi/status/aprsd-weewx-plugin.svg)](https://pypi.org/project/aprsd-weewx-plugin/) +[![Python Version](https://img.shields.io/pypi/pyversions/aprsd-weewx-plugin)](https://pypi.org/project/aprsd-weewx-plugin) +[![License](https://img.shields.io/pypi/l/aprsd-weewx-plugin)](https://opensource.org/licenses/GNU%20GPL%20v3.0) + +[![Read the Docs](https://img.shields.io/readthedocs/aprsd-weewx-plugin/latest.svg?label=Read%20the%20Docs)](https://aprsd-weewx-plugin.readthedocs.io/) +[![Tests](https://github.com/hemna/aprsd-weewx-plugin/workflows/Tests/badge.svg)](https://github.com/hemna/aprsd-weewx-plugin/actions?workflow=Tests) +[![Codecov](https://codecov.io/gh/hemna/aprsd-weewx-plugin/branch/main/graph/badge.svg)](https://codecov.io/gh/hemna/aprsd-weewx-plugin) +[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) + +## Features + +* **MQTT Integration**: Connects to Weewx weather station via MQTT to receive real-time weather data +* **APRS Weather Queries**: Responds to APRS messages with current weather conditions +* **Automatic Weather Reporting**: Optionally reports weather data to APRS-IS at regular intervals +* **Comprehensive Weather Data**: Includes temperature, dewpoint, wind speed/direction, humidity, pressure, and rainfall +* **Flexible Units**: Supports both imperial (Fahrenheit, mph, inHg) and metric (Celsius, m/s, mBar) units + +## Requirements + +* **APRSD**: Version 4.2.0 or higher +* **Weewx**: Weather station software configured to publish MQTT messages +* **MQTT Broker**: Accessible MQTT server (e.g., Mosquitto, Eclipse Mosquitto) +* **Python**: 3.8 or higher + +## Installation + +You can install **APRSD Weewx Plugin** via [pip](https://pip.pypa.io/) from [PyPI](https://pypi.org/): + +```console +$ pip install aprsd-weewx-plugin +``` + +## Configuration + +### Basic Configuration + +Add the plugin to your APRSD configuration file (typically `aprsd.yml`): + +```yaml +aprsd: + enabled_plugins: + - aprsd_weewx_plugin.weewx.WeewxMQTTPlugin + + aprsd_weewx_plugin: + enabled: true + mqtt_host: localhost + mqtt_port: 1883 + mqtt_user: weewx + mqtt_password: your_password_here +``` + +### Automatic Weather Reporting + +To enable automatic weather reporting to APRS-IS, add latitude and longitude: + +```yaml +aprsd_weewx_plugin: + enabled: true + mqtt_host: localhost + mqtt_port: 1883 + latitude: 37.7749 + longitude: -122.4194 + report_interval: 300 # Report every 5 minutes (in seconds) +``` + +### Weewx MQTT Configuration + +Ensure your Weewx installation is configured to publish weather data to MQTT. Add this to your Weewx configuration: + +```ini +[MQTT] + host = localhost + port = 1883 + topic = weather/loop + unit_system = US +``` + +## Usage + +### Querying Weather via APRS + +Once configured, you can query weather data by sending an APRS message to your station's callsign with a message starting with `w` or `W`: + +**Example APRS Interaction:** + +```text +You: WB4BOR-1>APRS,TCPIP*:>w WB4BOR +WB4BOR: WX: 72.5F/54.0F Wind 5@270G12 65% RA 0.00 0.00/hr 29.92inHg +``` + +**Response Format:** + +```text +WX: / Wind @G % RA /hr inHg +``` + +**Example Response Breakdown:** + +* `72.5F/54.0F` - Temperature 72.5°F, Dewpoint 54.0°F +* `Wind 5@270G12` - Wind speed 5 mph from 270° (west) with gusts to 12 mph +* `65%` - Relative humidity +* `RA 0.00 0.00/hr` - Daily rainfall 0.00 inches, current rate 0.00 inches/hour +* `29.92inHg` - Barometric pressure + +### Automatic Weather Reporting + +When latitude and longitude are configured, the plugin automatically sends weather packets to APRS-IS at the configured interval. These packets appear on APRS.fi and other APRS services. + +### Exporting Configuration + +You can export the plugin's configuration options using the CLI tool: + +```console +$ aprsd-weewx-plugin-export-config +``` + +This will output all available configuration options in JSON format. + +## Contributing + +Contributions are very welcome. +To learn more, see the [Contributor Guide](contributing). + +## License + +Distributed under the terms of the [GNU GPL v3.0 license](https://opensource.org/licenses/GNU%20GPL%20v3.0), +**APRSD Weewx Plugin** is free and open source software. + +## Issues + +If you encounter any problems, +please [file an issue](https://github.com/hemna/aprsd-weewx-plugin/issues) along with a detailed description. + +## Credits + +This project was generated from [@hemna](https://github.com/hemna)'s [APRSD Plugin Python Cookiecutter](https://github.com/hemna/cookiecutter-aprsd-plugin) template. diff --git a/README.rst b/README.rst deleted file mode 100644 index dfae4c5..0000000 --- a/README.rst +++ /dev/null @@ -1,99 +0,0 @@ -APRSD Weewx Plugin -=================== - -|PyPI| |Status| |Python Version| |License| - -|Read the Docs| |Tests| |Codecov| - -|pre-commit| - -.. |PyPI| image:: https://img.shields.io/pypi/v/aprsd-weewx-plugin.svg - :target: https://pypi.org/project/aprsd-weewx-plugin/ - :alt: PyPI -.. |Status| image:: https://img.shields.io/pypi/status/aprsd-weewx-plugin.svg - :target: https://pypi.org/project/aprsd-weewx-plugin/ - :alt: Status -.. |Python Version| image:: https://img.shields.io/pypi/pyversions/aprsd-weewx-plugin - :target: https://pypi.org/project/aprsd-weewx-plugin - :alt: Python Version -.. |License| image:: https://img.shields.io/pypi/l/aprsd-weewx-plugin - :target: https://opensource.org/licenses/GNU GPL v3.0 - :alt: License -.. |Read the Docs| image:: https://img.shields.io/readthedocs/aprsd-weewx-plugin/latest.svg?label=Read%20the%20Docs - :target: https://aprsd-weewx-plugin.readthedocs.io/ - :alt: Read the documentation at https://aprsd-weewx-plugin.readthedocs.io/ -.. |Tests| image:: https://github.com/hemna/aprsd-weewx-plugin/workflows/Tests/badge.svg - :target: https://github.com/hemna/aprsd-weewx-plugin/actions?workflow=Tests - :alt: Tests -.. |Codecov| image:: https://codecov.io/gh/hemna/aprsd-weewx-plugin/branch/main/graph/badge.svg - :target: https://codecov.io/gh/hemna/aprsd-weewx-plugin - :alt: Codecov -.. |pre-commit| image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white - :target: https://github.com/pre-commit/pre-commit - :alt: pre-commit - - -Features --------- - -* TODO - - -Requirements ------------- - -* TODO - - -Installation ------------- - -You can install *APRSD Weewx Plugin* via pip_ from PyPI_: - -.. code:: console - - $ pip install aprsd-weewx-plugin - - -Usage ------ - -Please see the `Command-line Reference `_ for details. - - -Contributing ------------- - -Contributions are very welcome. -To learn more, see the `Contributor Guide`_. - - -License -------- - -Distributed under the terms of the `GNU GPL v3.0 license`_, -*APRSD Weewx Plugin* is free and open source software. - - -Issues ------- - -If you encounter any problems, -please `file an issue`_ along with a detailed description. - - -Credits -------- - -This project was generated from `@hemna`_'s `APRSD Plugin Python Cookiecutter`_ template. - -.. _@hemna: https://github.com/hemna -.. _Cookiecutter: https://github.com/audreyr/cookiecutter -.. _GNU GPL v3.0 license: https://opensource.org/licenses/GNU GPL v3.0 -.. _PyPI: https://pypi.org/ -.. _APRSD Plugin Python Cookiecutter: https://github.com/hemna/cookiecutter-aprsd-plugin -.. _file an issue: https://github.com/hemna/aprsd-weewx-plugin/issues -.. _pip: https://pip.pypa.io/ -.. github-only -.. _Contributor Guide: CONTRIBUTING.rst -.. _Usage: https://aprsd-weewx-plugin.readthedocs.io/en/latest/usage.html diff --git a/aprsd_weewx_plugin/__init__.py b/aprsd_weewx_plugin/__init__.py index b36e612..c231366 100644 --- a/aprsd_weewx_plugin/__init__.py +++ b/aprsd_weewx_plugin/__init__.py @@ -9,7 +9,9 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +from importlib.metadata import PackageNotFoundError, version -import pbr.version - -__version__ = pbr.version.VersionInfo("aprsd_weewx_plugin").version_string() +try: + __version__ = version("aprsd_weewx_plugin") +except PackageNotFoundError: + pass diff --git a/docs/apidoc/aprsd_weewx_plugin.conf.rst b/docs/apidoc/aprsd_weewx_plugin.conf.rst new file mode 100644 index 0000000..03d8c7c --- /dev/null +++ b/docs/apidoc/aprsd_weewx_plugin.conf.rst @@ -0,0 +1,37 @@ +aprsd\_weewx\_plugin.conf package +================================= + +Submodules +---------- + +aprsd\_weewx\_plugin.conf.main module +------------------------------------- + +.. automodule:: aprsd_weewx_plugin.conf.main + :members: + :show-inheritance: + :undoc-members: + +aprsd\_weewx\_plugin.conf.opts module +------------------------------------- + +.. automodule:: aprsd_weewx_plugin.conf.opts + :members: + :show-inheritance: + :undoc-members: + +aprsd\_weewx\_plugin.conf.weewx module +-------------------------------------- + +.. automodule:: aprsd_weewx_plugin.conf.weewx + :members: + :show-inheritance: + :undoc-members: + +Module contents +--------------- + +.. automodule:: aprsd_weewx_plugin.conf + :members: + :show-inheritance: + :undoc-members: diff --git a/docs/apidoc/aprsd_weewx_plugin.rst b/docs/apidoc/aprsd_weewx_plugin.rst new file mode 100644 index 0000000..58765a0 --- /dev/null +++ b/docs/apidoc/aprsd_weewx_plugin.rst @@ -0,0 +1,37 @@ +aprsd\_weewx\_plugin package +============================ + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + aprsd_weewx_plugin.conf + +Submodules +---------- + +aprsd\_weewx\_plugin.cli module +------------------------------- + +.. automodule:: aprsd_weewx_plugin.cli + :members: + :show-inheritance: + :undoc-members: + +aprsd\_weewx\_plugin.weewx module +--------------------------------- + +.. automodule:: aprsd_weewx_plugin.weewx + :members: + :show-inheritance: + :undoc-members: + +Module contents +--------------- + +.. automodule:: aprsd_weewx_plugin + :members: + :show-inheritance: + :undoc-members: diff --git a/docs/apidoc/modules.rst b/docs/apidoc/modules.rst new file mode 100644 index 0000000..c366a83 --- /dev/null +++ b/docs/apidoc/modules.rst @@ -0,0 +1,7 @@ +aprsd_weewx_plugin +================== + +.. toctree:: + :maxdepth: 4 + + aprsd_weewx_plugin diff --git a/docs/authors.rst b/docs/authors.rst index e122f91..10fc261 100644 --- a/docs/authors.rst +++ b/docs/authors.rst @@ -1 +1,4 @@ -.. include:: ../AUTHORS.rst +Authors +======= + +.. include:: ../AUTHORS diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 0000000..79b465e --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1,39 @@ +CHANGES +======= + +v0.3.2 +------ + +* another try + +v0.3.1 +------ + +* Updated pressure \* 10 + +v0.3.0 +------ + +* Take the pressure from pressure\_inHg + +v0.2.0 +------ + +* update for 0.2.0 +* Fixed pep8 failures +* Update to aprsd 3.0.0 and include config options! +* don't dump the whole packet +* use Tx to send +* Working with pre 2.7.0 +* Removed trace +* lint +* Added pbr version +* Fixed missing entry in requirements.txt +* Create FUNDING.yml + +v0.1.2 +------ + +* Fixed README.rst formatting +* Updated from first repo +* Initial commit diff --git a/docs/conf.py b/docs/conf.py index d68c0ff..0b2815d 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,12 +20,10 @@ import os import sys - sys.path.insert(0, os.path.abspath("..")) import aprsd_weewx_plugin - # -- General configuration --------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. @@ -34,7 +32,7 @@ import aprsd_weewx_plugin # 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.viewcode"] +extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode", "myst_parser"] # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] @@ -42,8 +40,10 @@ 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" +source_suffix = { + ".rst": "restructuredtext", + ".md": "markdown", +} # The master toctree document. master_doc = "index" @@ -67,7 +67,7 @@ release = aprsd_weewx_plugin.__version__ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -97,7 +97,7 @@ html_theme = "alabaster" # 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"] +# html_static_path = ["_static"] # Commented out since _static directory doesn't exist # -- Options for HTMLHelp output --------------------------------------- @@ -112,15 +112,12 @@ 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', @@ -131,9 +128,11 @@ latex_elements = { # [howto, manual, or own class]). latex_documents = [ ( - master_doc, "aprsd_weewx_plugin.tex", + master_doc, + "aprsd_weewx_plugin.tex", "APRSD Weewx Plugin Documentation", - "Walter A. Boring IV", "manual", + "Walter A. Boring IV", + "manual", ), ] @@ -144,9 +143,11 @@ latex_documents = [ # (source start file, name, description, authors, manual section). man_pages = [ ( - master_doc, "aprsd_weewx_plugin", + master_doc, + "aprsd_weewx_plugin", "APRSD Weewx Plugin Documentation", - [author], 1, + [author], + 1, ), ] @@ -158,7 +159,8 @@ man_pages = [ # dir menu entry, description, category) texinfo_documents = [ ( - master_doc, "aprsd_weewx_plugin", + master_doc, + "aprsd_weewx_plugin", "APRSD Weewx Plugin Documentation", author, "aprsd_weewx_plugin", diff --git a/docs/contributing.rst b/docs/contributing.rst index e582053..07f5cf5 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -1 +1,4 @@ +Contributing +============ + .. include:: ../CONTRIBUTING.rst diff --git a/docs/history.rst b/docs/history.rst index 2506499..dbb0a90 100644 --- a/docs/history.rst +++ b/docs/history.rst @@ -1 +1,4 @@ -.. include:: ../HISTORY.rst +History +======== + +.. include:: ../ChangeLog diff --git a/docs/index.rst b/docs/index.rst index d6c35e8..2925806 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -5,11 +5,19 @@ Welcome to APRSD Nearest station plugin's documentation! :maxdepth: 2 :caption: Contents: - readme + readme.md installation + usage contributing authors history + changelog + +.. toctree:: + :maxdepth: 4 + :caption: API Documentation: + + apidoc/modules Indices and tables ================== diff --git a/docs/installation.rst b/docs/installation.rst index 97a0b04..9ba3142 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -4,6 +4,15 @@ Installation ============ +Prerequisites +------------- + +Before installing the plugin, ensure you have: + +* **APRSD** version 4.2.0 or higher installed and configured +* **Weewx** weather station software running and configured +* Access to an **MQTT broker** (local or remote) +* **Python** 3.8 or higher Stable release -------------- @@ -44,8 +53,86 @@ Once you have a copy of the source, you can install it with: .. code-block:: console - $ python setup.py install + $ pip install . +Configuration +------------- + +After installation, you need to configure the plugin in your APRSD configuration file. + +Basic Configuration +~~~~~~~~~~~~~~~~~~~~ + +Add the plugin to your APRSD configuration (typically ``aprsd.yml``): + +.. code-block:: yaml + + aprsd: + enabled_plugins: + - aprsd_weewx_plugin.weewx.WeewxMQTTPlugin + + aprsd_weewx_plugin: + enabled: true + mqtt_host: localhost + mqtt_port: 1883 + mqtt_user: weewx + mqtt_password: your_password_here + +With Automatic Weather Reporting +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable automatic weather reporting to APRS-IS, add latitude and longitude: + +.. code-block:: yaml + + aprsd_weewx_plugin: + enabled: true + mqtt_host: localhost + mqtt_port: 1883 + mqtt_user: weewx + mqtt_password: your_password_here + latitude: 37.7749 + longitude: -122.4194 + report_interval: 300 # Report every 5 minutes (in seconds) + +Configuration Options +~~~~~~~~~~~~~~~~~~~~~ + +* ``enabled`` (boolean): Enable/disable the plugin (default: false) +* ``mqtt_host`` (string): MQTT broker hostname (required) +* ``mqtt_port`` (integer): MQTT broker port (required) +* ``mqtt_user`` (string): MQTT username (optional) +* ``mqtt_password`` (string): MQTT password (optional, but recommended) +* ``latitude`` (float): Station latitude for automatic reporting (optional) +* ``longitude`` (float): Station longitude for automatic reporting (optional) +* ``report_interval`` (integer): Seconds between automatic reports (default: 60) + +Weewx MQTT Setup +~~~~~~~~~~~~~~~~ + +Ensure your Weewx installation publishes weather data to MQTT. Add this to your Weewx configuration (``weewx.conf``): + +.. code-block:: ini + + [MQTT] + host = localhost + port = 1883 + topic = weather/loop + unit_system = US + +The plugin subscribes to the ``weather/loop`` topic and expects JSON-formatted weather data. + +Exporting Configuration +~~~~~~~~~~~~~~~~~~~~~~~ + +You can view all available configuration options using the CLI tool: + +.. code-block:: console + + $ aprsd-weewx-plugin-export-config + +This outputs all configuration options in JSON format. + .. _Github repo: https://github.com/hemna/aprsd-weewx-plugin .. _tarball: https://github.com/hemna/aprsd-weewx-plugin/tarball/master diff --git a/docs/readme.md b/docs/readme.md new file mode 100644 index 0000000..ea96a2a --- /dev/null +++ b/docs/readme.md @@ -0,0 +1,50 @@ +# APRSD Weewx Plugin + +[![PyPI](https://img.shields.io/pypi/v/aprsd-weewx-plugin.svg)](https://pypi.org/project/aprsd-weewx-plugin/) +[![Status](https://img.shields.io/pypi/status/aprsd-weewx-plugin.svg)](https://pypi.org/project/aprsd-weewx-plugin/) +[![Python Version](https://img.shields.io/pypi/pyversions/aprsd-weewx-plugin)](https://pypi.org/project/aprsd-weewx-plugin) +[![License](https://img.shields.io/pypi/l/aprsd-weewx-plugin)](https://opensource.org/licenses/GNU%20GPL%20v3.0) + +[![Read the Docs](https://img.shields.io/readthedocs/aprsd-weewx-plugin/latest.svg?label=Read%20the%20Docs)](https://aprsd-weewx-plugin.readthedocs.io/) +[![Tests](https://github.com/hemna/aprsd-weewx-plugin/workflows/Tests/badge.svg)](https://github.com/hemna/aprsd-weewx-plugin/actions?workflow=Tests) +[![Codecov](https://codecov.io/gh/hemna/aprsd-weewx-plugin/branch/main/graph/badge.svg)](https://codecov.io/gh/hemna/aprsd-weewx-plugin) +[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) + +## Features + +* TODO + +## Requirements + +* TODO + +## Installation + +You can install **APRSD Weewx Plugin** via [pip](https://pip.pypa.io/) from [PyPI](https://pypi.org/): + +```console +$ pip install aprsd-weewx-plugin +``` + +## Usage + +Please see the [Command-line Reference](https://aprsd-weewx-plugin.readthedocs.io/en/latest/usage.html) for details. + +## Contributing + +Contributions are very welcome. +To learn more, see the [Contributor Guide](contributing). + +## License + +Distributed under the terms of the [GNU GPL v3.0 license](https://opensource.org/licenses/GNU%20GPL%20v3.0), +**APRSD Weewx Plugin** is free and open source software. + +## Issues + +If you encounter any problems, +please [file an issue](https://github.com/hemna/aprsd-weewx-plugin/issues) along with a detailed description. + +## Credits + +This project was generated from [@hemna](https://github.com/hemna)'s [APRSD Plugin Python Cookiecutter](https://github.com/hemna/cookiecutter-aprsd-plugin) template. diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100644 index 0000000..192b4cb --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,145 @@ +Usage +===== + +The APRSD Weewx Plugin provides two main functions: + +1. **Weather Query Responses**: Responds to APRS messages with current weather data +2. **Automatic Weather Reporting**: Periodically sends weather packets to APRS-IS + +Querying Weather via APRS +-------------------------- + +Once the plugin is configured and running, you can query weather data by sending an APRS message to your station's callsign. The plugin responds to messages that start with ``w`` or ``W``. + +Example Interaction +~~~~~~~~~~~~~~~~~~~ + +Here's a typical interaction: + +**You send:** +:: + + WB4BOR-1>APRS,TCPIP*:>w WB4BOR + +**Plugin responds:** +:: + + WB4BOR>APRS,TCPIP*:>WX: 72.5F/54.0F Wind 5@270G12 65% RA 0.00 0.00/hr 29.92inHg + +Response Format +~~~~~~~~~~~~~~~ + +The weather response follows this format: + +:: + + WX: / Wind @G % RA /hr inHg + +Field Breakdown +~~~~~~~~~~~~~~~ + +* **Temperature/Dewpoint**: Current temperature and dewpoint (Fahrenheit or Celsius) +* **Wind**: Wind speed (mph or m/s), direction in degrees, and gust speed +* **Humidity**: Relative humidity percentage +* **Rain**: Daily rainfall total and current rain rate +* **Pressure**: Barometric pressure (inHg or mBar) + +Example Responses +~~~~~~~~~~~~~~~~~ + +**Imperial Units (Fahrenheit, mph, inHg):** +:: + + WX: 72.5F/54.0F Wind 5@270G12 65% RA 0.00 0.00/hr 29.92inHg + +**Metric Units (Celsius, m/s, mBar):** +:: + + WX: 22.5C/12.2C Wind 2@270G5 65% RA 0.00 0.00/hr 1013.25mBar + +**With Rain:** +:: + + WX: 68.0F/55.0F Wind 8@180G15 72% RA 0.25 0.10/hr 30.05inHg + +Automatic Weather Reporting +--------------------------- + +When latitude and longitude are configured, the plugin automatically sends weather packets to APRS-IS at regular intervals. These packets: + +* Appear on APRS.fi and other APRS mapping services +* Include your station's position and weather data +* Are sent at the interval specified by ``report_interval`` (default: 60 seconds) + +Example APRS Weather Packet +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The plugin sends standard APRS weather packets that look like this on APRS.fi: + +:: + + WB4BOR>APRS,TCPIP*:@251234z3745.50N/12225.00W_270/005g012t072r000p000P000h65b10130 + +This packet includes: +* Timestamp (25th day, 12:34 UTC) +* Position (37°45.50'N, 122°25.00'W) +* Wind direction 270° at 5 mph, gusting to 12 mph +* Temperature 72°F +* Rainfall data +* Pressure and humidity + +Troubleshooting +--------------- + +No Response to Weather Queries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If the plugin doesn't respond to weather queries: + +1. Check that the plugin is enabled in your APRSD configuration +2. Verify MQTT connection is working (check APRSD logs) +3. Ensure Weewx is publishing to the ``weather/loop`` topic +4. Check that MQTT credentials are correct + +No Automatic Reports +~~~~~~~~~~~~~~~~~~~~~ + +If automatic weather reports aren't appearing: + +1. Verify ``latitude`` and ``longitude`` are configured +2. Check that your APRSD callsign is set correctly +3. Ensure APRSD is connected to APRS-IS +4. Review the ``report_interval`` setting + +MQTT Connection Issues +~~~~~~~~~~~~~~~~~~~~~~~ + +If you see MQTT connection errors: + +1. Verify the MQTT broker is running and accessible +2. Check firewall settings for the MQTT port +3. Verify MQTT username and password (if required) +4. Test MQTT connection with a tool like ``mosquitto_sub``: + + .. code-block:: console + + $ mosquitto_sub -h localhost -p 1883 -t weather/loop + +Testing the Plugin +------------------ + +You can test the plugin by: + +1. **Checking APRSD logs** for plugin initialization messages +2. **Sending a test message** via APRS to your callsign with "w" or "W" +3. **Monitoring MQTT traffic** to verify Weewx is publishing data +4. **Checking APRS.fi** for automatic weather reports (if enabled) + +Example Test Session +~~~~~~~~~~~~~~~~~~~~ + +1. Start APRSD with the plugin enabled +2. Wait for MQTT connection confirmation in logs +3. Send APRS message: ``w YOURCALL`` +4. Receive weather response +5. Check APRS.fi for automatic reports (if configured) diff --git a/pyproject.toml b/pyproject.toml index be5bbd0..0b01e04 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,77 +1,155 @@ -[build-system] -requires = ["setuptools>=45", "wheel", "pbr"] -build-backend = "setuptools.build_meta" - [project] -name = "aprsd_weewx_plugin" + +# This is the name of your project. The first time you publish this +# package, this name will be registered for you. It will determine how +# users can install this project, e.g.: +# +# $ pip install sampleproject +# +# And where it will live on PyPI: https://pypi.org/project/sampleproject/ +# +# There are some restrictions on what makes a valid project name +# specification here: +# https://packaging.python.org/specifications/core-metadata/#name +name = "aprsd-weewx-plugin" +description = "APRSD Plugin to send weather data to Weewx via MQTT." + +# Specify which Python versions you support. In contrast to the +# 'Programming Language' classifiers in this file, 'pip install' will check this +# and refuse to install the project if the version does not match. See +# https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires +requires-python = ">=3.8" + dynamic = ["version"] -description = "HAM Radio APRSD that reports weather from a weewx weather station." -readme = "README.rst" -requires-python = ">=3.11" -license = {text = "GPL-3.0"} -authors = [ - {name = "Walter A. Boring IV", email = "waboring@hemna.com"} + +dependencies = [ + "aprsd>=4.2.0", + "paho-mqtt", + "oslo_config", ] + +# This is an optional longer description of your project that represents +# the body of text which users will see when they visit PyPI. +# +# Often, this is the same as your README, so you can just read it in from +# that file directly. +# +# This field corresponds to the "Description" metadata field: +# https://packaging.python.org/specifications/core-metadata/#description-optional +readme = {file = "README.md", content-type = "text/markdown"} + + +# This is either text indicating the license for the distribution, or a file +# that contains the license. +# https://packaging.python.org/en/latest/specifications/core-metadata/#license +license = {file = "LICENSE"} + +# This should be your name or the name of the organization who originally +# authored the project, and a valid email address corresponding to the name +# listed. +authors = [ + {name = "Walter A. Boring IV", email = "waboring@hemna.com"}, +] + +# This should be your name or the names of the organization who currently +# maintains the project, and a valid email address corresponding to the name +# listed. +maintainers = [ + {name = "Walter A. Boring IV", email = "waboring@hemna.com"}, +] + +# This field adds keywords for your project which will appear on the +# project page. What does your project relate to? +# +# Note that this is a list of additional keywords, separated +# by commas, to be used to assist searching for the distribution in a +# larger catalog. +keywords = [ + "aprs", + "aprs-is", + "aprsd", + "aprsd-server", + "aprsd-client", + "aprsd-socket", + "aprsd-socket-server", + "aprsd-socket-client", +] + +# Classifiers help users find your project by categorizing it. +# +# For a list of valid classifiers, see https://pypi.org/classifiers/ classifiers = [ - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Intended Audience :: Developers", + "Intended Audience :: End Users/Desktop", + "Intended Audience :: Information Technology", "Topic :: Communications :: Ham Radio", - "Operating System :: POSIX :: Linux", - "Programming Language :: Python", + "Topic :: Internet", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", ] -dependencies = [ - "pbr", - "aprsd>=3.0.0", - "paho-mqtt", - "oslo-config", -] -[project.optional-dependencies] -dev = [ - "pip", - "pip-tools", - "bump2version", - "wheel", - "watchdog", - "ruff", - "tox", - "tox-uv", - "coverage", - "Sphinx", - "twine", - "pytest", - "uv", -] +# List additional groups of dependencies here (e.g. development +# dependencies). Users will be able to install these using the "extras" +# syntax, for example: +# +# $ pip install sampleproject[dev] +# +# Optional dependencies the project provides. These are commonly +# referred to as "extras". For a more extensive definition see: +# https://packaging.python.org/en/latest/specifications/dependency-specifiers/#extras +# [project.optional-dependencies] + +# List URLs that are relevant to your project +# +# This field corresponds to the "Project-URL" and "Home-Page" metadata fields: +# https://packaging.python.org/specifications/core-metadata/#project-url-multiple-use +# https://packaging.python.org/specifications/core-metadata/#home-page-optional +# +# Examples listed include a pattern for specifying where the package tracks +# issues, where the source is hosted, where to say thanks to the package +# maintainers, and where to support the project financially. The key is +# what's used to render the link text on PyPI. +[project.urls] +# "Homepage" = "https://github.com/hemna/aprsd-admin-extension" +# "Bug Reports" = "https://github.com/hemna/aprsd-admin-extension/issues" +# "Source" = "https://github.com/hemna/aprsd-admin-extension" +# Documentation = "https://aprsd-joke-plugin.readthedocs.io/en/latest/" [project.entry-points."oslo.config.opts"] - "aprsd_weewx_plugin.conf" = "aprsd_weewx_plugin.conf.opts:list_opts" + "aprsd_weewx_plugin.conf" = "aprsd_weewx_plugin.conf.opts:list_opts" [project.scripts] "aprsd-weewx-plugin-export-config" = "aprsd_weewx_plugin.cli:main" +# If you are using a different build backend, you will need to change this. [tool.setuptools] -packages = ["aprsd_weewx_plugin"] +# Packages to include +# Packages to include - use find: to auto-discover all packages and subpackages +packages = {find = {}} +package-data = {"sample" = ["*.dat"]} -[tool.setuptools.package-data] -"*" = ["LICENSE"] +[build-system] +requires = [ + "setuptools>=69.5.0", + "setuptools_scm>=0", + "wheel", +] +build-backend = "setuptools.build_meta" -[tool.setuptools.dynamic] -# Version is provided by pbr via setup hooks -# PBR will set __version__ in aprsd_weewx_plugin.__init__ during setup -version = {attr = "aprsd_weewx_plugin.__version__"} +[tool.isort] +force_sort_within_sections = true +multi_line_output = 4 +line_length = 88 +# Inform isort of paths to import names that should be considered part of the "First Party" group. +#src_paths = ["src/openstack_loadtest"] +skip_gitignore = true +# If you need to skip/exclude folders, consider using skip_glob as that will allow the +# isort defaults for skip to remain without the need to duplicate them. -[tool.pbr] -# PBR configuration - version is managed by pbr from git tags -# PBR uses setup hooks to inject version dynamically +[tool.coverage.run] +branch = true -[tool.ruff] -line-length = 99 -target-version = "py311" - -[tool.ruff.lint] -select = ["E", "F", "I", "N", "W"] -ignore = ["E203"] # Ignore whitespace before ':' (required by formatter) - -[tool.mypy] -ignore_missing_imports = true -strict = true +[tool.setuptools_scm] diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index 7555017..0000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,12 +0,0 @@ -pip -pip-tools -bump2version -wheel -watchdog -flake8 -tox -coverage -Sphinx -twine -pytest==6.2.5 -gray diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index c38f692..0000000 --- a/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -pbr -aprsd>=3.0.0 -paho-mqtt -oslo-config diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 81803a8..0000000 --- a/setup.cfg +++ /dev/null @@ -1,44 +0,0 @@ -[metadata] -name = aprsd_weewx_plugin -long_description = file: README.rst -long_description_content_type = text/x-rst -author = Walter A. Boring IV -author_email = waboring@hemna.com -license = GPL-3.0 -license_file = LICENSE -classifiers = - License :: OSI Approved :: GNU General Public License v3 (GPLv3) -classifier = - Topic :: Communications :: Ham Radio - Operating System :: POSIX :: Linux - Programming Language :: Python - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 -description_file = - README.rst -summary = HAM Radio APRSD that reports weather from a weewx weather station. - -[options.entry_points] -oslo.config.opts = - aprsd_weewx_plugin.conf = aprsd_weewx_plugin.conf.opts:list_opts - -[global] -setup-hooks = - pbr.hooks.setup_hook - -[files] -packages = - aprsd_weewx_plugin - -[build_sphinx] -source-dir = doc/source -build-dir = doc/build -all_files = 1 - -[upload_sphinx] -upload-dir = doc/build/html - -[mypy] -ignore_missing_imports = True -strict = True diff --git a/tox.ini b/tox.ini index 0dbc89a..423632a 100644 --- a/tox.ini +++ b/tox.ini @@ -42,11 +42,14 @@ commands = ruff check aprsd_weewx_plugin tests [testenv:docs] -skip_install = true +package = uv-editable deps = Sphinx + myst-parser changedir = {toxinidir}/docs commands = + python -c "import shutil; from pathlib import Path; Path('readme.md').write_text(Path('../README.md').read_text())" + python -c "import shutil; shutil.copy('../ChangeLog', 'changelog.rst')" {envpython} clean_docs.py sphinx-apidoc --force --output-dir apidoc {toxinidir}/aprsd_weewx_plugin sphinx-build -a -W . _build