441 lines
20 KiB
C#
441 lines
20 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;
|
|
|
|
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 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;
|
|
}
|
|
}
|
|
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);
|
|
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;
|
|
rover.UltimoContato = DateTime.Now;
|
|
}
|
|
}
|
|
((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)
|
|
{
|
|
obj.UltimoContato = DateTime.Now;
|
|
RoversNaRede.Remove(rover);
|
|
RoversNaRede.Add(obj);
|
|
}
|
|
}
|
|
((App)Application.Current).Shell.Main?.AtualizarDadosTela_ParametrosOperacao(obj.Controle);
|
|
((App)Application.Current).Shell.Main?.MAP?.CarregarDadosMapa(obj.Mapa, obj.RuasPercorrer);
|
|
}
|
|
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);
|
|
|
|
RequisitarParametrosOperacao();
|
|
}
|
|
}
|
|
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.UltimoContato).TotalSeconds < TempoRoverVivo;
|
|
if (!rover.Alive)
|
|
{
|
|
//((App)Application.Current).Shell.Main?.MAP?.markers?.UpdateMarkerInfo(rover.RoverId, status: AgroBase.Models.Enums.StatusOperacao.Erro);
|
|
rover.DadosLeitura = new OperacaoSensoriamentoLogModel();
|
|
rover.DadosLeitura.Momento = DateTime.Now;
|
|
rover.DadosLeitura.StatusOperacao = AgroBase.Models.Enums.StatusOperacao.Erro;
|
|
((App)Application.Current).Shell.Main?.AtualizarDadosTela_Telemetria(rover.RoverId);
|
|
((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);
|
|
}
|
|
}
|
|
}
|
|
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.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(string mod_id = null)
|
|
{
|
|
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
|
|
{
|
|
Momento = DateTime.Now,
|
|
Dispositivo = AgroBase.Models.Enums.T_Code.Dir,
|
|
Tecla = AgroBase.Models.Enums.BotoesJoystick.R3,
|
|
_comp_id = mod_id
|
|
});
|
|
}
|
|
|
|
public static void EnviarComandoLeverArm(double? lateral = null, double? frontal = null)
|
|
{
|
|
var cmd = new OperacaoComandoBaseModel()
|
|
{
|
|
Momento = DateTime.Now,
|
|
Dispositivo = AgroBase.Models.Enums.T_Code.Gps,
|
|
_comp_value = (lateral, frontal)
|
|
};
|
|
EnviarDadosControle(SelectedRoverId, cmd);
|
|
}
|
|
|
|
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 EnviarConfirmacaoHumanaTrajetoria(int idx_corredor, bool bat_liberada, bool herb_liberado)
|
|
{
|
|
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
|
|
{
|
|
Momento = DateTime.Now,
|
|
Dispositivo = AgroBase.Models.Enums.T_Code.Mod,
|
|
Tecla = AgroBase.Models.Enums.BotoesJoystick.R1,
|
|
_comp_value = (idx_corredor, bat_liberada, herb_liberado)
|
|
});
|
|
}
|
|
|
|
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)
|
|
});
|
|
}
|
|
|
|
public static void RequisitarParametrosOperacao()
|
|
{
|
|
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
|
|
{
|
|
Momento = DateTime.Now,
|
|
Dispositivo = AgroBase.Models.Enums.T_Code.Mod,
|
|
Tecla = AgroBase.Models.Enums.BotoesJoystick.Share
|
|
});
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
public static void EnviarComandoDirecional(AgroBase.Models.Enums.Direcao direcao, double angulo, AgroBase.Models.Enums.TipoMovimentoDirecional movimento, string mod_id = null)
|
|
{
|
|
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
|
|
{
|
|
Momento = DateTime.Now,
|
|
Dispositivo = AgroBase.Models.Enums.T_Code.Dir,
|
|
Tecla = DeParaDirecaoTecla(direcao),
|
|
_comp_id = mod_id,
|
|
Controle = new OperacaoComandoBaseControleModel()
|
|
{
|
|
AnguloSP = angulo,
|
|
TipoMovimentoDirecional = movimento
|
|
},
|
|
});
|
|
}
|
|
|
|
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
|
|
}
|
|
});
|
|
}
|
|
|
|
public static void EnviarComandoAtuador(string componente_id, bool? status = null, int? angulo_controle = null, double? angulo_abertura = null, double? altura = null)
|
|
{
|
|
EnviarDadosControle(SelectedRoverId, new OperacaoComandoBaseModel()
|
|
{
|
|
Momento = DateTime.Now,
|
|
Dispositivo = AgroBase.Models.Enums.T_Code.Atu,
|
|
_comp_id = componente_id,
|
|
_comp_value = angulo_abertura,
|
|
Controle = new OperacaoComandoBaseControleModel()
|
|
{
|
|
AnguloSP = angulo_controle,
|
|
Estado = status,
|
|
Altura = altura,
|
|
}
|
|
});
|
|
}
|
|
|
|
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
|
|
|
|
}
|
|
}
|