Skip to content

Commit

Permalink
Initial meisei IMS-100 support.
Browse files Browse the repository at this point in the history
  • Loading branch information
darksidelemm committed Sep 8, 2019
1 parent df18134 commit d56ab18
Show file tree
Hide file tree
Showing 14 changed files with 3,927 additions and 137 deletions.
6 changes: 5 additions & 1 deletion auto_rx/auto_rx.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,12 @@ def telemetry_filter(telemetry):
# Regex to check DFM06/09/15/17 callsigns. Also catches the 'unknown' types (xC, xD, etc)
dfm_callsign_valid = re.match(r'DFM[01x][5679CD]-\d{6}', _serial)

# Check Meisei sonde callsigns for validity.
# meisei_ims returns a callsign of IMS100-0 until it receives the serial number, so we filter based on the 0 being present or not.
meisei_callsign_valid = int(_serial.split('-')[1]) != 0

# If Vaisala or DFMs, check the callsigns are valid. If M10, iMet or LMS6, just pass it through.
if vaisala_callsign_valid or dfm_callsign_valid or ('M10' in telemetry['type']) or ('MK2LMS' in telemetry['type']) or ('LMS6' in telemetry['type']) or ('iMet' in telemetry['type']):
if vaisala_callsign_valid or dfm_callsign_valid or meisei_callsign_valid or ('M10' in telemetry['type']) or ('MK2LMS' in telemetry['type']) or ('LMS6' in telemetry['type']) or ('iMet' in telemetry['type']):
return True
else:
_id_msg = "Payload ID %s is invalid." % telemetry['id']
Expand Down
2 changes: 1 addition & 1 deletion auto_rx/autorx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# MINOR - New sonde type support, other fairly big changes that may result in telemetry or config file incompatability issus.
# PATCH - Small changes, or minor feature additions.

__version__ = "1.1.3.3"
__version__ = "1.1.4-beta1"


# Global Variables
Expand Down
9 changes: 9 additions & 0 deletions auto_rx/autorx/aprs.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ def telemetry_to_aprs_position(sonde_data, object_name="<id>", aprs_comment="BOM
_id_hex = hex(_id_suffix).upper()
_object_name = "LMS6" + _id_hex[-5:]

elif 'MEISEI' in sonde_data['type']:
# Convert the serial number to an int
_meisei_id = int(sonde_data['id'].split('-')[-1])
_id_suffix = hex(_meisei_id).upper().split('0X')[1]
# Clip to 6 hex digits, in case we end up with more for some reason.
if len(_id_suffix) > 6:
_id_suffix = _id_suffix[-6:]
_object_name = "IMS" + _id_suffix

# New Sonde types will be added in here.
else:
# Unknown sonde type, don't know how to handle this yet.
Expand Down
2 changes: 1 addition & 1 deletion auto_rx/autorx/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def read_auto_rx_config(filename, no_sdr_test=False):

# New demod tweaks - Added 2019-04-23
# Default to all experimental decoders off.
auto_rx_config['experimental_decoders'] = {'RS41': False, 'RS92': False, 'DFM': False, 'M10': False, 'iMet': False, 'LMS6': True, 'MK2LMS': False}
auto_rx_config['experimental_decoders'] = {'RS41': False, 'RS92': False, 'DFM': False, 'M10': False, 'iMet': False, 'LMS6': True, 'MK2LMS': False, 'MEISEI': False}
auto_rx_config['rs41_drift_tweak'] = config.getboolean('advanced', 'drift_tweak')
auto_rx_config['decoder_spacing_limit'] = config.getint('advanced', 'decoder_spacing_limit')
auto_rx_config['decoder_stats'] = config.getboolean('advanced', 'enable_stats')
Expand Down
20 changes: 18 additions & 2 deletions auto_rx/autorx/decode.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from .sonde_specific import *

# Global valid sonde types list.
VALID_SONDE_TYPES = ['RS92', 'RS41', 'DFM', 'M10', 'iMet', 'MK2LMS', 'LMS6']
VALID_SONDE_TYPES = ['RS92', 'RS41', 'DFM', 'M10', 'iMet', 'MK2LMS', 'LMS6', 'MEISEI']

# Known 'Drifty' Radiosonde types
# NOTE: Due to observed adjacent channel detections of RS41s, the adjacent channel decoder restriction
Expand Down Expand Up @@ -68,7 +68,8 @@ class SondeDecoder(object):
'heading' : 0.0
}

VALID_SONDE_TYPES = ['RS92', 'RS41', 'DFM', 'M10', 'iMet', 'MK2LMS', 'LMS6']
# TODO: Use the global valid sonde type list.
VALID_SONDE_TYPES = ['RS92', 'RS41', 'DFM', 'M10', 'iMet', 'MK2LMS', 'LMS6', 'MEISEI']

def __init__(self,
sonde_type="None",
Expand Down Expand Up @@ -395,6 +396,20 @@ def generate_decoder_command(self):

decode_cmd += "./lms6mod --json 2>/dev/null"

elif self.sonde_type == "MEISEI":
# Meisei IMS-100 Sondes
# Starting out with a 15 kHz bandwidth filter.

decode_cmd = "%s %s-p %d -d %s %s-M fm -F9 -s 15k -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, self.sonde_freq)
decode_cmd += "sox -t raw -r 15k -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 2>/dev/null |"

# Add in tee command to save audio to disk if debugging is enabled.
if self.save_decode_audio:
decode_cmd += " tee decode_%s.wav |" % str(self.device_idx)

# Meisei IMS-100 decoder
decode_cmd += "./meisei_ims --json 2>/dev/null"

else:
return None

Expand Down Expand Up @@ -562,6 +577,7 @@ def generate_decoder_command_experimental(self):
elif self.sonde_type == "iMet":
# iMet-4 Sondes
# These are AFSK and hence cannot be decoded using fsk_demod.
# Note: This block can probably be removed, as we should never be trying to start up an experimental demod for this sonde type.

decode_cmd = "%s %s-p %d -d %s %s-M fm -F9 -s 15k -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, self.sonde_freq)
decode_cmd += "sox -t raw -r 15k -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 2>/dev/null |"
Expand Down
18 changes: 7 additions & 11 deletions auto_rx/autorx/scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,17 +281,6 @@ def detect_sonde(frequency, rs_path="./", dwell_time=10, sdr_fm='rtl_fm', device



# dft_detect return codes:
# 2 = DFM
# 3 = RS41
# 4 = RS92
# 5 = M10
# 6 = IMET (AB)
# 7 = IMET (RS)
# 8 = LMS6
# 9 = C34/C50
# 10 = MK2LMS (1680 MHz LMS6, which uses the MK2A telemetry format)

# Split the line into sonde type and correlation score.
_fields = ret_output.split(':')

Expand Down Expand Up @@ -333,6 +322,13 @@ def detect_sonde(frequency, rs_path="./", dwell_time=10, sdr_fm='rtl_fm', device
return '-MK2LMS'
else:
return 'MK2LMS'
elif 'MEISEI' in _type:
logging.debug("Scanner #%s - Detected a Meisei Sonde! (Score: %.2f)" % (str(device_idx), _score))
# Not currently sure if we expect to see inverted Meisei sondes.
if _score < 0:
return '-MEISEI'
else:
return 'MEISEI'
else:
return None

Expand Down
2 changes: 1 addition & 1 deletion auto_rx/autorx/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@


# List of binaries we check for on startup
REQUIRED_RS_UTILS = ['dft_detect', 'dfm09mod', 'm10', 'imet1rs_dft', 'rs41mod', 'rs92mod', 'fsk_demod', 'mk2a_lms1680', 'lms6mod']
REQUIRED_RS_UTILS = ['dft_detect', 'dfm09mod', 'm10', 'imet1rs_dft', 'rs41mod', 'rs92mod', 'fsk_demod', 'mk2a_lms1680', 'lms6mod', 'meisei_ims']

def check_rs_utils():
""" Check the required RS decoder binaries exist
Expand Down
5 changes: 5 additions & 0 deletions auto_rx/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ echo "Building iMet Demodulator."
cd ../imet/
gcc imet1rs_dft.c -lm -o imet1rs_dft

echo "Building Meisei Demodulator."
cd ../meisei/
gcc meisei_ims.c -lm -o meisei_ims

echo "Building fsk-demod utils from codec2"
cd ../utils/
# This produces a static build of fsk_demod
Expand All @@ -58,6 +62,7 @@ cp ../demod/dfm09ecc .
cp ../m10/m10 .
cp ../utils/fsk_demod .
cp ../imet/imet1rs_dft .
cp ../meisei/meisei_ims .
cp ../mk2a/mk2a_lms1680 .

cp ../demod/mod/rs41mod .
Expand Down
Loading

0 comments on commit d56ab18

Please sign in to comment.