hotfixes para mks can

This commit is contained in:
Diego Freitas 2026-06-08 10:56:00 -03:00
parent 746ca24ee2
commit 57a8c37c92
3 changed files with 63 additions and 20 deletions

View File

@ -404,12 +404,24 @@ namespace AgroBase.Services
// Isso é muito específico do protocolo antigo. // Isso é muito específico do protocolo antigo.
// Pro BMS, o matching pode ser só por IdRx e Dispositivo. // Pro BMS, o matching pode ser só por IdRx e Dispositivo.
mensagem = Mensagens.FirstOrDefault(x => mensagem = Mensagens.FirstOrDefault(x =>
x.Enviado && {
!x.Respondido && if (!x.Enviado) return false;
x.Dispositivo == dispositivo && if (x.Respondido) return false;
x.IdRx == id && if (x.Dispositivo != dispositivo) return false;
(db ? true : x.DataTx[1] == data[1]) // basteria nao checa o funccode if (x.IdRx != id) return false;
); if (x.DataTx == null || x.DataTx.Length == 0) return false;
if (db)
return true;
if (x.Dispositivo == T_Code.Mks)
return data.Length > 0 && x.funcCodeRx == data[0];
if (data.Length < 2 || x.DataTx.Length < 2)
return true;
return x.DataTx[1] == data[1];
});
} }
if (mensagem == null) if (mensagem == null)
@ -557,6 +569,24 @@ namespace AgroBase.Services
return proximaMsg; return proximaMsg;
} }
private readonly ConcurrentDictionary<uint, DateTime> _cooldownPorId = new ConcurrentDictionary<uint, DateTime>();
private static readonly TimeSpan COOLDOWN_MKS = TimeSpan.FromMilliseconds(20);
private bool PodeEnviarAgora(CanMessage m)
{
if (m.Dispositivo != T_Code.Mks)
return true;
var now = DateTime.UtcNow;
var due = _cooldownPorId.GetOrAdd(m.IdTx, DateTime.MinValue);
if (now < due)
return false;
_cooldownPorId[m.IdTx] = now + COOLDOWN_MKS;
return true;
}
private async Task EnviarCAN() private async Task EnviarCAN()
{ {
if (_PortaCAN?.IsOpen != true) return; if (_PortaCAN?.IsOpen != true) return;
@ -572,7 +602,8 @@ namespace AgroBase.Services
var msg = ObterProximaMensagem(); var msg = ObterProximaMensagem();
if (msg == null) break; if (msg == null) break;
//if (!PodeEnviarAgora(msg)) break; // sem token “perdido”: sai do burst e tenta no próximo tick if (!PodeEnviarAgora(msg))
break;
// Evite delays arbitrários em caminho “quente” // Evite delays arbitrários em caminho “quente”
// Se precisar espaçar MKS, use cooldown por-ID (abaixo) // Se precisar espaçar MKS, use cooldown por-ID (abaixo)

View File

@ -229,14 +229,24 @@ namespace AgroBase.Services
lock (_LockMensagens) lock (_LockMensagens)
{ {
mensagem = MensagensPendentes.FirstOrDefault(x => mensagem = MensagensPendentes.FirstOrDefault(x =>
x.Enviado && {
!x.Respondido && if (!x.Enviado) return false;
x.Dispositivo == dispositivo && if (x.Respondido) return false;
x.IdRx == id && // usa o ID completo (11 ou 29 bits) if (x.Dispositivo != dispositivo) return false;
x.DataTx != null && if (x.IdRx != id) return false;
x.DataTx.Length > 1 && if (x.DataTx == null || x.DataTx.Length == 0) return false;
(db ? true : x.DataTx[1] == data[1])
); if (db)
return true;
if (x.Dispositivo == T_Code.Mks)
return data.Length > 0 && x.funcCodeRx == data[0];
if (data.Length < 2 || x.DataTx.Length < 2)
return true;
return x.DataTx[1] == data[1];
});
} }
if (mensagem == null) if (mensagem == null)
@ -244,6 +254,7 @@ namespace AgroBase.Services
mensagem = new CanMessage mensagem = new CanMessage
{ {
Dispositivo = dispositivo, Dispositivo = dispositivo,
IdTx = id,
IdRx = id, IdRx = id,
funcCodeRx = fCodeRx, funcCodeRx = fCodeRx,
DataRx = data, DataRx = data,
@ -378,7 +389,7 @@ namespace AgroBase.Services
} }
private readonly ConcurrentDictionary<uint, DateTime> _cooldownPorId = new ConcurrentDictionary<uint, DateTime>(); private readonly ConcurrentDictionary<uint, DateTime> _cooldownPorId = new ConcurrentDictionary<uint, DateTime>();
private static readonly TimeSpan COOLDOWN_MKS = TimeSpan.FromMilliseconds(6); private static readonly TimeSpan COOLDOWN_MKS = TimeSpan.FromMilliseconds(20);
private bool PodeEnviarAgora(CanMessage m) private bool PodeEnviarAgora(CanMessage m)
{ {
@ -408,7 +419,8 @@ namespace AgroBase.Services
var msg = ObterProximaMensagem(); var msg = ObterProximaMensagem();
if (msg == null) break; if (msg == null) break;
//if (!PodeEnviarAgora(msg)) break; // sem token “perdido”: sai do burst e tenta no próximo tick if (!PodeEnviarAgora(msg))
break;
// Evite delays arbitrários em caminho “quente” // Evite delays arbitrários em caminho “quente”
// Se precisar espaçar MKS, use cooldown por-ID (abaixo) // Se precisar espaçar MKS, use cooldown por-ID (abaixo)

View File

@ -53,9 +53,6 @@ namespace AgroBase.Services
private readonly ConcurrentDictionary<uint, bool> _roteadoresRegistrados = new ConcurrentDictionary<uint, bool>(); private readonly ConcurrentDictionary<uint, bool> _roteadoresRegistrados = new ConcurrentDictionary<uint, bool>();
private readonly List<CanMessage> MensagensPendentes = new List<CanMessage>(); private readonly List<CanMessage> MensagensPendentes = new List<CanMessage>();
private readonly ConcurrentDictionary<uint, DateTime> _cooldownPorId = new ConcurrentDictionary<uint, DateTime>();
private static readonly TimeSpan COOLDOWN_MKS = TimeSpan.FromMilliseconds(20);
private uint? _ultimoIdEnviado = null; private uint? _ultimoIdEnviado = null;
private bool DebugMode = false; private bool DebugMode = false;
@ -305,6 +302,9 @@ namespace AgroBase.Services
return baseLista.Where(x => x.IdTx == proximoId).OrderBy(x => x.Momento).FirstOrDefault(); return baseLista.Where(x => x.IdTx == proximoId).OrderBy(x => x.Momento).FirstOrDefault();
} }
private readonly ConcurrentDictionary<uint, DateTime> _cooldownPorId = new ConcurrentDictionary<uint, DateTime>();
private static readonly TimeSpan COOLDOWN_MKS = TimeSpan.FromMilliseconds(20);
private bool PodeEnviarAgora(CanMessage m) private bool PodeEnviarAgora(CanMessage m)
{ {
if (m.Dispositivo != T_Code.Mks) if (m.Dispositivo != T_Code.Mks)