Compare commits

..

4 Commits

Author SHA1 Message Date
968661f428 Removed trace 2022-12-02 16:32:12 -05:00
d4f6f0cb85 lint 2021-12-07 17:04:16 -05:00
913480098c Added pbr version 2021-12-07 16:59:57 -05:00
3289b5b3be Fixed missing entry in requirements.txt 2021-09-14 15:34:22 -04:00
10 changed files with 154 additions and 326 deletions

12
.github/FUNDING.yml vendored
View File

@ -1,12 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: wb4bor
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@ -1,2 +1 @@
Hemna <waboring@hemna.com> Hemna <waboring@hemna.com>
Walter A. Boring IV <waboring@hemna.com>

View File

@ -1,35 +1,16 @@
CHANGES CHANGES
======= =======
v0.3.2 v0.1.4
------ ------
* 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 * lint
* Added pbr version * Added pbr version
v0.1.3
------
* Fixed missing entry in requirements.txt * Fixed missing entry in requirements.txt
* Create FUNDING.yml
v0.1.2 v0.1.2
------ ------

View File

@ -21,7 +21,7 @@ docs: build
cp Changelog docs/changelog.rst cp Changelog docs/changelog.rst
tox -edocs tox -edocs
clean: clean-build clean-pyc clean-test clean-dev ## remove all build, test, coverage and Python artifacts clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts
clean-build: ## remove build artifacts clean-build: ## remove build artifacts
rm -fr build/ rm -fr build/
@ -42,10 +42,6 @@ clean-test: ## remove test and coverage artifacts
rm -fr htmlcov/ rm -fr htmlcov/
rm -fr .pytest_cache rm -fr .pytest_cache
clean-dev: ## Clean out the venv
rm -rf $(VENVDIR)
rm Makefile.venv
coverage: ## check code coverage quickly with the default Python coverage: ## check code coverage quickly with the default Python
coverage run --source aprsd_weewx_plugin setup.py test coverage run --source aprsd_weewx_plugin setup.py test
coverage report -m coverage report -m

View File

@ -1,7 +0,0 @@
from oslo_config import cfg
from aprsd_weewx_plugin.conf import weewx
CONF = cfg.CONF
weewx.register_opts(CONF)

View File

@ -1,80 +0,0 @@
# Copyright 2015 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
This is the single point of entry to generate the sample configuration
file for Nova. It collects all the necessary info from the other modules
in this package. It is assumed that:
* every other module in this package has a 'list_opts' function which
return a dict where
* the keys are strings which are the group names
* the value of each key is a list of config options for that group
* the nova.conf package doesn't have further packages with config options
* this module is only used in the context of sample file generation
"""
import collections
import importlib
import os
import pkgutil
LIST_OPTS_FUNC_NAME = "list_opts"
def _tupleize(dct):
"""Take the dict of options and convert to the 2-tuple format."""
return [(key, val) for key, val in dct.items()]
def list_opts():
opts = collections.defaultdict(list)
module_names = _list_module_names()
imported_modules = _import_modules(module_names)
_append_config_options(imported_modules, opts)
return _tupleize(opts)
def _list_module_names():
module_names = []
package_path = os.path.dirname(os.path.abspath(__file__))
for _, modname, ispkg in pkgutil.iter_modules(path=[package_path]):
if modname == "opts" or ispkg:
continue
else:
module_names.append(modname)
return module_names
def _import_modules(module_names):
imported_modules = []
for modname in module_names:
mod = importlib.import_module("aprsd_weewx_plugin.conf." + modname)
if not hasattr(mod, LIST_OPTS_FUNC_NAME):
msg = "The module 'aprsd_weewx_plugin.conf.%s' should have a '%s' "\
"function which returns the config options." % \
(modname, LIST_OPTS_FUNC_NAME)
raise Exception(msg)
else:
imported_modules.append(mod)
return imported_modules
def _append_config_options(imported_modules, config_options):
for mod in imported_modules:
configs = mod.list_opts()
for key, val in configs.items():
config_options[key].extend(val)

View File

@ -1,62 +0,0 @@
from oslo_config import cfg
weewx_group = cfg.OptGroup(
name="aprsd_weewx_plugin",
title="APRSD Weewx Plugin settings",
)
weewx_opts = [
cfg.FloatOpt(
"latitude",
default=None,
help="Latitude of the station you want to report as",
),
cfg.FloatOpt(
"longitude",
default=None,
help="Longitude of the station you want to report as",
),
cfg.IntOpt(
"report_interval",
default=60,
help="How long (in seconds) in between weather reports",
),
]
weewx_mqtt_opts = [
cfg.StrOpt(
"mqtt_user",
help="MQTT username",
),
cfg.StrOpt(
"mqtt_password",
secret=True,
help="MQTT password",
),
cfg.StrOpt(
"mqtt_host",
help="MQTT Hostname to connect to",
),
cfg.PortOpt(
"mqtt_port",
help="MQTT Port",
),
]
ALL_OPTS = (
weewx_opts +
weewx_mqtt_opts
)
def register_opts(cfg):
cfg.register_group(weewx_group)
cfg.register_opts(ALL_OPTS, group=weewx_group)
def list_opts():
register_opts(cfg.CONF)
return {
weewx_group.name: ALL_OPTS,
}

View File

@ -5,16 +5,11 @@ import logging
import queue import queue
import time import time
import aprsd.messaging
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
from aprsd import plugin, threads from aprsd import plugin, threads
from aprsd.threads import tx
from aprsd.packets import core
from oslo_config import cfg
from aprsd_weewx_plugin import conf # noqa
CONF = cfg.CONF
LOG = logging.getLogger("APRSD") LOG = logging.getLogger("APRSD")
@ -45,24 +40,23 @@ class WeewxMQTTPlugin(plugin.APRSDRegexCommandPluginBase):
def setup(self): def setup(self):
"""Ensure that the plugin has been configured.""" """Ensure that the plugin has been configured."""
self.enabled = True LOG.info("Looking for weewx.mqtt.host config entry")
if not CONF.aprsd_weewx_plugin.mqtt_host: if self.config.exists("services.weewx.mqtt.host"):
LOG.error("aprsd_weewx_plugin.mqtt_host is not set in config!") self.enabled = True
else:
LOG.error("Failed to find config weewx:mqtt:host")
LOG.info("Disabling the weewx mqtt subsription thread.")
self.enabled = False self.enabled = False
if not CONF.aprsd_weewx_plugin.mqtt_user:
LOG.warning("aprsd_weewx_plugin.mqtt_user is not set")
if not CONF.aprsd_weewx_plugin.mqtt_password:
LOG.warning("aprsd_weewx_plugin.mqtt_password is not set")
def create_threads(self): def create_threads(self):
if self.enabled: if self.enabled:
LOG.info("Creating WeewxMQTTThread") LOG.info("Creating WeewxMQTTThread")
self.queue = ClearableQueue(maxsize=1) self.queue = ClearableQueue(maxsize=1)
self.wx_queue = ClearableQueue(maxsize=1) self.wx_queue = queue.Queue(maxsize=2)
mqtt_thread = WeewxMQTTThread( mqtt_thread = WeewxMQTTThread(
config=self.config,
msg_queues=self.queue,
wx_queue=self.wx_queue, wx_queue=self.wx_queue,
msg_queue=self.queue,
) )
threads = [mqtt_thread] threads = [mqtt_thread]
@ -70,21 +64,19 @@ class WeewxMQTTPlugin(plugin.APRSDRegexCommandPluginBase):
# Then we can periodically report weather data # Then we can periodically report weather data
# to APRS # to APRS
if ( if (
CONF.aprsd_weewx_plugin.latitude and self.config.exists("services.weewx.location.latitude") and
CONF.aprsd_weewx_plugin.longitude self.config.exists("services.weewx.location.longitude")
): ):
LOG.info("Creating WeewxWXAPRSThread") LOG.info("Creating WeewxWXAPRSThread")
wx_thread = WeewxWXAPRSThread( wx_thread = WeewxWXAPRSThread(
config=self.config,
wx_queue=self.wx_queue, wx_queue=self.wx_queue,
) )
threads.append(wx_thread) threads.append(wx_thread)
else: else:
LOG.info( LOG.info(
"NOT starting Weewx WX APRS Thread due to missing " "NOT starting Weewx WX APRS Thread due to missing "
"GPS location settings. Please set " "GPS location settings.",
"aprsd_weewx_plugin.latitude and "
"aprsd_weewx_plugin.longitude to start reporting as an "
"aprs weather station.",
) )
return threads return threads
@ -97,88 +89,89 @@ class WeewxMQTTPlugin(plugin.APRSDRegexCommandPluginBase):
packet.get("message_text", None) packet.get("message_text", None)
# ack = packet.get("msgNo", "0") # ack = packet.get("msgNo", "0")
# see if there are any weather messages in the queue. if self.enabled:
msg = None # see if there are any weather messages in the queue.
LOG.info("Looking for a message") msg = None
if not self.queue.empty(): LOG.info("Looking for a message")
msg = self.queue.get(timeout=1) if not self.queue.empty():
else: msg = self.queue.get(timeout=1)
try:
msg = self.queue.get(timeout=30)
except Exception:
return "No Weewx Data"
if not msg:
return "No Weewx data"
else:
LOG.info(f"Got a message {msg}")
# Wants format of 71.5F/54.0F Wind 1@49G7 54%
if "outTemp_F" in msg:
temperature = "{:0.2f}F".format(float(msg["outTemp_F"]))
dewpoint = "{:0.2f}F".format(float(msg["dewpoint_F"]))
else: else:
temperature = "{:0.2f}C".format(float(msg["outTemp_C"])) try:
dewpoint = "{:0.2f}C".format(float(msg["dewpoint_C"])) msg = self.queue.get(timeout=30)
except Exception:
return "No Weewx Data"
wind_direction = "{:0.0f}".format(float(msg.get("windDir", 0))) if not msg:
LOG.info(f"wind direction {wind_direction}") return "No Weewx data"
if "windSpeed_mps" in msg:
wind_speed = "{:0.0f}".format(float(msg["windSpeed_mps"]))
wind_gust = "{:0.0f}".format(float(msg["windGust_mps"]))
else: else:
wind_speed = "{:0.0f}".format(float(msg["windSpeed_mph"])) LOG.info(f"Got a message {msg}")
wind_gust = "{:0.0f}".format(float(msg["windGust_mph"])) # Wants format of 71.5F/54.0F Wind 1@49G7 54%
if "outTemp_F" in msg:
temperature = "{:0.2f}F".format(float(msg["outTemp_F"]))
dewpoint = "{:0.2f}F".format(float(msg["dewpoint_F"]))
else:
temperature = "{:0.2f}C".format(float(msg["outTemp_C"]))
dewpoint = "{:0.2f}C".format(float(msg["dewpoint_C"]))
wind = "{}@{}G{}".format( wind_direction = "{:0.0f}".format(float(msg.get("windDir", 0)))
wind_speed, LOG.info(f"wind direction {wind_direction}")
wind_direction, if "windSpeed_mps" in msg:
wind_gust, wind_speed = "{:0.0f}".format(float(msg["windSpeed_mps"]))
) wind_gust = "{:0.0f}".format(float(msg["windGust_mps"]))
else:
wind_speed = "{:0.0f}".format(float(msg["windSpeed_mph"]))
wind_gust = "{:0.0f}".format(float(msg["windGust_mph"]))
humidity = "{:0.0f}%".format(float(msg["outHumidity"])) wind = "{}@{}G{}".format(
wind_speed,
wind_direction,
wind_gust,
)
ts = int("{:0.0f}".format(float(msg["dateTime"]))) humidity = "{:0.0f}%".format(float(msg["outHumidity"]))
ts = datetime.datetime.fromtimestamp(ts)
# do rain in format of last hour/day/month/year ts = int("{:0.0f}".format(float(msg["dateTime"])))
ts = datetime.datetime.fromtimestamp(ts)
rain = "RA {:.2f} {:.2f}/hr".format( # do rain in format of last hour/day/month/year
float(msg.get("dayRain_in", 0.00)),
float(msg.get("rainRate_inch_per_hour", 0.00)),
)
wx = "WX: {}/{} Wind {} {} {} {:.2f}inHg".format( rain = "RA {:.2f} {:.2f}/hr".format(
temperature, float(msg.get("dayRain_in", 0.00)),
dewpoint, float(msg.get("rainRate_inch_per_hour", 0.00)),
wind, )
humidity,
rain, wx = "WX: {}/{} Wind {} {} {} {:.2f}inHg".format(
float(msg.get("pressure_inHg", 0.00)), temperature,
) dewpoint,
LOG.debug( wind,
"Got weather {} -- len {}".format( humidity,
wx, rain,
len(wx), float(msg.get("pressure_inHg", 0.00)),
), )
) LOG.debug(
return wx "Got weather {} -- len {}".format(
wx,
len(wx),
),
)
return wx
else:
return "WeewxMQTT Not enabled"
class WeewxMQTTThread(threads.APRSDThread): class WeewxMQTTThread(threads.APRSDThread):
_mqtt_host = None def __init__(self, config, msg_queues, wx_queue):
_mqtt_port = None
client = None
def __init__(self, wx_queue, msg_queue):
super().__init__("WeewxMQTTThread") super().__init__("WeewxMQTTThread")
self.msg_queue = msg_queue self.config = config
self.msg_queues = msg_queues
self.wx_queue = wx_queue self.wx_queue = wx_queue
self.setup() self.setup()
def setup(self): def setup(self):
LOG.info("Creating mqtt client") LOG.info("Creating mqtt client")
self._mqtt_host = CONF.aprsd_weewx_plugin.mqtt_host self._mqtt_host = self.config["services"]["weewx"]["mqtt"]["host"]
self._mqtt_port = CONF.aprsd_weewx_plugin.mqtt_port self._mqtt_port = self.config["services"]["weewx"]["mqtt"]["port"]
LOG.info( LOG.info(
"Connecting to mqtt {}:{}".format( "Connecting to mqtt {}:{}".format(
self._mqtt_host, self._mqtt_host,
@ -187,12 +180,11 @@ class WeewxMQTTThread(threads.APRSDThread):
) )
self.client = mqtt.Client(client_id="WeewxMQTTPlugin") self.client = mqtt.Client(client_id="WeewxMQTTPlugin")
self.client.on_connect = self.on_connect self.client.on_connect = self.on_connect
self.client.on_disconnect = self.on_disconnect
self.client.on_message = self.on_message self.client.on_message = self.on_message
self.client.connect(self._mqtt_host, self._mqtt_port, 60) self.client.connect(self._mqtt_host, self._mqtt_port, 60)
if CONF.aprsd_weewx_plugin.mqtt_user: if self.config.exists("services.weewx.mqtt.user"):
username = CONF.aprsd_weewx_plugin.mqtt_user username = self.config.get("services.weewx.mqtt.user")
password = CONF.aprsd_weewx_plugin.mqtt_password password = self.config.get("services.weewx.mqtt.password")
LOG.info(f"Using MQTT username/password {username}/XXXXXX") LOG.info(f"Using MQTT username/password {username}/XXXXXX")
self.client.username_pw_set( self.client.username_pw_set(
username=username, username=username,
@ -205,42 +197,35 @@ class WeewxMQTTThread(threads.APRSDThread):
LOG.info(f"Connected to MQTT {self._mqtt_host} ({rc})") LOG.info(f"Connected to MQTT {self._mqtt_host} ({rc})")
client.subscribe("weather/loop") client.subscribe("weather/loop")
def on_disconnect(self, client, userdata, rc):
LOG.info(f"Disconnected from MQTT {self._mqtt_host} ({rc})")
def on_message(self, client, userdata, msg): def on_message(self, client, userdata, msg):
wx_data = json.loads(msg.payload) wx_data = json.loads(msg.payload)
LOG.debug("Got WX data") LOG.debug(f"Got WX data {wx_data}")
# Make sure we have only 1 item in the queue # Make sure we have only 1 item in the queue
if self.msg_queue.qsize() >= 1: if self.msg_queues.qsize() >= 1:
self.msg_queue.clear() self.msg_queues.clear()
self.msg_queue.put(wx_data) self.msg_queues.put(wx_data)
self.wx_queue.clear()
self.wx_queue.put(wx_data) self.wx_queue.put(wx_data)
def stop(self): def stop(self):
LOG.info(__class__.__name__+" Stop")
self.thread_stop = True
LOG.info("Stopping loop")
self.client.loop_stop()
LOG.info("Disconnecting from MQTT") LOG.info("Disconnecting from MQTT")
self.thread_stop = True
self.client.loop_stop()
self.client.disconnect() self.client.disconnect()
def loop(self): def loop(self):
LOG.info("Loop")
self.client.loop_forever() self.client.loop_forever()
# self.client.loop(timeout=10, max_packets=10) # self.client.loop(timeout=10, max_packets=10)
return True return True
class WeewxWXAPRSThread(threads.APRSDThread): class WeewxWXAPRSThread(threads.APRSDThread):
def __init__(self, wx_queue): def __init__(self, config, wx_queue):
super().__init__(self.__class__.__name__) super().__init__(self.__class__.__name__)
self.config = config
self.wx_queue = wx_queue self.wx_queue = wx_queue
self.latitude = CONF.aprsd_weewx_plugin.latitude self.latitude = self.config.get("services.weewx.location.latitude")
self.longitude = CONF.aprsd_weewx_plugin.longitude self.longitude = self.config.get("services.weewx.location.longitude")
self.callsign = CONF.callsign self.callsign = self.config.get("services.weewx.callsign")
self.report_interval = CONF.aprsd_weewx_plugin.report_interval
self.last_send = datetime.datetime.now() self.last_send = datetime.datetime.now()
if self.latitude and self.longitude: if self.latitude and self.longitude:
@ -248,6 +233,7 @@ class WeewxWXAPRSThread(threads.APRSDThread):
float(self.latitude), float(self.latitude),
float(self.longitude), float(self.longitude),
) )
self.address = f"{self.callsign}>APRS,TCPIP*:"
def decdeg2dmm_m(self, degrees_decimal): def decdeg2dmm_m(self, degrees_decimal):
is_positive = degrees_decimal >= 0 is_positive = degrees_decimal >= 0
@ -278,6 +264,12 @@ class WeewxWXAPRSThread(threads.APRSDThread):
minutes = str(det.get("minutes")).zfill(2) minutes = str(det.get("minutes")).zfill(2)
det.get("seconds") det.get("seconds")
hundredths = str(det.get("hundredths")).split(".")[1] hundredths = str(det.get("hundredths")).split(".")[1]
LOG.debug(
f"LAT degress {degrees} minutes {str(minutes)} "
"seconds {seconds} hundredths {hundredths} direction {direction}",
)
lat = f"{degrees}{str(minutes)}.{hundredths}{direction}" lat = f"{degrees}{str(minutes)}.{hundredths}{direction}"
return lat return lat
@ -292,6 +284,12 @@ class WeewxWXAPRSThread(threads.APRSDThread):
minutes = str(det.get("minutes")).zfill(2) minutes = str(det.get("minutes")).zfill(2)
det.get("seconds") det.get("seconds")
hundredths = str(det.get("hundredths")).split(".")[1] hundredths = str(det.get("hundredths")).split(".")[1]
LOG.debug(
f"LON degress {degrees} minutes {str(minutes)} "
"seconds {seconds} hundredths {hundredths} direction {direction}",
)
lon = f"{degrees}{str(minutes)}.{hundredths}{direction}" lon = f"{degrees}{str(minutes)}.{hundredths}{direction}"
return lon return lon
@ -311,7 +309,8 @@ class WeewxWXAPRSThread(threads.APRSDThread):
return retn_value return retn_value
def build_wx_packet(self, wx_data): def make_aprs_wx(self, wx_data):
# LOG.debug(wx_data)
wind_dir = float(wx_data.get("windDir", 0.00)) wind_dir = float(wx_data.get("windDir", 0.00))
wind_speed = float(wx_data.get("windSpeed_mph", 0.00)) wind_speed = float(wx_data.get("windSpeed_mph", 0.00))
wind_gust = float(wx_data.get("windGust_mph", 0.00)) wind_gust = float(wx_data.get("windGust_mph", 0.00))
@ -321,29 +320,46 @@ class WeewxWXAPRSThread(threads.APRSDThread):
rain_since_midnight = float(wx_data.get("day_Rain_in", 0.00)) rain_since_midnight = float(wx_data.get("day_Rain_in", 0.00))
humidity = float(wx_data.get("outHumidity", 0.00)) humidity = float(wx_data.get("outHumidity", 0.00))
# * 330.863886667 # * 330.863886667
# inHg * 33.8639 = mBar pressure = float(wx_data.get("relbarometer", 0.00)) * 10
pressure = float(wx_data.get("pressure_inHg", 0.00)) * 33.8639 * 10 LOG.info(f"wind_dir {wind_dir}")
return core.WeatherPacket( LOG.info(f"wind_speed {wind_speed}")
from_call=self.callsign, LOG.info(f"wind_gust {wind_gust}")
to_call="APRS", LOG.info(f"temperature {temperature}")
latitude=self.convert_latitude(float(self.latitude)), LOG.info(f"rain_last_hr {rain_last_hr}")
longitude=self.convert_longitude(float(self.longitude)), LOG.info(f"rain_last_24_hrs {rain_last_24_hrs}")
wind_direction=int(wind_dir), LOG.info(f"rain_since_midnight {rain_since_midnight}")
wind_speed=wind_speed, LOG.info(f"humidity {humidity}")
wind_gust=wind_gust, LOG.info(f"pressure {pressure}")
temperature=temperature,
rain_1h=rain_last_hr, # Assemble the weather data of the APRS packet
rain_24h=rain_last_24_hrs, return "{}/{}g{}t{}r{}p{}P{}h{}b{}".format(
rain_since_midnight=rain_since_midnight, self.str_or_dots(wind_dir, 3),
humidity=int(round(humidity)), self.str_or_dots(wind_speed, 3),
pressure=pressure, self.str_or_dots(wind_gust, 3),
comment="APRSD WX http://pypi.org/project/aprsd", self.str_or_dots(temperature, 3),
self.str_or_dots(rain_last_hr, 3),
self.str_or_dots(rain_last_24_hrs, 3),
self.str_or_dots(rain_since_midnight, 3),
self.str_or_dots(humidity, 2),
self.str_or_dots(pressure, 5),
) )
def build_packet(self, wx_data):
utc_datetime = datetime.datetime.now()
packet_data = "{}@{}z{}{}{}".format(
self.address,
utc_datetime.strftime("%d%H%M"),
self.position,
self.make_aprs_wx(wx_data),
"APRSD",
)
return packet_data
def loop(self): def loop(self):
now = datetime.datetime.now() now = datetime.datetime.now()
delta = now - self.last_send delta = now - self.last_send
max_timeout = {"seconds": self.report_interval} max_timeout = {"hours": 0.0, "minutes": 1, "seconds": 0}
max_delta = datetime.timedelta(**max_timeout) max_delta = datetime.timedelta(**max_timeout)
if delta >= max_delta: if delta >= max_delta:
if not self.wx_queue.empty(): if not self.wx_queue.empty():
@ -362,9 +378,11 @@ class WeewxWXAPRSThread(threads.APRSDThread):
# we have Weather now, so lets format the data # we have Weather now, so lets format the data
# and then send it out to APRS # and then send it out to APRS
packet = self.build_wx_packet(wx) raw_aprs_text = self.build_packet(wx)
packet = aprsd.messaging.RawMessage(raw_aprs_text)
LOG.debug(f"RAW WX Packet {packet}")
packet.retry_count = 1 packet.retry_count = 1
tx.send(packet) packet.send()
self.last_send = datetime.datetime.now() self.last_send = datetime.datetime.now()
time.sleep(1) time.sleep(1)
return True return True

View File

@ -1,4 +1,3 @@
pbr pbr
aprsd>=3.0.0 aprsd>=2.4.0
paho-mqtt paho-mqtt
oslo-config

View File

@ -19,10 +19,6 @@ description_file =
README.rst README.rst
summary = HAM Radio APRSD that reports weather from a weewx weather station. 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] [global]
setup-hooks = setup-hooks =
pbr.hooks.setup_hook pbr.hooks.setup_hook