sdr-scanner 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ """sdr_scanner package
2
+
3
+ Expose a tiny API and package version.
4
+ """
5
+
6
+ __version__ = "0.1.0"
7
+
8
+
9
+ __all__ = []
sdr_scanner/core.py ADDED
@@ -0,0 +1,202 @@
1
+ """Author : Johan Sheby
2
+ Date : 23/06/2025
3
+ Project : Multipurpose SDR CLI Toolkit
4
+ """
5
+ ######IMPORTS#####
6
+ import os
7
+ from time import sleep, time
8
+ from datetime import datetime
9
+
10
+ try:
11
+ from rtlsdr import RtlSdr as sdr
12
+ except Exception:
13
+ sdr = None
14
+ import numpy as np
15
+ import math
16
+ import json
17
+ import matplotlib.pyplot as plt
18
+ from dataclasses import dataclass
19
+
20
+ #####INITS########
21
+
22
+
23
+ ####FUNCTIONS#####
24
+
25
+
26
+ def clear_terminal():
27
+ """Clear the terminal screen"""
28
+ os.system('cls' if os.name == 'nt' else 'clear')
29
+
30
+
31
+ def write(file_path:str , write_material) :
32
+ with open(file_path, "w", encoding="utf-8") as file:
33
+ file.write(write_material)
34
+
35
+
36
+ def listen_freq(sdr_device, freq: float):
37
+ """
38
+ Function to listen to a specific frequency using the selected SDR device.
39
+
40
+ Parameters:
41
+ sdr_device: The SDR device instance
42
+ freq (float): The frequency to listen to in Mhz
43
+ """
44
+
45
+ sdr_device.center_freq = (freq*10**6)
46
+
47
+
48
+ samples = sdr_device.read_samples(256*1024)
49
+
50
+ return samples
51
+
52
+
53
+ def scanner(sdr_device, freq_start: float, freq_end: float, step: float , step_time:float , peak_check : bool):
54
+ """
55
+ Function to scan a range of frequencies using selected SDR device """
56
+
57
+ freq_start = float(freq_start)
58
+ freq_end = float(freq_end)
59
+
60
+ @dataclass
61
+ class ScanResults:
62
+ full_range: dict
63
+ peak_freq: float
64
+ peak_power: float
65
+
66
+ results = {}
67
+
68
+ sdr_device.center_freq = (freq_start*10**6)
69
+
70
+ # Calculate decimal precision based on step size
71
+ decimal_places = len(str(step).split('.')[-1]) if '.' in str(step) else 0
72
+
73
+ for freq in np.arange(freq_start, freq_end+step, step):
74
+ freq = round(freq, decimal_places + 1)
75
+ sleep(step_time)
76
+ samples = sdr_device.read_samples(256*1024)
77
+ power = np.mean(np.abs(samples) ** 2)
78
+ db = 10 * np.log10(power + 1e-10)
79
+ results[freq] = db
80
+
81
+ if peak_check == True and results:
82
+ peak_freq = max(results, key=results.get)
83
+ peak_power = results[peak_freq]
84
+ else:
85
+ peak_freq = None
86
+ peak_power = None
87
+ return ScanResults(results, peak_freq, peak_power)
88
+
89
+ def plot(data_sourcefile : str) :
90
+
91
+ with open(data_sourcefile , 'r') as f :
92
+ data = json.load(f)
93
+ frequencies = sorted([float(freq) for freq in data.keys()])
94
+ db_values = [data[str(f)] for f in frequencies]
95
+ plt.figure(figsize = (12,16))
96
+
97
+ plt.plot(frequencies, db_values, 'b-o', linewidth=2, markersize=6)
98
+ plt.xlabel('Frequency (MHz)')
99
+ plt.ylabel('Power (dB)')
100
+ plt.title('SDR Frequency Scan')
101
+ plt.grid(True, alpha=0.3)
102
+ plt.tight_layout()
103
+ plt.show()
104
+
105
+ def main_menu():
106
+ clear_terminal()
107
+ print("SDR Scanner Main Menu")
108
+ print("1. Custom Scan")
109
+ print("2. Band Scan")
110
+ print("3. Exit")
111
+ choice = input("Select an option: ")
112
+
113
+ if choice == '1':
114
+ custom_scan()
115
+ elif choice == '2':
116
+ band_scan()
117
+ elif choice == '3':
118
+ print("Exiting...")
119
+ exit()
120
+ else:
121
+ print("Invalid choice. Please try again.")
122
+ sleep(2)
123
+ main_menu()
124
+ def custom_scan():
125
+ global sdr_device
126
+
127
+ clear_terminal()
128
+ freq_start_selection = float(input("Input start frequency (Mhz) : "))
129
+ clear_terminal()
130
+ end_freq_selection = float(input("Input End frequency (Mhz) : "))
131
+ clear_terminal()
132
+ freq_step_selection = float(input("Input step frequency (Mhz) : "))
133
+ clear_terminal()
134
+ step_time_selection = float(input("Input step time (Seconds) : "))
135
+ clear_terminal()
136
+ clear_terminal()
137
+ filenameinput = str(input("What Should the result File Called ? : "))
138
+ clear_terminal()
139
+
140
+ print(f"starting Scan from {freq_start_selection} to {end_freq_selection}")
141
+ scan_result = scanner(sdr_device,freq_start_selection,end_freq_selection, freq_step_selection, step_time_selection,True)
142
+ clear_terminal()
143
+
144
+ write(f"sdr_scanner/{filenameinput}.json", json.dumps(scan_result.full_range, indent=2))
145
+ print(f"Result saved to '{filenameinput}.json' ")
146
+ plot(f"sdr_scanner/{filenameinput}.json")
147
+ print(f"Peak Frequency: {scan_result.peak_freq} MHz, Peak Power: {scan_result.peak_power} dB")
148
+ def band_scan():
149
+ global sdr_device
150
+ clear_terminal()
151
+
152
+ input_band= input("Press Enter to start Band Scan (1.FM, 2.AM, 3.Aviation 4.Maritime) : ")
153
+
154
+ if input_band == "1" :
155
+ print("Starting FM Band Scan from 88.0 MHz to 108.0 MHz")
156
+ scan_result = scanner(sdr_device, 88.0, 108.0, 0.2, 0.5, True)
157
+ write(f"sdr_scanner/fm_scan_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.json", json.dumps(scan_result.full_range, indent=2))
158
+ print("FM Band Scan Complete ")
159
+ elif input_band == "2" :
160
+ print("Starting AM Band Scan from 530.0 KHz to 1700.0 KHz")
161
+ scan_result = scanner(sdr_device, 530.0, 1700.0, 1.0, 0.5, True)
162
+ write(f"sdr_scanner/am_scan_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.json", json.dumps(scan_result.full_range, indent=2))
163
+ print("AM Band Scan Complete ")
164
+
165
+ elif input_band == "3" :
166
+ print("Starting Aviation Band Scan from 118.0 MHz to 137.0 MHz")
167
+ scan_result = scanner(sdr_device, 118.0, 137.0, 0.2, 0.5, True)
168
+ write(f"sdr_scanner/aviation_scan_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.json", json.dumps(scan_result.full_range, indent=2))
169
+ print("Aviation Band Scan Complete ")
170
+
171
+ elif input_band == "4" :
172
+ print("Starting Maritime Band Scan from 156.0 MHz to 174.0 MHz")
173
+ scan_result = scanner(sdr_device, 156.0, 174.0, 0.2, 0.5, True)
174
+ write(f"sdr_scanner/maritime_scan_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.json", json.dumps(scan_result.full_range, indent=2))
175
+ print("Maritime Band Scan Complete ")
176
+
177
+ ##################
178
+ def main():
179
+ global sdr_device
180
+
181
+ SDR_SELECTION = input("Select SDR Device (1 for RTL-SDR, 2 for Airspy): ")
182
+ if SDR_SELECTION == '1':
183
+ sdr_device = sdr()
184
+
185
+ sdr_device.sample_rate = 2.4e6
186
+ sdr_device.center_freq = 98.6e6
187
+ sdr_device.gain = 'auto'
188
+ main_menu()
189
+ clear_terminal()
190
+
191
+
192
+
193
+
194
+
195
+ if __name__ == "__main__":
196
+ main()
197
+
198
+
199
+
200
+
201
+
202
+
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: sdr-scanner
3
+ Version: 0.1.0
4
+ Summary: SDR Scanner utilities and tools
5
+ Author-email: Johan Sheby <Jotheexplorer123@gmail.com>
6
+ License: MIT
7
+ Keywords: sdr,rtl-sdr,radio,scanner,spectrum
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.8
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Requires-Python: >=3.8
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: numpy>=1.24
19
+ Requires-Dist: matplotlib>=3.0
20
+ Requires-Dist: pyrtlsdr>=0.2.9
21
+ Dynamic: license-file
22
+
23
+ # **SDRScan**
24
+ **by Johan Sheby**
25
+
26
+ ---
27
+ SDRSCan is a simple python program that lets you automatically scan through large radio spectrums and bands using an Software Defined Radio .
28
+
29
+
30
+
31
+ # Features
32
+ SDRScan features two modes of scanning , custom where you are able to input the :
33
+ * Start frequency
34
+ * End frequency
35
+ * Step Frequency
36
+ * Step Length (seconds)
37
+
38
+ and band mode where you are able to select pre programed frquency ranges :
39
+ * FM
40
+ * AM
41
+ * Aviation
42
+ * Maritime
43
+
44
+ # Hardware Support
45
+ This program currently only supports RTL-SDRS (Tested with the [ RTL-SDR V4](https://www.rtl-sdr.com/rtl-sdr-blog-v4-end-of-line/))
46
+ Airspy and Noolec Support : Maybe :man-shrugging:
47
+
48
+ # Installation
49
+ 1. Ensure Proper Drivers are installed (refer [here](https://www.rtl-sdr.com/rtl-sdr-quick-start-guide/))
50
+
51
+ # AI Use
52
+
53
+ AI Has been used in this project to :
54
+ * Set up folder structure for PyPi
55
+ * Autofill
56
+ * Repetive copy pasting
57
+ * Running Tests
58
+ * Troupleshooting drivers
59
+
@@ -0,0 +1,7 @@
1
+ sdr_scanner/__init__.py,sha256=54xvLavxB7bEg_kv7kK3tazZhtbnV3-7zi0xU76KaSw,114
2
+ sdr_scanner/core.py,sha256=MR1qf8zPD30aAzMH-BjmkplSPxlYcd4HY1Iv3geQY30,6377
3
+ sdr_scanner-0.1.0.dist-info/licenses/LICENSE,sha256=RdgHuJUzKB6Uqx_lbxMParaxjevZGDE50vbEphiM-PM,966
4
+ sdr_scanner-0.1.0.dist-info/METADATA,sha256=AwZ0tOoNi_MrW9_E8khArq50XUP00je-Pl1J8tb5h3A,1766
5
+ sdr_scanner-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
6
+ sdr_scanner-0.1.0.dist-info/top_level.txt,sha256=JHmEeduSh6FqjCnQMwnqMZLm61ElH_GX6Rno6LtyjCY,12
7
+ sdr_scanner-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,18 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Johan Sheby Melethe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ sdr_scanner