diff --git a/app.py b/app.py index 4cce203..d04c8da 100644 --- a/app.py +++ b/app.py @@ -12,6 +12,8 @@ from bs4 import BeautifulSoup import ipaddress from io import StringIO, BytesIO import csv +import serial.tools.list_ports +from ipaddress import ip_address, AddressValueError app = Flask(__name__) socketio = SocketIO(app) @@ -23,9 +25,18 @@ port3_status = True global ser1 global ser2 global ser3 -gateway_ips = {'gateway1': '192.168.0.101', - 'gateway2': '192.168.0.102', - 'gateway3': '192.168.0.103'} +gateway_ips = { + 'gateway1': '', + 'gateway2': '', + 'gateway3': '', + 'gateway4': '', + 'gateway5': '', + 'gateway6': '', + 'gateway7': '', + 'gateway8': '', + 'gateway9': '', + 'gateway10': '' +} frequency = lambda port: {'port1': 433, 'port2': 868,'port3': 915}.get(port, None) surveydata = {} parsed_entries = set() @@ -100,6 +111,12 @@ def convert_dict_to_csv(data): output.seek(0) return output +def is_valid_ip(ip): + try: + ip_address(ip) + return True + except AddressValueError: + return False def parse_and_store_data(): global surveydata @@ -107,9 +124,9 @@ def parse_and_store_data(): global gateway_ips # Include the port number (8000) in your gateway URLs gateway_urls = [ - f"http://{gateway_ips['gateway1']}:8000/cgi-bin/log-traffic.has", # Gateway 1 - f"http://{gateway_ips['gateway2']}:8000/cgi-bin/log-traffic.has", # Gateway 2 - f"http://{gateway_ips['gateway3']}:8000/cgi-bin/log-traffic.has" # Gateway 3 + f"http://{gateway_ips[f'gateway{i}']}:8000/cgi-bin/log-traffic.has" + for i in range(1, 11) + if gateway_ips[f'gateway{i}'] and is_valid_ip(gateway_ips[f'gateway{i}']) ] headers = { @@ -126,7 +143,9 @@ def parse_and_store_data(): for url in gateway_urls: try: + print(f"Fetching data from {url}") response = requests.get(url, headers=headers, timeout=10) + if response.status_code == 200: soup = BeautifulSoup(response.text, 'html.parser') table = soup.find('table') @@ -175,12 +194,11 @@ def parse_and_store_data(): print(f"Request to {url} failed with status code: {response.status_code}") except Exception as e: print(f"An error occurred while processing {url}: {e}") - - # Schedule the next call to this function Timer(30, parse_and_store_data).start() # Call this function every 30 seconds + def extract_dev_id(formatted_row): # Assuming DevEui or DevAddr is in the 'Content' part of the formatted_row # and it's formatted like 'Dev Addr: {DevEui}, Size: {Size}' @@ -336,6 +354,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 @@ -394,22 +417,21 @@ def get_table_data(): def set_gateways(): global gateway_ips data = request.form - for key in ['gateway1', 'gateway2', 'gateway3']: + for key in [f'gateway{i}' for i in range(1, 11)]: input_ip = data.get(key, '').strip() - if input_ip: # Proceed only if the input is not empty + if input_ip: try: - # Validate the IP address ipaddress.ip_address(input_ip) - # Update the IP address if valid gateway_ips[key] = input_ip except ValueError: - # Return an error if the IP address is invalid return jsonify({"error": f"Invalid IP address provided for {key}"}), 400 for gateway, ip_address in gateway_ips.items(): print(f"Gateway {gateway} has IP address: {ip_address}") + return jsonify({"message": "Gateway IPs updated successfully"}), 200 + @app.route('/downloadPackets', methods=['GET']) def downloadPackets(): csv_data = convert_dict_to_csv(surveydata) diff --git a/templates/analysis.html b/templates/analysis.html index 2c75f90..db6e7e1 100644 --- a/templates/analysis.html +++ b/templates/analysis.html @@ -33,6 +33,7 @@
- - + +

@@ -152,34 +153,43 @@ @@ -266,8 +276,8 @@
- - + +

@@ -339,34 +349,43 @@ @@ -454,8 +473,8 @@
- - + +

@@ -526,34 +545,43 @@ diff --git a/templates/index.html b/templates/index.html index cf0942e..8159183 100644 --- a/templates/index.html +++ b/templates/index.html @@ -19,6 +19,8 @@ + + @@ -33,6 +35,7 @@ -
+
-

LoRaWAN Gateway Configuration


-

-
+ + +
+

Configure Transceivers

+

+ The 'Configure Transceiver' buttons allow you to attach to the serial port of an Adafruit Feather M0, enabling you to capture LoRa traffic on that frequency. +

+
+ + +
+ +
+
+
+

433 MHz LoRa Transceiver


+
+
+ +
+ + +

+ + + +

Status: Checking...

+
+
+
+
+ + + + + + + + + + +
+
+
+ + +
+

+
+
+
+
+

868 MHz LoRa Transceiver


+
+
+
+ + +

+ + + +

Status: Checking...

+
+
+
+
+
+ + + + + + + + + + +
+
+ + +
+

+ +
+
+
+
+

915 MHZ LoRa Transceiver


+
+
+
+ + +

+ + + +

Status: Checking...

+
+
+
+
+
+ + + + + + + + +
+
+ + +
+
+
+ +
+

Configure LoRaWAN Gateways

+

+ The 'Configure LoRaWAN Gateway' section allows you to set up to ten Dragino LPS8N LoRaWAN gateways. +

+
    +
  • Click the "Configure Gateway" button to start configuring each gateway's IP address.
  • +
  • Skip configuring a gateway or disconnect an existing one by leaving the input field empty.
  • +
  • All entered IP addresses are validated for correct formatting.
  • +
  • Once configured, the application automatically retrieves and stores LoRaWAN traffic from each active gateway.
  • +
  • Access and analyze stored traffic in 'survey mode'.
  • +
+
+
+ + +
- - diff --git a/templates/survey.html b/templates/survey.html index d6de66c..531e382 100644 --- a/templates/survey.html +++ b/templates/survey.html @@ -33,6 +33,7 @@