using AgroBase.Models; using Newtonsoft.Json; using System.Diagnostics; using OperationControl.Services; using AgroMonitor; using Application = System.Windows.Application; using AgroBase.Models.Operacoes; 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}")); await MqttService.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttPosicao); await MqttService.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttRTCM); await MqttService.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttDispositivos, true, 1, async (message) => { 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 { public static double LeverArmFrontal { get; } = 0.0; // cm public static double LeverArmLateral { get; } = 0.0; // cm public static readonly string BaseMarkerID = "BASE"; private static readonly object _RoversLock = new object(); private static double TempoRoverVivo = 5.0; private static bool AdicionandoNovoRover = false; private static bool AtualizandoListaRovers = false; public static List RoversNaRede { get; set; } = new List(); public static string SelectedRoverId { get; set; } = BaseMarkerID; public static OperacaoParametrosModel? RoverEmFoco => RoversNaRede.FirstOrDefault(x => x.RoverId == SelectedRoverId); public static bool BaseEmFoco => SelectedRoverId == BaseMarkerID; public static async void AdicionarNovoRoverNaRede(string device_id) { if (AdicionandoNovoRover) return; AdicionandoNovoRover = true; try { if (string.IsNullOrEmpty(device_id)) return; bool rover_ja_adicionado = false; lock (_RoversLock) { rover_ja_adicionado = RoversNaRede.Any(x => x.RoverId == device_id); } if (!rover_ja_adicionado) { lock (_RoversLock) { RoversNaRede.Add(new OperacaoParametrosModel() { RoverId = device_id, Configurado = false, Alive = true, DadosLeitura = new OperacaoSensoriamentoLogModel() { Momento = DateTime.Now } }); } bool t_hbt_added = Variaveis.MqttService.Topicos.Any(x => x.Topico == VariaveisEquipamento.TopicoMqttHeartbeat.Replace("", device_id)); if (!t_hbt_added) await Variaveis.MqttService.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttHeartbeat.Replace("", device_id)); bool t_cmd_added = Variaveis.MqttService.Topicos.Any(x => x.Topico == VariaveisEquipamento.TopicoMqttComandos.Replace("", device_id)); if (!t_cmd_added) await Variaveis.MqttService.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttComandos.Replace("", device_id)); bool t_tel_added = Variaveis.MqttService.Topicos.Any(x => x.Topico == VariaveisEquipamento.TopicoMqttTelemetria.Replace("", device_id)); if (!t_tel_added) await Variaveis.MqttService.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttTelemetria.Replace("", device_id), true, 1, async (message) => { try { string json = message.Mensagem; if (string.IsNullOrEmpty(json)) return; var obj = JsonConvert.DeserializeObject(json); if (obj == null) return; lock (_RoversLock) { var rover = RoversNaRede.FirstOrDefault(x => x.RoverId == device_id); if (rover != null) { obj.Momento = DateTime.Now; rover.DadosLeitura = obj; } } ((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("", device_id)); if (!t_par_added) await Variaveis.MqttService.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttParametros.Replace("", device_id), true, 1, async (message) => { try { string json = message.Mensagem; if (string.IsNullOrEmpty(json)) return; var obj = JsonConvert.DeserializeObject(json); lock (_RoversLock) { var rover = RoversNaRede.FirstOrDefault(x => x.RoverId == device_id); if (rover != null) { RoversNaRede.Remove(rover); RoversNaRede.Add(obj); } } ((App)Application.Current).Shell.Main?.AtualizarDadosTela_ParametrosOperacao(obj.Controle); } catch (Exception ex) { Variaveis.MostrarLog($"Erro ao deserializar dados de parametros do rover {device_id}: {ex.Message}"); } }); List dispositivos_ids = new List() { "BASE" }; lock (_RoversLock) { dispositivos_ids = dispositivos_ids.Union(RoversNaRede.Select(x => x.RoverId).ToList()).ToList(); } ((App)Application.Current).Shell.Main?.AtualizarListaDispositivos(dispositivos_ids); RequisitarParametrosOperacao(); } } finally { AdicionandoNovoRover = false; } } public static async void AtualizarListaRoversNaRede() { if (AtualizandoListaRovers) return; AtualizandoListaRovers = true; try { var rovers_atual = new List(); lock (_RoversLock) { rovers_atual = new List(RoversNaRede); } foreach (var rover in rovers_atual) { rover.Alive = (DateTime.Now - rover.DadosLeitura.Momento).TotalSeconds < TempoRoverVivo; if (!rover.Alive) { ((App)Application.Current).Shell.Main?.MAP?.markers?.UpdateMarkerInfo(rover.RoverId, status: AgroBase.Models.Enums.StatusOperacao.Erro); } } } 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"); } } private static async void EnviarDadosControle(string rover_id, OperacaoComandoBaseModel controle) { var topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == VariaveisEquipamento.TopicoMqttComandos.Replace("", rover_id)); if (topico != null) { string json = JsonConvert.SerializeObject(controle); await Variaveis.MqttService.PublishAsync(topico, json); } } public static async void EnviarDadosPosicao(GPSModel posicao) { var topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == VariaveisMonitoramento.TopicoMqttPosicao); if (topico != null) { string json = JsonConvert.SerializeObject(posicao); await Variaveis.MqttService.PublishAsync(topico, json); } } public static async void EnviarDadosCorrecaoRTCM(byte[] correcao) { var topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == VariaveisMonitoramento.TopicoMqttRTCM); if (topico != null) { await Variaveis.MqttService.PublishAsync(topico, correcao); } } #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, Tecla = simulador ? AgroBase.Models.Enums.BotoesJoystick.L1 : iniciar ? AgroBase.Models.Enums.BotoesJoystick.L2 : AgroBase.Models.Enums.BotoesJoystick.L3 }); } 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); } public static void EnviarComandoReferenciamento() { EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel() { Momento = DateTime.Now, Tecla = AgroBase.Models.Enums.BotoesJoystick.R3 }); } public static void EnviarComandoLeverArm(double valorCm) { EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel() { Momento = DateTime.Now, Dispositivo = AgroBase.Models.Enums.T_Code.Gps, LeverArmLateral = Math.Round(valorCm, 0), }); } public static void EnviarParametrosOperacao(OperacaoParametrosModel parametros) { bool operacao_iniciada = (RoverEmFoco?.DadosLeitura?.OperacaoIniciada ?? false); bool parametros_parciais = parametros.Modo == null; EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel() { Momento = DateTime.Now, Dispositivo = AgroBase.Models.Enums.T_Code.Mod, Parametros = parametros, Tecla = (operacao_iniciada || parametros_parciais ? AgroBase.Models.Enums.BotoesJoystick.Touchpad : AgroBase.Models.Enums.BotoesJoystick.Options) }); } public static void RequisitarParametrosOperacao() { EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel() { Momento = DateTime.Now, Dispositivo = AgroBase.Models.Enums.T_Code.Mod, Tecla = AgroBase.Models.Enums.BotoesJoystick.Share }); } public static void EnviarComandoAtuador(string componente_id, bool status) { EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel() { Momento = DateTime.Now, Dispositivo = AgroBase.Models.Enums.T_Code.Atu, _comp_id = componente_id, _comp_value = status }); } 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 }); } #endregion } }