760 lines
27 KiB
C#
760 lines
27 KiB
C#
using AgroBase.Forms;
|
|
using AgroBase.Models;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO.Ports;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using static AgroBase.Models.Enums;
|
|
using System.Windows.Forms;
|
|
using Emgu.CV.Structure;
|
|
using System.Drawing.Printing;
|
|
using System.Threading;
|
|
using System.IO;
|
|
using Newtonsoft.Json;
|
|
using System.Collections;
|
|
|
|
namespace AgroBase.Services
|
|
{
|
|
public class BLD300RService
|
|
{
|
|
public static bool Iniciado
|
|
{
|
|
get
|
|
{
|
|
if (!SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Bld) && DadosLeitura.All(x => !x.Iniciado))
|
|
{
|
|
return false;
|
|
}
|
|
if (_PortaBLD != null && !_PortaBLD.IsOpen)
|
|
{
|
|
try
|
|
{
|
|
_PortaBLD.Open();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
RegisrarErrosComunicacao(0, $"Erro ao abrir porta {_PortaBLD.PortName}. Erro={ex.Message}");
|
|
//_PortaBLD = null;
|
|
}
|
|
}
|
|
return _PortaBLD != null && _PortaBLD.IsOpen && DadosLeitura.Any(x => x.Iniciado);
|
|
}
|
|
}
|
|
public static int TaxaAmostragem { get; set; } = 1000;
|
|
public static SerialPort _PortaBLD = new SerialPort();
|
|
|
|
public static List<BLD300RModel> DadosLeitura = new List<BLD300RModel>();
|
|
|
|
public static List<ModbusParametrosModel> Parametros = new List<ModbusParametrosModel>()
|
|
{
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "Versao",
|
|
Descricao = "Verifica a versão do driver",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 1,
|
|
LeituraLoop = false,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x00BB
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "ControleRS485",
|
|
Descricao = "Habilita/Desabilita controle através da interface RS485",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 1,
|
|
LeituraLoop = false,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x00B6
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "AlarmeCode",
|
|
Descricao = "Verifica o código de alarme",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 1,
|
|
LeituraLoop = true,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x0076
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "NumPolos",
|
|
Descricao = "Verifica/Define o número de polos do motor definido no driver",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 1,
|
|
LeituraLoop = false,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x0086
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "RPM_Max",
|
|
Descricao = "Verifica/Define o RPM máximo do motor através do controle",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 1,
|
|
LeituraLoop = false,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x0092
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "Rampa",
|
|
Descricao = "Verifica/Define o tempo de rampa de aceleração/desaceleração (x 100 ms)",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 1,
|
|
LeituraLoop = false,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x008A
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "RPM_SP",
|
|
Descricao = "Verifica/Define o RPM de Set Point",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 1,
|
|
LeituraLoop = false,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x0056
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "RPM",
|
|
Descricao = "Verifica o RPM atual do motor",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 0.27,
|
|
LeituraLoop = true,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x005F
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "Enabled",
|
|
Descricao = "Verifica/Define o status do motor",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 1,
|
|
LeituraLoop = true,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x0066
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "Breaked",
|
|
Descricao = "Verifica/Define o status do freio do motor",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 1,
|
|
LeituraLoop = true,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x006A
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "Direction",
|
|
Descricao = "Verifica/Define o sentido de giro do motor",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 1,
|
|
LeituraLoop = true,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x006D
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "LimiteCorrente",
|
|
Descricao = "Verifica o limite de corrente definido",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 0.01,
|
|
LeituraLoop = false,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0002,
|
|
Registro = 0x0096
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "Tensao",
|
|
Descricao = "Verifica a tensão de alimentação no driver",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 0.01,
|
|
LeituraLoop = true,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0002,
|
|
Registro = 0x00C8
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "Temperatura",
|
|
Descricao = "Verifica a temperatura do driver",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 0.01,
|
|
LeituraLoop = true,
|
|
LeituraGeral = true,
|
|
N_Registros = 0x0002,
|
|
Registro = 0x00d2
|
|
},
|
|
new ModbusParametrosModel()
|
|
{
|
|
Chave = "Restaurar",
|
|
Descricao = "Restaura os parâmetros de fábrica",
|
|
FuncaoGet = 0x03,
|
|
FuncaoSet = 0x06,
|
|
Escala = 1,
|
|
LeituraLoop = false,
|
|
LeituraGeral = false,
|
|
N_Registros = 0x0001,
|
|
Registro = 0x00CC
|
|
},
|
|
|
|
|
|
};
|
|
|
|
private static List<BLDComandoModel> FilaComandos = new List<BLDComandoModel>();
|
|
|
|
private static readonly object FilaLock = new object();
|
|
|
|
private static System.Windows.Forms.Timer tmrLoopComandos = new System.Windows.Forms.Timer() { Interval = 100 };
|
|
private static bool EnvioLiberado { get; set; } = true;
|
|
|
|
|
|
public static async Task<bool> VerificaPortaBLD(SerialPort porta)
|
|
{
|
|
if (!Iniciado)
|
|
{
|
|
porta.Close();
|
|
porta.BaudRate = 9600;
|
|
|
|
AtualizarPortaCOM(porta);
|
|
}
|
|
|
|
if (Iniciado)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
EnvioLiberado = false;
|
|
|
|
var Parametro = Parametros.First(x => x.Chave == "Versao");
|
|
|
|
List<string> Mod_IDs = new List<string>();
|
|
|
|
foreach (var Modulo in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Where(x => !x.MovMotor.BLD_Inicializado))
|
|
{
|
|
byte Addr = 0;
|
|
try
|
|
{
|
|
Addr = Convert.ToByte(Modulo.MovMotor.Endereco, 16);
|
|
}
|
|
catch
|
|
{
|
|
RegisrarErrosComunicacao(Addr, $"Erro ao definir endereço");
|
|
}
|
|
|
|
if (DadosLeitura.Any(x => x.Endereco == Addr && x.Iniciado))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var comando = ModbusService.ComandoGetParametro(Addr, Parametro);
|
|
|
|
EnviarComando(_PortaBLD, comando);
|
|
var resposta = await SerialService.LerDadosDaPortaSerialAsync(_PortaBLD, 7, 1000);
|
|
DecifrarResposta(resposta, Parametro, Addr);
|
|
|
|
if (DadosLeitura.Any(x => x.Endereco == Addr && x.Iniciado))
|
|
{
|
|
Mod_IDs.Add(Modulo.Modulo_ID);
|
|
}
|
|
}
|
|
|
|
if (Iniciado)
|
|
{
|
|
DefinirDispositivo(Mod_IDs);
|
|
}
|
|
else
|
|
{
|
|
_PortaBLD.Close();
|
|
_PortaBLD = null;
|
|
}
|
|
|
|
EnvioLiberado = true;
|
|
|
|
return Iniciado;
|
|
}
|
|
|
|
public static void AtualizarPortaCOM(SerialPort Porta)
|
|
{
|
|
_PortaBLD = new SerialPort();
|
|
_PortaBLD.PortName = Porta.PortName;
|
|
_PortaBLD.BaudRate = Porta.BaudRate;
|
|
|
|
_PortaBLD.Open();
|
|
}
|
|
|
|
private static void ReconectarPortaCOM()
|
|
{
|
|
RegisrarErrosComunicacao(0, $"Reiniciando conexão com a porta {_PortaBLD.PortName}...");
|
|
try
|
|
{
|
|
_PortaBLD.Close();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
RegisrarErrosComunicacao(0, $"Erro ao reiniciar conexão. Erro={ex.Message}");
|
|
}
|
|
|
|
if (Iniciado)
|
|
{
|
|
RegisrarErrosComunicacao(0, $"Reconexão com a porta {_PortaBLD.PortName} reestabelecida");
|
|
}
|
|
else
|
|
{
|
|
RegisrarErrosComunicacao(0, $"Erro ao reestabelecer conexão com a porta {_PortaBLD.PortName}");
|
|
}
|
|
}
|
|
|
|
private static void DefinirDispositivo(List<string> Mod_IDs)
|
|
{
|
|
if (Iniciado)
|
|
{
|
|
foreach (var Mod_ID in Mod_IDs)
|
|
{
|
|
var Modulo = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => x.Modulo_ID == Mod_ID);
|
|
byte Addr = Convert.ToByte(Modulo.MovMotor.Endereco.Replace("0x", ""), 16);
|
|
|
|
if (DadosLeitura.Any(x => x.Endereco == Addr && !x.Configurado))
|
|
{
|
|
ConfigurarDriver(Addr);
|
|
}
|
|
|
|
if (!SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Bld && x.Mod_ID == Mod_ID))
|
|
{
|
|
var leitura = DadosLeitura.FirstOrDefault(x => x.Endereco == Addr);
|
|
SerialService.DispositivosMapeados.Add(new SerialService.DispositivoDetalhesModel()
|
|
{
|
|
PortaCOM = _PortaBLD.PortName,
|
|
Dispositivo = T_Code.Bld,
|
|
Erro = leitura.CodigoAlarme > 0,
|
|
Versao = leitura.Versao.ToString(),
|
|
Mod_ID = Mod_ID,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void IniciarRotinas()
|
|
{
|
|
//Task.Run(() => LoopEnvioComandos()); // Inicia o loop de comandos em segundo plano
|
|
Task.Run(() => ReceberDados()); // Inicia a recepção de dados em segundo plano
|
|
if (!tmrLoopComandos.Enabled)
|
|
{
|
|
tmrLoopComandos.Tick += TmrLoopComandos_Tick;
|
|
tmrLoopComandos.Start();
|
|
}
|
|
}
|
|
|
|
private static void TmrLoopComandos_Tick(object sender, EventArgs e)
|
|
{
|
|
if (Iniciado && EnvioLiberado)
|
|
{
|
|
Task.Run(() => LoopEnvioComandos());
|
|
}
|
|
}
|
|
|
|
private static void EnviarComando(SerialPort _Porta, byte[] Comando)
|
|
{
|
|
lock (FilaLock)
|
|
{
|
|
try
|
|
{
|
|
if (_Porta != null)
|
|
{
|
|
if (!_Porta.IsOpen)
|
|
{
|
|
_Porta.Open();
|
|
}
|
|
if (_Porta.IsOpen)
|
|
{
|
|
_Porta.Write(Comando, 0, Comando.Length);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static async Task ReceberDados()
|
|
{
|
|
while (true)
|
|
{
|
|
await Task.Delay(TaxaAmostragem);
|
|
|
|
if (!Iniciado)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
foreach (var Leitura in DadosLeitura.Where(x => x.Iniciado).OrderBy(x => x.Endereco))
|
|
{
|
|
foreach (var Parametro in Parametros.Where(x => x.LeituraLoop))
|
|
{
|
|
var Comando = new BLDComandoModel()
|
|
{
|
|
Endereco = Leitura.Endereco,
|
|
AguardaResposta = true,
|
|
Parametro = Parametro,
|
|
Get = true,
|
|
TimeoutResposta = 300
|
|
};
|
|
AdicionarComandoNaFila(Comando);
|
|
}
|
|
|
|
var Modulo = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => Convert.ToByte(x.MovMotor.Endereco.Replace("0x", ""), 16) == Leitura.Endereco);
|
|
if (Modulo != null)
|
|
{
|
|
Modulo.MovMotor.RPM_Motor = Leitura.RPM;
|
|
Modulo.MovMotor.TemperaturaDriver = Math.Round(Leitura.Temperatura, 2);
|
|
Modulo.MovMotor.Corrente_Max = Math.Round(Leitura.CorrenteMax, 2);
|
|
Modulo.MovMotor.Tensao = Math.Round(Leitura.Tensao, 2);
|
|
Modulo.MovMotor.Ligado = Leitura.Ativado;
|
|
Modulo.MovMotor.Freio = Leitura.Freado;
|
|
Modulo.MovMotor.Sentido = Leitura.Direcao;
|
|
Modulo.MovMotor.CodigoAlarme = Leitura.CodigoAlarme;
|
|
|
|
Variaveis.OperacaoEmAndamento.DispMvd.Dados.RegistrarLogMov(Modulo);
|
|
|
|
if (Modulo.MovMotor.CodigoAlarme > 0 && Modulo.MovMotor.CodigoAlarme <= 99)
|
|
{
|
|
RegisrarErrosComunicacao(Leitura.Endereco, $"Módulo com código de alarme {Modulo.MovMotor.CodigoAlarme}, reiniciando o módulo...");
|
|
AdicionarComandoNaFila(new BLDComandoModel()
|
|
{
|
|
Endereco = Leitura.Endereco,
|
|
AguardaResposta = true,
|
|
TimeoutResposta = 200,
|
|
Get = false,
|
|
Parametro = Parametros.First(x => x.Chave == "AlarmeCode"),
|
|
Valor = 0
|
|
});
|
|
}
|
|
|
|
var Controle = Variaveis.OperacaoEmAndamento.Controle.TiposControle.FirstOrDefault(x => x.Tipo == T_Code.Mov);
|
|
Modulo.MovMotor.ProtocoloComando(Controle.UltimaDirecao);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static bool DecifrarResposta(byte[] resposta, ModbusParametrosModel Parametro, byte Addr)
|
|
{
|
|
try
|
|
{
|
|
var Leitura = DadosLeitura.FirstOrDefault(x => x.Endereco == Addr);
|
|
if (Leitura == null)
|
|
{
|
|
Leitura = new BLD300RModel()
|
|
{
|
|
Endereco = Addr,
|
|
UltimoComandoRecebido = DateTime.MinValue,
|
|
parametros = new List<BLDParametrosRequisitar>()
|
|
{
|
|
new BLDParametrosRequisitar()
|
|
{
|
|
Registro = Parametro.Registro,
|
|
Escala = Parametro.Escala,
|
|
Valor = null
|
|
}
|
|
}
|
|
};
|
|
DadosLeitura.Add(Leitura);
|
|
}
|
|
var ParametroLeitura = Leitura.parametros.FirstOrDefault(x => x.Registro == Parametro.Registro);
|
|
if (ParametroLeitura == null)
|
|
{
|
|
ParametroLeitura = new BLDParametrosRequisitar()
|
|
{
|
|
Registro = Parametro.Registro,
|
|
Escala = Parametro.Escala,
|
|
Valor = null
|
|
};
|
|
Leitura.parametros.Add(ParametroLeitura);
|
|
}
|
|
|
|
if (resposta.Length > 3)
|
|
{
|
|
if (Parametros.Any(x => x.FuncaoGet == resposta[1]))
|
|
{
|
|
int num_registros = resposta[2];
|
|
byte[] bytes_resposta = resposta.Skip(3).Take(num_registros).ToArray(); // Ajustando para pegar 2 bytes por registro
|
|
|
|
Parametro.Valor = bytes_resposta;
|
|
|
|
Parametro.UltimaRequisicao = DateTime.MaxValue;
|
|
}
|
|
else if (Parametros.Any(x => x.FuncaoSet == resposta[1]))
|
|
{
|
|
Parametro.Valor = resposta.Skip(4).Take(2).ToArray();
|
|
}
|
|
else
|
|
{
|
|
RegisrarErrosComunicacao(Addr, $"Resposta inválida ou código de função incorreto. {BitConverter.ToString(resposta)}");
|
|
}
|
|
|
|
ParametroLeitura.Valor = Parametro.Valor;
|
|
Leitura.UltimoComandoRecebido = DateTime.Now;
|
|
return true;
|
|
}
|
|
|
|
RegisrarErrosComunicacao(Addr, $"Resposta inválida. {BitConverter.ToString(resposta)}");
|
|
return false;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
RegisrarErrosComunicacao(Addr, $"Erro ao decifrar resposta. {BitConverter.ToString(resposta)}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private static void ConfigurarDriver(byte Addr)
|
|
{
|
|
var Modulo = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.FirstOrDefault(x => Convert.ToByte(x.MovMotor.Endereco.Replace("0x", ""), 16) == Addr);
|
|
AdicionarComandoNaFila(new BLDComandoModel()
|
|
{
|
|
Endereco = Addr,
|
|
AguardaResposta = true,
|
|
TimeoutResposta = 200,
|
|
Get = false,
|
|
Parametro = Parametros.First(x => x.Chave == "ControleRS485"),
|
|
Valor = 1
|
|
});
|
|
AdicionarComandoNaFila(new BLDComandoModel()
|
|
{
|
|
Endereco = Addr,
|
|
AguardaResposta = true,
|
|
TimeoutResposta = 200,
|
|
Get = false,
|
|
Parametro = Parametros.First(x => x.Chave == "AlarmeCode"),
|
|
Valor = 0
|
|
});
|
|
AdicionarComandoNaFila(new BLDComandoModel()
|
|
{
|
|
Endereco = Addr,
|
|
AguardaResposta = true,
|
|
TimeoutResposta = 200,
|
|
Get = false,
|
|
Parametro = Parametros.First(x => x.Chave == "NumPolos"),
|
|
Valor = Modulo.MovMotor.NumeroPolos
|
|
});
|
|
AdicionarComandoNaFila(new BLDComandoModel()
|
|
{
|
|
Endereco = Addr,
|
|
AguardaResposta = true,
|
|
TimeoutResposta = 200,
|
|
Get = false,
|
|
Parametro = Parametros.First(x => x.Chave == "RPM_Max"),
|
|
Valor = Modulo.MovMotor.RPM_Max
|
|
});
|
|
AdicionarComandoNaFila(new BLDComandoModel()
|
|
{
|
|
Endereco = Addr,
|
|
AguardaResposta = true,
|
|
TimeoutResposta = 200,
|
|
Get = false,
|
|
Parametro = Parametros.First(x => x.Chave == "Rampa"),
|
|
Valor = Modulo.MovMotor.Rampa
|
|
});
|
|
AdicionarComandoNaFila(new BLDComandoModel()
|
|
{
|
|
Endereco = Addr,
|
|
AguardaResposta = true,
|
|
TimeoutResposta = 200,
|
|
Get = false,
|
|
Parametro = Parametros.First(x => x.Chave == "Enabled"),
|
|
Valor = 0
|
|
});
|
|
DadosLeitura.Where(x => x.Endereco == Addr).First().Configurado = true;
|
|
}
|
|
|
|
public static async Task EnviarComandoControle(BLDComandoModel Comando)
|
|
{
|
|
try
|
|
{
|
|
byte[] comando = null;
|
|
|
|
if (Comando.Get)
|
|
{
|
|
comando = ModbusService.ComandoGetParametro(Comando.Endereco, Comando.Parametro);
|
|
}
|
|
else
|
|
{
|
|
comando = ModbusService.ComandoSetParametro(Comando.Endereco, Comando.Parametro, Comando.Valor);
|
|
}
|
|
|
|
if (comando != null && comando.Length > 0)
|
|
{
|
|
//Console.WriteLine("Enviando comando para o endereço: " + Comando.Endereco);
|
|
EnviarComando(_PortaBLD, comando);
|
|
|
|
Comando.Enviado = true;
|
|
|
|
if (Comando.AguardaResposta)
|
|
{
|
|
byte[] resposta = await SerialService.LerDadosDaPortaSerialAsync(_PortaBLD, 7, Comando.TimeoutResposta);
|
|
bool Respondido = DecifrarResposta(resposta, Comando.Parametro, Comando.Endereco);
|
|
if (!Respondido)
|
|
{
|
|
RegisrarErrosComunicacao(Comando.Endereco, $"Timeout ao receber resposta. GET={Comando.Get}, Parametro={Comando.Parametro.Chave}, Valor={Comando.Valor}");
|
|
Comando.Enviado = false;
|
|
Comando.Momento = DateTime.Now.AddMilliseconds(500);
|
|
//ReconectarPortaCOM();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
RegisrarErrosComunicacao(Comando.Endereco, $"Erro ao enviar comando. GET={Comando.Get}, Parametro={Comando.Parametro.Chave}, Valor={Comando.Valor}, Erro={ex.Message}");
|
|
Comando.Enviado = false;
|
|
Comando.Momento = DateTime.Now.AddMilliseconds(500);
|
|
ReconectarPortaCOM();
|
|
}
|
|
}
|
|
|
|
public static void AdicionarComandoNaFila(BLDComandoModel Comando)
|
|
{
|
|
lock (FilaLock)
|
|
{
|
|
if (!FilaComandos.Any(x => x.Endereco == Comando.Endereco && x.Parametro.Registro == Comando.Parametro.Registro && x.Get == Comando.Get && !x.Enviado))
|
|
{
|
|
FilaComandos.Add(Comando);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static async Task LoopEnvioComandos()
|
|
{
|
|
EnvioLiberado = false;
|
|
|
|
try
|
|
{
|
|
await ProcessarFilaPrioridade();
|
|
|
|
List<BLDComandoModel> comandosParaEnviar;
|
|
|
|
lock (FilaLock)
|
|
{
|
|
comandosParaEnviar = FilaComandos.Where(x => !x.Enviado && x.Get).OrderBy(x => x.Momento).ToList();
|
|
}
|
|
|
|
foreach (var Comando in comandosParaEnviar)
|
|
{
|
|
await EnviarComandoControle(Comando);
|
|
await ProcessarFilaPrioridade();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
RegisrarErrosComunicacao(0, $"Erro ao processar fila de comandos. Erro={ex.Message}");
|
|
}
|
|
finally
|
|
{
|
|
EnvioLiberado = true;
|
|
}
|
|
}
|
|
|
|
private static async Task ProcessarFilaPrioridade()
|
|
{
|
|
var FilaPrioridade = new List<BLDComandoModel>();
|
|
lock (FilaLock)
|
|
{
|
|
FilaPrioridade = FilaComandos.Where(x => !x.Enviado && !x.Get).OrderBy(x => x.Momento).ToList();
|
|
}
|
|
|
|
while (FilaPrioridade.Count > 0)
|
|
{
|
|
foreach (var Comando in FilaPrioridade)
|
|
{
|
|
await EnviarComandoControle(Comando);
|
|
}
|
|
|
|
lock (FilaLock)
|
|
{
|
|
FilaPrioridade = FilaComandos.Where(x => !x.Enviado && !x.Get).OrderBy(x => x.Momento).ToList();
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void RegisrarErrosComunicacao(byte addr, string mensagem)
|
|
{
|
|
var Caminho = Variaveis.CaminhoLogsDispositivos;
|
|
if (!Directory.Exists(Caminho))
|
|
{
|
|
Directory.CreateDirectory(Caminho);
|
|
}
|
|
|
|
var Arquivo = T_Code.Bld.ToString() + "_err.txt";
|
|
Caminho += "/" + Arquivo;
|
|
|
|
mensagem = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss:fff") + " - Porta " + _PortaBLD.PortName + " - " + addr + ": " + mensagem + Environment.NewLine;
|
|
|
|
if (!File.Exists(Caminho))
|
|
{
|
|
File.WriteAllText(Caminho, mensagem);
|
|
}
|
|
else
|
|
{
|
|
File.AppendAllText(Caminho, mensagem);
|
|
}
|
|
}
|
|
|
|
public class BLDParametrosRequisitar
|
|
{
|
|
public byte Registro { get; set; }
|
|
public byte[] Valor { get; set; }
|
|
public double Escala { get; set; }
|
|
}
|
|
|
|
public class BLDComandoModel
|
|
{
|
|
public DateTime Momento { get; set; } = DateTime.Now;
|
|
public bool Enviado { get; set; } = false;
|
|
public byte Endereco { get; set; }
|
|
public ModbusParametrosModel Parametro { get; set; }
|
|
public float Valor { get; set; }
|
|
public bool Get { get; set; }
|
|
public bool AguardaResposta { get; set; } = false;
|
|
public int TimeoutResposta { get; set; } = 1000;
|
|
}
|
|
|
|
}
|
|
}
|