diff --git a/routes/rtlamr.py b/routes/rtlamr.py index 3acb291..311bda7 100644 --- a/routes/rtlamr.py +++ b/routes/rtlamr.py @@ -29,6 +29,7 @@ rtl_tcp_lock = threading.Lock() # Track which device is being used rtlamr_active_device: int | None = None +rtlamr_active_sdr_type: str = 'rtlsdr' def stream_rtlamr_output(process: subprocess.Popen[bytes]) -> None: @@ -62,7 +63,7 @@ def stream_rtlamr_output(process: subprocess.Popen[bytes]) -> None: except Exception as e: app_module.rtlamr_queue.put({'type': 'error', 'text': str(e)}) finally: - global rtl_tcp_process, rtlamr_active_device + global rtl_tcp_process, rtlamr_active_device, rtlamr_active_sdr_type # Ensure rtlamr process is terminated try: process.terminate() @@ -91,19 +92,26 @@ def stream_rtlamr_output(process: subprocess.Popen[bytes]) -> None: app_module.rtlamr_process = None # Release SDR device if rtlamr_active_device is not None: - app_module.release_sdr_device(rtlamr_active_device) + app_module.release_sdr_device(rtlamr_active_device, rtlamr_active_sdr_type) rtlamr_active_device = None @rtlamr_bp.route('/start_rtlamr', methods=['POST']) def start_rtlamr() -> Response: - global rtl_tcp_process, rtlamr_active_device + global rtl_tcp_process, rtlamr_active_device, rtlamr_active_sdr_type with app_module.rtlamr_lock: if app_module.rtlamr_process: return jsonify({'status': 'error', 'message': 'RTLAMR already running'}), 409 data = request.json or {} + sdr_type_str = data.get('sdr_type', 'rtlsdr') + + if sdr_type_str != 'rtlsdr': + return jsonify({ + 'status': 'error', + 'message': f'{sdr_type_str.replace("_", " ").title()} is not yet supported for this mode. Please use an RTL-SDR device.' + }), 400 # Validate inputs try: @@ -116,7 +124,7 @@ def start_rtlamr() -> Response: # Check if device is available device_int = int(device) - error = app_module.claim_sdr_device(device_int, 'rtlamr') + error = app_module.claim_sdr_device(device_int, 'rtlamr', sdr_type_str) if error: return jsonify({ 'status': 'error', @@ -125,6 +133,7 @@ def start_rtlamr() -> Response: }), 409 rtlamr_active_device = device_int + rtlamr_active_sdr_type = sdr_type_str # Clear queue while not app_module.rtlamr_queue.empty(): @@ -170,7 +179,7 @@ def start_rtlamr() -> Response: logger.error(f"Failed to start rtl_tcp: {e}") # Release SDR device on rtl_tcp failure if rtlamr_active_device is not None: - app_module.release_sdr_device(rtlamr_active_device) + app_module.release_sdr_device(rtlamr_active_device, rtlamr_active_sdr_type) rtlamr_active_device = None return jsonify({'status': 'error', 'message': f'Failed to start rtl_tcp: {e}'}), 500 @@ -242,7 +251,7 @@ def start_rtlamr() -> Response: rtl_tcp_process.wait(timeout=2) rtl_tcp_process = None if rtlamr_active_device is not None: - app_module.release_sdr_device(rtlamr_active_device) + app_module.release_sdr_device(rtlamr_active_device, rtlamr_active_sdr_type) rtlamr_active_device = None return jsonify({'status': 'error', 'message': 'rtlamr not found. Install from https://github.com/bemasher/rtlamr'}) except Exception as e: @@ -253,14 +262,14 @@ def start_rtlamr() -> Response: rtl_tcp_process.wait(timeout=2) rtl_tcp_process = None if rtlamr_active_device is not None: - app_module.release_sdr_device(rtlamr_active_device) + app_module.release_sdr_device(rtlamr_active_device, rtlamr_active_sdr_type) rtlamr_active_device = None return jsonify({'status': 'error', 'message': str(e)}) @rtlamr_bp.route('/stop_rtlamr', methods=['POST']) def stop_rtlamr() -> Response: - global rtl_tcp_process, rtlamr_active_device + global rtl_tcp_process, rtlamr_active_device, rtlamr_active_sdr_type # Grab process refs inside locks, clear state, then terminate outside rtlamr_proc = None @@ -293,7 +302,7 @@ def stop_rtlamr() -> Response: # Release device from registry if rtlamr_active_device is not None: - app_module.release_sdr_device(rtlamr_active_device) + app_module.release_sdr_device(rtlamr_active_device, rtlamr_active_sdr_type) rtlamr_active_device = None return jsonify({'status': 'stopped'}) diff --git a/routes/sstv.py b/routes/sstv.py index 0b13cc5..9fe4d6c 100644 --- a/routes/sstv.py +++ b/routes/sstv.py @@ -57,6 +57,7 @@ _timescale_lock = threading.Lock() # Track which device is being used sstv_active_device: int | None = None +sstv_active_sdr_type: str = 'rtlsdr' def _progress_callback(data: dict) -> None: @@ -154,6 +155,14 @@ def start_decoder(): # Get parameters data = request.get_json(silent=True) or {} + sdr_type_str = data.get('sdr_type', 'rtlsdr') + + if sdr_type_str != 'rtlsdr': + return jsonify({ + 'status': 'error', + 'message': f'{sdr_type_str.replace("_", " ").title()} is not yet supported for this mode. Please use an RTL-SDR device.' + }), 400 + frequency = data.get('frequency', ISS_SSTV_FREQ) modulation = str(data.get('modulation', ISS_SSTV_MODULATION)).strip().lower() device_index = data.get('device', 0) @@ -209,9 +218,9 @@ def start_decoder(): longitude = None # Claim SDR device - global sstv_active_device + global sstv_active_device, sstv_active_sdr_type device_int = int(device_index) - error = app_module.claim_sdr_device(device_int, 'sstv') + error = app_module.claim_sdr_device(device_int, 'sstv', sdr_type_str) if error: return jsonify({ 'status': 'error', @@ -231,6 +240,7 @@ def start_decoder(): if success: sstv_active_device = device_int + sstv_active_sdr_type = sdr_type_str result = { 'status': 'started', @@ -247,7 +257,7 @@ def start_decoder(): return jsonify(result) else: # Release device on failure - app_module.release_sdr_device(device_int) + app_module.release_sdr_device(device_int, sdr_type_str) return jsonify({ 'status': 'error', 'message': 'Failed to start decoder' @@ -262,13 +272,13 @@ def stop_decoder(): Returns: JSON confirmation. """ - global sstv_active_device + global sstv_active_device, sstv_active_sdr_type decoder = get_sstv_decoder() decoder.stop() # Release device from registry if sstv_active_device is not None: - app_module.release_sdr_device(sstv_active_device) + app_module.release_sdr_device(sstv_active_device, sstv_active_sdr_type) sstv_active_device = None return jsonify({'status': 'stopped'}) diff --git a/routes/sstv_general.py b/routes/sstv_general.py index b305702..a17fe7d 100644 --- a/routes/sstv_general.py +++ b/routes/sstv_general.py @@ -30,6 +30,7 @@ _sstv_general_queue: queue.Queue = queue.Queue(maxsize=100) # Track which device is being used _sstv_general_active_device: int | None = None +_sstv_general_active_sdr_type: str = 'rtlsdr' # Predefined SSTV frequencies SSTV_FREQUENCIES = [ @@ -119,6 +120,14 @@ def start_decoder(): break data = request.get_json(silent=True) or {} + sdr_type_str = data.get('sdr_type', 'rtlsdr') + + if sdr_type_str != 'rtlsdr': + return jsonify({ + 'status': 'error', + 'message': f'{sdr_type_str.replace("_", " ").title()} is not yet supported for this mode. Please use an RTL-SDR device.' + }), 400 + frequency = data.get('frequency') modulation = data.get('modulation') device_index = data.get('device', 0) @@ -155,9 +164,9 @@ def start_decoder(): }), 400 # Claim SDR device - global _sstv_general_active_device + global _sstv_general_active_device, _sstv_general_active_sdr_type device_int = int(device_index) - error = app_module.claim_sdr_device(device_int, 'sstv_general') + error = app_module.claim_sdr_device(device_int, 'sstv_general', sdr_type_str) if error: return jsonify({ 'status': 'error', @@ -175,6 +184,7 @@ def start_decoder(): if success: _sstv_general_active_device = device_int + _sstv_general_active_sdr_type = sdr_type_str return jsonify({ 'status': 'started', 'frequency': frequency, @@ -182,7 +192,7 @@ def start_decoder(): 'device': device_index, }) else: - app_module.release_sdr_device(device_int) + app_module.release_sdr_device(device_int, sdr_type_str) return jsonify({ 'status': 'error', 'message': 'Failed to start decoder', @@ -192,12 +202,12 @@ def start_decoder(): @sstv_general_bp.route('/stop', methods=['POST']) def stop_decoder(): """Stop general SSTV decoder.""" - global _sstv_general_active_device + global _sstv_general_active_device, _sstv_general_active_sdr_type decoder = get_general_sstv_decoder() decoder.stop() if _sstv_general_active_device is not None: - app_module.release_sdr_device(_sstv_general_active_device) + app_module.release_sdr_device(_sstv_general_active_device, _sstv_general_active_sdr_type) _sstv_general_active_device = None return jsonify({'status': 'stopped'}) diff --git a/routes/weather_sat.py b/routes/weather_sat.py index 1e9c9f5..74e801c 100644 --- a/routes/weather_sat.py +++ b/routes/weather_sat.py @@ -136,6 +136,13 @@ def start_capture(): }) data = request.get_json(silent=True) or {} + sdr_type_str = data.get('sdr_type', 'rtlsdr') + + if sdr_type_str != 'rtlsdr': + return jsonify({ + 'status': 'error', + 'message': f'{sdr_type_str.replace("_", " ").title()} is not yet supported for this mode. Please use an RTL-SDR device.' + }), 400 # Validate satellite satellite = data.get('satellite') @@ -173,7 +180,7 @@ def start_capture(): if not rtl_tcp_host: try: import app as app_module - error = app_module.claim_sdr_device(device_index, 'weather_sat') + error = app_module.claim_sdr_device(device_index, 'weather_sat', sdr_type_str) if error: return jsonify({ 'status': 'error', diff --git a/static/js/modes/sstv-general.js b/static/js/modes/sstv-general.js index 3bec33d..b4e4d76 100644 --- a/static/js/modes/sstv-general.js +++ b/static/js/modes/sstv-general.js @@ -108,7 +108,7 @@ const SSTVGeneral = (function() { const response = await fetch('/sstv-general/start', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ frequency, modulation, device }) + body: JSON.stringify({ frequency, modulation, device, sdr_type: typeof getSelectedSDRType === 'function' ? getSelectedSDRType() : 'rtlsdr' }) }); const data = await response.json(); diff --git a/static/js/modes/weather-satellite.js b/static/js/modes/weather-satellite.js index 5627e88..00b01c5 100644 --- a/static/js/modes/weather-satellite.js +++ b/static/js/modes/weather-satellite.js @@ -258,6 +258,7 @@ const WeatherSat = (function() { device, gain, bias_t: biasT, + sdr_type: typeof getSelectedSDRType === 'function' ? getSelectedSDRType() : 'rtlsdr', }; // Add rtl_tcp params if using remote SDR diff --git a/templates/index.html b/templates/index.html index 9d5cbf8..a509e2a 100644 --- a/templates/index.html +++ b/templates/index.html @@ -5329,6 +5329,7 @@ gain: gain, ppm: ppm, device: device, + sdr_type: getSelectedSDRType(), msgtype: msgtype, filterid: filterid, unique: unique, diff --git a/utils/sdr/detection.py b/utils/sdr/detection.py index 12d7196..e3d0cc2 100644 --- a/utils/sdr/detection.py +++ b/utils/sdr/detection.py @@ -493,7 +493,7 @@ def probe_rtlsdr_device(device_index: int) -> str | None: ) return ( f'SDR device {device_index} is not available — ' - f'check that the RTL-SDR is connected and not in use by another process.' + f'check that the SDR device is connected and not in use by another process.' ) except Exception as e: