-
Notifications
You must be signed in to change notification settings - Fork 9
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
0 parents
commit 8c6e067
Showing
4 changed files
with
212 additions
and
0 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,123 @@ | ||
from datetime import datetime | ||
import os | ||
|
||
import weeutil.weeutil | ||
import weewx.engine | ||
import weewx.units | ||
|
||
|
||
class APRS(weewx.engine.StdService): | ||
def __init__(self, engine, config_dict): | ||
super(APRS, self).__init__(engine, config_dict) | ||
conf = config_dict['APRS'] | ||
self._output_filename = conf['output_filename'] | ||
self._output_filename_tmp = self._output_filename + '.tmp' | ||
self._include_position = int(conf.get('include_position', 0)) | ||
self._symbol_table = conf.get('symbol_table', '/') | ||
self._symbol_code = conf.get('symbol_code', '_') | ||
self._comment = conf.get('comment', '') | ||
|
||
self._message_type = '_' # Weather report (no position) | ||
self._time_format = '%m%d%H%M' | ||
self._latitude = None | ||
self._longitude = None | ||
self._wind_direction_marker = 'c' | ||
self._wind_speed_marker = 's' | ||
if self._include_position: | ||
# Position with timestamp (no APRS messaging) | ||
self._message_type = '/' | ||
self._time_format = '%d%H%Mz' | ||
self._latitude = ''.join(weeutil.weeutil.latlon_string( | ||
self.engine.stn_info.latitude_f, | ||
('N', 'S'), 'lat')) | ||
self._longitude = ''.join(weeutil.weeutil.latlon_string( | ||
self.engine.stn_info.longitude_f, | ||
('E', 'W'), 'lon')) | ||
self._wind_direction_marker = '' | ||
self._wind_speed_marker = '/' | ||
|
||
self.bind(weewx.NEW_ARCHIVE_RECORD, self._handle_new_archive_record) | ||
|
||
def _handle_new_archive_record(self, event): | ||
"""Generate a positionless APRS weather report and write it to a file""" | ||
record = event.record | ||
data = [ | ||
self._message_type, | ||
datetime.strftime( | ||
datetime.utcfromtimestamp(record['dateTime']), | ||
self._time_format), | ||
] | ||
if self._include_position: | ||
data.append(self._latitude) | ||
data.append(self._symbol_table) | ||
data.append(self._longitude) | ||
data.append(self._symbol_code) | ||
|
||
if record.get('windDir') is not None: | ||
# Wind direction (in degrees) | ||
# Wind from North needs to be reported as 360. | ||
# Wind from 0 means N/A in the APRS standard. | ||
# We need to make sure it does not get to 0, so do not rely on | ||
# the format string rouding, but round to no decimals before | ||
# comparing with 0 | ||
wind_dir = int(round(record['windDir'], 0)) | ||
if wind_dir <= 0: | ||
wind_dir = 360 | ||
data.append('%s%03u' % (self._wind_direction_marker, | ||
wind_dir)) | ||
else: | ||
data.append('%s...' % self._wind_direction_marker) | ||
|
||
if record.get('wind_average') is not None: | ||
# Sustained one-minute wind speed (in mph) | ||
data.append('%s%03.f' % (self._wind_speed_marker, | ||
record['wind_average'])) | ||
else: | ||
data.append('%s...' % self._wind_speed_marker) | ||
|
||
if record.get('windGust') is not None: | ||
# Gust (peak wind speed in mph in the last 5 minutes) | ||
data.append('g%03.f' % record['wind_average']) | ||
else: | ||
data.append('g...') | ||
|
||
if record.get('outTemp') is not None: | ||
# Temperature (in degrees Fahrenheit) | ||
data.append('t%03.f' % record['outTemp']) | ||
else: | ||
data.append('t...') | ||
|
||
if record.get('rainRate') is not None: | ||
# Rainfall (in hundredths of an inch) in the last hour | ||
data.append('r%03.f' % (record['rainRate'] * 100)) | ||
|
||
if record.get('daily_rain') is not None: | ||
# Rainfall (in hundredths of an inch) since midnight | ||
data.append('P%03.f' % (record['daily_rain'] * 100)) | ||
|
||
if record.get('outHumidity') is not None: | ||
# Humidity (in %. 00 = 100%) | ||
# We need to make sure it does not get over 99, so do not rely on | ||
# the format string rouding, but round to no decimals before | ||
# comparing with 100 | ||
humidity = int(round(record['outHumidity'], 0)) | ||
if humidity >= 100: | ||
humidity = 0 | ||
data.append('h%02u' % humidity) | ||
|
||
if record.get('barometer') is not None: | ||
# Barometric pressure (in tenths of millibars/tenths of hPascal) | ||
barometer = weewx.units.convert( | ||
(record['barometer'], 'inHg', 'group_pressure'), | ||
'mbar')[0] * 10 | ||
data.append('b%05.f' % barometer) | ||
|
||
if self._comment: | ||
data.append(self._comment) | ||
|
||
wxdata = ''.join(data) | ||
|
||
# Atomic update of self._output_filename. | ||
with open(self._output_filename_tmp, 'w') as f: | ||
f.write(wxdata) | ||
os.rename(self._output_filename_tmp, self._output_filename) |
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,27 @@ | ||
from setup import ExtensionInstaller | ||
|
||
|
||
def loader(): | ||
return APRSInstaller() | ||
|
||
|
||
class APRSInstaller(ExtensionInstaller): | ||
def __init__(self): | ||
super(APRSInstaller, self).__init__( | ||
version='0.1', | ||
name='aprs', | ||
description='Write archive data in APRS positionless format.', | ||
author='Ludovico Cavedon (K6LUD)', | ||
author_email='[email protected]', | ||
process_services='user.aprs.APRS', | ||
config={ | ||
'APRS': { | ||
'output_filename': '/dev/shm/aprs.pkt', | ||
'include_position': 0, | ||
'symbol_table': '/', | ||
'symbol_code': '_', | ||
'comment': '', | ||
}, | ||
}, | ||
files=[('bin/user', ['bin/user/aprs.py'])] | ||
) |
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,19 @@ | ||
Copyright (c) 2016 Ludovico Cavedon (K6LUD) <[email protected]> | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
this software and associated documentation files (the "Software"), to deal in | ||
the Software without restriction, including without limitation the rights to | ||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
of the Software, and to permit persons to whom the Software is furnished to do | ||
so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
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,43 @@ | ||
aprs - weewx extension for generating APRS-compliant packets | ||
|
||
This weewx[1] extension allows the generation of APRS-compliant packets | ||
containing weather information collected by weewx. | ||
This extension was written for the purpose of easy integration with aprx[2]. | ||
When this extension is enabled, weewx will generate a new APRS packet every | ||
StdArchive.archive_interval seconds. | ||
|
||
Installation: | ||
wee_extension --install aprs.tar.gz | ||
|
||
Configuration: | ||
[APRS] | ||
# The APRS weather packet payload will be written in output_filename | ||
output_filename = /dev/shm/aprs.pkt | ||
# include_position: | ||
# 0: a positionless weather report will be generated (default) | ||
# 1: a weather report with position will be generated | ||
include_position = 1 | ||
# In case of a position packet, symbol_table and symbol_code will | ||
# determine what symbol will be used to display the station (e.g. on | ||
# aprs.fi). "/_" is the default and will generate a blue WX icon. | ||
# A positionless packet does not include a symbol specification and | ||
# these two settings will be ignored | ||
symbol_table = / | ||
symbol_code = _ | ||
# The string in comment will be appended to the end of the packet. | ||
comment = SBARC U2k WX station | ||
|
||
Example of integration in the aprx configuration: | ||
<beacon> | ||
beaconmode both # Send packet via APRS-IS and radio. | ||
cycle-size 5m | ||
beacon srccall N0CALL-1 via WIDE2-1 file "/dev/shm/aprs.pkt" | ||
</beacon> | ||
|
||
Note: this configuration has the problem that aprx and weewx are not | ||
syncronized, so aprx may send out the same packet twice or miss one from time | ||
to time. | ||
|
||
|
||
[1] http://www.weewx.com/ | ||
[2] http://thelifeofkenneth.com/aprx/ |