iniciado comunicacao ip mqtt
This commit is contained in:
parent
a6acd81d17
commit
ba51fa73ca
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -47,7 +47,7 @@ namespace AgroBase.Forms
|
|||
try
|
||||
{
|
||||
cameraSolo.camera.pythonProcess?.Kill();
|
||||
Variaveis.MqttService.UnsubscribeAsync(cameraSolo.camera._mqttTopico).ConfigureAwait(false);
|
||||
Variaveis.MqttServiceLocal.UnsubscribeAsync(cameraSolo.camera._mqttTopico).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -183,7 +183,7 @@ namespace AgroBase.Forms
|
|||
int i = 0;
|
||||
|
||||
//var coordenadas = cameraService.AferirDadosCamera<CameraCoordenadasModel>();
|
||||
var MqttTopico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == cameraSolo.MqttTopico);
|
||||
var MqttTopico = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == cameraSolo.MqttTopico);
|
||||
|
||||
if (MqttTopico == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ namespace AgroBase.Forms.IHM
|
|||
}
|
||||
}
|
||||
|
||||
bool mqttConectado = Variaveis.MqttService.StatusConexao();
|
||||
bool mqttConectado = Variaveis.MqttServiceLocal.StatusConexao();
|
||||
lblMqtt.Text = "MQTT: " + (mqttConectado ? "Conectado" : "Desconectado");
|
||||
lblMqtt.ForeColor = mqttConectado ? Color.Green : Color.Red;
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ namespace AgroBase.Forms.Movimentacao
|
|||
try
|
||||
{
|
||||
tmrLeitura.Stop();
|
||||
Variaveis.MqttService.UnsubscribeAsync(cameraService._mqttTopico).GetAwaiter().GetResult();
|
||||
Variaveis.MqttServiceLocal.UnsubscribeAsync(cameraService._mqttTopico).GetAwaiter().GetResult();
|
||||
cameraService.pythonProcess.Kill();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace AgroBase.Forms.Sensoriamento
|
|||
{
|
||||
try
|
||||
{
|
||||
Variaveis.MqttService.UnsubscribeAsync(cameraService._mqttTopico).GetAwaiter().GetResult();
|
||||
Variaveis.MqttServiceLocal.UnsubscribeAsync(cameraService._mqttTopico).GetAwaiter().GetResult();
|
||||
cameraService.pythonProcess?.Kill();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -119,7 +119,7 @@ namespace AgroBase.Forms.Sensoriamento
|
|||
this.pnlLeituras.Controls.Clear();
|
||||
int i = 0;
|
||||
|
||||
var MqttTopico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == VideoUrl);
|
||||
var MqttTopico = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == VideoUrl);
|
||||
CameraCoordenadasFrameModel leitura = null;
|
||||
var Mensagem = MqttTopico.Mensagens.LastOrDefault(x => x.Momento > cameraService.IniciadoEm);
|
||||
if (Mensagem != null)
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ namespace AgroBase.Forms
|
|||
|
||||
ReiniciarModelo();
|
||||
|
||||
await Variaveis.MqttService.AdicionarNovoTopico(mqtt_topico_state);
|
||||
await Variaveis.MqttService.AdicionarNovoTopico(mqtt_topico_action, true, 2, async (message) =>
|
||||
await Variaveis.MqttServiceLocal.AdicionarNovoTopico(mqtt_topico_state);
|
||||
await Variaveis.MqttServiceLocal.AdicionarNovoTopico(mqtt_topico_action, true, 2, async (message) =>
|
||||
{
|
||||
Console.WriteLine("Mensagem recebida pelo modelo de IA: " + message);
|
||||
//btnAcrescentarGPS_Click(new Button(), new EventArgs());
|
||||
|
|
@ -72,10 +72,10 @@ namespace AgroBase.Forms
|
|||
|
||||
private async void frmTreinamentoIA_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
var t0 = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == mqtt_topico_state);
|
||||
await Variaveis.MqttService.UnsubscribeAsync(t0);
|
||||
var t1 = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == mqtt_topico_action);
|
||||
await Variaveis.MqttService.UnsubscribeAsync(t1);
|
||||
var t0 = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == mqtt_topico_state);
|
||||
await Variaveis.MqttServiceLocal.UnsubscribeAsync(t0);
|
||||
var t1 = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == mqtt_topico_action);
|
||||
await Variaveis.MqttServiceLocal.UnsubscribeAsync(t1);
|
||||
Variaveis.OperacaoEmAndamento.Treinando = false;
|
||||
}
|
||||
|
||||
|
|
@ -481,8 +481,8 @@ namespace AgroBase.Forms
|
|||
_robotState.UpdateCurrentRobotState();
|
||||
|
||||
|
||||
await Variaveis.MqttService.PublishAsync(
|
||||
Variaveis.MqttService.Topicos.First(x => x.Topico == mqtt_topico_state),
|
||||
await Variaveis.MqttServiceLocal.PublishAsync(
|
||||
Variaveis.MqttServiceLocal.Topicos.First(x => x.Topico == mqtt_topico_state),
|
||||
JsonConvert.SerializeObject(_robotState)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ namespace AgroBase.Forms
|
|||
|
||||
ThreadPool.SetMinThreads(workerThreads: 50, completionPortThreads: 50);
|
||||
|
||||
Variaveis.IniciarMQTT();
|
||||
|
||||
APIService.IniciarRotinas();
|
||||
|
||||
GeneralJoystick.IniciarRotinas();
|
||||
|
|
@ -93,7 +95,7 @@ namespace AgroBase.Forms
|
|||
|
||||
private async void IniciarConexaoMqtt()
|
||||
{
|
||||
await Variaveis.MqttService.ConnectAsync();
|
||||
await Variaveis.MqttServiceLocal.ConnectAsync();
|
||||
}
|
||||
|
||||
public static async Task EncerrarProcessos()
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ namespace AgroBase
|
|||
{
|
||||
AtualizaDadosGerais();
|
||||
|
||||
lblStripMqtt.Text = "MQTT: " + (Variaveis.MqttService.StatusConexao() ? "Conectado" : "Desconectado");
|
||||
lblStripMqtt.Text = "MQTT: " + (Variaveis.MqttServiceLocal.StatusConexao() ? "Conectado" : "Desconectado");
|
||||
|
||||
lblStripPython.Text = "IA: " + (VariaveisOperacao.Operadores.Conectado ? "Conectado" : "Desconectado");
|
||||
lblStripPython.ForeColor = VariaveisOperacao.Operadores.Conectado ? Color.Green : Color.Red;
|
||||
|
|
|
|||
|
|
@ -60,13 +60,13 @@ namespace AgroBase.Models
|
|||
try
|
||||
{
|
||||
Iniciada = false;
|
||||
Variaveis.MqttService.Topicos.Remove(camera._mqttTopico);
|
||||
Variaveis.MqttServiceLocal.Topicos.Remove(camera._mqttTopico);
|
||||
if (panelRgb != null)
|
||||
{
|
||||
panelRgb.Controls.Remove(browserRgb);
|
||||
}
|
||||
browserRgb = null;
|
||||
Task.Run(async () => await Variaveis.MqttService.UnsubscribeAsync(camera._mqttTopico));
|
||||
Task.Run(async () => await Variaveis.MqttServiceLocal.UnsubscribeAsync(camera._mqttTopico));
|
||||
|
||||
lock (camera.processLock)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ namespace AgroBase.Models
|
|||
try
|
||||
{
|
||||
Iniciada = false;
|
||||
Variaveis.MqttService.Topicos.Remove(camera._mqttTopico);
|
||||
Variaveis.MqttServiceLocal.Topicos.Remove(camera._mqttTopico);
|
||||
if (panel != null)
|
||||
{
|
||||
panel.Controls.Remove(browser);
|
||||
}
|
||||
browser = null;
|
||||
Task.Run(async () => await Variaveis.MqttService.UnsubscribeAsync(camera._mqttTopico));
|
||||
Task.Run(async () => await Variaveis.MqttServiceLocal.UnsubscribeAsync(camera._mqttTopico));
|
||||
lock (camera.processLock)
|
||||
{
|
||||
if (camera.pythonProcess != null)
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ public class MPCController
|
|||
|
||||
public async Task<bool> Inicializar()
|
||||
{
|
||||
await Variaveis.MqttService.AdicionarNovoTopico(TopicoRota);
|
||||
await Variaveis.MqttService.AdicionarNovoTopico(TopicoPosicao);
|
||||
await Variaveis.MqttService.AdicionarNovoTopico(TopicoComando, true, 2, async (mensagem) =>
|
||||
await Variaveis.MqttServiceLocal.AdicionarNovoTopico(TopicoRota);
|
||||
await Variaveis.MqttServiceLocal.AdicionarNovoTopico(TopicoPosicao);
|
||||
await Variaveis.MqttServiceLocal.AdicionarNovoTopico(TopicoComando, true, 2, async (mensagem) =>
|
||||
{
|
||||
if (mensagem.Mensagem == "OK")
|
||||
{
|
||||
|
|
@ -84,8 +84,8 @@ public class MPCController
|
|||
velocidade_max = FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Controle.PercentualVelocidadeMax)
|
||||
};
|
||||
|
||||
await Variaveis.MqttService.PublishAsync(
|
||||
Variaveis.MqttService.Topicos.First(x => x.Topico == TopicoRota),
|
||||
await Variaveis.MqttServiceLocal.PublishAsync(
|
||||
Variaveis.MqttServiceLocal.Topicos.First(x => x.Topico == TopicoRota),
|
||||
JsonConvert.SerializeObject(trajetoria)
|
||||
);
|
||||
}
|
||||
|
|
@ -123,8 +123,8 @@ public class MPCController
|
|||
}
|
||||
};
|
||||
|
||||
await Variaveis.MqttService.PublishAsync(
|
||||
Variaveis.MqttService.Topicos.First(x => x.Topico == TopicoPosicao),
|
||||
await Variaveis.MqttServiceLocal.PublishAsync(
|
||||
Variaveis.MqttServiceLocal.Topicos.First(x => x.Topico == TopicoPosicao),
|
||||
JsonConvert.SerializeObject(dadosEnvio)
|
||||
);
|
||||
|
||||
|
|
@ -161,10 +161,10 @@ public class MPCController
|
|||
Iniciado = false;
|
||||
ComandoAtual = new MPCComandoModel();
|
||||
Task.Run(async () => {
|
||||
Variaveis.MqttService.Topicos.Remove(Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == TopicoRota));
|
||||
Variaveis.MqttService.Topicos.Remove(Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == TopicoPosicao));
|
||||
await Variaveis.MqttService.UnsubscribeAsync(Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == TopicoComando));
|
||||
Variaveis.MqttService.Topicos.Remove(Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == TopicoComando));
|
||||
Variaveis.MqttServiceLocal.Topicos.Remove(Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == TopicoRota));
|
||||
Variaveis.MqttServiceLocal.Topicos.Remove(Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == TopicoPosicao));
|
||||
await Variaveis.MqttServiceLocal.UnsubscribeAsync(Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == TopicoComando));
|
||||
Variaveis.MqttServiceLocal.Topicos.Remove(Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == TopicoComando));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace AgroBase.Models
|
|||
|
||||
public void btnCarregar_Click(object sender, EventArgs e, string caminhoArquivo = "", bool monitoramento = false)
|
||||
{
|
||||
var Topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa);
|
||||
var Topico = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa);
|
||||
Topico.Mensagens.Clear();
|
||||
|
||||
TipoMapaOperacao? _tipoMapa = TipoMapa;
|
||||
|
|
@ -234,7 +234,7 @@ namespace AgroBase.Models
|
|||
{
|
||||
List<string> ids = new List<string>();
|
||||
bool idsMensagem = false;
|
||||
var Topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa);
|
||||
var Topico = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa);
|
||||
var Mensagem = Topico.Mensagens.LastOrDefault();
|
||||
if (Mensagem != null && !Mensagem.Mensagem.Contains("[]"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ using System.Text;
|
|||
using static AgroBase.Services.OIDCanService.OidHandler;
|
||||
using AgroBase.Models.Operadores;
|
||||
using AgroBase.Services.Operadores;
|
||||
using AgroMonitor;
|
||||
|
||||
namespace AgroBase.Models
|
||||
{
|
||||
|
|
@ -34,6 +35,10 @@ namespace AgroBase.Models
|
|||
tmrLeituras?.Dispose();
|
||||
tmrLeituras = new AsyncTaskTimerModel("tmrLeitura", tmrLeituras_Tick, 500);
|
||||
tmrLeituras.Start();
|
||||
|
||||
tmrComunicacao?.Dispose();
|
||||
tmrComunicacao = new AsyncTaskTimerModel("tmrComunicacao", tmrComunicacao_Tick, 1000);
|
||||
tmrComunicacao.Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +146,8 @@ namespace AgroBase.Models
|
|||
}
|
||||
}
|
||||
private static AsyncTaskTimerModel tmrLeituras;
|
||||
|
||||
private static AsyncTaskTimerModel tmrComunicacao;
|
||||
|
||||
|
||||
|
||||
#region PARAMETRIZACAO
|
||||
|
|
@ -924,7 +930,7 @@ namespace AgroBase.Models
|
|||
Variaveis.OperacaoEmAndamento.Trajetoria = new TrajetoriaMapaOperacaoModel(new List<List<GPSModel>>());
|
||||
Variaveis.OperacaoEmAndamento.GPSTrajetoria = new List<GPSModel>();
|
||||
|
||||
var Topico = Variaveis.MqttService.Topicos.FirstOrDefault(x => x.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa);
|
||||
var Topico = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa);
|
||||
Topico.Mensagens.Add(new MqttService.MqttTopicosMensagensModel()
|
||||
{
|
||||
Mensagem = "[]",
|
||||
|
|
@ -1186,7 +1192,7 @@ namespace AgroBase.Models
|
|||
}
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
|
||||
Variaveis.LoraService?.EnviarDadosParaBase();
|
||||
//Variaveis.LoraService?.EnviarDadosParaBase();
|
||||
|
||||
if (!Variaveis.OperacaoEmAndamento.Iniciado)
|
||||
{
|
||||
|
|
@ -1240,6 +1246,27 @@ namespace AgroBase.Models
|
|||
_Controle.TipoMovimento = oldTipoMovimento;
|
||||
}
|
||||
|
||||
private async Task tmrComunicacao_Tick()
|
||||
{
|
||||
bool base_encontrada = (DateTime.Now - VariaveisOperacao.PosicaoBase.Momento).TotalSeconds < 10;
|
||||
MqttService.MqttTopicosModel topico = null;
|
||||
string msg = string.Empty;
|
||||
if (!base_encontrada)
|
||||
{
|
||||
topico = Variaveis.MqttServiceBase.Topicos.FirstOrDefault(x => x.Topico == VariaveisMonitoramento.TopicoMqttDispositivos);
|
||||
msg = VariaveisEquipamento.Parametros.serial_number;
|
||||
}
|
||||
else
|
||||
{
|
||||
topico = Variaveis.MqttServiceBase.Topicos.FirstOrDefault(x => x.Topico == VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", VariaveisEquipamento.Parametros.serial_number));
|
||||
msg = JsonConvert.SerializeObject(Variaveis.OperacaoEmAndamento.Sensoriamento);
|
||||
}
|
||||
if (topico != null && !string.IsNullOrEmpty(msg))
|
||||
{
|
||||
await Variaveis.MqttServiceBase.PublishAsync(topico, msg);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region REGISTRO DE LOGS
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@ using System.Threading;
|
|||
using AgroBase.Models.Components;
|
||||
using Microsoft.Web.WebView2.WinForms;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using System.Text.Json;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System.Diagnostics;
|
||||
using Newtonsoft.Json;
|
||||
using AgroMonitor;
|
||||
|
||||
namespace AgroBase.Models
|
||||
{
|
||||
|
|
@ -55,7 +56,8 @@ namespace AgroBase.Models
|
|||
public static string CaminhoModelos { get; } = "C:\\AgroBaseModels\\";
|
||||
public static List<IDispositivosService> DispositivosConectados { get; set; } = new List<IDispositivosService>();
|
||||
public static OperacaoModel OperacaoEmAndamento { get; set; } = new OperacaoModel(ModoOperacao.Manual);
|
||||
public static MqttService MqttService { get; set; } = new MqttService("localhost", 1883);
|
||||
public static MqttService MqttServiceLocal { get; set; }
|
||||
public static MqttService MqttServiceBase { get; set; }
|
||||
public static LoRaEspService LoraService
|
||||
{
|
||||
get
|
||||
|
|
@ -86,6 +88,105 @@ namespace AgroBase.Models
|
|||
public static byte ID_Num_sMOD { get; } = 0;
|
||||
public static byte ID_Num_sTOD { get; } = 250;
|
||||
public static byte ID_Num_sLRA { get; } = 251;
|
||||
|
||||
public static async void IniciarMQTT()
|
||||
{
|
||||
if (MqttServiceLocal != null)
|
||||
{
|
||||
foreach (var topico in MqttServiceLocal.Topicos.Where(x => x.Inscrever))
|
||||
{
|
||||
await MqttServiceLocal.UnsubscribeAsync(topico);
|
||||
}
|
||||
MqttServiceLocal.Topicos.Clear();
|
||||
}
|
||||
|
||||
if (MqttServiceBase != null && !IsAgroMonitor)
|
||||
{
|
||||
foreach (var topico in MqttServiceBase.Topicos.Where(x => x.Inscrever))
|
||||
{
|
||||
await MqttServiceBase.UnsubscribeAsync(topico);
|
||||
}
|
||||
MqttServiceBase.Topicos.Clear();
|
||||
}
|
||||
|
||||
MqttServiceLocal = new MqttService("localhost", 1883, IsAgroMonitor ? "base" : VariaveisEquipamento.Parametros.serial_number, true);
|
||||
await MqttServiceLocal.AdicionarNovoTopico(MapasVariaveisModel.TopicoCoordenadasGPS);
|
||||
await MqttServiceLocal.AdicionarNovoTopico(MapasVariaveisModel.TopicoTrajetoriaDinamica);
|
||||
await MqttServiceLocal.AdicionarNovoTopico(MapasVariaveisModel.TopicoSelecaoRuasMapa, true, 1, async (message) =>
|
||||
{
|
||||
OperacaoEmAndamento.Mapa.AtualizarRuasSelecionadas();
|
||||
});
|
||||
|
||||
if (IsAgroMonitor)
|
||||
{
|
||||
await MqttServiceLocal.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttRTCM);
|
||||
await MqttServiceLocal.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttDispositivos, true, 1, async (message) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
string device_id = message.Mensagem;
|
||||
VariaveisMonitoramento.AdicionarNovoRoverNaRede(message.Mensagem);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro ao deserializar ping do rover: {ex.Message}");
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
MqttServiceBase = new MqttService(VariaveisEquipamento.Parametros.base_ip, 1883, VariaveisEquipamento.Parametros.serial_number, false);
|
||||
await MqttServiceBase.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttDispositivos);
|
||||
await MqttServiceBase.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", VariaveisEquipamento.Parametros.serial_number));
|
||||
await MqttServiceBase.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttComandos.Replace("<id>", VariaveisEquipamento.Parametros.serial_number), true, 1, async (message) =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(message.Mensagem))
|
||||
return;
|
||||
try
|
||||
{
|
||||
string json = message.Mensagem;
|
||||
var cmd = JsonConvert.DeserializeObject<OperacaoControleBaseModel>(json);
|
||||
OperacaoEmAndamento.ExecutaComandoDaBase(cmd);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro ao deserializar comando da base: {ex.Message}");
|
||||
}
|
||||
});
|
||||
await MqttServiceBase.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttRTCM, true, 1, async (message) =>
|
||||
{
|
||||
if (message.Bytes == null || message.Bytes.Length == 0)
|
||||
return;
|
||||
try
|
||||
{
|
||||
var bytes = message.Bytes;
|
||||
if (bytes != null && bytes.Length > 0)
|
||||
{
|
||||
GPSService.AplicarCorrecaoRTK_Mqtt(bytes, bytes.Length);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro ao deserializar RTCM da base: {ex.Message}");
|
||||
}
|
||||
});
|
||||
await MqttServiceBase.AdicionarNovoTopico(VariaveisMonitoramento.TopicoMqttPosicao, true, 1, async (message) =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(message.Mensagem))
|
||||
return;
|
||||
try
|
||||
{
|
||||
string json = message.Mensagem;
|
||||
var posicao = JsonConvert.DeserializeObject<GPSModel>(json);
|
||||
VariaveisOperacao.PosicaoBase = posicao;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro ao deserializar dados da base: {ex.Message}");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class VariaveisPortas
|
||||
|
|
@ -98,6 +199,25 @@ namespace AgroBase.Models
|
|||
|
||||
public static class VariaveisEquipamento
|
||||
{
|
||||
private static ParametrosConfigEquipamentoModel _parametros;
|
||||
public static ParametrosConfigEquipamentoModel Parametros
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_parametros == null)
|
||||
{
|
||||
_parametros = new ParametrosConfigEquipamentoModel();
|
||||
_parametros.AtualizarParametros();
|
||||
}
|
||||
return _parametros;
|
||||
}
|
||||
set
|
||||
{
|
||||
_parametros = value;
|
||||
}
|
||||
}
|
||||
public static string TopicoMqttComandos { get; } = $"agrobot/v1/rover/<id>/cmd";
|
||||
public static string TopicoMqttTelemetria { get; } = $"agrobot/v1/rover/<id>/telemetry";
|
||||
public static double LarguraEsquerda { get; } = 44.0; // 62
|
||||
public static double LarguraDireita { get; } = 44.0; // 22
|
||||
public static double ComprimentoFrente { get; } = 7.0; // 7
|
||||
|
|
@ -191,6 +311,8 @@ namespace AgroBase.Models
|
|||
public static double AnguloInclinacaoPitchMax { get; set; } = 45.0;
|
||||
public static string VozAlerta { get; set; } = "Microsoft Maria Desktop";
|
||||
|
||||
|
||||
|
||||
public static SensorSinaleiroComportamentoModel ComportamentoLedPorStatus(StatusOperacao? _status = null)
|
||||
{
|
||||
if (_status == null)
|
||||
|
|
@ -444,6 +566,38 @@ namespace AgroBase.Models
|
|||
return novaPosicao;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class ParametrosConfigEquipamentoModel
|
||||
{
|
||||
public bool Carregado { get; set; }
|
||||
public string serial_number { get; set; }
|
||||
public string base_ip { get; set; }
|
||||
|
||||
public void AtualizarParametros()
|
||||
{
|
||||
string config_path = Path.Combine(Variaveis.CaminhoSistema, Variaveis.CaminhoParametros, "config.json");
|
||||
if (!File.Exists(config_path))
|
||||
Carregado = false;
|
||||
|
||||
try
|
||||
{
|
||||
string json = File.ReadAllText(config_path);
|
||||
var par = JsonConvert.DeserializeObject<ParametrosConfigEquipamentoModel>(json);
|
||||
|
||||
serial_number = par.serial_number;
|
||||
base_ip = par.base_ip;
|
||||
|
||||
Carregado = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro ao carregar arquivo de configuracoes: {ex.Message}");
|
||||
Carregado = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class VariaveisOperacao
|
||||
|
|
@ -1252,7 +1406,7 @@ namespace AgroBase.Models
|
|||
string result = await browser.CoreWebView2.ExecuteScriptAsync(script);
|
||||
|
||||
// O resultado vem como string JSON (ex: "\"Texto dentro do body\"")
|
||||
string conteudo = JsonSerializer.Deserialize<string>(result);
|
||||
string conteudo = System.Text.Json.JsonSerializer.Deserialize<string>(result);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(conteudo) ||
|
||||
conteudo.Contains("Internal Server Error") ||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using AgroBase.Models;
|
||||
using AgroBase.Services;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
@ -121,5 +122,78 @@ namespace AgroMonitor
|
|||
public static double LeverArmFrontal { get; } = 0.0;
|
||||
public static double LeverArmLateral { get; } = 0.0;
|
||||
|
||||
public static string TopicoMqttDispositivos { get; } = $"agrobot/v1/base/devices";
|
||||
public static string TopicoMqttPosicao { get; } = $"agrobot/v1/base/position";
|
||||
public static string TopicoMqttRTCM { get; } = $"agrobot/v1/base/rtcm";
|
||||
private static readonly object _RoversLock = new object();
|
||||
public static Dictionary<string, OperacaoSensoriamentoLogModel> RoversNaRede { get; set; } = new Dictionary<string, OperacaoSensoriamentoLogModel>();
|
||||
public static async void AdicionarNovoRoverNaRede(string device_id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(device_id))
|
||||
return;
|
||||
|
||||
bool rover_ja_adicionado = false;
|
||||
lock (_RoversLock)
|
||||
{
|
||||
rover_ja_adicionado = RoversNaRede.ContainsKey(device_id);
|
||||
}
|
||||
|
||||
if (!rover_ja_adicionado)
|
||||
{
|
||||
lock (_RoversLock)
|
||||
{
|
||||
RoversNaRede.Add(device_id, new OperacaoSensoriamentoLogModel() { Momento = DateTime.Now });
|
||||
}
|
||||
|
||||
await Variaveis.MqttServiceLocal.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttComandos.Replace("<id>", device_id));
|
||||
await Variaveis.MqttServiceLocal.AdicionarNovoTopico(VariaveisEquipamento.TopicoMqttTelemetria.Replace("<id>", device_id), true, 1, async (message) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
string json = message.Mensagem;
|
||||
var obj = JsonConvert.DeserializeObject<OperacaoSensoriamentoLogModel>(json);
|
||||
lock (_RoversLock)
|
||||
{
|
||||
RoversNaRede[device_id] = obj;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro ao deserializar dados de telemetria do rover {device_id}: {ex.Message}");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
public static async void AtualizarListaRoversNaRede()
|
||||
{
|
||||
List<string> rovers_desconectados = new List<string>();
|
||||
var rovers_atual = new Dictionary<string, OperacaoSensoriamentoLogModel>();
|
||||
lock (_RoversLock)
|
||||
{
|
||||
rovers_atual = new Dictionary<string, OperacaoSensoriamentoLogModel>(RoversNaRede);
|
||||
}
|
||||
foreach (var rover in rovers_atual)
|
||||
{
|
||||
double tempo_sem_resposta = (DateTime.Now - rover.Value.Momento).TotalSeconds;
|
||||
if (tempo_sem_resposta > 5.0)
|
||||
{
|
||||
rovers_desconectados.Add(rover.Key);
|
||||
}
|
||||
}
|
||||
foreach (var device_id in rovers_desconectados)
|
||||
{
|
||||
lock (_RoversLock)
|
||||
{
|
||||
RoversNaRede.Remove(device_id);
|
||||
}
|
||||
var topicos_rover = Variaveis.MqttServiceLocal.Topicos.Where(x => x.Topico.Contains(device_id)).ToList();
|
||||
foreach (var topico in topicos_rover)
|
||||
{
|
||||
await Variaveis.MqttServiceLocal.UnsubscribeAsync(topico);
|
||||
Variaveis.MqttServiceLocal.Topicos.Remove(topico);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace AgroBase.Services
|
|||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
_mqttTopico = await Variaveis.MqttService.AdicionarNovoTopico(MqttTopico, true, 2, mqttCallback);
|
||||
_mqttTopico = await Variaveis.MqttServiceLocal.AdicionarNovoTopico(MqttTopico, true, 2, mqttCallback);
|
||||
|
||||
lock (processLock)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -955,6 +955,14 @@ namespace AgroBase.Services
|
|||
LoopRTK_Ntrip = false;
|
||||
}
|
||||
|
||||
public static void AplicarCorrecaoRTK_Mqtt(byte[] correcao, int bytesRead)
|
||||
{
|
||||
if (PortaGPS?.IsOpen ?? false)
|
||||
{
|
||||
PortaGPS.Write(correcao, 0, bytesRead);
|
||||
UltimoEnvioCorrecaoRTK = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void AtualizarCoordenadasGPS()
|
||||
|
|
@ -1055,8 +1063,8 @@ namespace AgroBase.Services
|
|||
Task.Run(async () =>
|
||||
{
|
||||
//Console.WriteLine(JsonConvert.SerializeObject(Coordenadas));
|
||||
await Variaveis.MqttService.PublishAsync(
|
||||
Variaveis.MqttService.Topicos.First(x => x.Topico == MapasVariaveisModel.TopicoCoordenadasGPS),
|
||||
await Variaveis.MqttServiceLocal.PublishAsync(
|
||||
Variaveis.MqttServiceLocal.Topicos.First(x => x.Topico == MapasVariaveisModel.TopicoCoordenadasGPS),
|
||||
JsonConvert.SerializeObject(Coordenadas)
|
||||
);
|
||||
});
|
||||
|
|
@ -1074,8 +1082,8 @@ namespace AgroBase.Services
|
|||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Variaveis.MqttService.PublishAsync(
|
||||
Variaveis.MqttService.Topicos.First(x => x.Topico == MapasVariaveisModel.TopicoTrajetoriaDinamica),
|
||||
await Variaveis.MqttServiceLocal.PublishAsync(
|
||||
Variaveis.MqttServiceLocal.Topicos.First(x => x.Topico == MapasVariaveisModel.TopicoTrajetoriaDinamica),
|
||||
JsonConvert.SerializeObject(Trajetoria)
|
||||
);
|
||||
});
|
||||
|
|
@ -1086,8 +1094,8 @@ namespace AgroBase.Services
|
|||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Variaveis.MqttService.PublishAsync(
|
||||
Variaveis.MqttService.Topicos.First(x => x.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa),
|
||||
await Variaveis.MqttServiceLocal.PublishAsync(
|
||||
Variaveis.MqttServiceLocal.Topicos.First(x => x.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa),
|
||||
JsonConvert.SerializeObject("[" + string.Join(",", RuasSelecionadas.ToArray()) + "]"),
|
||||
true
|
||||
);
|
||||
|
|
|
|||
|
|
@ -13,23 +13,36 @@ public class MqttService
|
|||
{
|
||||
private IMqttClient _client;
|
||||
private IMqttClientOptions _options;
|
||||
private string _brokerAddr;
|
||||
private int _brokerPort;
|
||||
private AsyncTaskTimerModel tmrCheck;
|
||||
|
||||
public List<MqttTopicosModel> Topicos;
|
||||
|
||||
public MqttService(string brokerAddress, int brokerPort)
|
||||
private void LogDebug(string msg)
|
||||
{
|
||||
Console.WriteLine($"[MQTT {_brokerAddr}:{_brokerPort}] - {msg}");
|
||||
}
|
||||
|
||||
public MqttService(string brokerAddress, int brokerPort, string client_id, bool local)
|
||||
{
|
||||
_brokerAddr = brokerAddress;
|
||||
_brokerPort = brokerPort;
|
||||
|
||||
var factory = new MqttFactory();
|
||||
_client = factory.CreateMqttClient();
|
||||
|
||||
string client = !local ? client_id : (client_id + "_local");
|
||||
|
||||
_options = new MqttClientOptionsBuilder()
|
||||
.WithTcpServer(brokerAddress, brokerPort)
|
||||
.WithClientId(client)
|
||||
.WithTcpServer(_brokerAddr, _brokerPort)
|
||||
.WithCleanSession()
|
||||
.Build();
|
||||
|
||||
_client.UseConnectedHandler(async e =>
|
||||
{
|
||||
Console.WriteLine("Connected to MQTT Broker.");
|
||||
LogDebug("Connected to MQTT Broker.");
|
||||
if (Topicos.Any(x => x.Inscrever))
|
||||
{
|
||||
foreach (var topic in Topicos)
|
||||
|
|
@ -37,17 +50,21 @@ public class MqttService
|
|||
await SubscribeAsync(topic);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
_client.UseDisconnectedHandler(e =>
|
||||
{
|
||||
Console.WriteLine("Disconnected from MQTT Broker.");
|
||||
LogDebug("Disconnected from MQTT Broker.");
|
||||
});
|
||||
|
||||
_client.UseApplicationMessageReceivedHandler(e =>
|
||||
{
|
||||
string message = Encoding.UTF8.GetString((e.ApplicationMessage.Payload == null) ? new byte[] { } : e.ApplicationMessage.Payload);
|
||||
var payloadBytes = e.ApplicationMessage.Payload ?? Array.Empty<byte>();
|
||||
var messageText = string.Empty;
|
||||
|
||||
// Só tenta decodificar texto se for realmente necessário
|
||||
try { messageText = Encoding.UTF8.GetString(payloadBytes); } catch { /* binário puro */ }
|
||||
|
||||
//Console.WriteLine($"Message received on topic {e.ApplicationMessage.Topic}");
|
||||
// Aqui você pode adicionar o código para lidar com a mensagem recebida
|
||||
|
||||
|
|
@ -59,7 +76,8 @@ public class MqttService
|
|||
{
|
||||
Momento = DateTime.Now,
|
||||
Cliente = e.ClientId,
|
||||
Mensagem = message
|
||||
Mensagem = messageText,
|
||||
Bytes = payloadBytes
|
||||
};
|
||||
topico.Mensagens.Add(Mensagem);
|
||||
|
||||
|
|
@ -79,7 +97,7 @@ public class MqttService
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro no callback do tópico '{topico.Topico}': {ex}");
|
||||
LogDebug($"Erro no callback do tópico '{topico.Topico}': {ex}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -88,13 +106,7 @@ public class MqttService
|
|||
|
||||
Topicos = new List<MqttTopicosModel>();
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await AdicionarNovoTopico(MapasVariaveisModel.TopicoCoordenadasGPS);
|
||||
await AdicionarNovoTopico(MapasVariaveisModel.TopicoSelecaoRuasMapa, true, 1, async (message) => { Variaveis.OperacaoEmAndamento.Mapa.AtualizarRuasSelecionadas(); });
|
||||
await AdicionarNovoTopico(MapasVariaveisModel.TopicoTrajetoriaDinamica);
|
||||
});
|
||||
|
||||
tmrCheck?.Dispose();
|
||||
tmrCheck = new AsyncTaskTimerModel("tmrCheck", tmrCheck_Tick, 1000);
|
||||
tmrCheck.Start();
|
||||
}
|
||||
|
|
@ -120,7 +132,7 @@ public class MqttService
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Erro ao tentar se conectar ao MQTT Broker: " + ex.Message);
|
||||
LogDebug("Erro ao tentar se conectar ao MQTT Broker: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +162,7 @@ public class MqttService
|
|||
|
||||
public async Task PublishAsync(MqttTopicosModel topic, byte[] payloadBytes, bool Forcar = false)
|
||||
{
|
||||
if (topic.Inscrever && !Forcar)
|
||||
if (topic.Inscrever || (topic.Inscrever && !Forcar))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -175,11 +187,11 @@ public class MqttService
|
|||
await ConnectAsync();
|
||||
}
|
||||
await _client.SubscribeAsync(new TopicFilterBuilder().WithTopic(topic.Topico).Build());
|
||||
Console.WriteLine("Subscribed to topic: " + topic.Topico);
|
||||
LogDebug($"Subscribed to topic: {topic.Topico}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"An error occurred while subscribing from the topic: {ex.Message}");
|
||||
LogDebug($"An error occurred while subscribing from the topic: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -196,11 +208,11 @@ public class MqttService
|
|||
await ConnectAsync();
|
||||
}
|
||||
await _client.UnsubscribeAsync(new string[] { topic.Topico });
|
||||
Console.WriteLine("Unsubscribed from topic: " + topic.Topico);
|
||||
LogDebug($"Unsubscribed from topic: {topic.Topico}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"An error occurred while unsubscribing from the topic: {ex.Message}");
|
||||
LogDebug($"An error occurred while unsubscribing from the topic: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +259,7 @@ public class MqttService
|
|||
.Build();
|
||||
|
||||
await _client.PublishAsync(mensagem);
|
||||
Console.WriteLine($"Mensagem retida limpa para o tópico: {topico}");
|
||||
LogDebug($"Mensagem retida limpa para o tópico: {topico}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,5 +277,6 @@ public class MqttService
|
|||
public DateTime Momento { get; set; }
|
||||
public string Cliente { get; set; }
|
||||
public string Mensagem { get; set; }
|
||||
public byte[] Bytes { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using AgroBase.Forms;
|
||||
using AgroBase.Models;
|
||||
using AgroBase.Models;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
|
@ -67,12 +66,7 @@ namespace AgroBase.Services
|
|||
if (!string.IsNullOrEmpty(ip) && ip != Variaveis.IP_Host)
|
||||
{
|
||||
bool configurado = await EthernetService.ConfigurarIP(true, false);
|
||||
foreach (var topico in Variaveis.MqttService.Topicos.Where(x => x.Inscrever))
|
||||
{
|
||||
await Variaveis.MqttService.UnsubscribeAsync(topico);
|
||||
}
|
||||
Variaveis.MqttService.Topicos.Clear();
|
||||
Variaveis.MqttService = new MqttService("localhost", 1883);
|
||||
Variaveis.IniciarMQTT();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
|
@ -17,6 +17,8 @@ namespace AgroMonitor
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
Variaveis.IniciarMQTT();
|
||||
|
||||
RedisService.Iniciar();
|
||||
RedisService.LimparDadosIniciais();
|
||||
APIService.IniciarRotinas();
|
||||
|
|
@ -58,8 +60,8 @@ namespace AgroMonitor
|
|||
|
||||
private async Task tmrDispositivos_Tick()
|
||||
{
|
||||
lblMqtt.Text = "MQTT: " + (Variaveis.MqttService.StatusConexao() ? "Conectado" : "Desconectado");
|
||||
lblMqtt.ForeColor = Variaveis.MqttService.StatusConexao() ? Color.Green : Color.Red;
|
||||
lblMqtt.Text = "MQTT: " + (Variaveis.MqttServiceLocal.StatusConexao() ? "Conectado" : "Desconectado");
|
||||
lblMqtt.ForeColor = Variaveis.MqttServiceLocal.StatusConexao() ? Color.Green : Color.Red;
|
||||
|
||||
lblLoRa.Text = "LoRa: " + (LoRaBaseService.Iniciado ? "Conectado" : "Desconectado");
|
||||
lblLoRa.ForeColor = LoRaBaseService.Iniciado ? Color.Green : Color.Red;
|
||||
|
|
@ -76,6 +78,8 @@ namespace AgroMonitor
|
|||
{
|
||||
tmrDispositivos.SetInterval(10000);
|
||||
}
|
||||
|
||||
VariaveisMonitoramento.AtualizarListaRoversNaRede();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
# base.py
|
||||
import time, json, struct
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
BROKER_IP = "0.0.0.0" # se a base RODA o broker, tanto faz; para conectar, use "127.0.0.1"
|
||||
RID = "rover01"
|
||||
TOP_TEL = f"agrobot/{RID}/telemetry"
|
||||
TOP_CMD = f"agrobot/{RID}/cmd"
|
||||
|
||||
last_t = None
|
||||
|
||||
def on_connect(c, u, f, rc):
|
||||
print("Base conectada, rc=", rc)
|
||||
c.subscribe(TOP_TEL, qos=0)
|
||||
|
||||
def on_message(c, u, msg):
|
||||
global last_t
|
||||
if msg.topic == TOP_TEL:
|
||||
tel = json.loads(msg.payload.decode("utf-8"))
|
||||
now = time.time()
|
||||
if "t" in tel:
|
||||
rtt_ms = (now - tel["t"]) * 1000
|
||||
else:
|
||||
rtt_ms = None
|
||||
print(f"[TEL] vel={tel.get('vel')}, heading={tel.get('heading')}, rtt≈{rtt_ms:.1f} ms")
|
||||
|
||||
client = mqtt.Client(client_id="base01", clean_session=True)
|
||||
client.on_connect = on_connect
|
||||
client.on_message = on_message
|
||||
client.connect("127.0.0.1", 1883, keepalive=60) # se a base é o broker; senão use o IP do broker
|
||||
client.loop_start()
|
||||
|
||||
# Envia um comando binário exemplo (QoS 1)
|
||||
time.sleep(1.0)
|
||||
vel, ang = 0.5, 10.0
|
||||
pkt = struct.pack("<ff", vel, ang)
|
||||
client.publish(TOP_CMD, pkt, qos=1, retain=False)
|
||||
print("[BASE] Comando enviado")
|
||||
|
||||
try:
|
||||
while True:
|
||||
time.sleep(0.5)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
client.loop_stop()
|
||||
client.disconnect()
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
# rover.py
|
||||
import time, json, struct
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
BROKER_IP = "192.168.99.120" # IP da Base
|
||||
RID = "rover01"
|
||||
TOP_TEL = f"agrobot/{RID}/telemetry"
|
||||
TOP_CMD = f"agrobot/{RID}/cmd"
|
||||
TOP_HEALTH = f"agrobot/{RID}/health"
|
||||
TOP_LWT = f"agrobot/{RID}/lwt"
|
||||
|
||||
def on_connect(c, u, f, rc):
|
||||
print("Rover conectado, rc=", rc)
|
||||
c.subscribe(TOP_CMD, qos=1)
|
||||
# Publica estado online (retido)
|
||||
c.publish(TOP_HEALTH, json.dumps({"status":"online","t":time.time()}), qos=1, retain=True)
|
||||
|
||||
def on_message(c, u, msg):
|
||||
if msg.topic == TOP_CMD:
|
||||
# Exemplo de payload binário: vel (float32), ang (float32)
|
||||
vel, ang = struct.unpack("<ff", msg.payload)
|
||||
print(f"[CMD] vel={vel:.2f} m/s, ang={ang:.2f}°")
|
||||
|
||||
client = mqtt.Client(client_id=f"{RID}", clean_session=True)
|
||||
client.will_set(TOP_LWT, payload="offline", qos=1, retain=True) # LWT
|
||||
client.on_connect = on_connect
|
||||
client.on_message = on_message
|
||||
client.connect(BROKER_IP, 1883, keepalive=60)
|
||||
client.loop_start()
|
||||
|
||||
try:
|
||||
i = 0
|
||||
while True:
|
||||
# Telemetria json (poderia ser binário também)
|
||||
tel = {"t": time.time(), "heading": 123.45+i*0.01, "vel": 1.6}
|
||||
client.publish(TOP_TEL, json.dumps(tel), qos=0, retain=False)
|
||||
i += 1
|
||||
time.sleep(0.2)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
client.loop_stop()
|
||||
client.disconnect()
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# base_tx.py
|
||||
import socket, time
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
|
||||
ROBO_IP = "192.168.99.108"
|
||||
|
||||
i = 0
|
||||
while True:
|
||||
msg = f"PING {i}".encode()
|
||||
sock.sendto(msg, (ROBO_IP, 5000))
|
||||
i += 1
|
||||
time.sleep(0.2)
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# robo_rx.py
|
||||
import socket
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock.bind(("0.0.0.0", 5000))
|
||||
|
||||
print("ROBO ouvindo na porta 5000...")
|
||||
while True:
|
||||
data, addr = sock.recvfrom(1024)
|
||||
print(f"[ROBÔ] Recebido de {addr}: {data}")
|
||||
Loading…
Reference in New Issue