// ViewModels/ConfigConexaoViewModel.cs using System; using System.ComponentModel; using System.Windows.Input; using System.Windows.Threading; using OperationControl.Helpers; using OperationControl.Models; using Brush = System.Windows.Media.Brush; using Brushes = System.Windows.Media.Brushes; namespace OperationControl.ViewModels { public class ConfigConexaoViewModel : INotifyPropertyChanged { public event Action SolicitarConfigRede; private readonly DispatcherTimer _timerGnss; public ConfigConexaoViewModel() { AbrirConfigRedeCommand = new RelayCommand(_ => AbrirConfigRede()); AbrirDetalhesGnssCommand = new RelayCommand(_ => AbrirDetalhesGnss()); SelecionarModoAutomaticoCommand = new RelayCommand(_ => TipoOperacaoSelecionado = ModoOperacao.Automatico); SelecionarModoManualCommand = new RelayCommand(_ => TipoOperacaoSelecionado = ModoOperacao.Manual); // aqui você já pode chamar um serviço real depois CarregarStatusInicial(); _timerGnss = new DispatcherTimer(); _timerGnss.Interval = TimeSpan.FromMilliseconds(800); // 0.8s fica responsivo _timerGnss.Tick += (_, __) => AtualizarStatusGnss(); _timerGnss.Start(); } // ====== PROPRIEDADES DE MODO DE OPERACAO ====== private ModoOperacao _tipoOperacaoSelecionado = ModoOperacao.Automatico; public ModoOperacao TipoOperacaoSelecionado { get => _tipoOperacaoSelecionado; set { if (_tipoOperacaoSelecionado != value) { _tipoOperacaoSelecionado = value; OnPropertyChanged(nameof(TipoOperacaoSelecionado)); OnPropertyChanged(nameof(OperacaoAutomaticaSelecionada)); OnPropertyChanged(nameof(OperacaoManualSelecionada)); OnPropertyChanged(nameof(DescricaoModoOperacao)); OnPropertyChanged(nameof(MensagemGeral)); OnPropertyChanged(nameof(PodeAvancar)); OnTudoOkChanged(); } } } public bool OperacaoAutomaticaSelecionada => TipoOperacaoSelecionado == ModoOperacao.Automatico; public bool OperacaoManualSelecionada => TipoOperacaoSelecionado == ModoOperacao.Manual; public bool PodeAvancar => TipoOperacaoSelecionado == ModoOperacao.Automatico ? RedeOk && GnssOk : RedeOk; public string DescricaoModoOperacao => TipoOperacaoSelecionado == ModoOperacao.Automatico ? "Operação autônoma. Exige rede e GNSS conectados. Na próxima etapa, será necessário carregar o mapa e fixar a base." : "Operação manual. Exige apenas rede conectada. O sistema pulará a preparação de mapa e base, liberando apenas funções manuais."; // ====== PROPRIEDADES DE REDE ====== private bool _redeOk; public bool RedeOk { get => _redeOk; set { if (_redeOk != value) { _redeOk = value; OnPropertyChanged(nameof(RedeOk)); OnPropertyChanged(nameof(StatusRedeTexto)); OnPropertyChanged(nameof(CorStatusRede)); OnPropertyChanged(nameof(CorBordaRede)); OnPropertyChanged(nameof(TudoOk)); OnTudoOkChanged(); } } } private string _detalhesRede; public string DetalhesRede { get => _detalhesRede; set { _detalhesRede = value; OnPropertyChanged(nameof(DetalhesRede)); } } public string StatusRedeTexto => RedeOk ? "Rede configurada" : "Rede com problema"; public Brush CorStatusRede => RedeOk ? Brushes.LightGreen : Brushes.OrangeRed; public Brush CorBordaRede => RedeOk ? Brushes.LightGreen : Brushes.OrangeRed; // ====== PROPRIEDADES DE GNSS ====== private bool _gnssOk; public bool GnssOk { get => _gnssOk; set { if (_gnssOk != value) { _gnssOk = value; OnPropertyChanged(nameof(GnssOk)); OnPropertyChanged(nameof(StatusGnssTexto)); OnPropertyChanged(nameof(CorStatusGnss)); OnPropertyChanged(nameof(CorBordaGnss)); OnPropertyChanged(nameof(TudoOk)); OnTudoOkChanged(); } } } private string _detalhesGnss; public string DetalhesGnss { get => _detalhesGnss; set { _detalhesGnss = value; OnPropertyChanged(nameof(DetalhesGnss)); } } public string StatusGnssTexto => GnssOk ? "GNSS conectado" : "GNSS não detectado"; public Brush CorStatusGnss => GnssOk ? Brushes.LightGreen : Brushes.OrangeRed; public Brush CorBordaGnss => GnssOk ? Brushes.LightGreen : Brushes.OrangeRed; // ====== MENSAGEM GERAL ====== private string _mensagemGeral; public string MensagemGeral { get { if (TipoOperacaoSelecionado == ModoOperacao.Automatico) { if (!RedeOk && !GnssOk) return "Conecte a rede e o GNSS para iniciar uma operação automática."; if (!RedeOk) return "Ajuste a rede para avançar."; if (!GnssOk) return "Conecte o GNSS para avançar na operação automática."; return "Tudo OK. Você pode avançar para a preparação do mapa e fixação da base."; } else { if (!RedeOk) return "Ajuste a rede para habilitar o modo manual."; return "Rede OK. Você pode avançar diretamente para a parametrização manual do rover."; } } } // ====== COMANDOS ====== public ICommand AbrirConfigRedeCommand { get; } public ICommand AbrirDetalhesGnssCommand { get; } public ICommand SelecionarModoAutomaticoCommand { get; } public ICommand SelecionarModoManualCommand { get; } private void AbrirConfigRede() { // depois você pode abrir uma janelinha de config //MessageBox.Show("Aqui vai abrir a tela de configuração de rede."); SolicitarConfigRede?.Invoke(); } private void AbrirDetalhesGnss() { string msg = Variaveis.GpsService.IsConnected ? $"Conectado à porta {Variaveis.GpsService.PortName}" : $"Não conectado"; MessageBox.Show(msg); } // ====== STATUS GERAL PARA AVANÇAR ====== public bool TudoOk => PodeAvancar; // Evento para o DockWindow saber quando ficou tudo ok public event Action TudoOkChanged; private void OnTudoOkChanged() { TudoOkChanged?.Invoke(TudoOk); } // ====== STATUS INICIAL (fake por enquanto) ====== public void CarregarStatusInicial() { // aqui você pluga de verdade nos seus serviços: // var statusRede = NetworkService.Get(); // var statusGnss = GnssService.Get(); AtualizarStatusRede(); AtualizarStatusGnss(); } private void AtualizarStatusGnss() { try { // Exemplo de checks (troca pelo teu serviço): // bool conectado = GnssService.Um982Conectado(); // string porta = GnssService.PortaAtual(); // string fix = GnssService.FixMode(); // "No Fix", "3D", "RTK Float", "RTK Fixed" // double? hdop = GnssService.Hdop(); bool conectado = AppShell.Mock || (Variaveis.GpsService?.IsConnected ?? false); if (!conectado) { GnssOk = false; DetalhesGnss = "UM982 não detectado. Verifique cabo USB e alimentação."; return; } // Se conectou: GnssOk = true; // Se você tiver mais infos, mostra aqui: // DetalhesGnss = $"Conectado ({porta}) | Fix: {fix} | HDOP: {hdop:0.0}"; DetalhesGnss = "Conectado. Recebendo dados GNSS."; } catch (Exception ex) { GnssOk = false; DetalhesGnss = "Erro ao verificar GNSS: " + ex.Message; } } public void AtualizarStatusRede() { try { var interfaces = EthernetService.ObterNomesInterfaces() .Where(x => x.Contains(AppShell.Mock ? "Ativa" : "Ethernet")) .Select(x => x.Split('(')[0].Trim()) .ToList(); string? iface = interfaces.FirstOrDefault(); var status = EthernetService.ObterStatusRede(iface, exigirGateway: false); RedeOk = status.RedeOk; DetalhesRede = status.Detalhes; } catch (Exception ex) { RedeOk = false; DetalhesRede = "Não foi possível ler a configuração.\n" + ex.Message; } } // ====== INotifyPropertyChanged ====== public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string nome) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome)); } public void Dispose() { _timerGnss?.Stop(); } } }