ajustes para oid
This commit is contained in:
parent
92a845aec0
commit
c3b93d4906
|
|
@ -257,14 +257,7 @@ namespace AgroBase.Models.Modules
|
||||||
{
|
{
|
||||||
byte addrTx = Modulo.MovMotor._EnderecoCAN_Tx;
|
byte addrTx = Modulo.MovMotor._EnderecoCAN_Tx;
|
||||||
byte addrRx = Modulo.MovMotor._EnderecoCAN_Rx;
|
byte addrRx = Modulo.MovMotor._EnderecoCAN_Rx;
|
||||||
OIDCanService.RequisitarDado(addrTx, addrRx, OIDCanService.OidHandler.OidParametros.VelocidadeAtual);
|
OIDCanService.RequisitarProximoDado(addrTx, addrRx);
|
||||||
OIDCanService.RequisitarDado(addrTx, addrRx, OIDCanService.OidHandler.OidParametros.Potencia);
|
|
||||||
OIDCanService.RequisitarDado(addrTx, addrRx, OIDCanService.OidHandler.OidParametros.Temperatura);
|
|
||||||
OIDCanService.RequisitarDado(addrTx, addrRx, OIDCanService.OidHandler.OidParametros.CicloTrabalho);
|
|
||||||
OIDCanService.RequisitarDado(addrTx, addrRx, OIDCanService.OidHandler.OidParametros.CodErro);
|
|
||||||
OIDCanService.RequisitarDado(addrTx, addrRx, OIDCanService.OidHandler.OidParametros.CorrenteBarramento);
|
|
||||||
OIDCanService.RequisitarDado(addrTx, addrRx, OIDCanService.OidHandler.OidParametros.CorrenteMotor);
|
|
||||||
OIDCanService.RequisitarDado(addrTx, addrRx, OIDCanService.OidHandler.OidParametros.Tensao);
|
|
||||||
Modulo.MovMotor.RequisitarDadosSensoresExternos();
|
Modulo.MovMotor.RequisitarDadosSensoresExternos();
|
||||||
|
|
||||||
var Controle = Variaveis.OperacaoEmAndamento.Controle.TiposControle?.FirstOrDefault(x => x.Tipo == T_Code.Mov);
|
var Controle = Variaveis.OperacaoEmAndamento.Controle.TiposControle?.FirstOrDefault(x => x.Tipo == T_Code.Mov);
|
||||||
|
|
|
||||||
|
|
@ -797,7 +797,68 @@ namespace AgroBase.Services
|
||||||
{
|
{
|
||||||
_roteadores.TryGetValue(id, out ICanMessageHandler handler);
|
_roteadores.TryGetValue(id, out ICanMessageHandler handler);
|
||||||
|
|
||||||
T_Code dispositivo = handler?.Dispositivo ?? T_Code.Vzo;
|
if (handler == null)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Fallback para OID/par Tx-Rx:
|
||||||
|
* Se o frame chegou pelo ID de TX do pendente, talvez não exista
|
||||||
|
* roteador registrado exatamente nesse ID. Tenta achar o handler
|
||||||
|
* pelo dispositivo pendente.
|
||||||
|
*/
|
||||||
|
T_Code? dispositivoPendente = null;
|
||||||
|
|
||||||
|
lock (_LockMensagens)
|
||||||
|
{
|
||||||
|
dispositivoPendente =
|
||||||
|
MensagensPendentes
|
||||||
|
.Where(x =>
|
||||||
|
x.ComResposta &&
|
||||||
|
x.Enviado &&
|
||||||
|
!x.Respondido &&
|
||||||
|
(
|
||||||
|
x.IdRx == id ||
|
||||||
|
x.IdTx == id
|
||||||
|
))
|
||||||
|
.OrderBy(x => x.EnviadoEm)
|
||||||
|
.Select(x => (T_Code?)x.Dispositivo)
|
||||||
|
.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dispositivoPendente.HasValue)
|
||||||
|
{
|
||||||
|
handler =
|
||||||
|
_roteadores
|
||||||
|
.Values
|
||||||
|
.FirstOrDefault(
|
||||||
|
h => h.Dispositivo == dispositivoPendente.Value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T_Code dispositivo =
|
||||||
|
handler?.Dispositivo ?? T_Code.Vzo;
|
||||||
|
|
||||||
|
if (dispositivo == T_Code.Vzo)
|
||||||
|
{
|
||||||
|
lock (_LockMensagens)
|
||||||
|
{
|
||||||
|
var pendente =
|
||||||
|
MensagensPendentes
|
||||||
|
.Where(x =>
|
||||||
|
x.ComResposta &&
|
||||||
|
x.Enviado &&
|
||||||
|
!x.Respondido &&
|
||||||
|
(
|
||||||
|
x.IdRx == id ||
|
||||||
|
x.IdTx == id
|
||||||
|
))
|
||||||
|
.OrderBy(x => x.EnviadoEm)
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (pendente != null)
|
||||||
|
dispositivo = pendente.Dispositivo;
|
||||||
|
}
|
||||||
|
}
|
||||||
bool db = dispositivo == T_Code.Bat;
|
bool db = dispositivo == T_Code.Bat;
|
||||||
|
|
||||||
byte fCodeRx = db ? (byte)DalyBMSService.GetDataId(id) : data.Length > 0 ? data[0] : (byte)0x00;
|
byte fCodeRx = db ? (byte)DalyBMSService.GetDataId(id) : data.Length > 0 ? data[0] : (byte)0x00;
|
||||||
|
|
@ -854,7 +915,11 @@ namespace AgroBase.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool MensagemCorrespondeResposta(CanMessage pendente, T_Code dispositivoResposta, uint idResposta, byte[] dataResposta)
|
private bool MensagemCorrespondeResposta(
|
||||||
|
CanMessage pendente,
|
||||||
|
T_Code dispositivoResposta,
|
||||||
|
uint idResposta,
|
||||||
|
byte[] dataResposta)
|
||||||
{
|
{
|
||||||
if (pendente == null)
|
if (pendente == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -871,9 +936,6 @@ namespace AgroBase.Services
|
||||||
if (pendente.Dispositivo != dispositivoResposta)
|
if (pendente.Dispositivo != dispositivoResposta)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (pendente.IdRx != idResposta)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
byte[] dataTx =
|
byte[] dataTx =
|
||||||
pendente.DataTx ?? new byte[0];
|
pendente.DataTx ?? new byte[0];
|
||||||
|
|
||||||
|
|
@ -884,32 +946,45 @@ namespace AgroBase.Services
|
||||||
{
|
{
|
||||||
case T_Code.Bat:
|
case T_Code.Bat:
|
||||||
/*
|
/*
|
||||||
* Daly: DataID vem no CAN ID, então idRx já fechou.
|
* Daly usa DataID no CAN ID estendido.
|
||||||
*/
|
*/
|
||||||
return true;
|
return pendente.IdRx == idResposta;
|
||||||
|
|
||||||
case T_Code.Mks:
|
case T_Code.Mks:
|
||||||
return
|
return
|
||||||
|
pendente.IdRx == idResposta &&
|
||||||
dataRx.Length > 0 &&
|
dataRx.Length > 0 &&
|
||||||
pendente.funcCodeRx == dataRx[0];
|
pendente.funcCodeRx == dataRx[0];
|
||||||
|
|
||||||
case T_Code.Oid:
|
case T_Code.Oid:
|
||||||
/*
|
{
|
||||||
* OID:
|
/*
|
||||||
* consulta retorna DATA[0]=0x0F e DATA[1]=param.
|
* OID pode responder no mesmo ID do comando ou no par lógico RX.
|
||||||
*/
|
*/
|
||||||
return
|
bool idOk =
|
||||||
dataRx.Length >= 2 &&
|
pendente.IdRx == idResposta ||
|
||||||
dataTx.Length >= 2 &&
|
pendente.IdTx == idResposta;
|
||||||
dataRx[0] == pendente.funcCodeRx &&
|
|
||||||
dataRx[1] == dataTx[1];
|
if (!idOk)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Consulta OID:
|
||||||
|
* TX: DATA[0]=0x0F, DATA[1]=param
|
||||||
|
* RX: DATA[0]=0x0F, DATA[1]=param, DATA[2..]=valor
|
||||||
|
*/
|
||||||
|
return
|
||||||
|
dataRx.Length >= 2 &&
|
||||||
|
dataTx.Length >= 2 &&
|
||||||
|
dataRx[0] == pendente.funcCodeRx &&
|
||||||
|
dataRx[1] == dataTx[1];
|
||||||
|
}
|
||||||
|
|
||||||
case T_Code.Atu:
|
case T_Code.Atu:
|
||||||
case T_Code.Sen:
|
case T_Code.Sen:
|
||||||
/*
|
if (pendente.IdRx != idResposta)
|
||||||
* ATU/SEN:
|
return false;
|
||||||
* casa pelo func/posição e, quando existir, pelo ID_Num.
|
|
||||||
*/
|
|
||||||
if (dataRx.Length <= 0)
|
if (dataRx.Length <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -922,6 +997,9 @@ namespace AgroBase.Services
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (pendente.IdRx != idResposta)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (dataRx.Length <= 0)
|
if (dataRx.Length <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ namespace AgroBase.Services
|
||||||
|
|
||||||
public static int TaxaAmostragem
|
public static int TaxaAmostragem
|
||||||
{
|
{
|
||||||
get { return 1000; }
|
get { return 60; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<bool> VerificaDispositivoConectado()
|
public static async Task<bool> VerificaDispositivoConectado()
|
||||||
|
|
@ -170,7 +170,7 @@ namespace AgroBase.Services
|
||||||
byte idRx =
|
byte idRx =
|
||||||
modulo.MovMotor._EnderecoCAN_Rx;
|
modulo.MovMotor._EnderecoCAN_Rx;
|
||||||
|
|
||||||
RegistrarHandler(idRx);
|
RegistrarHandlersMotor(idTx, idRx);
|
||||||
|
|
||||||
EnviarComandoDescoberta(idTx, idRx);
|
EnviarComandoDescoberta(idTx, idRx);
|
||||||
|
|
||||||
|
|
@ -217,7 +217,10 @@ namespace AgroBase.Services
|
||||||
if (modulo == null)
|
if (modulo == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RegistrarHandler(modulo._EnderecoCAN_Rx);
|
RegistrarHandlersMotor(
|
||||||
|
modulo._EnderecoCAN_Tx,
|
||||||
|
modulo._EnderecoCAN_Rx
|
||||||
|
);
|
||||||
|
|
||||||
var leitura =
|
var leitura =
|
||||||
DadosLeitura.FirstOrDefault(
|
DadosLeitura.FirstOrDefault(
|
||||||
|
|
@ -305,11 +308,19 @@ namespace AgroBase.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void RegistrarHandlersMotor(byte idTx, byte idRx)
|
||||||
|
{
|
||||||
|
RegistrarHandler(idTx);
|
||||||
|
|
||||||
|
if (idRx != idTx)
|
||||||
|
RegistrarHandler(idRx);
|
||||||
|
}
|
||||||
|
|
||||||
#region COMANDOS
|
#region COMANDOS
|
||||||
|
|
||||||
private static void EnviarComandoDescoberta(byte idTx, byte idRx)
|
private static void EnviarComandoDescoberta(byte idTx, byte idRx)
|
||||||
{
|
{
|
||||||
RegistrarHandler(idRx);
|
RegistrarHandlersMotor(idTx, idRx);
|
||||||
|
|
||||||
CanManager.CanService.AdicionarMensagemNaFila(
|
CanManager.CanService.AdicionarMensagemNaFila(
|
||||||
Dispositivo,
|
Dispositivo,
|
||||||
|
|
@ -333,7 +344,7 @@ namespace AgroBase.Services
|
||||||
bool get = true,
|
bool get = true,
|
||||||
bool contabilizarTimeoutHealth = true)
|
bool contabilizarTimeoutHealth = true)
|
||||||
{
|
{
|
||||||
RegistrarHandler(idRx);
|
RegistrarHandlersMotor(idTx, idRx);
|
||||||
|
|
||||||
CanManager.CanService.AdicionarMensagemNaFila(
|
CanManager.CanService.AdicionarMensagemNaFila(
|
||||||
dispositivo,
|
dispositivo,
|
||||||
|
|
@ -420,6 +431,17 @@ namespace AgroBase.Services
|
||||||
_ultimaConsultaPendente[idTx] = dado;
|
_ultimaConsultaPendente[idTx] = dado;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(
|
||||||
|
"[OID/TX] idTx=" +
|
||||||
|
idTx.ToString("X2") +
|
||||||
|
" idRx=" +
|
||||||
|
idRx.ToString("X2") +
|
||||||
|
" param=" +
|
||||||
|
dado +
|
||||||
|
" data=0F-" +
|
||||||
|
((byte)dado).ToString("X2")
|
||||||
|
);
|
||||||
|
|
||||||
EnviarComando(
|
EnviarComando(
|
||||||
Dispositivo,
|
Dispositivo,
|
||||||
idTx,
|
idTx,
|
||||||
|
|
@ -447,6 +469,22 @@ namespace AgroBase.Services
|
||||||
dado == OidParametros.CorrenteBarramento;
|
dado == OidParametros.CorrenteBarramento;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void RequisitarProximoDado(byte idTx, byte idRx)
|
||||||
|
{
|
||||||
|
OidParametros parametro =
|
||||||
|
EscolherProximoParametro(idTx) ??
|
||||||
|
OidParametros.VelocidadeAtual;
|
||||||
|
|
||||||
|
RequisitarDadoInterno(
|
||||||
|
idTx,
|
||||||
|
idRx,
|
||||||
|
parametro,
|
||||||
|
forcar: false,
|
||||||
|
contabilizarTimeoutHealth:
|
||||||
|
DeveContabilizarTimeoutHealth(parametro)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static void AtualizarDados()
|
public static void AtualizarDados()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -996,30 +1034,98 @@ namespace AgroBase.Services
|
||||||
SinalZNaoEncontrado = 19
|
SinalZNaoEncontrado = 19
|
||||||
}
|
}
|
||||||
|
|
||||||
private OIDModel ObterOuCriar(uint _idTx, uint _idRx)
|
private OIDModel ObterOuCriar(CanMessage mensagem)
|
||||||
{
|
{
|
||||||
lock (DadosLeitura)
|
lock (DadosLeitura)
|
||||||
{
|
{
|
||||||
byte idTx =
|
byte idTxMsg =
|
||||||
CanManager.ConverterIdCan(_idTx)[0];
|
CanManager.ConverterIdCan(
|
||||||
|
mensagem.IdTx
|
||||||
|
)[0];
|
||||||
|
|
||||||
byte idRx =
|
byte idRxMsg =
|
||||||
CanManager.ConverterIdCan(_idRx)[0];
|
CanManager.ConverterIdCan(
|
||||||
|
mensagem.IdRx
|
||||||
|
)[0];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Primeiro, tenta achar pelo par exato.
|
||||||
|
*/
|
||||||
var item =
|
var item =
|
||||||
DadosLeitura.FirstOrDefault(
|
DadosLeitura.FirstOrDefault(
|
||||||
x => x.EnderecoTx == idTx &&
|
x => x.EnderecoTx == idTxMsg &&
|
||||||
x.EnderecoRx == idRx
|
x.EnderecoRx == idRxMsg
|
||||||
|
);
|
||||||
|
|
||||||
|
if (item != null)
|
||||||
|
return item;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Depois, tenta achar pelo motor configurado.
|
||||||
|
* Isso evita criar leitura órfã quando o OID responde no mesmo ID
|
||||||
|
* usado como Tx ou em outro ID lógico.
|
||||||
|
*/
|
||||||
|
var motor =
|
||||||
|
Variaveis
|
||||||
|
.OperacaoEmAndamento
|
||||||
|
.DispMvd?
|
||||||
|
.Dados?
|
||||||
|
.Modulos?
|
||||||
|
.Select(x => x?.MovMotor)
|
||||||
|
.FirstOrDefault(m =>
|
||||||
|
m != null &&
|
||||||
|
(
|
||||||
|
m._EnderecoCAN_Tx == idTxMsg ||
|
||||||
|
m._EnderecoCAN_Rx == idTxMsg ||
|
||||||
|
m._EnderecoCAN_Tx == idRxMsg ||
|
||||||
|
m._EnderecoCAN_Rx == idRxMsg
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (motor != null)
|
||||||
|
{
|
||||||
|
item =
|
||||||
|
DadosLeitura.FirstOrDefault(
|
||||||
|
x => x.EnderecoTx == motor._EnderecoCAN_Tx
|
||||||
|
);
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
item = new OIDModel
|
||||||
|
{
|
||||||
|
EnderecoTx = motor._EnderecoCAN_Tx,
|
||||||
|
EnderecoRx = motor._EnderecoCAN_Rx
|
||||||
|
};
|
||||||
|
|
||||||
|
DadosLeitura.Add(item);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.EnderecoRx = motor._EnderecoCAN_Rx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fallback final.
|
||||||
|
*/
|
||||||
|
item =
|
||||||
|
DadosLeitura.FirstOrDefault(
|
||||||
|
x =>
|
||||||
|
x.EnderecoTx == idTxMsg ||
|
||||||
|
x.EnderecoRx == idTxMsg ||
|
||||||
|
x.EnderecoTx == idRxMsg ||
|
||||||
|
x.EnderecoRx == idRxMsg
|
||||||
);
|
);
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
item =
|
item = new OIDModel
|
||||||
new OIDModel
|
{
|
||||||
{
|
EnderecoTx = idTxMsg,
|
||||||
EnderecoTx = idTx,
|
EnderecoRx = idRxMsg
|
||||||
EnderecoRx = idRx
|
};
|
||||||
};
|
|
||||||
|
|
||||||
DadosLeitura.Add(item);
|
DadosLeitura.Add(item);
|
||||||
}
|
}
|
||||||
|
|
@ -1052,11 +1158,7 @@ namespace AgroBase.Services
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var item =
|
var item = ObterOuCriar(mensagem);
|
||||||
ObterOuCriar(
|
|
||||||
mensagem.IdTx,
|
|
||||||
mensagem.IdRx
|
|
||||||
);
|
|
||||||
|
|
||||||
if (func == OidFuncCode.ConsultaStatusRetornoZero)
|
if (func == OidFuncCode.ConsultaStatusRetornoZero)
|
||||||
{
|
{
|
||||||
|
|
@ -1070,6 +1172,15 @@ namespace AgroBase.Services
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(
|
||||||
|
"[OID/RX] idTx=" +
|
||||||
|
mensagem.IdTx.ToString("X") +
|
||||||
|
" idRx=" +
|
||||||
|
mensagem.IdRx.ToString("X") +
|
||||||
|
" data=" +
|
||||||
|
BitConverter.ToString(mensagem.DataRx ?? new byte[0])
|
||||||
|
);
|
||||||
|
|
||||||
OidParametros parametro =
|
OidParametros parametro =
|
||||||
(OidParametros)mensagem.DataRx[1];
|
(OidParametros)mensagem.DataRx[1];
|
||||||
|
|
||||||
|
|
@ -1084,9 +1195,8 @@ namespace AgroBase.Services
|
||||||
|
|
||||||
lock (_sync)
|
lock (_sync)
|
||||||
{
|
{
|
||||||
_ultimaConsultaPendente.Remove(
|
_ultimaConsultaPendente.Remove(item.EnderecoTx);
|
||||||
item.EnderecoTx
|
_ultimaConsultaPendente.Remove(item.EnderecoRx);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
||||||
|
|
@ -428,7 +428,7 @@ namespace AgroBase.Services.Operadores
|
||||||
RedisService.ModKey(Enums.T_Code.Mov),
|
RedisService.ModKey(Enums.T_Code.Mov),
|
||||||
($"{endereco_mov}.timestamp", agora),
|
($"{endereco_mov}.timestamp", agora),
|
||||||
($"{endereco_mov}.conectado", mod.MovMotor.Inicializado),
|
($"{endereco_mov}.conectado", mod.MovMotor.Inicializado),
|
||||||
($"{endereco_mov}.freq_base", Variaveis.OperacaoEmAndamento.DispMvd.Dados.tmrRegistradorMOV.IntervalHz),
|
($"{endereco_mov}.freq_base", 1),
|
||||||
($"{endereco_mov}.endereco", mod.MovMotor._EnderecoCAN_Tx),
|
($"{endereco_mov}.endereco", mod.MovMotor._EnderecoCAN_Tx),
|
||||||
($"{endereco_mov}.mod_id", mod.Modulo_ID),
|
($"{endereco_mov}.mod_id", mod.Modulo_ID),
|
||||||
($"{endereco_mov}.cod_erro", mod.MovMotor.CodigoAlarme),
|
($"{endereco_mov}.cod_erro", mod.MovMotor.CodigoAlarme),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue