From 57a8c37c92b93b910e799fc840a255b4b413e874 Mon Sep 17 00:00:00 2001 From: Diego Freitas Date: Mon, 8 Jun 2026 10:56:00 -0300 Subject: [PATCH] hotfixes para mks can --- .../AgroBase/Services/CANServiceSerial.cs | 45 ++++++++++++++++--- .../AgroBase/Services/CANServiceWaveshare.cs | 32 ++++++++----- .../AgroBase/Services/CanServiceEthernet.cs | 6 +-- 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/AgroBase/AgroBase/Services/CANServiceSerial.cs b/AgroBase/AgroBase/Services/CANServiceSerial.cs index 853394daf..427042714 100644 --- a/AgroBase/AgroBase/Services/CANServiceSerial.cs +++ b/AgroBase/AgroBase/Services/CANServiceSerial.cs @@ -404,12 +404,24 @@ namespace AgroBase.Services // Isso é muito específico do protocolo antigo. // Pro BMS, o matching pode ser só por IdRx e Dispositivo. mensagem = Mensagens.FirstOrDefault(x => - x.Enviado && - !x.Respondido && - x.Dispositivo == dispositivo && - x.IdRx == id && - (db ? true : x.DataTx[1] == data[1]) // basteria nao checa o funccode - ); + { + if (!x.Enviado) return false; + if (x.Respondido) return false; + if (x.Dispositivo != dispositivo) return false; + 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) @@ -557,6 +569,24 @@ namespace AgroBase.Services return proximaMsg; } + private readonly ConcurrentDictionary _cooldownPorId = new ConcurrentDictionary(); + 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() { if (_PortaCAN?.IsOpen != true) return; @@ -572,7 +602,8 @@ namespace AgroBase.Services var msg = ObterProximaMensagem(); 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” // Se precisar espaçar MKS, use cooldown por-ID (abaixo) diff --git a/AgroBase/AgroBase/Services/CANServiceWaveshare.cs b/AgroBase/AgroBase/Services/CANServiceWaveshare.cs index 6136c072e..02c002116 100644 --- a/AgroBase/AgroBase/Services/CANServiceWaveshare.cs +++ b/AgroBase/AgroBase/Services/CANServiceWaveshare.cs @@ -229,14 +229,24 @@ namespace AgroBase.Services lock (_LockMensagens) { mensagem = MensagensPendentes.FirstOrDefault(x => - x.Enviado && - !x.Respondido && - x.Dispositivo == dispositivo && - x.IdRx == id && // usa o ID completo (11 ou 29 bits) - x.DataTx != null && - x.DataTx.Length > 1 && - (db ? true : x.DataTx[1] == data[1]) - ); + { + if (!x.Enviado) return false; + if (x.Respondido) return false; + if (x.Dispositivo != dispositivo) return false; + 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) @@ -244,6 +254,7 @@ namespace AgroBase.Services mensagem = new CanMessage { Dispositivo = dispositivo, + IdTx = id, IdRx = id, funcCodeRx = fCodeRx, DataRx = data, @@ -378,7 +389,7 @@ namespace AgroBase.Services } private readonly ConcurrentDictionary _cooldownPorId = new ConcurrentDictionary(); - private static readonly TimeSpan COOLDOWN_MKS = TimeSpan.FromMilliseconds(6); + private static readonly TimeSpan COOLDOWN_MKS = TimeSpan.FromMilliseconds(20); private bool PodeEnviarAgora(CanMessage m) { @@ -408,7 +419,8 @@ namespace AgroBase.Services var msg = ObterProximaMensagem(); 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” // Se precisar espaçar MKS, use cooldown por-ID (abaixo) diff --git a/AgroBase/AgroBase/Services/CanServiceEthernet.cs b/AgroBase/AgroBase/Services/CanServiceEthernet.cs index 362b4e3ec..dccadb9c2 100644 --- a/AgroBase/AgroBase/Services/CanServiceEthernet.cs +++ b/AgroBase/AgroBase/Services/CanServiceEthernet.cs @@ -53,9 +53,6 @@ namespace AgroBase.Services private readonly ConcurrentDictionary _roteadoresRegistrados = new ConcurrentDictionary(); private readonly List MensagensPendentes = new List(); - private readonly ConcurrentDictionary _cooldownPorId = new ConcurrentDictionary(); - private static readonly TimeSpan COOLDOWN_MKS = TimeSpan.FromMilliseconds(20); - private uint? _ultimoIdEnviado = null; private bool DebugMode = false; @@ -305,6 +302,9 @@ namespace AgroBase.Services return baseLista.Where(x => x.IdTx == proximoId).OrderBy(x => x.Momento).FirstOrDefault(); } + private readonly ConcurrentDictionary _cooldownPorId = new ConcurrentDictionary(); + private static readonly TimeSpan COOLDOWN_MKS = TimeSpan.FromMilliseconds(20); + private bool PodeEnviarAgora(CanMessage m) { if (m.Dispositivo != T_Code.Mks)