Feat: Allowing the selection of the serial port from a list of available ports

This commit is contained in:
Halcy0nic
2024-09-03 14:13:52 -06:00
parent 33d9b565a9
commit 2717a66382
4 changed files with 359 additions and 272 deletions

6
app.py
View File

@@ -12,6 +12,7 @@ from bs4 import BeautifulSoup
import ipaddress
from io import StringIO, BytesIO
import csv
import serial.tools.list_ports
app = Flask(__name__)
socketio = SocketIO(app)
@@ -343,6 +344,11 @@ def transmit433():
ser1.write(msg.encode())
return jsonify(result="Ok")
@app.route('/get_serial_ports')
def get_serial_ports():
ports = [port.device for port in serial.tools.list_ports.comports()]
return jsonify(ports=ports)
@app.route('/transmit868', methods=['POST'])
def transmit868():
global ser2

View File

@@ -50,8 +50,8 @@
</h1>
<h2 class="lead mb-5">Skinny Research and Development</h2>
<p>
Analyze LoRa traffic received at 433, 868, or 915 MHz. Click the desired frequency below to get started. Once you are on the appropriate page, click the 'Connect Serial Port' button to connect to a serial port on your computer. Once connected to your LoRa receiver, traffic will automatically be streamed to the web page for analysis. To disconnect a receiver, click the 'Disconnect Serial Port' button.
</p>
Analyze LoRa traffic received at 433, 868, or 915 MHz. Click the desired frequency below to get started. Once you are on the appropriate page, click the 'Select Device' button to connect to a serial port on your computer. Once connected to your LoRa receiver, traffic will automatically be streamed to the web page for analysis. To disconnect a receiver, click the 'Disconnect Device' button.
</p>
<hr class="m-0" />
<br><br>
<!-- 433 -->
@@ -65,8 +65,8 @@
</div>
<div style="text-align:center;">
<button class="styled-button" onclick="promptUser433()">Connect Serial Port</button>
<button class="disconnect-button" onclick="deleteSerial433()">Disconnect Serial Port</button>
<button class="styled-button" onclick="promptUser433()">Select Device</button>
<button class="disconnect-button" onclick="deleteSerial433()">Disconnect Device</button>
<button class="transmit-button" onclick="transmit433()">Transmit Data</button><br><br>
<button class="transmit-button" onclick="clearDataPort1()">Clear Data</button>
<input type="checkbox" id="autoscroll-port1" checked>
@@ -153,34 +153,43 @@
<script>
function promptUser433() {
Swal.fire({
title: 'Serial Port:',
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Submit',
cancelButtonText: 'Cancel',
showLoaderOnConfirm: true,
preConfirm: (value) => {
// Make an AJAX request to Flask
fetch(`/attach_serial_433?user_input=${encodeURIComponent(value)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
},
allowOutsideClick: () => !Swal.isLoading()
});
// First, fetch the list of available ports
fetch('/get_serial_ports')
.then(response => response.json())
.then(data => {
const ports = data.ports;
// Create the select options
const selectOptions = ports.map(port => `<option value="${port}">${port}</option>`).join('');
Swal.fire({
title: 'Select Serial Port:',
html: `<select id="port-select" class="swal2-input">${selectOptions}</select>`,
showCancelButton: true,
confirmButtonText: 'Connect',
cancelButtonText: 'Cancel',
preConfirm: () => {
const selectedPort = document.getElementById('port-select').value;
return fetch(`/attach_serial_433?user_input=${encodeURIComponent(selectedPort)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
}
});
})
.catch(error => {
console.error('Error fetching ports:', error);
Swal.fire('Oops!', 'Failed to fetch available ports.', 'error');
});
}
</script>
@@ -267,8 +276,8 @@
<div class="serial-data" id="serial-data-port2">
</div>
<div style="text-align:center;">
<button class="styled-button" onclick="promptUser868()">Connect Serial Port</button>
<button class="disconnect-button" onclick="deleteSerial868()">Disconnect Serial Port</button>
<button class="styled-button" onclick="promptUser868()">Select Device</button>
<button class="disconnect-button" onclick="deleteSerial868()">Disconnect Device</button>
<button class="transmit-button" onclick="transmit868()">Transmit Data</button><br><br>
<button class="transmit-button" onclick="clearDataPort2()">Clear Data</button>
<input type="checkbox" id="autoscroll-port2" checked>
@@ -340,34 +349,43 @@
<script>
function promptUser868() {
Swal.fire({
title: 'Serial Port:',
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Submit',
cancelButtonText: 'Cancel',
showLoaderOnConfirm: true,
preConfirm: (value) => {
// Make an AJAX request to Flask
fetch(`/attach_serial_868?user_input=${encodeURIComponent(value)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
},
allowOutsideClick: () => !Swal.isLoading()
});
// First, fetch the list of available ports
fetch('/get_serial_ports')
.then(response => response.json())
.then(data => {
const ports = data.ports;
// Create the select options
const selectOptions = ports.map(port => `<option value="${port}">${port}</option>`).join('');
Swal.fire({
title: 'Select Serial Port:',
html: `<select id="port-select" class="swal2-input">${selectOptions}</select>`,
showCancelButton: true,
confirmButtonText: 'Connect',
cancelButtonText: 'Cancel',
preConfirm: () => {
const selectedPort = document.getElementById('port-select').value;
return fetch(`/attach_serial_868?user_input=${encodeURIComponent(selectedPort)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
}
});
})
.catch(error => {
console.error('Error fetching ports:', error);
Swal.fire('Oops!', 'Failed to fetch available ports.', 'error');
});
}
</script>
@@ -455,8 +473,8 @@
<div class="serial-data" id="serial-data-port3">
</div>
<div style="text-align:center;">
<button class="styled-button" onclick="promptUser915()">Connect Serial Port</button>
<button class="disconnect-button" onclick="deleteSerial915()">Disconnect Serial Port</button>
<button class="styled-button" onclick="promptUser915()">Select Device</button>
<button class="disconnect-button" onclick="deleteSerial915()">Disconnect Device</button>
<button class="transmit-button" onclick="transmit915()">Transmit Data</button><br><br>
<button class="transmit-button" onclick="clearDataPort3()">Clear Data</button>
<input type="checkbox" id="autoscroll-port3" checked>
@@ -527,34 +545,43 @@
<script>
function promptUser915() {
Swal.fire({
title: 'Serial Port:',
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Submit',
cancelButtonText: 'Cancel',
showLoaderOnConfirm: true,
preConfirm: (value) => {
// Make an AJAX request to Flask
fetch(`/attach_serial_915?user_input=${encodeURIComponent(value)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
},
allowOutsideClick: () => !Swal.isLoading()
});
// First, fetch the list of available ports
fetch('/get_serial_ports')
.then(response => response.json())
.then(data => {
const ports = data.ports;
// Create the select options
const selectOptions = ports.map(port => `<option value="${port}">${port}</option>`).join('');
Swal.fire({
title: 'Select Serial Port:',
html: `<select id="port-select" class="swal2-input">${selectOptions}</select>`,
showCancelButton: true,
confirmButtonText: 'Connect',
cancelButtonText: 'Cancel',
preConfirm: () => {
const selectedPort = document.getElementById('port-select').value;
return fetch(`/attach_serial_915?user_input=${encodeURIComponent(selectedPort)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
}
});
})
.catch(error => {
console.error('Error fetching ports:', error);
Swal.fire('Oops!', 'Failed to fetch available ports.', 'error');
});
}
</script>

View File

@@ -86,8 +86,8 @@
</div>
<div style="text-align:center;">
<button class="styled-button" onclick="promptUser433()">Connect Serial Port</button>
<button class="disconnect-button" onclick="deleteSerial433()">Disconnect Serial Port</button>
<button class="styled-button" onclick="promptUser433()">Select Device</button>
<button class="disconnect-button" onclick="deleteSerial433()">Disconnect Device</button>
<button class="transmit-button" onclick="transmit433()">Transmit Data</button><br><br>
<button class="transmit-button" onclick="clearDataPort1()">Clear Data</button>
<input type="checkbox" id="autoscroll-port1" checked>
@@ -174,34 +174,43 @@
<script>
function promptUser433() {
Swal.fire({
title: 'Serial Port:',
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Submit',
cancelButtonText: 'Cancel',
showLoaderOnConfirm: true,
preConfirm: (value) => {
// Make an AJAX request to Flask
fetch(`/attach_serial_433?user_input=${encodeURIComponent(value)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
},
allowOutsideClick: () => !Swal.isLoading()
});
// First, fetch the list of available ports
fetch('/get_serial_ports')
.then(response => response.json())
.then(data => {
const ports = data.ports;
// Create the select options
const selectOptions = ports.map(port => `<option value="${port}">${port}</option>`).join('');
Swal.fire({
title: 'Select Serial Port:',
html: `<select id="port-select" class="swal2-input">${selectOptions}</select>`,
showCancelButton: true,
confirmButtonText: 'Connect',
cancelButtonText: 'Cancel',
preConfirm: () => {
const selectedPort = document.getElementById('port-select').value;
return fetch(`/attach_serial_433?user_input=${encodeURIComponent(selectedPort)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
}
});
})
.catch(error => {
console.error('Error fetching ports:', error);
Swal.fire('Oops!', 'Failed to fetch available ports.', 'error');
});
}
</script>
@@ -288,8 +297,8 @@
<div class="serial-data" id="serial-data-port2">
</div>
<div style="text-align:center;">
<button class="styled-button" onclick="promptUser868()">Connect Serial Port</button>
<button class="disconnect-button" onclick="deleteSerial868()">Disconnect Serial Port</button>
<button class="styled-button" onclick="promptUser868()">Select Device</button>
<button class="disconnect-button" onclick="deleteSerial868()">Disconnect Device</button>
<button class="transmit-button" onclick="transmit868()">Transmit Data</button><br><br>
<button class="transmit-button" onclick="clearDataPort2()">Clear Data</button>
<input type="checkbox" id="autoscroll-port2" checked>
@@ -361,34 +370,43 @@
<script>
function promptUser868() {
Swal.fire({
title: 'Serial Port:',
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Submit',
cancelButtonText: 'Cancel',
showLoaderOnConfirm: true,
preConfirm: (value) => {
// Make an AJAX request to Flask
fetch(`/attach_serial_868?user_input=${encodeURIComponent(value)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
},
allowOutsideClick: () => !Swal.isLoading()
});
// First, fetch the list of available ports
fetch('/get_serial_ports')
.then(response => response.json())
.then(data => {
const ports = data.ports;
// Create the select options
const selectOptions = ports.map(port => `<option value="${port}">${port}</option>`).join('');
Swal.fire({
title: 'Select Serial Port:',
html: `<select id="port-select" class="swal2-input">${selectOptions}</select>`,
showCancelButton: true,
confirmButtonText: 'Connect',
cancelButtonText: 'Cancel',
preConfirm: () => {
const selectedPort = document.getElementById('port-select').value;
return fetch(`/attach_serial_868?user_input=${encodeURIComponent(selectedPort)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
}
});
})
.catch(error => {
console.error('Error fetching ports:', error);
Swal.fire('Oops!', 'Failed to fetch available ports.', 'error');
});
}
</script>
@@ -476,8 +494,8 @@
<div class="serial-data" id="serial-data-port3">
</div>
<div style="text-align:center;">
<button class="styled-button" onclick="promptUser915()">Connect Serial Port</button>
<button class="disconnect-button" onclick="deleteSerial915()">Disconnect Serial Port</button>
<button class="styled-button" onclick="promptUser915()">Select Device</button>
<button class="disconnect-button" onclick="deleteSerial915()">Disconnect Device</button>
<button class="transmit-button" onclick="transmit915()">Transmit Data</button><br><br>
<button class="transmit-button" onclick="clearDataPort3()">Clear Data</button>
<input type="checkbox" id="autoscroll-port3" checked>
@@ -548,34 +566,43 @@
<script>
function promptUser915() {
Swal.fire({
title: 'Serial Port:',
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Submit',
cancelButtonText: 'Cancel',
showLoaderOnConfirm: true,
preConfirm: (value) => {
// Make an AJAX request to Flask
fetch(`/attach_serial_915?user_input=${encodeURIComponent(value)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
},
allowOutsideClick: () => !Swal.isLoading()
});
// First, fetch the list of available ports
fetch('/get_serial_ports')
.then(response => response.json())
.then(data => {
const ports = data.ports;
// Create the select options
const selectOptions = ports.map(port => `<option value="${port}">${port}</option>`).join('');
Swal.fire({
title: 'Select Serial Port:',
html: `<select id="port-select" class="swal2-input">${selectOptions}</select>`,
showCancelButton: true,
confirmButtonText: 'Connect',
cancelButtonText: 'Cancel',
preConfirm: () => {
const selectedPort = document.getElementById('port-select').value;
return fetch(`/attach_serial_915?user_input=${encodeURIComponent(selectedPort)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
}
});
})
.catch(error => {
console.error('Error fetching ports:', error);
Swal.fire('Oops!', 'Failed to fetch available ports.', 'error');
});
}
</script>

View File

@@ -210,8 +210,8 @@
</div>
<div style="text-align:center;">
<button class="styled-button" onclick="promptUser433()">Connect Serial Port</button>
<button class="disconnect-button" onclick="deleteSerial433()">Disconnect Serial Port</button>
<button class="styled-button" onclick="promptUser433()">Select Device</button>
<button class="disconnect-button" onclick="deleteSerial433()">Disconnect Device</button>
<button class="transmit-button" onclick="transmit433()">Start Beacon</button>
<button class="disconnect-button" onclick="confirmStopTransmission433()">Stop Beacon</button><br><br>
<button class="transmit-button" onclick="clearDataPort1()">Clear Data</button>
@@ -283,34 +283,43 @@
<script>
function promptUser433() {
Swal.fire({
title: 'Serial Port:',
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Submit',
cancelButtonText: 'Cancel',
showLoaderOnConfirm: true,
preConfirm: (value) => {
// Make an AJAX request to Flask
fetch(`/attach_serial_433?user_input=${encodeURIComponent(value)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
},
allowOutsideClick: () => !Swal.isLoading()
});
// First, fetch the list of available ports
fetch('/get_serial_ports')
.then(response => response.json())
.then(data => {
const ports = data.ports;
// Create the select options
const selectOptions = ports.map(port => `<option value="${port}">${port}</option>`).join('');
Swal.fire({
title: 'Select Serial Port:',
html: `<select id="port-select" class="swal2-input">${selectOptions}</select>`,
showCancelButton: true,
confirmButtonText: 'Connect',
cancelButtonText: 'Cancel',
preConfirm: () => {
const selectedPort = document.getElementById('port-select').value;
return fetch(`/attach_serial_433?user_input=${encodeURIComponent(selectedPort)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
}
});
})
.catch(error => {
console.error('Error fetching ports:', error);
Swal.fire('Oops!', 'Failed to fetch available ports.', 'error');
});
}
</script>
@@ -458,8 +467,8 @@
<div class="serial-data" id="serial-data-port2">
</div>
<div style="text-align:center;">
<button class="styled-button" onclick="promptUser868()">Connect Serial Port</button>
<button class="disconnect-button" onclick="deleteSerial868()">Disconnect Serial Port</button>
<button class="styled-button" onclick="promptUser868()">Select Device</button>
<button class="disconnect-button" onclick="deleteSerial868()">Disconnect Device</button>
<button class="transmit-button" onclick="transmit868()">Start Beacon</button>
<button class="disconnect-button" onclick="confirmStopTransmission868()">Stop Beacon</button><br><br>
<button class="transmit-button" onclick="clearDataPort2()">Clear Data</button>
@@ -528,34 +537,43 @@
<script>
function promptUser868() {
Swal.fire({
title: 'Serial Port:',
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Submit',
cancelButtonText: 'Cancel',
showLoaderOnConfirm: true,
preConfirm: (value) => {
// Make an AJAX request to Flask
fetch(`/attach_serial_868?user_input=${encodeURIComponent(value)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
},
allowOutsideClick: () => !Swal.isLoading()
});
// First, fetch the list of available ports
fetch('/get_serial_ports')
.then(response => response.json())
.then(data => {
const ports = data.ports;
// Create the select options
const selectOptions = ports.map(port => `<option value="${port}">${port}</option>`).join('');
Swal.fire({
title: 'Select Serial Port:',
html: `<select id="port-select" class="swal2-input">${selectOptions}</select>`,
showCancelButton: true,
confirmButtonText: 'Connect',
cancelButtonText: 'Cancel',
preConfirm: () => {
const selectedPort = document.getElementById('port-select').value;
return fetch(`/attach_serial_868?user_input=${encodeURIComponent(selectedPort)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
}
});
})
.catch(error => {
console.error('Error fetching ports:', error);
Swal.fire('Oops!', 'Failed to fetch available ports.', 'error');
});
}
</script>
@@ -705,8 +723,8 @@
<div class="serial-data" id="serial-data-port3">
</div>
<div style="text-align:center;">
<button class="styled-button" onclick="promptUser915()">Connect Serial Port</button>
<button class="disconnect-button" onclick="deleteSerial915()">Disconnect Serial Port</button>
<button class="styled-button" onclick="promptUser915()">Select Device</button>
<button class="disconnect-button" onclick="deleteSerial915()">Disconnect Device</button>
<button class="transmit-button" onclick="transmit915()">Start Beacon</button>
<button class="disconnect-button" onclick="confirmStopTransmission915()">Stop Beacon</button><br><br>
<button class="transmit-button" onclick="clearDataPort3()">Clear Data</button>
@@ -776,34 +794,43 @@
<script>
function promptUser915() {
Swal.fire({
title: 'Serial Port:',
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Submit',
cancelButtonText: 'Cancel',
showLoaderOnConfirm: true,
preConfirm: (value) => {
// Make an AJAX request to Flask
fetch(`/attach_serial_915?user_input=${encodeURIComponent(value)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
},
allowOutsideClick: () => !Swal.isLoading()
});
// First, fetch the list of available ports
fetch('/get_serial_ports')
.then(response => response.json())
.then(data => {
const ports = data.ports;
// Create the select options
const selectOptions = ports.map(port => `<option value="${port}">${port}</option>`).join('');
Swal.fire({
title: 'Select Serial Port:',
html: `<select id="port-select" class="swal2-input">${selectOptions}</select>`,
showCancelButton: true,
confirmButtonText: 'Connect',
cancelButtonText: 'Cancel',
preConfirm: () => {
const selectedPort = document.getElementById('port-select').value;
return fetch(`/attach_serial_915?user_input=${encodeURIComponent(selectedPort)}`)
.then(response => response.json())
.then(data => {
Swal.fire({
title: 'Result',
text: data.result,
icon: 'info'
});
})
.catch(error => {
console.error('Error:', error);
Swal.fire('Oops!', 'Something went wrong.', 'error');
});
}
});
})
.catch(error => {
console.error('Error fetching ports:', error);
Swal.fire('Oops!', 'Failed to fetch available ports.', 'error');
});
}
</script>