2025-11-14 17:11:58 +00:00
using AgroBase.Models ;
using Newtonsoft.Json ;
using System.Diagnostics ;
using OperationControl.Services ;
2025-11-24 16:05:50 +00:00
using AgroMonitor ;
using Application = System . Windows . Application ;
using AgroBase.Models.Operacoes ;
2025-11-14 17:11:58 +00:00
namespace OperationControl.Models
{
public class Variaveis
{
public static MqttService MqttService ;
public static GpsService GpsService ;
public static void MostrarLog ( string message )
{
Debug . WriteLine ( message ) ;
}
public static async void IniciarMQTT ( )
{
if ( MqttService ! = null )
{
foreach ( var topico in MqttService . Topicos . Where ( x = > x . Inscrever ) )
{
await MqttService . UnsubscribeAsync ( topico ) ;
}
MqttService . Topicos . Clear ( ) ;
}
MqttService = new MqttService ( "localhost" , 1883 , "base" , true , msg = > MostrarLog ( $"[MQTT localhost:1883] - {msg}" ) ) ;
2025-11-24 16:05:50 +00:00
await MqttService . AdicionarNovoTopico ( VariaveisMonitoramento . TopicoMqttPosicao ) ;
await MqttService . AdicionarNovoTopico ( VariaveisMonitoramento . TopicoMqttRTCM ) ;
await MqttService . AdicionarNovoTopico ( VariaveisMonitoramento . TopicoMqttDispositivos , true , 1 , async ( message ) = >
2025-11-14 17:11:58 +00:00
{
try
{
string device_id = message . Mensagem ;
VariaveisControleOperacao . AdicionarNovoRoverNaRede ( message . Mensagem ) ;
}
catch ( Exception ex )
{
MostrarLog ( $"Erro ao deserializar ping do rover: {ex.Message}" ) ;
}
} ) ;
GpsService = new GpsService ( ) ;
}
}
public class VariaveisControleOperacao
{
2025-11-24 16:05:50 +00:00
public static double LeverArmFrontal { get ; } = 0.0 ; // cm
public static double LeverArmLateral { get ; } = 0.0 ; // cm
2025-11-14 17:11:58 +00:00
public static readonly string BaseMarkerID = "BASE" ;
private static readonly object _RoversLock = new object ( ) ;
2025-11-24 16:05:50 +00:00
private static double TempoRoverVivo = 5.0 ;
private static bool AdicionandoNovoRover = false ;
private static bool AtualizandoListaRovers = false ;
2025-11-26 20:00:16 +00:00
public static AgroBase . Models . Enums . StatusModulo StatusBase
{
get
{
if ( ( Variaveis . GpsService ? . IsConnected ? ? false ) & & ( Variaveis . GpsService ? . BaseFix ? . CorrecaoAbsoluta ? ? false ) )
return AgroBase . Models . Enums . StatusModulo . Operante ;
if ( Variaveis . GpsService ? . IsConnected ? ? false )
return AgroBase . Models . Enums . StatusModulo . Alerta ;
return AgroBase . Models . Enums . StatusModulo . Desconectado ;
}
}
2025-11-24 16:05:50 +00:00
public static List < OperacaoParametrosModel > RoversNaRede { get ; set ; } = new List < OperacaoParametrosModel > ( ) ;
2025-11-14 17:11:58 +00:00
public static string SelectedRoverId { get ; set ; } = BaseMarkerID ;
2025-11-24 16:05:50 +00:00
public static OperacaoParametrosModel ? RoverEmFoco = > RoversNaRede . FirstOrDefault ( x = > x . RoverId = = SelectedRoverId ) ;
public static bool BaseEmFoco = > SelectedRoverId = = BaseMarkerID ;
2025-11-14 17:11:58 +00:00
public static async void AdicionarNovoRoverNaRede ( string device_id )
{
2025-11-24 16:05:50 +00:00
if ( AdicionandoNovoRover ) return ;
AdicionandoNovoRover = true ;
2025-11-14 17:11:58 +00:00
2025-11-24 16:05:50 +00:00
try
2025-11-14 17:11:58 +00:00
{
2025-11-24 16:05:50 +00:00
if ( string . IsNullOrEmpty ( device_id ) )
return ;
2025-11-14 17:11:58 +00:00
2025-11-24 16:05:50 +00:00
bool rover_ja_adicionado = false ;
2025-11-14 17:11:58 +00:00
lock ( _RoversLock )
{
2025-11-24 16:05:50 +00:00
rover_ja_adicionado = RoversNaRede . Any ( x = > x . RoverId = = device_id ) ;
2025-11-14 17:11:58 +00:00
}
2025-11-24 16:05:50 +00:00
if ( ! rover_ja_adicionado )
2025-11-14 17:11:58 +00:00
{
2025-11-24 16:05:50 +00:00
lock ( _RoversLock )
2025-11-14 17:11:58 +00:00
{
2025-11-24 16:05:50 +00:00
RoversNaRede . Add ( new OperacaoParametrosModel ( )
2025-11-14 17:11:58 +00:00
{
2025-11-24 16:05:50 +00:00
RoverId = device_id ,
Configurado = false ,
Alive = true ,
2025-12-17 19:27:06 +00:00
DadosLeitura = new OperacaoParametrosDadosModel ( )
2025-11-24 16:05:50 +00:00
{
Momento = DateTime . Now
}
} ) ;
2025-11-14 17:11:58 +00:00
}
2025-11-24 16:05:50 +00:00
bool t_hbt_added = Variaveis . MqttService . Topicos . Any ( x = > x . Topico = = VariaveisEquipamento . TopicoMqttHeartbeat . Replace ( "<id>" , device_id ) ) ;
if ( ! t_hbt_added )
await Variaveis . MqttService . AdicionarNovoTopico ( VariaveisEquipamento . TopicoMqttHeartbeat . Replace ( "<id>" , device_id ) ) ;
bool t_cmd_added = Variaveis . MqttService . Topicos . Any ( x = > x . Topico = = VariaveisEquipamento . TopicoMqttComandos . Replace ( "<id>" , device_id ) ) ;
if ( ! t_cmd_added )
await Variaveis . MqttService . AdicionarNovoTopico ( VariaveisEquipamento . TopicoMqttComandos . Replace ( "<id>" , device_id ) ) ;
bool t_tel_added = Variaveis . MqttService . Topicos . Any ( x = > x . Topico = = VariaveisEquipamento . TopicoMqttTelemetria . Replace ( "<id>" , device_id ) ) ;
if ( ! t_tel_added )
await Variaveis . MqttService . AdicionarNovoTopico ( VariaveisEquipamento . TopicoMqttTelemetria . Replace ( "<id>" , device_id ) , true , 1 , async ( message ) = >
{
try
{
string json = message . Mensagem ;
if ( string . IsNullOrEmpty ( json ) ) return ;
2025-12-17 19:27:06 +00:00
var obj = JsonConvert . DeserializeObject < OperacaoParametrosDadosModel > ( json ) ;
2025-11-25 20:14:31 +00:00
if ( obj = = null ) return ;
2025-11-24 16:05:50 +00:00
lock ( _RoversLock )
{
var rover = RoversNaRede . FirstOrDefault ( x = > x . RoverId = = device_id ) ;
if ( rover ! = null )
{
obj . Momento = DateTime . Now ;
rover . DadosLeitura = obj ;
2025-12-04 13:51:11 +00:00
rover . UltimoContato = DateTime . Now ;
2025-11-24 16:05:50 +00:00
}
}
( ( App ) Application . Current ) . Shell . Main ? . AtualizarDadosTela_Telemetria ( device_id ) ;
}
catch ( Exception ex )
{
Variaveis . MostrarLog ( $"Erro ao deserializar dados de telemetria do rover {device_id}: {ex.Message}" ) ;
}
} ) ;
bool t_par_added = Variaveis . MqttService . Topicos . Any ( x = > x . Topico = = VariaveisEquipamento . TopicoMqttParametros . Replace ( "<id>" , device_id ) ) ;
if ( ! t_par_added )
await Variaveis . MqttService . AdicionarNovoTopico ( VariaveisEquipamento . TopicoMqttParametros . Replace ( "<id>" , device_id ) , true , 1 , async ( message ) = >
{
try
{
string json = message . Mensagem ;
if ( string . IsNullOrEmpty ( json ) ) return ;
var obj = JsonConvert . DeserializeObject < OperacaoParametrosModel > ( json ) ;
lock ( _RoversLock )
{
var rover = RoversNaRede . FirstOrDefault ( x = > x . RoverId = = device_id ) ;
if ( rover ! = null )
{
2025-12-04 13:51:11 +00:00
obj . UltimoContato = DateTime . Now ;
2025-11-25 12:17:19 +00:00
RoversNaRede . Remove ( rover ) ;
RoversNaRede . Add ( obj ) ;
2025-11-24 16:05:50 +00:00
}
}
2025-11-24 19:58:20 +00:00
( ( App ) Application . Current ) . Shell . Main ? . AtualizarDadosTela_ParametrosOperacao ( obj . Controle ) ;
2025-12-04 13:51:11 +00:00
( ( App ) Application . Current ) . Shell . Main ? . MAP ? . CarregarDadosMapa ( obj . Mapa , obj . RuasPercorrer ) ;
2025-11-24 16:05:50 +00:00
}
catch ( Exception ex )
{
Variaveis . MostrarLog ( $"Erro ao deserializar dados de parametros do rover {device_id}: {ex.Message}" ) ;
}
} ) ;
List < string > dispositivos_ids = new List < string > ( ) { "BASE" } ;
lock ( _RoversLock )
2025-11-14 17:11:58 +00:00
{
2025-11-24 16:05:50 +00:00
dispositivos_ids = dispositivos_ids . Union ( RoversNaRede . Select ( x = > x . RoverId ) . ToList ( ) ) . ToList ( ) ;
2025-11-14 17:11:58 +00:00
}
2025-11-24 16:05:50 +00:00
( ( App ) Application . Current ) . Shell . Main ? . AtualizarListaDispositivos ( dispositivos_ids ) ;
2025-11-24 19:58:20 +00:00
RequisitarParametrosOperacao ( ) ;
2025-11-24 16:05:50 +00:00
}
}
finally
{
AdicionandoNovoRover = false ;
2025-11-14 17:11:58 +00:00
}
}
public static async void AtualizarListaRoversNaRede ( )
{
2025-11-24 16:05:50 +00:00
if ( AtualizandoListaRovers ) return ;
AtualizandoListaRovers = true ;
try
2025-11-14 17:11:58 +00:00
{
2025-11-24 16:05:50 +00:00
var rovers_atual = new List < OperacaoParametrosModel > ( ) ;
lock ( _RoversLock )
2025-11-14 17:11:58 +00:00
{
2025-11-24 16:05:50 +00:00
rovers_atual = new List < OperacaoParametrosModel > ( RoversNaRede ) ;
2025-11-14 17:11:58 +00:00
}
2025-11-24 16:05:50 +00:00
foreach ( var rover in rovers_atual )
2025-11-14 17:11:58 +00:00
{
2025-12-04 13:51:11 +00:00
rover . Alive = ( DateTime . Now - rover . UltimoContato ) . TotalSeconds < TempoRoverVivo ;
2025-11-24 16:05:50 +00:00
if ( ! rover . Alive )
2025-11-14 17:11:58 +00:00
{
2025-11-28 19:44:53 +00:00
//((App)Application.Current).Shell.Main?.MAP?.markers?.UpdateMarkerInfo(rover.RoverId, status: AgroBase.Models.Enums.StatusOperacao.Erro);
2025-12-17 19:27:06 +00:00
rover . DadosLeitura = new OperacaoParametrosDadosModel ( ) ;
2025-11-28 19:44:53 +00:00
rover . DadosLeitura . Momento = DateTime . Now ;
2025-12-17 19:27:06 +00:00
rover . DadosLeitura . Operacao . Status = AgroBase . Models . Enums . StatusOperacao . Erro ;
2025-11-28 19:44:53 +00:00
( ( App ) Application . Current ) . Shell . Main ? . AtualizarDadosTela_Telemetria ( rover . RoverId ) ;
2025-12-04 13:51:11 +00:00
( ( App ) Application . Current ) . Shell . Main ? . AdicionarAlerta ( rover . RoverId , AgroBase . Models . Enums . T_Code . Ipb , SeveridadeAlerta . Critical , "Perda de comunicação com o equipamento!" ) ;
}
else
{
( ( App ) Application . Current ) . Shell . Main ? . RemoverAlerta ( rover . RoverId , AgroBase . Models . Enums . T_Code . Ipb ) ;
2025-11-14 17:11:58 +00:00
}
}
2025-11-24 16:05:50 +00:00
}
finally
{
AtualizandoListaRovers = false ;
}
}
public static async void EnviarDadosHeartbeat ( )
{
var topicos = Variaveis . MqttService . Topicos . Where ( x = > x . Topico . Contains ( VariaveisEquipamento . TopicoMqttHeartbeat . Split ( "/" ) [ VariaveisEquipamento . TopicoMqttHeartbeat . Split ( "/" ) . Length - 1 ] ) ) ;
foreach ( var topico in topicos )
{
await Variaveis . MqttService . PublishAsync ( topico , "0" ) ;
2025-11-14 17:11:58 +00:00
}
}
2025-11-24 16:05:50 +00:00
private static async void EnviarDadosControle ( string rover_id , OperacaoComandoBaseModel controle )
2025-11-14 17:11:58 +00:00
{
var topico = Variaveis . MqttService . Topicos . FirstOrDefault ( x = > x . Topico = = VariaveisEquipamento . TopicoMqttComandos . Replace ( "<id>" , rover_id ) ) ;
if ( topico ! = null )
{
string json = JsonConvert . SerializeObject ( controle ) ;
await Variaveis . MqttService . PublishAsync ( topico , json ) ;
}
}
public static async void EnviarDadosPosicao ( GPSModel posicao )
{
2025-11-24 16:05:50 +00:00
var topico = Variaveis . MqttService . Topicos . FirstOrDefault ( x = > x . Topico = = VariaveisMonitoramento . TopicoMqttPosicao ) ;
2025-11-14 17:11:58 +00:00
if ( topico ! = null )
{
string json = JsonConvert . SerializeObject ( posicao ) ;
await Variaveis . MqttService . PublishAsync ( topico , json ) ;
}
}
public static async void EnviarDadosCorrecaoRTCM ( byte [ ] correcao )
{
2025-11-24 16:05:50 +00:00
var topico = Variaveis . MqttService . Topicos . FirstOrDefault ( x = > x . Topico = = VariaveisMonitoramento . TopicoMqttRTCM ) ;
2025-11-14 17:11:58 +00:00
if ( topico ! = null )
{
await Variaveis . MqttService . PublishAsync ( topico , correcao ) ;
}
}
2025-11-24 16:05:50 +00:00
#region Controle
public static void EnviarComandoIniciarOperacao ( bool iniciar , bool simulador = false )
{
EnviarDadosControle ( SelectedRoverId , new OperacaoComandoBaseModel ( )
{
Momento = DateTime . Now ,
Dispositivo = AgroBase . Models . Enums . T_Code . Mod ,
2025-11-25 12:17:19 +00:00
Tecla = simulador ? AgroBase . Models . Enums . BotoesJoystick . L1 : iniciar ? AgroBase . Models . Enums . BotoesJoystick . L2 : AgroBase . Models . Enums . BotoesJoystick . L3
2025-11-24 16:05:50 +00:00
} ) ;
}
public static void EnviarComandoTransmissaoVideo ( AgroBase . Models . Enums . T_Code disp , bool ligar )
{
EnviarDadosControle ( SelectedRoverId , new OperacaoComandoBaseModel ( )
{
Momento = DateTime . Now ,
Dispositivo = disp ,
Tecla = ligar ? AgroBase . Models . Enums . BotoesJoystick . L1 : AgroBase . Models . Enums . BotoesJoystick . Vazio
} ) ;
}
public static void EnviarComandoParada ( bool? emergencia = null , bool? pausa = null )
{
var cmd = new OperacaoComandoBaseModel ( ) { Momento = DateTime . Now } ;
if ( emergencia ! = null ) cmd . Emergencia = ( bool ) emergencia ;
if ( pausa ! = null ) cmd . Pausa = ( bool ) pausa ;
if ( emergencia ! = null | | pausa ! = null )
EnviarDadosControle ( SelectedRoverId , cmd ) ;
}
2025-11-28 19:44:53 +00:00
public static void EnviarComandoReferenciamento ( string mod_id = null )
2025-11-24 16:05:50 +00:00
{
EnviarDadosControle ( SelectedRoverId , new OperacaoComandoBaseModel ( )
{
Momento = DateTime . Now ,
2025-11-26 20:00:16 +00:00
Dispositivo = AgroBase . Models . Enums . T_Code . Dir ,
2025-11-28 19:44:53 +00:00
Tecla = AgroBase . Models . Enums . BotoesJoystick . R3 ,
_comp_id = mod_id
2025-11-24 16:05:50 +00:00
} ) ;
}
2025-11-28 19:44:53 +00:00
public static void EnviarComandoLeverArm ( double? lateral = null , double? frontal = null )
2025-11-24 16:05:50 +00:00
{
2025-11-28 19:44:53 +00:00
var cmd = new OperacaoComandoBaseModel ( )
2025-11-24 16:05:50 +00:00
{
Momento = DateTime . Now ,
2025-12-11 18:27:19 +00:00
Dispositivo = AgroBase . Models . Enums . T_Code . Gps ,
_comp_value = ( lateral , frontal )
2025-11-28 19:44:53 +00:00
} ;
EnviarDadosControle ( SelectedRoverId , cmd ) ;
2025-11-24 16:05:50 +00:00
}
public static void EnviarParametrosOperacao ( OperacaoParametrosModel parametros )
{
2025-12-17 19:27:06 +00:00
bool operacao_iniciada = ( RoverEmFoco ? . DadosLeitura ? . Operacao ? . Iniciada ? ? false ) ;
2025-11-25 20:14:31 +00:00
bool parametros_parciais = parametros . Modo = = null ;
2025-11-24 16:05:50 +00:00
EnviarDadosControle ( SelectedRoverId , new OperacaoComandoBaseModel ( )
{
Momento = DateTime . Now ,
2025-11-25 12:17:19 +00:00
Dispositivo = AgroBase . Models . Enums . T_Code . Mod ,
2025-11-24 16:05:50 +00:00
Parametros = parametros ,
2025-11-25 20:14:31 +00:00
Tecla = ( operacao_iniciada | | parametros_parciais ? AgroBase . Models . Enums . BotoesJoystick . Touchpad : AgroBase . Models . Enums . BotoesJoystick . Options )
2025-11-24 16:05:50 +00:00
} ) ;
}
2025-12-10 19:06:22 +00:00
public static void EnviarConfirmacaoHumanaTrajetoria ( int idx_corredor , bool bat_liberada , bool herb_liberado )
2025-12-10 16:37:47 +00:00
{
EnviarDadosControle ( SelectedRoverId , new OperacaoComandoBaseModel ( )
{
Momento = DateTime . Now ,
Dispositivo = AgroBase . Models . Enums . T_Code . Mod ,
Tecla = AgroBase . Models . Enums . BotoesJoystick . R1 ,
2025-12-10 19:06:22 +00:00
_comp_value = ( idx_corredor , bat_liberada , herb_liberado )
2025-12-10 16:37:47 +00:00
} ) ;
}
2025-12-11 18:27:19 +00:00
public static void EnviarComandoCoolerControl ( AgroBase . Services . CoolerControlService . CoolerMode modo , AgroBase . Models . Enums . Estado ? entrada = null , AgroBase . Models . Enums . Estado ? saida = null , double? temp_on = null , double? temp_turbo = null )
{
EnviarDadosControle ( SelectedRoverId , new OperacaoComandoBaseModel ( )
{
Momento = DateTime . Now ,
Dispositivo = AgroBase . Models . Enums . T_Code . Npc ,
_comp_value = ( modo , entrada , saida , temp_on , temp_turbo )
} ) ;
}
2025-11-24 19:58:20 +00:00
public static void RequisitarParametrosOperacao ( )
{
EnviarDadosControle ( SelectedRoverId , new OperacaoComandoBaseModel ( )
{
Momento = DateTime . Now ,
2025-11-25 12:17:19 +00:00
Dispositivo = AgroBase . Models . Enums . T_Code . Mod ,
2025-11-24 19:58:20 +00:00
Tecla = AgroBase . Models . Enums . BotoesJoystick . Share
} ) ;
}
2025-11-26 20:00:16 +00:00
private static AgroBase . Models . Enums . BotoesJoystick DeParaDirecaoTecla ( AgroBase . Models . Enums . Direcao direcao )
{
switch ( direcao )
{
case AgroBase . Models . Enums . Direcao . Esquerda :
return AgroBase . GeneralJoystick . DeParaComandos . FirstOrDefault ( x = > x . key = = Keys . Left ) ? . botaoJoy ? ? AgroBase . Models . Enums . BotoesJoystick . Vazio ;
case AgroBase . Models . Enums . Direcao . Direita :
return AgroBase . GeneralJoystick . DeParaComandos . FirstOrDefault ( x = > x . key = = Keys . Right ) ? . botaoJoy ? ? AgroBase . Models . Enums . BotoesJoystick . Vazio ;
case AgroBase . Models . Enums . Direcao . Cima :
return AgroBase . GeneralJoystick . DeParaComandos . FirstOrDefault ( x = > x . key = = Keys . Up ) ? . botaoJoy ? ? AgroBase . Models . Enums . BotoesJoystick . Vazio ;
case AgroBase . Models . Enums . Direcao . Baixo :
return AgroBase . GeneralJoystick . DeParaComandos . FirstOrDefault ( x = > x . key = = Keys . Down ) ? . botaoJoy ? ? AgroBase . Models . Enums . BotoesJoystick . Vazio ;
default :
return AgroBase . Models . Enums . BotoesJoystick . Vazio ;
}
}
2025-11-28 19:44:53 +00:00
public static void EnviarComandoDirecional ( AgroBase . Models . Enums . Direcao direcao , double angulo , AgroBase . Models . Enums . TipoMovimentoDirecional movimento , string mod_id = null )
2025-11-26 20:00:16 +00:00
{
EnviarDadosControle ( SelectedRoverId , new OperacaoComandoBaseModel ( )
{
Momento = DateTime . Now ,
Dispositivo = AgroBase . Models . Enums . T_Code . Dir ,
Tecla = DeParaDirecaoTecla ( direcao ) ,
2025-11-28 19:44:53 +00:00
_comp_id = mod_id ,
2025-11-26 20:00:16 +00:00
Controle = new OperacaoComandoBaseControleModel ( )
{
AnguloSP = angulo ,
TipoMovimentoDirecional = movimento
2025-11-28 19:44:53 +00:00
} ,
2025-11-26 20:00:16 +00:00
} ) ;
}
public static void EnviarComandoMovimentacao ( AgroBase . Models . Enums . Direcao direcao , double velocidade )
{
EnviarDadosControle ( SelectedRoverId , new OperacaoComandoBaseModel ( )
{
Momento = DateTime . Now ,
Dispositivo = AgroBase . Models . Enums . T_Code . Mov ,
Tecla = DeParaDirecaoTecla ( direcao ) ,
Controle = new OperacaoComandoBaseControleModel ( )
{
PercentualVelocidadeSP = velocidade
}
} ) ;
}
2025-12-02 18:42:15 +00:00
public static void EnviarComandoAtuador ( string componente_id , bool? status = null , int? angulo_controle = null , double? angulo_abertura = null , double? altura = null )
2025-11-25 20:14:31 +00:00
{
EnviarDadosControle ( SelectedRoverId , new OperacaoComandoBaseModel ( )
{
Momento = DateTime . Now ,
Dispositivo = AgroBase . Models . Enums . T_Code . Atu ,
_comp_id = componente_id ,
2025-12-02 18:42:15 +00:00
_comp_value = angulo_abertura ,
Controle = new OperacaoComandoBaseControleModel ( )
{
AnguloSP = angulo_controle ,
Estado = status ,
Altura = altura ,
}
2025-11-25 20:14:31 +00:00
} ) ;
}
public static void EnviarComandoSensoriamento ( string componente_id , dynamic status )
{
EnviarDadosControle ( SelectedRoverId , new OperacaoComandoBaseModel ( )
{
Momento = DateTime . Now ,
Dispositivo = AgroBase . Models . Enums . T_Code . Sen ,
_comp_id = componente_id ,
_comp_value = status
} ) ;
}
2025-11-24 16:05:50 +00:00
#endregion
2025-11-14 17:11:58 +00:00
}
}