2018-05-24 12:10:10 +00:00
#!/usr/bin/env python
#
# radiosonde_auto_rx - Configuration File Reader
#
# Copyright (C) 2018 Mark Jessop <vk5qi@rfhead.net>
# Released under GNU GPL v3 or later
#
2018-06-18 11:28:49 +00:00
import copy
2018-05-24 12:10:10 +00:00
import logging
2020-03-20 06:18:42 +00:00
import os
2018-05-24 12:10:10 +00:00
import traceback
import json
2022-09-20 22:57:39 +00:00
from configparser import RawConfigParser
2022-04-02 09:38:13 +00:00
from . sdr_wrappers import test_sdr
2018-05-24 12:10:10 +00:00
2018-06-29 11:25:33 +00:00
# Dummy initial config with some parameters we need to make the web interface happy.
2020-12-18 06:47:54 +00:00
global_config = {
" min_freq " : 400.0 ,
" max_freq " : 403.0 ,
" snr_threshold " : 10 ,
" station_lat " : 0.0 ,
" station_lon " : 0.0 ,
2021-05-14 11:58:42 +00:00
" station_alt " : 0.0 ,
2020-12-18 06:47:54 +00:00
}
2018-06-18 11:17:38 +00:00
2021-04-19 10:13:34 +00:00
# Web interface credentials
web_password = " none "
2020-10-02 02:46:10 +00:00
# Fixed minimum update rates for APRS & Habitat
# These are set to avoid congestion on the APRS-IS network, and on the Habitat server
# Please respect other users of these networks and leave these settings as they are.
2022-03-01 07:20:02 +00:00
MINIMUM_APRS_UPDATE_RATE = 30
2020-10-02 02:46:10 +00:00
MINIMUM_HABITAT_UPDATE_RATE = 30
2020-12-18 06:47:54 +00:00
2019-06-22 08:15:46 +00:00
def read_auto_rx_config ( filename , no_sdr_test = False ) :
2021-04-28 09:36:30 +00:00
""" Read an Auto-RX v2 Station Configuration File.
2018-05-24 12:10:10 +00:00
2021-04-28 09:36:30 +00:00
This function will attempt to parse a configuration file .
It will also confirm the accessibility of any SDRs specified in the config file .
2018-05-24 12:10:10 +00:00
2021-04-28 09:36:30 +00:00
Args :
filename ( str ) : Filename of the configuration file to read .
no_sdr_test ( bool ) : Skip testing the SDRs ( used for some unit tests )
2018-05-25 14:29:16 +00:00
2021-04-28 09:36:30 +00:00
Returns :
auto_rx_config ( dict ) : The configuration dictionary .
sdr_config ( dict ) : A dictionary with SDR parameters .
"""
2021-04-19 10:13:34 +00:00
global global_config , web_password
2020-12-18 06:47:54 +00:00
# Configuration Defaults:
auto_rx_config = {
# Log Settings
" per_sonde_log " : True ,
# Email Settings
" email_enabled " : False ,
#'email_error_notifications': False,
" email_smtp_server " : " localhost " ,
" email_smtp_port " : 25 ,
" email_smtp_authentication " : " None " ,
" email_smtp_login " : " None " ,
" email_smtp_password " : " None " ,
" email_from " : " sonde@localhost " ,
" email_to " : None ,
" email_subject " : " <type> Sonde launch detected on <freq>: <id> " ,
2021-12-31 08:11:35 +00:00
" email_nearby_landing_subject " : " Nearby Radiosonde Landing Detected - <id> " ,
2020-12-18 06:47:54 +00:00
# SDR Settings
2022-04-02 09:38:13 +00:00
" sdr_type " : " RTLSDR " ,
" sdr_hostname " : " localhost " ,
" sdr_port " : 5555 ,
2020-12-18 06:47:54 +00:00
" sdr_fm " : " rtl_fm " ,
" sdr_power " : " rtl_power " ,
2022-05-14 07:59:15 +00:00
" ss_iq_path " : " ./ss_iq " ,
" ss_power_path " : " ./ss_power " ,
2020-12-18 06:47:54 +00:00
" sdr_quantity " : 1 ,
# Search Parameters
" min_freq " : 400.4 ,
" max_freq " : 404.0 ,
" rx_timeout " : 120 ,
2021-04-28 09:35:43 +00:00
" only_scan " : [ ] ,
" never_scan " : [ ] ,
" always_scan " : [ ] ,
2022-05-14 08:30:54 +00:00
" always_decode " : [ ] ,
2020-12-18 06:47:54 +00:00
# Location Settings
" station_lat " : 0.0 ,
" station_lon " : 0.0 ,
" station_alt " : 0.0 ,
" station_code " : " SONDE " , # NOTE: This will not be read from the config file, but will be left in place for now
# as a default setting.
" gpsd_enabled " : False ,
" gpsd_host " : " localhost " ,
" gpsd_port " : 2947 ,
# Position Filter Settings
" max_altitude " : 50000 ,
" max_radius_km " : 1000 ,
" min_radius_km " : 0 ,
" radius_temporary_block " : False ,
2021-04-17 11:34:11 +00:00
# "sonde_time_threshold": 3, # Commented out to ensure warning message is shown.
2020-12-18 06:47:54 +00:00
# Habitat Settings
" habitat_enabled " : False ,
" habitat_upload_rate " : 30 ,
" habitat_uploader_callsign " : " SONDE_AUTO_RX " ,
" habitat_uploader_antenna " : " 1/4-wave " ,
" habitat_upload_listener_position " : False ,
" habitat_payload_callsign " : " <id> " ,
# APRS Settings
" aprs_enabled " : False ,
" aprs_upload_rate " : 30 ,
" aprs_user " : " N0CALL " ,
" aprs_pass " : " 00000 " ,
" aprs_server " : " rotate.aprs2.net " ,
" aprs_object_id " : " <id> " ,
#'aprs_use_custom_object_id': False,
" aprs_custom_comment " : " Radiosonde Auto-RX <freq> " ,
" aprs_position_report " : False ,
" station_beacon_enabled " : False ,
" station_beacon_rate " : 30 ,
" station_beacon_comment " : " radiosonde_auto_rx SondeGate v<version> " ,
" station_beacon_icon " : " /r " ,
# Web Settings,
" web_host " : " 0.0.0.0 " ,
" web_port " : 5000 ,
" web_archive_age " : 120 ,
2021-04-19 10:13:34 +00:00
" web_control " : False ,
2021-04-28 09:36:30 +00:00
# "web_password": "none", # Commented out to ensure warning message is shown
2020-12-18 06:47:54 +00:00
#'kml_refresh_rate': 10,
# Advanced Parameters
" search_step " : 800 ,
" snr_threshold " : 10 ,
" min_distance " : 1000 ,
" dwell_time " : 10 ,
" max_peaks " : 10 ,
" quantization " : 10000 ,
" decoder_spacing_limit " : 15000 ,
" synchronous_upload " : False ,
" scan_dwell_time " : 20 ,
" detect_dwell_time " : 5 ,
" scan_delay " : 10 ,
" payload_id_valid " : 5 ,
" temporary_block_time " : 60 ,
" rs41_drift_tweak " : False ,
" decoder_stats " : False ,
" ngp_tweak " : False ,
# Rotator Settings
" enable_rotator " : False ,
" rotator_update_rate " : 30 ,
" rotator_hostname " : " 127.0.0.1 " ,
" rotator_port " : 4533 ,
" rotation_threshold " : 5.0 ,
" rotator_homing_enabled " : False ,
" rotator_homing_delay " : 10 ,
" rotator_home_azimuth " : 0 ,
" rotator_home_elevation " : 0 ,
# OziExplorer Settings
" ozi_enabled " : False ,
" ozi_update_rate " : 5 ,
" ozi_port " : 55681 ,
" payload_summary_enabled " : False ,
" payload_summary_port " : 55672 ,
# Debugging settings
" save_detection_audio " : False ,
" save_decode_audio " : False ,
" save_decode_iq " : False ,
2021-06-03 11:10:18 +00:00
" save_raw_hex " : False ,
2022-10-22 22:50:36 +00:00
" save_system_log " : False ,
" enable_debug_logging " : False ,
2020-12-18 06:47:54 +00:00
# URL for the Habitat DB Server.
# As of July 2018 we send via sondehub.org, which will allow us to eventually transition away
# from using the habhub.org tracker, and leave it for use by High-Altitude Balloon Hobbyists.
# For now, sondehub.org just acts as a proxy to habhub.org.
# This setting is not exposed to users as it's only used for unit/int testing
" habitat_url " : " https://habitat.sondehub.org/ " ,
2021-01-29 11:05:48 +00:00
# New Sondehub DB Settings
2021-01-29 12:08:23 +00:00
" sondehub_enabled " : True ,
2021-02-21 01:25:44 +00:00
" sondehub_upload_rate " : 30 ,
2021-04-17 11:34:11 +00:00
# "sondehub_contact_email": "none@none.com" # Commented out to ensure a warning message is shown on startup
2023-08-14 05:28:26 +00:00
" wideband_sondes " : False , # Wideband sonde detection / decoding
2020-12-18 06:47:54 +00:00
}
try :
# Check the file exists.
if not os . path . isfile ( filename ) :
logging . critical ( " Config file %s does not exist! " % filename )
return None
config = RawConfigParser ( auto_rx_config )
config . read ( filename )
# Log Settings
auto_rx_config [ " per_sonde_log " ] = config . getboolean ( " logging " , " per_sonde_log " )
2019-03-23 10:16:15 +00:00
# Email Settings
2020-12-18 06:47:54 +00:00
if config . has_option ( " email " , " email_enabled " ) :
try :
auto_rx_config [ " email_enabled " ] = config . getboolean (
" email " , " email_enabled "
)
auto_rx_config [ " email_smtp_server " ] = config . get ( " email " , " smtp_server " )
auto_rx_config [ " email_smtp_port " ] = config . get ( " email " , " smtp_port " )
auto_rx_config [ " email_smtp_authentication " ] = config . get (
" email " , " smtp_authentication "
)
auto_rx_config [ " email_smtp_login " ] = config . get ( " email " , " smtp_login " )
auto_rx_config [ " email_smtp_password " ] = config . get (
" email " , " smtp_password "
)
auto_rx_config [ " email_from " ] = config . get ( " email " , " from " )
auto_rx_config [ " email_to " ] = config . get ( " email " , " to " )
auto_rx_config [ " email_subject " ] = config . get ( " email " , " subject " )
if auto_rx_config [ " email_smtp_authentication " ] not in [
" None " ,
" TLS " ,
" SSL " ,
] :
logging . error (
" Config - Invalid email authentication setting. Must be None, TLS or SSL. "
)
return None
except :
logging . error ( " Config - Invalid or missing email settings. Disabling. " )
auto_rx_config [ " email_enabled " ] = False
# SDR Settings
auto_rx_config [ " sdr_fm " ] = config . get ( " advanced " , " sdr_fm_path " )
auto_rx_config [ " sdr_power " ] = config . get ( " advanced " , " sdr_power_path " )
auto_rx_config [ " sdr_quantity " ] = config . getint ( " sdr " , " sdr_quantity " )
# Search Parameters
auto_rx_config [ " min_freq " ] = config . getfloat ( " search_params " , " min_freq " )
auto_rx_config [ " max_freq " ] = config . getfloat ( " search_params " , " max_freq " )
auto_rx_config [ " rx_timeout " ] = config . getint ( " search_params " , " rx_timeout " )
2021-04-28 09:36:30 +00:00
if (
config . has_option ( " search_params " , " only_scan " )
and config . get ( " search_params " , " only_scan " ) != " "
) : # check if user has new name for scan lists
2021-04-28 09:35:43 +00:00
auto_rx_config [ " only_scan " ] = json . loads (
config . get ( " search_params " , " only_scan " )
)
else :
logging . warning (
" Config - whitelist configuration has been deprecated and replaced with only_scan list "
)
auto_rx_config [ " only_scan " ] = json . loads (
config . get ( " search_params " , " whitelist " )
)
2021-04-28 09:36:30 +00:00
if (
config . has_option ( " search_params " , " never_scan " )
and config . get ( " search_params " , " never_scan " ) != " "
) : # check if user has new name for scan lists
2021-04-28 09:35:43 +00:00
auto_rx_config [ " never_scan " ] = json . loads (
config . get ( " search_params " , " never_scan " )
)
else :
logging . warning (
" Config - blacklist configuration has been deprecated and replaced with never_scan list "
)
2021-05-01 13:11:43 +00:00
auto_rx_config [ " never_scan " ] = json . loads (
2021-04-28 09:35:43 +00:00
config . get ( " search_params " , " blacklist " )
)
2021-04-28 09:36:30 +00:00
if (
config . has_option ( " search_params " , " always_scan " )
and config . get ( " search_params " , " always_scan " ) != " "
) : # check if user has new name for scan lists
2021-04-28 09:35:43 +00:00
auto_rx_config [ " always_scan " ] = json . loads (
config . get ( " search_params " , " always_scan " )
)
else :
logging . warning (
2021-04-28 09:56:37 +00:00
" Config - greylist configuration has been deprecated and replaced with always_scan list "
2021-04-28 09:35:43 +00:00
)
auto_rx_config [ " always_scan " ] = json . loads (
config . get ( " search_params " , " greylist " )
)
2020-12-18 06:47:54 +00:00
# Location Settings
auto_rx_config [ " station_lat " ] = config . getfloat ( " location " , " station_lat " )
auto_rx_config [ " station_lon " ] = config . getfloat ( " location " , " station_lon " )
auto_rx_config [ " station_alt " ] = config . getfloat ( " location " , " station_alt " )
2021-07-17 01:49:39 +00:00
if auto_rx_config [ " station_lat " ] > 90.0 or auto_rx_config [ " station_lat " ] < - 90.0 :
logging . critical ( " Config - Invalid Station Latitude! (Outside +/- 90 degrees!) " )
return None
if auto_rx_config [ " station_lon " ] > 180.0 or auto_rx_config [ " station_lon " ] < - 180.0 :
logging . critical ( " Config - Invalid Station Longitude! (Outside +/- 180 degrees!) " )
return None
2020-12-18 06:47:54 +00:00
# Position Filtering
auto_rx_config [ " max_altitude " ] = config . getint ( " filtering " , " max_altitude " )
auto_rx_config [ " max_radius_km " ] = config . getint ( " filtering " , " max_radius_km " )
# Habitat Settings
2021-04-23 11:06:59 +00:00
# Deprecated from v1.5.0
# auto_rx_config["habitat_enabled"] = config.getboolean(
# "habitat", "habitat_enabled"
# )
2021-04-28 09:36:30 +00:00
# auto_rx_config["habitat_upload_rate"] = config.getint("habitat", "upload_rate")
2020-12-18 06:47:54 +00:00
auto_rx_config [ " habitat_uploader_callsign " ] = config . get (
" habitat " , " uploader_callsign "
)
auto_rx_config [ " habitat_upload_listener_position " ] = config . getboolean (
" habitat " , " upload_listener_position "
)
auto_rx_config [ " habitat_uploader_antenna " ] = config . get (
" habitat " , " uploader_antenna "
) . strip ( )
2021-04-27 12:14:38 +00:00
2021-04-23 11:06:59 +00:00
# try: # Use the default configuration if not found
# auto_rx_config["habitat_url"] = config.get("habitat", "url")
# except:
# pass
2020-12-18 06:47:54 +00:00
2021-04-23 11:06:59 +00:00
# Deprecated from v1.5.0
# if auto_rx_config["habitat_upload_rate"] < MINIMUM_HABITAT_UPDATE_RATE:
# logging.warning(
# "Config - Habitat Update Rate clipped to minimum of %d seconds. Please be respectful of other users of Habitat."
# % MINIMUM_HABITAT_UPDATE_RATE
# )
# auto_rx_config["habitat_upload_rate"] = MINIMUM_HABITAT_UPDATE_RATE
2020-12-18 06:47:54 +00:00
# APRS Settings
auto_rx_config [ " aprs_enabled " ] = config . getboolean ( " aprs " , " aprs_enabled " )
auto_rx_config [ " aprs_upload_rate " ] = config . getint ( " aprs " , " upload_rate " )
auto_rx_config [ " aprs_user " ] = config . get ( " aprs " , " aprs_user " )
auto_rx_config [ " aprs_pass " ] = config . get ( " aprs " , " aprs_pass " )
auto_rx_config [ " aprs_server " ] = config . get ( " aprs " , " aprs_server " )
auto_rx_config [ " aprs_object_id " ] = config . get ( " aprs " , " aprs_object_id " )
auto_rx_config [ " aprs_custom_comment " ] = config . get (
" aprs " , " aprs_custom_comment "
)
2021-08-08 08:02:54 +00:00
# 2021-08-08 - Disable option for producing APRS position reports.
#auto_rx_config["aprs_position_report"] = config.getboolean(
# "aprs", "aprs_position_report"
#)
auto_rx_config [ " aprs_position_report " ] = False
2020-12-18 06:47:54 +00:00
auto_rx_config [ " station_beacon_enabled " ] = config . getboolean (
" aprs " , " station_beacon_enabled "
)
auto_rx_config [ " station_beacon_rate " ] = config . getint (
" aprs " , " station_beacon_rate "
)
auto_rx_config [ " station_beacon_comment " ] = config . get (
" aprs " , " station_beacon_comment "
)
auto_rx_config [ " station_beacon_icon " ] = config . get (
" aprs " , " station_beacon_icon "
)
if auto_rx_config [ " aprs_upload_rate " ] < MINIMUM_APRS_UPDATE_RATE :
logging . warning (
2022-03-01 07:20:02 +00:00
" Config - APRS Update Rate clipped to minimum of %d seconds. "
2020-12-18 06:47:54 +00:00
% MINIMUM_APRS_UPDATE_RATE
)
auto_rx_config [ " aprs_upload_rate " ] = MINIMUM_APRS_UPDATE_RATE
# OziPlotter Settings
auto_rx_config [ " ozi_enabled " ] = config . getboolean ( " oziplotter " , " ozi_enabled " )
auto_rx_config [ " ozi_update_rate " ] = config . getint (
" oziplotter " , " ozi_update_rate "
)
auto_rx_config [ " ozi_port " ] = config . getint ( " oziplotter " , " ozi_port " )
auto_rx_config [ " payload_summary_enabled " ] = config . getboolean (
" oziplotter " , " payload_summary_enabled "
)
auto_rx_config [ " payload_summary_port " ] = config . getint (
" oziplotter " , " payload_summary_port "
)
# Advanced Settings
auto_rx_config [ " search_step " ] = config . getfloat ( " advanced " , " search_step " )
auto_rx_config [ " snr_threshold " ] = config . getfloat ( " advanced " , " snr_threshold " )
auto_rx_config [ " min_distance " ] = config . getfloat ( " advanced " , " min_distance " )
auto_rx_config [ " dwell_time " ] = config . getint ( " advanced " , " dwell_time " )
auto_rx_config [ " quantization " ] = config . getint ( " advanced " , " quantization " )
auto_rx_config [ " max_peaks " ] = config . getint ( " advanced " , " max_peaks " )
auto_rx_config [ " scan_dwell_time " ] = config . getint ( " advanced " , " scan_dwell_time " )
auto_rx_config [ " detect_dwell_time " ] = config . getint (
" advanced " , " detect_dwell_time "
)
auto_rx_config [ " scan_delay " ] = config . getint ( " advanced " , " scan_delay " )
auto_rx_config [ " payload_id_valid " ] = config . getint (
" advanced " , " payload_id_valid "
)
auto_rx_config [ " synchronous_upload " ] = config . getboolean (
" advanced " , " synchronous_upload "
)
# Rotator Settings
auto_rx_config [ " rotator_enabled " ] = config . getboolean (
" rotator " , " rotator_enabled "
)
auto_rx_config [ " rotator_update_rate " ] = config . getint ( " rotator " , " update_rate " )
auto_rx_config [ " rotator_hostname " ] = config . get ( " rotator " , " rotator_hostname " )
auto_rx_config [ " rotator_port " ] = config . getint ( " rotator " , " rotator_port " )
auto_rx_config [ " rotator_homing_enabled " ] = config . getboolean (
" rotator " , " rotator_homing_enabled "
)
auto_rx_config [ " rotator_home_azimuth " ] = config . getfloat (
" rotator " , " rotator_home_azimuth "
)
auto_rx_config [ " rotator_home_elevation " ] = config . getfloat (
" rotator " , " rotator_home_elevation "
)
auto_rx_config [ " rotator_homing_delay " ] = config . getint (
" rotator " , " rotator_homing_delay "
)
auto_rx_config [ " rotation_threshold " ] = config . getfloat (
" rotator " , " rotation_threshold "
)
# Web interface settings.
auto_rx_config [ " web_host " ] = config . get ( " web " , " web_host " )
auto_rx_config [ " web_port " ] = config . getint ( " web " , " web_port " )
auto_rx_config [ " web_archive_age " ] = config . getint ( " web " , " archive_age " )
auto_rx_config [ " save_detection_audio " ] = config . getboolean (
" debugging " , " save_detection_audio "
)
auto_rx_config [ " save_decode_audio " ] = config . getboolean (
" debugging " , " save_decode_audio "
)
auto_rx_config [ " save_decode_iq " ] = config . getboolean (
" debugging " , " save_decode_iq "
)
# NOTE 2019-09-21: The station code will now be fixed at the default to avoid multiple iMet callsign issues.
# auto_rx_config['station_code'] = config.get('location', 'station_code')
# if len(auto_rx_config['station_code']) > 5:
# auto_rx_config['station_code'] = auto_rx_config['station_code'][:5]
# logging.warning("Config - Clipped station code to 5 digits: %s" % auto_rx_config['station_code'])
auto_rx_config [ " temporary_block_time " ] = config . getint (
" advanced " , " temporary_block_time "
)
# New demod tweaks - Added 2019-04-23
2021-03-27 04:53:26 +00:00
# Default to experimental decoders on for FSK/GFSK sondes...
2020-12-18 06:47:54 +00:00
auto_rx_config [ " experimental_decoders " ] = {
" RS41 " : True ,
" RS92 " : True ,
" DFM " : True ,
" M10 " : True ,
" M20 " : True ,
" IMET " : False ,
2021-03-19 10:18:35 +00:00
" IMET5 " : True ,
2020-12-18 06:47:54 +00:00
" LMS6 " : True ,
" MK2LMS " : False ,
2022-11-17 00:03:40 +00:00
" MEISEI " : True ,
2022-11-11 01:08:08 +00:00
" MTS01 " : False , # Until we test it
2021-04-17 11:34:11 +00:00
" MRZ " : False , # .... except for the MRZ, until we know it works.
2023-08-14 05:28:26 +00:00
" WXR301 " : False , # No fsk_demod chain for this yet.
2020-12-18 06:47:54 +00:00
" UDP " : False ,
}
2021-03-27 04:53:26 +00:00
2020-12-18 06:47:54 +00:00
auto_rx_config [ " decoder_spacing_limit " ] = config . getint (
" advanced " , " decoder_spacing_limit "
)
2023-08-14 05:28:26 +00:00
# Use 'experimental' (not really, anymore!) decoders for RS41, RS92, M10, DFM and LMS6-400.
# Don't allow overriding to the FM based decoders.
# auto_rx_config["experimental_decoders"]["RS41"] = config.getboolean(
# "advanced", "rs41_experimental"
# )
# auto_rx_config["experimental_decoders"]["RS92"] = config.getboolean(
# "advanced", "rs92_experimental"
# )
# auto_rx_config["experimental_decoders"]["M10"] = config.getboolean(
# "advanced", "m10_experimental"
# )
# auto_rx_config["experimental_decoders"]["DFM"] = config.getboolean(
# "advanced", "dfm_experimental"
# )
# auto_rx_config["experimental_decoders"]["LMS6"] = config.getboolean(
# "advanced", "lms6-400_experimental"
# )
2020-12-18 06:47:54 +00:00
try :
auto_rx_config [ " web_control " ] = config . getboolean ( " web " , " web_control " )
auto_rx_config [ " ngp_tweak " ] = config . getboolean ( " advanced " , " ngp_tweak " )
auto_rx_config [ " gpsd_enabled " ] = config . getboolean (
" location " , " gpsd_enabled "
)
auto_rx_config [ " gpsd_host " ] = config . get ( " location " , " gpsd_host " )
auto_rx_config [ " gpsd_port " ] = config . getint ( " location " , " gpsd_port " )
except :
logging . warning (
" Config - Did not find web control / ngp_tweak / gpsd options, using defaults (disabled) "
)
auto_rx_config [ " web_control " ] = False
auto_rx_config [ " ngp_tweak " ] = False
auto_rx_config [ " gpsd_enabled " ] = False
try :
auto_rx_config [ " min_radius_km " ] = config . getint (
" filtering " , " min_radius_km "
)
auto_rx_config [ " radius_temporary_block " ] = config . getboolean (
" filtering " , " radius_temporary_block "
)
except :
logging . warning (
" Config - Did not find minimum radius filter setting, using default (0km). "
)
auto_rx_config [ " min_radius_km " ] = 0
auto_rx_config [ " radius_temporary_block " ] = False
try :
auto_rx_config [ " aprs_use_custom_object_id " ] = config . getboolean (
" aprs " , " aprs_use_custom_object_id "
)
except :
logging . warning (
" Config - Did not find aprs_use_custom_object_id setting, using default (False) "
)
auto_rx_config [ " aprs_use_custom_object_id " ] = False
2020-12-22 23:11:13 +00:00
try :
2021-01-24 07:47:11 +00:00
auto_rx_config [ " aprs_port " ] = config . getint ( " aprs " , " aprs_port " )
2020-12-22 23:11:13 +00:00
except :
logging . warning (
2022-03-01 07:20:02 +00:00
" Config - Did not find aprs_port setting - using default of 14590. "
2020-12-22 23:11:13 +00:00
)
auto_rx_config [ " aprs_port " ] = 14590
2020-12-18 06:47:54 +00:00
try :
auto_rx_config [ " email_error_notifications " ] = config . getboolean (
2020-12-18 09:44:11 +00:00
" email " , " error_notifications "
)
auto_rx_config [ " email_launch_notifications " ] = config . getboolean (
" email " , " launch_notifications "
)
auto_rx_config [ " email_landing_notifications " ] = config . getboolean (
" email " , " landing_notifications "
)
auto_rx_config [ " email_landing_range_threshold " ] = config . getfloat (
" email " , " landing_range_threshold "
)
auto_rx_config [ " email_landing_altitude_threshold " ] = config . getfloat (
" email " , " landing_altitude_threshold "
2020-12-18 06:47:54 +00:00
)
except :
logging . warning (
2020-12-18 09:44:11 +00:00
" Config - Did not find new email settings (v1.3.3), using defaults "
2020-12-18 06:47:54 +00:00
)
auto_rx_config [ " email_error_notifications " ] = False
2020-12-18 09:44:11 +00:00
auto_rx_config [ " email_launch_notifications " ] = True
auto_rx_config [ " email_landing_notifications " ] = True
auto_rx_config [ " email_landing_range_threshold " ] = 30
auto_rx_config [ " email_landing_altitude_threshold " ] = 1000
2020-12-18 06:47:54 +00:00
try :
auto_rx_config [ " kml_refresh_rate " ] = config . getint (
" web " , " kml_refresh_rate "
)
except :
logging . warning (
" Config - Did not find kml_refresh_rate setting, using default (10 seconds). "
)
auto_rx_config [ " kml_refresh_rate " ] = 11
2021-01-29 11:05:48 +00:00
# New Sondehub db Settings
try :
auto_rx_config [ " sondehub_enabled " ] = config . getboolean (
2021-02-21 01:25:44 +00:00
" sondehub " , " sondehub_enabled "
)
auto_rx_config [ " sondehub_upload_rate " ] = config . getint (
" sondehub " , " sondehub_upload_rate "
2021-01-29 11:05:48 +00:00
)
2021-07-03 10:16:42 +00:00
if auto_rx_config [ " sondehub_upload_rate " ] < 10 :
logging . warning (
" Config - Clipped Sondehub update rate to lower limit of 10 seconds "
)
auto_rx_config [ " sondehub_upload_rate " ] = 10
2021-01-29 11:05:48 +00:00
except :
logging . warning (
2021-03-27 04:53:26 +00:00
" Config - Did not find sondehub_enabled setting, using default (enabled / 15 seconds). "
2021-01-29 11:05:48 +00:00
)
auto_rx_config [ " sondehub_enabled " ] = True
2021-02-21 01:25:44 +00:00
auto_rx_config [ " sondehub_upload_rate " ] = 15
2021-01-29 11:05:48 +00:00
2021-03-13 01:44:50 +00:00
try :
auto_rx_config [ " experimental_decoders " ] [ " MRZ " ] = config . getboolean (
" advanced " , " mrz_experimental "
)
except :
logging . warning (
" Config - Did not find MRZ decoder experimental decoder setting, using default (disabled). "
)
auto_rx_config [ " experimental_decoders " ] [ " MRZ " ] = False
2021-03-13 03:08:14 +00:00
try :
auto_rx_config [ " experimental_decoders " ] [ " IMET5 " ] = config . getboolean (
" advanced " , " imet54_experimental "
)
except :
logging . warning (
2021-03-19 10:18:35 +00:00
" Config - Did not find iMet-54 decoder experimental decoder setting, using default (enabled). "
2021-03-13 03:08:14 +00:00
)
2021-03-19 10:18:35 +00:00
auto_rx_config [ " experimental_decoders " ] [ " IMET5 " ] = True
2021-03-13 03:08:14 +00:00
2021-03-28 10:06:58 +00:00
# Sondehub Contact email (1.5.1)
try :
auto_rx_config [ " sondehub_contact_email " ] = config . get (
" sondehub " , " sondehub_contact_email "
)
except :
logging . warning (
" Config - Did not find Sondehub contact e-mail setting, using default (none). "
)
auto_rx_config [ " sondehub_contact_email " ] = " none@none.com "
2021-03-29 07:12:30 +00:00
# Sonde time threshold (1.5.1)
try :
auto_rx_config [ " sonde_time_threshold " ] = config . getfloat (
" filtering " , " sonde_time_threshold "
)
except :
logging . warning (
" Config - Did not find Sonde Time Threshold, using default (3 hrs). "
)
auto_rx_config [ " sonde_time_threshold " ] = 3
2021-03-28 10:06:58 +00:00
2021-04-19 10:13:34 +00:00
# Web control password
try :
2021-04-28 09:36:30 +00:00
auto_rx_config [ " web_password " ] = config . get ( " web " , " web_password " )
2021-04-19 10:13:34 +00:00
if auto_rx_config [ " web_password " ] == " none " :
2021-04-28 09:36:30 +00:00
logging . warning ( " Config - Web Password not set, disabling web control " )
2021-04-19 10:13:34 +00:00
auto_rx_config [ " web_control " ] = True
except :
logging . warning (
" Config - Did not find Web Password setting, using default (web control disabled) "
)
auto_rx_config [ " web_control " ] = False
auto_rx_config [ " web_password " ] = " none "
2021-06-03 11:10:18 +00:00
try :
auto_rx_config [ " save_raw_hex " ] = config . getboolean (
" debugging " , " save_raw_hex "
)
except :
logging . warning (
" Config - Did not find save_raw_hex setting, using default (disabled) "
)
auto_rx_config [ " save_raw_hex " ] = False
2021-07-31 12:17:03 +00:00
try :
auto_rx_config [ " experimental_decoders " ] [ " MK2LMS " ] = config . getboolean (
" advanced " , " lms6-1680_experimental "
)
except :
logging . warning (
" Config - Did not find lms6-1680_experimental setting, using default (disabled) "
)
auto_rx_config [ " experimental_decoders " ] [ " MK2LMS " ] = False
2021-04-19 10:13:34 +00:00
2021-12-31 08:11:35 +00:00
try :
auto_rx_config [ " email_nearby_landing_subject " ] = config . get (
" email " , " nearby_landing_subject "
)
except :
logging . warning (
" Config - Did not find email_nearby_landing_subject setting, using default "
)
auto_rx_config [ " email_nearby_landing_subject " ] = " Nearby Radiosonde Landing Detected - <id> "
2022-03-01 07:20:02 +00:00
# As of auto_rx version 1.5.10, we are limiting APRS output to only radiosondy.info,
# and only on the non-forwarding port.
# This decision was not made lightly, and is a result of the considerable amount of
# non-amateur traffic that radiosonde flights are causing within the APRS-IS network.
# Until some form of common format can be agreed to amongst the developers of *all*
# radiosonde tracking software to enable radiosonde telemetry to be de-duped,
# I have decided to help reduce the impact on the wider APRS-IS network by restricting
# the allowed servers and ports.
# If you are using another APRS-IS server that *does not* forward to the wider APRS-IS
# network and want it allowed, then please raise an issue at
# https://github.com/projecthorus/radiosonde_auto_rx/issues
#
# You are of course free to fork and modify this codebase as you wish, but please be aware
# that this goes against the wishes of the radiosonde_auto_rx developers to not be part
# of the bigger problem of APRS-IS congestion.
2023-06-24 13:52:38 +00:00
ALLOWED_APRS_SERVERS = [ " radiosondy.info " , " wettersonde.net " , " localhost " ]
ALLOWED_APRS_PORTS = [ 14580 , 14590 ]
2022-03-01 07:20:02 +00:00
if auto_rx_config [ " aprs_server " ] not in ALLOWED_APRS_SERVERS :
logging . warning (
" Please do not upload to servers which forward to the wider APRS-IS network and cause network congestion. Switching to default server of radiosondy.info. If you believe this to be in error, please raise an issue at https://github.com/projecthorus/radiosonde_auto_rx/issues "
)
auto_rx_config [ " aprs_server " ] = " radiosondy.info "
if auto_rx_config [ " aprs_port " ] not in ALLOWED_APRS_PORTS :
logging . warning (
" Please do not use APRS ports which forward data out to the wider APRS-IS network and cause network congestion. Switching to default port of 14590. If you believe this to be in error, please raise an issue at https://github.com/projecthorus/radiosonde_auto_rx/issues "
)
auto_rx_config [ " aprs_port " ] = 14590
2022-04-02 09:38:13 +00:00
# 1.6.0 - New SDR options
2022-10-25 20:24:16 +00:00
if not config . has_option ( " sdr " , " sdr_type " ) :
logging . warning (
" Config - Missing sdr_type configuration option, defaulting to RTLSDR. "
)
auto_rx_config [ " sdr_type " ] = " RTLSDR "
else :
2022-04-02 09:38:13 +00:00
auto_rx_config [ " sdr_type " ] = config . get ( " sdr " , " sdr_type " )
2022-10-25 20:24:16 +00:00
try :
2022-04-02 09:38:13 +00:00
auto_rx_config [ " sdr_hostname " ] = config . get ( " sdr " , " sdr_hostname " )
auto_rx_config [ " sdr_port " ] = config . getint ( " sdr " , " sdr_port " )
2022-05-14 07:59:15 +00:00
auto_rx_config [ " ss_iq_path " ] = config . get ( " advanced " , " ss_iq_path " )
auto_rx_config [ " ss_power_path " ] = config . get ( " advanced " , " ss_power_path " )
2022-04-02 09:38:13 +00:00
except :
2022-10-25 20:24:16 +00:00
logging . debug ( " Config - Did not find new sdr_type associated options. " )
2022-04-02 09:38:13 +00:00
2022-05-14 08:30:54 +00:00
try :
auto_rx_config [ " always_decode " ] = json . loads (
config . get ( " search_params " , " always_decode " )
)
except :
logging . debug (
" Config - No always_decode settings, defaulting to none. "
)
auto_rx_config [ " always_decode " ] = [ ]
2022-08-12 04:23:47 +00:00
try :
auto_rx_config [ " experimental_decoders " ] [ " MEISEI " ] = config . getboolean (
" advanced " , " meisei_experimental "
)
except :
logging . warning (
2022-11-22 20:52:49 +00:00
" Config - Did not find meisei_experimental setting, using default (enabled) "
2022-08-12 04:23:47 +00:00
)
2022-11-22 20:52:49 +00:00
auto_rx_config [ " experimental_decoders " ] [ " MEISEI " ] = True
2022-08-12 04:23:47 +00:00
2022-10-22 22:50:36 +00:00
try :
auto_rx_config [ " save_system_log " ] = config . getboolean (
" logging " , " save_system_log "
)
auto_rx_config [ " enable_debug_logging " ] = config . getboolean (
" logging " , " enable_debug_logging "
)
except :
logging . warning (
" Config - Did not find system / debug logging options, using defaults (disabled, unless set as a command-line option.) "
)
2023-05-18 08:45:47 +00:00
# 1.6.2 - Encrypted Sonde Email Notifications
try :
auto_rx_config [ " email_encrypted_sonde_notifications " ] = config . getboolean (
" email " , " encrypted_sonde_notifications "
)
except :
logging . warning (
" Config - Did not find encrypted_sonde_notifications setting (new in v1.6.2), using default (True) "
)
auto_rx_config [ " email_encrypted_sonde_notifications " ] = True
2022-05-14 08:30:54 +00:00
2023-08-14 05:28:26 +00:00
# 1.6.3 - Weathex WXR301d support
try :
auto_rx_config [ " wideband_sondes " ] = config . getboolean (
" advanced " , " wideband_sondes "
)
except :
logging . warning (
" Config - Missing wideband_sondes option (new in v1.6.3), using default (False) "
)
auto_rx_config [ " wideband_sondes " ] = False
2020-12-18 06:47:54 +00:00
# If we are being called as part of a unit test, just return the config now.
if no_sdr_test :
return auto_rx_config
2022-04-02 09:38:13 +00:00
# Now we enumerate our SDRs.
2020-12-18 06:47:54 +00:00
auto_rx_config [ " sdr_settings " ] = { }
2022-04-02 09:38:13 +00:00
if auto_rx_config [ " sdr_type " ] == " RTLSDR " :
# Multiple RTLSDRs in use - we need to read in each SDRs settings.
for _n in range ( 1 , auto_rx_config [ " sdr_quantity " ] + 1 ) :
_section = " sdr_ %d " % _n
try :
_device_idx = config . get ( _section , " device_idx " )
_ppm = round ( config . getfloat ( _section , " ppm " ) )
_gain = config . getfloat ( _section , " gain " )
_bias = config . getboolean ( _section , " bias " )
if ( auto_rx_config [ " sdr_quantity " ] > 1 ) and ( _device_idx == " 0 " ) :
logging . critical (
" Config - RTLSDR Device ID of 0 used with a multi-SDR configuration. Go read the warning in the config file! "
)
return None
# See if the SDR exists.
_sdr_valid = test_sdr ( sdr_type = " RTLSDR " , rtl_device_idx = _device_idx )
if _sdr_valid :
auto_rx_config [ " sdr_settings " ] [ _device_idx ] = {
" ppm " : _ppm ,
" gain " : _gain ,
" bias " : _bias ,
" in_use " : False ,
" task " : None ,
}
logging . info ( " Config - Tested RTLSDR # %s OK " % _device_idx )
else :
logging . warning ( " Config - RTLSDR # %s invalid. " % _device_idx )
except Exception as e :
logging . error (
" Config - Error parsing RTLSDR %d config - %s " % ( _n , str ( e ) )
2020-12-18 06:47:54 +00:00
)
2022-04-02 09:38:13 +00:00
continue
elif auto_rx_config [ " sdr_type " ] == " SpyServer " :
# Test access to the SpyServer
_sdr_ok = test_sdr (
sdr_type = auto_rx_config [ " sdr_type " ] ,
sdr_hostname = auto_rx_config [ " sdr_hostname " ] ,
2022-05-14 07:59:15 +00:00
sdr_port = auto_rx_config [ " sdr_port " ] ,
ss_iq_path = auto_rx_config [ " ss_iq_path " ] ,
ss_power_path = auto_rx_config [ " ss_power_path " ] ,
2022-12-17 15:15:03 +00:00
check_freq = 1e6 * ( auto_rx_config [ " max_freq " ] + auto_rx_config [ " min_freq " ] ) / 2.0 ,
2022-04-02 09:38:13 +00:00
)
if not _sdr_ok :
logging . critical ( f " Config - Could not contact SpyServer { auto_rx_config [ ' sdr_hostname ' ] } : { auto_rx_config [ ' sdr_port ' ] } . Exiting. " )
return None
for _n in range ( 1 , auto_rx_config [ " sdr_quantity " ] + 1 ) :
_sdr_name = f " SPY { _n : 02d } "
auto_rx_config [ " sdr_settings " ] [ _sdr_name ] = {
" ppm " : 0 ,
" gain " : 0 ,
" bias " : 0 ,
" in_use " : False ,
" task " : None ,
}
elif auto_rx_config [ " sdr_type " ] == " KA9Q " :
# Test access to the SpyServer
_sdr_ok = test_sdr (
sdr_type = auto_rx_config [ " sdr_type " ] ,
sdr_hostname = auto_rx_config [ " sdr_hostname " ] ,
sdr_port = auto_rx_config [ " sdr_port " ]
)
if not _sdr_ok :
logging . critical ( f " Config - Could not contact KA9Q Server { auto_rx_config [ ' sdr_hostname ' ] } : { auto_rx_config [ ' sdr_port ' ] } . Exiting. " )
return None
for _n in range ( 1 , auto_rx_config [ " sdr_quantity " ] + 1 ) :
_sdr_name = f " KA9Q { _n : 02d } "
auto_rx_config [ " sdr_settings " ] [ _sdr_name ] = {
" ppm " : 0 ,
" gain " : 0 ,
" bias " : 0 ,
" in_use " : False ,
" task " : None ,
}
logging . critical ( " Config - KA9Q SDR Support not implemented yet - exiting. " )
return None
else :
logging . critical ( f " Config - Unknown SDR Type { auto_rx_config [ ' sdr_type ' ] } - exiting. " )
return None
2020-12-18 06:47:54 +00:00
# Sanity checks when using more than one SDR
if ( len ( auto_rx_config [ " sdr_settings " ] . keys ( ) ) > 1 ) and (
auto_rx_config [ " aprs_object_id " ] != " <id> "
) :
logging . critical (
" Fixed APRS object ID used in a multi-SDR configuration. Go read the warnings in the config file! "
)
return None
if ( len ( auto_rx_config [ " sdr_settings " ] . keys ( ) ) > 1 ) and (
auto_rx_config [ " rotator_enabled " ]
) :
logging . critical (
" Rotator enabled in a multi-SDR configuration. Go read the warnings in the config file! "
)
return None
# TODO: Revisit this limitation once the OziPlotter output sub-module is complete.
if ( len ( auto_rx_config [ " sdr_settings " ] . keys ( ) ) > 1 ) and auto_rx_config [
" ozi_enabled "
] :
logging . critical ( " Oziplotter output enabled in a multi-SDR configuration. " )
return None
if len ( auto_rx_config [ " sdr_settings " ] . keys ( ) ) == 0 :
# We have no SDRs to use!!
logging . error ( " Config - No working SDRs! Cannot run... " )
2023-07-03 13:44:47 +00:00
raise SystemError ( " No working SDRs! " )
2020-12-18 06:47:54 +00:00
else :
# Create a global copy of the configuration file at this point
global_config = copy . deepcopy ( auto_rx_config )
# Excise some sensitive parameters from the global config.
global_config . pop ( " email_smtp_login " )
global_config . pop ( " email_smtp_password " )
global_config . pop ( " email_smtp_server " )
2021-04-17 12:09:28 +00:00
global_config . pop ( " email_smtp_port " )
global_config . pop ( " email_from " )
global_config . pop ( " email_to " )
global_config . pop ( " email_smtp_authentication " )
2021-04-19 10:13:34 +00:00
global_config . pop ( " sondehub_contact_email " )
global_config . pop ( " web_password " )
web_password = auto_rx_config [ " web_password " ]
2020-12-18 06:47:54 +00:00
return auto_rx_config
2023-07-03 13:44:47 +00:00
except SystemError as e :
raise e
2020-12-18 06:47:54 +00:00
except :
traceback . print_exc ( )
logging . error ( " Could not parse config file. " )
return None
if __name__ == " __main__ " :
2021-04-28 09:36:30 +00:00
""" Quick test script to attempt to read in a config file. """
2020-12-18 06:47:54 +00:00
import sys , pprint
logging . basicConfig (
format = " %(asctime)s %(levelname)s : %(message)s " , level = logging . DEBUG
)
config = read_auto_rx_config ( sys . argv [ 1 ] )
pprint . pprint ( global_config )