Working serial command sender
This commit is contained in:
@@ -8,6 +8,9 @@ import dataflux.ui.routines
|
|||||||
|
|
||||||
from dataflux.state import AppState
|
from dataflux.state import AppState
|
||||||
from dataflux.tags import (
|
from dataflux.tags import (
|
||||||
|
BUTTON_SERIAL_CONSOLE_SEND,
|
||||||
|
INPUT_SERIAL_CONSOLE,
|
||||||
|
TEXT_SERIAL_CONSOLE,
|
||||||
WINDOW_LORA_CONNECTION_MENU,
|
WINDOW_LORA_CONNECTION_MENU,
|
||||||
WINDOW_LORA_CONNECTION_MENU_COMBO,
|
WINDOW_LORA_CONNECTION_MENU_COMBO,
|
||||||
WINDOW_SERIAL_CONNECTION_MENU,
|
WINDOW_SERIAL_CONNECTION_MENU,
|
||||||
@@ -27,3 +30,10 @@ def connection_window_connect_serial(sender, app_data, user_data: AppState) -> N
|
|||||||
dataflux.services.serial.connect_serial(user_data, device)
|
dataflux.services.serial.connect_serial(user_data, device)
|
||||||
dataflux.ui.routines.update_global_connection_status(user_data)
|
dataflux.ui.routines.update_global_connection_status(user_data)
|
||||||
dpg.hide_item(WINDOW_SERIAL_CONNECTION_MENU)
|
dpg.hide_item(WINDOW_SERIAL_CONNECTION_MENU)
|
||||||
|
|
||||||
|
|
||||||
|
def serial_console_button_send(sender, app_data, user_data: AppState) -> None:
|
||||||
|
text = dpg.get_value(INPUT_SERIAL_CONSOLE)
|
||||||
|
dpg.set_value(INPUT_SERIAL_CONSOLE, "")
|
||||||
|
user_data.serial_send_queue.put(text)
|
||||||
|
print("Put into send queue: " + text)
|
||||||
|
|||||||
@@ -51,10 +51,10 @@ def connect_serial(state: AppState, device: str) -> None:
|
|||||||
state.serial_port.close()
|
state.serial_port.close()
|
||||||
state.serial_port = None
|
state.serial_port = None
|
||||||
|
|
||||||
state.serial_port = Serial(port=device, baudrate=115200)
|
state.serial_port = Serial(
|
||||||
state.serial_thread = Thread(
|
port=device, baudrate=115200, timeout=0.05, write_timeout=0.1
|
||||||
target=serial_reader_worker, args=(state,), daemon=True
|
|
||||||
)
|
)
|
||||||
|
state.serial_thread = Thread(target=serial_worker, args=(state,), daemon=True)
|
||||||
state.serial_status_thread = Thread(
|
state.serial_status_thread = Thread(
|
||||||
target=serial_status_worker, args=(state,), daemon=True
|
target=serial_status_worker, args=(state,), daemon=True
|
||||||
)
|
)
|
||||||
@@ -87,7 +87,7 @@ def lora_status_worker(state: AppState) -> None:
|
|||||||
dataflux.ui.routines.status.flash_status_connection_status(duration)
|
dataflux.ui.routines.status.flash_status_connection_status(duration)
|
||||||
|
|
||||||
|
|
||||||
def serial_reader_worker(state: AppState) -> None:
|
def serial_worker(state: AppState) -> None:
|
||||||
while state.serial_thread_running:
|
while state.serial_thread_running:
|
||||||
port = state.serial_port
|
port = state.serial_port
|
||||||
if port is None:
|
if port is None:
|
||||||
@@ -103,6 +103,16 @@ def serial_reader_worker(state: AppState) -> None:
|
|||||||
if line:
|
if line:
|
||||||
text = line.decode("utf-8", errors="replace")
|
text = line.decode("utf-8", errors="replace")
|
||||||
state.serial_data_queue.put(text)
|
state.serial_data_queue.put(text)
|
||||||
|
|
||||||
|
if port.writable():
|
||||||
|
try:
|
||||||
|
data: str = state.serial_send_queue.get_nowait()
|
||||||
|
except Empty:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
state.serial_data_queue.put(data + "\n")
|
||||||
|
port.write(data.encode("utf-8"))
|
||||||
|
print("Wrote data: " + data)
|
||||||
disconnect_serial(state)
|
disconnect_serial(state)
|
||||||
dataflux.ui.routines.update_global_connection_status(state)
|
dataflux.ui.routines.update_global_connection_status(state)
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class AppState:
|
|||||||
serial_port: Serial | None = None
|
serial_port: Serial | None = None
|
||||||
serial_thread: Thread | None = None
|
serial_thread: Thread | None = None
|
||||||
serial_data_queue: Queue | None = field(default_factory=Queue)
|
serial_data_queue: Queue | None = field(default_factory=Queue)
|
||||||
|
serial_send_queue: Queue | None = field(default_factory=Queue)
|
||||||
serial_thread_running: bool = False
|
serial_thread_running: bool = False
|
||||||
|
|
||||||
telemetry_thread: Thread | None = None
|
telemetry_thread: Thread | None = None
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ WINDOW_LORA_CONNECTION_MENU_COMBO: str = "window_lora_connection_menu_combo"
|
|||||||
WINDOW_SERIAL_CONNECTION_MENU_COMBO: str = "window_serial_connection_menu_combo"
|
WINDOW_SERIAL_CONNECTION_MENU_COMBO: str = "window_serial_connection_menu_combo"
|
||||||
WINDOW_FILE_DIALOG_DUMP_BUFFERS: str = "window_file_dialog_dump_buffers"
|
WINDOW_FILE_DIALOG_DUMP_BUFFERS: str = "window_file_dialog_dump_buffers"
|
||||||
|
|
||||||
|
CHILD_WINDOW_SERIAL_CONSOLE: str = "child_window_serial_console"
|
||||||
|
|
||||||
STATUS_LORA_STATUS_BOX: str = "status_lora_status_box"
|
STATUS_LORA_STATUS_BOX: str = "status_lora_status_box"
|
||||||
STATUS_LORA_STATUS_TEXT: str = "status_lora_status_text"
|
STATUS_LORA_STATUS_TEXT: str = "status_lora_status_text"
|
||||||
STATUS_SERIAL_STATUS_BOX: str = "status_serial_status_box"
|
STATUS_SERIAL_STATUS_BOX: str = "status_serial_status_box"
|
||||||
@@ -30,6 +32,10 @@ PAGE_SERIAL_CONSOLE: str = "page_serial_console"
|
|||||||
|
|
||||||
TEXT_SERIAL_CONSOLE: str = "text_serial_console"
|
TEXT_SERIAL_CONSOLE: str = "text_serial_console"
|
||||||
|
|
||||||
|
BUTTON_SERIAL_CONSOLE_SEND: str = "button_serial_console_send"
|
||||||
|
|
||||||
|
INPUT_SERIAL_CONSOLE: str = "input_serial_console"
|
||||||
|
|
||||||
SUB_PAGE_DATA_GRAPHS: str = "sub_page_data_graphs"
|
SUB_PAGE_DATA_GRAPHS: str = "sub_page_data_graphs"
|
||||||
SUB_PAGE_MAP: str = "sub_page_map"
|
SUB_PAGE_MAP: str = "sub_page_map"
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,19 @@
|
|||||||
|
|
||||||
import dearpygui.dearpygui as dpg
|
import dearpygui.dearpygui as dpg
|
||||||
|
|
||||||
from dataflux.tags import TEXT_SERIAL_CONSOLE
|
from dataflux.tags import CHILD_WINDOW_SERIAL_CONSOLE, TEXT_SERIAL_CONSOLE
|
||||||
|
|
||||||
|
|
||||||
def append_text_to_console(text: str) -> None:
|
def append_text_to_console(text: str) -> None:
|
||||||
old = dpg.get_value(TEXT_SERIAL_CONSOLE)
|
old = dpg.get_value(TEXT_SERIAL_CONSOLE)
|
||||||
dpg.set_value(TEXT_SERIAL_CONSOLE, old + text)
|
dpg.set_value(TEXT_SERIAL_CONSOLE, old + text)
|
||||||
|
|
||||||
|
def scroll_to_bottom() -> None:
|
||||||
|
dpg.set_y_scroll(
|
||||||
|
CHILD_WINDOW_SERIAL_CONSOLE,
|
||||||
|
dpg.get_y_scroll_max(CHILD_WINDOW_SERIAL_CONSOLE),
|
||||||
|
)
|
||||||
|
|
||||||
|
frame = dpg.get_frame_count()
|
||||||
|
dpg.set_frame_callback(frame + 1, scroll_to_bottom)
|
||||||
|
dpg.set_frame_callback(frame + 2, scroll_to_bottom)
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import dataflux.callbacks.serial
|
|||||||
|
|
||||||
from dataflux.state import AppState
|
from dataflux.state import AppState
|
||||||
from dataflux.tags import (
|
from dataflux.tags import (
|
||||||
|
BUTTON_SERIAL_CONSOLE_SEND,
|
||||||
|
CHILD_WINDOW_SERIAL_CONSOLE,
|
||||||
GRAPH_SERIES_SPEED,
|
GRAPH_SERIES_SPEED,
|
||||||
GRAPH_SERIES_TENG,
|
GRAPH_SERIES_TENG,
|
||||||
GRAPH_SERIES_VBAT,
|
GRAPH_SERIES_VBAT,
|
||||||
@@ -17,6 +19,7 @@ from dataflux.tags import (
|
|||||||
GRAPH_Y_AXIS_SPEED,
|
GRAPH_Y_AXIS_SPEED,
|
||||||
GRAPH_Y_AXIS_TENG,
|
GRAPH_Y_AXIS_TENG,
|
||||||
GRAPH_Y_AXIS_VBAT,
|
GRAPH_Y_AXIS_VBAT,
|
||||||
|
INPUT_SERIAL_CONSOLE,
|
||||||
LIVE_DATA_TENG_VALUE,
|
LIVE_DATA_TENG_VALUE,
|
||||||
LIVE_DATA_UTC_TIME_VALUE,
|
LIVE_DATA_UTC_TIME_VALUE,
|
||||||
LIVE_DATA_VBAT_VALUE,
|
LIVE_DATA_VBAT_VALUE,
|
||||||
@@ -286,6 +289,7 @@ def build_windows(state: AppState) -> None:
|
|||||||
|
|
||||||
with dpg.group(tag=PAGE_SERIAL_CONSOLE, show=False):
|
with dpg.group(tag=PAGE_SERIAL_CONSOLE, show=False):
|
||||||
with dpg.child_window(
|
with dpg.child_window(
|
||||||
|
tag=CHILD_WINDOW_SERIAL_CONSOLE,
|
||||||
width=-1,
|
width=-1,
|
||||||
height=-40,
|
height=-40,
|
||||||
border=True,
|
border=True,
|
||||||
@@ -293,8 +297,14 @@ def build_windows(state: AppState) -> None:
|
|||||||
):
|
):
|
||||||
dpg.add_text(tag=TEXT_SERIAL_CONSOLE, wrap=0)
|
dpg.add_text(tag=TEXT_SERIAL_CONSOLE, wrap=0)
|
||||||
with dpg.group(horizontal=True):
|
with dpg.group(horizontal=True):
|
||||||
dpg.add_input_text(width=-100)
|
dpg.add_input_text(tag=INPUT_SERIAL_CONSOLE, width=-100)
|
||||||
dpg.add_button(label="Send", width=100)
|
dpg.add_button(
|
||||||
|
tag=BUTTON_SERIAL_CONSOLE_SEND,
|
||||||
|
label="Send",
|
||||||
|
width=100,
|
||||||
|
callback=dataflux.callbacks.serial.serial_console_button_send,
|
||||||
|
user_data=state,
|
||||||
|
)
|
||||||
|
|
||||||
with dpg.theme(tag=THEME_STATUS_CONNECTED):
|
with dpg.theme(tag=THEME_STATUS_CONNECTED):
|
||||||
with dpg.theme_component(dpg.mvChildWindow):
|
with dpg.theme_component(dpg.mvChildWindow):
|
||||||
|
|||||||
Reference in New Issue
Block a user