From 2d828a6907df67b59e316433c755660abe9ab4a2 Mon Sep 17 00:00:00 2001 From: masto Date: Mon, 2 Oct 2023 21:17:45 +0200 Subject: [PATCH 01/17] - CLI CMD "ATR" optimize output for long paths - Fixed: CLI CMD "ATR" Call & Port switched in header --- cli/cliMain.py | 20 +++++++++++++++----- constant.py | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/cli/cliMain.py b/cli/cliMain.py index bbbbc4a5..64b38753 100644 --- a/cli/cliMain.py +++ b/cli/cliMain.py @@ -521,9 +521,10 @@ def cmd_aprs_trace(self): intervall_str = 'off' else: intervall_str = str(_intervall) - out = '\r # APRS-Tracer Beacon\r\r' - out += f'Tracer Call : {self.port_handler.aprs_ais.be_tracer_port}\r' - out += f'Tracer Port : {self.port_handler.aprs_ais.be_tracer_station}\r' + # out = '\r # APRS-Tracer Beacon\r\r' + out = '\r' + out += f'Tracer Port : {self.port_handler.aprs_ais.be_tracer_port}\r' + out += f'Tracer Call : {self.port_handler.aprs_ais.be_tracer_station}\r' out += f'Tracer WIDE Path: {self.port_handler.aprs_ais.be_tracer_wide}\r' out += f'Tracer intervall: {intervall_str}\r' out += f'Last Trace send : {_last_send}\r\r' @@ -538,9 +539,18 @@ def cmd_aprs_trace(self): _path = ', '.join(_ent.get('path', [])) _loc = f'{_ent.get("locator", "------")[:6]}({round(_ent.get("distance", -1))}km)' _call = _ent.get('call', '') - _path = ', '.join(_ent.get('path', [])) + _path_raw = _ent.get('path', []) + _path = '' + _c = 0 + for _el in _path_raw: + _path += f'{_el}> ' + _c += 1 + if _c == 3: + _path += '\r' + ''.rjust(42, ' ') + _c = 0 + out += f'{_td.rjust(9):10}{_ent.get("port_id", "-"):6}{_call:10}{_loc:16}' - out += f'{_path}' + out += f'{_path[:-2]}' out += '\r' return out + '\r' diff --git a/constant.py b/constant.py index 17e76b06..e25a8683 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.97.9' +VER = '2.98.0dev' LANGUAGE = 0 # QUICK FIX """ 0 = German From f5d8e024270d2ae364103ea3d95b787637beed15 Mon Sep 17 00:00:00 2001 From: masto Date: Tue, 3 Oct 2023 22:28:43 +0200 Subject: [PATCH 02/17] - moved cli related fnc's to cliMain.py --- ax25/ax25Statistics.py | 89 +---------------------------- ax25aprs/aprs_station.py | 23 -------- cli/cliMain.py | 118 ++++++++++++++++++++++++++++++++++++++- constant.py | 2 +- gui/guiAPRS_wx_plot.py | 3 - gui/guiAPRS_wx_tree.py | 1 - 6 files changed, 117 insertions(+), 119 deletions(-) diff --git a/ax25/ax25Statistics.py b/ax25/ax25Statistics.py index 2f6865d9..7c0fc8f8 100644 --- a/ax25/ax25Statistics.py +++ b/ax25/ax25Statistics.py @@ -4,11 +4,10 @@ import pickle -from UserDB.UserDBmain import USER_DB from constant import CFG_mh_data_file, CFG_port_stat_data_file from fnc.cfg_fnc import cleanup_obj_dict, set_obj_att from fnc.socket_fnc import check_ip_add_format -from fnc.str_fnc import conv_time_for_sorting, get_timedelta_str +from fnc.str_fnc import conv_time_for_sorting def get_time_str(): @@ -304,92 +303,6 @@ def mh_ip_failed(self, axip: str): def mh_set_ip(self, call: str, axip: (str, int)): self.calls[call].axip_add = axip - def mh_out_cli(self, max_ent=20): - out = '\r' - # out += '\r < MH - List >\r\r' - c = 0 - max_c = 0 - """ - tp = 0 - tb = 0 - rj = 0 - """ - sort_list = self.get_sort_mh_entry('last', False) - - for call in list(sort_list.keys()): - max_c += 1 - if max_c > max_ent: - break - time_delta_str = get_timedelta_str(sort_list[call].last_seen) - - out += f'{time_delta_str} P:{sort_list[call].port:4} {sort_list[call].own_call:9}'.ljust(27, " ") - """ - tp += sort_list[call].pac_n - tb += sort_list[call].byte_n - rj += sort_list[call].rej_n - """ - c += 1 - if c == 2: # Breite - c = 0 - out += '\r' - """ - out += '\r' - out += '\rTotal Packets Rec.: ' + str(tp) - out += '\rTotal REJ-Packets Rec.: ' + str(rj) - out += '\rTotal Bytes Rec.: ' + str(tb) - """ - out += '\r' - - return out - - def mh_long_out_cli(self, max_ent=10): - out = '\r' - out += "-----Time-Port---Call------via-------LOC------Dist(km)--Type---Packets\r" - max_c = 0 - """ - tp = 0 - tb = 0 - rj = 0 - """ - sort_list = self.get_sort_mh_entry('last', False) - - for call in list(sort_list.keys()): - max_c += 1 - if max_c > max_ent: - break - time_delta_str = get_timedelta_str(sort_list[call].last_seen) - via = sort_list[call].route - if via: - via = via[-1] - else: - via = '' - loc = '' - dis = '' - typ = '' - userdb_ent = USER_DB.get_entry(sort_list[call].own_call, add_new=False) - if userdb_ent: - loc = userdb_ent.LOC - if userdb_ent.Distance: - dis = str(userdb_ent.Distance) - typ = userdb_ent.TYP - - out += (f' {time_delta_str:9}{sort_list[call].port:7}{sort_list[call].own_call:10}' - f'{via:10}{loc:9}{dis:10}{typ:7}{sort_list[call].pac_n}') - """ - tp += sort_list[call].pac_n - tb += sort_list[call].byte_n - rj += sort_list[call].rej_n - """ - out += '\r' - out += '\r' - """ - out += '\rTotal Packets Rec.: ' + str(tp) - out += '\rTotal REJ-Packets Rec.: ' + str(rj) - out += '\rTotal Bytes Rec.: ' + str(tb) - out += '\r' - """ - return out - def mh_out_beacon(self, max_ent=12): _tmp = self.get_sort_mh_entry('last', False) _ret = '' diff --git a/ax25aprs/aprs_station.py b/ax25aprs/aprs_station.py index b12bd4d1..c8742ea6 100644 --- a/ax25aprs/aprs_station.py +++ b/ax25aprs/aprs_station.py @@ -381,29 +381,6 @@ def get_wx_entry_sort_distance(self): def get_wx_data(self): return dict(self.aprs_wx_msg_pool) - def get_wx_cli_out(self, max_ent=10): - _data = self.get_wx_entry_sort_distance() - if not _data: - return '' - max_c = 0 - out = '\r-----Last-Port--Call------LOC-------------Temp-Press---Hum-Lum-Rain(24h)-\r' - for k in _data: - max_c += 1 - if max_c > max_ent: - break - _ent = self.aprs_wx_msg_pool[k][-1] - _td = get_timedelta_str(_ent['rx_time']) - _loc = f'{_ent.get("locator", "------")[:6]}({round(_ent.get("distance", -1))}km)' - _pres = f'{_ent["weather"].get("pressure", 0):.2f}' - _rain = f'{_ent["weather"].get("rain_24h", 0):.3f}' - out += f'{_td.rjust(9):10}{_ent.get("port_id", ""):6}{k:10}{_loc:16}' - out += f'{str(round(_ent["weather"].get("temperature", 0))):5}' - out += f'{_pres:7} ' - out += f'{_ent["weather"].get("humidity", 0):3} ' - out += f'{_ent["weather"].get("luminosity", 0):3} ' - out += f'{_rain:6}\r' - return out - ##################### # @staticmethod diff --git a/cli/cliMain.py b/cli/cliMain.py index 64b38753..10b52c72 100644 --- a/cli/cliMain.py +++ b/cli/cliMain.py @@ -470,10 +470,49 @@ def cmd_mh(self): parm = int(self.parameter[0]) except ValueError: pass - ret = MH_LIST.mh_out_cli(max_ent=parm) + ret = self._get_mh_out_cli(max_ent=parm) return ret + '\r' + @staticmethod + def _get_mh_out_cli(max_ent=20): + out = '\r' + # out += '\r < MH - List >\r\r' + c = 0 + max_c = 0 + """ + tp = 0 + tb = 0 + rj = 0 + """ + sort_list = MH_LIST.get_sort_mh_entry('last', False) + + for call in list(sort_list.keys()): + max_c += 1 + if max_c > max_ent: + break + time_delta_str = get_timedelta_str(sort_list[call].last_seen) + + out += f'{time_delta_str} P:{sort_list[call].port:4} {sort_list[call].own_call:9}'.ljust(27, " ") + """ + tp += sort_list[call].pac_n + tb += sort_list[call].byte_n + rj += sort_list[call].rej_n + """ + c += 1 + if c == 2: # Breite + c = 0 + out += '\r' + """ + out += '\r' + out += '\rTotal Packets Rec.: ' + str(tp) + out += '\rTotal REJ-Packets Rec.: ' + str(rj) + out += '\rTotal Bytes Rec.: ' + str(tb) + """ + out += '\r' + + return out + def cmd_mhl(self): parm = 10 if self.parameter: @@ -481,10 +520,59 @@ def cmd_mhl(self): parm = int(self.parameter[0]) except ValueError: pass - ret = MH_LIST.mh_long_out_cli(max_ent=parm) + ret = self._get_mh_long_out_cli(max_ent=parm) return ret + '\r' + @staticmethod + def _get_mh_long_out_cli(max_ent=10): + out = '\r' + out += "-----Time-Port---Call------via-------LOC------Dist(km)--Type---Packets\r" + max_c = 0 + """ + tp = 0 + tb = 0 + rj = 0 + """ + sort_list = MH_LIST.get_sort_mh_entry('last', False) + + for call in list(sort_list.keys()): + max_c += 1 + if max_c > max_ent: + break + time_delta_str = get_timedelta_str(sort_list[call].last_seen) + via = sort_list[call].route + if via: + via = via[-1] + else: + via = '' + loc = '' + dis = '' + typ = '' + userdb_ent = USER_DB.get_entry(sort_list[call].own_call, add_new=False) + if userdb_ent: + loc = userdb_ent.LOC + if userdb_ent.Distance: + dis = str(userdb_ent.Distance) + typ = userdb_ent.TYP + + out += (f' {time_delta_str:9}{sort_list[call].port:7}{sort_list[call].own_call:10}' + f'{via:10}{loc:9}{dis:10}{typ:7}{sort_list[call].pac_n}') + """ + tp += sort_list[call].pac_n + tb += sort_list[call].byte_n + rj += sort_list[call].rej_n + """ + out += '\r' + out += '\r' + """ + out += '\rTotal Packets Rec.: ' + str(tp) + out += '\rTotal REJ-Packets Rec.: ' + str(rj) + out += '\rTotal Bytes Rec.: ' + str(tb) + out += '\r' + """ + return out + def cmd_wx(self): """ WX Stations """ if self.port_handler.aprs_ais is None: @@ -495,11 +583,35 @@ def cmd_wx(self): parm = int(self.parameter[0]) except ValueError: pass - ret = self.port_handler.aprs_ais.get_wx_cli_out(max_ent=parm) # TODO move CLI shit to cliMain + ret = self._get_wx_cli_out(max_ent=parm) + if not ret: return f'\r # {STR_TABLE["cli_no_wx_data"][self.connection.cli_language]}\r\r' return ret + '\r' + def _get_wx_cli_out(self, max_ent=10): + _data = self.port_handler.aprs_ais.get_wx_entry_sort_distance() + if not _data: + return '' + max_c = 0 + out = '\r-----Last-Port--Call------LOC-------------Temp-Press---Hum-Lum-Rain(24h)-\r' + for k in _data: + max_c += 1 + if max_c > max_ent: + break + _ent = self.port_handler.aprs_ais.aprs_wx_msg_pool[k][-1] + _td = get_timedelta_str(_ent['rx_time']) + _loc = f'{_ent.get("locator", "------")[:6]}({round(_ent.get("distance", -1))}km)' + _pres = f'{_ent["weather"].get("pressure", 0):.2f}' + _rain = f'{_ent["weather"].get("rain_24h", 0):.3f}' + out += f'{_td.rjust(9):10}{_ent.get("port_id", ""):6}{k:10}{_loc:16}' + out += f'{str(round(_ent["weather"].get("temperature", 0))):5}' + out += f'{_pres:7} ' + out += f'{_ent["weather"].get("humidity", 0):3} ' + out += f'{_ent["weather"].get("luminosity", 0):3} ' + out += f'{_rain:6}\r' + return out + def cmd_aprs_trace(self): """APRS Tracer""" if self.port_handler.aprs_ais is None: diff --git a/constant.py b/constant.py index e25a8683..249ffb06 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.0dev' +VER = '2.98.1dev' LANGUAGE = 0 # QUICK FIX """ 0 = German diff --git a/gui/guiAPRS_wx_plot.py b/gui/guiAPRS_wx_plot.py index bb605395..312df364 100644 --- a/gui/guiAPRS_wx_plot.py +++ b/gui/guiAPRS_wx_plot.py @@ -6,9 +6,6 @@ from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -from fnc.loc_fnc import coordinates_to_locator -from fnc.str_fnc import convert_str_to_datetime - def adjust_list_len(target_list: list, compare_list: list): if len(target_list) < len(compare_list): diff --git a/gui/guiAPRS_wx_tree.py b/gui/guiAPRS_wx_tree.py index f56048ce..18192622 100644 --- a/gui/guiAPRS_wx_tree.py +++ b/gui/guiAPRS_wx_tree.py @@ -3,7 +3,6 @@ from tkinter import ttk from ax25.ax25InitPorts import PORT_HANDLER -from fnc.loc_fnc import coordinates_to_locator, locator_distance from gui.guiAPRS_wx_plot import WXPlotWindow logger = logging.getLogger(__name__) From 407dfa8d145634d3338b60d320aeaffd5d435c95 Mon Sep 17 00:00:00 2001 From: masto Date: Tue, 3 Oct 2023 23:44:09 +0200 Subject: [PATCH 03/17] - Distance and Locator colum added to GUI MH List's --- ax25/ax25Statistics.py | 30 ++++++++++++++++++------------ constant.py | 2 +- gui/guiMH.py | 24 ++++++++++++++++++------ gui/guiMain.py | 16 ++++++++++------ 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/ax25/ax25Statistics.py b/ax25/ax25Statistics.py index 7c0fc8f8..c92fd3c5 100644 --- a/ax25/ax25Statistics.py +++ b/ax25/ax25Statistics.py @@ -4,16 +4,13 @@ import pickle +from UserDB.UserDBmain import USER_DB from constant import CFG_mh_data_file, CFG_port_stat_data_file from fnc.cfg_fnc import cleanup_obj_dict, set_obj_att from fnc.socket_fnc import check_ip_add_format from fnc.str_fnc import conv_time_for_sorting -def get_time_str(): - return datetime.now().strftime('%d/%m/%y %H:%M:%S') - - def get_bandwidth_struct(): _struct = {} for _h in range(24): @@ -67,6 +64,8 @@ class MyHeard: rej_n = 0 # N REJ axip_add = '', 0 # IP, Port axip_fail = 0 # Fail Counter + locator = '' + distance = -1 class MH(object): @@ -185,7 +184,7 @@ def mh_inp(self, ax25_frame, port_name, port_id): self.input_stat_db(ax25_frame, port_id) ######################## # MH Entry - call_str = ax25_frame.from_call.call_str + call_str = str(ax25_frame.from_call.call_str) if call_str not in self.calls.keys(): self.new_call_alarm = True ent = MyHeard() @@ -195,14 +194,14 @@ def mh_inp(self, ax25_frame, port_name, port_id): ent.last_seen = datetime.now() ent.own_call = call_str ent.pac_n += 1 - ent.port = port_name - ent.port_id = port_id - ent.byte_n += ax25_frame.data_len + ent.port = str(port_name) + ent.port_id = int(port_id) + ent.byte_n += int(ax25_frame.data_len) ent.h_byte_n += len(ax25_frame.data_bytes) - ax25_frame.data_len if ax25_frame.ctl_byte.flag == 'REJ': ent.rej_n += 1 # TO Calls - to_c_str = ax25_frame.to_call.call_str + to_c_str = str(ax25_frame.to_call.call_str) if to_c_str not in ent.to_calls: ent.to_calls.append(to_c_str) # Routes @@ -210,7 +209,7 @@ def mh_inp(self, ax25_frame, port_name, port_id): if ax25_frame.via_calls: for call in ax25_frame.via_calls: if call.c_bit: - ent.route.append(call.call_str) + ent.route.append(str(call.call_str)) if ent.route not in ent.all_routes: ent.all_routes.append(list(ent.route)) @@ -219,10 +218,15 @@ def mh_inp(self, ax25_frame, port_name, port_id): if ent.axip_add[0]: if check_ip_add_format(ent.axip_add[0]): if check_ip_add_format(ax25_frame.axip_add[0]): - ent.axip_add = ax25_frame.axip_add + ent.axip_add = tuple(ax25_frame.axip_add) else: - ent.axip_add = ax25_frame.axip_add + ent.axip_add = tuple(ax25_frame.axip_add) + # Get Locator and Distance from User-DB + db_ent = USER_DB.get_entry(call_str, add_new=False) + if db_ent: + ent.locator = str(db_ent.LOC) + ent.distance = float(db_ent.Distance) self.calls[call_str] = ent def mh_get_data_fm_call(self, call_str): @@ -260,6 +264,8 @@ def get_sort_mh_entry(self, flag_str: str, reverse: bool): 'first': conv_time_for_sorting(flag.first_seen), 'port': str(flag.port_id), 'call': flag.own_call, + 'loc': flag.locator, + 'dist': str(flag.distance), 'pack': str(flag.pac_n), 'rej': str(flag.rej_n), 'route': str(max(flag.all_routes)), diff --git a/constant.py b/constant.py index 249ffb06..3e2ccd0e 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.1dev' +VER = '2.98.2dev' LANGUAGE = 0 # QUICK FIX """ 0 = German diff --git a/gui/guiMH.py b/gui/guiMH.py index b462df58..cb5cc901 100644 --- a/gui/guiMH.py +++ b/gui/guiMH.py @@ -44,7 +44,10 @@ def __init__(self, root_win): columns = ( 'mh_last_seen', 'mh_first_seen' , - 'mh_port', 'mh_call', + 'mh_port', + 'mh_call', + 'mh_loc', + 'mh_dist', 'mh_nPackets', 'mh_REJ', 'mh_route', @@ -62,15 +65,22 @@ def __init__(self, root_win): self._tree.heading('mh_first_seen', text='Erste Paket', command=lambda: self._sort_entry('first')) self._tree.heading('mh_port', text='Port', command=lambda: self._sort_entry('port')) self._tree.heading('mh_call', text='Call', command=lambda: self._sort_entry('call')) + self._tree.heading('mh_loc', text='LOC', command=lambda: self._sort_entry('loc')) + self._tree.heading('mh_dist', text='km', command=lambda: self._sort_entry('dist')) self._tree.heading('mh_nPackets', text='Packets', command=lambda: self._sort_entry('pack')) self._tree.heading('mh_REJ', text='REJs', command=lambda: self._sort_entry('rej')) self._tree.heading('mh_route', text='Route', command=lambda: self._sort_entry('route')) self._tree.heading('mh_last_ip', text='AXIP', command=lambda: self._sort_entry('axip')) self._tree.heading('mh_ip_fail', text='Fail', command=lambda: self._sort_entry('axipfail')) - self._tree.column("mh_port", anchor=tk.CENTER, stretch=tk.NO, width=80) - self._tree.column("mh_nPackets", anchor=tk.CENTER, stretch=tk.NO, width=80) - self._tree.column("mh_REJ", anchor=tk.CENTER, stretch=tk.NO, width=55) - self._tree.column("mh_ip_fail", anchor=tk.CENTER, stretch=tk.NO, width=50) + self._tree.column("mh_last_seen", anchor=tk.W, stretch=tk.YES, width=180) + self._tree.column("mh_first_seen", anchor=tk.W, stretch=tk.YES, width=180) + self._tree.column("mh_call", anchor=tk.W, stretch=tk.YES, width=120) + self._tree.column("mh_loc", anchor=tk.W, stretch=tk.YES, width=100) + self._tree.column("mh_dist", anchor=tk.W, stretch=tk.YES, width=70) + self._tree.column("mh_port", anchor=tk.W, stretch=tk.NO, width=80) + self._tree.column("mh_nPackets", anchor=tk.W, stretch=tk.NO, width=80) + self._tree.column("mh_REJ", anchor=tk.W, stretch=tk.NO, width=55) + self._tree.column("mh_ip_fail", anchor=tk.W, stretch=tk.NO, width=50) # self.tree.column("# 2", anchor=tk.CENTER, stretch=tk.YES) # tree.column(1, stretch=True) @@ -85,7 +95,7 @@ def entry_selected(self, event): record = item['values'] # show a message call = record[3] - vias = record[6] + vias = record[8] port = record[2] port = int(port.split(' ')[0]) if vias: @@ -134,6 +144,8 @@ def _format_tree_ent(self, mh_list): f'{conv_time_DE_str(ent.first_seen)}', f'{ent.port_id} {ent.port}', f'{ent.own_call}', + f'{ent.locator}', + f'{ent.distance}', f'{ent.pac_n}', f'{ent.rej_n}', ' '.join(route), diff --git a/gui/guiMain.py b/gui/guiMain.py index d88ffa50..0c1bc8b2 100644 --- a/gui/guiMain.py +++ b/gui/guiMain.py @@ -321,6 +321,7 @@ def __init__(self, main_cl): columns = ( 'mh_last_seen', 'mh_call', + 'mh_dist', 'mh_port', 'mh_nPackets', 'mh_route', @@ -331,14 +332,16 @@ def __init__(self, main_cl): self._tree.heading('mh_last_seen', text='Zeit') self._tree.heading('mh_call', text='Call') + self._tree.heading('mh_dist', text='km') self._tree.heading('mh_port', text='Port') self._tree.heading('mh_nPackets', text='PACK') self._tree.heading('mh_route', text='Route') - self._tree.column("mh_last_seen", anchor=tk.CENTER, stretch=tk.NO, width=90) - self._tree.column("mh_call", stretch=tk.NO, width=100) - self._tree.column("mh_port", anchor=tk.CENTER, stretch=tk.NO, width=80) - self._tree.column("mh_nPackets", anchor=tk.CENTER, stretch=tk.NO, width=60) - self._tree.column("mh_route", stretch=tk.YES, width=180) + self._tree.column("mh_last_seen", anchor=tk.W, stretch=tk.NO, width=85) + self._tree.column("mh_call", anchor=tk.W, stretch=tk.NO, width=105) + self._tree.column("mh_dist", anchor=tk.CENTER, stretch=tk.NO, width=70) + self._tree.column("mh_port", anchor=tk.W, stretch=tk.NO, width=61) + self._tree.column("mh_nPackets", anchor=tk.W, stretch=tk.NO, width=60) + self._tree.column("mh_route", anchor=tk.W, stretch=tk.YES, width=180) self._tree_data = [] self._last_mh_ent = [] @@ -731,7 +734,7 @@ def _entry_selected(self, event): record = item['values'] # show a message call = record[1] - vias = record[4] + vias = record[5] port = record[2] port = int(port.split(' ')[0]) if vias: @@ -758,6 +761,7 @@ def _format_tree_ent(self): self._tree_data.append(( f"{conv_time_DE_str(ent.last_seen).split(' ')[1]}", f'{ent.own_call}', + f'{ent.distance}', f'{ent.port_id} {ent.port}', f'{ent.pac_n}', ' '.join(route), From c58adbb619d7a363e9fb55b0dd40af15a09cdc88 Mon Sep 17 00:00:00 2001 From: masto Date: Wed, 4 Oct 2023 02:22:06 +0200 Subject: [PATCH 04/17] - TkMainWin cleaned up. - Add Gui Stuff in guiMH.py for DX-Alarm Settings and Auto Tracer Settings --- ax25aprs/aprs_dec.py | 24 ++-- constant.py | 2 +- gui/guiMH.py | 118 +++++++++++++-- gui/guiMain.py | 336 ++++++++++++++++++++++--------------------- 4 files changed, 294 insertions(+), 186 deletions(-) diff --git a/ax25aprs/aprs_dec.py b/ax25aprs/aprs_dec.py index 1338f13f..ed191d2f 100644 --- a/ax25aprs/aprs_dec.py +++ b/ax25aprs/aprs_dec.py @@ -140,6 +140,7 @@ def format_aprs_msg(aprs_frame: aprslib.parse, own_locator, full_aprs_frame: apr ret = '' dist = '' typ = '' + loc = '' db_ent = USER_DB.get_entry(full_aprs_frame['from'], add_new=add_new_user) for k in aprs_frame: # print(f"{k}: {aprs_frame[k]}") @@ -175,13 +176,8 @@ def format_aprs_msg(aprs_frame: aprslib.parse, own_locator, full_aprs_frame: apr loc = coordinates_to_locator(latitude=aprs_frame['latitude'], longitude=aprs_frame['longitude']) ret += f"├►LOCATOR : {loc}\n" - if db_ent: - if not db_ent.LOC: - db_ent.LOC = loc - if not db_ent.Lat: - db_ent.Lat = aprs_frame['latitude'] - db_ent.Lon = aprs_frame['longitude'] - if own_locator: + + if own_locator and loc: dist = locator_distance(own_locator, loc) ret += f"├►DISTANCE : {dist} km\n" # if db_ent: @@ -202,12 +198,14 @@ def format_aprs_msg(aprs_frame: aprslib.parse, own_locator, full_aprs_frame: apr if k in ['weather', 'wx']: typ = 'APRS-WX' if db_ent: - # if not db_ent.Distance: - if db_ent.LOC and own_locator: - db_ent.Distance = locator_distance(own_locator, db_ent.LOC) - dist = locator_distance(own_locator, db_ent.LOC) - if not db_ent.TYP and typ: - db_ent.TYP = typ + if loc: + db_ent.LOC = loc + db_ent.Lat = aprs_frame['latitude'] + db_ent.Lon = aprs_frame['longitude'] + if type(dist) == float: + db_ent.Distance = float(dist) + if not db_ent.TYP and typ: + db_ent.TYP = typ return ret, dist diff --git a/constant.py b/constant.py index 3e2ccd0e..339f5fa8 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.2dev' +VER = '2.98.3dev' LANGUAGE = 0 # QUICK FIX """ 0 = German diff --git a/gui/guiMH.py b/gui/guiMH.py index cb5cc901..140e68cc 100644 --- a/gui/guiMH.py +++ b/gui/guiMH.py @@ -12,10 +12,6 @@ class MHWin(tk.Toplevel): def __init__(self, root_win): tk.Toplevel.__init__(self) self._root_win = root_win - ################################### - # Vars - self._rev_ent = False - # self.mh_win = tk.Tk() self.title("MyHEARD") self.style = self._root_win.style # self.geometry("1250x700") @@ -30,15 +26,113 @@ def __init__(self, root_win): self.iconbitmap("favicon.ico") except tk.TclError: pass - self.lift() self._menubar = Menu(self) self.config(menu=self._menubar) self._menubar.add_command(label="Quit", command=self.close) self._menubar.add_command(label="Port-Statistik", command=lambda: self._root_win.open_port_stat_win()) + self.lift() + ################################### + # Vars + self._rev_ent = False + self._alarm_active_var = tk.BooleanVar(self) + self._alarm_newCall_var = tk.BooleanVar(self) + self._alarm_seenSince_var = tk.StringVar(self) + self._alarm_distance_var = tk.StringVar(self) + self._tracer_active_var = tk.BooleanVar(self) + self._tracer_duration_var = tk.StringVar(self) + self._get_vars() # ############################### Columns ############################ self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=0, minsize=50) - self.grid_rowconfigure(1, weight=1) + self.grid_rowconfigure(1, weight=0, minsize=30) + self.grid_rowconfigure(2, weight=1) + # ###################### DX Alarm Settings ###################### + # ALARM + lower_frame = tk.Frame(self) + lower_frame.grid(row=0, column=0, columnspan=2, sticky='nsew') + frame_11_label = tk.Frame(lower_frame) + frame_11_label.pack(side=tk.TOP) + tk.Label(frame_11_label, text='DX-Alarm Setting').pack() + ### + # activ Checkbox + frame_21_active = tk.Frame(lower_frame) + frame_21_active.pack(side=tk.LEFT, fill=tk.BOTH, padx=30) + + tk.Label(frame_21_active, text='Activate ').pack(side=tk.LEFT, ) + tk.Checkbutton(frame_21_active, + variable=self._alarm_active_var, + # command=self._chk_alarm_active + ).pack(side=tk.LEFT, ) + + # New Call in List Checkbox + frame_21_newCall = tk.Frame(lower_frame) + frame_21_newCall.pack(side=tk.LEFT, fill=tk.BOTH, padx=30) + + tk.Label(frame_21_newCall, text='new Call ').pack(side=tk.LEFT, ) + tk.Checkbutton(frame_21_newCall, + variable=self._alarm_newCall_var, + # command=self._chk_alarm_active + ).pack(side=tk.LEFT, ) + + # Alarm seen since Days + frame_21_seen = tk.Frame(lower_frame) + frame_21_seen.pack(side=tk.LEFT, fill=tk.BOTH, padx=30) + + tk.Label(frame_21_seen, text='seen since (Days) ').pack(side=tk.LEFT, ) + tk.Spinbox(frame_21_seen, + from_=1, + to=365, + increment=10, + width=4, + textvariable=self._alarm_seenSince_var, + # command=self._set_alarm_distance + ).pack(side=tk.LEFT, ) + + # Alarm Distance + frame_21_distance = tk.Frame(lower_frame) + frame_21_distance.pack(side=tk.LEFT, fill=tk.BOTH, padx=30) + + tk.Label(frame_21_distance, text='Distance ').pack(side=tk.LEFT, ) + tk.Spinbox(frame_21_distance, + from_=1, + to=20000, + increment=50, + width=6, + textvariable=self._alarm_distance_var, + # command=self._set_alarm_distance + ).pack(side=tk.LEFT, ) + + # ###################### Auto Tracer ###################### + # Tracer + lower_frame_tracer = tk.Frame(self) + lower_frame_tracer.grid(row=1, column=0, columnspan=2, sticky='nsew') + frame_12_label = tk.Frame(lower_frame_tracer) + frame_12_label.pack(side=tk.LEFT, fill=tk.BOTH, padx=30) + tk.Label(frame_12_label, text='Auto APRS-Tracer: ').pack(side=tk.LEFT, ) + ### + # activ Checkbox + frame_22_active = tk.Frame(lower_frame_tracer) + frame_22_active.pack(side=tk.LEFT, fill=tk.BOTH, ) + + tk.Label(frame_22_active, text='Activate ').pack(side=tk.LEFT, ) + tk.Checkbutton(frame_22_active, + variable=self._tracer_active_var, + # command=self._chk_alarm_active + ).pack(side=tk.LEFT, ) + # duration + frame_22_duration = tk.Frame(lower_frame_tracer) + frame_22_duration.pack(side=tk.LEFT, fill=tk.BOTH, padx=30) + + tk.Label(frame_22_duration, text='Duration (min) ').pack(side=tk.LEFT, ) + tk.Spinbox(frame_22_duration, + from_=5, + to=1440, + increment=5, + width=5, + textvariable=self._tracer_duration_var, + # command=self._set_alarm_distance + ).pack(side=tk.LEFT, ) + ########################################################################################## # TREE columns = ( @@ -55,11 +149,11 @@ def __init__(self, root_win): 'mh_ip_fail' ) self._tree = ttk.Treeview(self, columns=columns, show='headings') - self._tree.grid(row=1, column=0, sticky='nsew') + self._tree.grid(row=2, column=0, sticky='nsew') # add a scrollbar scrollbar = ttk.Scrollbar(self, orient=tk.VERTICAL, command=self._tree.yview) self._tree.configure(yscrollcommand=scrollbar.set) - scrollbar.grid(row=1, column=1, sticky='ns') + scrollbar.grid(row=2, column=1, sticky='ns') self._tree.heading('mh_last_seen', text='Letzte Paket', command=lambda: self._sort_entry('last')) self._tree.heading('mh_first_seen', text='Erste Paket', command=lambda: self._sort_entry('first')) @@ -89,6 +183,14 @@ def __init__(self, root_win): self._update_mh() self._tree.bind('<>', self.entry_selected) + def _get_vars(self): + self._alarm_active_var.set(bool()) + self._alarm_newCall_var.set(bool()) + self._alarm_seenSince_var.set(str()) + self._alarm_distance_var.set(str()) + self._tracer_active_var.set(bool()) + self._tracer_duration_var.set(str()) + def entry_selected(self, event): for selected_item in self._tree.selection(): item = self._tree.item(selected_item) diff --git a/gui/guiMain.py b/gui/guiMain.py index 0c1bc8b2..6383047a 100644 --- a/gui/guiMain.py +++ b/gui/guiMain.py @@ -1537,6 +1537,128 @@ def ch_btn_alarm(self, btn: tk.Button): class TkMainWin: def __init__(self): + ###################################### + # Init Vars + self._init_vars() + ###################################### + # GUI Stuff + self.main_win = tk.Tk() + self.main_win.title("P.ython o.ther P.acket T.erminal {}".format(VER)) + self.main_win.geometry("1400x850") + try: + self.main_win.iconbitmap("favicon.ico") + except TclError: + pass + self.main_win.protocol("WM_DELETE_WINDOW", self._destroy_win) + ########################## + self.style = ttk.Style() + # self.style.theme_use('classic') + # self.style.theme_use('clam') + self.main_win.columnconfigure(0, minsize=500, weight=1) + self.main_win.columnconfigure(1, minsize=2, weight=5) + self.main_win.rowconfigure(0, minsize=3, weight=1) # Boarder + self.main_win.rowconfigure(1, minsize=220, weight=2) + self.main_win.rowconfigure(2, minsize=28, weight=1) # CH BTN + ############################ + ############################ + # Input Output TXT Frames and Status Bar + self._txt_win = TxTframe(self) + self._out_txt = self._txt_win.out_txt_win + self._inp_txt = self._txt_win.in_txt_win + self._mon_txt = self._txt_win.mon_txt + ####################### + # Window Text Buffers + self._win_buf: {int: ChVars} = {} + for i in range(11): + self._win_buf[i] = ChVars() + self._win_buf[i].input_win_index = str(self._inp_txt.index(tk.INSERT)) + ######################### + # Channel Buttons + self._ch_btn = ChBtnFrm(self) + self._ch_btn.ch_btn_frame.grid(row=2, column=0, columnspan=1, sticky="nsew") + ######################### + + ######################### + # Tabbed Frame right + self._side_btn_frame_top = tk.Frame(self.main_win, width=200, height=540) + self._side_btn_frame_top.grid(row=1, rowspan=2, column=1, sticky="nsew") + self._side_btn_frame_top.rowconfigure(0, minsize=40, weight=0) # CONN BTN + self._side_btn_frame_top.rowconfigure(1, minsize=40, weight=0) # BTN row 2 + self._side_btn_frame_top.rowconfigure(2, minsize=1, weight=0) # Dummy + self._side_btn_frame_top.rowconfigure(3, minsize=300, weight=10) # Reiter Frame + self._side_btn_frame_top.rowconfigure(4, minsize=100, weight=1) # Reiter Frame + + self._side_btn_frame_top.columnconfigure(0, minsize=10, weight=0) + self._side_btn_frame_top.columnconfigure(1, minsize=100, weight=2) + self._side_btn_frame_top.columnconfigure(2, minsize=100, weight=2) + self._side_btn_frame_top.columnconfigure(3, minsize=10, weight=1) + self._side_btn_frame_top.columnconfigure(4, minsize=10, weight=5) + self._side_btn_frame_top.columnconfigure(6, minsize=10, weight=1) + ############## + # GUI Buttons + self._init_btn() + ############## + # Side Frame + self.tabbed_sideFrame = SideTabbedFrame(self) + self.setting_sound = self.tabbed_sideFrame.sound_on + self.setting_sprech = self.tabbed_sideFrame.sprech_on + self.setting_bake = self.tabbed_sideFrame.bake_on + self.setting_rx_echo = self.tabbed_sideFrame.rx_echo_on + # self.setting_dx_alarm = self.tabbed_sideFrame.dx_alarm_on + ############################ + # Canvas Plot + self._init_bw_plot() + ########################### + # set KEY BINDS + self._set_binds() + self._set_keybinds() + # Menubar + self._init_menubar() + # set Ch Btn Color + self.ch_status_update() + # ..... + self._monitor_start_msg() + ############################# + # set GUI Var to Port Handler + PORT_HANDLER.set_gui(self) + ####################### + # LOOP LOOP LOOP + self.main_win.after(self._loop_delay, self._tasker) + self.main_win.mainloop() + + def __del__(self): + # self.disco_all() + # self.ax25_port_handler.close_all() + pass + + def _destroy_win(self): + self.msg_to_monitor("PoPT wird beendet.") + self._is_closing = True + logging.info('Closing GUI: Closing Ports.') + PORT_HANDLER.close_all_ports() + + logging.info('Closing GUI.') + self._close_port_stat_win() + if self.settings_win is not None: + self.settings_win.destroy() + if self.mh_window is not None: + self.mh_window.destroy() + if self.wx_window is not None: + self.wx_window.destroy() + if self.userdb_win is not None: + self.userdb_win.destroy() + if self.userDB_tree_win is not None: + self.userDB_tree_win.destroy() + if self.aprs_mon_win is not None: + self.aprs_mon_win.destroy() + if self.aprs_pn_msg_win is not None: + self.aprs_pn_msg_win.destroy() + if self.be_tracer_win is not None: + self.be_tracer_win.destroy() + + #################### + # Init Stuff + def _init_vars(self): self.language = LANGUAGE ############################### self._root_dir = get_root_dir() @@ -1544,13 +1666,15 @@ def __init__(self): ##################### ##################### # GUI VARS - self._sound_th = None + self.connect_history = {} + self.ch_alarm = False self.ch_alarm_sound_one_time = False self.channel_index = 1 + self.mon_mode = 0 self._mon_buff = [] - self.connect_history = {} + self._sound_th = None self._is_closing = False #################### # GUI PARAM @@ -1568,32 +1692,52 @@ def __init__(self): self._test_task_timer = time.time() ############### self.text_size = 14 - ###################################### - # GUI Stuff - self.main_win = tk.Tk() - self.main_win.title("P.ython o.ther P.acket T.erminal {}".format(VER)) - self.main_win.geometry("1400x850") - try: - self.main_win.iconbitmap("favicon.ico") - except TclError: - pass - self.main_win.protocol("WM_DELETE_WINDOW", self._destroy_win) - ########################## - self.style = ttk.Style() - # self.style.theme_use('classic') - # self.style.theme_use('clam') - self.main_win.columnconfigure(0, minsize=500, weight=1) - self.main_win.columnconfigure(1, minsize=2, weight=5) - self.main_win.rowconfigure(0, minsize=3, weight=1) # Boarder - # self.main_win.rowconfigure(1, minsize=0, weight=1) # BTN SIDE - self.main_win.rowconfigure(1, minsize=220, weight=2) - self.main_win.rowconfigure(2, minsize=28, weight=1) # CH BTN - # self.main_win.rowconfigure(3, minsize=2, weight=0) # Boarder - ############################ ############################ - ############################ - ############## - # Menüleiste + # Windows + self.new_conn_win = None + self.settings_win = None + self.mh_window = None + self.wx_window = None + self.port_stat_win = None + self.be_tracer_win = None + self.locator_calc_window = None + self.aprs_mon_win = None + self.aprs_pn_msg_win = None + self.userdb_win = None + self.userDB_tree_win = None + ############################## + # BW-Plot + self._bw_plot_x_scale = [] + for _i in list(range(60)): + self._bw_plot_x_scale.append(_i / 6) + self._bw_plot_lines = {} + + def _init_bw_plot(self): + # plt.ion() + self._bw_fig = Figure(figsize=(8, 5), dpi=80) + # plt.style.use('dark_background') + self._ax = self._bw_fig.add_subplot(111) + self._bw_fig.subplots_adjust(left=0.1, right=0.95, top=0.99, bottom=0.1) + self._ax.axis([0, 10, 0, 100]) + self._bw_fig.set_facecolor('xkcd:light grey') + self._ax.set_facecolor('#000000') + # self.bw_fig.xlim(0, 10) # TODO As Option + self._ax.xaxis.label.set_color('black') + self._ax.yaxis.label.set_color('black') + self._ax.tick_params(axis='x', colors='black') + self._ax.tick_params(axis='y', colors='black') + self._ax.set_xlabel(STR_TABLE['minutes'][self.language]) + self._ax.set_ylabel(STR_TABLE['occup'][self.language]) + # plt.xlim(0, 10) # TODO As Option + self._canvas = FigureCanvasTkAgg(self._bw_fig, master=self._side_btn_frame_top) # A tk.DrawingArea. + self._canvas.flush_events() + self._canvas.draw() + self._canvas.get_tk_widget().grid(row=4, column=0, columnspan=7, sticky="nsew") + # self._canvas.get_tk_widget().pack(fill=tk.BOTH) + # self._canvas.get_tk_widget().config(cursor="none") + self._bw_fig.canvas.flush_events() + + def _init_menubar(self): _menubar = Menu(self.main_win, tearoff=False) self.main_win.config(menu=_menubar) # Menü 1 "Verbindungen" @@ -1713,45 +1857,7 @@ def __init__(self): underline=0) _menubar.add_cascade(label=STR_TABLE['help'][self.language], menu=_MenuHelp, underline=0) - # Menü 4 "Debug" - # menubar.add_command(label="Debug") - ############################ - ############################ - # Input Output TXT Frames and Status Bar - self._txt_win = TxTframe(self) - self._out_txt = self._txt_win.out_txt_win - self._inp_txt = self._txt_win.in_txt_win - self._mon_txt = self._txt_win.mon_txt - ####################### - # Window Text Buffers - self._win_buf: {int: ChVars} = {} - for i in range(11): - self._win_buf[i] = ChVars() - self._win_buf[i].input_win_index = str(self._inp_txt.index(tk.INSERT)) - # Channel Buttons - self._ch_btn = ChBtnFrm(self) - self._ch_btn.ch_btn_frame.grid(row=2, column=0, columnspan=1, sticky="nsew") - ######################### - # BTN and Tabbed Frame right side - self._side_btn_frame_top = tk.Frame(self.main_win, width=200, height=540) - # self.side_btn_frame_top = tk.Frame(self.pw, width=200, height=540) - # self.pw.add(self.txt_win.pw) - self._side_btn_frame_top.grid(row=1, rowspan=2, column=1, sticky="nsew") - self._side_btn_frame_top.rowconfigure(0, minsize=40, weight=0) # CONN BTN - self._side_btn_frame_top.rowconfigure(1, minsize=40, weight=0) # BTN row 2 - self._side_btn_frame_top.rowconfigure(2, minsize=1, weight=0) # Dummy - # self._side_btn_frame_top.rowconfigure(3, minsize=1, weight=2) # Dummy - self._side_btn_frame_top.rowconfigure(3, minsize=300, weight=10) # Reiter Frame - self._side_btn_frame_top.rowconfigure(4, minsize=100, weight=1) # Reiter Frame - # self._side_btn_frame_top.rowconfigure(5, minsize=15, weight=1) # Reiter Frame - - self._side_btn_frame_top.columnconfigure(0, minsize=10, weight=0) - self._side_btn_frame_top.columnconfigure(1, minsize=100, weight=2) - self._side_btn_frame_top.columnconfigure(2, minsize=100, weight=2) - self._side_btn_frame_top.columnconfigure(3, minsize=10, weight=1) - self._side_btn_frame_top.columnconfigure(4, minsize=10, weight=5) - self._side_btn_frame_top.columnconfigure(6, minsize=10, weight=1) - + def _init_btn(self): _btn_upper_frame = tk.Frame(self._side_btn_frame_top) _btn_lower_frame = tk.Frame(self._side_btn_frame_top) _btn_upper_frame.place(x=5, y=5) @@ -1791,104 +1897,6 @@ def __init__(self): text="Kaffèmaschine", bg="HotPink2", width=12, command=self._kaffee).place(x=215, y=10) """ - self.tabbed_sideFrame = SideTabbedFrame(self) - # self.pw.add(self.tabbed_sideFrame.tab_side_frame) - self.setting_sound = self.tabbed_sideFrame.sound_on - self.setting_sprech = self.tabbed_sideFrame.sprech_on - self.setting_bake = self.tabbed_sideFrame.bake_on - self.setting_rx_echo = self.tabbed_sideFrame.rx_echo_on - # self.setting_dx_alarm = self.tabbed_sideFrame.dx_alarm_on - ############################ - # Canvas Plot ( TEST ) - # plt.ion() - self._bw_fig = Figure(figsize=(8, 5), dpi=80) - # plt.style.use('dark_background') - self._ax = self._bw_fig.add_subplot(111) - self._bw_fig.subplots_adjust(left=0.1, right=0.95, top=0.99, bottom=0.1) - self._ax.axis([0, 10, 0, 100]) - self._bw_fig.set_facecolor('xkcd:light grey') - self._ax.set_facecolor('#000000') - # self.bw_fig.xlim(0, 10) # TODO As Option - self._ax.xaxis.label.set_color('black') - self._ax.yaxis.label.set_color('black') - self._ax.tick_params(axis='x', colors='black') - self._ax.tick_params(axis='y', colors='black') - self._ax.set_xlabel(STR_TABLE['minutes'][self.language]) - self._ax.set_ylabel(STR_TABLE['occup'][self.language]) - self._bw_plot_lines = {} - # plt.xlim(0, 10) # TODO As Option - self._canvas = FigureCanvasTkAgg(self._bw_fig, master=self._side_btn_frame_top) # A tk.DrawingArea. - self._canvas.flush_events() - self._canvas.draw() - self._canvas.get_tk_widget().grid(row=4, column=0, columnspan=7, sticky="nsew") - # self._canvas.get_tk_widget().pack(fill=tk.BOTH) - # self._canvas.get_tk_widget().config(cursor="none") - self._bw_fig.canvas.flush_events() - - self._bw_plot_x_scale = [] - for _i in list(range(60)): - self._bw_plot_x_scale.append(_i / 6) - self._bw_plot_lines = {} - - ############################ - # Windows - self.new_conn_win = None - self.settings_win = None - self.mh_window = None - self.wx_window = None - self.port_stat_win = None - self.be_tracer_win = None - self.locator_calc_window = None - self.aprs_mon_win = None - self.aprs_pn_msg_win = None - self.userdb_win = None - self.userDB_tree_win = None - ########################### - # Init - # set Ch Btn Color - self.ch_status_update() - # set KEY BINDS - self._set_binds() - self._set_keybinds() - # ..... - self._monitor_start_msg() - ####################### - # set GUI Vav - PORT_HANDLER.set_gui(self) - ####################### - # LOOP - self.main_win.after(self._loop_delay, self._tasker) - self.main_win.mainloop() - - def __del__(self): - # self.disco_all() - # self.ax25_port_handler.close_all() - pass - - def _destroy_win(self): - self.msg_to_monitor("PoPT wird beendet.") - self._is_closing = True - logging.info('Closing GUI: Closing Ports.') - PORT_HANDLER.close_all_ports() - - logging.info('Closing GUI.') - self._close_port_stat_win() - if self.settings_win is not None: - self.settings_win.destroy() - if self.mh_window is not None: - self.mh_window.destroy() - if self.wx_window is not None: - self.wx_window.destroy() - if self.userdb_win is not None: - self.userdb_win.destroy() - if self.userDB_tree_win is not None: - self.userDB_tree_win.destroy() - if self.aprs_mon_win is not None: - self.aprs_mon_win.destroy() - if self.aprs_pn_msg_win is not None: - self.aprs_pn_msg_win.destroy() - if self.be_tracer_win is not None: - self.be_tracer_win.destroy() def _monitor_start_msg(self): From 1335d54008ea4130215e2052265ddb4c022a9572 Mon Sep 17 00:00:00 2001 From: masto Date: Wed, 4 Oct 2023 04:49:06 +0200 Subject: [PATCH 05/17] - more cleanups in TkMainWin. - add tracer/autotracer var/btn-state handling --- constant.py | 2 +- gui/guiAPRS_be_tracer.py | 4 +- gui/guiMH.py | 22 ++- gui/guiMain.py | 383 +++++++++++++++++++++------------------ 4 files changed, 222 insertions(+), 189 deletions(-) diff --git a/constant.py b/constant.py index 339f5fa8..5c3f609d 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.3dev' +VER = '2.98.4dev' LANGUAGE = 0 # QUICK FIX """ 0 = German diff --git a/gui/guiAPRS_be_tracer.py b/gui/guiAPRS_be_tracer.py index b4c3951b..5fa2dd55 100644 --- a/gui/guiAPRS_be_tracer.py +++ b/gui/guiAPRS_be_tracer.py @@ -283,9 +283,7 @@ def _chk_port(self, event=None): def _chk_active(self, event=None): self._save_vars() - _root_gui = PORT_HANDLER.get_root_gui() - if _root_gui is not None: - _root_gui.tabbed_sideFrame.set_tracer_chk(PORT_HANDLER.get_aprs_ais().be_tracer_active) + self._root_win.set_tracer_fm_aprs() def close(self): self._root_win.be_tracer_win = None diff --git a/gui/guiMH.py b/gui/guiMH.py index 140e68cc..8cc599fb 100644 --- a/gui/guiMH.py +++ b/gui/guiMH.py @@ -34,11 +34,11 @@ def __init__(self, root_win): ################################### # Vars self._rev_ent = False - self._alarm_active_var = tk.BooleanVar(self) + # self._alarm_active_var = self._root_win.setting_dx_alarm self._alarm_newCall_var = tk.BooleanVar(self) self._alarm_seenSince_var = tk.StringVar(self) self._alarm_distance_var = tk.StringVar(self) - self._tracer_active_var = tk.BooleanVar(self) + # self._tracer_active_var = tk.BooleanVar(self) self._tracer_duration_var = tk.StringVar(self) self._get_vars() # ############################### Columns ############################ @@ -60,7 +60,7 @@ def __init__(self, root_win): tk.Label(frame_21_active, text='Activate ').pack(side=tk.LEFT, ) tk.Checkbutton(frame_21_active, - variable=self._alarm_active_var, + variable=self._root_win.setting_dx_alarm, # command=self._chk_alarm_active ).pack(side=tk.LEFT, ) @@ -104,6 +104,10 @@ def __init__(self, root_win): # ###################### Auto Tracer ###################### # Tracer + _auto_tracer_state = { + True: 'disabled', + False: 'normal' + }.get(self._root_win.get_tracer(), 'disabled') lower_frame_tracer = tk.Frame(self) lower_frame_tracer.grid(row=1, column=0, columnspan=2, sticky='nsew') frame_12_label = tk.Frame(lower_frame_tracer) @@ -116,8 +120,9 @@ def __init__(self, root_win): tk.Label(frame_22_active, text='Activate ').pack(side=tk.LEFT, ) tk.Checkbutton(frame_22_active, - variable=self._tracer_active_var, - # command=self._chk_alarm_active + variable=self._root_win.setting_auto_tracer, + command=self._root_win.set_auto_tracer, + state=_auto_tracer_state ).pack(side=tk.LEFT, ) # duration frame_22_duration = tk.Frame(lower_frame_tracer) @@ -130,6 +135,7 @@ def __init__(self, root_win): increment=5, width=5, textvariable=self._tracer_duration_var, + state=_auto_tracer_state # command=self._set_alarm_distance ).pack(side=tk.LEFT, ) @@ -137,7 +143,7 @@ def __init__(self, root_win): # TREE columns = ( 'mh_last_seen', - 'mh_first_seen' , + 'mh_first_seen', 'mh_port', 'mh_call', 'mh_loc', @@ -184,11 +190,11 @@ def __init__(self, root_win): self._tree.bind('<>', self.entry_selected) def _get_vars(self): - self._alarm_active_var.set(bool()) + # self._alarm_active_var.set(bool()) self._alarm_newCall_var.set(bool()) self._alarm_seenSince_var.set(str()) self._alarm_distance_var.set(str()) - self._tracer_active_var.set(bool()) + # self._tracer_active_var.set(bool(self._root_win.setting_auto_tracer.get())) self._tracer_duration_var.set(str()) def entry_selected(self, event): diff --git a/gui/guiMain.py b/gui/guiMain.py index 6383047a..08eeb964 100644 --- a/gui/guiMain.py +++ b/gui/guiMain.py @@ -348,59 +348,59 @@ def __init__(self, main_cl): self._update_side_mh() self._tree.bind('<>', self._entry_selected) - # Settings ########################## + # Global Settings ########################## # Global Sound - self.sound_on = tk.BooleanVar(self.tab4_settings) Checkbutton(self.tab4_settings, text="Sound", - variable=self.sound_on, + variable=self._main_win.setting_sound, ).place(x=10, y=10) - # self.sound_on.set(True) # Global Sprech - self.sprech_on = tk.BooleanVar(self.tab4_settings) sprech_btn = Checkbutton(self.tab4_settings, text="Sprachausgabe", - variable=self.sprech_on, + variable=self._main_win.setting_sprech, command=self._chk_sprech_on ) sprech_btn.place(x=10, y=35) - if is_linux(): - self.sprech_on.set(True) - else: - self.sprech_on.set(False) + if not is_linux(): sprech_btn.configure(state='disabled') - # Global Bake - self.bake_on = tk.BooleanVar(self.tab4_settings) Checkbutton(self.tab4_settings, text="Baken", - variable=self.bake_on, + variable=self._main_win.setting_bake, ).place(x=10, y=60) - self.bake_on.set(True) - # self.bake_on.set(True) # DX Alarm > dx_alarm_on - self.tracer_on = tk.BooleanVar(self.tab4_settings) - - _chk_btn = Checkbutton(self.tab4_settings, - text="Tracer", - variable=self.tracer_on, - command=self._chk_tracer, - # state='disabled' - ) - _chk_btn.place(x=10, y=85) - + Checkbutton(self.tab4_settings, + text="Tracer", + variable=self._main_win.setting_tracer, + command=self._chk_tracer, + # state='disabled' + ).place(x=10, y=85) + _auto_tracer_state = { + True: 'disabled', + False: 'normal' + }.get(self._main_win.get_tracer(), 'disabled') + self._autotracer_chk_btn = Checkbutton(self.tab4_settings, + text="Auto-Tracer", + variable=self._main_win.setting_auto_tracer, + command=self._chk_tracer, + state=_auto_tracer_state + ) + self._autotracer_chk_btn.place(x=10, y=115) + Checkbutton(self.tab4_settings, + text="DX-Alarm", + variable=self._main_win.setting_dx_alarm, + # command=self._chk_tracer, + # state='disabled' + ).place(x=10, y=145) # RX ECHO - self.rx_echo_on = tk.BooleanVar(self.tab4_settings) - _chk_btn = Checkbutton(self.tab4_settings, - text="RX-Echo", - variable=self.rx_echo_on, - ) - _chk_btn.place(x=10, y=115) - + Checkbutton(self.tab4_settings, + text="RX-Echo", + variable=self._main_win.setting_rx_echo, + ).place(x=10, y=175) ############ # CH ECHO - self.chk_btn_default_clr = _chk_btn.cget('bg') - self.ch_echo_vars = {} + self._chk_btn_default_clr = self._autotracer_chk_btn.cget('bg') + self._ch_echo_vars = {} ################# ################# # Monitor Frame @@ -560,7 +560,7 @@ def __init__(self, main_cl): } self._chk_mon_port() - self._update_ch_echo() + # self._update_ch_echo() self._update_side_mh() self._update_side_trace() @@ -570,19 +570,25 @@ def reset_dx_alarm(self, event=None): # self.tab2_mh.configure(bg=self.tab2_mh_def_bg_clr) """ - def _update_ch_echo(self): + def set_auto_tracer_state(self): + _state = { + True: 'disabled', + False: 'normal' + }.get(self._main_win.get_tracer(), 'disabled') + self._autotracer_chk_btn.configure(state=_state) + def _update_ch_echo(self): # TODO AGAIN !! _tab = self.tab5_ch_links akt_ch_id = self._main_win.channel_index _var = tk.BooleanVar(_tab) - for ch_id in list(self.ch_echo_vars.keys()): + for ch_id in list(self._ch_echo_vars.keys()): if ch_id not in list(PORT_HANDLER.get_all_connections().keys()): - self.ch_echo_vars[ch_id][1].destroy() - del self.ch_echo_vars[ch_id] + self._ch_echo_vars[ch_id][1].destroy() + del self._ch_echo_vars[ch_id] for ch_id in list(PORT_HANDLER.get_all_connections().keys()): conn = PORT_HANDLER.get_all_connections()[ch_id] - if ch_id not in self.ch_echo_vars.keys(): + if ch_id not in self._ch_echo_vars.keys(): chk_bt_var = tk.IntVar() chk_bt = tk.Checkbutton(_tab, text=conn.to_call_str, @@ -594,30 +600,30 @@ def _update_ch_echo(self): chk_bt.place(x=10, y=10 + (28 * (ch_id - 1))) # _chk_bt.configure(state='disabled') tmp = chk_bt_var, chk_bt - self.ch_echo_vars[ch_id] = tmp + self._ch_echo_vars[ch_id] = tmp else: - self.ch_echo_vars[ch_id][1].configure(state='normal') - self.ch_echo_vars[ch_id][1].configure(text=conn.to_call_str) + self._ch_echo_vars[ch_id][1].configure(state='normal') + self._ch_echo_vars[ch_id][1].configure(text=conn.to_call_str) if ch_id != akt_ch_id: - self.ch_echo_vars[ch_id][1].configure(state='normal') + self._ch_echo_vars[ch_id][1].configure(state='normal') else: - self.ch_echo_vars[ch_id][1].configure(state='disabled') - if akt_ch_id in self.ch_echo_vars.keys(): - if self.ch_echo_vars[ch_id][0].get() and self.ch_echo_vars[akt_ch_id][0].get(): - self.ch_echo_vars[ch_id][1].configure(bg='green1') - self.ch_echo_vars[akt_ch_id][1].configure(bg='green1') + self._ch_echo_vars[ch_id][1].configure(state='disabled') + if akt_ch_id in self._ch_echo_vars.keys(): + if self._ch_echo_vars[ch_id][0].get() and self._ch_echo_vars[akt_ch_id][0].get(): + self._ch_echo_vars[ch_id][1].configure(bg='green1') + self._ch_echo_vars[akt_ch_id][1].configure(bg='green1') else: - self.ch_echo_vars[ch_id][1].configure(bg=self.chk_btn_default_clr) - self.ch_echo_vars[akt_ch_id][1].configure(bg=self.chk_btn_default_clr) + self._ch_echo_vars[ch_id][1].configure(bg=self._chk_btn_default_clr) + self._ch_echo_vars[akt_ch_id][1].configure(bg=self._chk_btn_default_clr) # self.sound_on.set(1) def _chk_ch_echo(self): # self.main_win.channel_index - for ch_id in list(self.ch_echo_vars.keys()): - _vars = self.ch_echo_vars[ch_id] + for ch_id in list(self._ch_echo_vars.keys()): + _vars = self._ch_echo_vars[ch_id] if ch_id != self._main_win.channel_index: - if _vars[0].get() and self.ch_echo_vars[self._main_win.channel_index][0].get(): + if _vars[0].get() and self._ch_echo_vars[self._main_win.channel_index][0].get(): PORT_HANDLER.get_all_connections()[ch_id].ch_echo.append( PORT_HANDLER.get_all_connections()[self._main_win.channel_index]) PORT_HANDLER.get_all_connections()[self._main_win.channel_index].ch_echo.append( @@ -653,10 +659,7 @@ def _chk_dx_alarm(self): """ def _chk_tracer(self): - self._main_win.set_tracer(self.tracer_on.get()) - - def set_tracer_chk(self, state: bool): - self.tracer_on.set(state) + self._main_win.set_tracer() def _chk_rnr(self): conn = self._main_win.get_conn() @@ -690,7 +693,8 @@ def _chk_t2auto(self): _conn.calc_irtt() def _chk_sprech_on(self): - if self.sprech_on.get(): + + if self._main_win.setting_sprech.get(): self.t2speech.configure(state='normal') else: self.t2speech.configure(state='disabled') @@ -735,7 +739,7 @@ def _entry_selected(self, event): # show a message call = record[1] vias = record[5] - port = record[2] + port = record[3] port = int(port.split(' ')[0]) if vias: call = f'{call} {vias}' @@ -911,7 +915,7 @@ def on_ch_stat_change(self): self.rx_count_var.set('RX: --- kb') self.t2speech_var.set(self._main_win.get_ch_param().t2speech) - self._update_ch_echo() + # self._update_ch_echo() def set_max_frame(self): conn = self._main_win.get_conn() @@ -1537,13 +1541,10 @@ def ch_btn_alarm(self, btn: tk.Button): class TkMainWin: def __init__(self): - ###################################### - # Init Vars - self._init_vars() ###################################### # GUI Stuff self.main_win = tk.Tk() - self.main_win.title("P.ython o.ther P.acket T.erminal {}".format(VER)) + self.main_win.title(f"P.ython o.ther P.acket T.erminal {VER}") self.main_win.geometry("1400x850") try: self.main_win.iconbitmap("favicon.ico") @@ -1554,13 +1555,17 @@ def __init__(self): self.style = ttk.Style() # self.style.theme_use('classic') # self.style.theme_use('clam') + ###################################### + # Init Vars + self._init_vars() + ###################################### + # .... self.main_win.columnconfigure(0, minsize=500, weight=1) self.main_win.columnconfigure(1, minsize=2, weight=5) self.main_win.rowconfigure(0, minsize=3, weight=1) # Boarder self.main_win.rowconfigure(1, minsize=220, weight=2) self.main_win.rowconfigure(2, minsize=28, weight=1) # CH BTN ############################ - ############################ # Input Output TXT Frames and Status Bar self._txt_win = TxTframe(self) self._out_txt = self._txt_win.out_txt_win @@ -1576,8 +1581,6 @@ def __init__(self): # Channel Buttons self._ch_btn = ChBtnFrm(self) self._ch_btn.ch_btn_frame.grid(row=2, column=0, columnspan=1, sticky="nsew") - ######################### - ######################### # Tabbed Frame right self._side_btn_frame_top = tk.Frame(self.main_win, width=200, height=540) @@ -1600,11 +1603,6 @@ def __init__(self): ############## # Side Frame self.tabbed_sideFrame = SideTabbedFrame(self) - self.setting_sound = self.tabbed_sideFrame.sound_on - self.setting_sprech = self.tabbed_sideFrame.sprech_on - self.setting_bake = self.tabbed_sideFrame.bake_on - self.setting_rx_echo = self.tabbed_sideFrame.rx_echo_on - # self.setting_dx_alarm = self.tabbed_sideFrame.dx_alarm_on ############################ # Canvas Plot self._init_bw_plot() @@ -1627,8 +1625,6 @@ def __init__(self): self.main_win.mainloop() def __del__(self): - # self.disco_all() - # self.ax25_port_handler.close_all() pass def _destroy_win(self): @@ -1667,11 +1663,29 @@ def _init_vars(self): ##################### # GUI VARS self.connect_history = {} - + # GLb Settings + self.setting_sound = tk.BooleanVar(self.main_win) + self.setting_sprech = tk.BooleanVar(self.main_win) + self.setting_bake = tk.BooleanVar(self.main_win) + self.setting_rx_echo = tk.BooleanVar(self.main_win) + self.setting_tracer = tk.BooleanVar(self.main_win) + self.setting_auto_tracer = tk.BooleanVar(self.main_win) + self.setting_dx_alarm = tk.BooleanVar(self.main_win) + # Glb Settings Defaults + self.setting_sound.set(False) + self.setting_bake.set(True) + self.setting_rx_echo.set(False) + self.setting_tracer.set(False) + self.setting_auto_tracer.set(False) + self.setting_dx_alarm.set(True) + if is_linux(): + self.setting_sprech.set(True) + else: + self.setting_sprech.set(False) + # Controlling self.ch_alarm = False self.ch_alarm_sound_one_time = False self.channel_index = 1 - self.mon_mode = 0 self._mon_buff = [] self._sound_th = None @@ -1898,8 +1912,64 @@ def _init_btn(self): bg="HotPink2", width=12, command=self._kaffee).place(x=215, y=10) """ - def _monitor_start_msg(self): + ####################################### + # KEYBIND Stuff + def _set_binds(self): + self._inp_txt.bind("", self._on_click_inp_txt) + + def _set_keybinds(self): + self.main_win.unbind("") + self.main_win.unbind("") + # self.main_win.bind("",lambda event: self.callback(event)) + self.main_win.bind('', lambda event: self.switch_channel(1)) + self.main_win.bind('', lambda event: self.switch_channel(2)) + self.main_win.bind('', lambda event: self.switch_channel(3)) + self.main_win.bind('', lambda event: self.switch_channel(4)) + self.main_win.bind('', lambda event: self.switch_channel(5)) + self.main_win.bind('', lambda event: self.switch_channel(6)) + self.main_win.bind('', lambda event: self.switch_channel(7)) + self.main_win.bind('', lambda event: self.switch_channel(8)) + self.main_win.bind('', lambda event: self.switch_channel(9)) + self.main_win.bind('', lambda event: self.switch_channel(10)) + self.main_win.bind('', lambda event: self.switch_channel(0)) + self.main_win.bind('', self._snd_text) + self.main_win.bind('', self._release_return) + self.main_win.bind('', self._shift_return) + self.main_win.bind('', self._arrow_keys) + self.main_win.bind('', self._arrow_keys) + self.main_win.bind('', self._arrow_keys) + self.main_win.bind('', self._arrow_keys) + # self.main_win.bind('', self.snd_text) + self.main_win.bind('', lambda event: self.open_new_conn_win()) + self.main_win.bind('', lambda event: self.open_new_conn_win()) + self.main_win.bind('', lambda event: self._disco_conn()) + self.main_win.bind('', lambda event: self._copy_select()) + self.main_win.bind('', lambda event: self._cut_select()) + # self.main_win.bind('', lambda event: self.clipboard_past()) + self.main_win.bind('', lambda event: self._select_all()) + self.main_win.bind('', lambda event: self._increase_textsize()) + self.main_win.bind('', lambda event: self._decrease_textsize()) + self.main_win.bind('', lambda event: self._text_win_bigger()) + self.main_win.bind('', lambda event: self._text_win_smaller()) + + self.main_win.bind('', lambda event: self._any_key(event)) + + def _any_key(self, event: tk.Event): + if event.keycode == 104: # Numpad Enter + self._snd_text(event) + + def _arrow_keys(self, event=None): + self._on_click_inp_txt() + + def _shift_return(self, event=None): + pass + def _release_return(self, event=None): + pass + + ########################## + # Start Message in Monitor + def _monitor_start_msg(self): # tmp_lang = int(self.language) # self.language = random.choice([0, 1, 2, 3, 4, 5, 6, 7, 8]) self.sprech(random.choice(WELCOME_SPEECH)) @@ -1927,6 +1997,36 @@ def _monitor_start_msg(self): PORT_HANDLER.get_all_ports()[port_k].port_cfg.parm_PortParm[1] )) + ########################## + # GUI Sizing/Formatting Stuff + def _increase_textsize(self): + self.text_size += 1 + self.text_size = max(self.text_size, 3) + width = self._inp_txt.cget('width') + self._inp_txt.configure(font=(FONT, self.text_size), width=width + 1) + self._out_txt.configure(font=(FONT, self.text_size), width=width + 1) + self._mon_txt.configure(font=(FONT, self.text_size), width=width + 1) + + def _decrease_textsize(self): + self.text_size -= 1 + self.text_size = max(self.text_size, 3) + width = self._inp_txt.cget('width') + self._inp_txt.configure(font=(FONT, self.text_size), width=width - 1) + self._out_txt.configure(font=(FONT, self.text_size), width=width - 1) + self._mon_txt.configure(font=(FONT, self.text_size), width=width - 1) + + def _text_win_bigger(self): + _width = self._inp_txt.cget('width') + self._inp_txt.configure(width=_width + 1) + self._out_txt.configure(width=_width + 1) + self._mon_txt.configure(width=_width + 1) + + def _text_win_smaller(self): + _width = self._inp_txt.cget('width') + self._inp_txt.configure(width=max(_width - 1, 56)) + self._out_txt.configure(width=max(_width - 1, 56)) + self._mon_txt.configure(width=max(_width - 1, 56)) + ########################## # Clipboard Stuff def _copy_select(self): @@ -2007,87 +2107,6 @@ def _save_monitor_to_file(self): data = self._mon_txt.get('1.0', tk.END) save_file_dialog(data) - def _set_binds(self): - self._inp_txt.bind("", self._on_click_inp_txt) - - def _set_keybinds(self): - self.main_win.unbind("") - self.main_win.unbind("") - # self.main_win.bind("",lambda event: self.callback(event)) - self.main_win.bind('', lambda event: self.switch_channel(1)) - self.main_win.bind('', lambda event: self.switch_channel(2)) - self.main_win.bind('', lambda event: self.switch_channel(3)) - self.main_win.bind('', lambda event: self.switch_channel(4)) - self.main_win.bind('', lambda event: self.switch_channel(5)) - self.main_win.bind('', lambda event: self.switch_channel(6)) - self.main_win.bind('', lambda event: self.switch_channel(7)) - self.main_win.bind('', lambda event: self.switch_channel(8)) - self.main_win.bind('', lambda event: self.switch_channel(9)) - self.main_win.bind('', lambda event: self.switch_channel(10)) - self.main_win.bind('', lambda event: self.switch_channel(0)) - self.main_win.bind('', self._snd_text) - self.main_win.bind('', self._release_return) - self.main_win.bind('', self._shift_return) - self.main_win.bind('', self._arrow_keys) - self.main_win.bind('', self._arrow_keys) - self.main_win.bind('', self._arrow_keys) - self.main_win.bind('', self._arrow_keys) - # self.main_win.bind('', self.snd_text) - self.main_win.bind('', lambda event: self.open_new_conn_win()) - self.main_win.bind('', lambda event: self.open_new_conn_win()) - self.main_win.bind('', lambda event: self._disco_conn()) - self.main_win.bind('', lambda event: self._copy_select()) - self.main_win.bind('', lambda event: self._cut_select()) - # self.main_win.bind('', lambda event: self.clipboard_past()) - self.main_win.bind('', lambda event: self._select_all()) - self.main_win.bind('', lambda event: self._increase_textsize()) - self.main_win.bind('', lambda event: self._decrease_textsize()) - self.main_win.bind('', lambda event: self._text_win_bigger()) - self.main_win.bind('', lambda event: self._text_win_smaller()) - - self.main_win.bind('', lambda event: self._any_key(event)) - - def _any_key(self, event: tk.Event): - if event.keycode == 104: # Numpad Enter - self._snd_text(event) - - def _arrow_keys(self, event=None): - self._on_click_inp_txt() - - def _shift_return(self, event=None): - pass - - def _release_return(self, event=None): - pass - - def _increase_textsize(self): - self.text_size += 1 - self.text_size = max(self.text_size, 3) - width = self._inp_txt.cget('width') - self._inp_txt.configure(font=(FONT, self.text_size), width=width + 1) - self._out_txt.configure(font=(FONT, self.text_size), width=width + 1) - self._mon_txt.configure(font=(FONT, self.text_size), width=width + 1) - - def _decrease_textsize(self): - self.text_size -= 1 - self.text_size = max(self.text_size, 3) - width = self._inp_txt.cget('width') - self._inp_txt.configure(font=(FONT, self.text_size), width=width - 1) - self._out_txt.configure(font=(FONT, self.text_size), width=width - 1) - self._mon_txt.configure(font=(FONT, self.text_size), width=width - 1) - - def _text_win_bigger(self): - _width = self._inp_txt.cget('width') - self._inp_txt.configure(width=_width + 1) - self._out_txt.configure(width=_width + 1) - self._mon_txt.configure(width=_width + 1) - - def _text_win_smaller(self): - _width = self._inp_txt.cget('width') - self._inp_txt.configure(width=max(_width - 1, 56)) - self._out_txt.configure(width=max(_width - 1, 56)) - self._mon_txt.configure(width=max(_width - 1, 56)) - def change_conn_btn(self): # TODO Nur triggern wenn ch_btn click | neue in conn | disco # TODO extra Funktionen für on_disco & on_newconn @@ -3058,26 +3077,36 @@ def _update_ft_info(self): def get_ch_new_data_tr(self, ch_id): return bool(self._win_buf[ch_id].new_data_tr) - @staticmethod - def set_tracer(state: bool): + def set_tracer(self, state=None): _ais_obj = PORT_HANDLER.get_aprs_ais() if _ais_obj is not None: - _ais_obj.be_tracer_active = bool(state) - + _ais_obj.be_tracer_active = bool(self.setting_tracer.get()) + else: + self.setting_tracer.set(False) + self.tabbed_sideFrame.set_auto_tracer_state() -""" -if __name__ == '__main__': - logger.info(f"PoPT_{VER} start....") - ############# - # INIT GUI - # TODO: if setting_gui (running without GUI option): - logger.info(f"Loading GUI.") - root = tk.Tk() - # gui.guiMain.TkMainWin() - TkMainWin(root) - root.mainloop() + @staticmethod + def get_tracer(): + _ais_obj = PORT_HANDLER.get_aprs_ais() + if _ais_obj is not None: + return _ais_obj.be_tracer_active + return False - logger.info(f"PoPT_{VER} ENDE.") - print('ENDE') + def set_tracer_fm_aprs(self): + _ais_obj = PORT_HANDLER.get_aprs_ais() + if _ais_obj is not None: + self.setting_tracer.set(_ais_obj.be_tracer_active) + else: + self.setting_tracer.set(False) + self.tabbed_sideFrame.set_auto_tracer_state() -""" + def set_auto_tracer(self, event=None): + _ais_obj = PORT_HANDLER.get_aprs_ais() + set_to = False + if _ais_obj is not None: + if self.setting_tracer.get(): + set_to = False + else: + set_to = not bool(self.setting_auto_tracer.get()) + self.setting_auto_tracer.set(set_to) + self.tabbed_sideFrame.set_auto_tracer_state() From 9f157e00db67c008c8840c8b3ed7eb9242135ac9 Mon Sep 17 00:00:00 2001 From: masto Date: Wed, 4 Oct 2023 08:34:47 +0200 Subject: [PATCH 06/17] - finished "better DX-Alarm" --- ax25/ax25Statistics.py | 37 +++++++++++++++++++--------- ax25aprs/aprs_dec.py | 13 +++++----- constant.py | 5 +++- gui/guiMH.py | 41 ++++++++++++++++++++++--------- gui/guiMain.py | 56 +++++++++++++++++++++++------------------- 5 files changed, 96 insertions(+), 56 deletions(-) diff --git a/ax25/ax25Statistics.py b/ax25/ax25Statistics.py index c92fd3c5..c98c94c3 100644 --- a/ax25/ax25Statistics.py +++ b/ax25/ax25Statistics.py @@ -101,7 +101,10 @@ def __init__(self): if not hasattr(self.calls[call], att): setattr(self.calls[call], att, getattr(MyHeard, att)) - self.new_call_alarm = False + self.dx_alarm_trigger = False + self.parm_new_call_alarm = False + self.parm_distance_alarm = 50 + self.parm_lastseen_alarm = 1 def __del__(self): pass @@ -109,11 +112,11 @@ def __del__(self): def bw_mon_inp(self, ax25_frame, port_id): if port_id not in self.port_statistik_DB.keys(): self.port_statistik_DB[port_id] = {} - self.init_bw_struct(port_id) - self.input_stat_db(ax_frame=ax25_frame, port_id=port_id) + self._init_bw_struct(port_id) + self._input_stat_db(ax_frame=ax25_frame, port_id=port_id) - def input_bw_calc(self, port_id, ax_frame=None, ): - self.init_bw_struct(port_id=port_id) + def _input_bw_calc(self, port_id, ax_frame=None, ): + self._init_bw_struct(port_id=port_id) if ax_frame is not None: if self.now_min == datetime.now().strftime('%H:%M:%S')[:-1]: self.bandwidth[port_id][self.now_min] += len(ax_frame.data_bytes) @@ -125,12 +128,12 @@ def input_bw_calc(self, port_id, ax_frame=None, ): self.now_min = datetime.now().strftime('%H:%M:%S')[:-1] self.bandwidth[port_id][self.now_min] = 0 - def init_bw_struct(self, port_id): + def _init_bw_struct(self, port_id): if port_id not in self.bandwidth: self.bandwidth[port_id] = get_bandwidth_struct() def get_bandwidth(self, port_id, baud=1200): - self.init_bw_struct(port_id=port_id) + self._init_bw_struct(port_id=port_id) ret = deque([0] * 60, maxlen=60) now = datetime.now() ten_minutes_ago = now - timedelta(minutes=10) @@ -147,7 +150,7 @@ def get_bandwidth(self, port_id, baud=1200): i += 1 return ret - def input_stat_db(self, ax_frame, port_id): + def _input_stat_db(self, ax_frame, port_id): now = datetime.now() date_str = now.strftime('%d/%m/%y') hour = now.hour @@ -162,7 +165,7 @@ def input_stat_db(self, ax_frame, port_id): if dt not in last_days: del self.port_statistik_DB[port_id][dt] - self.input_bw_calc(ax_frame=ax_frame, port_id=port_id) + self._input_bw_calc(ax_frame=ax_frame, port_id=port_id) if date_str not in list(self.port_statistik_DB[port_id].keys()): self.port_statistik_DB[port_id][date_str] = init_day_dic() self.port_statistik_DB[port_id][date_str][hour]['N_pack'][minute] += 1 @@ -181,16 +184,20 @@ def mh_inp(self, ax25_frame, port_name, port_id): if port_id not in self.port_statistik_DB.keys(): self.port_statistik_DB[port_id] = init_day_dic() # self.port_statistik_DB[port_id].input_stat_db(ax_frame=ax25_frame) - self.input_stat_db(ax25_frame, port_id) + self._input_stat_db(ax25_frame, port_id) ######################## # MH Entry call_str = str(ax25_frame.from_call.call_str) if call_str not in self.calls.keys(): - self.new_call_alarm = True ent = MyHeard() - ent.first_seen = datetime.now() + if self.parm_new_call_alarm: + self.dx_alarm_trigger = True else: ent = self.calls[call_str] + _t_delta = datetime.now() - ent.last_seen + if self.parm_lastseen_alarm: + if _t_delta.days >= self.parm_lastseen_alarm: + self.dx_alarm_trigger = True ent.last_seen = datetime.now() ent.own_call = call_str ent.pac_n += 1 @@ -227,6 +234,10 @@ def mh_inp(self, ax25_frame, port_name, port_id): if db_ent: ent.locator = str(db_ent.LOC) ent.distance = float(db_ent.Distance) + if self.parm_distance_alarm: + if ent.distance >= self.parm_distance_alarm: + self.dx_alarm_trigger = True + self.calls[call_str] = ent def mh_get_data_fm_call(self, call_str): @@ -292,6 +303,7 @@ def mh_get_last_ip(self, call_str: str, param_fail=20): return self.calls[call_str].axip_add return '', 0 + """ def mh_get_ip_fm_all(self, param_fail=20): ret: [(str, (str, int))] = [] for stat_call in self.calls.keys(): @@ -300,6 +312,7 @@ def mh_get_ip_fm_all(self, param_fail=20): ent = stat_call, station.axip_add ret.append(ent) return ret + """ def mh_ip_failed(self, axip: str): for k in self.calls.keys(): diff --git a/ax25aprs/aprs_dec.py b/ax25aprs/aprs_dec.py index ed191d2f..27108763 100644 --- a/ax25aprs/aprs_dec.py +++ b/ax25aprs/aprs_dec.py @@ -141,10 +141,7 @@ def format_aprs_msg(aprs_frame: aprslib.parse, own_locator, full_aprs_frame: apr dist = '' typ = '' loc = '' - db_ent = USER_DB.get_entry(full_aprs_frame['from'], add_new=add_new_user) for k in aprs_frame: - # print(f"{k}: {aprs_frame[k]}") - if aprs_frame[k]: # if k not in ['from', 'to', 'symbol_table', 'symbol', 'subpacket', 'weather']: if k not in ['from', 'to', 'raw', 'symbol_table', 'symbol', 'subpacket', 'weather']: @@ -197,15 +194,17 @@ def format_aprs_msg(aprs_frame: aprslib.parse, own_locator, full_aprs_frame: apr ret += f"├►{k.upper().ljust(13)}: {aprs_frame[k]}\n" if k in ['weather', 'wx']: typ = 'APRS-WX' - if db_ent: - if loc: + + if loc: + db_ent = USER_DB.get_entry(full_aprs_frame.get('from', ''), add_new=add_new_user) + if db_ent: db_ent.LOC = loc db_ent.Lat = aprs_frame['latitude'] db_ent.Lon = aprs_frame['longitude'] if type(dist) == float: db_ent.Distance = float(dist) - if not db_ent.TYP and typ: - db_ent.TYP = typ + if not db_ent.TYP and typ: + db_ent.TYP = typ return ret, dist diff --git a/constant.py b/constant.py index 5c3f609d..a41e7b58 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.4dev' +VER = '2.98.5dev' LANGUAGE = 0 # QUICK FIX """ 0 = German @@ -17,6 +17,9 @@ CFG_mh_data_file = 'data/mh_data.popt' CFG_port_stat_data_file = 'data/port_stat.popt' CFG_aprs_data_file = 'aprs.popt' +CFG_sound_DICO = '//data//sound//disco_alarm.wav' +CFG_sound_CONN = '//data//sound//conn_alarm.wav' +CFG_sound_RX_BEEP = '//data//sound//rx_beep.wav' CFG_txt_save = { 'stat_parm_cli_ctext': 'ctx', diff --git a/gui/guiMH.py b/gui/guiMH.py index 8cc599fb..90c7e591 100644 --- a/gui/guiMH.py +++ b/gui/guiMH.py @@ -71,35 +71,35 @@ def __init__(self, root_win): tk.Label(frame_21_newCall, text='new Call ').pack(side=tk.LEFT, ) tk.Checkbutton(frame_21_newCall, variable=self._alarm_newCall_var, - # command=self._chk_alarm_active + command=self._set_alarm_newCall ).pack(side=tk.LEFT, ) # Alarm seen since Days frame_21_seen = tk.Frame(lower_frame) frame_21_seen.pack(side=tk.LEFT, fill=tk.BOTH, padx=30) - tk.Label(frame_21_seen, text='seen since (Days) ').pack(side=tk.LEFT, ) + tk.Label(frame_21_seen, text='seen since (Days) (0 = off)').pack(side=tk.LEFT, ) tk.Spinbox(frame_21_seen, from_=1, to=365, - increment=10, + increment=1, width=4, textvariable=self._alarm_seenSince_var, - # command=self._set_alarm_distance + command=self._set_alarm_last_seen ).pack(side=tk.LEFT, ) # Alarm Distance frame_21_distance = tk.Frame(lower_frame) frame_21_distance.pack(side=tk.LEFT, fill=tk.BOTH, padx=30) - tk.Label(frame_21_distance, text='Distance ').pack(side=tk.LEFT, ) + tk.Label(frame_21_distance, text='Distance (0 = off)').pack(side=tk.LEFT, ) tk.Spinbox(frame_21_distance, - from_=1, + from_=0, to=20000, - increment=50, + increment=1, width=6, textvariable=self._alarm_distance_var, - # command=self._set_alarm_distance + command=self._set_alarm_distance ).pack(side=tk.LEFT, ) # ###################### Auto Tracer ###################### @@ -191,12 +191,31 @@ def __init__(self, root_win): def _get_vars(self): # self._alarm_active_var.set(bool()) - self._alarm_newCall_var.set(bool()) - self._alarm_seenSince_var.set(str()) - self._alarm_distance_var.set(str()) + self._alarm_newCall_var.set(bool(MH_LIST.parm_new_call_alarm)) + self._alarm_seenSince_var.set(str(MH_LIST.parm_lastseen_alarm)) + self._alarm_distance_var.set(str(MH_LIST.parm_distance_alarm)) # self._tracer_active_var.set(bool(self._root_win.setting_auto_tracer.get())) self._tracer_duration_var.set(str()) + def _set_alarm_distance(self, event=None): + _var = self._alarm_distance_var.get() + try: + _var = int(_var) + except ValueError: + return + MH_LIST.parm_distance_alarm = _var + + def _set_alarm_last_seen(self, event=None): + _var = self._alarm_seenSince_var.get() + try: + _var = int(_var) + except ValueError: + return + MH_LIST.parm_lastseen_alarm = _var + + def _set_alarm_newCall(self, event=None): + MH_LIST.parm_new_call_alarm = bool(self._alarm_newCall_var.get()) + def entry_selected(self, event): for selected_item in self._tree.selection(): item = self._tree.item(selected_item) diff --git a/gui/guiMain.py b/gui/guiMain.py index 08eeb964..eeed6a5f 100644 --- a/gui/guiMain.py +++ b/gui/guiMain.py @@ -48,7 +48,8 @@ from gui.guiFileTX import FileSend from constant import LANGUAGE, FONT, POPT_BANNER, WELCOME_SPEECH, VER, CFG_clr_sys_msg, STATION_TYPS, \ ENCODINGS, TEXT_SIZE_STATUS, TXT_BACKGROUND_CLR, TXT_OUT_CLR, TXT_INP_CLR, TXT_INP_CURSOR_CLR, TXT_MON_CLR, \ - STAT_BAR_CLR, STAT_BAR_TXT_CLR, FONT_STAT_BAR, STATUS_BG, PARAM_MAX_MON_LEN + STAT_BAR_CLR, STAT_BAR_TXT_CLR, FONT_STAT_BAR, STATUS_BG, PARAM_MAX_MON_LEN, CFG_sound_RX_BEEP, CFG_sound_CONN, \ + CFG_sound_DICO from string_tab import STR_TABLE from fnc.os_fnc import is_linux, is_windows, get_root_dir from fnc.gui_fnc import get_all_tags, set_all_tags, generate_random_hex_color @@ -385,18 +386,18 @@ def __init__(self, main_cl): command=self._chk_tracer, state=_auto_tracer_state ) - self._autotracer_chk_btn.place(x=10, y=115) + self._autotracer_chk_btn.place(x=10, y=110) Checkbutton(self.tab4_settings, text="DX-Alarm", variable=self._main_win.setting_dx_alarm, # command=self._chk_tracer, # state='disabled' - ).place(x=10, y=145) + ).place(x=10, y=135) # RX ECHO Checkbutton(self.tab4_settings, text="RX-Echo", variable=self._main_win.setting_rx_echo, - ).place(x=10, y=175) + ).place(x=10, y=160) ############ # CH ECHO self._chk_btn_default_clr = self._autotracer_chk_btn.cget('bg') @@ -1663,7 +1664,7 @@ def _init_vars(self): ##################### # GUI VARS self.connect_history = {} - # GLb Settings + # GLb Setting Vars self.setting_sound = tk.BooleanVar(self.main_win) self.setting_sprech = tk.BooleanVar(self.main_win) self.setting_bake = tk.BooleanVar(self.main_win) @@ -1671,17 +1672,6 @@ def _init_vars(self): self.setting_tracer = tk.BooleanVar(self.main_win) self.setting_auto_tracer = tk.BooleanVar(self.main_win) self.setting_dx_alarm = tk.BooleanVar(self.main_win) - # Glb Settings Defaults - self.setting_sound.set(False) - self.setting_bake.set(True) - self.setting_rx_echo.set(False) - self.setting_tracer.set(False) - self.setting_auto_tracer.set(False) - self.setting_dx_alarm.set(True) - if is_linux(): - self.setting_sprech.set(True) - else: - self.setting_sprech.set(False) # Controlling self.ch_alarm = False self.ch_alarm_sound_one_time = False @@ -1725,6 +1715,22 @@ def _init_vars(self): for _i in list(range(60)): self._bw_plot_x_scale.append(_i / 6) self._bw_plot_lines = {} + ######################################## + # Set Default Settings TODO Save to cfg + self.setting_sound.set(False) + self.setting_bake.set(True) + self.setting_rx_echo.set(False) + self.setting_tracer.set(False) + self.setting_auto_tracer.set(False) + self.setting_dx_alarm.set(True) + if is_linux(): + self.setting_sprech.set(True) + else: + self.setting_sprech.set(False) + # MH + MH_LIST.parm_new_call_alarm = True + MH_LIST.parm_distance_alarm = 50 + MH_LIST.parm_lastseen_alarm = 1 def _init_bw_plot(self): # plt.ion() @@ -2259,13 +2265,13 @@ def _rx_beep_sound(self): if tr: if temp.rx_beep_tr: temp.rx_beep_tr = False - self._sound_play(self._root_dir + '//data//sound//rx_beep.wav', False) + self._sound_play(self._root_dir + CFG_sound_RX_BEEP, False) def new_conn_sound(self): - self._sound_play(self._root_dir + '//data//sound//conn_alarm.wav', False) + self._sound_play(self._root_dir + CFG_sound_CONN, False) def disco_sound(self): - self._sound_play(self._root_dir + '//data//sound//disco_alarm.wav', False) + self._sound_play(self._root_dir + CFG_sound_DICO, False) # Sound Ende ################# @@ -2274,10 +2280,10 @@ def disco_sound(self): def _dx_alarm(self): """ Alarm when new User in MH List """ - # self.tabbed_sideFrame.tabControl.select(self.tabbed_sideFrame.tab2_mh) - _clr = generate_random_hex_color() - if self._mh_btn.cget('bg') != _clr: - self._mh_btn.configure(bg=_clr) + if self.setting_dx_alarm.get(): + _clr = generate_random_hex_color() + if self._mh_btn.cget('bg') != _clr: + self._mh_btn.configure(bg=_clr) def _tracer_alarm(self): """ Tracer Alarm """ @@ -2293,7 +2299,7 @@ def _reset_tracer_alarm(self): self._tracer_btn.configure(bg=self._tracer_btn_def_clr) def _reset_dx_alarm(self): - MH_LIST.new_call_alarm = False + MH_LIST.dx_alarm_trigger = False if self._mh_btn.cget('bg') != self._mh_btn_def_clr: self._mh_btn.configure(bg=self._mh_btn_def_clr) @@ -2347,7 +2353,7 @@ def _tasker_1_sec(self): # if MH_LIST.new_call_alarm and self.setting_dx_alarm.get(): if self.ch_alarm: self.ch_status_update() - if MH_LIST.new_call_alarm: + if MH_LIST.dx_alarm_trigger: self._dx_alarm() if PORT_HANDLER.get_aprs_ais() is not None: if PORT_HANDLER.get_aprs_ais().tracer_is_alarm(): From 0022c0d6a07d8503533ff8d65f7c73990d44c7e6 Mon Sep 17 00:00:00 2001 From: masto Date: Wed, 4 Oct 2023 13:27:03 +0200 Subject: [PATCH 07/17] - finished "Auto Tracer" --- UserDB/UserDBmain.py | 4 ++-- ax25/ax25Statistics.py | 12 +++++++--- ax25aprs/aprs_station.py | 44 +++++++++++++++++++++++++++++++--- cli/cliMain.py | 1 + constant.py | 7 +++++- gui/guiMH.py | 14 ++++++++--- gui/guiMain.py | 51 ++++++++++++++++++++++++++++++++++++---- gui/guiUserDB.py | 41 +++++++++++++++++--------------- idea.txt | 5 +++- 9 files changed, 142 insertions(+), 37 deletions(-) diff --git a/UserDB/UserDBmain.py b/UserDB/UserDBmain.py index f36adec5..1c3d69fa 100644 --- a/UserDB/UserDBmain.py +++ b/UserDB/UserDBmain.py @@ -120,9 +120,9 @@ def get_entry(self, call_str, add_new=True): else: return False else: - self.entry_var_upgrade(call_tup[0]) + # self.entry_var_upgrade(call_tup[0]) return self.db[call_tup[0]] - self.entry_var_upgrade(call_str) + # self.entry_var_upgrade(call_str) return self.db[call_str] return False diff --git a/ax25/ax25Statistics.py b/ax25/ax25Statistics.py index c98c94c3..50df6b40 100644 --- a/ax25/ax25Statistics.py +++ b/ax25/ax25Statistics.py @@ -1,3 +1,4 @@ +import time from collections import deque from datetime import datetime from datetime import timedelta @@ -102,6 +103,7 @@ def __init__(self): setattr(self.calls[call], att, getattr(MyHeard, att)) self.dx_alarm_trigger = False + self.last_dx_alarm = time.time() self.parm_new_call_alarm = False self.parm_distance_alarm = 50 self.parm_lastseen_alarm = 1 @@ -109,6 +111,10 @@ def __init__(self): def __del__(self): pass + def _set_dx_alarm(self): + self.dx_alarm_trigger = True + self.last_dx_alarm = time.time() + def bw_mon_inp(self, ax25_frame, port_id): if port_id not in self.port_statistik_DB.keys(): self.port_statistik_DB[port_id] = {} @@ -191,13 +197,13 @@ def mh_inp(self, ax25_frame, port_name, port_id): if call_str not in self.calls.keys(): ent = MyHeard() if self.parm_new_call_alarm: - self.dx_alarm_trigger = True + self._set_dx_alarm() else: ent = self.calls[call_str] _t_delta = datetime.now() - ent.last_seen if self.parm_lastseen_alarm: if _t_delta.days >= self.parm_lastseen_alarm: - self.dx_alarm_trigger = True + self._set_dx_alarm() ent.last_seen = datetime.now() ent.own_call = call_str ent.pac_n += 1 @@ -236,7 +242,7 @@ def mh_inp(self, ax25_frame, port_name, port_id): ent.distance = float(db_ent.Distance) if self.parm_distance_alarm: if ent.distance >= self.parm_distance_alarm: - self.dx_alarm_trigger = True + self._set_dx_alarm() self.calls[call_str] = ent diff --git a/ax25aprs/aprs_station.py b/ax25aprs/aprs_station.py index c8742ea6..f3596ee2 100644 --- a/ax25aprs/aprs_station.py +++ b/ax25aprs/aprs_station.py @@ -10,7 +10,7 @@ from constant import APRS_SW_ID, APRS_TRACER_COMMENT, CFG_aprs_data_file from fnc.cfg_fnc import cleanup_obj, save_to_file, load_fm_file, set_obj_att from fnc.loc_fnc import decimal_degrees_to_aprs, locator_distance, coordinates_to_locator -from fnc.str_fnc import convert_umlaute_to_ascii, get_timedelta_str, convert_str_to_datetime +from fnc.str_fnc import convert_umlaute_to_ascii logger = logging.getLogger(__name__) @@ -53,13 +53,14 @@ def __init__(self, load_cfg=True): self.aprs_wx_msg_pool = {} """ Beacon Tracer """ # Param - self.be_tracer_active = False self.be_tracer_interval = 5 self.be_tracer_port = 0 self.be_tracer_station = 'NOCALL' self.be_tracer_wide = 1 self.be_tracer_alarm_active = False self.be_tracer_alarm_range = 50 + self.be_auto_tracer_duration = 60 + # Packet Pool TODO: extra var f Packet history self.be_tracer_traced_packets = {} # Control vars @@ -78,6 +79,9 @@ def __init__(self, load_cfg=True): } self.aprs_wx_msg_pool = {} """ + self.be_tracer_active = False + self.be_auto_tracer_active = False + self._be_auto_tracer_timer = 0 """""" self.ais = None self.ais_mon_gui = None @@ -666,6 +670,15 @@ def _tracer_task(self): if time.time() > self._be_tracer_interval_timer: # print("TRACER TASKER") self.tracer_sendit() + return + if self.be_auto_tracer_active: + if not self.be_auto_tracer_duration: + return + if time.time() > self._be_auto_tracer_timer: + return + if time.time() > self._be_tracer_interval_timer: + self.tracer_sendit() + return def _tracer_build_msg(self): # !5251.12N\01109.78E-27.235MHz P.ython o.ther P.acket T.erminal (PoPT) @@ -700,9 +713,18 @@ def tracer_sendit(self): if _pack.get('raw_message_text', '') and _pack.get('comment', ''): self._be_tracer_tx_trace_packet = _pack.get('comment', '') self._send_as_UI(_pack) - self._be_tracer_interval_timer = time.time() + (60 * self.be_tracer_interval) + self._tracer_reset_timer() # print(self._tracer_build_msg()) + def _tracer_reset_timer(self): + self._be_tracer_interval_timer = time.time() + (60 * self.be_tracer_interval) + + def tracer_reset_auto_timer(self, ext_timer=None): + if ext_timer is None: + self._be_auto_tracer_timer = time.time() + (self.be_auto_tracer_duration * 60) + else: + self._be_auto_tracer_timer = ext_timer + (self.be_auto_tracer_duration * 60) + def tracer_get_last_send(self): return time.time() - (self._be_tracer_interval_timer - (60 * self.be_tracer_interval)) @@ -784,3 +806,19 @@ def tracer_update_gui(self): def tracer_traces_get(self): return self.be_tracer_traced_packets + + def tracer_auto_tracer_set(self, state=None): + if self.be_tracer_active: + self.be_auto_tracer_active = False + return False + if state is None: + self.be_auto_tracer_active = not self.be_auto_tracer_active + self.tracer_reset_auto_timer() + return bool(self.be_auto_tracer_active) + self._be_auto_tracer_timer = 0 + self.be_auto_tracer_active = state + return bool(self.be_auto_tracer_active) + + def tracer_auto_tracer_duration_set(self, dur: int): + self.be_auto_tracer_duration = dur + diff --git a/cli/cliMain.py b/cli/cliMain.py index 10b52c72..faa72ea5 100644 --- a/cli/cliMain.py +++ b/cli/cliMain.py @@ -639,6 +639,7 @@ def cmd_aprs_trace(self): out += f'Tracer Call : {self.port_handler.aprs_ais.be_tracer_station}\r' out += f'Tracer WIDE Path: {self.port_handler.aprs_ais.be_tracer_wide}\r' out += f'Tracer intervall: {intervall_str}\r' + out += f'Auto Tracer : {constant.BOOL_ON_OFF.get(self.port_handler.aprs_ais.be_auto_tracer_active, False)}\r' out += f'Last Trace send : {_last_send}\r\r' out += '-----Last-Port--Call------LOC-------------Path----------------------------------\r' max_c = 0 diff --git a/constant.py b/constant.py index a41e7b58..55417eb5 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.5dev' +VER = '2.98.6dev' LANGUAGE = 0 # QUICK FIX """ 0 = German @@ -176,3 +176,8 @@ 'DEST-RNR-REJ': 'sky blue', # 15 'BOTH-RNR-REJ': 'deep sky blue', # 16 } + +BOOL_ON_OFF = { + True: 'ON', + False: 'OFF', +} diff --git a/gui/guiMH.py b/gui/guiMH.py index 90c7e591..ed047d6f 100644 --- a/gui/guiMH.py +++ b/gui/guiMH.py @@ -135,8 +135,8 @@ def __init__(self, root_win): increment=5, width=5, textvariable=self._tracer_duration_var, - state=_auto_tracer_state - # command=self._set_alarm_distance + state=_auto_tracer_state, + command=self._set_auto_tracer, ).pack(side=tk.LEFT, ) ########################################################################################## @@ -195,7 +195,7 @@ def _get_vars(self): self._alarm_seenSince_var.set(str(MH_LIST.parm_lastseen_alarm)) self._alarm_distance_var.set(str(MH_LIST.parm_distance_alarm)) # self._tracer_active_var.set(bool(self._root_win.setting_auto_tracer.get())) - self._tracer_duration_var.set(str()) + self._tracer_duration_var.set(str(self._root_win.get_auto_tracer_duration())) def _set_alarm_distance(self, event=None): _var = self._alarm_distance_var.get() @@ -216,6 +216,14 @@ def _set_alarm_last_seen(self, event=None): def _set_alarm_newCall(self, event=None): MH_LIST.parm_new_call_alarm = bool(self._alarm_newCall_var.get()) + def _set_auto_tracer(self, event=None): + _dur = self._tracer_duration_var.get() + try: + _dur = int(_dur) + except ValueError: + return + self._root_win.set_auto_tracer_duration(_dur) + def entry_selected(self, event): for selected_item in self._tree.selection(): item = self._tree.item(selected_item) diff --git a/gui/guiMain.py b/gui/guiMain.py index eeed6a5f..0f261d7f 100644 --- a/gui/guiMain.py +++ b/gui/guiMain.py @@ -383,14 +383,14 @@ def __init__(self, main_cl): self._autotracer_chk_btn = Checkbutton(self.tab4_settings, text="Auto-Tracer", variable=self._main_win.setting_auto_tracer, - command=self._chk_tracer, + command=self._chk_auto_tracer, state=_auto_tracer_state ) self._autotracer_chk_btn.place(x=10, y=110) Checkbutton(self.tab4_settings, text="DX-Alarm", variable=self._main_win.setting_dx_alarm, - # command=self._chk_tracer, + command=self._main_win.set_dx_alarm, # state='disabled' ).place(x=10, y=135) # RX ECHO @@ -572,10 +572,11 @@ def reset_dx_alarm(self, event=None): """ def set_auto_tracer_state(self): + _bool_state = self._main_win.get_tracer() or not self._main_win.get_dx_alarm() _state = { True: 'disabled', False: 'normal' - }.get(self._main_win.get_tracer(), 'disabled') + }.get(_bool_state, 'disabled') self._autotracer_chk_btn.configure(state=_state) def _update_ch_echo(self): @@ -662,6 +663,9 @@ def _chk_dx_alarm(self): def _chk_tracer(self): self._main_win.set_tracer() + def _chk_auto_tracer(self): + self._main_win.set_auto_tracer() + def _chk_rnr(self): conn = self._main_win.get_conn() if conn: @@ -1652,6 +1656,8 @@ def _destroy_win(self): self.aprs_pn_msg_win.destroy() if self.be_tracer_win is not None: self.be_tracer_win.destroy() + self.main_win.update_idletasks() + self._loop_delay = 800 #################### # Init Stuff @@ -2284,6 +2290,9 @@ def _dx_alarm(self): _clr = generate_random_hex_color() if self._mh_btn.cget('bg') != _clr: self._mh_btn.configure(bg=_clr) + _aprs_obj = PORT_HANDLER.get_aprs_ais() + if _aprs_obj is not None: + _aprs_obj.tracer_reset_auto_timer(MH_LIST.last_dx_alarm) def _tracer_alarm(self): """ Tracer Alarm """ @@ -2315,6 +2324,7 @@ def _tasker(self): # MAINLOOP self._tasker_1_sec() self._tasker_5_sec() # self._tasker_tester() + self.main_win.update_idletasks() self.main_win.after(self._loop_delay, self._tasker) @staticmethod @@ -2554,7 +2564,6 @@ def _monitor_task(self): self._mon_txt.configure(state="disabled", exportselection=True) if tr or self.tabbed_sideFrame.mon_scroll_var.get(): self._see_end_mon_win() - self.main_win.update_idletasks() def see_end_qso_win(self): self._out_txt.see("end") @@ -2694,9 +2703,14 @@ def _UserDB_tree(self): self.userDB_tree_win = UserDBtreeview(self) def gui_set_distance(self): + self._set_distance_fm_conn() + + def _set_distance_fm_conn(self): _conn = self.get_conn() if _conn: _conn.set_distance() + return True + return False # ############## # DISCO @@ -3089,6 +3103,7 @@ def set_tracer(self, state=None): _ais_obj.be_tracer_active = bool(self.setting_tracer.get()) else: self.setting_tracer.set(False) + self.set_auto_tracer() self.tabbed_sideFrame.set_auto_tracer_state() @staticmethod @@ -3110,9 +3125,35 @@ def set_auto_tracer(self, event=None): _ais_obj = PORT_HANDLER.get_aprs_ais() set_to = False if _ais_obj is not None: + self.set_tracer_fm_aprs() if self.setting_tracer.get(): set_to = False else: - set_to = not bool(self.setting_auto_tracer.get()) + set_to = bool(self.setting_auto_tracer.get()) + _ais_obj.tracer_auto_tracer_set(set_to) self.setting_auto_tracer.set(set_to) self.tabbed_sideFrame.set_auto_tracer_state() + + @staticmethod + def get_auto_tracer_duration(): + _ais_obj = PORT_HANDLER.get_aprs_ais() + if _ais_obj is None: + return 0 + return _ais_obj.be_auto_tracer_duration + + def set_auto_tracer_duration(self, dur): + _ais_obj = PORT_HANDLER.get_aprs_ais() + if _ais_obj is not None: + if type(dur) == int: + _ais_obj.tracer_auto_tracer_duration_set(dur) + self.set_auto_tracer() + + def set_dx_alarm(self, event=None): + _dx_alarm = bool(self.setting_dx_alarm.get()) + if not _dx_alarm: + self.setting_auto_tracer.set(False) + self.set_auto_tracer() + + def get_dx_alarm(self): + return bool(self.setting_dx_alarm.get()) + diff --git a/gui/guiUserDB.py b/gui/guiUserDB.py index bb350168..d95a3cad 100644 --- a/gui/guiUserDB.py +++ b/gui/guiUserDB.py @@ -23,7 +23,7 @@ def __init__(self, root, ent_key=''): f"{self.win_height}+" f"{self.root.main_win.winfo_x()}+" f"{self.root.main_win.winfo_y()}") - self.protocol("WM_DELETE_WINDOW", self.destroy_win) + self.protocol("WM_DELETE_WINDOW", self._destroy_win) self.resizable(False, False) try: self.iconbitmap("favicon.ico") @@ -59,7 +59,7 @@ def __init__(self, root, ent_key=''): # bg="green", height=1, width=8, - command=self.destroy_win) + command=self._destroy_win) ok_bt.place(x=20, y=self.win_height - 50) save_bt.place(x=110, y=self.win_height - 50) cancel_bt.place(x=self.win_width - 120, y=self.win_height - 50) @@ -404,6 +404,7 @@ def __init__(self, root, ent_key=''): root.userdb_win = self def select_entry(self, event=None): + self._save_vars() for selected_item in self.tree.selection(): item = self.tree.item(selected_item) record = item['values'][0] @@ -474,15 +475,14 @@ def set_var_to_ent(self): self.db_ent.sys_pw_parm.append('SYS') self.login_cmd_var.set(str(self.db_ent.sys_pw_parm[2])) - - self.update_sysop_opt() - self.update_stations() + self._update_sysop_opt() + self._update_stations() def sysop_opt_remove(self): self.sysop_var.set('') # remove default selection only, not the full list self.sysop_ent['menu'].delete(0, 'end') # remove full list - def update_sysop_opt(self): + def _update_sysop_opt(self): self.sysop_opt_remove() # remove all options if self.db_ent.TYP == 'SYSOP': @@ -498,12 +498,13 @@ def update_sysop_opt(self): for opt in sorted(self._user_db.get_keys_by_typ(typ='SYSOP')): self.sysop_ent['menu'].add_command(label=opt, command=tk._setit(self.sysop_var, opt)) - def update_stations(self): + def _update_stations(self): sysop_key = '' - if self.db_ent.TYP == 'SYSOP': - sysop_key = self.db_ent.call_str - else: - sysop_key = self.db_ent.Sysop_Call + if self.db_ent: + if self.db_ent.TYP == 'SYSOP': + sysop_key = self.db_ent.call_str + else: + sysop_key = self.db_ent.Sysop_Call node_str = 'NODES: ' bbs_str = 'BBS: ' @@ -527,6 +528,13 @@ def update_stations(self): self.stations_other_var.set(other_str) def save_btn_cmd(self): + self._save_vars() + self._user_db.save_data() + self.select_entry() + self.root.update_station_info() + self.root.msg_to_monitor(f'Info: User Daten für {self.db_ent.call_str} wurden gespeichert..') + + def _save_vars(self): if self.db_ent: self.db_ent.Name = self.name_var.get() self.db_ent.QTH = self.qth_var.get() @@ -560,17 +568,12 @@ def save_btn_cmd(self): if tmp != self.db_ent.Sysop_Call: self.db_ent.Sysop_Call = tmp self.on_select_sysop() - - self._user_db.save_data() - self.select_entry() self.root.gui_set_distance() - self.root.update_station_info() - self.root.msg_to_monitor(f'Info: User Daten für {self.db_ent.call_str} wurden gespeichert..') def ok_btn_cmd(self): - + self._save_vars() self.root.msg_to_monitor('Lob: Du hast dir heute noch kein Lob verdient.') - self.destroy_win() + self._destroy_win() def del_btn_cmd(self): if self.db_ent: @@ -587,7 +590,7 @@ def del_btn_cmd(self): self.db_ent = self._user_db.get_entry(ents[0]) self.select_entry() - def destroy_win(self): + def _destroy_win(self): self.root.userdb_win = None self.destroy() diff --git a/idea.txt b/idea.txt index 519f746a..422642bd 100644 --- a/idea.txt +++ b/idea.txt @@ -11,6 +11,8 @@ Ideas/TODO's : - Debugging Tool - Simple Mailbox - BBS Tool was Bulletins und PMs von/an Heimat-BBS holt/sendet und Mails aufbereitet darstellt. +- BBS (S&F und all den Gedöns) +- "Nachrichten-Center" fasst alle Nachrichtenkanäle (APRS Bulletin/PN, BBS) übersichtlich zusammen. - Telnet Port - Loop Port oder einfach localhost via AXIP - MultiKISS @@ -27,6 +29,7 @@ Ideas/TODO's : ✓ APRS Private Message System ✓ APRS Tracer ✓ APRS Tracer Alarm +✓ APRS Auto-Tracer nach DX-Alarm(MH-Liste) ✓ APRS WX Stationen (Wetterstationen) Monitoring Auswertung - APRS Digi / I-Gate Funktion - "Managed-DIGI" Funktion (Die DIGI Verbindung wird wie ein Noden Link behandelt) @@ -36,7 +39,7 @@ Ideas/TODO's : - Daten Komprimierung - Daten Verschlüsselung (AES/RSA) ✓ ordentliches Noden System bzw CLI überarbeiten -- DX-Alarm überarbeiten +✓ DX-Alarm überarbeiten ✓ Autoscrolling überarbeiten. - Optional nur als Konsolen Anwendung ohne GUI. (Ist bereits dafür vorbereitet) - Drucker Ausgabe vom QSO From a27ca0aec9474bab207b6f8f897c8a50030436b8 Mon Sep 17 00:00:00 2001 From: masto Date: Wed, 4 Oct 2023 14:32:39 +0200 Subject: [PATCH 08/17] - Cli CMD "AXIP" added. --- cli/cliMain.py | 31 +++++++++++++++++++++++++++++++ constant.py | 2 +- fnc/str_fnc.py | 22 +++++++++++++++++----- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/cli/cliMain.py b/cli/cliMain.py index faa72ea5..1e1c4eda 100644 --- a/cli/cliMain.py +++ b/cli/cliMain.py @@ -98,6 +98,7 @@ def __init__(self, connection): b'PORT': (self.cmd_port, 'Ports'), b'LCSTATUS': (self.cmd_lcstatus, STR_TABLE['cmd_help_lcstatus'][self.connection.cli_language]), b'MH': (self.cmd_mh, 'MYHeard Liste'), + b'AXIP': (self.cmd_axip, 'AXIP-MH Liste'), b'LMH': (self.cmd_mhl, 'Long MYHeard Liste'), b'ATR': (self.cmd_aprs_trace, 'APRS-Tracer'), b'WX': (self.cmd_wx, 'Wetterstationen'), @@ -463,6 +464,36 @@ def cmd_q(self): # Quit self.crone_state_index = 100 # Quit State return '' + def cmd_axip(self): + parm = 10 + if self.parameter: + try: + parm = int(self.parameter[0]) + except ValueError: + pass + ret = self._get_axip_out_cli(max_ent=parm) + + return ret + '\r' + + @staticmethod + def _get_axip_out_cli(max_ent=10): + _ent = MH_LIST.get_sort_mh_entry('last', reverse=False) + max_c = 0 + out = '\r' + # out += '\r < AXIP - Clients >\r\r' + out += '-Call-----IP:Port------------------------Last---------------\r' + for k in _ent.keys(): + if _ent[k].axip_add[0]: + max_c += 1 + if max_c > max_ent: + break + out += '{:9} {:30} {:8}\r'.format( + _ent[k].own_call, + _ent[k].axip_add[0] + ':' + str(_ent[k].axip_add[1]), + get_timedelta_str(_ent[k].last_seen, r_just=False) + ) + return out + def cmd_mh(self): parm = 20 if self.parameter: diff --git a/constant.py b/constant.py index 55417eb5..95cfbf95 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.6dev' +VER = '2.98.7dev' LANGUAGE = 0 # QUICK FIX """ 0 = German diff --git a/fnc/str_fnc.py b/fnc/str_fnc.py index a750e09d..b15a31da 100644 --- a/fnc/str_fnc.py +++ b/fnc/str_fnc.py @@ -43,7 +43,7 @@ def get_file_timestamp(): return datetime.now().strftime('%d%m/%y-%H%M') -def get_timedelta_str(dateti: datetime.now()): +def get_timedelta_str(dateti: datetime.now(), r_just=True): _time_delta = datetime.now() - dateti _td_days = _time_delta.days _td_hours = int(_time_delta.seconds / 3600) @@ -52,15 +52,27 @@ def get_timedelta_str(dateti: datetime.now()): if _td_days: # td_hours = td_hours - td_days * 24 - _time_delta_str = f'{str(_td_days).rjust(3, " ")}d,{str(_td_hours).rjust(2, " ")}h' + if r_just: + _time_delta_str = f'{str(_td_days).rjust(3, " ")}d,{str(_td_hours).rjust(2, " ")}h' + else: + _time_delta_str = f'{_td_days}d,{_td_hours}h' elif _td_hours: _td_min = _td_min - _td_hours * 60 - _time_delta_str = f'{str(_td_hours).rjust(3, " ")}h,{str(_td_min).rjust(2, " ")}m' + if r_just: + _time_delta_str = f'{str(_td_hours).rjust(3, " ")}h,{str(_td_min).rjust(2, " ")}m' + else: + _time_delta_str = f'{_td_hours}h,{_td_min}m' elif _td_min: _td_sec = _td_sec - _td_min * 60 - _time_delta_str = f'{str(_td_min).rjust(3, " ")}m,{str(_td_sec).rjust(2, " ")}s' + if r_just: + _time_delta_str = f'{str(_td_min).rjust(3, " ")}m,{str(_td_sec).rjust(2, " ")}s' + else: + _time_delta_str = f'{_td_min}m,{_td_sec}s' else: - _time_delta_str = f'{str(_td_sec).rjust(7, " ")}s' + if r_just: + _time_delta_str = f'{str(_td_sec).rjust(7, " ")}s' + else: + _time_delta_str = f'{_td_sec}s' return _time_delta_str From a65ec361c73d4400395cc3a5eba77ba5c5897dc8 Mon Sep 17 00:00:00 2001 From: masto Date: Thu, 5 Oct 2023 01:34:09 +0200 Subject: [PATCH 09/17] - Detail output of Datapoints for WX Stations with CLI CMD "wx call" --- ax25aprs/aprs_station.py | 1 + cli/cliMain.py | 67 +++++++++++++++++++++++++++++++++------- constant.py | 2 +- fnc/str_fnc.py | 1 - gui/guiMain.py | 39 ++++++++++------------- 5 files changed, 75 insertions(+), 35 deletions(-) diff --git a/ax25aprs/aprs_station.py b/ax25aprs/aprs_station.py index f3596ee2..4aa5d666 100644 --- a/ax25aprs/aprs_station.py +++ b/ax25aprs/aprs_station.py @@ -677,6 +677,7 @@ def _tracer_task(self): if time.time() > self._be_auto_tracer_timer: return if time.time() > self._be_tracer_interval_timer: + print(f"Auto-Tracer timer: {round(self._be_auto_tracer_timer - time.time())}") self.tracer_sendit() return diff --git a/cli/cliMain.py b/cli/cliMain.py index 1e1c4eda..9d3ff842 100644 --- a/cli/cliMain.py +++ b/cli/cliMain.py @@ -481,13 +481,13 @@ def _get_axip_out_cli(max_ent=10): max_c = 0 out = '\r' # out += '\r < AXIP - Clients >\r\r' - out += '-Call-----IP:Port------------------------Last---------------\r' + out += '-Call-----IP:Port---------------------------Last------------\r' for k in _ent.keys(): if _ent[k].axip_add[0]: max_c += 1 if max_c > max_ent: break - out += '{:9} {:30} {:8}\r'.format( + out += '{:9} {:33} {:8}\r'.format( _ent[k].own_call, _ent[k].axip_add[0] + ':' + str(_ent[k].axip_add[1]), get_timedelta_str(_ent[k].last_seen, r_just=False) @@ -609,16 +609,60 @@ def cmd_wx(self): if self.port_handler.aprs_ais is None: return f'\r # {STR_TABLE["cli_no_wx_data"][self.connection.cli_language]}\r\r' parm = 10 + _ret = '' + self.decode_param() if self.parameter: - try: - parm = int(self.parameter[0]) - except ValueError: - pass - ret = self._get_wx_cli_out(max_ent=parm) - - if not ret: + if self.parameter[0].isdigit(): + try: + parm = int(self.parameter[0]) + except ValueError: + pass + _ret = self._get_wx_cli_out(max_ent=parm) + else: + _call = validate_call(self.parameter[0]) + if _call: + _len = parm + if len(self.parameter) == 2: + try: + _len = int(self.parameter[1]) + except ValueError: + pass + _ret = self._get_wx_fm_call_cli_out(call=_call, max_ent=_len) + else: + _ret = self._get_wx_cli_out(max_ent=parm) + if not _ret: return f'\r # {STR_TABLE["cli_no_wx_data"][self.connection.cli_language]}\r\r' - return ret + '\r' + return _ret + '\r' + + def _get_wx_fm_call_cli_out(self, call, max_ent=10): + _data = self.port_handler.aprs_ais.get_wx_data().get(call, '') + if not _data: + return '' + _data.reverse() + max_c = 0 + _loc = f'{_data[0].get("locator", "------")[:6]}({round(_data[0].get("distance", -1))}km)' + out = '\r' + out += f'WX-Station: {call}\r' + out += f'Locator : {_loc}\r' + out += f'Comment : {_data[0].get("comment", "")}\r' + out += f'Datapoints: {len(_data)}\r\r' + out += '-----Last-Port--Temp-Press---Hum-Lum-Rain(24h)-WindGust\r' + for el in _data: + max_c += 1 + if max_c > max_ent: + break + # _ent = self.port_handler.aprs_ais.aprs_wx_msg_pool[k][-1] + _td = get_timedelta_str(el['rx_time']) + _pres = f'{el["weather"].get("pressure", 0):.2f}' + _rain = f'{el["weather"].get("rain_24h", 0):.3f}' + out += f'{_td.rjust(9):10}{el.get("port_id", ""):6}' + out += f'{str(round(el["weather"].get("temperature", 0))):5}' + out += f'{_pres:7} ' + out += f'{el["weather"].get("humidity", 0):3} ' + out += f'{el["weather"].get("luminosity", 0):3} ' + out += f'{_rain:9} ' + out += f'{el["weather"].get("wind_gust", 0):.3f}\r' + return out def _get_wx_cli_out(self, max_ent=10): _data = self.port_handler.aprs_ais.get_wx_entry_sort_distance() @@ -670,7 +714,8 @@ def cmd_aprs_trace(self): out += f'Tracer Call : {self.port_handler.aprs_ais.be_tracer_station}\r' out += f'Tracer WIDE Path: {self.port_handler.aprs_ais.be_tracer_wide}\r' out += f'Tracer intervall: {intervall_str}\r' - out += f'Auto Tracer : {constant.BOOL_ON_OFF.get(self.port_handler.aprs_ais.be_auto_tracer_active, False)}\r' + out += f'Auto Tracer : {constant.BOOL_ON_OFF.get(self.port_handler.aprs_ais.be_auto_tracer_active, False).lower()}\r' + # out += f'APRS-Server : {constant.BOOL_ON_OFF.get(self.port_handler.aprs_ais., False).lower()}\r' out += f'Last Trace send : {_last_send}\r\r' out += '-----Last-Port--Call------LOC-------------Path----------------------------------\r' max_c = 0 diff --git a/constant.py b/constant.py index 95cfbf95..b15d6517 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.7dev' +VER = '2.98.8dev' LANGUAGE = 0 # QUICK FIX """ 0 = German diff --git a/fnc/str_fnc.py b/fnc/str_fnc.py index b15a31da..4132a0dd 100644 --- a/fnc/str_fnc.py +++ b/fnc/str_fnc.py @@ -116,7 +116,6 @@ def convert_str_to_datetime(date_str, date_format='%d/%m/%y %H:%M:%S'): except ValueError: return 0 - def conv_timestamp_delta(delta): if delta: timestamp = str(delta) diff --git a/gui/guiMain.py b/gui/guiMain.py index 0f261d7f..b726b955 100644 --- a/gui/guiMain.py +++ b/gui/guiMain.py @@ -1563,6 +1563,21 @@ def __init__(self): ###################################### # Init Vars self._init_vars() + ############### + self.text_size = 14 + ############################ + # Windows + self.new_conn_win = None + self.settings_win = None + self.mh_window = None + self.wx_window = None + self.port_stat_win = None + self.be_tracer_win = None + self.locator_calc_window = None + self.aprs_mon_win = None + self.aprs_pn_msg_win = None + self.userdb_win = None + self.userDB_tree_win = None ###################################### # .... self.main_win.columnconfigure(0, minsize=500, weight=1) @@ -1667,7 +1682,6 @@ def _init_vars(self): self._root_dir = get_root_dir() self._root_dir = self._root_dir.replace('/', '//') ##################### - ##################### # GUI VARS self.connect_history = {} # GLb Setting Vars @@ -1700,21 +1714,6 @@ def _init_vars(self): self._non_non_prio_task_timer = time.time() self._non_non_non_prio_task_timer = time.time() self._test_task_timer = time.time() - ############### - self.text_size = 14 - ############################ - # Windows - self.new_conn_win = None - self.settings_win = None - self.mh_window = None - self.wx_window = None - self.port_stat_win = None - self.be_tracer_win = None - self.locator_calc_window = None - self.aprs_mon_win = None - self.aprs_pn_msg_win = None - self.userdb_win = None - self.userDB_tree_win = None ############################## # BW-Plot self._bw_plot_x_scale = [] @@ -1739,27 +1738,23 @@ def _init_vars(self): MH_LIST.parm_lastseen_alarm = 1 def _init_bw_plot(self): - # plt.ion() self._bw_fig = Figure(figsize=(8, 5), dpi=80) # plt.style.use('dark_background') self._ax = self._bw_fig.add_subplot(111) self._bw_fig.subplots_adjust(left=0.1, right=0.95, top=0.99, bottom=0.1) - self._ax.axis([0, 10, 0, 100]) + self._ax.axis([0, 10, 0, 100]) # TODO As Option self._bw_fig.set_facecolor('xkcd:light grey') self._ax.set_facecolor('#000000') - # self.bw_fig.xlim(0, 10) # TODO As Option self._ax.xaxis.label.set_color('black') self._ax.yaxis.label.set_color('black') self._ax.tick_params(axis='x', colors='black') self._ax.tick_params(axis='y', colors='black') self._ax.set_xlabel(STR_TABLE['minutes'][self.language]) self._ax.set_ylabel(STR_TABLE['occup'][self.language]) - # plt.xlim(0, 10) # TODO As Option - self._canvas = FigureCanvasTkAgg(self._bw_fig, master=self._side_btn_frame_top) # A tk.DrawingArea. + self._canvas = FigureCanvasTkAgg(self._bw_fig, master=self._side_btn_frame_top) self._canvas.flush_events() self._canvas.draw() self._canvas.get_tk_widget().grid(row=4, column=0, columnspan=7, sticky="nsew") - # self._canvas.get_tk_widget().pack(fill=tk.BOTH) # self._canvas.get_tk_widget().config(cursor="none") self._bw_fig.canvas.flush_events() From 357dec7a20a94e76f92f689c5570b7f2279dcaa3 Mon Sep 17 00:00:00 2001 From: masto Date: Thu, 5 Oct 2023 02:59:27 +0200 Subject: [PATCH 10/17] - Add selectable ports for DX-Alarm --- ax25/ax25Statistics.py | 14 ++++++----- cli/cliMain.py | 4 +-- constant.py | 2 +- gui/guiMH.py | 55 ++++++++++++++++++++++++++++++++++++++---- gui/guiMain.py | 10 ++++++-- 5 files changed, 69 insertions(+), 16 deletions(-) diff --git a/ax25/ax25Statistics.py b/ax25/ax25Statistics.py index 50df6b40..6e9aa837 100644 --- a/ax25/ax25Statistics.py +++ b/ax25/ax25Statistics.py @@ -107,13 +107,15 @@ def __init__(self): self.parm_new_call_alarm = False self.parm_distance_alarm = 50 self.parm_lastseen_alarm = 1 + self.parm_alarm_ports = [] def __del__(self): pass - def _set_dx_alarm(self): - self.dx_alarm_trigger = True - self.last_dx_alarm = time.time() + def _set_dx_alarm(self, port_id: int): + if port_id in self.parm_alarm_ports: + self.dx_alarm_trigger = True + self.last_dx_alarm = time.time() def bw_mon_inp(self, ax25_frame, port_id): if port_id not in self.port_statistik_DB.keys(): @@ -197,13 +199,13 @@ def mh_inp(self, ax25_frame, port_name, port_id): if call_str not in self.calls.keys(): ent = MyHeard() if self.parm_new_call_alarm: - self._set_dx_alarm() + self._set_dx_alarm(port_id) else: ent = self.calls[call_str] _t_delta = datetime.now() - ent.last_seen if self.parm_lastseen_alarm: if _t_delta.days >= self.parm_lastseen_alarm: - self._set_dx_alarm() + self._set_dx_alarm(port_id) ent.last_seen = datetime.now() ent.own_call = call_str ent.pac_n += 1 @@ -242,7 +244,7 @@ def mh_inp(self, ax25_frame, port_name, port_id): ent.distance = float(db_ent.Distance) if self.parm_distance_alarm: if ent.distance >= self.parm_distance_alarm: - self._set_dx_alarm() + self._set_dx_alarm(port_id) self.calls[call_str] = ent diff --git a/cli/cliMain.py b/cli/cliMain.py index 9d3ff842..3e980a1d 100644 --- a/cli/cliMain.py +++ b/cli/cliMain.py @@ -481,13 +481,13 @@ def _get_axip_out_cli(max_ent=10): max_c = 0 out = '\r' # out += '\r < AXIP - Clients >\r\r' - out += '-Call-----IP:Port---------------------------Last------------\r' + out += '-Call------IP:Port---------------------------Last------------\r' for k in _ent.keys(): if _ent[k].axip_add[0]: max_c += 1 if max_c > max_ent: break - out += '{:9} {:33} {:8}\r'.format( + out += ' {:9} {:33} {:8}\r'.format( _ent[k].own_call, _ent[k].axip_add[0] + ':' + str(_ent[k].axip_add[1]), get_timedelta_str(_ent[k].last_seen, r_just=False) diff --git a/constant.py b/constant.py index b15d6517..3d135a3d 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.8dev' +VER = '2.98.9dev' LANGUAGE = 0 # QUICK FIX """ 0 = German diff --git a/gui/guiMH.py b/gui/guiMH.py index ed047d6f..c407ff28 100644 --- a/gui/guiMH.py +++ b/gui/guiMH.py @@ -2,6 +2,8 @@ import tkinter as tk from tkinter import Menu from tkinter import ttk + +from ax25.ax25InitPorts import PORT_HANDLER from ax25.ax25Statistics import MyHeard, MH_LIST from fnc.str_fnc import conv_time_DE_str @@ -26,10 +28,12 @@ def __init__(self, root_win): self.iconbitmap("favicon.ico") except tk.TclError: pass + """ self._menubar = Menu(self) self.config(menu=self._menubar) self._menubar.add_command(label="Quit", command=self.close) self._menubar.add_command(label="Port-Statistik", command=lambda: self._root_win.open_port_stat_win()) + """ self.lift() ################################### # Vars @@ -40,12 +44,17 @@ def __init__(self, root_win): self._alarm_distance_var = tk.StringVar(self) # self._tracer_active_var = tk.BooleanVar(self) self._tracer_duration_var = tk.StringVar(self) + self._alarm_ports = [] + _ports = list(PORT_HANDLER.get_all_ports().keys()) + for _por_id in _ports: + self._alarm_ports.append(tk.BooleanVar(self)) self._get_vars() # ############################### Columns ############################ self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=0, minsize=50) - self.grid_rowconfigure(1, weight=0, minsize=30) - self.grid_rowconfigure(2, weight=1) + self.grid_rowconfigure(1, weight=0, minsize=25) + self.grid_rowconfigure(2, weight=0, minsize=25) + self.grid_rowconfigure(3, weight=1) # ###################### DX Alarm Settings ###################### # ALARM lower_frame = tk.Frame(self) @@ -102,6 +111,23 @@ def __init__(self, root_win): command=self._set_alarm_distance ).pack(side=tk.LEFT, ) + # ###################### Ports ############################ + lower_frame_ports = tk.Frame(self) + lower_frame_ports.grid(row=1, column=0, columnspan=2, sticky='nsew') + frame_13_label = tk.Frame(lower_frame_ports) + frame_13_label.pack(side=tk.LEFT, fill=tk.BOTH, padx=30) + tk.Label(frame_13_label, text='Ports: ').pack(side=tk.LEFT, ) + _i = 0 + for _port_id in _ports: + _frame = tk.Frame(lower_frame_ports) + _frame.pack(side=tk.LEFT, fill=tk.BOTH, padx=7) + _text = f'{_port_id}' + tk.Label(_frame, text=_text, width=3).pack(side=tk.LEFT, padx=1) + tk.Checkbutton(_frame, + variable=self._alarm_ports[_i], + command=self._set_alarm_ports, + ).pack(side=tk.LEFT, padx=1) + _i += 1 # ###################### Auto Tracer ###################### # Tracer _auto_tracer_state = { @@ -109,7 +135,7 @@ def __init__(self, root_win): False: 'normal' }.get(self._root_win.get_tracer(), 'disabled') lower_frame_tracer = tk.Frame(self) - lower_frame_tracer.grid(row=1, column=0, columnspan=2, sticky='nsew') + lower_frame_tracer.grid(row=2, column=0, columnspan=2, sticky='nsew') frame_12_label = tk.Frame(lower_frame_tracer) frame_12_label.pack(side=tk.LEFT, fill=tk.BOTH, padx=30) tk.Label(frame_12_label, text='Auto APRS-Tracer: ').pack(side=tk.LEFT, ) @@ -155,11 +181,11 @@ def __init__(self, root_win): 'mh_ip_fail' ) self._tree = ttk.Treeview(self, columns=columns, show='headings') - self._tree.grid(row=2, column=0, sticky='nsew') + self._tree.grid(row=3, column=0, sticky='nsew') # add a scrollbar scrollbar = ttk.Scrollbar(self, orient=tk.VERTICAL, command=self._tree.yview) self._tree.configure(yscrollcommand=scrollbar.set) - scrollbar.grid(row=2, column=1, sticky='ns') + scrollbar.grid(row=3, column=1, sticky='ns') self._tree.heading('mh_last_seen', text='Letzte Paket', command=lambda: self._sort_entry('last')) self._tree.heading('mh_first_seen', text='Erste Paket', command=lambda: self._sort_entry('first')) @@ -196,6 +222,25 @@ def _get_vars(self): self._alarm_distance_var.set(str(MH_LIST.parm_distance_alarm)) # self._tracer_active_var.set(bool(self._root_win.setting_auto_tracer.get())) self._tracer_duration_var.set(str(self._root_win.get_auto_tracer_duration())) + _i = 0 + for _var in self._alarm_ports: + if _i in MH_LIST.parm_alarm_ports: + _var.set(True) + else: + _var.set(False) + _i += 1 + + def _set_alarm_ports(self, event=None): + _i = 0 + for _var in self._alarm_ports: + if _var.get(): + if _i not in MH_LIST.parm_alarm_ports: + MH_LIST.parm_alarm_ports.append(int(_i)) + else: + if _i in MH_LIST.parm_alarm_ports: + MH_LIST.parm_alarm_ports.remove(int(_i)) + _i += 1 + print(MH_LIST.parm_alarm_ports) def _set_alarm_distance(self, event=None): _var = self._alarm_distance_var.get() diff --git a/gui/guiMain.py b/gui/guiMain.py index b726b955..3e95e0e7 100644 --- a/gui/guiMain.py +++ b/gui/guiMain.py @@ -1733,13 +1733,19 @@ def _init_vars(self): else: self.setting_sprech.set(False) # MH - MH_LIST.parm_new_call_alarm = True + """ MH_LIST.parm_distance_alarm = 50 MH_LIST.parm_lastseen_alarm = 1 + """ + MH_LIST.parm_new_call_alarm = True + # Set Port 0 for DX Alarm as default # TODO remove + if PORT_HANDLER.get_port_by_index(0): + MH_LIST.parm_alarm_ports = [0] + else: + MH_LIST.parm_alarm_ports = [] def _init_bw_plot(self): self._bw_fig = Figure(figsize=(8, 5), dpi=80) - # plt.style.use('dark_background') self._ax = self._bw_fig.add_subplot(111) self._bw_fig.subplots_adjust(left=0.1, right=0.95, top=0.99, bottom=0.1) self._ax.axis([0, 10, 0, 100]) # TODO As Option From d41e5f127d3194e074ea185dbc6ecd303a836954 Mon Sep 17 00:00:00 2001 From: masto Date: Thu, 5 Oct 2023 03:32:37 +0200 Subject: [PATCH 11/17] - received digis on a route will be added to MH-List now --- ax25/ax25Statistics.py | 32 +++++++++++++++++++++++--------- constant.py | 2 +- idea.txt | 1 + 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/ax25/ax25Statistics.py b/ax25/ax25Statistics.py index 6e9aa837..d4c2bd34 100644 --- a/ax25/ax25Statistics.py +++ b/ax25/ax25Statistics.py @@ -186,16 +186,20 @@ def mh_inp_axip_add(self, ent: '', axip_add: tuple): if ent in self.calls.keys(): self.calls[ent].axip_add = axip_add - def mh_inp(self, ax25_frame, port_name, port_id): - ######################## - # Port Stat - if port_id not in self.port_statistik_DB.keys(): - self.port_statistik_DB[port_id] = init_day_dic() - # self.port_statistik_DB[port_id].input_stat_db(ax_frame=ax25_frame) - self._input_stat_db(ax25_frame, port_id) + def mh_inp(self, ax25_frame, port_name, port_id, digi=''): + if not digi: + ######################## + # Port Stat + if port_id not in self.port_statistik_DB.keys(): + self.port_statistik_DB[port_id] = init_day_dic() + # self.port_statistik_DB[port_id].input_stat_db(ax_frame=ax25_frame) + self._input_stat_db(ax25_frame, port_id) ######################## # MH Entry - call_str = str(ax25_frame.from_call.call_str) + if digi: + call_str = digi + else: + call_str = str(ax25_frame.from_call.call_str) if call_str not in self.calls.keys(): ent = MyHeard() if self.parm_new_call_alarm: @@ -221,10 +225,14 @@ def mh_inp(self, ax25_frame, port_name, port_id): ent.to_calls.append(to_c_str) # Routes ent.route = [] # Last Route + _last_digi = '' if ax25_frame.via_calls: for call in ax25_frame.via_calls: if call.c_bit: ent.route.append(str(call.call_str)) + _last_digi = str(call.call_str) + if digi and ent.route: + ent.route = ent.route[:-1] if ent.route not in ent.all_routes: ent.all_routes.append(list(ent.route)) @@ -238,7 +246,7 @@ def mh_inp(self, ax25_frame, port_name, port_id): ent.axip_add = tuple(ax25_frame.axip_add) # Get Locator and Distance from User-DB - db_ent = USER_DB.get_entry(call_str, add_new=False) + db_ent = USER_DB.get_entry(call_str, add_new=True) if db_ent: ent.locator = str(db_ent.LOC) ent.distance = float(db_ent.Distance) @@ -248,6 +256,12 @@ def mh_inp(self, ax25_frame, port_name, port_id): self.calls[call_str] = ent + if digi: + USER_DB.set_typ(call_str=digi, add_new=False, typ='DIGI') + return + if _last_digi: + self.mh_inp(ax25_frame, port_name, port_id, _last_digi) + def mh_get_data_fm_call(self, call_str): if call_str in self.calls.keys(): return self.calls[call_str] diff --git a/constant.py b/constant.py index 3d135a3d..aa563be0 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.9dev' +VER = '2.98.10dev' LANGUAGE = 0 # QUICK FIX """ 0 = German diff --git a/idea.txt b/idea.txt index 422642bd..6be5eb7b 100644 --- a/idea.txt +++ b/idea.txt @@ -2,6 +2,7 @@ Ideas/TODO's : - ESC Befehle - Individuelle Farben (Vorschreib Fenster) +- Beacon System überarbeiten ✓ UserDB - Infos / Ctext usw. in User-DB speichern - User-DB Sync System (Manuell zu triggern bei connect zu anderer PoPT Station) From ac93f88cc7bdc43bce6de69c4dc8ff2f10fbc837 Mon Sep 17 00:00:00 2001 From: masto Date: Thu, 5 Oct 2023 04:35:12 +0200 Subject: [PATCH 12/17] - Fixed: Routes are not shown in GUI MH-List --- ax25/ax25Statistics.py | 10 ++++++---- cli/cliMain.py | 6 ++++-- gui/guiMH.py | 7 +------ 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/ax25/ax25Statistics.py b/ax25/ax25Statistics.py index d4c2bd34..be717598 100644 --- a/ax25/ax25Statistics.py +++ b/ax25/ax25Statistics.py @@ -87,7 +87,8 @@ def __init__(self): self.calls: {str: MyHeard} = {} for call in mh_load: self.calls[call] = set_obj_att(new_obj=MyHeard(), input_obj=mh_load[call]) - + # Fix: Delete empty Routes in routes entry + # self.calls[call].all_routes = list(filter(lambda a: a != [], self.calls[call].all_routes)) try: with open(CFG_port_stat_data_file, 'rb') as inp: self.port_statistik_DB = pickle.load(inp) @@ -231,11 +232,11 @@ def mh_inp(self, ax25_frame, port_name, port_id, digi=''): if call.c_bit: ent.route.append(str(call.call_str)) _last_digi = str(call.call_str) - if digi and ent.route: + if ent.route and digi: ent.route = ent.route[:-1] - if ent.route not in ent.all_routes: ent.all_routes.append(list(ent.route)) + # Update AXIP Address if ax25_frame.axip_add[0]: if ent.axip_add[0]: @@ -292,6 +293,7 @@ def get_sort_mh_entry(self, flag_str: str, reverse: bool): self.calls: {str: MyHeard} for k in self.calls.keys(): flag: MyHeard = self.calls[k] + key: str = { 'last': conv_time_for_sorting(flag.last_seen), 'first': conv_time_for_sorting(flag.first_seen), @@ -301,7 +303,7 @@ def get_sort_mh_entry(self, flag_str: str, reverse: bool): 'dist': str(flag.distance), 'pack': str(flag.pac_n), 'rej': str(flag.rej_n), - 'route': str(max(flag.all_routes)), + 'route': str(flag.route), 'axip': str(flag.axip_add), 'axipfail': str(flag.axip_fail), }[flag_str] diff --git a/cli/cliMain.py b/cli/cliMain.py index 3e980a1d..750e9ffe 100644 --- a/cli/cliMain.py +++ b/cli/cliMain.py @@ -523,8 +523,10 @@ def _get_mh_out_cli(max_ent=20): if max_c > max_ent: break time_delta_str = get_timedelta_str(sort_list[call].last_seen) - - out += f'{time_delta_str} P:{sort_list[call].port:4} {sort_list[call].own_call:9}'.ljust(27, " ") + _call_str = sort_list[call].own_call + if sort_list[call].route: + _call_str += '*' + out += f'{time_delta_str} P:{sort_list[call].port:4} {_call_str:10}'.ljust(27, " ") """ tp += sort_list[call].pac_n tb += sort_list[call].byte_n diff --git a/gui/guiMH.py b/gui/guiMH.py index c407ff28..b9edd420 100644 --- a/gui/guiMH.py +++ b/gui/guiMH.py @@ -1,6 +1,5 @@ import logging import tkinter as tk -from tkinter import Menu from tkinter import ttk from ax25.ax25InitPorts import PORT_HANDLER @@ -240,7 +239,6 @@ def _set_alarm_ports(self, event=None): if _i in MH_LIST.parm_alarm_ports: MH_LIST.parm_alarm_ports.remove(int(_i)) _i += 1 - print(MH_LIST.parm_alarm_ports) def _set_alarm_distance(self, event=None): _var = self._alarm_distance_var.get() @@ -315,9 +313,6 @@ def _format_tree_ent(self, mh_list): axip_str = '{} - {}'.format(ent.axip_add[0], ent.axip_add[1]) else: axip_str = '' - route = '' - if ent.all_routes: - route = min(ent.all_routes) self._tree_data.append(( f'{conv_time_DE_str(ent.last_seen)}', @@ -328,7 +323,7 @@ def _format_tree_ent(self, mh_list): f'{ent.distance}', f'{ent.pac_n}', f'{ent.rej_n}', - ' '.join(route), + ' '.join(ent.route), f'{axip_str}', f'{ent.axip_fail}', )) From ba283d6bfbbfeca43674118d96272ce12bfff602 Mon Sep 17 00:00:00 2001 From: masto Date: Thu, 5 Oct 2023 05:21:50 +0200 Subject: [PATCH 13/17] - cleaned up guiMain.py Vars --- constant.py | 2 +- gui/guiMain.py | 449 ++++++++++++++++++++++++------------------------- 2 files changed, 224 insertions(+), 227 deletions(-) diff --git a/constant.py b/constant.py index aa563be0..7b0c61ef 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.10dev' +VER = '2.98.11dev' LANGUAGE = 0 # QUICK FIX """ 0 = German diff --git a/gui/guiMain.py b/gui/guiMain.py index 3e95e0e7..57e3300d 100644 --- a/gui/guiMain.py +++ b/gui/guiMain.py @@ -89,39 +89,39 @@ def __init__(self, main_cl): self.style = main_cl.style self.ch_index = main_cl.channel_index - self._tab_side_frame = tk.Frame( + _tab_side_frame = tk.Frame( main_cl.get_side_frame(), # width=300, height=400 ) - self._tab_side_frame.grid(row=3, column=0, columnspan=6, pady=10, sticky="nsew") + _tab_side_frame.grid(row=3, column=0, columnspan=6, pady=10, sticky="nsew") self._tabControl = ttk.Notebook( - self._tab_side_frame, + _tab_side_frame, height=300, # width=500 ) tab1_kanal = ttk.Frame(self._tabControl) # self.tab1_1_RTT = ttk.Frame(self._tabControl) - self.tab2_mh = tk.Frame(self._tabControl) - # self.tab2_mh.bind("", self.reset_dx_alarm) - self.tab2_mh_def_bg_clr = self.tab2_mh.cget('bg') - self.tab4_settings = ttk.Frame(self._tabControl) - self.tab5_ch_links = ttk.Frame(self._tabControl) # TODO - self.tab6_monitor = ttk.Frame(self._tabControl) - self.tab7_tracer = ttk.Frame(self._tabControl) + tab2_mh = tk.Frame(self._tabControl) + # tab2_mh.bind("", self.reset_dx_alarm) + # self.tab2_mh_def_bg_clr = tab2_mh.cget('bg') + tab4_settings = ttk.Frame(self._tabControl) + # self.tab5_ch_links = ttk.Frame(self._tabControl) # TODO + tab6_monitor = ttk.Frame(self._tabControl) + tab7_tracer = ttk.Frame(self._tabControl) self._tabControl.add(tab1_kanal, text='Kanal') # tab3 = ttk.Frame(self._tabControl) # TODO # self._tabControl.add(tab3, text='Ports') # TODO - self._tabControl.add(self.tab4_settings, text='Global') - self._tabControl.add(self.tab6_monitor, text='Monitor') - self._tabControl.add(self.tab2_mh, text='MH') - self._tabControl.add(self.tab7_tracer, text='Tracer') + self._tabControl.add(tab4_settings, text='Global') + self._tabControl.add(tab6_monitor, text='Monitor') + self._tabControl.add(tab2_mh, text='MH') + self._tabControl.add(tab7_tracer, text='Tracer') # self._tabControl.add(self.tab5_ch_links, text='CH-Echo') # TODO self._tabControl.pack(expand=0, fill="both") - self._tabControl.select(self.tab2_mh) + self._tabControl.select(tab2_mh) ################################################ # Kanal parm_y = 20 @@ -317,7 +317,7 @@ def __init__(self, main_cl): ################################ # MH ########################## # TREE - self.tab2_mh.columnconfigure(0, minsize=300, weight=1) + tab2_mh.columnconfigure(0, minsize=300, weight=1) columns = ( 'mh_last_seen', @@ -328,7 +328,7 @@ def __init__(self, main_cl): 'mh_route', ) - self._tree = ttk.Treeview(self.tab2_mh, columns=columns, show='headings') + self._tree = ttk.Treeview(tab2_mh, columns=columns, show='headings') self._tree.grid(row=0, column=0, sticky='nsew') self._tree.heading('mh_last_seen', text='Zeit') @@ -351,12 +351,12 @@ def __init__(self, main_cl): # Global Settings ########################## # Global Sound - Checkbutton(self.tab4_settings, + Checkbutton(tab4_settings, text="Sound", variable=self._main_win.setting_sound, ).place(x=10, y=10) # Global Sprech - sprech_btn = Checkbutton(self.tab4_settings, + sprech_btn = Checkbutton(tab4_settings, text="Sprachausgabe", variable=self._main_win.setting_sprech, command=self._chk_sprech_on @@ -365,12 +365,12 @@ def __init__(self, main_cl): if not is_linux(): sprech_btn.configure(state='disabled') # Global Bake - Checkbutton(self.tab4_settings, + Checkbutton(tab4_settings, text="Baken", variable=self._main_win.setting_bake, ).place(x=10, y=60) # DX Alarm > dx_alarm_on - Checkbutton(self.tab4_settings, + Checkbutton(tab4_settings, text="Tracer", variable=self._main_win.setting_tracer, command=self._chk_tracer, @@ -380,21 +380,21 @@ def __init__(self, main_cl): True: 'disabled', False: 'normal' }.get(self._main_win.get_tracer(), 'disabled') - self._autotracer_chk_btn = Checkbutton(self.tab4_settings, + self._autotracer_chk_btn = Checkbutton(tab4_settings, text="Auto-Tracer", variable=self._main_win.setting_auto_tracer, command=self._chk_auto_tracer, state=_auto_tracer_state ) self._autotracer_chk_btn.place(x=10, y=110) - Checkbutton(self.tab4_settings, + Checkbutton(tab4_settings, text="DX-Alarm", variable=self._main_win.setting_dx_alarm, command=self._main_win.set_dx_alarm, # state='disabled' ).place(x=10, y=135) # RX ECHO - Checkbutton(self.tab4_settings, + Checkbutton(tab4_settings, text="RX-Echo", variable=self._main_win.setting_rx_echo, ).place(x=10, y=160) @@ -408,16 +408,16 @@ def __init__(self, main_cl): # Address _x = 10 _y = 10 - self.to_add_var = tk.StringVar(self.tab6_monitor) - tk.Label(self.tab6_monitor, text=f"{STR_TABLE['to'][self._lang]}:").place(x=_x, y=_y) - self.to_add_ent = tk.Entry(self.tab6_monitor, textvariable=self.to_add_var) + self.to_add_var = tk.StringVar(tab6_monitor) + tk.Label(tab6_monitor, text=f"{STR_TABLE['to'][self._lang]}:").place(x=_x, y=_y) + self.to_add_ent = tk.Entry(tab6_monitor, textvariable=self.to_add_var) self.to_add_ent.place(x=_x + 40, y=_y) # CMD/RPT _x = 10 _y = 80 - self.cmd_var = tk.BooleanVar(self.tab6_monitor) - self.cmd_ent = tk.Checkbutton(self.tab6_monitor, + self.cmd_var = tk.BooleanVar(tab6_monitor) + self.cmd_ent = tk.Checkbutton(tab6_monitor, variable=self.cmd_var, text='CMD/RPT') self.cmd_ent.place(x=_x, y=_y) @@ -425,8 +425,8 @@ def __init__(self, main_cl): # Poll _x = 10 _y = 105 - self.poll_var = tk.BooleanVar(self.tab6_monitor) - self.poll_ent = tk.Checkbutton(self.tab6_monitor, + self.poll_var = tk.BooleanVar(tab6_monitor) + self.poll_ent = tk.Checkbutton(tab6_monitor, variable=self.poll_var, text='Poll') self.poll_ent.place(x=_x, y=_y) @@ -434,13 +434,13 @@ def __init__(self, main_cl): # Port _x = 40 _y = 140 - tk.Label(self.tab6_monitor, text=f"{STR_TABLE['port'][self._lang]}:").place(x=_x, y=_y) - self.mon_port_var = tk.StringVar(self.tab6_monitor) + tk.Label(tab6_monitor, text=f"{STR_TABLE['port'][self._lang]}:").place(x=_x, y=_y) + self.mon_port_var = tk.StringVar(tab6_monitor) self.mon_port_var.set('0') _vals = ['0'] if PORT_HANDLER.get_all_ports().keys(): _vals = [str(x) for x in list(PORT_HANDLER.get_all_ports().keys())] - self.mon_port_ent = tk.ttk.Combobox(self.tab6_monitor, + self.mon_port_ent = tk.ttk.Combobox(tab6_monitor, width=4, textvariable=self.mon_port_var, values=_vals, @@ -450,11 +450,11 @@ def __init__(self, main_cl): # Calls _x = 40 _y = 175 - self.mon_call_var = tk.StringVar(self.tab6_monitor) + self.mon_call_var = tk.StringVar(tab6_monitor) _vals = [] # if self.main_win.ax25_port_handler.ax25_ports.keys(): # _vals = [str(x) for x in list(self.main_win.ax25_port_handler.ax25_ports.keys())] - self.mon_call_ent = tk.ttk.Combobox(self.tab6_monitor, + self.mon_call_ent = tk.ttk.Combobox(tab6_monitor, width=9, textvariable=self.mon_call_var, values=_vals, @@ -464,8 +464,8 @@ def __init__(self, main_cl): # Auto Scrolling _x = 10 _y = 210 - self.mon_scroll_var = tk.BooleanVar(self.tab6_monitor) - self.mon_scroll_ent = tk.Checkbutton(self.tab6_monitor, + self.mon_scroll_var = tk.BooleanVar(tab6_monitor) + self.mon_scroll_ent = tk.Checkbutton(tab6_monitor, variable=self.mon_scroll_var, text=STR_TABLE['scrolling'][self._lang]) self.mon_scroll_ent.place(x=_x, y=_y) @@ -473,9 +473,9 @@ def __init__(self, main_cl): # Monitor APRS Decoding Output _x = 10 _y = 235 - self.mon_aprs_var = tk.BooleanVar(self.tab6_monitor) + self.mon_aprs_var = tk.BooleanVar(tab6_monitor) self.mon_aprs_var.set(True) - self.mon_aprs_ent = tk.Checkbutton(self.tab6_monitor, + self.mon_aprs_ent = tk.Checkbutton(tab6_monitor, variable=self.mon_aprs_var, text='APRS-Decoding') self.mon_aprs_ent.place(x=_x, y=_y) @@ -483,15 +483,15 @@ def __init__(self, main_cl): # PID _x = 10 _y = 45 - self.mon_pid_var = tk.StringVar(self.tab6_monitor) - tk.Label(self.tab6_monitor, text='PID:').place(x=_x, y=_y) + self.mon_pid_var = tk.StringVar(tab6_monitor) + tk.Label(tab6_monitor, text='PID:').place(x=_x, y=_y) pid = PIDByte() pac_types = dict(pid.pac_types) _vals = [] for x in list(pac_types.keys()): pid.pac_types[int(x)]() _vals.append(f"{str(hex(int(x))).upper()}>{pid.flag}") - self.mon_pid_ent = tk.ttk.Combobox(self.tab6_monitor, + self.mon_pid_ent = tk.ttk.Combobox(tab6_monitor, width=20, values=_vals, textvariable=self.mon_pid_var) @@ -502,10 +502,10 @@ def __init__(self, main_cl): self.mon_port_on_vars = {} all_ports = PORT_HANDLER.get_all_ports() for port_id in all_ports: - self.mon_port_on_vars[port_id] = tk.BooleanVar(self.tab6_monitor) + self.mon_port_on_vars[port_id] = tk.BooleanVar(tab6_monitor) _x = 170 _y = 80 + (25 * port_id) - tk.Checkbutton(self.tab6_monitor, + tk.Checkbutton(tab6_monitor, text=f"Port {port_id}", variable=self.mon_port_on_vars[port_id], command=self._chk_mon_port_filter @@ -514,10 +514,10 @@ def __init__(self, main_cl): ################################ # TRACER # TREE - self.tab7_tracer.columnconfigure(0, minsize=150, weight=1) - self.tab7_tracer.columnconfigure(1, minsize=150, weight=1) - self.tab7_tracer.rowconfigure(0, minsize=100, weight=1) - self.tab7_tracer.rowconfigure(1, minsize=50, weight=1) + tab7_tracer.columnconfigure(0, minsize=150, weight=1) + tab7_tracer.columnconfigure(1, minsize=150, weight=1) + tab7_tracer.rowconfigure(0, minsize=100, weight=1) + tab7_tracer.rowconfigure(1, minsize=50, weight=1) tracer_columns = ( 'rx_time', @@ -527,7 +527,7 @@ def __init__(self, main_cl): 'path', ) - self._trace_tree = ttk.Treeview(self.tab7_tracer, columns=tracer_columns, show='headings') + self._trace_tree = ttk.Treeview(tab7_tracer, columns=tracer_columns, show='headings') self._trace_tree.grid(row=0, column=0, columnspan=2, sticky='nsew') self._trace_tree.heading('rx_time', text='Zeit') @@ -545,11 +545,11 @@ def __init__(self, main_cl): self._trace_tree_data_old = {} self._update_side_trace() - tk.Button(self.tab7_tracer, + tk.Button(tab7_tracer, text="SEND", command=self._tracer_send ).grid(row=1, column=0, padx=10) - # tk.Button(self.tab7_tracer, text="SEND").grid(row=1, column=1, padx=10) + # tk.Button(tab7_tracer, text="SEND").grid(row=1, column=1, padx=10) self._trace_tree.bind('<>', self._trace_entry_selected) ################## @@ -568,7 +568,7 @@ def __init__(self, main_cl): """ def reset_dx_alarm(self, event=None): self._main_win.reset_dx_alarm() - # self.tab2_mh.configure(bg=self.tab2_mh_def_bg_clr) + # tab2_mh.configure(bg=self.tab2_mh_def_bg_clr) """ def set_auto_tracer_state(self): @@ -946,32 +946,32 @@ def chk_autoscroll(self): class TxTframe: def __init__(self, main_win): - self.pw = ttk.PanedWindow(orient=tk.VERTICAL) + self._pw = ttk.PanedWindow(orient=tk.VERTICAL) self._main_class = main_win - self.text_size = main_win.text_size + self._text_size = main_win.text_size ################### # Input Win - self.status_frame = tk.Frame(self.pw, width=500, height=320, bd=0, borderwidth=0, bg=STAT_BAR_CLR) - self.status_frame.pack(side=tk.BOTTOM, expand=0) - - self.status_frame.columnconfigure(1, minsize=60, weight=2) # Name - self.status_frame.columnconfigure(2, minsize=40, weight=3) # Status - self.status_frame.columnconfigure(3, minsize=40, weight=4) # unACK - self.status_frame.columnconfigure(4, minsize=40, weight=4) # VS VR - self.status_frame.columnconfigure(5, minsize=20, weight=5) # N2 - self.status_frame.columnconfigure(6, minsize=20, weight=5) # T1 - self.status_frame.columnconfigure(7, minsize=20, weight=5) # T1 - self.status_frame.columnconfigure(8, minsize=20, weight=5) # T2 - self.status_frame.columnconfigure(9, minsize=20, weight=5) # T3 - self.status_frame.columnconfigure(10, minsize=50, weight=1) # RX Beep - self.status_frame.columnconfigure(11, minsize=20, weight=1) # TimeStamp - self.status_frame.rowconfigure(0, weight=1) # Stat - self.status_frame.rowconfigure(1, minsize=20, weight=0) # Out - - self.in_txt_win = scrolledtext.ScrolledText(self.status_frame, + self._status_frame = tk.Frame(self._pw, width=500, height=320, bd=0, borderwidth=0, bg=STAT_BAR_CLR) + self._status_frame.pack(side=tk.BOTTOM, expand=0) + + self._status_frame.columnconfigure(1, minsize=60, weight=2) # Name + self._status_frame.columnconfigure(2, minsize=40, weight=3) # Status + self._status_frame.columnconfigure(3, minsize=40, weight=4) # unACK + self._status_frame.columnconfigure(4, minsize=40, weight=4) # VS VR + self._status_frame.columnconfigure(5, minsize=20, weight=5) # N2 + self._status_frame.columnconfigure(6, minsize=20, weight=5) # T1 + self._status_frame.columnconfigure(7, minsize=20, weight=5) # T1 + self._status_frame.columnconfigure(8, minsize=20, weight=5) # T2 + self._status_frame.columnconfigure(9, minsize=20, weight=5) # T3 + self._status_frame.columnconfigure(10, minsize=50, weight=1) # RX Beep + self._status_frame.columnconfigure(11, minsize=20, weight=1) # TimeStamp + self._status_frame.rowconfigure(0, weight=1) # Stat + self._status_frame.rowconfigure(1, minsize=20, weight=0) # Out + + self.in_txt_win = scrolledtext.ScrolledText(self._status_frame, background=TXT_BACKGROUND_CLR, foreground=TXT_INP_CLR, - font=(FONT, self.text_size), + font=(FONT, self._text_size), insertbackground=TXT_INP_CURSOR_CLR, height=100, width=82, @@ -983,61 +983,61 @@ def __init__(self, main_win): self.in_txt_win.grid(row=0, column=0, columnspan=12, sticky="nsew") ############## # Status Frame - self.status_name = Label(self.status_frame, text="", font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), + self.status_name = Label(self._status_frame, text="", font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), foreground=STAT_BAR_TXT_CLR, bg=STAT_BAR_CLR) self.status_name.grid(row=1, column=1, sticky="nsew") - self.status_status = Label(self.status_frame, text="", + self.status_status = Label(self._status_frame, text="", font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), bg=STAT_BAR_CLR, foreground=STAT_BAR_TXT_CLR) self.status_status.grid(row=1, column=2, sticky="nsew") - self.status_unack = Label(self.status_frame, text="", + self.status_unack = Label(self._status_frame, text="", foreground=STAT_BAR_TXT_CLR, font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), bg=STAT_BAR_CLR) self.status_unack.grid(row=1, column=3, sticky="nsew") - self.status_vs = Label(self.status_frame, text="", + self.status_vs = Label(self._status_frame, text="", font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), bg=STAT_BAR_CLR, foreground=STAT_BAR_TXT_CLR) self.status_vs.grid(row=1, column=4, sticky="nsew") - self.status_n2 = Label(self.status_frame, text="", + self.status_n2 = Label(self._status_frame, text="", font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), bg=STAT_BAR_CLR, foreground=STAT_BAR_TXT_CLR) self.status_n2.grid(row=1, column=7, sticky="nsew") - self.status_t1 = Label(self.status_frame, text="", + self.status_t1 = Label(self._status_frame, text="", font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), bg=STAT_BAR_CLR, foreground=STAT_BAR_TXT_CLR) self.status_t1.grid(row=1, column=8, sticky="nsew") # PARM T2 - self.status_t2 = Label(self.status_frame, text="", + self.status_t2 = Label(self._status_frame, text="", font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), bg=STAT_BAR_CLR, foreground=STAT_BAR_TXT_CLR) self.status_t2.grid(row=1, column=5, sticky="nsew") # RTT - self.status_rtt = Label(self.status_frame, text="", + self.status_rtt = Label(self._status_frame, text="", font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), bg=STAT_BAR_CLR, foreground=STAT_BAR_TXT_CLR) self.status_rtt.grid(row=1, column=6, sticky="nsew") - self.status_t3 = Label(self.status_frame, text="", + self.status_t3 = Label(self._status_frame, text="", font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), bg=STAT_BAR_CLR, foreground=STAT_BAR_TXT_CLR) self.status_t3.grid(row=1, column=9, sticky="nsew") # Checkbox RX-BEEP self.rx_beep_var = tk.IntVar() - self.rx_beep_box = Checkbutton(self.status_frame, + self.rx_beep_box = Checkbutton(self._status_frame, text="RX-BEEP", bg=STAT_BAR_CLR, font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), @@ -1051,7 +1051,7 @@ def __init__(self, main_win): self.rx_beep_box.grid(row=1, column=10, sticky="nsew") # TODO Checkbox Time Stamp self.ts_box_var = tk.IntVar() - self.ts_box_box = Checkbutton(self.status_frame, + self.ts_box_box = Checkbutton(self._status_frame, text="T-S", font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), bg=STAT_BAR_CLR, @@ -1064,28 +1064,28 @@ def __init__(self, main_win): state='disabled' ) self.ts_box_box.grid(row=1, column=11, sticky="nsew") - self.status_frame.pack(side=tk.BOTTOM) + self._status_frame.pack(side=tk.BOTTOM) #################### # Output - self.out_frame = tk.Frame(self.pw, width=500, height=320, bd=0, borderwidth=0, ) - self.out_frame.pack(side=tk.BOTTOM, expand=0) - self.out_frame.rowconfigure(1, minsize=22, weight=1) - self.out_frame.rowconfigure(0, weight=1) - self.out_frame.columnconfigure(0, minsize=3, weight=0) # Spacer - self.out_frame.columnconfigure(1, minsize=80, weight=2) # Name - self.out_frame.columnconfigure(2, minsize=60, weight=3) # QTH - self.out_frame.columnconfigure(3, minsize=20, weight=4) # LOC - self.out_frame.columnconfigure(4, minsize=20, weight=5) # Typ - self.out_frame.columnconfigure(5, minsize=80, weight=4) # Software - self.out_frame.columnconfigure(6, minsize=28, weight=4) # Status (PIPE/FT) - self.out_frame.columnconfigure(7, minsize=30, weight=4) # Conn Timer - self.out_frame.columnconfigure(8, minsize=30, weight=4) # Text Encoding - self.out_frame.columnconfigure(9, minsize=3, weight=0) # Spacer - self.out_txt_win = scrolledtext.ScrolledText(self.out_frame, + self._out_frame = tk.Frame(self._pw, width=500, height=320, bd=0, borderwidth=0, ) + self._out_frame.pack(side=tk.BOTTOM, expand=0) + self._out_frame.rowconfigure(1, minsize=22, weight=1) + self._out_frame.rowconfigure(0, weight=1) + self._out_frame.columnconfigure(0, minsize=3, weight=0) # Spacer + self._out_frame.columnconfigure(1, minsize=80, weight=2) # Name + self._out_frame.columnconfigure(2, minsize=60, weight=3) # QTH + self._out_frame.columnconfigure(3, minsize=20, weight=4) # LOC + self._out_frame.columnconfigure(4, minsize=20, weight=5) # Typ + self._out_frame.columnconfigure(5, minsize=80, weight=4) # Software + self._out_frame.columnconfigure(6, minsize=28, weight=4) # Status (PIPE/FT) + self._out_frame.columnconfigure(7, minsize=30, weight=4) # Conn Timer + self._out_frame.columnconfigure(8, minsize=30, weight=4) # Text Encoding + self._out_frame.columnconfigure(9, minsize=3, weight=0) # Spacer + self.out_txt_win = scrolledtext.ScrolledText(self._out_frame, background=TXT_BACKGROUND_CLR, foreground=TXT_OUT_CLR, - font=(FONT, self.text_size), + font=(FONT, self._text_size), height=100, width=82, bd=0, @@ -1095,16 +1095,16 @@ def __init__(self, main_win): self.out_txt_win.tag_config("input", foreground="yellow") self.out_txt_win.grid(row=0, column=0, columnspan=10, sticky="nsew") # Stat INFO (Name,QTH usw) - self.stat_info_name_var = tk.StringVar(self.out_frame) - self.stat_info_qth_var = tk.StringVar(self.out_frame) - self.stat_info_loc_var = tk.StringVar(self.out_frame) - self.stat_info_typ_var = tk.StringVar(self.out_frame) - self.stat_info_sw_var = tk.StringVar(self.out_frame) - self.stat_info_timer_var = tk.StringVar(self.out_frame) - self.stat_info_encoding_var = tk.StringVar(self.out_frame) - self.stat_info_status_var = tk.StringVar(self.out_frame) + self.stat_info_name_var = tk.StringVar(self._out_frame) + self.stat_info_qth_var = tk.StringVar(self._out_frame) + self.stat_info_loc_var = tk.StringVar(self._out_frame) + self.stat_info_typ_var = tk.StringVar(self._out_frame) + self.stat_info_sw_var = tk.StringVar(self._out_frame) + self.stat_info_timer_var = tk.StringVar(self._out_frame) + self.stat_info_encoding_var = tk.StringVar(self._out_frame) + self.stat_info_status_var = tk.StringVar(self._out_frame) size = 0 - name_label = tk.Label(self.out_frame, + name_label = tk.Label(self._out_frame, textvariable=self.stat_info_name_var, # bg=STAT_BAR_CLR, height=1, @@ -1115,7 +1115,7 @@ def __init__(self, main_win): ) name_label.grid(row=1, column=1, sticky="nsew") name_label.bind('', self._main_class.open_user_db_win) - qth_label = tk.Label(self.out_frame, + qth_label = tk.Label(self._out_frame, textvariable=self.stat_info_qth_var, bg=STAT_BAR_CLR, fg=STAT_BAR_TXT_CLR, @@ -1126,7 +1126,7 @@ def __init__(self, main_win): ) qth_label.bind('', self._main_class.open_user_db_win) qth_label.grid(row=1, column=2, sticky="nsew") - loc_label = tk.Label(self.out_frame, + loc_label = tk.Label(self._out_frame, textvariable=self.stat_info_loc_var, bg=STAT_BAR_CLR, fg=STAT_BAR_TXT_CLR, @@ -1140,7 +1140,7 @@ def __init__(self, main_win): opt = list(STATION_TYPS) stat_typ = tk.OptionMenu( - self.out_frame, + self._out_frame, self.stat_info_typ_var, *opt, command=self.set_stat_typ @@ -1156,7 +1156,7 @@ def __init__(self, main_win): ) stat_typ.grid(row=1, column=4, sticky="nsew") - tk.Label(self.out_frame, + tk.Label(self._out_frame, textvariable=self.stat_info_sw_var, width=20, bg="#ffd444", @@ -1167,7 +1167,7 @@ def __init__(self, main_win): font=(FONT_STAT_BAR, TEXT_SIZE_STATUS - size) ).grid(row=1, column=5, sticky="nsew") - self.status_label = tk.Label(self.out_frame, + self.status_label = tk.Label(self._out_frame, textvariable=self.stat_info_status_var, bg=STAT_BAR_CLR, fg="red3", @@ -1179,7 +1179,7 @@ def __init__(self, main_win): self.status_label.grid(row=1, column=6, sticky="nsew") self.status_label.bind('', self._main_class.do_priv) - tk.Label(self.out_frame, + tk.Label(self._out_frame, textvariable=self.stat_info_timer_var, width=10, height=1, @@ -1191,7 +1191,7 @@ def __init__(self, main_win): ).grid(row=1, column=7, sticky="nsew") opt = ENCODINGS txt_encoding_ent = tk.OptionMenu( - self.out_frame, + self._out_frame, self.stat_info_encoding_var, *opt, command=self.change_txt_encoding @@ -1207,10 +1207,10 @@ def __init__(self, main_win): txt_encoding_ent.grid(row=1, column=8, sticky="nsew", ) ############# # Monitor - self.mon_txt = scrolledtext.ScrolledText(self.pw, + self.mon_txt = scrolledtext.ScrolledText(self._pw, background=TXT_BACKGROUND_CLR, foreground=TXT_MON_CLR, - font=(FONT, self.text_size), + font=(FONT, self._text_size), height=100, width=82, bd=0, @@ -1222,15 +1222,15 @@ def __init__(self, main_win): # paned window - self.pw.add(self.status_frame, weight=1) + self._pw.add(self._status_frame, weight=1) # self.pw.paneconfig(self.status_frame, height=40) - self.pw.add(self.out_frame, weight=1) + self._pw.add(self._out_frame, weight=1) - self.pw.add(self.mon_txt, weight=1) + self._pw.add(self.mon_txt, weight=1) # place the panedwindow on the root window - self.pw.pack(fill=tk.BOTH, expand=True) - self.pw.grid(row=1, column=0, sticky="nsew") + self._pw.pack(fill=tk.BOTH, expand=True) + self._pw.grid(row=1, column=0, sticky="nsew") def update_status_win(self): station = self._main_class.get_conn(self._main_class.channel_index) @@ -1313,20 +1313,20 @@ def switch_mon_mode(self): # TODO Save Stretched Positions if self._main_class.mon_mode: try: - self.pw.remove(self.status_frame) - self.pw.remove(self.mon_txt) + self._pw.remove(self._status_frame) + self._pw.remove(self.mon_txt) except tk.TclError: pass - self.pw.add(self.status_frame, weight=1) - self.pw.add(self.out_frame, weight=1) - self.pw.add(self.mon_txt, weight=1) + self._pw.add(self._status_frame, weight=1) + self._pw.add(self._out_frame, weight=1) + self._pw.add(self.mon_txt, weight=1) # self.pw.configure(height=837) else: # _pw_height = self.pw.winfo_height() # _mon_txt_height = self.mon_txt.winfo_height() # _out_txt_height = self.out_txt_win.winfo_height() - self.pw.remove(self.out_frame) + self._pw.remove(self._out_frame) # self.pw.configure(height=837) def chk_rx_beep(self): @@ -1373,96 +1373,96 @@ def change_txt_encoding(self, event=None, enc=''): class ChBtnFrm: def __init__(self, main_win): self._main_class = main_win - self.ch_btn_blink_timer = time.time() - self.ch_btn_frame = tk.Frame(self._main_class.main_win, width=500, height=10) + self._ch_btn_blink_timer = time.time() + self._ch_btn_frame = tk.Frame(self._main_class.main_win, width=500, height=10) _btn_font = ("fixedsys", 8,) - self.ch_btn_frame.columnconfigure(1, minsize=50, weight=1) - self.ch_btn_frame.columnconfigure(2, minsize=50, weight=1) - self.ch_btn_frame.columnconfigure(3, minsize=50, weight=1) - self.ch_btn_frame.columnconfigure(4, minsize=50, weight=1) - self.ch_btn_frame.columnconfigure(5, minsize=50, weight=1) - self.ch_btn_frame.columnconfigure(6, minsize=50, weight=1) - self.ch_btn_frame.columnconfigure(7, minsize=50, weight=1) - self.ch_btn_frame.columnconfigure(8, minsize=50, weight=1) - self.ch_btn_frame.columnconfigure(9, minsize=50, weight=1) - self.ch_btn_frame.columnconfigure(10, minsize=50, weight=1) + self._ch_btn_frame.columnconfigure(1, minsize=50, weight=1) + self._ch_btn_frame.columnconfigure(2, minsize=50, weight=1) + self._ch_btn_frame.columnconfigure(3, minsize=50, weight=1) + self._ch_btn_frame.columnconfigure(4, minsize=50, weight=1) + self._ch_btn_frame.columnconfigure(5, minsize=50, weight=1) + self._ch_btn_frame.columnconfigure(6, minsize=50, weight=1) + self._ch_btn_frame.columnconfigure(7, minsize=50, weight=1) + self._ch_btn_frame.columnconfigure(8, minsize=50, weight=1) + self._ch_btn_frame.columnconfigure(9, minsize=50, weight=1) + self._ch_btn_frame.columnconfigure(10, minsize=50, weight=1) # self.ch_btn_frame.grid(row=1, column=1, sticky="nsew") - self.ch_1_var = tk.StringVar(self.ch_btn_frame) - self.ch_2_var = tk.StringVar(self.ch_btn_frame) - self.ch_3_var = tk.StringVar(self.ch_btn_frame) - self.ch_4_var = tk.StringVar(self.ch_btn_frame) - self.ch_5_var = tk.StringVar(self.ch_btn_frame) - self.ch_6_var = tk.StringVar(self.ch_btn_frame) - self.ch_7_var = tk.StringVar(self.ch_btn_frame) - self.ch_8_var = tk.StringVar(self.ch_btn_frame) - self.ch_9_var = tk.StringVar(self.ch_btn_frame) - self.ch_10_var = tk.StringVar(self.ch_btn_frame) - self.ch_1_var.set('1') - self.ch_2_var.set('2') - self.ch_3_var.set('3') - self.ch_4_var.set('4') - self.ch_5_var.set('5') - self.ch_6_var.set('6') - self.ch_7_var.set('7') - self.ch_8_var.set('8') - self.ch_9_var.set('9') - self.ch_10_var.set('10') - self.ch_button1 = tk.Button(self.ch_btn_frame, font=_btn_font, textvariable=self.ch_1_var, bg="red", - command=lambda: self._main_class.switch_channel(1)) - self.ch_button2 = tk.Button(self.ch_btn_frame, font=_btn_font, textvariable=self.ch_2_var, bg="red", - command=lambda: self._main_class.switch_channel(2)) - self.ch_button3 = tk.Button(self.ch_btn_frame, font=_btn_font, textvariable=self.ch_3_var, bg="red", - command=lambda: self._main_class.switch_channel(3)) - self.ch_button4 = tk.Button(self.ch_btn_frame, font=_btn_font, textvariable=self.ch_4_var, bg="red", - command=lambda: self._main_class.switch_channel(4)) - self.ch_button5 = tk.Button(self.ch_btn_frame, font=_btn_font, textvariable=self.ch_5_var, bg="red", - command=lambda: self._main_class.switch_channel(5)) - self.ch_button6 = tk.Button(self.ch_btn_frame, font=_btn_font, textvariable=self.ch_6_var, bg="red", - command=lambda: self._main_class.switch_channel(6)) - self.ch_button7 = tk.Button(self.ch_btn_frame, font=_btn_font, textvariable=self.ch_7_var, bg="red", - command=lambda: self._main_class.switch_channel(7)) - self.ch_button8 = tk.Button(self.ch_btn_frame, font=_btn_font, textvariable=self.ch_8_var, bg="red", - command=lambda: self._main_class.switch_channel(8)) - self.ch_button9 = tk.Button(self.ch_btn_frame, font=_btn_font, textvariable=self.ch_9_var, bg="red", - command=lambda: self._main_class.switch_channel(9)) - self.ch_button10 = tk.Button(self.ch_btn_frame, font=_btn_font, textvariable=self.ch_10_var, bg="red", - command=lambda: self._main_class.switch_channel(10)) - self.ch_button1.grid(row=1, column=1, sticky="nsew") - self.ch_button2.grid(row=1, column=2, sticky="nsew") - self.ch_button3.grid(row=1, column=3, sticky="nsew") - self.ch_button4.grid(row=1, column=4, sticky="nsew") - self.ch_button5.grid(row=1, column=5, sticky="nsew") - self.ch_button6.grid(row=1, column=6, sticky="nsew") - self.ch_button7.grid(row=1, column=7, sticky="nsew") - self.ch_button8.grid(row=1, column=8, sticky="nsew") - self.ch_button9.grid(row=1, column=9, sticky="nsew") - self.ch_button10.grid(row=1, column=10, sticky="nsew") + ch_1_var = tk.StringVar(self._ch_btn_frame) + ch_2_var = tk.StringVar(self._ch_btn_frame) + ch_3_var = tk.StringVar(self._ch_btn_frame) + ch_4_var = tk.StringVar(self._ch_btn_frame) + ch_5_var = tk.StringVar(self._ch_btn_frame) + ch_6_var = tk.StringVar(self._ch_btn_frame) + ch_7_var = tk.StringVar(self._ch_btn_frame) + ch_8_var = tk.StringVar(self._ch_btn_frame) + ch_9_var = tk.StringVar(self._ch_btn_frame) + ch_10_var = tk.StringVar(self._ch_btn_frame) + ch_1_var.set('1') + ch_2_var.set('2') + ch_3_var.set('3') + ch_4_var.set('4') + ch_5_var.set('5') + ch_6_var.set('6') + ch_7_var.set('7') + ch_8_var.set('8') + ch_9_var.set('9') + ch_10_var.set('10') + ch_button1 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_1_var, bg="red", + command=lambda: self._main_class.switch_channel(1)) + ch_button2 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_2_var, bg="red", + command=lambda: self._main_class.switch_channel(2)) + ch_button3 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_3_var, bg="red", + command=lambda: self._main_class.switch_channel(3)) + ch_button4 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_4_var, bg="red", + command=lambda: self._main_class.switch_channel(4)) + ch_button5 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_5_var, bg="red", + command=lambda: self._main_class.switch_channel(5)) + ch_button6 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_6_var, bg="red", + command=lambda: self._main_class.switch_channel(6)) + ch_button7 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_7_var, bg="red", + command=lambda: self._main_class.switch_channel(7)) + ch_button8 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_8_var, bg="red", + command=lambda: self._main_class.switch_channel(8)) + ch_button9 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_9_var, bg="red", + command=lambda: self._main_class.switch_channel(9)) + ch_button10 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_10_var, bg="red", + command=lambda: self._main_class.switch_channel(10)) + ch_button1.grid(row=1, column=1, sticky="nsew") + ch_button2.grid(row=1, column=2, sticky="nsew") + ch_button3.grid(row=1, column=3, sticky="nsew") + ch_button4.grid(row=1, column=4, sticky="nsew") + ch_button5.grid(row=1, column=5, sticky="nsew") + ch_button6.grid(row=1, column=6, sticky="nsew") + ch_button7.grid(row=1, column=7, sticky="nsew") + ch_button8.grid(row=1, column=8, sticky="nsew") + ch_button9.grid(row=1, column=9, sticky="nsew") + ch_button10.grid(row=1, column=10, sticky="nsew") self._con_btn_dict = { - 1: self.ch_button1, - 2: self.ch_button2, - 3: self.ch_button3, - 4: self.ch_button4, - 5: self.ch_button5, - 6: self.ch_button6, - 7: self.ch_button7, - 8: self.ch_button8, - 9: self.ch_button9, - 10: self.ch_button10, + 1: ch_button1, + 2: ch_button2, + 3: ch_button3, + 4: ch_button4, + 5: ch_button5, + 6: ch_button6, + 7: ch_button7, + 8: ch_button8, + 9: ch_button9, + 10: ch_button10, } self._ch_btn_textvar = { - 1: self.ch_1_var, - 2: self.ch_2_var, - 3: self.ch_3_var, - 4: self.ch_4_var, - 5: self.ch_5_var, - 6: self.ch_6_var, - 7: self.ch_7_var, - 8: self.ch_8_var, - 9: self.ch_9_var, - 10: self.ch_10_var, + 1: ch_1_var, + 2: ch_2_var, + 3: ch_3_var, + 4: ch_4_var, + 5: ch_5_var, + 6: ch_6_var, + 7: ch_7_var, + 8: ch_8_var, + 9: ch_9_var, + 10: ch_10_var, } - def ch_btn_status_update(self): + def _ch_btn_status_update(self): # self.main_class.on_channel_status_change() _ch_alarm = False # if PORT_HANDLER.get_all_connections().keys(): @@ -1501,8 +1501,8 @@ def ch_btn_status_update(self): _ch_alarm = False else: _ch_alarm = True - if self.ch_btn_blink_timer < time.time(): - self.ch_btn_alarm(self._con_btn_dict[i]) + if self._ch_btn_blink_timer < time.time(): + self._ch_btn_alarm(self._con_btn_dict[i]) else: if _is_link: _ch_alarm = False @@ -1531,17 +1531,15 @@ def ch_btn_status_update(self): if self._con_btn_dict[i].cget('bg') != 'yellow': self._con_btn_dict[i].configure(bg='yellow') - if self.ch_btn_blink_timer < time.time(): - self.ch_btn_blink_timer = time.time() + self._main_class.parm_btn_blink_time + if self._ch_btn_blink_timer < time.time(): + self._ch_btn_blink_timer = time.time() + self._main_class.parm_btn_blink_time self._main_class.ch_alarm = _ch_alarm - def ch_btn_alarm(self, btn: tk.Button): - # TODO find another solution - if self.ch_btn_blink_timer < time.time(): + def _ch_btn_alarm(self, btn: tk.Button): + if self._ch_btn_blink_timer < time.time(): _clr = generate_random_hex_color() if btn.cget('bg') != _clr: btn.configure(bg=_clr) - # self.ch_btn_blink_timer = time.time() + self.main_class.parm_btn_blink_time class TkMainWin: @@ -1600,7 +1598,7 @@ def __init__(self): ######################### # Channel Buttons self._ch_btn = ChBtnFrm(self) - self._ch_btn.ch_btn_frame.grid(row=2, column=0, columnspan=1, sticky="nsew") + self._ch_btn._ch_btn_frame.grid(row=2, column=0, columnspan=1, sticky="nsew") ######################### # Tabbed Frame right self._side_btn_frame_top = tk.Frame(self.main_win, width=200, height=540) @@ -2919,7 +2917,7 @@ def switch_channel(self, ch_ind: int = 0): def ch_status_update(self): """ Triggered by tasker !!! """ """Triggerd when Connection Status has changed""" - self._ch_btn.ch_btn_status_update() + self._ch_btn._ch_btn_status_update() # self.change_conn_btn() self.on_channel_status_change() @@ -2964,7 +2962,7 @@ def _ch_btn_clk(self, ind: int): self._txt_win.ts_box_box.configure(bg=STAT_BAR_CLR) self.on_channel_status_change() - self._ch_btn.ch_btn_status_update() + self._ch_btn._ch_btn_status_update() self._kanal_switch() # Sprech def on_channel_status_change(self): @@ -3157,4 +3155,3 @@ def set_dx_alarm(self, event=None): def get_dx_alarm(self): return bool(self.setting_dx_alarm.get()) - From 43b55cd2d91c7def08c25bf4a46eb581ac8f8fe5 Mon Sep 17 00:00:00 2001 From: masto Date: Thu, 5 Oct 2023 06:54:55 +0200 Subject: [PATCH 14/17] - Stations that triggered DX or TR Alarm are marked in MH/Tracer List --- ax25/ax25Statistics.py | 20 ++++++++++++++++---- ax25aprs/aprs_station.py | 6 ++++-- constant.py | 2 +- gui/guiAPRS_be_tracer.py | 11 ++++++++--- gui/guiMH.py | 14 +++++++++++--- 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/ax25/ax25Statistics.py b/ax25/ax25Statistics.py index be717598..d28d3694 100644 --- a/ax25/ax25Statistics.py +++ b/ax25/ax25Statistics.py @@ -105,6 +105,8 @@ def __init__(self): self.dx_alarm_trigger = False self.last_dx_alarm = time.time() + self.dx_alarm_hist = [] + self.dx_alarm_perma_hist = {} self.parm_new_call_alarm = False self.parm_distance_alarm = 50 self.parm_lastseen_alarm = 1 @@ -113,10 +115,17 @@ def __init__(self): def __del__(self): pass - def _set_dx_alarm(self, port_id: int): + def _set_dx_alarm(self, ent, port_id: int): if port_id in self.parm_alarm_ports: self.dx_alarm_trigger = True self.last_dx_alarm = time.time() + _now = datetime.now() + self.dx_alarm_hist.append(ent.own_call) + self.dx_alarm_perma_hist[str(ent.own_call)] = _now, ent + + def reset_dx_alarm_his(self): + self.dx_alarm_hist = [] + self.dx_alarm_trigger = False def bw_mon_inp(self, ax25_frame, port_id): if port_id not in self.port_statistik_DB.keys(): @@ -188,6 +197,7 @@ def mh_inp_axip_add(self, ent: '', axip_add: tuple): self.calls[ent].axip_add = axip_add def mh_inp(self, ax25_frame, port_name, port_id, digi=''): + _dx_alarm = False if not digi: ######################## # Port Stat @@ -204,13 +214,13 @@ def mh_inp(self, ax25_frame, port_name, port_id, digi=''): if call_str not in self.calls.keys(): ent = MyHeard() if self.parm_new_call_alarm: - self._set_dx_alarm(port_id) + _dx_alarm = True else: ent = self.calls[call_str] _t_delta = datetime.now() - ent.last_seen if self.parm_lastseen_alarm: if _t_delta.days >= self.parm_lastseen_alarm: - self._set_dx_alarm(port_id) + _dx_alarm = True ent.last_seen = datetime.now() ent.own_call = call_str ent.pac_n += 1 @@ -253,7 +263,9 @@ def mh_inp(self, ax25_frame, port_name, port_id, digi=''): ent.distance = float(db_ent.Distance) if self.parm_distance_alarm: if ent.distance >= self.parm_distance_alarm: - self._set_dx_alarm(port_id) + _dx_alarm = True + if _dx_alarm: + self._set_dx_alarm(port_id=port_id, ent=ent) self.calls[call_str] = ent diff --git a/ax25aprs/aprs_station.py b/ax25aprs/aprs_station.py index 4aa5d666..9ced6a81 100644 --- a/ax25aprs/aprs_station.py +++ b/ax25aprs/aprs_station.py @@ -774,13 +774,13 @@ def _tracer_add_traced_packet(self, pack): _dist = _user_db_ent.Distance pack['distance'] = _dist pack['locator'] = _loc - + pack['tr_alarm'] = self._tracer_check_alarm(pack) if _k in self.be_tracer_traced_packets.keys(): self.be_tracer_traced_packets[_k].append(pack) else: self.be_tracer_traced_packets[_k] = deque([pack], maxlen=500) # print(f'Tracer RX dict: {self.be_tracer_traced_packets}') - self._tracer_check_alarm(pack) + # self._tracer_check_alarm(pack) self.tracer_update_gui() return True return False @@ -791,6 +791,8 @@ def _tracer_check_alarm(self, pack): _dist = pack.get('distance', 0) if _dist >= self.be_tracer_alarm_range: self._be_tracer_is_alarm = True + return True + return False def tracer_is_alarm(self): return self._be_tracer_is_alarm diff --git a/constant.py b/constant.py index 7b0c61ef..2654660c 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.11dev' +VER = '2.98.12dev' LANGUAGE = 0 # QUICK FIX """ 0 = German diff --git a/gui/guiAPRS_be_tracer.py b/gui/guiAPRS_be_tracer.py index 5fa2dd55..c1f15e7e 100644 --- a/gui/guiAPRS_be_tracer.py +++ b/gui/guiAPRS_be_tracer.py @@ -212,8 +212,12 @@ def update_tree_data(self): def _update_tree(self): for i in self._tree.get_children(): self._tree.delete(i) + self._tree.tag_configure("tr_alarm", background='#55ed9f', foreground='black') for ret_ent in self._tree_data: - self._tree.insert('', tk.END, values=ret_ent) + if ret_ent[1]: + self._tree.insert('', tk.END, values=ret_ent[0], tags=('tr_alarm',)) + else: + self._tree.insert('', tk.END, values=ret_ent[0], ) def _format_tree_data(self): _traces = PORT_HANDLER.get_aprs_ais().tracer_traces_get() @@ -232,7 +236,7 @@ def _format_tree_data(self): _loc = _pack.get('locator', '') _dist = _pack.get('distance', 0) - self._tree_data.append(( + self._tree_data.append((( _rx_time, _call, _port_id, @@ -240,7 +244,8 @@ def _format_tree_data(self): f'{_rtt:.2f}', _loc, _dist, - )) + ), _pack.get('tr_alarm', False))) + _pack['tr_alarm'] = False def _save_btn(self): self._save_vars() diff --git a/gui/guiMH.py b/gui/guiMH.py index b9edd420..74175390 100644 --- a/gui/guiMH.py +++ b/gui/guiMH.py @@ -292,8 +292,12 @@ def _init_tree_data(self): def _update_tree(self): for i in self._tree.get_children(): self._tree.delete(i) + self._tree.tag_configure("dx_alarm", background='#55ed9f', foreground='black') for ret_ent in self._tree_data: - self._tree.insert('', tk.END, values=ret_ent) + if ret_ent[1]: + self._tree.insert('', tk.END, values=ret_ent[0], tags=('dx_alarm',)) + else: + self._tree.insert('', tk.END, values=ret_ent[0], ) def _sort_entry(self, flag: str): sort_date = MH_LIST.get_sort_mh_entry(flag_str=flag, reverse=self._rev_ent) @@ -313,8 +317,11 @@ def _format_tree_ent(self, mh_list): axip_str = '{} - {}'.format(ent.axip_add[0], ent.axip_add[1]) else: axip_str = '' + _dx_alarm = False + if ent.own_call in list(MH_LIST.dx_alarm_hist): + _dx_alarm = True - self._tree_data.append(( + self._tree_data.append((( f'{conv_time_DE_str(ent.last_seen)}', f'{conv_time_DE_str(ent.first_seen)}', f'{ent.port_id} {ent.port}', @@ -326,12 +333,13 @@ def _format_tree_ent(self, mh_list): ' '.join(ent.route), f'{axip_str}', f'{ent.axip_fail}', - )) + ), _dx_alarm)) def __del__(self): self._root_win.mh_window = None # self.destroy() def close(self): + MH_LIST.reset_dx_alarm_his() self._root_win.mh_window = None self.destroy() From 8583d65e1a23aa6f739854fa34ac631a827c44d7 Mon Sep 17 00:00:00 2001 From: masto Date: Thu, 5 Oct 2023 11:37:10 +0200 Subject: [PATCH 15/17] - CLI CMD "DXLIST" added. Shows history of DX/Tracer Alarms --- ax25/ax25Statistics.py | 78 +++++++++++++----------------------- ax25aprs/aprs_station.py | 30 +++++++++++++- cli/cliMain.py | 86 ++++++++++++++++++++++++++++++++-------- constant.py | 3 +- fnc/str_fnc.py | 4 ++ fnc/struct_fnc.py | 65 ++++++++++++++++++++++++++++++ gui/guiAPRS_be_tracer.py | 3 +- gui/guiMH.py | 3 +- string_tab.py | 4 ++ 9 files changed, 205 insertions(+), 71 deletions(-) create mode 100644 fnc/struct_fnc.py diff --git a/ax25/ax25Statistics.py b/ax25/ax25Statistics.py index d28d3694..a897cd0d 100644 --- a/ax25/ax25Statistics.py +++ b/ax25/ax25Statistics.py @@ -10,44 +10,7 @@ from fnc.cfg_fnc import cleanup_obj_dict, set_obj_att from fnc.socket_fnc import check_ip_add_format from fnc.str_fnc import conv_time_for_sorting - - -def get_bandwidth_struct(): - _struct = {} - for _h in range(24): - for _m in range(60): - for _s in range(6): - _ts_str = f'{str(_h).zfill(2)}:{str(_m).zfill(2)}:{_s}' - _struct[_ts_str] = 0 - return _struct - - -def get_port_stat_struct(): - struct_hour = {} - for key in [ - 'N_pack', - 'I', - 'SABM', - 'DM', - 'DISC', - 'REJ', - 'RR', - 'RNR', - 'UI', - 'FRMR', - 'DATA_W_HEADER', - 'DATA' - ]: - struct_hour[key] = {minute: 0 for minute in range(60)} - return struct_hour - - -def init_day_dic(): - - ret = {} - for hour in range(24): - ret[hour] = get_port_stat_struct() - return ret +from fnc.struct_fnc import get_bandwidth_struct, init_day_dic, get_dx_tx_alarm_his_pack class MyHeard: @@ -56,15 +19,15 @@ class MyHeard: route = [] all_routes = [] port = '' - port_id = 0 # Not used yet + port_id = 0 # Not used yet first_seen = datetime.now() last_seen = datetime.now() - pac_n = 0 # N Packets - byte_n = 0 # N Bytes - h_byte_n = 0 # N Header Bytes - rej_n = 0 # N REJ - axip_add = '', 0 # IP, Port - axip_fail = 0 # Fail Counter + pac_n = 0 # N Packets + byte_n = 0 # N Bytes + h_byte_n = 0 # N Header Bytes + rej_n = 0 # N REJ + axip_add = '', 0 # IP, Port + axip_fail = 0 # Fail Counter locator = '' distance = -1 @@ -115,13 +78,28 @@ def __init__(self): def __del__(self): pass - def _set_dx_alarm(self, ent, port_id: int): + def _set_dx_alarm(self, ent): + port_id = ent.port_id if port_id in self.parm_alarm_ports: self.dx_alarm_trigger = True self.last_dx_alarm = time.time() - _now = datetime.now() self.dx_alarm_hist.append(ent.own_call) - self.dx_alarm_perma_hist[str(ent.own_call)] = _now, ent + self._add_dx_alarm_hist(ent=ent) + + def _add_dx_alarm_hist(self, ent): + _via = '' + if ent.route: + _via = ent.route[-1] + _hist_struc = get_dx_tx_alarm_his_pack( + port_id=ent.port_id, + call_str=ent.own_call, + via=_via, + path=ent.route, + locator=ent.locator, + distance=ent.distance, + typ='MHEARD', + ) + self.dx_alarm_perma_hist[str(_hist_struc['key'])] = dict(_hist_struc) def reset_dx_alarm_his(self): self.dx_alarm_hist = [] @@ -235,7 +213,7 @@ def mh_inp(self, ax25_frame, port_name, port_id, digi=''): if to_c_str not in ent.to_calls: ent.to_calls.append(to_c_str) # Routes - ent.route = [] # Last Route + ent.route = [] # Last Route _last_digi = '' if ax25_frame.via_calls: for call in ax25_frame.via_calls: @@ -265,7 +243,7 @@ def mh_inp(self, ax25_frame, port_name, port_id, digi=''): if ent.distance >= self.parm_distance_alarm: _dx_alarm = True if _dx_alarm: - self._set_dx_alarm(port_id=port_id, ent=ent) + self._set_dx_alarm(ent=ent) self.calls[call_str] = ent diff --git a/ax25aprs/aprs_station.py b/ax25aprs/aprs_station.py index 9ced6a81..cff9be23 100644 --- a/ax25aprs/aprs_station.py +++ b/ax25aprs/aprs_station.py @@ -11,6 +11,7 @@ from fnc.cfg_fnc import cleanup_obj, save_to_file, load_fm_file, set_obj_att from fnc.loc_fnc import decimal_degrees_to_aprs, locator_distance, coordinates_to_locator from fnc.str_fnc import convert_umlaute_to_ascii +from fnc.struct_fnc import get_dx_tx_alarm_his_pack logger = logging.getLogger(__name__) @@ -61,8 +62,9 @@ def __init__(self, load_cfg=True): self.be_tracer_alarm_range = 50 self.be_auto_tracer_duration = 60 - # Packet Pool TODO: extra var f Packet history + # Packet Pool self.be_tracer_traced_packets = {} + self.be_tracer_alarm_hist = {} # Control vars self._be_tracer_is_alarm = False self._be_tracer_tx_trace_packet = '' @@ -677,7 +679,6 @@ def _tracer_task(self): if time.time() > self._be_auto_tracer_timer: return if time.time() > self._be_tracer_interval_timer: - print(f"Auto-Tracer timer: {round(self._be_auto_tracer_timer - time.time())}") self.tracer_sendit() return @@ -791,9 +792,34 @@ def _tracer_check_alarm(self, pack): _dist = pack.get('distance', 0) if _dist >= self.be_tracer_alarm_range: self._be_tracer_is_alarm = True + self._tracer_add_alarm_hist(pack) return True return False + def _tracer_add_alarm_hist(self, aprs_pack): + _via = '' + if aprs_pack.get('via', ''): + if aprs_pack.get('path', []): + _via = get_last_digi_fm_path(aprs_pack) + else: + _via_list = [] + for _digi in aprs_pack.get('path', []): + if '*' == _digi[-1]: + _via_list.append(str(_digi)) + if len(_via_list) > 1: + _via = _via_list[-2] + + _hist_struc = get_dx_tx_alarm_his_pack( + port_id=aprs_pack.get('port_id', -1), + call_str=aprs_pack.get('call', ''), + via=_via, + path=aprs_pack.get('path', []), + locator=aprs_pack.get('locator', ''), + distance=aprs_pack.get('distance', -1), + typ='TRACE', + ) + self.be_tracer_alarm_hist[str(_hist_struc['key'])] = dict(_hist_struc) + def tracer_is_alarm(self): return self._be_tracer_is_alarm diff --git a/cli/cliMain.py b/cli/cliMain.py index 750e9ffe..b562ac98 100644 --- a/cli/cliMain.py +++ b/cli/cliMain.py @@ -97,15 +97,16 @@ def __init__(self, connection): b'CONNECT': (self.cmd_connect, 'Connect'), b'PORT': (self.cmd_port, 'Ports'), b'LCSTATUS': (self.cmd_lcstatus, STR_TABLE['cmd_help_lcstatus'][self.connection.cli_language]), - b'MH': (self.cmd_mh, 'MYHeard Liste'), - b'AXIP': (self.cmd_axip, 'AXIP-MH Liste'), - b'LMH': (self.cmd_mhl, 'Long MYHeard Liste'), + b'MH': (self.cmd_mh, 'MYHeard List'), + b'LMH': (self.cmd_mhl, 'Long MYHeard List'), + b'AXIP': (self.cmd_axip, 'AXIP-MH List'), b'ATR': (self.cmd_aprs_trace, 'APRS-Tracer'), + b'DXLIST': (self.cmd_dxlist, 'DX/Tracer Alarm List'), b'WX': (self.cmd_wx, 'Wetterstationen'), b'ECHO': (self.cmd_echo, 'Echo'), b'VERSION': (self.cmd_ver, 'Version'), b'HELP': (self.cmd_help, STR_TABLE['help'][self.connection.cli_language]), - b'?': (self.cmd_help, ''), + b'?': (self.cmd_shelp, STR_TABLE['cmd_shelp'][self.connection.cli_language]), b'NAME': (self.cmd_set_name, STR_TABLE['cmd_help_set_name'][self.connection.cli_language]), b'QTH': (self.cmd_set_qth, STR_TABLE['cmd_help_set_qth'][self.connection.cli_language]), @@ -117,7 +118,7 @@ def __init__(self, connection): b'USER': (self.cmd_user_db_detail, STR_TABLE['cmd_help_user_db'][self.connection.cli_language]), b'UMLAUT': (self.cmd_umlaut, STR_TABLE['auto_text_encoding'][self.connection.cli_language]), b'INFO': (self.cmd_i, 'Info'), - b'LINFO': (self.cmd_li, 'Lange Info'), + b'LINFO': (self.cmd_li, 'Long Info'), b'NEWS': (self.cmd_news, 'NEWS'), b'POPT': (self.cmd_popt_banner, 'PoPT Banner'), } @@ -344,6 +345,9 @@ def find_cmd(self): treffer.append(cmd) if not treffer: return f"\r # {STR_TABLE['cmd_not_known'][self.connection.cli_language]}\r" + if len(treffer) > 1: + return (f"\r # {STR_TABLE['cmd_not_known'][self.connection.cli_language]}" + f"\r # {(b' '.join(treffer)).decode(self.encoding[0], 'ignore')} ?\r") self.cmd = b'' ret = self.commands[treffer[0]][0]() # self.last_line = b'' @@ -464,6 +468,43 @@ def cmd_q(self): # Quit self.crone_state_index = 100 # Quit State return '' + def cmd_dxlist(self): + parm = 10 + if self.parameter: + try: + parm = int(self.parameter[0]) + except ValueError: + pass + ret = self._get_alarm_out_cli(max_ent=parm) + + return ret + '\r' + + def _get_alarm_out_cli(self, max_ent=10): + alarm_his = dict(MH_LIST.dx_alarm_perma_hist) + alarm_his.update(dict(self.port_handler.get_aprs_ais().be_tracer_alarm_hist)) + if not alarm_his: + return f'\r # {STR_TABLE["cli_no_data"][self.connection.cli_language]}\r' + out = '\r' + out += "-----Time-Port---Call------via-------LOC------Dist(km)--Type---\r" + max_c = 0 + key_list = list(alarm_his.keys()) + key_list.sort(reverse=True) + for _k in key_list: + max_c += 1 + if max_c > max_ent: + break + time_delta_str = get_timedelta_str(alarm_his[_k]['ts']) + via = alarm_his[_k]['via'] + loc = alarm_his[_k]['loc'] + dis = str(alarm_his[_k]['dist']) + typ = alarm_his[_k]['typ'] + port = str(alarm_his[_k]['port_id']) + call = alarm_his[_k]['call_str'] + + out += f' {time_delta_str} {port:6} {call:10}{via:10}{loc:9}{dis:10}{typ}\r' + + return out + def cmd_axip(self): parm = 10 if self.parameter: @@ -475,9 +516,10 @@ def cmd_axip(self): return ret + '\r' - @staticmethod - def _get_axip_out_cli(max_ent=10): + def _get_axip_out_cli(self, max_ent=10): _ent = MH_LIST.get_sort_mh_entry('last', reverse=False) + if not _ent: + return f'\r # {STR_TABLE["cli_no_data"][self.connection.cli_language]}\r' max_c = 0 out = '\r' # out += '\r < AXIP - Clients >\r\r' @@ -505,8 +547,10 @@ def cmd_mh(self): return ret + '\r' - @staticmethod - def _get_mh_out_cli(max_ent=20): + def _get_mh_out_cli(self, max_ent=20): + sort_list = MH_LIST.get_sort_mh_entry('last', False) + if not sort_list: + return f'\r # {STR_TABLE["cli_no_data"][self.connection.cli_language]}\r' out = '\r' # out += '\r < MH - List >\r\r' c = 0 @@ -516,7 +560,6 @@ def _get_mh_out_cli(max_ent=20): tb = 0 rj = 0 """ - sort_list = MH_LIST.get_sort_mh_entry('last', False) for call in list(sort_list.keys()): max_c += 1 @@ -542,7 +585,6 @@ def _get_mh_out_cli(max_ent=20): out += '\rTotal REJ-Packets Rec.: ' + str(rj) out += '\rTotal Bytes Rec.: ' + str(tb) """ - out += '\r' return out @@ -557,8 +599,10 @@ def cmd_mhl(self): return ret + '\r' - @staticmethod - def _get_mh_long_out_cli(max_ent=10): + def _get_mh_long_out_cli(self, max_ent=10): + sort_list = MH_LIST.get_sort_mh_entry('last', False) + if not sort_list: + return f'\r # {STR_TABLE["cli_no_data"][self.connection.cli_language]}\r' out = '\r' out += "-----Time-Port---Call------via-------LOC------Dist(km)--Type---Packets\r" max_c = 0 @@ -567,8 +611,6 @@ def _get_mh_long_out_cli(max_ent=10): tb = 0 rj = 0 """ - sort_list = MH_LIST.get_sort_mh_entry('last', False) - for call in list(sort_list.keys()): max_c += 1 if max_c > max_ent: @@ -597,7 +639,6 @@ def _get_mh_long_out_cli(max_ent=10): rj += sort_list[call].rej_n """ out += '\r' - out += '\r' """ out += '\rTotal Packets Rec.: ' + str(tp) out += '\rTotal REJ-Packets Rec.: ' + str(rj) @@ -1062,6 +1103,19 @@ def cmd_help(self): ret += '\r\r' return ret + def cmd_shelp(self): + ret = '\r # ' + _c = 0 + _cmds = list(self.commands.keys()) + _cmds.sort() + for k in _cmds: + ret += (k + b' ').decode(self.encoding[0], 'ignore') + if len(ret) - _c > 60: + ret += '\r # ' + _c += 60 + ret += '\r\r' + return ret + def cmd_umlaut(self): # print(self.parameter) if not self.parameter: diff --git a/constant.py b/constant.py index 2654660c..d67d210c 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.12dev' +VER = '2.98.13dev' LANGUAGE = 0 # QUICK FIX """ 0 = German @@ -124,6 +124,7 @@ FONT_STAT_BAR = 'Arial' PARAM_MAX_MON_LEN = 100000 CFG_clr_sys_msg = 'red' +CFG_TR_DX_ALARM_BG_CLR = '#55ed9f' POPT_BANNER = '\r$$$$$$$\ $$$$$$\ $$$$$$$\ $$$$$$$$|\r' \ diff --git a/fnc/str_fnc.py b/fnc/str_fnc.py index 4132a0dd..09f77ebc 100644 --- a/fnc/str_fnc.py +++ b/fnc/str_fnc.py @@ -31,6 +31,10 @@ def conv_time_for_sorting(dateti: datetime.now()): return dateti.strftime('%y/%m/%d %H:%M:%S') +def conv_time_for_key(dateti: datetime.now()): + return dateti.strftime('%y%m%d%H%M%S') + + def conv_time_US_str(dateti: datetime.now()): return dateti.strftime('%m/%d/%y %H:%M:%S') diff --git a/fnc/struct_fnc.py b/fnc/struct_fnc.py new file mode 100644 index 00000000..3bdfe61a --- /dev/null +++ b/fnc/struct_fnc.py @@ -0,0 +1,65 @@ +from datetime import datetime + +from fnc.str_fnc import conv_time_for_key + + +def get_dx_tx_alarm_his_pack( + port_id: int, + call_str: str, + via: str, + path: list, + locator: str, + distance: float, + typ: str, +): + _now = datetime.now() + return { + 'ts': _now, + 'port_id': port_id, + 'call_str': call_str, + 'via': via, + 'path': path, + 'loc': locator, + 'dist': distance, + 'typ': typ, + 'key': f"{conv_time_for_key(_now)}{call_str}", + + } + + +def get_bandwidth_struct(): + _struct = {} + for _h in range(24): + for _m in range(60): + for _s in range(6): + _ts_str = f'{str(_h).zfill(2)}:{str(_m).zfill(2)}:{_s}' + _struct[_ts_str] = 0 + return _struct + + +def get_port_stat_struct(): + struct_hour = {} + for key in [ + 'N_pack', + 'I', + 'SABM', + 'DM', + 'DISC', + 'REJ', + 'RR', + 'RNR', + 'UI', + 'FRMR', + 'DATA_W_HEADER', + 'DATA' + ]: + struct_hour[key] = {minute: 0 for minute in range(60)} + return struct_hour + + +def init_day_dic(): + + ret = {} + for hour in range(24): + ret[hour] = get_port_stat_struct() + return ret diff --git a/gui/guiAPRS_be_tracer.py b/gui/guiAPRS_be_tracer.py index c1f15e7e..59d503cd 100644 --- a/gui/guiAPRS_be_tracer.py +++ b/gui/guiAPRS_be_tracer.py @@ -3,6 +3,7 @@ from tkinter import ttk from ax25.ax25InitPorts import PORT_HANDLER +from constant import CFG_TR_DX_ALARM_BG_CLR logger = logging.getLogger(__name__) @@ -212,7 +213,7 @@ def update_tree_data(self): def _update_tree(self): for i in self._tree.get_children(): self._tree.delete(i) - self._tree.tag_configure("tr_alarm", background='#55ed9f', foreground='black') + self._tree.tag_configure("tr_alarm", background=CFG_TR_DX_ALARM_BG_CLR, foreground='black') for ret_ent in self._tree_data: if ret_ent[1]: self._tree.insert('', tk.END, values=ret_ent[0], tags=('tr_alarm',)) diff --git a/gui/guiMH.py b/gui/guiMH.py index 74175390..3c713bb1 100644 --- a/gui/guiMH.py +++ b/gui/guiMH.py @@ -4,6 +4,7 @@ from ax25.ax25InitPorts import PORT_HANDLER from ax25.ax25Statistics import MyHeard, MH_LIST +from constant import CFG_TR_DX_ALARM_BG_CLR from fnc.str_fnc import conv_time_DE_str logger = logging.getLogger(__name__) @@ -292,7 +293,7 @@ def _init_tree_data(self): def _update_tree(self): for i in self._tree.get_children(): self._tree.delete(i) - self._tree.tag_configure("dx_alarm", background='#55ed9f', foreground='black') + self._tree.tag_configure("dx_alarm", background=CFG_TR_DX_ALARM_BG_CLR, foreground='black') for ret_ent in self._tree_data: if ret_ent[1]: self._tree.insert('', tk.END, values=ret_ent[0], tags=('dx_alarm',)) diff --git a/string_tab.py b/string_tab.py index bd49b96d..57a9f5de 100644 --- a/string_tab.py +++ b/string_tab.py @@ -201,6 +201,9 @@ 'port_overview': ('Port Übersicht', 'Port Overview', 'Lekker Ports'), + 'cmd_shelp': ('Kurzhilfe', + 'Short help', + 'Lekker Short Helpye'), 'time_connected': ('Connect Dauer', 'Connect duration', @@ -217,6 +220,7 @@ 'Show connected terminal channels (detailed version)', 'Toon lekker aangesloten terminalkanalen (gedetailleerde versie)'), 'cli_no_wx_data': ('Keine Wetterdaten vorhanden.', 'No WX data available', 'No WX data available'), + 'cli_no_data': ('Keine Daten vorhanden.', 'No data available.', 'No data available.'), 'cli_no_tracer_data': ('Keine Tracerdaten vorhanden.', 'No Tracer data available', 'No Tracer data available'), } From b528af14b8b350ebe2bc59e833539c2781c20ee4 Mon Sep 17 00:00:00 2001 From: masto Date: Thu, 5 Oct 2023 12:38:18 +0200 Subject: [PATCH 16/17] - CLI CMD "LANG" added. Change CLI Language. (DE, EN, NL) --- ax25/ax25Connection.py | 8 ++++++-- cli/cliMain.py | 14 ++++++++++++-- constant.py | 8 +++++++- string_tab.py | 15 +++++++++++---- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/ax25/ax25Connection.py b/ax25/ax25Connection.py index f86de2c3..260d4157 100644 --- a/ax25/ax25Connection.py +++ b/ax25/ax25Connection.py @@ -232,11 +232,11 @@ def __init__(self, ax25_frame: AX25Frame, cfg, port, rx=True): """ User DB Entry """ # self.user_db = USER_DB self.user_db_ent = False + self.cli_language = 0 self.set_user_db_ent() """ Station Individual Parameter """ self.set_packet_param() """ Init CLI """ - self.cli_language = 0 self.cli = cli.cliMain.NoneCLI(self) self.cli_type = '' if self.stat_cfg.stat_parm_pipe is None: @@ -386,9 +386,13 @@ def set_user_db_ent(self): self.user_db_ent.Language = 0 else: self.user_db_ent.Language = int(self.gui.language) - self.cli_language = int(self.gui.language) + self.cli_language = self.user_db_ent.Language self.set_distance() + def set_user_db_language(self, lang_ind: int): + self.user_db_ent.Language = int(lang_ind) + self.cli_language = int(lang_ind) + def set_distance(self): if self.user_db_ent: if self.my_locator and self.user_db_ent.LOC: diff --git a/cli/cliMain.py b/cli/cliMain.py index b562ac98..98536169 100644 --- a/cli/cliMain.py +++ b/cli/cliMain.py @@ -95,15 +95,15 @@ def __init__(self, connection): b'QUIT': (self.cmd_q, 'Quit'), b'BYE': (self.cmd_q, ''), b'CONNECT': (self.cmd_connect, 'Connect'), + b'ECHO': (self.cmd_echo, 'Echo'), b'PORT': (self.cmd_port, 'Ports'), - b'LCSTATUS': (self.cmd_lcstatus, STR_TABLE['cmd_help_lcstatus'][self.connection.cli_language]), b'MH': (self.cmd_mh, 'MYHeard List'), b'LMH': (self.cmd_mhl, 'Long MYHeard List'), b'AXIP': (self.cmd_axip, 'AXIP-MH List'), b'ATR': (self.cmd_aprs_trace, 'APRS-Tracer'), b'DXLIST': (self.cmd_dxlist, 'DX/Tracer Alarm List'), + b'LCSTATUS': (self.cmd_lcstatus, STR_TABLE['cmd_help_lcstatus'][self.connection.cli_language]), b'WX': (self.cmd_wx, 'Wetterstationen'), - b'ECHO': (self.cmd_echo, 'Echo'), b'VERSION': (self.cmd_ver, 'Version'), b'HELP': (self.cmd_help, STR_TABLE['help'][self.connection.cli_language]), b'?': (self.cmd_shelp, STR_TABLE['cmd_shelp'][self.connection.cli_language]), @@ -119,6 +119,7 @@ def __init__(self, connection): b'UMLAUT': (self.cmd_umlaut, STR_TABLE['auto_text_encoding'][self.connection.cli_language]), b'INFO': (self.cmd_i, 'Info'), b'LINFO': (self.cmd_li, 'Long Info'), + b'LANG': (self.cmd_lang, STR_TABLE['cli_change_language'][self.connection.cli_language]), b'NEWS': (self.cmd_news, 'NEWS'), b'POPT': (self.cmd_popt_banner, 'PoPT Banner'), } @@ -468,6 +469,15 @@ def cmd_q(self): # Quit self.crone_state_index = 100 # Quit State return '' + def cmd_lang(self): + if not self.parameter: + return f'\r # {STR_TABLE["cli_no_lang_param"][self.connection.cli_language]}{" ".join(list(constant.LANG_IND.keys()))}\r' + self.decode_param() + if self.parameter[0].upper() in constant.LANG_IND.keys(): + self.connection.set_user_db_language(constant.LANG_IND[self.parameter[0].upper()]) + return f'\r # {STR_TABLE["cli_lang_set"][self.connection.cli_language]}\r' + return f'\r # {STR_TABLE["cli_no_lang_param"][self.connection.cli_language]}{" ".join(list(constant.LANG_IND.keys()))}\r' + def cmd_dxlist(self): parm = 10 if self.parameter: diff --git a/constant.py b/constant.py index d67d210c..e3492e52 100644 --- a/constant.py +++ b/constant.py @@ -3,13 +3,19 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.13dev' +VER = '2.98.14dev' LANGUAGE = 0 # QUICK FIX """ 0 = German 1 = English 2 = Dutch """ +LANG_IND = { + 'DE': 0, + 'EN': 1, + 'NL': 2, + } + CFG_data_path = 'data/' CFG_usertxt_path = 'userdata/' CFG_ft_downloads = 'ft_downloads/' diff --git a/string_tab.py b/string_tab.py index 57a9f5de..8281ab07 100644 --- a/string_tab.py +++ b/string_tab.py @@ -203,7 +203,7 @@ 'Lekker Ports'), 'cmd_shelp': ('Kurzhilfe', 'Short help', - 'Lekker Short Helpye'), + 'Lekker Korte hulp'), 'time_connected': ('Connect Dauer', 'Connect duration', @@ -219,8 +219,15 @@ 'cmd_help_lcstatus': ('Verbundene Terminalkanäle anzeigen (ausführliche Version)', 'Show connected terminal channels (detailed version)', 'Toon lekker aangesloten terminalkanalen (gedetailleerde versie)'), - 'cli_no_wx_data': ('Keine Wetterdaten vorhanden.', 'No WX data available', 'No WX data available'), - 'cli_no_data': ('Keine Daten vorhanden.', 'No data available.', 'No data available.'), - 'cli_no_tracer_data': ('Keine Tracerdaten vorhanden.', 'No Tracer data available', 'No Tracer data available'), + 'cli_no_wx_data': ('Keine Wetterdaten vorhanden.', 'No WX data available', 'Geen lekker WX beschikbaar.'), + 'cli_no_data': ('Keine Daten vorhanden.', 'No data available.', 'Geen gegevens beschikbaar.'), + 'cli_no_tracer_data': ('Keine Tracerdaten vorhanden.', 'No Tracer data available', 'Geen tracergegevens beschikbaar.'), + 'cli_change_language': ('Sprache ändern.', 'Change language.', 'Lekker taal veranderen'), + 'cli_lang_set': ('Sprache auf Deutsch geändert.', + 'Language changed to English.', + 'Taal veranderd naar lekker Nederlands.'), + 'cli_no_lang_param': ('Sprache nicht erkannt! Mögliche Sprachen: ', + 'Language not recognized! Possible languages: ', + 'Taal niet herkend! Mogelijke talen: '), } From 6c7aafc195c4aa0d8a65ab510190a14dba2511c7 Mon Sep 17 00:00:00 2001 From: masto Date: Thu, 5 Oct 2023 14:04:22 +0200 Subject: [PATCH 17/17] - Add flip-flop to prio tasker to split workload - Vars cleaned up in guiMain.py - Ready to merge into Master --- ax25/ax25Connection.py | 1 - cli/cliMain.py | 32 +++-- constant.py | 2 +- gui/guiMain.py | 301 ++++++++++++++++++++++------------------- 4 files changed, 181 insertions(+), 155 deletions(-) diff --git a/ax25/ax25Connection.py b/ax25/ax25Connection.py index 260d4157..e728f1e3 100644 --- a/ax25/ax25Connection.py +++ b/ax25/ax25Connection.py @@ -230,7 +230,6 @@ def __init__(self, ax25_frame: AX25Frame, cfg, port, rx=True): """ Encoding """ self.encoding = 'CP437' # 'UTF-8' """ User DB Entry """ - # self.user_db = USER_DB self.user_db_ent = False self.cli_language = 0 self.set_user_db_ent() diff --git a/cli/cliMain.py b/cli/cliMain.py index 98536169..16f77600 100644 --- a/cli/cliMain.py +++ b/cli/cliMain.py @@ -93,7 +93,7 @@ def __init__(self, connection): # Standard Commands ( GLOBAL ) self.commands = { b'QUIT': (self.cmd_q, 'Quit'), - b'BYE': (self.cmd_q, ''), + b'BYE': (self.cmd_q, 'Bye'), b'CONNECT': (self.cmd_connect, 'Connect'), b'ECHO': (self.cmd_echo, 'Echo'), b'PORT': (self.cmd_port, 'Ports'), @@ -104,24 +104,25 @@ def __init__(self, connection): b'DXLIST': (self.cmd_dxlist, 'DX/Tracer Alarm List'), b'LCSTATUS': (self.cmd_lcstatus, STR_TABLE['cmd_help_lcstatus'][self.connection.cli_language]), b'WX': (self.cmd_wx, 'Wetterstationen'), - b'VERSION': (self.cmd_ver, 'Version'), - b'HELP': (self.cmd_help, STR_TABLE['help'][self.connection.cli_language]), - b'?': (self.cmd_shelp, STR_TABLE['cmd_shelp'][self.connection.cli_language]), - b'NAME': (self.cmd_set_name, STR_TABLE['cmd_help_set_name'][self.connection.cli_language]), - b'QTH': (self.cmd_set_qth, STR_TABLE['cmd_help_set_qth'][self.connection.cli_language]), - b'LOC': (self.cmd_set_loc, STR_TABLE['cmd_help_set_loc'][self.connection.cli_language]), - b'ZIP': (self.cmd_set_zip, STR_TABLE['cmd_help_set_zip'][self.connection.cli_language]), - b'PRMAIL': (self.cmd_set_pr_mail, STR_TABLE['cmd_help_set_prmail'][self.connection.cli_language]), - b'EMAIL': (self.cmd_set_e_mail, STR_TABLE['cmd_help_set_email'][self.connection.cli_language]), - b'WEB': (self.cmd_set_http, STR_TABLE['cmd_help_set_http'][self.connection.cli_language]), - b'USER': (self.cmd_user_db_detail, STR_TABLE['cmd_help_user_db'][self.connection.cli_language]), - b'UMLAUT': (self.cmd_umlaut, STR_TABLE['auto_text_encoding'][self.connection.cli_language]), b'INFO': (self.cmd_i, 'Info'), b'LINFO': (self.cmd_li, 'Long Info'), - b'LANG': (self.cmd_lang, STR_TABLE['cli_change_language'][self.connection.cli_language]), b'NEWS': (self.cmd_news, 'NEWS'), + b'VERSION': (self.cmd_ver, 'Version'), + b'USER': (self.cmd_user_db_detail, STR_TABLE['cmd_help_user_db'][self.connection.cli_language]), + b'DBNAME': (self.cmd_set_name, STR_TABLE['cmd_help_set_name'][self.connection.cli_language]), + b'DBQTH': (self.cmd_set_qth, STR_TABLE['cmd_help_set_qth'][self.connection.cli_language]), + b'DBLOC': (self.cmd_set_loc, STR_TABLE['cmd_help_set_loc'][self.connection.cli_language]), + b'DBZIP': (self.cmd_set_zip, STR_TABLE['cmd_help_set_zip'][self.connection.cli_language]), + b'DBPRMAIL': (self.cmd_set_pr_mail, STR_TABLE['cmd_help_set_prmail'][self.connection.cli_language]), + b'DBEMAIL': (self.cmd_set_e_mail, STR_TABLE['cmd_help_set_email'][self.connection.cli_language]), + b'DBWEB': (self.cmd_set_http, STR_TABLE['cmd_help_set_http'][self.connection.cli_language]), + b'LANG': (self.cmd_lang, STR_TABLE['cli_change_language'][self.connection.cli_language]), + b'UMLAUT': (self.cmd_umlaut, STR_TABLE['auto_text_encoding'][self.connection.cli_language]), b'POPT': (self.cmd_popt_banner, 'PoPT Banner'), + b'HELP': (self.cmd_help, STR_TABLE['help'][self.connection.cli_language]), + b'?': (self.cmd_shelp, STR_TABLE['cmd_shelp'][self.connection.cli_language]), + } self.str_cmd_exec = { @@ -1078,7 +1079,8 @@ def cmd_lcstatus(self): return ret def cmd_help(self): - ret = f"\r < {STR_TABLE['help'][self.connection.cli_language]} >\r" + # ret = f"\r < {STR_TABLE['help'][self.connection.cli_language]} >\r" + ret = "\r" """ c = 1 new_cmd = {} diff --git a/constant.py b/constant.py index e3492e52..bdc16ad3 100644 --- a/constant.py +++ b/constant.py @@ -3,7 +3,7 @@ https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python """ -VER = '2.98.14dev' +VER = '2.98.15' LANGUAGE = 0 # QUICK FIX """ 0 = German diff --git a/gui/guiMain.py b/gui/guiMain.py index 57e3300d..4a0468f3 100644 --- a/gui/guiMain.py +++ b/gui/guiMain.py @@ -983,58 +983,80 @@ def __init__(self, main_win): self.in_txt_win.grid(row=0, column=0, columnspan=12, sticky="nsew") ############## # Status Frame - self.status_name = Label(self._status_frame, text="", font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), - foreground=STAT_BAR_TXT_CLR, - bg=STAT_BAR_CLR) - self.status_name.grid(row=1, column=1, sticky="nsew") - - self.status_status = Label(self._status_frame, text="", + self.status_name_var = tk.StringVar(self._status_frame) + self.status_status_var = tk.StringVar(self._status_frame) + self.status_unack_var = tk.StringVar(self._status_frame) + self.status_vs_var = tk.StringVar(self._status_frame) + self.status_n2_var = tk.StringVar(self._status_frame) + self.status_t1_var = tk.StringVar(self._status_frame) + self.status_t2_var = tk.StringVar(self._status_frame) + self.status_rtt_var = tk.StringVar(self._status_frame) + self.status_t3_var = tk.StringVar(self._status_frame) + Label(self._status_frame, + textvariable=self.status_name_var, + font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), + foreground=STAT_BAR_TXT_CLR, + bg=STAT_BAR_CLR + ).grid(row=1, column=1, sticky="nsew") + + self.status_status = Label(self._status_frame, + textvariable=self.status_status_var, font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), bg=STAT_BAR_CLR, - foreground=STAT_BAR_TXT_CLR) + foreground=STAT_BAR_TXT_CLR + ) self.status_status.grid(row=1, column=2, sticky="nsew") - self.status_unack = Label(self._status_frame, text="", + self.status_unack = Label(self._status_frame, + textvariable=self.status_unack_var, foreground=STAT_BAR_TXT_CLR, font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), - bg=STAT_BAR_CLR) + bg=STAT_BAR_CLR + ) self.status_unack.grid(row=1, column=3, sticky="nsew") - self.status_vs = Label(self._status_frame, text="", - font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), - bg=STAT_BAR_CLR, - foreground=STAT_BAR_TXT_CLR) - self.status_vs.grid(row=1, column=4, sticky="nsew") + Label(self._status_frame, + textvariable=self.status_vs_var, + font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), + bg=STAT_BAR_CLR, + foreground=STAT_BAR_TXT_CLR + ).grid(row=1, column=4, sticky="nsew") - self.status_n2 = Label(self._status_frame, text="", + self.status_n2 = Label(self._status_frame, + textvariable=self.status_n2_var, font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), bg=STAT_BAR_CLR, - foreground=STAT_BAR_TXT_CLR) + foreground=STAT_BAR_TXT_CLR + ) self.status_n2.grid(row=1, column=7, sticky="nsew") - self.status_t1 = Label(self._status_frame, text="", - font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), - bg=STAT_BAR_CLR, - foreground=STAT_BAR_TXT_CLR) - self.status_t1.grid(row=1, column=8, sticky="nsew") + Label(self._status_frame, + textvariable=self.status_t1_var, + font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), + bg=STAT_BAR_CLR, + foreground=STAT_BAR_TXT_CLR + ).grid(row=1, column=8, sticky="nsew") # PARM T2 - self.status_t2 = Label(self._status_frame, text="", - font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), - bg=STAT_BAR_CLR, - foreground=STAT_BAR_TXT_CLR) - self.status_t2.grid(row=1, column=5, sticky="nsew") + Label(self._status_frame, + textvariable=self.status_t2_var, + font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), + bg=STAT_BAR_CLR, + foreground=STAT_BAR_TXT_CLR + ).grid(row=1, column=5, sticky="nsew") # RTT - self.status_rtt = Label(self._status_frame, text="", - font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), - bg=STAT_BAR_CLR, - foreground=STAT_BAR_TXT_CLR) - self.status_rtt.grid(row=1, column=6, sticky="nsew") - - self.status_t3 = Label(self._status_frame, text="", - font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), - bg=STAT_BAR_CLR, - foreground=STAT_BAR_TXT_CLR) - self.status_t3.grid(row=1, column=9, sticky="nsew") + Label(self._status_frame, + textvariable=self.status_rtt_var, + font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), + bg=STAT_BAR_CLR, + foreground=STAT_BAR_TXT_CLR + ).grid(row=1, column=6, sticky="nsew") + + Label(self._status_frame, + textvariable=self.status_t3_var, + font=(FONT_STAT_BAR, TEXT_SIZE_STATUS), + bg=STAT_BAR_CLR, + foreground=STAT_BAR_TXT_CLR + ).grid(row=1, column=9, sticky="nsew") # Checkbox RX-BEEP self.rx_beep_var = tk.IntVar() self.rx_beep_box = Checkbutton(self._status_frame, @@ -1046,7 +1068,7 @@ def __init__(self, main_win): onvalue=1, offvalue=0, foreground=STAT_BAR_TXT_CLR, variable=self.rx_beep_var, - command=self.chk_rx_beep + command=self._chk_rx_beep ) self.rx_beep_box.grid(row=1, column=10, sticky="nsew") # TODO Checkbox Time Stamp @@ -1143,7 +1165,7 @@ def __init__(self, main_win): self._out_frame, self.stat_info_typ_var, *opt, - command=self.set_stat_typ + command=self._set_stat_typ ) stat_typ.configure( background="#0ed8c3", @@ -1194,7 +1216,7 @@ def __init__(self, main_win): self._out_frame, self.stat_info_encoding_var, *opt, - command=self.change_txt_encoding + command=self._change_txt_encoding ) txt_encoding_ent.configure( background="steel blue", @@ -1236,10 +1258,12 @@ def update_status_win(self): station = self._main_class.get_conn(self._main_class.channel_index) if station: _from_call = station.ax25_out_frame.from_call.call_str + """ _via_calls = '' for _via in station.ax25_out_frame.via_calls: # via: Call _via_calls += _via.call_str + ' ' + """ _status = station.zustand_tab[station.zustand_exec.stat_index][1] # uid = station.ax25_out_frame.addr_uid _n2 = station.n2 @@ -1253,61 +1277,57 @@ def update_status_win(self): _t2_text = f"T2: {int(station.parm_T2 * 1000)}A" else: _t2_text = f"T2: {int(station.parm_T2 * 1000)}" - - if self.status_name.cget('text') != _from_call: - self.status_name.configure(text=_from_call) - if self.status_status.cget('text') != _status: + if self.status_name_var.get() != _from_call: + self.status_name_var.set(_from_call) + if self.status_status_var.get() != _status: _status_bg = STATUS_BG[_status] - self.status_status.configure(text=_status, bg=_status_bg) - - if len(station.tx_buf_unACK.keys()): - if self.status_unack.cget('bg') != 'yellow': - self.status_unack.configure(bg='yellow') - else: - if self.status_unack.cget('bg') != 'green': - self.status_unack.configure(bg='green') - if self.status_unack.cget('text') != _unAck: - self.status_unack.configure(text=_unAck) - - if self.status_vs.cget('text') != _vs_vr: - self.status_vs.configure(text=_vs_vr) - - if _n2 > 4: - if self.status_n2.cget('bg') != 'yellow': - self.status_n2.configure(bg='yellow') - elif _n2 > 10: - if self.status_n2.cget('bg') != 'orange': - self.status_n2.configure(bg='orange') - else: - if self.status_n2.cget('bg') != STAT_BAR_CLR: - self.status_n2.configure(bg=STAT_BAR_CLR) - - if self.status_n2.cget('text') != _n2_text: - self.status_n2.configure(text=_n2_text) - - if self.status_t1.cget('text') != _t1_text: - self.status_t1.configure(text=_t1_text) - - if self.status_t2.cget('text') != _t2_text: - self.status_t2.configure(text=_t2_text) - - if self.status_rtt.cget('text') != _rtt_text: - self.status_rtt.configure(text=_rtt_text) - - if self.status_t3.cget('text') != _t3_text: - self.status_t3.configure(text=_t3_text) + self.status_status_var.set(_status) + self.status_status.configure(bg=_status_bg) + if self.status_unack_var.get() != _unAck: + self.status_unack_var.set(_unAck) + if len(station.tx_buf_unACK.keys()): + if self.status_unack.cget('bg') != 'yellow': + self.status_unack.configure(bg='yellow') + else: + if self.status_unack.cget('bg') != 'green': + self.status_unack.configure(bg='green') + if self.status_vs_var.get() != _vs_vr: + self.status_vs_var.set(_vs_vr) + if self.status_n2_var.get() != _n2_text: + self.status_n2_var.set(_n2_text) + if _n2 > 4: + if self.status_n2.cget('bg') != 'yellow': + self.status_n2.configure(bg='yellow') + elif _n2 > 10: + if self.status_n2.cget('bg') != 'orange': + self.status_n2.configure(bg='orange') + else: + if self.status_n2.cget('bg') != STAT_BAR_CLR: + self.status_n2.configure(bg=STAT_BAR_CLR) + if self.status_t1_var.get() != _t1_text: + self.status_t1_var.set(_t1_text) + if self.status_t2_var.get() != _t2_text: + self.status_t2_var.set(_t2_text) + if self.status_rtt_var.get() != _rtt_text: + self.status_rtt_var.set(_rtt_text) + if self.status_t3_var.get() != _t3_text: + self.status_t3_var.set(_t3_text) else: if self.status_status.cget('text') or self.status_status.cget('bg') != STAT_BAR_CLR: - self.status_name.configure(text="", bg=STAT_BAR_CLR) - self.status_status.configure(text="", bg=STAT_BAR_CLR) - self.status_unack.configure(text="", bg=STAT_BAR_CLR) - self.status_vs.configure(text="", bg=STAT_BAR_CLR) - self.status_n2.configure(text="", bg=STAT_BAR_CLR) - self.status_t1.configure(text="", bg=STAT_BAR_CLR) - self.status_t2.configure(text="", bg=STAT_BAR_CLR) - self.status_t3.configure(text="", bg=STAT_BAR_CLR) - self.status_rtt.configure(text="", bg=STAT_BAR_CLR) + # self.status_name.configure(text="", bg=STAT_BAR_CLR) + self.status_name_var.set('') + self.status_status.configure(bg=STAT_BAR_CLR) + self.status_status_var.set('') + self.status_unack.configure(bg=STAT_BAR_CLR) + self.status_unack_var.set('') + self.status_vs_var.set('') + self.status_n2.configure(bg=STAT_BAR_CLR) + self.status_n2_var.set('') + self.status_t1_var.set('') + self.status_t2_var.set('') + self.status_t3_var.set('') + self.status_rtt_var.set('') def switch_mon_mode(self): # TODO Save Stretched Positions @@ -1329,7 +1349,7 @@ def switch_mon_mode(self): self._pw.remove(self._out_frame) # self.pw.configure(height=837) - def chk_rx_beep(self): + def _chk_rx_beep(self): _rx_beep_check = self.rx_beep_var.get() if _rx_beep_check: if self.rx_beep_box.cget('bg') != 'green': @@ -1349,7 +1369,7 @@ def chk_timestamp(self): self.ts_box_box.configure(bg=STAT_BAR_CLR, activebackground=STAT_BAR_CLR) self._main_class.get_ch_param().timestamp_opt = _ts_check - def set_stat_typ(self, event=None): + def _set_stat_typ(self, event=None): conn = self._main_class.get_conn() if conn: db_ent = conn.user_db_ent @@ -1358,7 +1378,7 @@ def set_stat_typ(self, event=None): else: self.stat_info_typ_var.set('-----') - def change_txt_encoding(self, event=None, enc=''): + def _change_txt_encoding(self, event=None, enc=''): conn = self._main_class.get_conn() if conn: db_ent = conn.user_db_ent @@ -1374,29 +1394,30 @@ class ChBtnFrm: def __init__(self, main_win): self._main_class = main_win self._ch_btn_blink_timer = time.time() - self._ch_btn_frame = tk.Frame(self._main_class.main_win, width=500, height=10) + _ch_btn_frame = tk.Frame(self._main_class.main_win, width=500, height=10) + _ch_btn_frame.grid(row=2, column=0, columnspan=1, sticky="nsew") _btn_font = ("fixedsys", 8,) - self._ch_btn_frame.columnconfigure(1, minsize=50, weight=1) - self._ch_btn_frame.columnconfigure(2, minsize=50, weight=1) - self._ch_btn_frame.columnconfigure(3, minsize=50, weight=1) - self._ch_btn_frame.columnconfigure(4, minsize=50, weight=1) - self._ch_btn_frame.columnconfigure(5, minsize=50, weight=1) - self._ch_btn_frame.columnconfigure(6, minsize=50, weight=1) - self._ch_btn_frame.columnconfigure(7, minsize=50, weight=1) - self._ch_btn_frame.columnconfigure(8, minsize=50, weight=1) - self._ch_btn_frame.columnconfigure(9, minsize=50, weight=1) - self._ch_btn_frame.columnconfigure(10, minsize=50, weight=1) + _ch_btn_frame.columnconfigure(1, minsize=50, weight=1) + _ch_btn_frame.columnconfigure(2, minsize=50, weight=1) + _ch_btn_frame.columnconfigure(3, minsize=50, weight=1) + _ch_btn_frame.columnconfigure(4, minsize=50, weight=1) + _ch_btn_frame.columnconfigure(5, minsize=50, weight=1) + _ch_btn_frame.columnconfigure(6, minsize=50, weight=1) + _ch_btn_frame.columnconfigure(7, minsize=50, weight=1) + _ch_btn_frame.columnconfigure(8, minsize=50, weight=1) + _ch_btn_frame.columnconfigure(9, minsize=50, weight=1) + _ch_btn_frame.columnconfigure(10, minsize=50, weight=1) # self.ch_btn_frame.grid(row=1, column=1, sticky="nsew") - ch_1_var = tk.StringVar(self._ch_btn_frame) - ch_2_var = tk.StringVar(self._ch_btn_frame) - ch_3_var = tk.StringVar(self._ch_btn_frame) - ch_4_var = tk.StringVar(self._ch_btn_frame) - ch_5_var = tk.StringVar(self._ch_btn_frame) - ch_6_var = tk.StringVar(self._ch_btn_frame) - ch_7_var = tk.StringVar(self._ch_btn_frame) - ch_8_var = tk.StringVar(self._ch_btn_frame) - ch_9_var = tk.StringVar(self._ch_btn_frame) - ch_10_var = tk.StringVar(self._ch_btn_frame) + ch_1_var = tk.StringVar(_ch_btn_frame) + ch_2_var = tk.StringVar(_ch_btn_frame) + ch_3_var = tk.StringVar(_ch_btn_frame) + ch_4_var = tk.StringVar(_ch_btn_frame) + ch_5_var = tk.StringVar(_ch_btn_frame) + ch_6_var = tk.StringVar(_ch_btn_frame) + ch_7_var = tk.StringVar(_ch_btn_frame) + ch_8_var = tk.StringVar(_ch_btn_frame) + ch_9_var = tk.StringVar(_ch_btn_frame) + ch_10_var = tk.StringVar(_ch_btn_frame) ch_1_var.set('1') ch_2_var.set('2') ch_3_var.set('3') @@ -1407,25 +1428,25 @@ def __init__(self, main_win): ch_8_var.set('8') ch_9_var.set('9') ch_10_var.set('10') - ch_button1 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_1_var, bg="red", + ch_button1 = tk.Button(_ch_btn_frame, font=_btn_font, textvariable=ch_1_var, bg="red", command=lambda: self._main_class.switch_channel(1)) - ch_button2 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_2_var, bg="red", + ch_button2 = tk.Button(_ch_btn_frame, font=_btn_font, textvariable=ch_2_var, bg="red", command=lambda: self._main_class.switch_channel(2)) - ch_button3 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_3_var, bg="red", + ch_button3 = tk.Button(_ch_btn_frame, font=_btn_font, textvariable=ch_3_var, bg="red", command=lambda: self._main_class.switch_channel(3)) - ch_button4 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_4_var, bg="red", + ch_button4 = tk.Button(_ch_btn_frame, font=_btn_font, textvariable=ch_4_var, bg="red", command=lambda: self._main_class.switch_channel(4)) - ch_button5 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_5_var, bg="red", + ch_button5 = tk.Button(_ch_btn_frame, font=_btn_font, textvariable=ch_5_var, bg="red", command=lambda: self._main_class.switch_channel(5)) - ch_button6 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_6_var, bg="red", + ch_button6 = tk.Button(_ch_btn_frame, font=_btn_font, textvariable=ch_6_var, bg="red", command=lambda: self._main_class.switch_channel(6)) - ch_button7 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_7_var, bg="red", + ch_button7 = tk.Button(_ch_btn_frame, font=_btn_font, textvariable=ch_7_var, bg="red", command=lambda: self._main_class.switch_channel(7)) - ch_button8 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_8_var, bg="red", + ch_button8 = tk.Button(_ch_btn_frame, font=_btn_font, textvariable=ch_8_var, bg="red", command=lambda: self._main_class.switch_channel(8)) - ch_button9 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_9_var, bg="red", + ch_button9 = tk.Button(_ch_btn_frame, font=_btn_font, textvariable=ch_9_var, bg="red", command=lambda: self._main_class.switch_channel(9)) - ch_button10 = tk.Button(self._ch_btn_frame, font=_btn_font, textvariable=ch_10_var, bg="red", + ch_button10 = tk.Button(_ch_btn_frame, font=_btn_font, textvariable=ch_10_var, bg="red", command=lambda: self._main_class.switch_channel(10)) ch_button1.grid(row=1, column=1, sticky="nsew") ch_button2.grid(row=1, column=2, sticky="nsew") @@ -1598,7 +1619,7 @@ def __init__(self): ######################### # Channel Buttons self._ch_btn = ChBtnFrm(self) - self._ch_btn._ch_btn_frame.grid(row=2, column=0, columnspan=1, sticky="nsew") + # self._ch_btn._ch_btn_frame.grid(row=2, column=0, columnspan=1, sticky="nsew") ######################### # Tabbed Frame right self._side_btn_frame_top = tk.Frame(self.main_win, width=200, height=540) @@ -1704,7 +1725,8 @@ def _init_vars(self): self._parm_rx_beep_cooldown = 2 # s # Tasker Timings self._loop_delay = 250 # ms - self._parm_non_prio_task_timer = 0.5 # s + self._parm_non_prio_task_timer = 0.25 # s + self._prio_task_flip = True self._parm_non_non_prio_task_timer = 1 # s self._parm_non_non_non_prio_task_timer = 5 # s self._parm_test_task_timer = 60 # 5 # s @@ -2318,12 +2340,12 @@ def _tasker(self): # MAINLOOP if self._is_closing: self._tasker_quit() else: - # self._tasker_prio() - self._tasker_05_sec() + self._tasker_prio() + # self._tasker_05_sec() self._tasker_1_sec() self._tasker_5_sec() # self._tasker_tester() - self.main_win.update_idletasks() + # self.main_win.update_idletasks() self.main_win.after(self._loop_delay, self._tasker) @staticmethod @@ -2333,23 +2355,26 @@ def _tasker_quit(): logging.info('Closing GUI: Done.') def _tasker_prio(self): - """ Prio Tasks """ - pass - - def _tasker_05_sec(self): - """ 0.5 Sec """ - if time.time() > self._non_prio_task_timer: - self._non_prio_task_timer = time.time() + self._parm_non_prio_task_timer - ##################### + """ Prio Tasks 250 ms each flip """ + if self._prio_task_flip: self._aprs_task() self._monitor_task() self._update_qso_win() + else: self._txt_win.update_status_win() self.change_conn_btn() if self.setting_sound: self._rx_beep_sound() if self.setting_sprech: self._check_sprech_ch_buf() + self._prio_task_flip = not self._prio_task_flip + + def _tasker_05_sec(self): + """ 0.5 Sec """ + if time.time() > self._non_prio_task_timer: + self._non_prio_task_timer = time.time() + self._parm_non_prio_task_timer + ##################### + pass def _tasker_1_sec(self): """ 1 Sec """