168 lines
4.7 KiB
C#
168 lines
4.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Windows.Input;
|
|
using AmebaPro3_ControlPanel.Services.Uart;
|
|
using AmebaPro3_ControlPanel.Utilities;
|
|
|
|
namespace AmebaPro3_ControlPanel.ViewModels;
|
|
|
|
public class UartConsoleViewModel : ConsolePanelViewModel
|
|
{
|
|
private string? _selectedPort;
|
|
private int _baudRate;
|
|
private readonly PythonUartSession _uartSession;
|
|
private bool _isConnecting;
|
|
|
|
public UartConsoleViewModel(string title, int defaultBaudRate) : base(title)
|
|
{
|
|
_baudRate = defaultBaudRate;
|
|
_uartSession = new PythonUartSession(GetUartBridgePath(), SynchronizationContext.Current);
|
|
_uartSession.LineReceived += line => LogLines.Add(line);
|
|
_uartSession.ErrorReceived += line => LogLines.Add($"[UART ERROR] {line}");
|
|
_uartSession.Exited += OnSessionExited;
|
|
|
|
ConnectCommand = new RelayCommand(_ => ConnectAsync(), _ => !IsConnected && !_isConnecting && !string.IsNullOrWhiteSpace(SelectedPort));
|
|
DisconnectCommand = new RelayCommand(_ => Disconnect(), _ => IsConnected);
|
|
OpenTeraTermCommand = new RelayCommand(_ => OpenTeraTerm(), _ => !string.IsNullOrWhiteSpace(SelectedPort));
|
|
}
|
|
|
|
public ObservableCollection<string> AvailablePorts { get; } = new();
|
|
|
|
public string? SelectedPort
|
|
{
|
|
get => _selectedPort;
|
|
set
|
|
{
|
|
if (SetProperty(ref _selectedPort, value))
|
|
{
|
|
(ConnectCommand as RelayCommand)?.RaiseCanExecuteChanged();
|
|
(OpenTeraTermCommand as RelayCommand)?.RaiseCanExecuteChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
public int BaudRate
|
|
{
|
|
get => _baudRate;
|
|
set => SetProperty(ref _baudRate, value);
|
|
}
|
|
|
|
public ICommand ConnectCommand { get; }
|
|
|
|
public ICommand DisconnectCommand { get; }
|
|
|
|
public ICommand OpenTeraTermCommand { get; }
|
|
|
|
public void SetPorts(IEnumerable<string> ports)
|
|
{
|
|
AvailablePorts.Clear();
|
|
foreach (var port in ports)
|
|
{
|
|
AvailablePorts.Add(port);
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(SelectedPort))
|
|
{
|
|
SelectedPort = AvailablePorts.FirstOrDefault();
|
|
}
|
|
}
|
|
|
|
protected override void SendCurrentCommand(bool addToHistory)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(CurrentCommand))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var command = CurrentCommand.Trim();
|
|
base.SendCurrentCommand(addToHistory);
|
|
|
|
if (IsConnected)
|
|
{
|
|
_ = _uartSession.SendAsync(command);
|
|
}
|
|
else
|
|
{
|
|
LogLines.Add("[UART] Not connected.");
|
|
}
|
|
}
|
|
|
|
private async void ConnectAsync()
|
|
{
|
|
if (_isConnecting || string.IsNullOrWhiteSpace(SelectedPort))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_isConnecting = true;
|
|
(ConnectCommand as RelayCommand)?.RaiseCanExecuteChanged();
|
|
LogLines.Add($"[UART] Connecting to {SelectedPort} @ {BaudRate}...");
|
|
|
|
var started = await _uartSession.StartAsync(SelectedPort, BaudRate);
|
|
if (started)
|
|
{
|
|
IsConnected = true;
|
|
LogLines.Add($"[UART] Connected to {SelectedPort} @ {BaudRate}.");
|
|
}
|
|
else
|
|
{
|
|
LogLines.Add("[UART] Failed to start session. Ensure Python + pyserial are installed.");
|
|
}
|
|
|
|
_isConnecting = false;
|
|
(DisconnectCommand as RelayCommand)?.RaiseCanExecuteChanged();
|
|
(ConnectCommand as RelayCommand)?.RaiseCanExecuteChanged();
|
|
}
|
|
|
|
private void Disconnect()
|
|
{
|
|
_ = DisconnectAsync();
|
|
}
|
|
|
|
private async System.Threading.Tasks.Task DisconnectAsync()
|
|
{
|
|
IsConnected = false;
|
|
_isConnecting = false;
|
|
(DisconnectCommand as RelayCommand)?.RaiseCanExecuteChanged();
|
|
(ConnectCommand as RelayCommand)?.RaiseCanExecuteChanged();
|
|
|
|
await _uartSession.StopAsync();
|
|
LogLines.Add("[UART] Disconnected.");
|
|
}
|
|
|
|
private void OnSessionExited()
|
|
{
|
|
if (!IsConnected)
|
|
{
|
|
return;
|
|
}
|
|
|
|
IsConnected = false;
|
|
_isConnecting = false;
|
|
LogLines.Add("[UART] Session closed.");
|
|
(DisconnectCommand as RelayCommand)?.RaiseCanExecuteChanged();
|
|
(ConnectCommand as RelayCommand)?.RaiseCanExecuteChanged();
|
|
}
|
|
|
|
private void OpenTeraTerm()
|
|
{
|
|
if (TeraTermLauncher.TryLaunch(SelectedPort, BaudRate, out var message))
|
|
{
|
|
LogLines.Add($"[UART] {message}");
|
|
}
|
|
else
|
|
{
|
|
LogLines.Add($"[UART] {message}");
|
|
}
|
|
}
|
|
|
|
private static string GetUartBridgePath()
|
|
{
|
|
return Path.Combine(AppContext.BaseDirectory, "Scripts", "uart_bridge.py");
|
|
}
|
|
}
|