1
0
forked from iarv/contact

Compare commits

...

5 Commits

Author SHA1 Message Date
pdxlocations
49281f9106 works but not what i want 2025-02-21 18:13:30 -08:00
pdxlocations
f644b92356 use global interface in save 2025-02-20 22:32:17 -08:00
pdxlocations
3db44f4ae3 remove double writeconfig 2025-02-20 21:57:09 -08:00
pdxlocations
8c837e68a0 keep cursor in the input window (#130) 2025-02-18 22:30:42 -08:00
pdxlocations
5dd06624e3 do close interface after region set 2025-02-12 16:08:18 -08:00
6 changed files with 76 additions and 33 deletions

View File

@@ -1,4 +1,5 @@
interface = None
lock = None
display_log = False
all_messages = {}
channel_list = []
@@ -9,5 +10,4 @@ myNodeNum = 0
selected_channel = 0
selected_message = 0
selected_node = 0
current_window = 0
lock = None
current_window = 0

View File

@@ -56,6 +56,8 @@ def main(stdscr):
confirmation = get_list_input("Your region is UNSET. Set it now?", "Yes", ["Yes", "No"])
if confirmation == "Yes":
set_region()
globals.interface.close()
globals.interface = initialize_interface(args)
logging.info("Interface initialized")
globals.myNodeNum = get_nodeNum()
globals.channel_list = get_channels()

View File

@@ -5,7 +5,7 @@ import base64
from db_handler import update_node_info_in_db
import globals
def save_changes(interface, menu_path, modified_settings):
def save_changes(menu_path, modified_settings):
"""
Save changes to the device based on modified settings.
:param interface: Meshtastic interface instance
@@ -17,7 +17,7 @@ def save_changes(interface, menu_path, modified_settings):
logging.info("No changes to save. modified_settings is empty.")
return
node = interface.getNode('^local')
node = globals.interface.getNode('^local')
if menu_path[1] == "Radio Settings" or menu_path[1] == "Module Settings":
config_category = menu_path[2].lower() # for radio and module configs
@@ -27,7 +27,7 @@ def save_changes(interface, menu_path, modified_settings):
lon = float(modified_settings.get('longitude', 0.0))
alt = int(modified_settings.get('altitude', 0))
interface.localNode.setFixedPosition(lat, lon, alt)
globals.interface.localNode.setFixedPosition(lat, lon, alt)
logging.info(f"Updated {config_category} with Latitude: {lat} and Longitude {lon} and Altitude {alt}")
return
@@ -122,10 +122,5 @@ def save_changes(interface, menu_path, modified_settings):
except Exception as e:
logging.error(f"Failed to write configuration for category '{config_category}': {e}")
node.writeConfig(config_category)
logging.info(f"Changes written to config category: {config_category}")
except Exception as e:
logging.error(f"Error saving changes: {e}")
logging.error(f"Error saving changes: {e}")

View File

@@ -152,7 +152,7 @@ def settings_menu(stdscr, interface):
menu_win.erase()
menu_win.refresh()
if show_save_option and selected_index == len(options):
save_changes(interface, menu_path, modified_settings)
save_changes(menu_path, modified_settings)
modified_settings.clear()
logging.info("Changes Saved")

View File

@@ -74,7 +74,6 @@ def handle_resize(stdscr, firstrun):
win.box()
win.refresh()
entry_win.keypad(True)
curses.curs_set(1)
@@ -90,13 +89,12 @@ def handle_resize(stdscr, firstrun):
def main_ui(stdscr):
global input_text
input_text = ""
stdscr.keypad(True)
get_channels()
handle_resize(stdscr, True)
input_text = ""
while True:
draw_text_field(entry_win, f"Input: {input_text[-(stdscr.getmaxyx()[1] - 10):]}", get_color("input"))
@@ -444,6 +442,11 @@ def draw_node_list():
refresh_pad(2)
# Restore cursor to input field
entry_win.move(1, len("Input: ") + len(input_text)+1)
entry_win.refresh()
curses.curs_set(1)
def select_channel(idx):
old_selected_channel = globals.selected_channel
globals.selected_channel = max(0, min(idx, len(globals.channel_list) - 1))
@@ -540,6 +543,11 @@ def draw_packetlog_win():
packetlog_win.box()
packetlog_win.refresh()
# Restore cursor to input field
entry_win.move(1, len("Input: ") + len(input_text)+1)
entry_win.refresh()
curses.curs_set(1)
def search(win):
start_idx = globals.selected_node
select_func = select_node

View File

@@ -4,39 +4,59 @@ import logging
import base64
def extract_fields(message_instance, current_config=None):
FIELD_EXCLUSION_MAP = {
"global": {"sessionkey"},
"channel": {"channel_num", "id"},
"radio": {"ignore_incoming"},
"module": None
}
def extract_fields(message_instance, current_config=None, parent_context=None, exclusion_map=None):
if isinstance(current_config, dict): # Handle dictionaries
return {key: (None, current_config.get(key, "Not Set")) for key in current_config}
if not hasattr(message_instance, "DESCRIPTOR"):
return {}
if exclusion_map is None:
exclusion_map = FIELD_EXCLUSION_MAP # Use default if not provided
# Combine global exclusions with context-specific exclusions
global_exclusions = exclusion_map.get("global", set())
context_exclusions = exclusion_map.get(parent_context, set())
total_exclusions = global_exclusions.union(context_exclusions)
menu = {}
fields = message_instance.DESCRIPTOR.fields
for field in fields:
if field.name in {"sessionkey", "channel_num", "id", "ignore_incoming"}: # Skip certain fields
if field.name in total_exclusions:
continue
if field.message_type: # Nested message
nested_instance = getattr(message_instance, field.name)
nested_config = getattr(current_config, field.name, None) if current_config else None
menu[field.name] = extract_fields(nested_instance, nested_config)
menu[field.name] = extract_fields(
nested_instance,
nested_config,
parent_context=parent_context,
exclusion_map=exclusion_map
)
elif field.enum_type: # Handle enum fields
current_value = getattr(current_config, field.name, "Not Set") if current_config else "Not Set"
if isinstance(current_value, int): # If the value is a number, map it to its name
if isinstance(current_value, int): # Map enum number to name
enum_value = field.enum_type.values_by_number.get(current_value)
if enum_value: # Check if the enum value exists
current_value_name = f"{enum_value.name}"
else:
current_value_name = f"Unknown ({current_value})"
current_value_name = f"{enum_value.name}" if enum_value else f"Unknown ({current_value})"
menu[field.name] = (field, current_value_name)
else:
menu[field.name] = (field, current_value) # Non-integer values
else: # Handle other field types
menu[field.name] = (field, current_value)
else: # Other field types
current_value = getattr(current_config, field.name, "Not Set") if current_config else "Not Set"
menu[field.name] = (field, current_value)
return menu
def generate_menu_from_protobuf(interface):
# Function to generate the menu structure from protobuf messages
menu_structure = {"Main Menu": {}}
@@ -68,9 +88,18 @@ def generate_menu_from_protobuf(interface):
for i in range(8):
current_channel = interface.localNode.getChannelByChannelIndex(i)
if current_channel:
channel_config = extract_fields(channel, current_channel.settings)
# Convert 'psk' field to Base64
channel_config["psk"] = (channel_config["psk"][0], base64.b64encode(channel_config["psk"][1]).decode('utf-8'))
# Apply 'channel' context here
channel_config = extract_fields(
channel,
current_channel.settings,
parent_context="channel", # Dynamic context
exclusion_map=FIELD_EXCLUSION_MAP # Pass exclusion map
)
# Convert 'psk' to Base64
channel_config["psk"] = (
channel_config["psk"][0],
base64.b64encode(channel_config["psk"][1]).decode('utf-8')
)
menu_structure["Main Menu"]["Channels"][f"Channel {i + 1}"] = channel_config
# Add Radio Settings
@@ -99,14 +128,23 @@ def generate_menu_from_protobuf(interface):
ordered_position_menu[key] = value
# Update the menu with the new order
menu_structure["Main Menu"]["Radio Settings"]["position"] = ordered_position_menu
menu_structure["Main Menu"]["Radio Settings"] = extract_fields(
radio,
current_radio_config,
parent_context="radio",
exclusion_map=FIELD_EXCLUSION_MAP
)
# Add Module Settings
module = module_config_pb2.ModuleConfig()
current_module_config = interface.localNode.moduleConfig if interface else None
menu_structure["Main Menu"]["Module Settings"] = extract_fields(module, current_module_config)
menu_structure["Main Menu"]["Module Settings"] = extract_fields(
module,
current_module_config,
parent_context="module", # Apply 'module' context
exclusion_map=FIELD_EXCLUSION_MAP
)
# Add App Settings
menu_structure["Main Menu"]["App Settings"] = {"Open": "app_settings"}