agrobot_base/AgroBase/OperationControl/Models/Variaveis.cs

302 lines
13 KiB
C#

using AgroBase.Models;
using Newtonsoft.Json;
using System.Diagnostics;
using OperationControl.Services;
using AgroMonitor;
using Application = System.Windows.Application;
using AgroBase.Models.Operacoes;
using Mapsui;
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<OperacaoParametrosModel> RoversNaRede { get; set; } = new List<OperacaoParametrosModel>();
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("<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;
var obj = JsonConvert.DeserializeObject<OperacaoSensoriamentoLogModel>(json);
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("<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)
{
rover = obj;
}
}
((App)Application.Current).Shell.Main?.AtualizarDadosTela_Telemetria(device_id);
}
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)
{
dispositivos_ids = dispositivos_ids.Union(RoversNaRede.Select(x => x.RoverId).ToList()).ToList();
}
((App)Application.Current).Shell.Main?.AtualizarListaDispositivos(dispositivos_ids);
}
}
finally
{
AdicionandoNovoRover = false;
}
}
public static async void AtualizarListaRoversNaRede()
{
if (AtualizandoListaRovers) return;
AtualizandoListaRovers = true;
try
{
var rovers_atual = new List<OperacaoParametrosModel>();
lock (_RoversLock)
{
rovers_atual = new List<OperacaoParametrosModel>(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("<id>", 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.Share : iniciar ? AgroBase.Models.Enums.BotoesJoystick.PS : AgroBase.Models.Enums.BotoesJoystick.Vazio
});
}
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)
{
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
{
Momento = DateTime.Now,
Parametros = parametros,
Tecla = (!(RoverEmFoco.DadosLeitura?.OperacaoIniciada ?? false) ? AgroBase.Models.Enums.BotoesJoystick.Options : AgroBase.Models.Enums.BotoesJoystick.Vazio)
});
}
#endregion
}
}