0% found this document useful (0 votes)
10 views7 pages

SNS_updated

The document contains a Python script that implements a GUI for EMI measurement using HackRF. It includes functions for signal classification, running a HackRF sweep, visualizing spectrum data, generating reports, and sending notifications via AWS SNS. The GUI allows users to input parameters for frequency range, gains, and the number of sweeps, and provides options to save output files and reports.

Uploaded by

Dixit Jain
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views7 pages

SNS_updated

The document contains a Python script that implements a GUI for EMI measurement using HackRF. It includes functions for signal classification, running a HackRF sweep, visualizing spectrum data, generating reports, and sending notifications via AWS SNS. The GUI allows users to input parameters for frequency range, gains, and the number of sweeps, and provides options to save output files and reports.

Uploaded by

Dixit Jain
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

import tkinter as tk

from tkinter import ttk, filedialog, messagebox


import subprocess
import csv
import matplotlib.pyplot as plt
from fpdf import FPDF
from datetime import datetime
import traceback
import os
import boto3
import json

def classify_signal(frequency):
signal_types = [
(2.412e9, 2.8e9, "Wi-Fi EMI ", "Internet connectivity"),
(2.8e9, 5e9 , "Wi-Fi" , "Internet connectivity"),
(2.410e9, 2.4835e9, "Bluetooth EMI", "Short-range wireless communication"),
(2.4845e9, 2.993e9, "Bluetooth ", "Short-range wireless communication"),
(2.7e9, 3.4e9, "Weather Radar EMI", "Precipitation monitoring"),
(2.51e9,2.6e9, "Fixed wireless access system EMI"),
(3.5e9, 3.5e9, "5G EMI", "Mobile networks"),
#(2.9e9, 3.9e9, "Military Radar", "Defense and security"),
(2.9e9, 3.5e9, "Satellite Communication", "Telemetry, control, and
communication"),
]

for freq_min, freq_max, signal, purpose in signal_types:


if freq_min <= frequency <= freq_max:
return signal, purpose
return "Unknown", "N/A"

def run_hackrf_sweep(output_file, freq_min, freq_max, bin_width, vga_gain,


lna_gain, amp_enable, antenna_enable,
num_sweeps):
command = [
"hackrf_sweep",
"-f", f"{freq_min}:{freq_max}",
"-w", str(bin_width),
"-g", str(vga_gain),
"-l", str(lna_gain),
"-a", str(amp_enable),
"-p", str(antenna_enable),
"-r", output_file,
"-N", str(num_sweeps)
]
try:
# Use subprocess with capture_output to get more information
result = subprocess.run(command, check=True, capture_output=True,
text=True)

# Print out any output for debugging


if result.stdout:
print("HackRF Sweep STDOUT:", result.stdout)
if result.stderr:
print("HackRF Sweep STDERR:", result.stderr)
# Verify file was created
if not os.path.exists(output_file) or os.path.getsize(output_file) == 0:
messagebox.showwarning("Warning", "Output file is empty. Check HackRF
connection and settings.")
return False

messagebox.showinfo("Success", "HackRF sweep completed successfully.")


return True

except subprocess.CalledProcessError as e:
messagebox.showerror("Error", f"Error running hackrf_sweep: {e}")
print(f"Command failed with error: {e}")
print(f"STDOUT: {e.stdout}")
print(f"STDERR: {e.stderr}")
return False
except FileNotFoundError:
messagebox.showerror("Error", "HackRF tools are not installed or not found
in system PATH.")
return False

def visualize_spectrum(output_file):
try:
freq_bins = []
power_levels = []

with open(output_file, "r") as file:


csv_reader = csv.reader(file)
for row in csv_reader:
try:
# Ensure row has enough elements
if len(row) < 6:
continue

freq_start = float(row[2]) # Start frequency (Hz)


bin_width = float(row[4]) # Frequency bin width (Hz)

# Convert power levels, handling potential non-numeric values


powers = []
for power_str in row[6:]:
try:
power = float(power_str)
powers.append(power)
except ValueError:
continue

# Only process if we have valid powers


if powers:
for i, power in enumerate(powers):
freq_bins.append(freq_start + i * bin_width)
power_levels.append(power)

except (ValueError, IndexError) as e:


print(f"Error processing row: {e}")
continue

# Check if we have any data


if not freq_bins or not power_levels:
messagebox.showwarning("No Data", "No spectrum data found to
visualize.")
return

# Create the plot


plt.figure(figsize=(12, 6))
plt.plot(freq_bins, power_levels, label="Power Spectrum")
plt.xlabel("Frequency (Hz)")
plt.ylabel("Power (dB)")
plt.title("EMI Spectrum Analysis")
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()

except Exception as e:
messagebox.showerror("Error", f"Failed to visualize spectrum: {e}")
print(f"Detailed error: {traceback.format_exc()}")

def generate_report(output_file, report_file):


"""Generates a PDF report from the CSV data."""
try:
freq_bins = []
power_levels = []
signal_data = [] # Store signal information for the report

with open(output_file, 'r') as file:


csv_reader = csv.reader(file)
for row in csv_reader:
try:
freq_start = int(row[2]) # Start frequency (Hz)
bin_width = float(row[4]) # Frequency bin width (Hz)
powers = [float(p) for p in row[6:]] # Power levels (dB)

for i, power in enumerate(powers):


current_freq = freq_start + i * bin_width
freq_bins.append(current_freq)
power_levels.append(power)

# Classify signal for each frequency


signal, purpose = classify_signal(current_freq)
signal_data.append((current_freq, power, signal, purpose))
except (ValueError, IndexError):
continue

if not signal_data:
raise ValueError("No valid data found in the CSV file.")

pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.cell(200, 10, txt="EMI Measurement Report", ln=True, align='C')
pdf.ln(10)

# Add signal information to the report


for freq, amp, signal, purpose in signal_data:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
pdf.cell(0, 10,
txt=f"Date: {timestamp}, Frequency: {freq} Hz, Amplitude:
{amp} dB, Signal: {signal}, Purpose: {purpose}",
ln=True)

pdf.output(report_file)
messagebox.showinfo("Success", f"Report generated and saved to
{report_file}.")
except Exception as e:
messagebox.showerror("Error", f"Error generating report: {e}")
def notification():
topic_arn = 'arn:aws:sns:ap-south-1:515966519193:EMC'
sns_client = boto3.client(
'sns',
aws_access_key_id='AKIAXQIQAI6MTLUHUJP6',
aws_secret_access_key='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',
region_name='ap-south-1'
)

# Define publish_message as a string


publish_message = 'No Anomaly Detected'

# Publish the message to the SNS topic


response = sns_client.publish(
TopicArn=topic_arn, # Correct parameter name is TopicArn
Message=publish_message # Pass the string directly as the message
)

print(response)

def start_sweep():
output_file = filedialog.asksaveasfilename(
defaultextension=".csv",
filetypes=[("CSV files", ".csv"), ("All files", ".*")]
)
if not output_file:
return

try:
freq_min = int(freq_min_entry.get())
freq_max = int(freq_max_entry.get())
bin_width = int(bin_width_entry.get())
vga_gain = int(vga_gain_entry.get())
lna_gain = int(lna_gain_entry.get())
amp_enable = amp_enable_var.get()
antenna_enable = antenna_enable_var.get()
num_sweeps = int(num_sweeps_entry.get())
except ValueError:
messagebox.showerror("Error", "Please enter valid numeric values for all
fields.")
return

# Run sweep and check if successful


if run_hackrf_sweep(
output_file,
freq_min,
freq_max,
bin_width,
vga_gain,
lna_gain,
amp_enable,
antenna_enable,
num_sweeps,
):
# Only proceed if sweep was successful
visualize_spectrum(output_file)
notification()
report_file = filedialog.asksaveasfilename(
defaultextension=".pdf",
filetypes=[("PDF files", ".pdf"), ("All files", ".*")]
)
if report_file:
generate_report(output_file, report_file)

# Create the GUI


root = tk.Tk()
root.title("EMI Measurement GUI")
root.geometry("400x400")

# Frequency range
ttk.Label(root, text="Frequency Range (MHz)").pack(pady=5)
freq_min_entry = ttk.Entry(root, width=10)
freq_min_entry.pack(pady=5)
freq_min_entry.insert(0, "0")
freq_max_entry = ttk.Entry(root, width=10)
freq_max_entry.pack(pady=5)
freq_max_entry.insert(0, "6000")

# Bin width
ttk.Label(root, text="Bin Width (Hz)").pack(pady=5)
bin_width_entry = ttk.Entry(root, width=10)
bin_width_entry.pack(pady=5)
bin_width_entry.insert(0, "1000000")

# Gains
ttk.Label(root, text="VGA Gain (dB)").pack(pady=5)
vga_gain_entry = ttk.Entry(root, width=10)
vga_gain_entry.pack(pady=5)
vga_gain_entry.insert(0, "20")

ttk.Label(root, text="LNA Gain (dB)").pack(pady=5)


lna_gain_entry = ttk.Entry(root, width=10)
lna_gain_entry.pack(pady=5)
lna_gain_entry.insert(0, "16")

# Amplifier and antenna


amp_enable_var = tk.IntVar(value=1)
ttk.Checkbutton(root, text="Enable Amplifier",
variable=amp_enable_var).pack(pady=5)

antenna_enable_var = tk.IntVar(value=1)
ttk.Checkbutton(root, text="Enable Antenna",
variable=antenna_enable_var).pack(pady=5)

# Number of sweeps
ttk.Label(root, text="Number of Sweeps").pack(pady=5)
num_sweeps_entry = ttk.Entry(root, width=10)
num_sweeps_entry.pack(pady=5)
num_sweeps_entry.insert(0, "100")
# Start button
ttk.Button(root, text="Start Sweep", command=start_sweep).pack(pady=20)
root.mainloop()

# import tkinter as tk
# from tkinter import messagebox
# import numpy as np
# import matplotlib.pyplot as plt
# from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
# import subprocess

# Function to capture signal


# def capture_signal(center_freq, sample_rate, gain,
output_file="captured_data.bin"):
# try:
# command = [
# "hackrf_transfer",
# "-f", str(center_freq),
# "-s", str(sample_rate),
# "-g", str(gain),
# "-o", output_file
# ]
# subprocess.run(command, check=True)
# except subprocess.CalledProcessError as e:
# messagebox.showerror("Error", f"Signal capture failed: {e}")
# return False
# return True

# Function to process signal


# def process_signal(file, sample_rate):
# with open(file, "rb") as f:
# raw_data = np.frombuffer(f.read(), dtype=np.int8)
# iq_data = raw_data[0::2] + 1j * raw_data[1::2]
# fft_data = np.fft.fftshift(np.fft.fft(iq_data))
# freqs = np.fft.fftshift(np.fft.fftfreq(len(fft_data), 1/sample_rate))
# spectrum = 20 * np.log10(np.abs(fft_data))
# return freqs, spectrum

# Function to detect sources


# def detect_sources(freqs, spectrum, threshold=-50):
# peaks = freqs[spectrum > threshold]
# detected_sources = []
# for peak in peaks:
# detected_sources.append(f"EMI source at {peak:.2f} Hz")
# return detected_sources

# Function to run the entire process


# def start_measurement():
# try:
# center_freq = int(center_freq_entry.get())
# sample_rate = int(sample_rate_entry.get())
# gain = int(gain_entry.get())
# except ValueError:
# messagebox.showerror("Input Error", "Please enter valid numeric values.")
# return

# log_text.delete("1.0", tk.END) # Clear log area


# Step 1: Capture signal
# if not capture_signal(center_freq, sample_rate, gain):
# return

# Step 2: Process signal


# freqs, spectrum = process_signal("captured_data.bin", sample_rate)

# Step 3: Visualize spectrum


# ax.clear()
# ax.plot(freqs, spectrum)
# ax.set_title("EMI Spectrum")
# ax.set_xlabel("Frequency (Hz)")
# ax.set_ylabel("Amplitude (dB)")
# canvas.draw()

# Step 4: Detect sources


# sources = detect_sources(freqs, spectrum)
# if sources:
# log_text.insert(tk.END, "\n".join(sources))
# else:
# log_text.insert(tk.END, "No significant EMI sources detected.")

# Create the GUI window


# root = tk.Tk()
# root.title("Portable EMI Measurement")

# Input fields
# tk.Label(root, text="Center Frequency (Hz):").grid(row=0, column=0, sticky="w")
# center_freq_entry = tk.Entry(root)
# center_freq_entry.grid(row=0, column=1)

# tk.Label(root, text="Sample Rate (Hz):").grid(row=1, column=0, sticky="w")


# sample_rate_entry = tk.Entry(root)
# sample_rate_entry.grid(row=1, column=1)

# tk.Label(root, text="RF Gain (dB):").grid(row=2, column=0, sticky="w")


# gain_entry = tk.Entry(root)
# gain_entry.grid(row=2, column=1)

# Start button
# start_button = tk.Button(root, text="Start", command=start_measurement)
# start_button.grid(row=3, column=0, columnspan=2)

# Spectrum display
# fig, ax = plt.subplots(figsize=(5, 3))
# canvas = FigureCanvasTkAgg(fig, master=root)
# canvas_widget = canvas.get_tk_widget()
# canvas_widget.grid(row=4, column=0, columnspan=2)

# Log area
# tk.Label(root, text="Detected Sources:").grid(row=5, column=0, sticky="w")
# log_text = tk.Text(root, height=10, width=50)
# log_text.grid(row=6, column=0, columnspan=2)

# Run the GUI event loop

You might also like