diff --git a/.idea/misc.xml b/.idea/misc.xml
index afcdc7f..12391f3 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,5 +3,5 @@
-
+
\ No newline at end of file
diff --git a/python/docker_entrypoint.sh b/python/docker_entrypoint.sh
index aeb780b..bafdaea 100644
--- a/python/docker_entrypoint.sh
+++ b/python/docker_entrypoint.sh
@@ -7,4 +7,5 @@ if [ "$API" = true ]; then
sleep 1
fi
-python3.12 main.py
\ No newline at end of file
+python3.12 start_discovery_server.py &
+python3.12 main.py
diff --git a/python/src/discovery.py b/python/src/ble_discovery.py
similarity index 100%
rename from python/src/discovery.py
rename to python/src/ble_discovery.py
diff --git a/python/src/find_gateways.py b/python/src/find_gateways.py
index 2271f06..969c194 100644
--- a/python/src/find_gateways.py
+++ b/python/src/find_gateways.py
@@ -1,54 +1,75 @@
-from time import sleep
-import socket
-import FindMyIP
-import ipaddress
-import threading
-import requests
+# https://github.com/jholtmann/ip_discovery
+
import os
+import FindMyIP
+from socket import *
+from helpers import get_unix_time
DEBUG = True if os.environ.get('DEBUG') is not None else False
-max_threads = 50
-port = 8000
-final = {}
+DISCOVERY_ACK = 'IP_DISCOVERY_ACK'.encode() # ACK for broadcast
+DISCOVERY_RSP_GTW = 'IP_DISCOVERY_RSP_GTW'.encode() # RSP for gateway
+DISCOVERY_RSP_MSH = 'IP_DISCOVERY_RSP_MSH'.encode() # RSP for mesh
+DISCOVERY_TIMEOUT = 20
+SOCKET_TIMEOUT = 5
+PORT_SERVER = 9434
+PORT_CLIENT = 9435
-def check_port(ip, port):
+def start_discovery_server():
+ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
+ sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
+ sock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
+ server_address = ('', PORT_SERVER)
+ local_ip = FindMyIP.internal()
try:
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP
- # sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
- socket.setdefaulttimeout(2.0) # seconds (float)
- result = sock.connect_ex((ip, port))
- if result == 0: final[ip] = True
- else: final[ip] = False
+ sock.bind(server_address)
+ print("Started discovery socket")
+ while True:
+ data, addr = sock.recvfrom(4096)
+ print(f"Received a packet from {addr}")
+ print(f"{addr[0]} | {local_ip}")
+ print(f"{data} | {DISCOVERY_ACK}")
+
+ if data == DISCOVERY_ACK:
+ print("ACK accepted")
+ if str(addr[0]) == str(local_ip): continue
+ print("IP accepted")
+ sock.sendto(DISCOVERY_RSP_GTW, (addr[0], PORT_CLIENT))
+ print(f"Send ACK to {addr}")
+
+ except Exception as err:
+ print(err)
sock.close()
- except:
- pass
-
-def scan_for_gateways():
+def start_discovery_client():
+ print("Started discovery client")
+ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
+ sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
+ sock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
+ sock.settimeout(SOCKET_TIMEOUT)
+ server_address = ('255.255.255.255', PORT_SERVER)
local_ip = FindMyIP.internal()
- local_ip = local_ip.split('.')[:-1]
- local_ip.append("0")
- local_ip = '.'.join(local_ip)
- print(f"Scan on {local_ip}/24 for port {port}") if DEBUG else {}
+ start_time_stamp = get_unix_time()
+ delta = round(get_unix_time() - start_time_stamp, 2)
+ discovered_devices = []
- for ip in ipaddress.IPv4Network(f'{local_ip}/24'):
- threading.Thread(target=check_port, args=[str(ip), port]).start()
- # limit the number of threads.
- while threading.active_count() > max_threads: sleep(1)
+ try:
+ sock.bind(('', PORT_CLIENT))
+ while True:
+ delta = round(get_unix_time() - start_time_stamp, 2)
+ print(delta)
+ sock.sendto(DISCOVERY_ACK, server_address)
+ data, addr = sock.recvfrom(4096)
+ print('IP: ' + str(addr[0]))
+ if data == DISCOVERY_RSP_GTW or data == DISCOVERY_RSP_GTW and addr[0] not in discovered_devices:
+ print('IP: ' + str(addr[0]))
+ discovered_devices.append(addr[0])
+ except Exception as err:
+ print(err)
- sorted_ips = dict(sorted(final.items(), key=lambda item: tuple(map(int, item[0].split('.')))))
+ finally:
+ sock.close()
- gateways = []
- for ip, state in sorted_ips.items():
- if state:
- try:
- response = requests.get(f'http://{ip}:{port}/api')
- # TODO: Check if the API is for real a gateway
- if response.status_code == 200:
- print(ip, response.json()) if DEBUG else {}
- gateways.append([ip, response.json()])
- except:pass
- return gateways
+# start_discovery_client()
diff --git a/python/src/helpers.py b/python/src/helpers.py
new file mode 100644
index 0000000..e7aaafc
--- /dev/null
+++ b/python/src/helpers.py
@@ -0,0 +1,16 @@
+import datetime
+import time
+
+
+def get_time_now():
+ date_now = datetime.datetime.now()
+ return str(date_now).split(" ")[0]
+
+
+def get_unix_time():
+ return time.time()
+
+
+def get_date():
+ date_now = datetime.datetime.now()
+ return str(date_now).split(" ")
diff --git a/python/src/loop.py b/python/src/loop.py
index 561a624..d3625f5 100644
--- a/python/src/loop.py
+++ b/python/src/loop.py
@@ -1,6 +1,6 @@
from time import sleep
from log_data import log_to_json
-from discovery import start_discovery
+from ble_discovery import start_discovery
def start_loop(interval=40, timeout=20):
diff --git a/python/src/main.py b/python/src/main.py
index 4561b4d..0f7ecac 100644
--- a/python/src/main.py
+++ b/python/src/main.py
@@ -1,5 +1,5 @@
import os
-from discovery import start_discovery
+from ble_discovery import start_discovery
from log_data import log_to_json
from loop import start_loop
from check_update import check_for_update
diff --git a/python/src/start_discovery_server.py b/python/src/start_discovery_server.py
new file mode 100644
index 0000000..2eb9c21
--- /dev/null
+++ b/python/src/start_discovery_server.py
@@ -0,0 +1,2 @@
+from find_gateways import start_discovery_server
+start_discovery_server()