2026-03-27 01:42:40 +00:00
using AgroBase.Models ;
using AgroBase.Models.Operacoes ;
2026-03-25 10:52:19 +00:00
using AgroBase.Services ;
using Newtonsoft.Json.Linq ;
using OperationControl.Controls ;
2026-03-10 19:56:55 +00:00
using OperationControl.Helpers ;
using OperationControl.Models ;
using OperationControl.ViewModels.Views.Operacao ;
2026-03-25 10:52:19 +00:00
using OperationControl.Views ;
using OperationControl.Views.Operacao ;
using System.ComponentModel ;
using System.Windows ;
using System.Windows.Input ;
2026-03-12 22:16:15 +00:00
using static AgroBase . Models . Enums ;
2026-03-25 10:52:19 +00:00
using static OperationControl . Services . BaseFixService ;
2026-03-10 19:56:55 +00:00
namespace OperationControl.ViewModels
{
public class DockWindowViewModel : INotifyPropertyChanged
{
private readonly ConfigConexaoView _viewConfig ;
private readonly PreparacaoMapaView _viewPreparacaoMapa ;
public readonly PreparacaoMapaTopView _viewPreparacaoMapaTop ;
2026-03-18 10:40:59 +00:00
public readonly PreparacaoMapaBottomView _viewPreparacaoMapaBottom ;
2026-03-10 19:56:55 +00:00
private readonly OperacaoTopView _viewOperacaoTop ;
2026-03-18 10:40:59 +00:00
public readonly OperacaoCenterView _viewOperacaoCenter ;
2026-03-10 19:56:55 +00:00
public readonly OperacaoLeftView _viewOperacaoLeft ;
public readonly OperacaoRightView _viewOperacaoRight ;
public readonly OperacaoBottomView _viewOperacaoBottom ;
2026-03-11 20:11:17 +00:00
public OperacaoBottomViewModel BottomVM = > _viewOperacaoBottom ? . _vm ;
2026-03-10 19:56:55 +00:00
private DockStep _currentStep ;
public DockWindowViewModel ( )
{
// Views
_viewConfig = new ConfigConexaoView ( ) ;
_viewConfig . _vm . TudoOkChanged + = OnTudoOkChanged ;
_viewPreparacaoMapa = new PreparacaoMapaView ( ) ;
_viewPreparacaoMapaTop = new PreparacaoMapaTopView ( ) ;
_viewPreparacaoMapaBottom = new PreparacaoMapaBottomView ( ) ;
_viewPreparacaoMapaBottom . _vm . CarregarMapaSolicitado + = OnCarregarMapaSolicitado ;
_viewPreparacaoMapaBottom . _vm . FixarBaseSolicitado + = OnFixarBaseSolicitado ;
2026-03-25 10:52:19 +00:00
_viewPreparacaoMapaBottom . _vm . AplicarOffsetSolicitado + = OnAplicarOffsetSolicitado ;
2026-03-10 19:56:55 +00:00
_viewOperacaoTop = new OperacaoTopView ( ) ;
_viewOperacaoCenter = new OperacaoCenterView ( ) ;
_viewOperacaoCenter . _vm . RoverSelecionadoChanged + = OnRoverSelecionadoChanged ;
_viewOperacaoLeft = new OperacaoLeftView ( ) ;
_viewOperacaoRight = new OperacaoRightView ( ) ;
_viewOperacaoRight . _vm . PropertyChanged + = OperacaoRightVm_PropertyChanged ;
_viewOperacaoRight . _vm . RoverSelecionadoChanged + = OnRoverSelecionadoChanged ;
_viewOperacaoRight . _vm . SecaoSelecionadaChanged + = OnSecaoSelecionadaChanged ;
2026-03-17 00:43:15 +00:00
_viewOperacaoRight . areaParametrizacao . _vm . LerParametrosSolicitado + = OnLerParametrosSolicitado ;
_viewOperacaoRight . areaParametrizacao . _vm . SalvarParametrosSolicitado + = OnSalvarParametrosSolicitado ;
2026-03-10 19:56:55 +00:00
_viewOperacaoBottom = new OperacaoBottomView ( ) ;
2026-03-11 20:11:17 +00:00
_viewOperacaoBottom . _vm . SolicitarAbrirDiagnostico + = AbrirDiagnosticoPeloAlerta ;
2026-03-10 19:56:55 +00:00
// Commands
BackCommand = new RelayCommand ( _ = > GoBack ( ) , _ = > CanGoBack ) ;
NextCommand = new RelayCommand ( _ = > GoNext ( ) , _ = > CanGoNext ) ;
// Estado inicial
ConfigConexaoOk = _viewConfig . _vm . TudoOk ;
CurrentStep = DockStep . ConfigConexao ;
}
private void OnTudoOkChanged ( bool ok )
{
ConfigConexaoOk = ok ;
OnPropertyChanged ( nameof ( CanGoNext ) ) ;
CommandManager . InvalidateRequerySuggested ( ) ;
}
// ====== ETAPA ATUAL ======
public ModoOperacao ModoOperacaoAtual = > _viewConfig . _vm . TipoOperacaoSelecionado ;
public DockStep CurrentStep
{
get = > _currentStep ;
set
{
if ( _currentStep ! = value )
{
_currentStep = value ;
OnPropertyChanged ( nameof ( CurrentStep ) ) ;
OnPropertyChanged ( nameof ( CanGoBack ) ) ;
OnPropertyChanged ( nameof ( CanGoNext ) ) ;
OnPropertyChanged ( nameof ( MostrarPainelEsquerdo ) ) ;
OnPropertyChanged ( nameof ( MostrarBotaoVoltarEsquerda ) ) ;
OnPropertyChanged ( nameof ( RightPanelWidth ) ) ;
OnPropertyChanged ( nameof ( LeftPanelWidth ) ) ;
AtualizarConteudo ( ) ;
CommandManager . InvalidateRequerySuggested ( ) ;
}
}
}
// ====== ESTADO ======
private bool _configConexaoOk ;
public bool ConfigConexaoOk
{
get = > _configConexaoOk ;
set
{
if ( _configConexaoOk ! = value )
{
_configConexaoOk = value ;
OnPropertyChanged ( nameof ( ConfigConexaoOk ) ) ;
OnPropertyChanged ( nameof ( CanGoNext ) ) ;
CommandManager . InvalidateRequerySuggested ( ) ;
}
}
}
private bool _mapaCarregado ;
public bool MapaCarregado
{
get = > _mapaCarregado ;
set
{
if ( _mapaCarregado ! = value )
{
_mapaCarregado = value ;
OnPropertyChanged ( nameof ( MapaCarregado ) ) ;
OnPropertyChanged ( nameof ( CanGoNext ) ) ;
CommandManager . InvalidateRequerySuggested ( ) ;
}
}
}
2026-03-12 01:00:21 +00:00
private bool _baseFixada = AppShell . Mock ;
2026-03-10 19:56:55 +00:00
public bool BaseFixada
{
get = > _baseFixada ;
set
{
if ( _baseFixada ! = value )
{
_baseFixada = value ;
OnPropertyChanged ( nameof ( BaseFixada ) ) ;
OnPropertyChanged ( nameof ( CanGoNext ) ) ;
CommandManager . InvalidateRequerySuggested ( ) ;
}
}
}
public bool CanGoBack = > CurrentStep ! = DockStep . ConfigConexao ;
public bool CanGoNext
{
get
{
return CurrentStep switch
{
DockStep . ConfigConexao = > PodeAvancarConfigConexao ( ) ,
DockStep . PreparacaoMapa = > MapaCarregado & & BaseFixada ,
_ = > false
} ;
}
}
private bool PodeAvancarConfigConexao ( )
{
return ModoOperacaoAtual switch
{
ModoOperacao . Automatico = > _viewConfig . _vm . RedeOk & & _viewConfig . _vm . GnssOk ,
ModoOperacao . Manual = > _viewConfig . _vm . RedeOk ,
_ = > false
} ;
}
public bool MostrarPainelEsquerdo = > CurrentStep = = DockStep . ParametrizacaoRover ;
public bool MostrarBotaoVoltarEsquerda = > CurrentStep ! = DockStep . ParametrizacaoRover ;
public GridLength LeftPanelWidth
{
get
{
return CurrentStep switch
{
DockStep . ParametrizacaoRover = > new GridLength ( 280 ) ,
_ = > new GridLength ( 60 )
} ;
}
}
public GridLength RightPanelWidth
{
get
{
return CurrentStep switch
{
2026-03-17 00:43:15 +00:00
DockStep . ParametrizacaoRover = > _viewOperacaoRight ? . _vm ? . IsCollapsed = = true
2026-03-10 19:56:55 +00:00
? new GridLength ( 44 )
: new GridLength ( 320 ) ,
_ = > new GridLength ( 60 )
} ;
}
}
private void OperacaoRightVm_PropertyChanged ( object sender , PropertyChangedEventArgs e )
{
if ( e . PropertyName = = nameof ( OperacaoRightViewModel . IsCollapsed ) )
{
OnPropertyChanged ( nameof ( RightPanelWidth ) ) ;
}
}
// ====== CONTEÚDOS ======
private object _centerContent ;
public object CenterContent
{
get = > _centerContent ;
set
{
_centerContent = value ;
OnPropertyChanged ( nameof ( CenterContent ) ) ;
}
}
private object _topContent ;
public object TopContent
{
get = > _topContent ;
set
{
_topContent = value ;
OnPropertyChanged ( nameof ( TopContent ) ) ;
}
}
private object _bottomContent ;
public object BottomContent
{
get = > _bottomContent ;
set
{
_bottomContent = value ;
OnPropertyChanged ( nameof ( BottomContent ) ) ;
}
}
private object _leftContent ;
public object LeftContent
{
get = > _leftContent ;
set
{
_leftContent = value ;
OnPropertyChanged ( nameof ( LeftContent ) ) ;
}
}
private object _rightContent ;
public object RightContent
{
get = > _rightContent ;
set
{
_rightContent = value ;
OnPropertyChanged ( nameof ( RightContent ) ) ;
}
}
// ====== COMMANDS ======
public ICommand BackCommand { get ; }
public ICommand NextCommand { get ; }
private void GoBack ( )
{
switch ( CurrentStep )
{
case DockStep . PreparacaoMapa :
CurrentStep = DockStep . ConfigConexao ;
break ;
}
}
private void GoNext ( )
{
if ( ! CanGoNext ) return ;
switch ( CurrentStep )
{
case DockStep . ConfigConexao :
if ( ModoOperacaoAtual = = ModoOperacao . Manual )
CurrentStep = DockStep . ParametrizacaoRover ;
else
CurrentStep = DockStep . PreparacaoMapa ;
break ;
case DockStep . PreparacaoMapa :
CurrentStep = DockStep . ParametrizacaoRover ;
break ;
}
}
private FrameworkElement CriarBotaoNextSimples ( )
{
return new System . Windows . Controls . Button
{
Content = "⮞" ,
FontSize = 24 ,
Width = 40 ,
Height = 40 ,
HorizontalAlignment = System . Windows . HorizontalAlignment . Center ,
VerticalAlignment = VerticalAlignment . Center ,
Command = NextCommand
} ;
}
private void AtualizarConteudo ( )
{
TopContent = null ;
BottomContent = null ;
LeftContent = null ;
RightContent = null ;
CenterContent = null ;
switch ( CurrentStep )
{
case DockStep . ConfigConexao :
CenterContent = _viewConfig ;
RightContent = CriarBotaoNextSimples ( ) ;
break ;
case DockStep . PreparacaoMapa :
TopContent = _viewPreparacaoMapaTop ;
CenterContent = _viewPreparacaoMapa ;
BottomContent = _viewPreparacaoMapaBottom ;
RightContent = CriarBotaoNextSimples ( ) ;
break ;
case DockStep . ParametrizacaoRover :
TopContent = _viewOperacaoTop ;
LeftContent = _viewOperacaoLeft ;
CenterContent = _viewOperacaoCenter ;
RightContent = _viewOperacaoRight ;
BottomContent = _viewOperacaoBottom ;
2026-03-12 01:00:21 +00:00
AtualizarDadosMapa ( null ) ;
2026-03-12 22:16:15 +00:00
AtualizarBarraSuperior ( StatusModulo . Conectado , "BASE" , "VISÃO GERAL" , "Selecione um equipamento na lista à direita para configurá-lo" , "NORMAL" , "Aguardando" ) ;
2026-03-10 19:56:55 +00:00
break ;
}
OnPropertyChanged ( nameof ( MostrarPainelEsquerdo ) ) ;
OnPropertyChanged ( nameof ( MostrarBotaoVoltarEsquerda ) ) ;
}
// ====== INotifyPropertyChanged ======
public event PropertyChangedEventHandler PropertyChanged ;
private void OnPropertyChanged ( string nome )
{
PropertyChanged ? . Invoke ( this , new PropertyChangedEventArgs ( nome ) ) ;
}
2026-03-13 18:58:02 +00:00
public void AtualizarBarraSuperior ( OperacaoParametrosModel rover )
{
var obj = rover ? . DadosLeitura ;
if ( rover = = null | | obj = = null )
return ;
2026-03-17 17:26:07 +00:00
if ( rover . RoverId ! = VariaveisControleOperacao . SelectedRoverId )
return ;
2026-03-13 18:58:02 +00:00
var eventos = new List < MotivoTopBarModel > ( ) ;
2026-03-17 17:26:07 +00:00
double tempoSemResposta = ( DateTime . Now - rover . UltimoContato ) . TotalSeconds ;
2026-03-19 10:55:56 +00:00
bool semComunicacao = ! AppShell . Mock & & tempoSemResposta > = VariaveisControleOperacao . TempoRoverVivo ;
2026-03-17 17:26:07 +00:00
2026-03-20 02:03:07 +00:00
// ============================
// 0) Perda de comunicação
// ============================
2026-03-17 17:26:07 +00:00
if ( semComunicacao )
{
eventos . Add ( new MotivoTopBarModel
{
Prioridade = 2000 ,
Fonte = "Comunicacao" ,
Titulo = "PERDA DE COMUNICAÇÃO COM O ROVER" ,
Descricao = $"Sem resposta do rover há {tempoSemResposta:F1} s. Tentando reconectar automaticamente." ,
StatusVisual = StatusModulo . Desconectado
} ) ;
}
2026-03-20 02:03:07 +00:00
// ============================
// 0) NCP desconectado
// ============================
2026-03-13 19:30:21 +00:00
if ( obj . ModulosSaude ? . All ( x = > ( x ? . status ? ? StatusModulo . Desconectado ) = = StatusModulo . Desconectado ) ? ? false )
{
eventos . Add ( new MotivoTopBarModel
{
Prioridade = 1100 ,
2026-03-19 10:55:56 +00:00
Fonte = "NCP" ,
2026-03-13 19:30:21 +00:00
Titulo = "NÚCLEO CENTRAL DE PROCESSAMENTO DESCONECTADO" ,
Descricao = "O núcleo central de processamento foi desconectado, tentando reconectar..." ,
StatusVisual = StatusModulo . Falha
} ) ;
}
2026-03-13 18:58:02 +00:00
// ============================
// 1) Emergência
// ============================
if ( obj . Operacao ? . Emergencia = = true )
{
eventos . Add ( new MotivoTopBarModel
{
Prioridade = 1000 ,
Fonte = "Emergencia" ,
Titulo = "OPERAÇÃO BLOQUEADA POR EMERGÊNCIA" ,
Descricao = "Parada de emergência solicitada." ,
StatusVisual = StatusModulo . Falha
} ) ;
}
// ============================
// 2) Pausa
// ============================
if ( obj . Operacao ? . Pausa = = true )
{
eventos . Add ( new MotivoTopBarModel
{
Prioridade = 900 ,
Fonte = "Pausa" ,
Titulo = "OPERAÇÃO PAUSADA" ,
Descricao = "Pausa operacional solicitada." ,
StatusVisual = StatusModulo . Alerta
} ) ;
}
// ============================
// 3) Controle
// ============================
var motivosControle = obj . Controle ? . Motivos ?
. Where ( x = > ! string . IsNullOrWhiteSpace ( x ) )
. Distinct ( )
. ToList ( ) ? ? new List < string > ( ) ;
foreach ( var motivo in motivosControle )
{
eventos . Add ( new MotivoTopBarModel
{
Prioridade = 800 ,
Fonte = "Controle" ,
Titulo = "CONTROLE SEM LIBERAÇÃO" ,
Descricao = motivo ,
StatusVisual = StatusModulo . Alerta
} ) ;
}
// ============================
// 4) Trajetória / autonomia
// ============================
var motivosTrajetoria = obj . Trajetoria ? . AutonomiaCorredor ? . Motivos ?
. Where ( x = > ! string . IsNullOrWhiteSpace ( x ) )
. Distinct ( )
. ToList ( ) ? ? new List < string > ( ) ;
foreach ( var motivo in motivosTrajetoria )
{
eventos . Add ( new MotivoTopBarModel
{
Prioridade = 700 ,
Fonte = "Trajetoria" ,
Titulo = "TRAJETÓRIA BLOQUEADA" ,
Descricao = motivo ,
StatusVisual = StatusModulo . Alerta
} ) ;
}
// ============================
// 5) Módulos com condições operacionais críticas
// ============================
var modulosCriticos = obj . ModulosSaude ?
2026-03-19 10:55:56 +00:00
. Where ( mod = >
( mod ? . condicoes_operacionais ? . Any ( cond = > cond ? . severidade > 90 ) ? ? false ) | |
(
! new List < StatusModulo > ( ) { StatusModulo . Operante , StatusModulo . Alerta } . Contains ( mod ? . status ? ? StatusModulo . Desconectado ) & &
( rover ? . ModulosMandatorios ? . Any ( x = >
( x ? . Dispositivo ? ? T_Code . Vzo ) = = ( mod ? . modulo ? ? T_Code . Vzo ) & &
( x ? . Utilizar ? ? false ) & &
( x ? . Mandatorio ? ? false )
) ? ? false )
2026-03-20 02:03:07 +00:00
) | |
(
( mod ? . status ? ? StatusModulo . Desconectado ) = = StatusModulo . Alerta & &
( rover ? . ModulosMandatorios ? . Any ( x = >
( x ? . Dispositivo ? ? T_Code . Vzo ) = = ( mod ? . modulo ? ? T_Code . Vzo ) & &
( x ? . Utilizar ? ? false ) & &
( x ? . Mandatorio ? ? false )
) ? ? false )
2026-03-19 10:55:56 +00:00
)
)
2026-03-13 18:58:02 +00:00
. ToList ( ) ? ? new List < AgroBase . Models . Operadores . ManagerWorkerMessageResponseModulosPendentesModel > ( ) ;
foreach ( var modulo in modulosCriticos )
{
var nomeModulo = ( modulo ? . modulo ? ? T_Code . Vzo ) . ToString ( ) ;
2026-03-19 10:55:56 +00:00
bool temCondicaoSevera = modulo ? . condicoes_operacionais ? . Any ( cond = > cond ? . severidade > 90 ) ? ? false ;
bool moduloMandatorioNaoOperante =
! new List < StatusModulo > ( ) { StatusModulo . Operante , StatusModulo . Alerta } . Contains ( modulo ? . status ? ? StatusModulo . Desconectado ) & &
( rover ? . ModulosMandatorios ? . Any ( x = >
( x ? . Dispositivo ? ? T_Code . Vzo ) = = ( modulo ? . modulo ? ? T_Code . Vzo ) & &
( x ? . Utilizar ? ? false ) & &
( x ? . Mandatorio ? ? false )
) ? ? false ) ;
2026-03-20 02:03:07 +00:00
bool moduloMandatorioAlerta =
( modulo ? . status ? ? StatusModulo . Desconectado ) = = StatusModulo . Alerta & &
( rover ? . ModulosMandatorios ? . Any ( x = >
( x ? . Dispositivo ? ? T_Code . Vzo ) = = ( modulo ? . modulo ? ? T_Code . Vzo ) & &
( x ? . Utilizar ? ? false ) & &
( x ? . Mandatorio ? ? false )
) ? ? false ) ;
// Caso 1: módulo mandatório não operante
if ( moduloMandatorioNaoOperante )
{
var statusTexto = ( modulo ? . status ? ? StatusModulo . Desconectado ) . ToString ( ) ;
string motivos = string . Join ( "; " , modulo ? . motivos ? ? new List < string > ( ) { "Desconhecido" } ) ;
2026-03-19 10:55:56 +00:00
2026-03-20 02:03:07 +00:00
eventos . Add ( new MotivoTopBarModel
{
Prioridade = 620 ,
Fonte = "ModuloCritico" ,
Titulo = "MÓDULO MANDATÓRIO NÃO OPERACIONAL" ,
Descricao = $"{nomeModulo}: módulo mandatório em estado '{statusTexto}': {motivos}" ,
StatusVisual = StatusModulo . Falha ,
Modulo = modulo ? . modulo
} ) ;
}
// Caso 2: condições operacionais severas
2026-03-19 10:55:56 +00:00
if ( temCondicaoSevera )
{
var descricoesCriticas = modulo ? . condicoes_operacionais ?
. Where ( cond = > cond ? . severidade > 90 )
. Select ( cond = > cond ? . descricao ? ? "" )
. Where ( desc = > ! string . IsNullOrWhiteSpace ( desc ) )
. Distinct ( )
. ToList ( ) ? ? new List < string > ( ) ;
foreach ( var desc in descricoesCriticas )
{
eventos . Add ( new MotivoTopBarModel
{
2026-03-20 02:03:07 +00:00
Prioridade = 610 ,
2026-03-19 10:55:56 +00:00
Fonte = "ModuloCritico" ,
Titulo = "CONDIÇÕES OPERACIONAIS CRÍTICAS" ,
Descricao = $"{nomeModulo}: {desc}" ,
StatusVisual = StatusModulo . Alerta ,
Modulo = modulo ? . modulo
} ) ;
}
}
2026-03-13 18:58:02 +00:00
2026-03-20 02:03:07 +00:00
// Caso 3: módulo mandatório em alerta
if ( moduloMandatorioAlerta )
2026-03-13 18:58:02 +00:00
{
2026-03-19 10:55:56 +00:00
var statusTexto = ( modulo ? . status ? ? StatusModulo . Desconectado ) . ToString ( ) ;
2026-03-20 02:03:07 +00:00
string motivos = string . Join ( "; " , modulo ? . motivos ? ? new List < string > ( ) { "Desconhecido" } ) ;
2026-03-19 10:55:56 +00:00
2026-03-13 18:58:02 +00:00
eventos . Add ( new MotivoTopBarModel
{
2026-03-20 02:03:07 +00:00
Prioridade = 600 ,
2026-03-13 18:58:02 +00:00
Fonte = "ModuloCritico" ,
2026-03-20 02:03:07 +00:00
Titulo = "MÓDULO MANDATÓRIO EM ALERTA" ,
Descricao = $"{nomeModulo}: módulo mandatório em estado '{statusTexto}': {motivos}" ,
StatusVisual = StatusModulo . Alerta ,
2026-03-13 18:58:02 +00:00
Modulo = modulo ? . modulo
} ) ;
}
}
var ordemModulos = new Dictionary < T_Code , int >
{
{ T_Code . Ipb , 1 } ,
{ T_Code . Npc , 2 } ,
2026-03-19 10:55:56 +00:00
{ T_Code . Can , 3 } ,
{ T_Code . Bat , 4 } ,
{ T_Code . Gps , 5 } ,
{ T_Code . Atu , 6 } ,
{ T_Code . Sen , 7 }
2026-03-13 18:58:02 +00:00
} ;
// ============================
// 6) Remove vazios / repetidos
// ============================
var eventosOrdenados = eventos
. Where ( x = > ! string . IsNullOrWhiteSpace ( x . Titulo ) & & ! string . IsNullOrWhiteSpace ( x . Descricao ) )
. GroupBy ( x = > new { x . Fonte , x . Titulo , x . Descricao , x . Prioridade , x . StatusVisual } )
. Select ( g = > g . First ( ) )
. OrderByDescending ( x = > x . Prioridade )
. ThenBy ( x = > x . Modulo . HasValue & & ordemModulos . ContainsKey ( x . Modulo . Value ) ? ordemModulos [ x . Modulo . Value ] : int . MaxValue )
. ThenBy ( x = > x . Fonte )
. ToList ( ) ;
2026-03-20 02:03:07 +00:00
if ( ! eventosOrdenados . Any ( ) )
{
eventosOrdenados . Add ( new MotivoTopBarModel
{
Prioridade = 0 ,
Fonte = "Normal" ,
Titulo = "ROVER OPERANDO NORMALMENTE" ,
Descricao = "Trajetória, controle e operação em condição normal." ,
StatusVisual = obj . StatusRover = = StatusModulo . Desconectado
? StatusModulo . Desconectado
: StatusModulo . Operante
} ) ;
}
2026-03-13 18:58:02 +00:00
// ============================
// 7) Monta visual final
// ============================
StatusModulo statusVisual ;
string linha1 ;
string linha2 ;
string badge ;
string resumo ;
if ( eventosOrdenados . Any ( ) )
{
var principal = eventosOrdenados . First ( ) ;
statusVisual = principal . StatusVisual ;
linha1 = principal . Titulo ;
// Pega até 3 descrições distintas, por prioridade
var descricoes = eventosOrdenados
. Select ( x = > x . Descricao ? . Trim ( ) )
. Where ( x = > ! string . IsNullOrWhiteSpace ( x ) )
. Distinct ( )
. Take ( 3 )
. ToList ( ) ;
linha2 = string . Join ( " • " , descricoes ) ;
// Badge curto
badge = principal . Fonte switch
{
2026-03-17 17:26:07 +00:00
"Comunicacao" = > "DESCONECTADO" ,
2026-03-13 18:58:02 +00:00
"Emergencia" = > "EMERGÊNCIA" ,
"Pausa" = > "PAUSADO" ,
"Trajetoria" = > "TRAJETÓRIA" ,
"Controle" = > "CONTROLE" ,
"ModuloCritico" = > "ALERTA" ,
_ = > statusVisual . ToString ( ) . ToUpper ( )
} ;
// Resumo curto
resumo = principal . Fonte switch
{
2026-03-17 17:26:07 +00:00
"Comunicacao" = > "Sem telemetria" ,
2026-03-13 18:58:02 +00:00
"Emergencia" = > "Parada imediata" ,
"Pausa" = > "Aguardando retomada" ,
"Trajetoria" = > "Operação bloqueada" ,
"Controle" = > "Controle bloqueado" ,
"ModuloCritico" = > "Atenção operacional" ,
_ = > ( obj . Operacao ? . Status ? ? StatusOperacao . NaoIniciado ) . ToString ( )
} ;
}
else
{
statusVisual = obj . StatusRover = = StatusModulo . Desconectado
? StatusModulo . Desconectado
: StatusModulo . Operante ;
linha1 = "ROVER OPERANDO NORMALMENTE" ;
linha2 = "Trajetória, controle e operação em condição normal." ;
badge = statusVisual . ToString ( ) . ToUpper ( ) ;
resumo = ( obj . Operacao ? . Status ? ? StatusOperacao . NaoIniciado ) . ToString ( ) ;
}
2026-03-20 02:03:07 +00:00
_viewOperacaoCenter ? . Historico ? . _vm ? . CompararERegistrarMudancasEventos ( rover . RoverId , eventosOrdenados ) ;
2026-03-13 18:58:02 +00:00
// Segurança extra: evita linha vazia
if ( string . IsNullOrWhiteSpace ( linha2 ) )
linha2 = "Sem detalhes adicionais." ;
// ============================
// 8) Atualiza UI
// ============================
System . Windows . Application . Current . Dispatcher . BeginInvoke ( new Action ( ( ) = >
{
_viewOperacaoTop ? . _vm . AtualizarStatus (
statusVisual ,
rover . RoverId ,
2026-03-13 19:30:21 +00:00
obj ? . Operacao ? . Status ? ? StatusOperacao . NaoIniciado ,
2026-03-13 18:58:02 +00:00
linha1 ,
linha2 ,
badge ,
resumo
) ;
} ) ) ;
}
2026-03-12 22:16:15 +00:00
public void AtualizarBarraSuperior ( StatusModulo status , string titulo , string linha1 , string linha2 , string status_str , string resumo )
{
System . Windows . Application . Current . Dispatcher . BeginInvoke ( new Action ( ( ) = >
{
2026-03-13 19:30:21 +00:00
_viewOperacaoTop ? . _vm . AtualizarStatus ( status , titulo , StatusOperacao . Parametrizando , linha1 , linha2 . Replace ( "\n\n" , " • " ) , status_str , resumo ) ;
2026-03-12 22:16:15 +00:00
} ) ) ;
}
2026-03-10 19:56:55 +00:00
public void AtualizarDadosGnss ( AgroBase . Models . GPSModel dados )
{
2026-03-19 10:55:56 +00:00
var bf = Models . Variaveis . GpsService . BaseFix ;
2026-03-10 19:56:55 +00:00
if ( bf . CorrecaoEmAndamento )
{
AtualizarProgressoFixacaoBase ( bf . Progresso , bf . ProgressoStr ) ;
if ( bf . Progresso > = 100 ) FinalizarFixacaoBase ( true , bf . ProgressoStr ) ;
}
2026-03-12 01:00:21 +00:00
MapViewControl ? Mapa = CurrentStep = = DockStep . PreparacaoMapa ? _viewPreparacaoMapa ? . MapaPreparacao : CurrentStep = = DockStep . ParametrizacaoRover ? _viewOperacaoCenter ? . Mapa : null ;
if ( CurrentStep = = DockStep . PreparacaoMapa )
2026-03-10 19:56:55 +00:00
{
2026-03-12 01:00:21 +00:00
_viewPreparacaoMapaTop ? . _vm ? . AtualizarDados ( dados ) ;
2026-03-10 19:56:55 +00:00
}
2026-03-16 17:17:38 +00:00
CriarMarcadorBase ( Mapa ) ;
2026-03-12 01:00:21 +00:00
Mapa ? . markers ? . UpdateMarkerPosition ( VariaveisControleOperacao . BaseMarkerID , lat : dados ? . Latitude , lon : dados ? . Longitude , heading : dados ? . OrientacaoReal ) ;
2026-03-10 19:56:55 +00:00
}
2026-03-16 19:22:06 +00:00
public void AtualizarParametrosRover ( OperacaoParametrosModel ? rover )
{
2026-03-17 00:43:15 +00:00
_viewOperacaoRight ? . areaParametrizacao ? . _vm ? . AtualizarParametros ( rover ) ;
2026-03-16 19:22:06 +00:00
AtualizarDadosMapa ( rover ) ;
2026-03-18 10:40:59 +00:00
AtualizarDadosTela ( rover ) ;
2026-03-16 19:22:06 +00:00
}
2026-03-12 01:00:21 +00:00
public void AtualizarDadosMapa ( OperacaoParametrosModel ? dados )
2026-03-10 19:56:55 +00:00
{
2026-03-30 19:45:33 +00:00
_viewOperacaoCenter ? . Mapa ? . LoadMapFile ( _ultimoMapaCarregado , _ultimoTipoMapaCarregado ) ;
2026-03-27 01:42:40 +00:00
_viewOperacaoCenter ? . Mapa ? . CarregarDadosMapa ( dados ? . Mapa , dados ? . RuasPercorrer , dados ? . PontosRetorno ) ;
2026-03-10 19:56:55 +00:00
}
#region TELA 2
private string? _ultimoMapaCarregado ;
2026-03-30 19:45:33 +00:00
private TipoMapaOperacao _ultimoTipoMapaCarregado = TipoMapaOperacao . RuasPlantacao ;
2026-03-10 19:56:55 +00:00
2026-03-11 20:11:17 +00:00
private void CriarMarcadorBase ( MapViewControl Mapa )
{
string markerId = VariaveisControleOperacao . BaseMarkerID ;
if ( ! Mapa ? . markers ? . Added ( markerId ) ? ? false )
{
Mapa ? . markers ? . AddMarker (
markerId ,
true ,
2026-03-27 01:42:40 +00:00
lat : Models . Variaveis . GpsService ? . UltimaLeitura ? . Latitude ,
lon : Models . Variaveis . GpsService ? . UltimaLeitura ? . Longitude ,
heading : Models . Variaveis . GpsService ? . UltimaLeitura ? . OrientacaoReal ,
2026-03-11 20:11:17 +00:00
label : "Base"
) ;
}
}
2026-03-30 19:45:33 +00:00
private void OnCarregarMapaSolicitado ( string caminhoArquivo , TipoMapaOperacao tipo )
2026-03-10 19:56:55 +00:00
{
try
{
_ultimoMapaCarregado = caminhoArquivo ;
2026-03-30 19:45:33 +00:00
_viewPreparacaoMapa ? . MapaPreparacao ? . LoadMapFile ( caminhoArquivo , tipo ) ;
2026-03-10 19:56:55 +00:00
MapaCarregado = true ;
_viewPreparacaoMapaBottom ? . _vm . AtualizarProgresso ( 0 , $"Mapa carregado: {System.IO.Path.GetFileName(caminhoArquivo)}" ) ;
}
catch ( Exception ex )
{
MapaCarregado = false ;
_viewPreparacaoMapaBottom ? . _vm . AtualizarProgresso ( 0 , $"Erro ao carregar mapa: {ex.Message}" ) ;
}
}
2026-03-25 10:52:19 +00:00
private async void OnFixarBaseSolicitado ( MetodoFixacaoBase metodoFix , double? lat , double? lon , double? alt )
2026-03-10 19:56:55 +00:00
{
try
{
2026-03-27 01:42:40 +00:00
if ( ! ( Models . Variaveis . GpsService . BaseFix ? . FixLiberado ? ? false ) )
2026-03-10 19:56:55 +00:00
{
bool fixar = false ;
2026-03-27 01:42:40 +00:00
if ( Models . Variaveis . GpsService . BaseFix ? . PosicaoBaseFixada ? ? false )
2026-03-10 19:56:55 +00:00
{
var res = System . Windows . MessageBox . Show (
"Mudar posição da base?" ,
"Tem certeza que deseja fixar a posição da base novamente?" ,
MessageBoxButton . YesNo ,
MessageBoxImage . Question ) ;
if ( res = = MessageBoxResult . Yes )
fixar = true ;
}
else
{
fixar = true ;
}
if ( fixar )
{
_viewPreparacaoMapaBottom ? . _vm . IniciarFixacao ( ) ;
2026-03-27 01:42:40 +00:00
await Models . Variaveis . GpsService . ConfigurarModulo ( true , metodoFix , lat , lon , alt ) ;
2026-03-10 19:56:55 +00:00
}
}
else
{
2026-03-27 01:42:40 +00:00
Models . Variaveis . GpsService . BaseFix . ReiniciarFix ( ) ;
2026-03-10 19:56:55 +00:00
BaseFixada = false ;
}
}
catch ( Exception ex )
{
_viewPreparacaoMapaBottom ? . _vm . FinalizarFixacao ( false , $"Erro na fixação da base: {ex.Message}" ) ;
}
}
public void AtualizarProgressoFixacaoBase ( double progresso , string status )
{
System . Windows . Application . Current . Dispatcher . BeginInvoke ( new Action ( ( ) = >
{
_viewPreparacaoMapaBottom ? . _vm . AtualizarProgresso ( progresso , status ) ;
} ) ) ;
}
public void FinalizarFixacaoBase ( bool sucesso , string mensagem )
{
System . Windows . Application . Current . Dispatcher . BeginInvoke ( new Action ( ( ) = >
{
BaseFixada = sucesso ;
_viewPreparacaoMapaBottom ? . _vm . FinalizarFixacao ( sucesso , mensagem ) ;
} ) ) ;
}
public void CancelarFixacaoBase ( string mensagem )
{
System . Windows . Application . Current . Dispatcher . BeginInvoke ( new Action ( ( ) = >
{
BaseFixada = false ;
_viewPreparacaoMapaBottom ? . _vm . CancelarFixacao ( mensagem ) ;
} ) ) ;
}
2026-03-25 10:52:19 +00:00
private async void OnAplicarOffsetSolicitado ( double? offsetFrontalCm , double? offsetLateralCm )
{
if ( offsetFrontalCm = = null | | offsetLateralCm = = null ) return ;
_viewPreparacaoMapaBottom ? . _vm . IniciarFixacao ( ) ;
2026-03-27 01:42:40 +00:00
var gps = Models . Variaveis . GpsService ;
2026-03-25 10:52:19 +00:00
gps . LeverArm = new GeoLeverArm ( offsetCampoFrontalCm : offsetFrontalCm . Value , offsetCampoLateralCm : offsetLateralCm . Value ) ;
2026-04-13 15:44:19 +00:00
( double lat , double lon ) = gps . LeverArm . FixLeverArmLatLon_Fast ( gps . BaseFix . LatitudeFix , gps . BaseFix . LongitudeFix , gps . BaseFix . OrientacaoFix , 5 ) ;
2026-03-27 01:42:40 +00:00
await Models . Variaveis . GpsService . ConfigurarModulo ( true , MetodoFixacaoBase . Manual , lat , lon , gps . BaseFix . AltitudeElpsoidalFix , offset : true ) ;
2026-03-25 10:52:19 +00:00
}
2026-03-10 19:56:55 +00:00
#endregion
#region TELA 3
2026-03-12 01:00:21 +00:00
public void AtualizarListaRovers ( List < OperacaoParametrosModel > rovers_atual )
{
var cards = rovers_atual . Select ( x = > new RoverCardModel ( )
{
EquipamentoId = x . IP ,
NumeroSerie = x . RoverId ,
Status = x . DadosLeitura ? . StatusRover ? ? AgroBase . Models . Enums . StatusModulo . Desconectado
} ) . ToArray ( ) ;
_viewOperacaoRight ? . _vm ? . AtualizarListaRovers ( cards ) ;
foreach ( var rover in cards )
{
if ( ! _viewOperacaoCenter ? . Mapa ? . markers ? . Added ( rover . NumeroSerie ) ? ? false )
{
var roverDados = VariaveisControleOperacao . RoversNaRede . FirstOrDefault ( x = > x . RoverId = = rover . NumeroSerie ) ;
if ( roverDados ! = null )
{
_viewOperacaoCenter ? . Mapa ? . markers ? . AddMarker (
rover . NumeroSerie ,
false ,
lat : roverDados . DadosLeitura ? . Gnss ? . Latitude ? ? 0 ,
lon : roverDados . DadosLeitura ? . Gnss ? . Longitude ? ? 0 ,
heading : roverDados . DadosLeitura ? . Gnss ? . OrientacaoReal ? ? 0
) ;
}
}
}
}
public void AtualizarDadosTela ( OperacaoParametrosModel rover )
{
if ( rover = = null ) return ;
var obj = rover . DadosLeitura ;
if ( obj = = null ) return ;
2026-03-12 14:00:43 +00:00
// MAPA
2026-03-12 01:00:21 +00:00
var simulacao = obj . Controle ? . SimulacaoMPC ? . Select ( x = > new double [ ] { x . longitude , x . latitude } ) ? . ToList ( ) ;
_viewOperacaoCenter ? . Mapa ? . markers . UpdateMarkerPosition ( rover . RoverId , lat : obj . Gnss ? . Latitude , lon : obj . Gnss ? . Longitude , heading : obj . Gnss ? . OrientacaoReal , predict : simulacao ) ;
2026-03-30 19:45:33 +00:00
if ( _viewOperacaoCenter ? . Mapa ? . chbAcompanhar . IsChecked ? ? false ) _viewOperacaoCenter ? . Mapa ? . SetView ( obj . Gnss ? . Latitude , obj . Gnss ? . Longitude ) ;
2026-03-12 01:00:21 +00:00
_viewOperacaoCenter ? . Mapa ? . markers . UpdateMarkerInfo ( rover . RoverId , status : obj . Operacao ? . Status ? ? AgroBase . Models . Enums . StatusOperacao . NaoIniciado ) ;
2026-03-12 14:00:43 +00:00
// ALERTAS
2026-03-12 01:00:21 +00:00
_viewOperacaoBottom ? . _vm ? . AtualizarListaAlertasTodosRovers ( ) ;
if ( rover . RoverId ! = VariaveisControleOperacao . SelectedRoverId ) return ;
2026-03-13 18:58:02 +00:00
AtualizarBarraSuperior ( rover ) ;
2026-03-13 14:05:41 +00:00
2026-03-12 14:00:43 +00:00
// ESQUERDA
2026-03-13 14:05:41 +00:00
var conexao = obj . ModulosSaude ? . FirstOrDefault ( x = > x . modulo = = T_Code . Ipb ) ;
2026-03-19 10:55:56 +00:00
double saude_rede = conexao ? . saude ? ? 0 ;
2026-03-12 20:03:24 +00:00
double conexao_latencia = conexao ? . detalhes ? [ "avg_rtt" ] ? . Value < double? > ( ) ? ? 0.0 ;
double conexao_perda = conexao ? . detalhes ? [ "loss_pct" ] ? . Value < double? > ( ) ? ? 0.0 ;
double bwTot = conexao ? . detalhes ? [ "bw_total_mbps" ] ? . Value < double? > ( ) ? ? 0.0 ;
2026-03-12 01:00:21 +00:00
string comunicacao = $"{conexao_latencia:0.00} ms {bwTot:0.00} Mbps" ;
string comunicacao_extended = $"{conexao_latencia:0.00} ms {conexao_perda:F2}% {bwTot:0.00} Mbps" ;
_viewOperacaoLeft ? . _vm ? . AtualizarRover (
rover ? . Descricao ? ? "" ,
2026-03-19 10:55:56 +00:00
obj . Controle ,
2026-03-12 01:00:21 +00:00
obj . Refrigeracao ? . Temperatura ? ? 0 ,
obj . Bateria ? . PercentualBateria ? ? 0 ,
obj . Atuador ? . PercentualReservatorio ? ? 0 ,
2026-03-19 10:55:56 +00:00
$"{saude_rede}%" ,
2026-03-17 00:43:15 +00:00
$"{obj.Gnss?.QualidadeFix ?? TiposCorrecaoGPS.SemCorrecao} {obj.Gnss?.PrecisaoCm:F2} cm" ,
2026-03-19 10:55:56 +00:00
AgroBase . Models . GPSUtils . DistanciaEntrePontos ( new AgroBase . Models . GPSModel ( ) { Latitude = obj . Gnss ? . Latitude ? ? 0 , Longitude = obj . Gnss ? . Longitude ? ? 0 } , Models . Variaveis . GpsService . UltimaLeitura ) ,
2026-03-17 00:43:15 +00:00
obj . Operacao ? . Iniciada ? ? false
2026-03-12 01:00:21 +00:00
) ;
2026-03-12 14:00:43 +00:00
// DIREITA (RESUMO)
2026-03-17 00:43:15 +00:00
_viewOperacaoRight ? . areaResumo ? . _vm ? . AtualizarResumo ( r = >
2026-03-12 01:00:21 +00:00
{
r . Operacao = ( obj . Operacao ? . Liberada ? ? false ) ? "🔓 Liberada" : "🔒 Bloqueada" ;
r . Modo = obj . Operacao = = null ? "-" : obj . Operacao . Modo . ToString ( ) ;
r . Status = obj . Operacao = = null ? "-" : $"{obj.Operacao.Status}" + ( obj . Operacao . Status = = AgroBase . Models . Enums . StatusOperacao . Aguardando ? $" ({obj.Operacao.TempoAguardandoSegs:0}s)" : "" ) ;
r . Carro = obj . Trajetoria = = null ? "-" : obj . Trajetoria . StatusCarro . ToString ( ) ;
2026-03-12 20:03:24 +00:00
r . Temperatura = $"{(obj.Refrigeracao?.Temperatura ?? 0):F2} °C" ;
r . RuaAtual = obj . Trajetoria = = null ? "-" : $"{obj.Trajetoria.CorredorAtualDistanciaPercorrida:F2} m / " + $"{obj.Trajetoria.CorredorAtualDistanciaTotal:0.00} m " + $"({obj.Trajetoria.CorredorAtualIdx + 1})" ;
2026-03-12 01:00:21 +00:00
r . AreaTotal = obj . Trajetoria = = null ? "-" : $"{obj.Trajetoria.DistanciaPercorrida:0.00} m / " + $"{obj.Trajetoria.DistanciaTotal:0.00} m" ;
r . Bateria = obj . Bateria = = null ? "-" : $"{obj.Bateria.TensaoInstantanea:0.00} V " + $"({TimeSpan.FromMinutes(obj.Bateria.TempoEstimadoRestanteMinutos):dd\\.hh\\:mm\\:ss} " + $"{obj.Bateria.DistanciaEstimadaRestanteMetros:0.00} m)" ;
r . Herbicida = obj . Atuador = = null ? "-" : $"{obj.Atuador.VolumeReservatorioL:0.00} L " + $"({TimeSpan.FromMinutes(obj.Atuador.TempoEstimadoRestanteMinutos):hh\\:mm\\:ss} " + $"{obj.Atuador.DistanciaEstimadaRestanteMetros:0.00} m)" ;
r . Infestacao = obj . Atuador = = null ? "-" : $"{obj.Atuador.HerbicidaPorAtuacaoMl:0.00} mL/atuação" ;
r . Conexao = comunicacao = = null ? "-" : $"{comunicacao}" ;
r . Duracao = obj . Operacao = = null ? "00:00:00 / 00:00:00" : $"{TimeSpan.FromSeconds(obj.Operacao.TempoDecorridoSegs):hh\\:mm\\:ss} / " + $"{(string.IsNullOrWhiteSpace(obj.Trajetoria?.TempoEstimadoOperacao) ? " 00 : 00 : 00 " : obj.Trajetoria.TempoEstimadoOperacao)}" ;
// Opcionais para progress bars, caso queira evoluir o resumo
r . RuaAtualPercentual = obj . Trajetoria ? . PercentualRuaAtual ? ? 0 ;
r . AreaTotalPercentual = obj . Trajetoria ? . PercentualOperacao ? ? 0 ;
r . BateriaPercentual = obj . Bateria ? . PercentualBateria ? ? 0 ;
r . HerbicidaPercentual = obj . Atuador ? . PercentualReservatorio ? ? 0 ;
r . InfestacaoPercentual = obj . Atuador ? . PercentualErvasTerreno ? ? 0 ;
} ) ;
2026-03-12 14:00:43 +00:00
// DIAGNOSTICO
2026-03-18 10:40:59 +00:00
AtualizarDadosDiagnostico ( rover ) ;
2026-03-12 01:00:21 +00:00
2026-04-07 10:51:05 +00:00
// CAMERAS
var snr = obj ? . Cameras ? . FirstOrDefault ( x = > x . dispositivo = = AgroBase . Models . Enums . T_Code . Snr ) ;
var cam = obj ? . Cameras ? . FirstOrDefault ( x = > x . dispositivo = = AgroBase . Models . Enums . T_Code . Cam ) ;
_viewOperacaoCenter ? . Monitoramento ? . _vm ? . AtualizarDadosCameras ( snr , cam , obj ? . OperadorVisual ? . StatusCarro , obj ? . Atuador ? . PercentualErvasNoRadar ) ;
2026-03-12 14:00:43 +00:00
// PULVERIZADOR
2026-04-07 10:51:05 +00:00
bool telaPulverizador = _viewOperacaoCenter ? . _vm ? . ConteudoAtual = = OperacaoCenterConteudo . Pulverizador ;
var bomba = obj . Atuador ? . Bombas ? . FirstOrDefault ( x = > x . ID = = "BMBLN" ) ;
var agitador = obj . Atuador ? . Bombas ? . FirstOrDefault ( x = > x . ID = = "BMBAGT" ) ;
if ( telaPulverizador )
{
_viewOperacaoCenter ? . Pulverizador ? . _vm ? . AtualizarParametrosTela ( new Views . Operacao . Monitoramento . PulverizadorSnapshot ( )
{
StatusGeralPulverizador = ( obj ? . ModulosSaude ? . FirstOrDefault ( x = > x . modulo = = T_Code . Atu ) ? . status ? ? StatusModulo . Desconectado ) . ToString ( ) ,
CameraErvasStatus = _viewOperacaoCenter ? . Monitoramento ? . _vm ? . CameraErvasStatus ? ? "" ,
ModoPulverizacaoTexto = ( rover ? . Controle ? . PulverizadorAutomatico ? ? false ) ? "Automático" : "Manual" ,
PulverizacaoLiberadaTexto = ( obj ? . ModulosSaude ? . FirstOrDefault ( x = > x . modulo = = T_Code . Atu ) ? . motivos ? . Any ( ) ? ? false ) ? "Liberado" : "Bloqueado" ,
StatusBombaTexto = ( bomba ? . ComandoEstado ? ? false ) ? "Ligado" : "Desligado" ,
StatusBombaTextoLido = ( bomba ? . LeituraEstado ? ? false ) ? "Ligado" : "Desligado" ,
PotenciaBombaValor = $"{(bomba?.ComandoPotencia ?? 0):F2} %" ,
PotenciaBombaValorLido = $"{(bomba?.ComandoPotencia ?? 0):F2} %" ,
ModoAgitadorTexto = ( rover ? . Controle ? . AtuAgitadorModo ? ? ModoAgitadorCalda . SemAgitacao ) . ToString ( ) ,
PotenciaAgitadorValor = $"{agitador?.ComandoPotencia ?? 0} %" ,
PotenciaAgitadorValorLido = $"{agitador?.LeituraPotencia ?? 0} %" ,
NivelTanqueValor = $"{(obj?.Atuador?.PercentualReservatorio ?? 0):F2} %" ,
NivelTanqueLitrosValor = $"{(obj?.Atuador?.VolumeReservatorioL ?? 0):F2} L" ,
PressaoLinhaValor = $"{(rover?.Controle?.AtuPressaoLinha ?? 0):F2} psi" ,
PressaoLinhaPsiValor = $"{(obj?.Atuador?.PressaoLinhaPsi ?? 0):F2} psi" ,
VazaoInstantaneaValor = $"{(obj?.Atuador?.VazaoInstantaneaMLs ?? 0):F2} mL/s" ,
VazaoMediaValor = $"média {(obj?.Atuador?.VazaoMediaMLs ?? 0):F2} mL/s" ,
AutonomiaDistanciaValor = $"{(obj?.Atuador?.DistanciaEstimadaRestanteMetros ?? 0):F2} m" ,
AutonomiaTempoValor = $"{FuncoesGlobais.ConverterSegundosParaHHmmss((int)(obj?.Atuador?.TempoEstimadoRestanteMinutos ?? 0) * 60)}" ,
VolumeVazadoValor = $"{(obj?.Atuador?.VolumeVazaoMl ?? 0):F2} mL" ,
TempoLigadoPulverizacaoValor = $"{FuncoesGlobais.ConverterSegundosParaHHmmss((int)(bomba?.TempoAtuado ?? 0) / 1000)}" ,
BicosAtivosValor = $"{(obj?.Atuador?.Bicos?.Count(x => x.ComandoEstado == true) ?? 0)} / {obj?.Atuador?.Bicos?.Count ?? 0}" ,
InfoComplementarBicosValor = $"vazão média: {(obj?.Atuador?.Bicos?.Where(x => x.ComandoEstado == true)?.Average(x => x.VazaoInstantaneaMLs) ?? 0)} mL/s" ,
PercentualErvasRadar = $"radar: {(obj?.Atuador?.PercentualErvasNoRadar ?? 0)} %" ,
PercentualErvasTerreno = $"terreno: {(obj?.Atuador?.PercentualErvasTerreno ?? 0)} %" ,
} ) ;
}
var ATU = telaPulverizador ? _viewOperacaoCenter . Pulverizador . areaPulverizador : _viewOperacaoCenter . Monitoramento . Pulverizador ;
2026-03-12 01:00:21 +00:00
ATU . ComprimentoBarraCm = AgroBase . Models . VariaveisEquipamento . ComprimentoBarraPulverizadoraCm ;
ATU . DistanciaEntreBicosCm = AgroBase . Models . VariaveisEquipamento . DistanciaEntreBicosCm ;
2026-03-12 14:00:43 +00:00
//ATU.AlturaBarra = obj?.Controle?.AlturaBarra ?? AgroBase.Models.VariaveisEquipamento.AlturaBarraPulverizadoraCm;
2026-03-12 01:00:21 +00:00
ATU . IsBombaOn = bomba ? . LeituraEstado ? ? false ;
ATU . PressaoLinha = obj ? . Atuador ? . PressaoLinhaPsi ? ? 0 ;
ATU . VazaoInstantanea = obj ? . Atuador ? . VazaoInstantaneaMLs ? ? 0 ;
ATU . TempoAtuado = ( bomba ? . TempoAtuado ? ? 0 ) / 1000.0 ;
double erroLateral = ( ( obj ? . Trajetoria ? . DistanciaEsquerda ? ? 0 ) - ( obj ? . Trajetoria ? . DistanciaDireita ? ? 0 ) ) / 2.0 * 100.0 ;
ATU . LarguraRuaCm = 100.0 ;
ATU . ErroLateralCm = erroLateral ;
if ( ATU . QtdBicos ! = obj ? . Atuador ? . Bicos ? . Count )
{
ATU . QtdBicos = obj ? . Atuador ? . Bicos ? . Count ? ? AgroBase . Models . VariaveisEquipamento . QuantidadeBicosPulverizadores ;
}
foreach ( var bico in ATU . Bicos )
{
var _bc = obj ? . Atuador ? . Bicos ? . FirstOrDefault ( x = > ( x . Posicao - 1 ) = = bico . Index ) ;
if ( _bc = = null ) continue ;
bico . OpeningAngle = _bc . AnguloAbertura ;
bico . AnguloControle = _bc . ComandoAngulo ;
bico . IsCommandOn = _bc . ComandoEstado ;
bico . IsSpraying = _bc . LeituraEstado ;
bico . Vazao = _bc . VazaoInstantaneaMLs ;
bico . Atuacoes = _bc . QtdAtuacoes ;
bico . TempoAtuado = _bc . TempoAtuado / 1000.0 ;
}
2026-03-12 14:00:43 +00:00
2026-03-12 20:03:24 +00:00
// HEADING
var HDG = _viewOperacaoCenter . Monitoramento . Heading ;
HDG . Heading = obj ? . Gnss ? . OrientacaoReal ? ? double . NaN ;
HDG . CourseHeading = obj ? . Trajetoria ? . AnguloCaminho ? ? double . NaN ;
2026-03-12 01:00:21 +00:00
2026-03-12 20:03:24 +00:00
// ATTITUDE
var IMU = _viewOperacaoCenter . Monitoramento . Attitude ;
if ( obj ? . Imu ? . InclinacaoFrontal ! = null ) IMU . PitchDeg = ( double ) obj . Imu . InclinacaoFrontal ;
if ( obj ? . Imu ? . InclinacaoLateral ! = null ) IMU . RollDeg = ( double ) obj . Imu . InclinacaoLateral ;
IMU . LateralError = erroLateral ;
2026-03-10 19:56:55 +00:00
2026-03-12 20:03:24 +00:00
2026-03-10 19:56:55 +00:00
}
2026-03-11 20:11:17 +00:00
private void AbrirDiagnosticoPeloAlerta ( AlertaModel alerta )
2026-03-10 19:56:55 +00:00
{
2026-03-11 20:11:17 +00:00
if ( alerta = = null )
return ;
2026-03-10 19:56:55 +00:00
2026-03-11 20:11:17 +00:00
_viewOperacaoRight ? . _vm ? . SelecionarRover ( alerta . Rover_ID ) ;
_viewOperacaoRight ? . _vm ? . SelecionarSecao ( SecaoRightBar . Diagnostico ) ;
_viewOperacaoCenter ? . Diagnostico ? . _vm ? . AbrirModuloPorAlerta ( alerta . Modulo , alerta . Mod_ID ) ;
2026-03-10 19:56:55 +00:00
}
2026-03-18 10:40:59 +00:00
public void AtualizarDadosDiagnostico ( OperacaoParametrosModel ? rover )
{
_viewOperacaoCenter ? . Diagnostico ? . _vm ? . AtualizarDados ( rover ) ;
_viewOperacaoCenter ? . Diagnostico ? . AtualizarGraficos ( ) ;
}
2026-03-10 19:56:55 +00:00
public void AdicionarAlerta ( string roverId , AgroBase . Models . Enums . T_Code modulo , SeveridadeAlerta severidade , string mensagem , string modId = null )
{
2026-03-11 20:11:17 +00:00
_viewOperacaoBottom ? . _vm ? . AdicionarAlerta ( roverId , modulo , severidade , mensagem , modId ) ;
2026-03-10 19:56:55 +00:00
}
public void RemoverAlerta ( string roverId , AgroBase . Models . Enums . T_Code modulo , SeveridadeAlerta ? severidade = null , string modId = null )
{
2026-03-11 20:11:17 +00:00
_viewOperacaoBottom ? . _vm ? . RemoverAlerta ( roverId , modulo , severidade , modId ) ;
2026-03-10 19:56:55 +00:00
}
2026-03-12 01:00:21 +00:00
2026-03-10 19:56:55 +00:00
private void OnRoverSelecionadoChanged ( string roverId )
{
_viewOperacaoRight ? . _vm ? . DestacarRoverNoMapa ( roverId ) ;
}
private void OnRoverSelecionadoChanged ( RoverCardModel rover )
{
bool dados_base = rover = = null ;
if ( dados_base )
{
if ( ! VariaveisControleOperacao . BaseEmFoco )
{
2026-03-11 20:11:17 +00:00
_viewOperacaoCenter ? . Monitoramento ? . PararStreamCameraFrontal ( ) ;
_viewOperacaoCenter ? . Monitoramento ? . PararStreamCameraErvas ( ) ;
2026-03-10 19:56:55 +00:00
VariaveisControleOperacao . EnviarComandoIniciarUDP ( VariaveisControleOperacao . RoverEmFoco ? . IP , false ) ;
}
AtualizarDadosMapa ( VariaveisControleOperacao . RoverEmFoco ) ;
VariaveisControleOperacao . SelectedRoverId = VariaveisControleOperacao . BaseMarkerID ;
2026-03-12 01:00:21 +00:00
_viewOperacaoCenter ? . Mapa ? . markers ? . SetMarkerFocused ( VariaveisControleOperacao . SelectedRoverId , true ) ;
2026-03-10 19:56:55 +00:00
_viewOperacaoCenter ? . _vm ? . SelecionarRoverLista ( rover ) ;
2026-03-12 22:16:15 +00:00
AtualizarBarraSuperior ( StatusModulo . Conectado , "BASE" , "VISÃO GERAL" , "Selecione um equipamento na lista à direita para configurá-lo" , "NORMAL" , "Aguardando" ) ;
2026-03-10 19:56:55 +00:00
_viewOperacaoLeft ? . _vm ? . DefinirSemRover ( ) ;
}
else
{
2026-03-17 00:43:15 +00:00
VariaveisControleOperacao . SelectedRoverId = ( rover . NumeroSerie ? ? "" ) . ToString ( ) ;
2026-03-12 01:00:21 +00:00
_viewOperacaoCenter ? . Mapa ? . markers ? . SetMarkerFocused ( VariaveisControleOperacao . SelectedRoverId , true ) ;
2026-03-10 19:56:55 +00:00
AtualizarDadosTela ( VariaveisControleOperacao . RoverEmFoco ) ;
2026-03-11 20:11:17 +00:00
_viewOperacaoCenter ? . Monitoramento ? . IniciarStreamCameraFrontal ( ) ;
_viewOperacaoCenter ? . Monitoramento ? . IniciarStreamCameraErvas ( ) ;
2026-03-10 19:56:55 +00:00
VariaveisControleOperacao . EnviarComandoIniciarUDP ( VariaveisControleOperacao . RoverEmFoco ? . IP , true ) ;
_viewOperacaoCenter ? . _vm ? . SelecionarRoverLista ( rover ) ;
2026-03-12 01:00:21 +00:00
AtualizarDadosMapa ( VariaveisControleOperacao . RoverEmFoco ) ;
2026-03-13 18:58:02 +00:00
AtualizarBarraSuperior ( VariaveisControleOperacao . RoverEmFoco ) ;
2026-03-17 19:45:43 +00:00
VariaveisControleOperacao . RequisitarParametrosOperacao ( ) ;
2026-03-10 19:56:55 +00:00
}
}
private void OnSecaoSelecionadaChanged ( SecaoRightBar secao )
{
2026-04-07 10:51:05 +00:00
switch ( secao )
{
case SecaoRightBar . Parametrizacao :
VariaveisControleOperacao . RequisitarParametrosOperacao ( ) ;
break ;
case SecaoRightBar . Pulverizador :
if ( _viewOperacaoCenter . Monitoramento . videoWeed . imageName ! = _viewOperacaoCenter . Pulverizador . imgVideo . Name )
{
_viewOperacaoCenter . Monitoramento . videoWeed . Parar ( ) ;
_viewOperacaoCenter . Monitoramento . videoWeed = new TcpVideoReceiver ( 5002 , _viewOperacaoCenter . Pulverizador . imgVideo ) ;
_viewOperacaoCenter . Monitoramento . videoWeed . Iniciar ( ) ;
}
break ;
default :
if ( _viewOperacaoCenter . Monitoramento . videoWeed . imageName ! = _viewOperacaoCenter . Monitoramento . imgVideoWeed . Name )
{
_viewOperacaoCenter . Monitoramento . videoWeed . Parar ( ) ;
_viewOperacaoCenter . Monitoramento . videoWeed = new TcpVideoReceiver ( 5002 , _viewOperacaoCenter . Monitoramento . imgVideoWeed ) ;
_viewOperacaoCenter . Monitoramento . videoWeed . Iniciar ( ) ;
}
break ;
}
2026-03-10 19:56:55 +00:00
_viewOperacaoCenter ? . _vm ? . DefinirSecao ( secao ) ;
2026-03-12 01:00:21 +00:00
AtualizarDadosMapa ( VariaveisControleOperacao . RoverEmFoco ) ;
2026-03-10 19:56:55 +00:00
}
private void OnLerParametrosSolicitado ( )
{
if ( VariaveisControleOperacao . RoverEmFoco = = null )
return ;
VariaveisControleOperacao . RequisitarParametrosOperacao ( ) ;
}
private void OnSalvarParametrosSolicitado ( OperacaoParametrosModel parametros )
{
2026-03-27 01:42:40 +00:00
var rover = VariaveisControleOperacao . RoverEmFoco ;
2026-03-27 10:45:24 +00:00
if ( parametros . Modo = = AgroBase . Models . Enums . ModoOperacao . RetornoBase & & ! ( rover . DadosLeitura ? . Operacao ? . Iniciada ? ? false ) )
2026-03-27 01:42:40 +00:00
{
var pontos = _viewOperacaoCenter ? . Mapa ? . _pontosSelecionados ;
if ( ! ( pontos ? . Any ( ) ? ? false ) )
{
System . Windows . MessageBox . Show ( "Clique no mapa para marcar os pontos por onde o equipamento deve seguir" , "Pontos não marcados" , MessageBoxButton . OK , MessageBoxImage . Warning ) ;
return ;
}
if ( System . Windows . MessageBox . Show ( $"Deseja iniciar a operação de retorno seguindo os {pontos.Count} pontos marcados no mapa, somando em {GPSUtils.DistanciaDoTrecho(pontos):F2} metros?" , "Confirmação" , MessageBoxButton . YesNo , MessageBoxImage . Question ) = = MessageBoxResult . Yes )
{
parametros . PontosRetorno = pontos . Select ( x = > new double [ ] { x . Latitude , x . Longitude } ) . ToList ( ) ;
VariaveisControleOperacao . EnviarComandoRetornoBase ( pontosRetorno : parametros . PontosRetorno ) ;
rover . PontosRetorno = parametros . PontosRetorno ;
Task . Run ( async ( ) = >
{
await Task . Delay ( 500 ) ;
_viewOperacaoRight ? . _vm ? . SelecionarSecao ( SecaoRightBar . Resumo ) ;
} ) ;
}
return ;
}
2026-05-27 19:32:31 +00:00
var tipoMapa = _viewOperacaoCenter ? . Mapa ? . TipoMapaSelecionado ? ? TipoMapaOperacao . Indefinido ;
2026-03-17 17:26:07 +00:00
var dadosMapa = _viewOperacaoCenter ? . Mapa ? . CriarDadosMapa ( ) ;
2026-03-30 19:45:33 +00:00
var ruasPercorrer = _viewOperacaoCenter ? . Mapa ? . RuasMapaCarregado ? . Where ( x = > x . Selected ) ? . OrderBy ( x = > x . OrderSelection . Value ) ? . Select ( x = > x . Id ) ? . ToList ( ) ? ? new List < string > ( ) ;
2026-03-18 12:48:33 +00:00
if ( rover ? . DadosLeitura ? . Operacao ? . Modo ! = parametros . Modo & & ( rover ? . DadosLeitura ? . Operacao ? . Iniciada ? ? false ) )
{
System . Windows . MessageBox . Show ( $"Já existe uma operação {rover?.DadosLeitura?.Operacao?.Modo ?? AgroBase.Models.Enums.ModoOperacao.NaoDefinido} em andamento. Finalize a operação atual para salvar os novos parametros." , "Mudança de Operação" , MessageBoxButton . OK , MessageBoxImage . Warning ) ;
return ;
}
2026-03-17 17:26:07 +00:00
2026-03-18 12:48:33 +00:00
if ( ! ( rover ? . DadosLeitura ? . Operacao ? . Iniciada ? ? false ) & & parametros . Modo = = AgroBase . Models . Enums . ModoOperacao . MapaGPS & & ( ( dadosMapa ? . features ? . Count ? ? 0 ) = = 0 | | ! ruasPercorrer . Any ( ) ) )
2026-03-17 17:26:07 +00:00
{
System . Windows . MessageBox . Show ( "Selecione as ruas no mapa onde o equipamento irá operar" , "Ruas não selecionadas" , MessageBoxButton . OK , MessageBoxImage . Warning ) ;
return ;
}
2026-03-18 10:40:59 +00:00
if ( rover = = null )
2026-03-10 19:56:55 +00:00
return ;
2026-03-18 10:40:59 +00:00
if ( parametros ? . Controle ? . MovimentoAutomatico ? ? false )
{
var _mov = parametros ? . ModulosMandatorios ? . FirstOrDefault ( x = > x . Dispositivo = = T_Code . Mov ) ;
if ( _mov = = null )
{
_mov = new AgroBase . Models . OperacaoModulosMandatoriosModel ( )
{
Dispositivo = T_Code . Mov ,
Utilizar = true ,
Mandatorio = true ,
ComponentesEmUso = new Dictionary < string , ( bool , bool ) > ( )
{
{ "ET" , ( true , true ) } ,
{ "DT" , ( true , true ) } ,
{ "EF" , ( true , true ) } ,
{ "DF" , ( true , true ) } ,
}
} ;
}
else
{
foreach ( var key in _mov . ComponentesEmUso ? . Keys . ToList ( ) ? ? new List < string > ( ) )
{
_mov . ComponentesEmUso [ key ] = ( true , true ) ;
}
_mov . Utilizar = true ;
_mov . Mandatorio = true ;
}
}
if ( parametros ? . Controle ? . DirecionalAutomatico ? ? false )
{
var _dir = parametros ? . ModulosMandatorios ? . FirstOrDefault ( x = > x . Dispositivo = = T_Code . Dir ) ;
if ( _dir = = null )
{
_dir = new AgroBase . Models . OperacaoModulosMandatoriosModel ( )
{
Dispositivo = T_Code . Dir ,
Utilizar = true ,
Mandatorio = true ,
ComponentesEmUso = new Dictionary < string , ( bool , bool ) > ( )
{
{ "ET" , ( true , true ) } ,
{ "DT" , ( true , true ) } ,
{ "EF" , ( true , true ) } ,
{ "DF" , ( true , true ) } ,
}
} ;
}
else
{
foreach ( var key in _dir . ComponentesEmUso ? . Keys . ToList ( ) ? ? new List < string > ( ) )
{
_dir . ComponentesEmUso [ key ] = ( true , true ) ;
}
_dir . Utilizar = true ;
_dir . Mandatorio = true ;
}
}
if ( parametros ? . Controle ? . PulverizadorAutomatico ? ? false )
{
var _atu = parametros ? . ModulosMandatorios ? . FirstOrDefault ( x = > x . Dispositivo = = T_Code . Atu ) ;
if ( _atu = = null )
{
_atu = new AgroBase . Models . OperacaoModulosMandatoriosModel ( )
{
Dispositivo = T_Code . Atu ,
Utilizar = true ,
Mandatorio = true ,
ComponentesEmUso = new Dictionary < string , ( bool , bool ) > ( )
{
{ "MASRS" , ( true , true ) } ,
{ "FLXLN" , ( true , true ) } ,
{ "PRSLN" , ( true , true ) } ,
{ "BOMBA" , ( true , true ) } ,
{ "B01" , ( true , true ) } ,
{ "B02" , ( true , true ) } ,
{ "B03" , ( true , true ) } ,
{ "B04" , ( true , true ) } ,
{ "B05" , ( true , true ) } ,
{ "B06" , ( true , true ) } ,
{ "B07" , ( true , true ) } ,
}
} ;
}
else
{
foreach ( var key in _atu . ComponentesEmUso ? . Keys . ToList ( ) ? ? new List < string > ( ) )
{
_atu . ComponentesEmUso [ key ] = ( true , true ) ;
}
_atu . Utilizar = true ;
_atu . Mandatorio = true ;
}
}
if ( parametros ? . Controle ? . ImuParadaPorInclinacao ? ? false )
{
var _imu = parametros . ModulosMandatorios ? . FirstOrDefault ( x = > x . Dispositivo = = T_Code . Imu ) ;
if ( _imu = = null )
{
_imu = new AgroBase . Models . OperacaoModulosMandatoriosModel ( )
{
Dispositivo = T_Code . Imu ,
Utilizar = true ,
Mandatorio = true ,
} ;
parametros ? . ModulosMandatorios ? . Add ( _imu ) ;
}
else
{
_imu . Utilizar = true ;
_imu . Mandatorio = true ;
}
}
if ( parametros ? . Controle ? . OakParadaPorObstaculo ? ? false )
{
var _snr = parametros . ModulosMandatorios ? . FirstOrDefault ( x = > x . Dispositivo = = T_Code . Snr ) ;
if ( _snr = = null )
{
_snr = new AgroBase . Models . OperacaoModulosMandatoriosModel ( )
{
Dispositivo = T_Code . Snr ,
Utilizar = true ,
Mandatorio = true ,
} ;
parametros ? . ModulosMandatorios ? . Add ( _snr ) ;
}
else
{
_snr . Utilizar = true ;
_snr . Mandatorio = true ;
}
}
2026-03-10 19:56:55 +00:00
2026-03-12 01:00:21 +00:00
var novosParametros = new OperacaoParametrosModel ( )
2026-03-10 19:56:55 +00:00
{
2026-03-16 19:22:06 +00:00
Modo = parametros . Modo ,
2026-03-10 19:56:55 +00:00
Descricao = parametros . Descricao ,
QtdCamerasSolo = parametros . QtdCamerasSolo ,
QtdBicos = parametros . QtdBicos ,
CapacidadeReservatorio = parametros . CapacidadeReservatorio ,
Controle = parametros . Controle ,
2026-03-16 19:22:06 +00:00
ModulosMandatorios = parametros ? . ModulosMandatorios ,
ParametrosMandatorios = parametros ? . ParametrosMandatorios ,
2026-03-10 19:56:55 +00:00
2026-05-27 19:32:31 +00:00
TipoMapa = tipoMapa ,
2026-03-17 19:45:43 +00:00
RuasPercorrer = ruasPercorrer ,
Mapa = dadosMapa
2026-03-12 01:00:21 +00:00
} ;
VariaveisControleOperacao . EnviarParametrosOperacao ( novosParametros ) ;
2026-03-18 10:40:59 +00:00
rover . Modo = novosParametros . Modo ;
rover . Descricao = novosParametros . Descricao ;
rover . QtdCamerasSolo = novosParametros . QtdCamerasSolo ;
rover . QtdBicos = novosParametros . QtdBicos ;
rover . CapacidadeReservatorio = novosParametros . CapacidadeReservatorio ;
rover . Controle = novosParametros . Controle ;
rover . ModulosMandatorios = novosParametros . ModulosMandatorios ;
rover . ParametrosMandatorios = novosParametros . ParametrosMandatorios ;
2026-03-27 01:42:40 +00:00
rover . PontosRetorno = novosParametros . PontosRetorno ;
2026-05-27 19:32:31 +00:00
rover . TipoMapa = novosParametros . TipoMapa ;
rover . RuasPercorrer = novosParametros . RuasPercorrer ;
2026-03-18 10:40:59 +00:00
rover . Mapa = novosParametros . Mapa ;
AtualizarDadosDiagnostico ( rover ) ;
Task . Run ( async ( ) = >
{
await Task . Delay ( 500 ) ;
_viewOperacaoRight ? . _vm ? . SelecionarSecao ( SecaoRightBar . Diagnostico ) ;
} ) ;
2026-03-10 19:56:55 +00:00
}
#endregion
}
public enum ModoOperacao
{
Automatico = 1 ,
Manual = 2
}
public enum DockStep
{
ConfigConexao = 1 ,
PreparacaoMapa = 2 ,
ParametrizacaoRover = 3
}
}