Skip to content

Commit a648140

Browse files
authored
Merge pull request #456 from Stefal/detect_rtkbase
Detect rtkbase tool
2 parents 78f20c1 + f0a4512 commit a648140

File tree

12 files changed

+518
-2
lines changed

12 files changed

+518
-2
lines changed

tools/find_rtkbase/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Changelog
2+
3+
## [0.1] - not released
4+
- First release
29 MB
Binary file not shown.
34.2 MB
Binary file not shown.

tools/find_rtkbase/find_rtkbase.py

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#! /usr/bin/env python3
2+
3+
import tkinter as tk
4+
import tkinter.font
5+
import tkinter.ttk as ttk
6+
import webbrowser
7+
import threading
8+
import scan_network
9+
import tkinter as tk
10+
from tkinter import ttk
11+
import logging
12+
import argparse
13+
import os
14+
logging.basicConfig(format='%(levelname)s: %(message)s')
15+
log = logging.getLogger(__name__)
16+
log.setLevel('ERROR')
17+
18+
19+
class MyApp:
20+
def __init__(self, master, ports=[80, 443], allscan=False):
21+
self.master = master
22+
self.ports = ports
23+
self.allscan = allscan
24+
master.title("Find RTKBase v0.1")
25+
master.geometry("400x200")
26+
master.columnconfigure(0, weight=1)
27+
master.rowconfigure(0, weight=1)
28+
default_font = tkinter.font.nametofont("TkDefaultFont")
29+
default_font.configure(size=12)
30+
self._create_gui()
31+
self.available_base = None
32+
if os.name == 'nt':
33+
log.debug('"False" scan to pop up the windows firewall window')
34+
scan_network.zeroconf_scan('RTKBase Web Server', '_http._tcp.local.', timeout=0)
35+
36+
def _create_gui(self):
37+
38+
#Scanning and results frame
39+
self.top_frame = ttk.Frame(self.master, padding="10")
40+
self.top_frame.grid(row=0, column=0, sticky="nsew")
41+
self.top_frame.columnconfigure(0, weight=1)
42+
self.top_frame.rowconfigure(97, weight=1)
43+
self.intro_label = ttk.Label(self.top_frame, text="Click 'Find' to search for RTKBase")
44+
self.intro_label.grid(column=0, row=0, pady=10)
45+
self.scanninglabel = ttk.Label(self.top_frame, text="Searching....")
46+
self.scanninglabel.grid(column=0, row=0, pady=10)
47+
self.scanninglabel.grid_remove()
48+
self.progress_bar = ttk.Progressbar(self.top_frame,mode='indeterminate')
49+
self.progress_bar.grid(column=2, columnspan=2, row=0, pady=10)
50+
self.progress_bar.grid_remove()
51+
self.nobase_label = ttk.Label(self.top_frame, text="No base station detected")
52+
self.nobase_label.grid(column=0, row=0, columnspan=2, pady=10)
53+
self.nobase_label.grid_remove()
54+
self.error_label = ttk.Label(self.top_frame, text="Error")
55+
self.error_label.grid(column=0, row=0, columnspan=2, pady=10)
56+
self.error_label.grid_remove()
57+
58+
59+
# Scan/Quit Frame
60+
self.bottom_frame = ttk.Frame(self.top_frame)
61+
self.bottom_frame.grid(column=0, row=99, columnspan=4, sticky="ew")
62+
self.bottom_frame.columnconfigure(0, weight=1)
63+
self.bottom_frame.columnconfigure(1, weight=1)
64+
self.scanButton = ttk.Button(self.bottom_frame, text="Find", command=self.scan_network)
65+
self.scanButton.grid(column=0, row=0, padx=(0, 5), sticky="e")
66+
self.quitButton = ttk.Button(self.bottom_frame, text="Quit", command=self.master.quit)
67+
self.quitButton.grid(column=1, row=0, padx=(5, 0), sticky="w")
68+
69+
# info Frame
70+
""" self.info_frame = ttk.Frame(self.top_frame)
71+
self.info_frame.grid(column=3, row=99, sticky="ew")
72+
self.version_label = ttk.Label(self.info_frame, text="v0.1")
73+
self.version_label.grid(sticky="e") """
74+
75+
def scan_network(self):
76+
77+
#Cleaning GUI
78+
try:
79+
self.intro_label.grid_remove()
80+
self.error_label.grid_remove()
81+
for label in self.base_labels_list:
82+
label.destroy()
83+
for button in self.base_buttons_list:
84+
button.destroy()
85+
except AttributeError:
86+
pass
87+
self.nobase_label.grid_remove()
88+
self.scanButton.config(state=tk.DISABLED)
89+
self.scanninglabel.grid()
90+
self.progress_bar.grid()
91+
self.progress_bar.start()
92+
93+
#Launch scan
94+
thread = threading.Thread(target=self._scan_thread)
95+
thread.start()
96+
97+
def _scan_thread(self):
98+
log.debug(f"Start Scanning (ports {self.ports})")
99+
try:
100+
self.available_base = scan_network.main(self.ports, self.allscan)
101+
#self.available_base = [{'ip': '192.168.1.23', 'port' : 80, 'fqdn' : 'rtkbase.home'},
102+
# {'ip': '192.168.1.124', 'port' : 80, 'fqdn' : 'localhost'},
103+
# {'ip': '192.168.1.199', 'port' : 443, 'fqdn' : 'basegnss'} ]
104+
#self.available_base = [{'ip': '192.168.1.123', 'port' : 80, 'fqdn' : 'localhost'},]
105+
except Exception as e:
106+
log.debug(f"Error during network scan: {e}")
107+
self.progress_bar.stop()
108+
self.progress_bar.grid_remove()
109+
self.scanninglabel.grid_remove()
110+
self.error_label.grid()
111+
self.scanButton.config(state=tk.NORMAL)
112+
return
113+
114+
log.debug("Scan terminated")
115+
self._after_scan_thread()
116+
117+
def _after_scan_thread(self):
118+
log.debug(f"available_base: {self.available_base}")
119+
self.scanninglabel.grid_remove()
120+
self.progress_bar.stop()
121+
self.progress_bar.grid_remove()
122+
self.base_labels_list = ["base" + str(i) + "Label" for i, j in enumerate(self.available_base)]
123+
self.base_buttons_list = ["base" + str(i) + "Button" for i, j in enumerate(self.available_base)]
124+
if len(self.available_base)>0:
125+
for i, base in enumerate(self.available_base):
126+
def action(ip = (base.get('server') or base.get('ip')), port = base.get('port')):
127+
self.launch_browser(ip, port)
128+
129+
self.base_labels_list[i] = ttk.Label(self.top_frame, text=f"{base.get('server') or base.get('fqdn')} ({base.get('ip')})")
130+
self.base_labels_list[i].grid(column=0, row=i)
131+
self.base_buttons_list[i] = ttk.Button(self.top_frame, text='Open', command=action)
132+
self.base_buttons_list[i].grid(column=3, row=i)
133+
else:
134+
self.nobase_label.grid()
135+
self.scanButton.config(state=tk.NORMAL)
136+
137+
def launch_browser(self, ip, port):
138+
print('{} port {}'.format(ip, port))
139+
webbrowser.open(f"http://{ip}:{port}")
140+
141+
def arg_parse():
142+
""" Parse the command line you use to launch the script """
143+
144+
parser= argparse.ArgumentParser(prog='Scan for RTKBase', description="A tool to scan network and find Rtkbase Gnss base station")
145+
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
146+
parser.add_argument("-p", "--ports", nargs='+', help="Port(s) used to find the web server. Default value is 80 and 443", default=[80, 443], type=int)
147+
parser.add_argument("-a", "--allscan", help="force scan with mDns AND ip range", action='store_true')
148+
parser.add_argument("-d", "--debug", action='store_true')
149+
parser.add_argument("--version", action="version", version="%(prog)s 1.0")
150+
args = parser.parse_args()
151+
return args
152+
153+
if __name__ == "__main__":
154+
args = arg_parse()
155+
if args.debug:
156+
log.setLevel('DEBUG')
157+
log.debug(f"Arguments: {args}")
158+
root = tk.Tk()
159+
iconpath = os.path.join(os.path.dirname(__file__), 'rtkbase_icon.png')
160+
icon = tk.PhotoImage(file=iconpath)
161+
root.wm_iconphoto(False, icon)
162+
app = MyApp(root, args.ports, args.allscan)
163+
root.mainloop()
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
3+
4+
block_cipher = None
5+
6+
7+
a = Analysis(
8+
['find_rtkbase.py'],
9+
pathex=[],
10+
binaries=[],
11+
datas=[('rtkbase_icon.png', '.') ],
12+
hiddenimports=[
13+
'zeroconf._utils.ipaddress', # and potentially others in .venv\Lib\site-packages\zeroconf\_utils, but that seems to pull in every pyd file
14+
'zeroconf._handlers.answers', # and potentially others in .venv\Lib\site-packages\zeroconf\_handlers, but that seems to pull in every pyd file
15+
],
16+
hookspath=[],
17+
hooksconfig={},
18+
runtime_hooks=[],
19+
excludes=["IPython"],
20+
win_no_prefer_redirects=False,
21+
win_private_assemblies=False,
22+
cipher=block_cipher,
23+
noarchive=False,
24+
)
25+
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
26+
27+
exe = EXE(
28+
pyz,
29+
a.scripts,
30+
a.binaries,
31+
a.zipfiles,
32+
a.datas,
33+
[],
34+
name='find_rtkbase',
35+
debug=False,
36+
bootloader_ignore_signals=False,
37+
strip=False,
38+
upx=True,
39+
upx_exclude=[],
40+
runtime_tmpdir=None,
41+
console=True,
42+
disable_windowed_traceback=False,
43+
argv_emulation=False,
44+
target_arch=None,
45+
codesign_identity=None,
46+
entitlements_file=None,
47+
)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
3+
4+
block_cipher = None
5+
6+
7+
a = Analysis(
8+
['find_rtkbase.py'],
9+
pathex=[],
10+
binaries=[],
11+
datas=[('rtkbase_icon.png', '.') ],
12+
hiddenimports=[
13+
'zeroconf._utils.ipaddress', # and potentially others in .venv\Lib\site-packages\zeroconf\_utils, but that seems to pull in every pyd file
14+
'zeroconf._handlers.answers', # and potentially others in .venv\Lib\site-packages\zeroconf\_handlers, but that seems to pull in every pyd file
15+
],
16+
hookspath=[],
17+
hooksconfig={},
18+
runtime_hooks=[],
19+
excludes=["IPython"],
20+
win_no_prefer_redirects=False,
21+
win_private_assemblies=False,
22+
cipher=block_cipher,
23+
noarchive=False,
24+
)
25+
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
26+
27+
exe = EXE(
28+
pyz,
29+
a.scripts,
30+
a.binaries,
31+
a.zipfiles,
32+
a.datas,
33+
[],
34+
name='find_rtkbase',
35+
debug=False,
36+
bootloader_ignore_signals=False,
37+
strip=False,
38+
upx=True,
39+
upx_exclude=[],
40+
runtime_tmpdir=None,
41+
console=False,
42+
disable_windowed_traceback=False,
43+
argv_emulation=False,
44+
target_arch=None,
45+
codesign_identity=None,
46+
entitlements_file=None,
47+
)
9.66 KB
Loading

tools/find_rtkbase/readme.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# find_rtkbase
2+
3+
This is a gui app to find RTKBase base station on the local network.
4+
Executable files are available in the /dist directory for Windows x64 and Gnu/Linux x86_64.
5+
6+
![find_rtkbase gui screenshot](find_rtkbase_screenshot.png)
7+
## building binary/executable from source:
8+
9+
- without console option:
10+
11+
```pyinstaller find_rtkbase_noconsole.spec```
12+
13+
- with console option (find_rtkbase --help):
14+
15+
```pyinstaller find_rtkbase_console.spec```
16+
385 KB
Loading

0 commit comments

Comments
 (0)