640 lines
24 KiB
C#
640 lines
24 KiB
C#
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 static AgroBase.Models.Enuns;
|
|
|
|
namespace AgroBase.Models.Modules
|
|
{
|
|
public class AtuadorModel : DispositivoBaseModel
|
|
{
|
|
private bool _MensagemConexaoRecebida { get; set; } = false;
|
|
public bool MensagemConexaoRecebida(bool Reset = false)
|
|
{
|
|
if (Reset)
|
|
{
|
|
_MensagemConexaoRecebida = false;
|
|
}
|
|
return _MensagemConexaoRecebida;
|
|
}
|
|
|
|
public static int _TaxaAmostragem { get; set; } = 500;
|
|
public bool Conectado { get; set; } = false;
|
|
public static PinoutDataModel Pinout { get; set; }
|
|
public static List<FuncoesPinout> Funcoes { get; set; } = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.SDA,
|
|
FuncoesPinout.SCL,
|
|
};
|
|
public int QuantidadeBicos { get; set; } = 4;
|
|
public double DensidadeHerbicida { get; set; } = 1.1;
|
|
public double CapacidadeReservatorio { get; set; } = 30;
|
|
public bool AtuacaoNivelAlto { get; set; } = true;
|
|
public List<AtuadorBicoModel> BicosPulverizadores { get; set; } = new List<AtuadorBicoModel>();
|
|
public AtuadorBombaModel BombaPressurizadora { get; set; } = new AtuadorBombaModel();
|
|
public List<SensorModel> Sensores { get; set; } = new List<SensorModel>();
|
|
public double PercentualInicioPulverizacao { get; set; } = 0.3;
|
|
public string ScriptDeteccaoErvas { get; set; } = PythonService.ScriptWeedDetector;
|
|
|
|
#region MASSA
|
|
public double _MassaRef { get; set; } = 0.8;
|
|
public double _MassaLeituraRef { get; set; } = 40876.37;
|
|
public double _MassaLeituraExtra { get; set; } = 1895800; // 2015000.0;
|
|
public double _MassaLeitura { get; set; }
|
|
public double MassaReservatorio
|
|
{
|
|
get
|
|
{
|
|
double leituraMassa = _MassaLeitura * -1;
|
|
leituraMassa += _MassaLeituraExtra;
|
|
|
|
double FatorLeitura = _MassaRef / _MassaLeituraRef;
|
|
double Massa = FatorLeitura * leituraMassa;
|
|
|
|
return Massa;
|
|
}
|
|
}
|
|
public double VolumeReservatorio
|
|
{
|
|
get
|
|
{
|
|
return MassaReservatorio / DensidadeHerbicida;
|
|
}
|
|
}
|
|
public double PercentualReservatorio
|
|
{
|
|
get
|
|
{
|
|
return VolumeReservatorio / CapacidadeReservatorio * 100;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region VAZAO
|
|
public double VolumeVazaoAferido { get; set; } = 0;
|
|
public double _FluxoMlRef { get; set;} = 600;
|
|
public double _FluxoPulsoRef { get; set;} = 538;
|
|
public int _LeituraPulsos { get; set; }
|
|
public int _LeituraPeriodo { get; set; }
|
|
public double VazaoFluxoMLpS
|
|
{
|
|
get
|
|
{
|
|
if (_LeituraPeriodo == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
double FatorLeitura = (double)_FluxoMlRef / (double)_FluxoPulsoRef;
|
|
double Frequencia = ((double)_LeituraPulsos / (double)_LeituraPeriodo * 1000);
|
|
//double vazao = (_LeituraPulsos * FatorLeitura) / ((double)_LeituraPeriodo / 1000);
|
|
//double vazao = ((double)1 / FatorLeitura) * (60 * 1000 / _LeituraPeriodo);
|
|
//double vazao = ((double)_LeituraPulsos / (((double)_LeituraPeriodo / 1000) * 8.1)) + 3;
|
|
//double Fator = (double)_LeituraPulsos / (double)_LeituraPeriodo;
|
|
|
|
//double vazao = ((double)_LeituraPulsos / (double)_LeituraPeriodo * 1000) * ;
|
|
|
|
//double vazao = Frequencia * 1.22;
|
|
|
|
double Rh = 0.0047;
|
|
double Rt = 0.0037;
|
|
double vazao = (Frequencia * 2 * Math.PI * Rh * Math.PI * (Rt * Rt)) * 1000000;
|
|
|
|
Console.WriteLine("Pulsos: " + _LeituraPulsos + " - Periodo: " + _LeituraPeriodo + " ms - Vazão: " + vazao.ToString("0.00000"));
|
|
|
|
return vazao;
|
|
}
|
|
}
|
|
}
|
|
public double VolumeVazaoML { get; set; }
|
|
#endregion
|
|
|
|
#region PRESSAO
|
|
public double _PressaoVmin { get; set; } = 0.0;
|
|
public double _PressaoVmax { get; set; } = 4.5;
|
|
public double _PressaoMax { get; set; } = 174.045; // 1,2 MPa
|
|
public double _LeituraPressao { get; set; }
|
|
public double PressaoLinha { get; set; } = 0;
|
|
public double PressaoLinhaCalc
|
|
{
|
|
get
|
|
{
|
|
double tensao = FuncoesMatematicas.Map(_LeituraPressao, 0, 4095, 0, 3300) / 1000.0;
|
|
|
|
double pressao = FuncoesMatematicas.Map(tensao, _PressaoVmin, _PressaoVmax, 0, _PressaoMax);
|
|
|
|
return pressao;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
|
|
public static AtuadorModel CarregarParametrosIniciais()
|
|
{
|
|
AtuadorModel Atuador = new AtuadorModel()
|
|
{
|
|
QuantidadeBicos = 10,
|
|
Conectado = false,
|
|
BicosPulverizadores = new List<AtuadorBicoModel>(),
|
|
BombaPressurizadora = new AtuadorBombaModel()
|
|
{
|
|
ID = "BOMBA",
|
|
Comandar = false,
|
|
Ligado = false,
|
|
Inicializado = false,
|
|
Pressao = 0,
|
|
PressaoSP = 80,
|
|
Testando = false,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.ENA,
|
|
FuncoesPinout.CS,
|
|
FuncoesPinout.INA,
|
|
FuncoesPinout.INB,
|
|
FuncoesPinout.PWM,
|
|
}
|
|
},
|
|
Sensores = new List<SensorModel>()
|
|
{
|
|
new SensorModel()
|
|
{
|
|
ID = "FLXLN",
|
|
Descricao = "Fluxo na linha principal",
|
|
Prioridade = 23,
|
|
Componente = S_Code.sFLX,
|
|
Aferir = false,
|
|
Inicializado = false,
|
|
Testando = false,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.Fluxo,
|
|
},
|
|
DelayAmostragem = 100,
|
|
UnidadeMedida = "mL/s",
|
|
Parametros = new List<string[]>(),
|
|
},
|
|
new SensorModel()
|
|
{
|
|
ID = "MASRS",
|
|
Descricao = "Massa do reservatório de herbicida",
|
|
Prioridade = 3,
|
|
Componente = S_Code.sMAS,
|
|
Aferir = false,
|
|
Inicializado = false,
|
|
Testando = false,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.DT,
|
|
FuncoesPinout.SCK,
|
|
},
|
|
DelayAmostragem = 1000,
|
|
UnidadeMedida = "Kg",
|
|
Parametros = new List<string[]>(),
|
|
},
|
|
new SensorModel()
|
|
{
|
|
ID = "PRSLN",
|
|
Descricao = "Pressão na linha principal",
|
|
Prioridade = 3,
|
|
Componente = S_Code.sPRS,
|
|
Aferir = false,
|
|
Inicializado = false,
|
|
Testando = false,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.Pressao,
|
|
},
|
|
DelayAmostragem = 1000,
|
|
UnidadeMedida = "psi",
|
|
Parametros = new List<string[]>()
|
|
{
|
|
new string[] { "Vmin", "000.00" },
|
|
new string[] { "Vmax", "004.50" },
|
|
new string[] { "Pmax", "174.04" },
|
|
},
|
|
},
|
|
},
|
|
};
|
|
for (int i = 0; i < Atuador.QuantidadeBicos; i++)
|
|
{
|
|
Atuador.BicosPulverizadores.Add(new AtuadorBicoModel()
|
|
{
|
|
ID = "B" + (i + 1).ToString("00"),
|
|
Posicao = i + 1,
|
|
Comandar = false,
|
|
Atuado = false,
|
|
Funcoes = new List<FuncoesPinout>()
|
|
{
|
|
FuncoesPinout.Solenoide,
|
|
},
|
|
StatusBico = false,
|
|
MediaNivelFluxo = 0
|
|
});
|
|
}
|
|
return Atuador;
|
|
}
|
|
|
|
public List<string> ProtocoloConfiguracao(bool Conectar)
|
|
{
|
|
List<string> Config = BicosPulverizadores.Select(x => x.ProtocoloConfiguracaoBico(Conectar)).ToList();
|
|
Config.Add(BombaPressurizadora.ProtocoloConfiguracaoBomba(Conectar));
|
|
Config.AddRange(Sensores.Select(x => x.ProtocoloConfiguracaoSensor(Pinout, Conectar)).ToList());
|
|
string ProtocoloMOD =
|
|
((int)F_Code.Cfg).ToString() + SerialService.SplitMessage +
|
|
"MD" + SerialService.SplitParams +
|
|
(Conectar ? "1" : "0") + SerialService.SplitParams +
|
|
_TaxaAmostragem.ToString() + SerialService.SplitParams +
|
|
(AtuacaoNivelAlto ? "1" : "0");
|
|
Config.Add(ProtocoloMOD);
|
|
return Config;
|
|
}
|
|
|
|
public void RecebeProtocoloSerial(string Protocolo)
|
|
{
|
|
// #ET;00000;00000;00000;000
|
|
if (!string.IsNullOrEmpty(Protocolo) && Protocolo[0].ToString() == SerialService.BeginSensor)
|
|
{
|
|
string[] Dados = Protocolo.Replace(SerialService.BeginSensor, "").Split(SerialService.EndLine[0])[0].Split(';');
|
|
string _id = Dados[1].Trim();
|
|
S_Code TipoSensor = (S_Code)(int.Parse(Dados[0]));
|
|
AtuadorBicoModel Bico = BicosPulverizadores.FirstOrDefault(x => x.ID.Trim() == _id);
|
|
SensorModel Sensor = Sensores.FirstOrDefault(x => x.ID.Trim() == _id);
|
|
AtuadorBombaModel Bomba = _id == BombaPressurizadora.ID.Trim() ? BombaPressurizadora : null;
|
|
if (Bico == null && Sensor == null && Bomba == null)
|
|
{
|
|
if (_id == "MD")
|
|
{
|
|
Conectado = Dados[2] == "1";
|
|
_MensagemConexaoRecebida = true;
|
|
}
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
switch (TipoSensor)
|
|
{
|
|
case S_Code.sCFG:
|
|
{
|
|
bool Inicializado = Dados[2] == "1";
|
|
if (Bico != null)
|
|
{
|
|
Bico.Inicializado = Inicializado;
|
|
}
|
|
if (Sensor != null)
|
|
{
|
|
Sensor.Inicializado = Inicializado;
|
|
}
|
|
if (Bomba != null)
|
|
{
|
|
Bomba.Inicializado = Inicializado;
|
|
}
|
|
break;
|
|
}
|
|
case S_Code.sTST:
|
|
{
|
|
bool Testando = Dados[1] == "1";
|
|
if (Bico != null)
|
|
{
|
|
Bico.Testando = Testando;
|
|
}
|
|
if (Sensor != null)
|
|
{
|
|
Sensor.Testando = Testando;
|
|
}
|
|
break;
|
|
}
|
|
case S_Code.sBIC:
|
|
{
|
|
bool StatusBico = Dados[2] == "1";
|
|
Bico.StatusBico = StatusBico;
|
|
break;
|
|
}
|
|
case S_Code.sFLX:
|
|
{
|
|
int pulsos = 0;
|
|
int.TryParse(Dados[2].Replace(".", ","), out pulsos);
|
|
int tempo = 0;
|
|
int.TryParse(Dados[3].Replace(".", ","), out tempo);
|
|
|
|
_LeituraPulsos = pulsos;
|
|
_LeituraPeriodo = tempo;
|
|
|
|
if (VazaoFluxoMLpS > 0)
|
|
{
|
|
foreach (var bico in BicosPulverizadores.Where(x => x.Atuado))
|
|
{
|
|
bico.MediaNivelFluxo = VazaoFluxoMLpS / BicosPulverizadores.Count(y => y.Atuado);
|
|
};
|
|
|
|
double periodoAtual = Sensor.Leituras.Any() ? (double)_LeituraPeriodo - Sensor.Leituras[1] : (double)_LeituraPeriodo;
|
|
VolumeVazaoML += (VazaoFluxoMLpS) * (periodoAtual / 1000);
|
|
|
|
Variaveis.OperacaoEmAndamento.OpMapaGPS.Sensoriamento.HerbicidaConsumido = (VolumeVazaoML / 1000);
|
|
}
|
|
|
|
Sensor.Leituras = new List<double>()
|
|
{
|
|
pulsos,
|
|
tempo
|
|
};
|
|
break;
|
|
}
|
|
case S_Code.sMAS:
|
|
{
|
|
double massa = 0;
|
|
double.TryParse(Dados[2].Replace(".", ","), out massa);
|
|
_MassaLeitura = massa;
|
|
|
|
Sensor.Leituras = new List<double>()
|
|
{
|
|
massa
|
|
};
|
|
break;
|
|
}
|
|
case S_Code.sPRS:
|
|
{
|
|
double pressao = 0;
|
|
double.TryParse(Dados[2].Replace(".", ","), out pressao);
|
|
double leitura = 0;
|
|
double.TryParse(Dados[3].Replace(".", ","), out leitura);
|
|
|
|
PressaoLinha = pressao;
|
|
_LeituraPressao = leitura;
|
|
|
|
BombaPressurizadora.Pressao = PressaoLinha;
|
|
|
|
Sensor.Leituras = new List<double>()
|
|
{
|
|
pressao,
|
|
};
|
|
break;
|
|
}
|
|
case S_Code.sBMB:
|
|
{
|
|
bool Ligado = Dados[2] == "1";
|
|
Bomba.Ligado = Ligado;
|
|
double potencia = 0;
|
|
double.TryParse(Dados[3].Replace(".", ","), out potencia);
|
|
Bomba.Potencia = potencia;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (Sensor != null)
|
|
{
|
|
if (Sensor.Leituras[0] > Sensor.ValorMaximo)
|
|
{
|
|
Sensor.ValorMaximo = Sensor.Leituras[0];
|
|
}
|
|
else if (Sensor.Leituras[0] < Sensor.ValorMinimo)
|
|
{
|
|
Sensor.ValorMinimo = Sensor.Leituras[0];
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
public string GetTaxaAmostragem()
|
|
{
|
|
return _TaxaAmostragem.ToString("00000");
|
|
}
|
|
|
|
public void SetTaxaAmostragem(int TaxaAmostragem)
|
|
{
|
|
_TaxaAmostragem = TaxaAmostragem;
|
|
}
|
|
|
|
public bool GetStatusConexao()
|
|
{
|
|
return Conectado;
|
|
}
|
|
|
|
public void IniciarRegistrador()
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
public class AtuadorBicoModel
|
|
{
|
|
public string ID { get; set; }
|
|
public int Posicao { get; set; }
|
|
public bool Atuado { get; set; }
|
|
public bool Comandar { get; set; }
|
|
public bool Inicializado { get; set; }
|
|
public bool Testando { get; set; }
|
|
public List<FuncoesPinout> Funcoes { get; set; }
|
|
public bool StatusBico { get; set; }
|
|
public double MediaNivelFluxo { get; set; }
|
|
|
|
|
|
public string ProtocoloConfiguracaoBico(bool Conectar)
|
|
{
|
|
var _pinout = new PinoutDataModel()
|
|
{
|
|
ExpansorGPIO = AtuadorModel.Pinout.ExpansorGPIO,
|
|
EnderecoExpansor = AtuadorModel.Pinout.EnderecoExpansor,
|
|
Pinos = AtuadorModel.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 +
|
|
(Comandar ? "1" : "0") + SerialService.SplitParams +
|
|
Posicao.ToString() + SerialService.SplitParams +
|
|
PinoutModel.PinoProtocolo(_pinout, Funcoes);
|
|
|
|
return Protocolo;
|
|
}
|
|
|
|
public string ProtocoloComando()
|
|
{
|
|
if (Comandar)
|
|
{
|
|
string ProtocoloBico =
|
|
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
|
|
ID + SerialService.SplitParams +
|
|
(Atuado ? "1" : "0");
|
|
return ProtocoloBico;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
public string ProtocoloTeste()
|
|
{
|
|
if (Comandar)
|
|
{
|
|
string ProtocoloBico =
|
|
((int)F_Code.Tst).ToString() + SerialService.SplitMessage +
|
|
ID;
|
|
return ProtocoloBico;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
|
|
public AtuadorBicoModel Clone()
|
|
{
|
|
AtuadorBicoModel clone = new AtuadorBicoModel()
|
|
{
|
|
ID = this.ID,
|
|
Posicao = this.Posicao,
|
|
Atuado = this.Atuado,
|
|
Comandar = this.Comandar,
|
|
Inicializado = this.Inicializado,
|
|
Testando = this.Testando,
|
|
Funcoes = this.Funcoes,
|
|
StatusBico = this.StatusBico,
|
|
MediaNivelFluxo = this.MediaNivelFluxo,
|
|
};
|
|
|
|
return clone;
|
|
}
|
|
}
|
|
|
|
public class AtuadorBombaModel
|
|
{
|
|
public string ID { get; set; }
|
|
public bool BombaAtuada { get; set; }
|
|
public bool Ligado { get; set; }
|
|
public bool Comandar { get; set; }
|
|
public bool Inicializado { get; set; }
|
|
public bool Testando { get; set; }
|
|
public List<FuncoesPinout> Funcoes { get; set; } = new List<FuncoesPinout>();
|
|
public double PressaoSP { get; set; }
|
|
public double Pressao { get; set; }
|
|
public double Potencia { get; set; }
|
|
|
|
|
|
public string ProtocoloConfiguracaoBomba(bool Conectar)
|
|
{
|
|
var _pinout = new PinoutDataModel()
|
|
{
|
|
ExpansorGPIO = AtuadorModel.Pinout.ExpansorGPIO,
|
|
EnderecoExpansor = AtuadorModel.Pinout.EnderecoExpansor,
|
|
Pinos = AtuadorModel.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 +
|
|
(Comandar ? "1" : "0") + SerialService.SplitParams +
|
|
PressaoSP.ToString("000") + SerialService.SplitParams +
|
|
PinoutModel.PinoProtocolo(_pinout, Funcoes);
|
|
|
|
return Protocolo;
|
|
}
|
|
|
|
public string ProtocoloComando()
|
|
{
|
|
if (Comandar)
|
|
{
|
|
string ProtocoloBomba =
|
|
((int)F_Code.Cmd).ToString() + SerialService.SplitMessage +
|
|
ID.PadRight(5, ' ') + SerialService.SplitParams +
|
|
(BombaAtuada ? "1" : "0") + SerialService.SplitParams +
|
|
PressaoSP.ToString();
|
|
return ProtocoloBomba;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
public string ProtocoloTeste()
|
|
{
|
|
if (Comandar)
|
|
{
|
|
string ProtocoloBomba =
|
|
((int)F_Code.Tst).ToString() + SerialService.SplitMessage +
|
|
ID;
|
|
return ProtocoloBomba;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
|
|
public AtuadorBombaModel Clone()
|
|
{
|
|
AtuadorBombaModel clone = new AtuadorBombaModel()
|
|
{
|
|
ID = this.ID,
|
|
Ligado = this.Ligado,
|
|
Comandar = this.Comandar,
|
|
Inicializado = this.Inicializado,
|
|
Testando = this.Testando,
|
|
Funcoes = this.Funcoes,
|
|
Pressao = this.Pressao,
|
|
PressaoSP = this.PressaoSP,
|
|
};
|
|
|
|
return clone;
|
|
}
|
|
}
|
|
|
|
public class CalibragemVazao
|
|
{
|
|
public bool Calibrando { get; set; } = false;
|
|
public DateTime IniciadoEm { get; set; }
|
|
public double TempoCalibragem { get; set; } = 10000.0;
|
|
public double VolumeComputado { get; set; } = 0;
|
|
public List<double> PressoesAferidas { get; set; } = new List<double>();
|
|
public double MassaInicial { get; set; } = 0.0;
|
|
public double MassaFinal { get; set; } = 0.0;
|
|
public int QtdPulsos { get; set; } = 0;
|
|
public double Periodo { get; set; } = 0.0;
|
|
public double PressaoMedia
|
|
{
|
|
get
|
|
{
|
|
return PressoesAferidas.Average();
|
|
}
|
|
}
|
|
public double MassaPerdida
|
|
{
|
|
get
|
|
{
|
|
return (MassaInicial - MassaFinal) * 1000;
|
|
}
|
|
}
|
|
public double Q
|
|
{
|
|
get
|
|
{
|
|
return (double)VolumeComputado / (double)Periodo;
|
|
}
|
|
}
|
|
public double VolumeCalculado { get; set; } = 0.0;
|
|
public double d
|
|
{
|
|
get
|
|
{
|
|
return (double)MassaPerdida / (double)VolumeComputado;
|
|
}
|
|
}
|
|
public double x
|
|
{
|
|
get
|
|
{
|
|
return (double)VolumeComputado / (double)QtdPulsos;
|
|
}
|
|
}
|
|
public double Q2
|
|
{
|
|
get
|
|
{
|
|
return (double)x * (double)QtdPulsos;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|