agrobot_base/AgroBase/AgroBase/Models/Modules/MovimentacaoModel.cs

549 lines
22 KiB
C#

using AgroBase.Forms;
using AgroBase.Models.Modules;
using AgroBase.Services;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
namespace AgroBase.Models
{
public class MovimentacaoModel : DispositivoBaseModel
{
public string Modulo_ID { get; set; } = T_Code.Mov.ToString();
private bool _MensagemConexaoRecebida { get; set; } = false;
public bool MensagemConexaoRecebida(bool Reset = false)
{
if (Reset)
{
_MensagemConexaoRecebida = false;
}
return _MensagemConexaoRecebida;
}
public bool Conectado { get; set; } = false;
public static int _TaxaAmostragem { get; set; } = 500;
public static int NumPolos { get; set; } = 0;
public static int Rampa { get; set; } = 0;
public static int RPM_Max { get; set; } = 0;
public static int LogsManter { get; set; } = 60;
public static PinoutDataModel Pinout { get; set; }
public static List<FuncoesPinout> Funcoes { get; set; } = new List<FuncoesPinout>();
public List<MovSensoriamentoMotor> Motores { get; set; }
public static Direcao UltimaDirecao { get; set; } = Direcao.Parado;
public int TempoEmAtividade { get; set; } = 0;
public double DistanciaPercorridaTotal { get; set; } = 0;
public double DistanciaPercorridaParcial { get; set; } = 0;
public double DistanciaPercorridaOperacao { get; set; } = 0;
public AsyncTaskTimerModel tmrRegistrador { get; set; }
public static MovimentacaoModel CarregarParametrosIniciais()
{
return new MovimentacaoModel()
{
Motores = new List<MovSensoriamentoMotor>()
{
new MovSensoriamentoMotor() {
Canal = 1,
Endereco = "0x01",
ID = "ET",
Descricao = "Esquerdo Trás",
ConfigSentidos = new ConfiguracaoSentidoMotor() {
Direita = Sentido.Antihorario,
Esquerda = Sentido.Horario,
Frente = Sentido.Horario,
Tras = Sentido.Antihorario
},
Funcoes = new List<FuncoesPinout>() {
FuncoesPinout.TMP,
}
},
new MovSensoriamentoMotor() {
Canal = 2,
Endereco = "0x02",
ID = "EF",
Descricao = "Esquerdo Frente",
ConfigSentidos = new ConfiguracaoSentidoMotor() {
Direita = Sentido.Antihorario,
Esquerda = Sentido.Horario,
Frente = Sentido.Horario,
Tras = Sentido.Antihorario
},
Funcoes = new List<FuncoesPinout>() {
FuncoesPinout.TMP,
}
},
new MovSensoriamentoMotor() {
Canal = 3,
Endereco = "0x03",
ID = "DT",
Descricao = "Direito Trás",
ConfigSentidos = new ConfiguracaoSentidoMotor() {
Direita = Sentido.Horario,
Esquerda = Sentido.Antihorario,
Frente = Sentido.Horario,
Tras = Sentido.Antihorario
},
Funcoes = new List<FuncoesPinout>() {
FuncoesPinout.TMP,
}
},
new MovSensoriamentoMotor() {
Canal = 4,
Endereco = "0x04",
ID = "DF",
Descricao = "Direito Frente",
ConfigSentidos = new ConfiguracaoSentidoMotor() {
Direita = Sentido.Antihorario,
Esquerda = Sentido.Horario,
Frente = Sentido.Antihorario,
Tras = Sentido.Horario
},
Funcoes = new List<FuncoesPinout>() {
FuncoesPinout.TMP,
}
}
},
};
}
public Dictionary<string, List<string>> ProtocoloConfiguracao(bool Conectar)
{
// Inicializar o dicionário
var configDictionary = new Dictionary<string, List<string>>();
// Adicionar configurações dos Motores que devem ser comandados
var motoresConfig = Motores
.Where(x => x.Comandar)
.Select(x => x.ProtocoloConfiguracaoMotor(Conectar))
.ToList();
configDictionary.Add(Modulo_ID, motoresConfig);
// Adicionar configuração do ProtocoloMOD
string protocoloMOD =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
"MD" + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
_TaxaAmostragem.ToString();
var protocoloMODConfig = new List<string> { protocoloMOD };
configDictionary.Add(Modulo_ID, protocoloMODConfig);
return configDictionary;
}
public void RecebeProtocoloSerial(string Protocolo)
{
if (!string.IsNullOrEmpty(Protocolo) && Protocolo[0].ToString() == SerialService.BeginSensor)
{
try
{
string[] Dados = Protocolo.Replace(SerialService.BeginSensor, "").Split(SerialService.EndLine[0])[0].Split(';');
S_Code TipoSensor = (S_Code)(int.Parse(Dados[0]));
MovSensoriamentoMotor Motor = Motores.FirstOrDefault(x => x.ID == Dados[1]);
if (Motor == null)
{
if (Dados[1] == "MD")
{
Conectado = Dados[2] == "1";
_MensagemConexaoRecebida = true;
}
return;
}
bool AtualizaGrafico = false;
try
{
switch (TipoSensor)
{
case S_Code.sBLD:
{
double rpm = 0;
double.TryParse(Dados[2].Replace(".", ","), out rpm);
Motor.RPM = rpm;
double temperatura = 0;
double.TryParse(Dados[3].Replace(".", ","), out temperatura);
temperatura = FuncoesMatematicas.CalcularTemperatura(temperatura, -1.038);
Motor.Temperatura = temperatura;
double tensao = 0;
double.TryParse(Dados[4].Replace(".", ","), out tensao);
Motor.Tensao = tensao;
double corrente_max = 0;
double.TryParse(Dados[5].Replace(".", ","), out corrente_max);
corrente_max = FuncoesMatematicas.Map(corrente_max, 15780, 16799, 0, 20.6);
Motor.Corrente_Max = corrente_max;
bool ligado = Dados[6] == "1";
Motor.Ligado = ligado;
int sentido = 0;
int.TryParse(Dados[7], out sentido);
Motor.Sentido = (Sentido)sentido;
bool freio = Dados[8] == "1";
Motor.Freio = freio;
int codAlarme = 0;
int.TryParse(Dados[9], out codAlarme);
Motor.CodigoAlarme = codAlarme;
double tempDriver = 0;
double.TryParse(Dados[10].Replace(".", ","), out tempDriver);
tempDriver = FuncoesMatematicas.CalcularTemperatura(tempDriver, 0);
Motor.TemperaturaDriver = tempDriver;
AtualizaGrafico = true;
break;
}
case S_Code.sTST:
{
bool testando = Dados[2] == "1";
if (!Motor.Testando && testando)
{
Motor.LogTestes = new List<SensoriamentoMotorTestes>();
}
Motor.Testando = testando;
if (Motor.Testando && Dados.Length >= 5)
{
string componente = Dados[1];
string resultado = Dados[2];
string comando = Dados[3];
string leitura = Dados[4];
Motor.LogTestes.Add(new SensoriamentoMotorTestes()
{
Componente = componente,
Sucesso = resultado == "SUCESSO",
Resultado = resultado,
Comando = comando,
Leitura = leitura,
Momento = DateTime.Now
});
}
break;
}
case S_Code.sCFG:
{
Motor.Inicializado = Dados[2] == "1";
break;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
if (AtualizaGrafico)
{
Motor.LogGrafico.Add(new MovSensorimanetoGrafico()
{
Momento = DateTime.Now,
ComponenteID = Motor.ID,
RPM_SP = Motor.RPM_SP,
RPM = Motor.RPM,
Temperatura = Motor.Temperatura,
Sentido = Motor.Sentido,
Velocidade = Motor.VelocidadeInstantanea,
TemperaturaDriver = Motor.TemperaturaDriver,
Tensao = Motor.Tensao,
});
if (Motor.LogGrafico.Count() > LogsManter)
{
Motor.LogGrafico.RemoveAt(0);
}
//frmInstancial.frmAcompanhamento.tmrAtualizacao_Tick();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
public void DefineStatusConexao(string Mod_ID, bool conecatdo)
{
if (Mod_ID == Modulo_ID)
{
Conectado = conecatdo;
//Variaveis.OperacaoEmAndamento.DispMov.AcaoConexao();
}
}
public string GetTaxaAmostragem()
{
return _TaxaAmostragem.ToString("00000");
}
public void SetTaxaAmostragem(int TaxaAmostragem)
{
_TaxaAmostragem = TaxaAmostragem;
}
public bool GetStatusConexao()
{
return Conectado;
}
public void IniciarRegistrador()
{
tmrRegistrador = new AsyncTaskTimerModel(tmrRegistrador_Tick, 1000);
tmrRegistrador.Start();
}
private async Task tmrRegistrador_Tick()
{
if (UltimaDirecao != Direcao.Parado)
{
TempoEmAtividade++;
double VelocidadeMedia = Motores.Average(x => x.VelocidadeInstantanea * 1000 / 3600);
DistanciaPercorridaTotal += 1 * VelocidadeMedia;
DistanciaPercorridaParcial += (UltimaDirecao == Direcao.Frente ? 1 : UltimaDirecao == Direcao.Tras ? -1 : 0) * VelocidadeMedia;
DistanciaPercorridaOperacao += 1 * VelocidadeMedia;
}
}
public static double CalculaVelocidadeRPM(double RPM)
{
double VelocidadeInstantanea = Math.Round((Math.PI * VariaveisEquipamento.DiametroRoda * 60 * RPM) / 1000, 2); // Km/h
return VelocidadeInstantanea;
}
public static double CalculaRPMVelocidade(double Velocidade)
{
double RPM = Math.Round((Velocidade * 1000) / (Math.PI * VariaveisEquipamento.DiametroRoda * 60), 2);
return RPM;
}
public static double ConverteKmhParaMs(double Velocidade)
{
return Velocidade / 3.6;
}
public async Task LoopRegistrador()
{
}
}
public class MovSensoriamentoMotor
{
public int Canal { get; set; }
public string ID { get; set; }
public string Descricao { get; set; }
// SETs
public string Endereco { get; set; }
public bool Ligado { get; set; } = false;
public bool Freio { get; set; } = false;
public int CodigoAlarme { get; set; } = 0;
public int RPM_SP { get; set; } = 0;
public Sentido Sentido_SP { get; set; } = Sentido.Parado;
public int NumeroPolos { get; set; } = 2;
public int Rampa { get; set;} = 0;
public int RPM_Max { get; set; } = 800;
// GETs
public double RPM { get; set; } = 0;
public Sentido Sentido { get; set; } = Sentido.Parado;
public double Temperatura { get; set; } = 0;
public double TemperaturaDriver { get; set; } = 0;
public double Tensao { get; set; } = 0;
public double Corrente_Max { get; set; } = 0;
public bool Comandar { get; set; } = false;
public bool Alarme { get; set; } = false;
public bool Inicializado { get; set; } = false;
public bool Testando { get; set; } = false;
public double VelocidadeInstantanea { get; set; } = 0;
public double Corrente { get; set; } = 0;
public ConfiguracaoSentidoMotor ConfigSentidos { get; set; }
public List<AlarmeModel> Alarmes { get; set; } = new List<AlarmeModel>();
public List<SensoriamentoMotorTestes> LogTestes { get; set; } = new List<SensoriamentoMotorTestes>();
public List<MovSensorimanetoGrafico> LogGrafico { get; set; } = new List<MovSensorimanetoGrafico>();
public List<FuncoesPinout> Funcoes { get; set; }
public string ProtocoloConfiguracaoMotor(bool Conectar)
{
var _pinout = new PinoutDataModel()
{
ExpansorGPIO = MovimentacaoModel.Pinout.ExpansorGPIO,
EnderecoExpansor = MovimentacaoModel.Pinout.EnderecoExpansor,
Pinos = MovimentacaoModel.Pinout.Pinos.ToList(),
};
_pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList();
string Protocolo =
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
(Conectar ? "1" : "0") + SerialService.SplitParams +
Canal.ToString() + SerialService.SplitParams +
Endereco + SerialService.SplitParams +
NumeroPolos + SerialService.SplitParams +
Rampa + SerialService.SplitParams +
RPM_Max + SerialService.SplitParams +
PinoutModel.PinoProtocolo(_pinout, Funcoes); // 29 ~ 51
return Protocolo;
}
public string ProtocoloComando(Direcao DirecaoAtual, bool CmdAlarme = false)
{
if (Comandar && (!Alarme || CmdAlarme))
{
if (!CmdAlarme)
{
MovimentacaoModel.UltimaDirecao = DirecaoAtual;
}
RPM_SP =
DirecaoAtual == Direcao.Parado ? 0 :
CmdAlarme ? 0 :
Variaveis.OperacaoEmAndamento.Controle.RPM_SP;
switch (DirecaoAtual)
{
case Direcao.Frente:
Sentido_SP = ConfigSentidos.Frente;
break;
case Direcao.Tras:
Sentido_SP = ConfigSentidos.Tras;
break;
case Direcao.Esquerda:
Sentido_SP = ConfigSentidos.Esquerda;
break;
case Direcao.Direita:
Sentido_SP = ConfigSentidos.Direita;
break;
case Direcao.Parado:
default:
Sentido_SP = ConfigSentidos.Parado;
break;
}
string ProtocoloMotor = "";
ProtocoloMotor =
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
ID + SerialService.SplitParams +
((int)Sentido_SP).ToString() + SerialService.SplitParams +
RPM_SP.ToString() + SerialService.SplitParams +
(Freio ? "1" : "0");
return ProtocoloMotor;
}
return "";
}
public string ProtocoloTeste()
{
if (Comandar)
{
string ProtocoloMotor =
((int)F_Code.Tst).ToString() + SerialService.SplitMessage +
ID;
return ProtocoloMotor;
}
return "";
}
public void AtualizarSensoresMotor(SensorModel Sensor)
{
bool Computar = true;
switch (Sensor.Componente)
{
case S_Code.sTMP:
Temperatura = Sensor.Leituras[0];
break;
case S_Code.sCOR:
Corrente = Sensor.Leituras[0];
Tensao = Sensor.Leituras[1];
break;
default:
Computar = false;
break;
}
if (!Computar)
{
return;
}
AlarmeModel _Alarme = new AlarmeModel()
{
Tipo = Sensor.Componente,
Valor = Sensor.Leituras[0],
Maximo = Sensor.Leituras[0] > Sensor.LimiteMaximo,
Minimo = Sensor.Leituras[0] < Sensor.LimiteMinimo,
ParaMaximo = false,
ParaMinimo = false
};
bool Adicionado = false;
var Alm = Alarmes.FirstOrDefault(x => x.Tipo == _Alarme.Tipo);
if (Alm == null)
{
Alm = _Alarme;
Alarmes.Add(Alm);
Adicionado = true;
}
bool AlarmeAnterior = (Alm.Maximo && Alm.ParaMaximo) || (Alm.Minimo && Alm.ParaMinimo);
bool AlarmeAtual = (_Alarme.Maximo && _Alarme.ParaMaximo) || (_Alarme.Minimo && _Alarme.ParaMinimo);
if (Inicializado && (!AlarmeAnterior || Adicionado) && AlarmeAtual) // Motor iniciado, Não estava em alarme anteriormente ou foi adicionado agora, alarme atual
{
//Variaveis.OperacaoEmAndamento.DispMov.AdicionarMensagemFila(Variaveis.OperacaoEmAndamento.DispMov.Dados.Modulo_ID, ProtocoloComando(Direcao.Frente, true), true, false);
}
Alm.Valor = _Alarme.Valor;
Alm.Maximo = _Alarme.Maximo;
Alm.Minimo = _Alarme.Minimo;
Alarme = Alarmes.Any(x => (x.Maximo && x.ParaMaximo) || (x.Minimo && x.ParaMinimo));
}
}
public class SensoriamentoMotorTestes
{
public DateTime Momento { get; set; }
public string Componente { get; set; }
public bool Sucesso { get; set; }
public string Resultado { get; set; }
public string Comando { get; set; }
public string Leitura { get; set; }
}
public class MovSensorimanetoGrafico
{
public DateTime Momento { get; set; }
public string ComponenteID { get; set; }
public int RPM_SP { get; set; }
public double RPM { get; set; }
public double Temperatura { get; set; }
public double TemperaturaDriver { get; set; }
public Sentido Sentido { get; set; }
public double Velocidade { get; set; }
public double Tensao { get; set; }
}
}