kopia lustrzana https://github.com/glidernet/python-ogn-client
weather message
Pattern for weather message. Target message example: XUDN>WX,TCPIP,qAS,R8LAY-13:;XUDN *131019z5657.96N/04104.25E_236/007c236s007g013t029h89b10270Weather:overcast clouds; Cloudiness:99%; Wind:236° 3.1 m/s (5.8 m/s); Temp:-1.6°C; Humidity:89%; Dew point:-3.2°C; Pressure:1027 hPa; Visibility:10 km; Daylight:[11:38][06:36-18:14]pull/122/head
rodzic
a19209b3d8
commit
895a1b60ac
|
@ -2,7 +2,7 @@ import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from ogn.parser.utils import createTimestamp, parseAngle, KNOTS_TO_MS, KPH_TO_MS, FEETS_TO_METER, INCH_TO_MM, fahrenheit_to_celsius, CheapRuler, normalized_quality
|
from ogn.parser.utils import createTimestamp, parseAngle, KNOTS_TO_MS, KPH_TO_MS, FEETS_TO_METER, INCH_TO_MM, fahrenheit_to_celsius, CheapRuler, normalized_quality
|
||||||
from ogn.parser.pattern import PATTERN_APRS, PATTERN_APRS_POSITION, PATTERN_APRS_POSITION_WEATHER, PATTERN_APRS_STATUS, PATTERN_SERVER
|
from ogn.parser.pattern import PATTERN_APRS, PATTERN_APRS_POSITION, PATTERN_APRS_POSITION_WEATHER, PATTERN_APRS_POSITION_WEATHER_WX, PATTERN_APRS_STATUS, PATTERN_SERVER
|
||||||
from ogn.parser.exceptions import AprsParseError
|
from ogn.parser.exceptions import AprsParseError
|
||||||
|
|
||||||
from ogn.parser.aprs_comment.ogn_parser import OgnParser
|
from ogn.parser.aprs_comment.ogn_parser import OgnParser
|
||||||
|
@ -20,19 +20,15 @@ from ogn.parser.aprs_comment.safesky_parser import SafeskyParser
|
||||||
from ogn.parser.aprs_comment.generic_parser import GenericParser
|
from ogn.parser.aprs_comment.generic_parser import GenericParser
|
||||||
|
|
||||||
positions = {}
|
positions = {}
|
||||||
server_timestamp = None
|
|
||||||
|
|
||||||
|
|
||||||
def parse(aprs_message, reference_timestamp=None, calculate_relations=False, use_server_timestamp=True):
|
def parse(aprs_message, reference_timestamp=None, calculate_relations=False):
|
||||||
global positions
|
global positions
|
||||||
global server_timestamp
|
|
||||||
|
|
||||||
if use_server_timestamp is True:
|
if reference_timestamp is None:
|
||||||
reference_timestamp = server_timestamp or datetime.utcnow()
|
|
||||||
elif reference_timestamp is None:
|
|
||||||
reference_timestamp = datetime.utcnow()
|
reference_timestamp = datetime.utcnow()
|
||||||
|
|
||||||
message = parse_aprs(aprs_message, reference_timestamp=reference_timestamp)
|
message = parse_aprs(aprs_message, reference_timestamp)
|
||||||
if message['aprs_type'] == 'position' or message['aprs_type'] == 'status':
|
if message['aprs_type'] == 'position' or message['aprs_type'] == 'status':
|
||||||
message.update(parse_comment(message['comment'],
|
message.update(parse_comment(message['comment'],
|
||||||
dstcall=message['dstcall'],
|
dstcall=message['dstcall'],
|
||||||
|
@ -46,9 +42,6 @@ def parse(aprs_message, reference_timestamp=None, calculate_relations=False, use
|
||||||
message['bearing'] = cheap_ruler.bearing((message['longitude'], message['latitude']), positions[message['receiver_name']])
|
message['bearing'] = cheap_ruler.bearing((message['longitude'], message['latitude']), positions[message['receiver_name']])
|
||||||
message['normalized_quality'] = normalized_quality(message['distance'], message['signal_quality']) if 'signal_quality' in message else None
|
message['normalized_quality'] = normalized_quality(message['distance'], message['signal_quality']) if 'signal_quality' in message else None
|
||||||
|
|
||||||
if message['aprs_type'] == 'server':
|
|
||||||
server_timestamp = message['timestamp']
|
|
||||||
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,13 +69,14 @@ def parse_aprs(message, reference_timestamp=None):
|
||||||
else:
|
else:
|
||||||
match = re.search(PATTERN_APRS, message)
|
match = re.search(PATTERN_APRS, message)
|
||||||
if match:
|
if match:
|
||||||
aprs_type = 'position' if match.group('aprs_type') == '/' else 'status' if match.group('aprs_type') == '>' else 'unknown'
|
result.update({'aprs_type': 'unknown'})
|
||||||
result.update({'aprs_type': aprs_type})
|
aprs_type = 'position' if match.group('aprs_type') == '/' else 'status' if match.group('aprs_type') == '>' else 'weather_wx' if match.group('aprs_type') == ';' else 'unknown'
|
||||||
aprs_body = match.group('aprs_body')
|
aprs_body = match.group('aprs_body')
|
||||||
if aprs_type == 'position':
|
if aprs_type == 'position':
|
||||||
match_position = re.search(PATTERN_APRS_POSITION, aprs_body)
|
match_position = re.search(PATTERN_APRS_POSITION, aprs_body)
|
||||||
if match_position:
|
if match_position:
|
||||||
result.update({
|
result.update({
|
||||||
|
'aprs_type': 'position',
|
||||||
'name': match.group('callsign'),
|
'name': match.group('callsign'),
|
||||||
'dstcall': match.group('dstcall'),
|
'dstcall': match.group('dstcall'),
|
||||||
'relay': match.group('relay') if match.group('relay') else None,
|
'relay': match.group('relay') if match.group('relay') else None,
|
||||||
|
@ -132,12 +126,12 @@ def parse_aprs(message, reference_timestamp=None):
|
||||||
'comment': match_position_weather.group('comment') if match_position_weather.group('comment') else "",
|
'comment': match_position_weather.group('comment') if match_position_weather.group('comment') else "",
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
|
|
||||||
raise AprsParseError(message)
|
raise AprsParseError(message)
|
||||||
elif aprs_type == 'status':
|
elif aprs_type == 'status':
|
||||||
match_status = re.search(PATTERN_APRS_STATUS, aprs_body)
|
match_status = re.search(PATTERN_APRS_STATUS, aprs_body)
|
||||||
if match_status:
|
if match_status:
|
||||||
result.update({
|
result.update({
|
||||||
|
'aprs_type': 'status',
|
||||||
'name': match.group('callsign'),
|
'name': match.group('callsign'),
|
||||||
'dstcall': match.group('dstcall'),
|
'dstcall': match.group('dstcall'),
|
||||||
'receiver_name': match.group('receiver'),
|
'receiver_name': match.group('receiver'),
|
||||||
|
@ -145,6 +139,37 @@ def parse_aprs(message, reference_timestamp=None):
|
||||||
'comment': match_status.group('comment') if match_status.group('comment') else ""})
|
'comment': match_status.group('comment') if match_status.group('comment') else ""})
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(message)
|
raise NotImplementedError(message)
|
||||||
|
elif aprs_type == 'weather_wx':
|
||||||
|
match_position_weather = re.search(PATTERN_APRS_POSITION_WEATHER_WX, aprs_body)
|
||||||
|
if match_position_weather:
|
||||||
|
result.update({
|
||||||
|
'aprs_type': 'position_weather',
|
||||||
|
|
||||||
|
'name': match_position_weather.group('callsign').strip(),
|
||||||
|
'dstcall': match.group('dstcall'),
|
||||||
|
'relay': match.group('relay') if match.group('relay') else None,
|
||||||
|
'receiver_name': match.group('receiver'),
|
||||||
|
'timestamp': createTimestamp(match_position_weather.group('time'), reference_timestamp),
|
||||||
|
'latitude': parseAngle('0' + match_position_weather.group('latitude')) * # noqa: W504
|
||||||
|
(-1 if match_position_weather.group('latitude_sign') == 'S' else 1),
|
||||||
|
'symboltable': match_position_weather.group('symbol_table'),
|
||||||
|
'longitude': parseAngle(match_position_weather.group('longitude')) * # noqa: W504
|
||||||
|
(-1 if match_position_weather.group('longitude_sign') == 'W' else 1),
|
||||||
|
'symbolcode': match_position_weather.group('symbol'),
|
||||||
|
|
||||||
|
'wind_direction': int(match_position_weather.group('wind_direction')) if match_position_weather.group('wind_direction') != None else None,
|
||||||
|
'wind_speed': int(match_position_weather.group('wind_speed')) * KNOTS_TO_MS / KPH_TO_MS if match_position_weather.group('wind_speed') != None else None,
|
||||||
|
'wind_speed_peak': int(match_position_weather.group('wind_speed_peak')) * KNOTS_TO_MS / KPH_TO_MS if match_position_weather.group('wind_speed_peak') != None else None,
|
||||||
|
'temperature': fahrenheit_to_celsius(float(match_position_weather.group('temperature'))) if match_position_weather.group('temperature') != None else None,
|
||||||
|
'rainfall_1h': int(match_position_weather.group('rainfall_1h')) / 100.0 * INCH_TO_MM if match_position_weather.group('rainfall_1h') else None,
|
||||||
|
'rainfall_24h': int(match_position_weather.group('rainfall_24h')) / 100.0 * INCH_TO_MM if match_position_weather.group('rainfall_24h') else None,
|
||||||
|
'humidity': int(match_position_weather.group('humidity')) * 0.01 if match_position_weather.group('humidity') else None,
|
||||||
|
'barometric_pressure': int(match_position_weather.group('barometric_pressure'))/10 if match_position_weather.group('barometric_pressure') else None,
|
||||||
|
|
||||||
|
'comment': match_position_weather.group('comment') if match_position_weather.group('comment') else "",
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
else:
|
else:
|
||||||
raise AprsParseError(message)
|
raise AprsParseError(message)
|
||||||
|
|
||||||
|
@ -171,6 +196,8 @@ dstcall_parser_mapping = {'APRS': OgnParser(),
|
||||||
|
|
||||||
|
|
||||||
def parse_comment(aprs_comment, dstcall='APRS', aprs_type="position"):
|
def parse_comment(aprs_comment, dstcall='APRS', aprs_type="position"):
|
||||||
|
print('parse_comment')
|
||||||
|
print(aprs_comment)
|
||||||
parser = dstcall_parser_mapping.get(dstcall)
|
parser = dstcall_parser_mapping.get(dstcall)
|
||||||
if parser:
|
if parser:
|
||||||
return parser.parse(aprs_comment, aprs_type)
|
return parser.parse(aprs_comment, aprs_type)
|
||||||
|
|
Ładowanie…
Reference in New Issue