Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a tab for configuring static ip addresses #182

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 147 additions & 8 deletions ex_installer/ex_commandstation.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ def setup_config_frame(self):
tab_list = [
"General",
"WiFi Options",
"TrackManager Config"
"TrackManager Config",
"Ethernet Options"
]
for tab in tab_list:
self.config_tabview.add(tab)
Expand All @@ -223,6 +224,8 @@ def setup_config_frame(self):
self.wifi_tab_frame.grid(**tab_frame_options)
self.track_tab_frame = ctk.CTkFrame(self.config_tabview.tab("TrackManager Config"), border_width=0)
self.track_tab_frame.grid(**tab_frame_options)
self.ethernet_tab_frame = ctk.CTkFrame(self.config_tabview.tab("Ethernet Options"), border_width=0)
self.ethernet_tab_frame.grid(**tab_frame_options)

# Create options frames
self.switch_frame = ctk.CTkFrame(self.general_tab_frame, border_width=0)
Expand Down Expand Up @@ -329,6 +332,27 @@ def setup_config_frame(self):
command=self.set_ethernet, font=self.instruction_font)
CreateToolTip(self.ethernet_switch, ethernet_tip,
"https://dcc-ex.com/reference/hardware/ethernet-boards.html")

# Set up Ethernet Widgets
self.ethernet_static_ip_switch = ctk.CTkSwitch(self.ethernet_tab_frame, text="Static IP address",
onvalue="on", offvalue="off",
width=100, command=self.set_ethernet_static_ip,
font=self.instruction_font)
self.ethernet_ip_frame = ctk.CTkFrame(self.ethernet_tab_frame, border_width=0)
self.ethernet_ip_label = ctk.CTkLabel(self.ethernet_ip_frame, text="IP:",
font=self.instruction_font)
self.ethernet_ip_a_entry = ctk.CTkEntry(self.ethernet_ip_frame,
placeholder_text="192",
width=50, fg_color="white", font=self.instruction_font)
self.ethernet_ip_b_entry = ctk.CTkEntry(self.ethernet_ip_frame,
placeholder_text="168",
width=50, fg_color="white", font=self.instruction_font)
self.ethernet_ip_c_entry = ctk.CTkEntry(self.ethernet_ip_frame,
placeholder_text="1",
width=50, fg_color="white", font=self.instruction_font)
self.ethernet_ip_d_entry = ctk.CTkEntry(self.ethernet_ip_frame,
placeholder_text="200",
width=50, fg_color="white", font=self.instruction_font)

# Track Manager Options
self.track_modes_enabled = ctk.StringVar(self, value="off")
Expand Down Expand Up @@ -450,21 +474,36 @@ def setup_config_frame(self):
self.track_b_label.grid(column=0, row=1, sticky="e", **grid_options)
self.track_b_combo.grid(column=1, row=1, sticky="w", **grid_options)
self.track_b_id_label.grid(column=2, row=1, sticky="e", **grid_options)
self.track_b_entry.grid(column=3, row=1, sticky="w", **grid_options)
self.track_b_entry.grid(column=3, row=1, sticky="w", **grid_options)

# Layout ethernet_frame
self.ethernet_tab_frame.grid_columnconfigure(0, weight=1)
self.ethernet_tab_frame.grid_rowconfigure((0, 1), weight=1)
self.ethernet_static_ip_switch.grid(column=0, row=0, **grid_options)
self.ethernet_ip_frame.grid_columnconfigure((0, 1, 2, 3, 4), weight=1)
self.ethernet_ip_frame.grid_rowconfigure(0, weight=1)
self.ethernet_ip_label.grid(column=0, row=0,sticky="e", **grid_options)
self.ethernet_ip_a_entry.grid(column=1, row=0,sticky="e", **grid_options)
self.ethernet_ip_b_entry.grid(column=2, row=0,sticky="e", **grid_options)
self.ethernet_ip_c_entry.grid(column=3, row=0,sticky="e", **grid_options)
self.ethernet_ip_d_entry.grid(column=4, row=0,sticky="e", **grid_options)

# Layout WiFi tab
self.wifi_options_frame.grid(column=0, row=0, sticky="nsew")

# Layout general tab
self.general_tab_frame.grid_columnconfigure(0, weight=1)
self.general_tab_frame.grid_columnconfigure(1, weight=2)
self.general_tab_frame.grid_rowconfigure(0, weight=1)
self.switch_frame.grid(column=0, row=0, **grid_options)
self.options_frame.grid(column=1, row=0, **grid_options)

# Layout WiFi tab
self.wifi_options_frame.grid(column=0, row=0, sticky="nsew")
self.options_frame.grid(column=1, row=0, **grid_options)

# Layout TrackManager tab
self.track_modes_frame.grid(column=0, row=0, sticky="nsew")

# Layout Ethernet tab
self.ethernet_ip_frame.grid(column=0, row=1)

# Layout config_frame
self.config_frame.grid_columnconfigure(0, weight=1)
self.config_frame.grid_rowconfigure(1, weight=1)
Expand Down Expand Up @@ -581,6 +620,7 @@ def set_wifi(self):
if self.wifi_switch.get() == "on":
if self.ethernet_switch.get() == "on":
self.ethernet_switch.deselect()
self.refresh_ethernet_tab_option()
self.config_tabview._segmented_button._buttons_dict["WiFi Options"].configure(state="normal")
self.set_wifi_widgets()
self.log.debug("WiFi enabled")
Expand Down Expand Up @@ -611,17 +651,44 @@ def set_wifi_widgets(self):
self.wifi_pwd_entry.configure(placeholder_text="Enter your WiFi password")
self.log.debug("WiFi ST mode selected")

def refresh_ethernet_tab_option(self):
"""
Function to refresh the tab button (used by wifi too)
"""
if self.ethernet_switch.get() == "on":
self.config_tabview._segmented_button._buttons_dict["Ethernet Options"].configure(state="normal")
else:
self.config_tabview._segmented_button._buttons_dict["Ethernet Options"].configure(state="disabled")
self.set_ethernet_static_ip()

def set_ethernet(self):
"""
Function to enable Ethernet support
"""
if self.ethernet_switch.get() == "on":
if self.wifi_switch.get() == "on":
self.wifi_switch.deselect()
self.set_wifi()
self.set_wifi()
self.log.debug("Ethernet enabled")
else:
self.log.debug("Ethernet disabled")
self.log.debug("Ethernet disabled")
self.refresh_ethernet_tab_option()

def set_ethernet_static_ip(self):
if self.ethernet_static_ip_switch.get() == "on":
self.ethernet_ip_label.grid()
self.ethernet_ip_a_entry.grid()
self.ethernet_ip_b_entry.grid()
self.ethernet_ip_c_entry.grid()
self.ethernet_ip_d_entry.grid()
self.log.debug("Static IP enabled")
else:
self.ethernet_ip_label.grid_remove()
self.ethernet_ip_a_entry.grid_remove()
self.ethernet_ip_b_entry.grid_remove()
self.ethernet_ip_c_entry.grid_remove()
self.ethernet_ip_d_entry.grid_remove()
self.log.debug("Static IP disabled")

def decrement_channel(self):
"""
Expand All @@ -648,6 +715,8 @@ def display_config_screen(self):
self.config_frame.grid()
self.set_display()
self.set_wifi()
self.set_ethernet()
self.set_ethernet_static_ip()
self.set_track_modes()
self.set_advanced_config()
self.check_motor_driver(self.motor_driver_combo.get())
Expand Down Expand Up @@ -780,6 +849,57 @@ def delete_config_files(self):
self.process_error(f"Failed to delete one or more files: {file_list}")
self.log.error("Failed to delete: %s", file_list)

def ethernet_is_ip_equal(self, ip1, ip2):
for i in range(4):
if(ip1[i] != ip2[i]):
return False
return True

def ethernet_check_for_reserved_ips(self, ip):
# from https://en.wikipedia.org/wiki/Reserved_IP_addresses
if self.ethernet_is_ip_equal(ip, [255, 255, 255, 255]):
return True
if self.ethernet_is_ip_equal(ip, [240, 0, 0, 0]):
return True
if self.ethernet_is_ip_equal(ip, [233, 252, 0, 0]):
return True
if self.ethernet_is_ip_equal(ip, [224, 0, 0, 0]):
return True
if self.ethernet_is_ip_equal(ip, [203, 0, 113, 0]):
return True
if self.ethernet_is_ip_equal(ip, [198, 0, 0, 0]):
return True
if self.ethernet_is_ip_equal(ip, [198, 51, 100, 0]):
return True
if self.ethernet_is_ip_equal(ip, [192, 0, 0, 0]):
return True
if self.ethernet_is_ip_equal(ip, [192, 0, 2, 0]):
return True
if self.ethernet_is_ip_equal(ip, [192, 88, 99, 0]):
return True
if self.ethernet_is_ip_equal(ip, [192, 168, 0, 0]):
return True
if self.ethernet_is_ip_equal(ip, [172, 16, 0, 0]):
return True
if self.ethernet_is_ip_equal(ip, [169, 254, 0, 0]):
return True
if self.ethernet_is_ip_equal(ip, [127, 0, 0, 0]):
return True
if self.ethernet_is_ip_equal(ip, [100, 64, 0, 0]):
return True
if self.ethernet_is_ip_equal(ip, [10, 0, 0, 0]):
return True
if self.ethernet_is_ip_equal(ip, [0, 0, 0, 0]):
return True
return False

def ethernet_get_ip_number(self, entry):
num = entry.get()
if not num.isnumeric():
return (False, num)
num = int(num)
return ((num >= 0) and (num <= 255), num)

def generate_config(self):
"""
Function to validate options and return any errors
Expand Down Expand Up @@ -838,6 +958,25 @@ def generate_config(self):
param_errors.append("Can not have both Ethernet and WiFi enabled")
else:
config_list.append("#define ENABLE_ETHERNET true\n")
if self.ethernet_static_ip_switch.get() == "on":
ip_entries = [self.ethernet_ip_a_entry, self.ethernet_ip_b_entry, self.ethernet_ip_c_entry, self.ethernet_ip_d_entry]
ip_data = []
for entry in ip_entries:
ip_num = self.ethernet_get_ip_number(entry)
if not ip_num[0]:
param_errors.append("Invalid static IP value")
ip_data = None
break

ip_data.append(ip_num[1])

if ip_data:
#check for know ip addresses
if self.ethernet_check_for_reserved_ips(ip_data):
param_errors.append("IP value is reserved")
else:
line = "#define IP_ADDRESS { " + str(ip_data[0]) + ', ' + str(ip_data[1]) + ', ' + str(ip_data[2]) + ', ' + str(ip_data[3]) + ' }\n'
config_list.append(line)
if self.override_current_limit.get() == "on":
try:
int(self.current_limit.get())
Expand Down
Loading