agrobot_base/AgroBase/AgroBase/Services/DispositivosService.cs

747 lines
26 KiB
C#

using AgroBase.Forms;
using AgroBase.Forms.Atuador;
using AgroBase.Forms.Direcional;
using AgroBase.Forms.Movimentacao;
using AgroBase.Forms.Sensoriamento;
using AgroBase.Models;
using AgroBase.Models.Modules;
using AgroBase.Services;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enuns;
namespace AgroBase.Comum
{
public class DispositivosService<T> : IDispositivosService where T : DispositivoBaseModel, new()
{
public T_Code Dispositivo { get; set; } = T_Code.Vzo;
public string _Nome { get; set; }
public string _Descricao { get; set; }
public SerialPort _Porta { get; set; }
public GroupBox gpbItem { get; set; }
public ComboBox cmbPorta { get; set; }
public ComboBox cmbBaudRate { get; set; }
public NumericUpDown nudAmostragem { get; set; }
public Label lblStatus { get; set; }
public Button btnConectar { get; set; }
public Button btnAtualizar { get; set; }
public TextBox txtEnvios { get; set; }
public RichTextBox txaConsole { get; set; }
public Timer tmrConexao { get; set; }
public int _index { get; set; }
public List<string> DadosEnviados { get; set; } = new List<string>();
public List<string> DadosRecebidos { get; set; } = new List<string>();
public T Dados { get; set; } = new T();
DispositivoBaseModel IDispositivosService.Dados
{
get { return this.Dados; }
set { this.Dados = (T)value; } // Isso pode lançar uma exceção se o valor não for do tipo T
}
public Form frmConfig { get; set; }
public Form frmPlot { get; set; }
public Timer tmrLimpeza = new Timer() { Interval = 1000, Enabled = false };
public int Ticks { get; set; } = 0;
public int TempoConectado { get; set; } = 0;
public int BaudRate()
{
if (cmbBaudRate.SelectedIndex < 0)
{
return 0;
}
return Convert.ToInt32(cmbBaudRate.SelectedItem.ToString());
}
public string PortaCOM()
{
if (cmbPorta.SelectedIndex < 0)
{
return "";
}
return cmbPorta.SelectedItem.ToString();
}
public string StatusPorta()
{
string _status = _Porta.IsOpen ? "Conectado" : "Desconectado";
frmInstancial.frmPrincipal.lblStripErro.Text = _status;
return _status;
}
public void AtualizarPortas()
{
cmbPorta.Items.Clear();
cmbPorta.Text = "";
var DispositivosTipo = SerialService.DispositivosConectados.Where(x => x.Dispositivo == Dispositivo).ToList();
for (int i = 0; i < DispositivosTipo.Count(); i++)
{
string PortaCom = DispositivosTipo[i].PortaCOM;
SerialPort _Porta = new SerialPort() { PortName = PortaCom };
try
{
_Porta.Open();
_Porta.Close();
cmbPorta.Items.Add(PortaCom);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
if (cmbPorta.Items.Count > 1)
cmbPorta.SelectedIndex = 1;
else if (cmbPorta.Items.Count > 0)
cmbPorta.SelectedIndex = 0;
}
public void AtualizarBauds()
{
cmbBaudRate.Items.Clear();
cmbBaudRate.Text = "";
cmbBaudRate.Items.Add("9600");
cmbBaudRate.Items.Add("34800");
cmbBaudRate.Items.Add("115200");
cmbBaudRate.SelectedIndex = 2;
}
public bool ConectarPortaSerial()
{
try
{
_Porta.PortName = PortaCOM();
_Porta.BaudRate = BaudRate();
if (_Porta.IsOpen)
{
return false;
}
_Porta.Open();
LimparBufferSerial(false);
lblStatus.Text = StatusPorta();
return _Porta.IsOpen;
}
catch (Exception ex)
{
frmInstancial.frmPrincipal.lblStripErro.Text = "Erro ao conectar na porta '" + PortaCOM() + "' - " + ex.Message;
return false;
}
}
public bool DesconectarPortaSerial()
{
try
{
if (!_Porta.IsOpen)
{
return false;
}
LimparBufferSerial(false);
_Porta.Close();
lblStatus.Text = StatusPorta();
return !_Porta.IsOpen;
}
catch (Exception ex)
{
frmInstancial.frmPrincipal.lblStripErro.Text = "Erro ao desconectar da porta '" + PortaCOM() + "' - " + ex.Message;
return false;
}
}
public void EnviarDadosSerial(string Dados)
{
AtualizarConsole(Dados);
if (!_Porta.IsOpen || string.IsNullOrEmpty(Dados))
{
return;
}
Ticks = 0;
_Porta.Write(Dados + SerialService.EndLine);
DadosEnviados.Add("> " + DateTime.Now.ToString("HH:mm:ss:fff") + " - " + Dados);
AtualizarConsole(DadosEnviados[DadosEnviados.Count - 1]);
}
public Control InstanciarDispositivo(int index)
{
switch (Dispositivo)
{
case T_Code.Mov:
Dados = CarregarParametros(MovimentacaoModel.CarregarParametrosIniciais());
frmPlot = new frmMovPlot();
frmConfig = new frmMovConfig();
Dados.IniciarRegistrador();
break;
case T_Code.Dir:
Dados = CarregarParametros(DirecionalModel.CarregarParametrosIniciais());
frmPlot = new frmDirPlot();
frmConfig = new frmDirConfig();
break;
case T_Code.Sen:
Dados = CarregarParametros(SensoriamentoModel.CarregarParametrosIniciais());
frmConfig = new frmSenConfig();
break;
case T_Code.Atu:
Dados = CarregarParametros(AtuadorModel.CarregarParametrosIniciais());
frmConfig = new frmAtuConfig();
break;
default:
Dados = default(T);
break;
}
if (!EqualityComparer<T>.Default.Equals(Dados, default(T)))
{
Dados.PopulaGridSensoriamento();
Dados.CarregarPinout("pinout" + Enum.GetName(typeof(T_Code), Dispositivo) + ".pin");
}
_Porta.DataReceived -= _Porta_DataReceived;
_Porta.DataReceived += _Porta_DataReceived;
gpbItem = new GroupBox()
{
Name = "gpb" + _Nome,
Text = _Descricao,
Location = new System.Drawing.Point() { X = 13, Y = 0 },
Size = new System.Drawing.Size() { Height = 251, Width = 580 },
};
AtualizaIndex(index);
Label lblPorta = new Label()
{
Name = "lbl" + _Nome + "Por",
Text = "Porta",
Location = new System.Drawing.Point() { X = 28, Y = 27 },
Size = new System.Drawing.Size() { Height = 17, Width = 42 }
};
cmbPorta = new ComboBox()
{
Name = "cmb" + _Nome + "Por",
Text = "",
Location = new System.Drawing.Point() { X = 31, Y = 47 },
Size = new System.Drawing.Size() { Height = 24, Width = 89 },
DropDownStyle = ComboBoxStyle.DropDownList
};
AtualizarPortas();
Label lblBaudRate = new Label()
{
Name = "lbl" + _Nome + "Bau",
Text = "Baud Rate",
Location = new System.Drawing.Point() { X = 28, Y = 74 },
Size = new System.Drawing.Size() { Height = 17, Width = 75 }
};
cmbBaudRate = new ComboBox()
{
Name = "cmb" + _Nome + "Bau",
Text = "",
Location = new System.Drawing.Point() { X = 31, Y = 94 },
Size = new System.Drawing.Size() { Height = 24, Width = 89 },
DropDownStyle = ComboBoxStyle.DropDownList
};
AtualizarBauds();
Label lblAmostragem = new Label()
{
Name = "lbl" + _Nome + "Amo",
Text = "Amostragem (ms)",
Location = new System.Drawing.Point() { X = 31, Y = 124 },
Size = new System.Drawing.Size() { Height = 17, Width = 100 }
};
nudAmostragem = new NumericUpDown()
{
Name = "nud" + _Nome + "Amo",
Minimum = 0,
Maximum = 99999,
Value = decimal.Parse(Dados.GetTaxaAmostragem()),
Location = new System.Drawing.Point() { X = 31, Y = 144 },
Size = new System.Drawing.Size() { Height = 24, Width = 89 }
};
nudAmostragem.ValueChanged -= nudAmostragem_ValueChanged;
nudAmostragem.ValueChanged += nudAmostragem_ValueChanged;
btnAtualizar = new Button()
{
Name = "btn" + _Nome + "Att",
Text = "Atualizar",
Location = new System.Drawing.Point() { X = 31, Y = 170 },
Size = new System.Drawing.Size() { Height = 24, Width = 89 }
};
btnAtualizar.Click -= btnAtualizar_Click;
btnAtualizar.Click += btnAtualizar_Click;
btnConectar = new Button()
{
Name = "btn" + _Nome + "Con",
Text = "Conectar",
Location = new System.Drawing.Point() { X = 31, Y = 201 },
Size = new System.Drawing.Size() { Height = 24, Width = 89 }
};
btnConectar.Click -= btnConectar_Click;
btnConectar.Click += btnConectar_Click;
lblStatus = new Label()
{
Name = "lbl" + _Nome + "Sta",
Text = _Porta.IsOpen ? "Conectado" : "Desconectado",
Location = new System.Drawing.Point() { X = 28, Y = 231 },
Size = new System.Drawing.Size() { Height = 17, Width = 100 }
};
Label lblDispositivos = new Label()
{
Name = "lbl" + _Nome + "Disp",
Text =
Dispositivo == T_Code.Sen ? "Sensores" :
Dispositivo == T_Code.Atu ? "Atuadores" :
SerialService.DispositivosMotores.Any(x => x == Dispositivo) ? "Motores" :
"Dispositivos",
Location = new System.Drawing.Point() { X = 135, Y = 27 },
Size = new System.Drawing.Size() { Height = 17, Width = 100 }
};
CheckedListBox clbDispositivos = new CheckedListBox()
{
Name = "clb" + _Nome,
Location = new System.Drawing.Point() { X = 135, Y = 45 },
Size = new System.Drawing.Size() { Height = 125, Width = 100 }
};
if (SerialService.DispositivosMotores.Contains(Dispositivo))
{
clbDispositivos.Items.Clear();
Models.MovSensoriamentoMotor[] Motores = { };
if (Dados is MovimentacaoModel movModel && Dispositivo == T_Code.Mov)
{
Motores = movModel.Motores.Select(x => new Models.MovSensoriamentoMotor { ID = x.ID, Comandar = x.Comandar }).ToArray();
}
else if (Dados is DirecionalModel dirModel && Dispositivo == T_Code.Dir)
{
Motores = dirModel.Motores.Select(x => new Models.MovSensoriamentoMotor { ID = x.ID, Comandar = x.Comandar }).ToArray();
}
foreach (var Motor in Motores)
{
clbDispositivos.Items.Add(Motor.ID);
clbDispositivos.SetItemChecked(clbDispositivos.Items.Count - 1, Motor.Comandar);
}
}
else if (Dados is SensoriamentoModel senModel && Dispositivo == T_Code.Sen)
{
clbDispositivos.Items.Clear();
var Sensores = senModel.Sensores;
foreach (var Sensor in Sensores)
{
clbDispositivos.Items.Add(Sensor.ID);
clbDispositivos.SetItemChecked(clbDispositivos.Items.Count - 1, Sensor.Aferir);
}
}
else if (Dados is AtuadorModel atuModel && Dispositivo == T_Code.Atu)
{
clbDispositivos.Items.Clear();
var Bicos = atuModel.BicosPulverizadores;
foreach (var Bico in Bicos)
{
clbDispositivos.Items.Add(Bico.ID.ToString());
clbDispositivos.SetItemChecked(clbDispositivos.Items.Count - 1, Bico.Comandar);
}
}
clbDispositivos.ItemCheck -= clbDispositivos_ItemCheck;
clbDispositivos.ItemCheck += clbDispositivos_ItemCheck;
Label lblEnvio = new Label()
{
Name = "lbl" + _Nome + "Env",
Text = "Enviar dados",
Location = new System.Drawing.Point() { X = 255, Y = 27 },
Size = new System.Drawing.Size() { Height = 17, Width = 75 }
};
txtEnvios = new TextBox()
{
Name = "txt" + _Nome,
Text = "",
Location = new System.Drawing.Point() { X = 255, Y = 47 },
Size = new System.Drawing.Size() { Height = 24, Width = 215 },
ReadOnly = true
};
txtEnvios.KeyDown -= txtEnvios_KeyDown;
txtEnvios.KeyDown += txtEnvios_KeyDown;
Button btnLimpar = new Button()
{
Name = "btn" + _Nome + "Lim",
Text = "Limpar",
Location = new System.Drawing.Point() { X = 480, Y = 47 },
Size = new System.Drawing.Size() { Height = 24, Width = 70 },
};
btnLimpar.Click -= btnLimpar_Click;
btnLimpar.Click += btnLimpar_Click;
Label lblRecebidos = new Label()
{
Name = "lbl" + _Nome + "Rec",
Text = "Dados recebidos",
Location = new System.Drawing.Point() { X = 255, Y = 74 },
Size = new System.Drawing.Size() { Height = 17, Width = 100 }
};
txaConsole = new RichTextBox()
{
Name = "txa" + _Nome,
Text = "",
Location = new System.Drawing.Point() { X = 255, Y = 94 },
Size = new System.Drawing.Size() { Height = 141, Width = 300 },
ReadOnly = true
};
tmrConexao = new Timer()
{
Interval = 3000,
Enabled = false
};
tmrConexao.Tick -= TmrConexao_Tick;
tmrConexao.Tick += TmrConexao_Tick;
tmrLimpeza = new Timer()
{
Interval = 1000,
Enabled = false
};
tmrLimpeza.Tick -= TmrLimpeza_Tick;
tmrLimpeza.Tick += TmrLimpeza_Tick;
Button btnConfig = new Button()
{
Name = "btn" + _Nome + "Config",
Text = "Configuração",
Location = new System.Drawing.Point() { X = 135, Y = 170 },
Size = new System.Drawing.Size() { Height = 24, Width = 89 }
};
btnConfig.Click -= btnConfig_Click;
btnConfig.Click += btnConfig_Click;
Button btnPlot = new Button()
{
Name = "btn" + _Nome + "Plot",
Text = "Plotagem",
Location = new System.Drawing.Point() { X = 135, Y = 201 },
Size = new System.Drawing.Size() { Height = 24, Width = 89 }
};
btnPlot.Click -= btnPlot_Click;
btnPlot.Click += btnPlot_Click;
gpbItem.Controls.Add(lblPorta);
gpbItem.Controls.Add(cmbPorta);
gpbItem.Controls.Add(lblBaudRate);
gpbItem.Controls.Add(cmbBaudRate);
gpbItem.Controls.Add(lblAmostragem);
gpbItem.Controls.Add(nudAmostragem);
gpbItem.Controls.Add(lblDispositivos);
gpbItem.Controls.Add(clbDispositivos);
gpbItem.Controls.Add(btnAtualizar);
gpbItem.Controls.Add(btnConectar);
gpbItem.Controls.Add(lblStatus);
gpbItem.Controls.Add(lblEnvio);
gpbItem.Controls.Add(txtEnvios);
gpbItem.Controls.Add(btnLimpar);
gpbItem.Controls.Add(lblRecebidos);
gpbItem.Controls.Add(txaConsole);
gpbItem.Controls.Add(btnConfig);
gpbItem.Controls.Add(btnPlot);
return gpbItem;
}
private void btnPlot_Click(object sender, EventArgs e)
{
if (frmPlot != null)
{
frmPlot.Show();
}
}
private void btnConfig_Click(object sender, EventArgs e)
{
if (frmConfig != null)
{
frmConfig.Show();
}
}
private void TmrConexao_Tick(object sender, EventArgs e)
{
AcaoConexao();
tmrConexao.Enabled = false;
}
private void TmrLimpeza_Tick(object sender, EventArgs e)
{
if (Ticks > 5)
{
LimparBufferSerial(true);
Ticks = -1;
}
Ticks++;
TempoConectado++;
}
private void clbDispositivos_ItemCheck(object sender, ItemCheckEventArgs e)
{
((CheckedListBox)sender).ItemCheck -= clbDispositivos_ItemCheck;
((CheckedListBox)sender).SetItemCheckState(e.Index, e.NewValue);
((CheckedListBox)sender).ItemCheck += clbDispositivos_ItemCheck;
switch (Dispositivo)
{
case T_Code.Mov:
if (Dados is MovimentacaoModel movModel)
{
movModel.Motores.ForEach(x => x.Comandar = false);
foreach (var Item in ((CheckedListBox)sender).CheckedItems)
{
movModel.Motores.First(x => x.ID == Item.ToString()).Comandar = true;
}
}
break;
case T_Code.Dir:
if (Dados is DirecionalModel dirModel)
{
dirModel.Motores.ForEach(x => x.Comandar = false);
foreach (var Item in ((CheckedListBox)sender).CheckedItems)
{
dirModel.Motores.First(x => x.ID == Item.ToString()).Comandar = true;
}
}
break;
case T_Code.Sen:
if (Dados is SensoriamentoModel senModel)
{
senModel.Sensores.ForEach(x => x.Aferir = false);
foreach (var Item in ((CheckedListBox)sender).CheckedItems)
{
senModel.Sensores.First(x => x.ID == Item.ToString()).Aferir = true;
}
}
break;
case T_Code.Atu:
if (Dados is AtuadorModel atuModel)
{
atuModel.BicosPulverizadores.ForEach(x => x.Comandar = false);
foreach (var Item in ((CheckedListBox)sender).CheckedItems)
{
atuModel.BicosPulverizadores.First(x => x.ID == Item.ToString()).Comandar = true;
}
}
break;
}
var Config = Dados.ProtocoloConfiguracao(true);
frmInstancial.frmPrincipal.lblStripErro.Text = Config[Config.Count - 1];
}
private void nudAmostragem_ValueChanged(object sender, EventArgs e)
{
Dados.SetTaxaAmostragem((Convert.ToInt32(((NumericUpDown)sender).Value)));
}
private void btnLimpar_Click(object sender, EventArgs e)
{
LimparBufferSerial(true);
}
public void LimparBufferSerial(bool LimparConsole)
{
if (LimparConsole)
{
txaConsole.Text = "";
}
if (_Porta.IsOpen)
{
_Porta.DiscardInBuffer();
_Porta.DiscardOutBuffer();
}
}
private void txtEnvios_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter && txtEnvios.Text != "")
{
EnviarDadosSerial(txtEnvios.Text);
txtEnvios.Text = "";
txtEnvios.Focus();
}
}
public void AtualizaIndex(int index)
{
_index = index;
gpbItem.Location = new System.Drawing.Point() { X = gpbItem.Location.X, Y = (220 + (_index * 210)) };
}
private void _Porta_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string Recebido = "";
try
{
Recebido = _Porta.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
if (Recebido == "")
{
return;
}
if (Dispositivo == T_Code.Vzo)
{
Dispositivo = (T_Code)(int.Parse(Recebido.Substring(0, 3)));
lblStatus.Invoke((Action)(() => lblStatus.Text = StatusPorta() + " - " + Enum.GetName(typeof(T_Code), Dispositivo)));
}
DadosRecebidos.Add("< " + DateTime.Now.ToString("HH:mm:ss:fff") + " - " + Recebido);
AtualizarConsole(DadosRecebidos[DadosRecebidos.Count - 1]);
if (Recebido[0].ToString() == SerialService.BeginSensor && !EqualityComparer<T>.Default.Equals(Dados, default(T)))
{
Dados.RecebeProtocoloSerial(Recebido);
Dados.AtualizaGridSensoriamento();
}
}
private void btnConectar_Click(object sender, EventArgs e)
{
List<string> Config = new List<string>();
if (_Porta.IsOpen)
{
LimparBufferSerial(false);
Config = Dados.ProtocoloConfiguracao(false);
foreach (var ProtocoloConfiguracao in Config)
{
if (ProtocoloConfiguracao != "")
{
EnviarDadosSerial(ProtocoloConfiguracao);
Task.Delay(100);
}
}
}
else
{
if (ConectarPortaSerial())
{
LimparBufferSerial(false);
Config = Dados.ProtocoloConfiguracao(true);
foreach (var ProtocoloConfiguracao in Config)
{
if (ProtocoloConfiguracao != "")
{
EnviarDadosSerial(ProtocoloConfiguracao);
Task.Delay(100);
}
}
}
}
GeneralJoystick.AtualizaDispositivo();
tmrConexao.Enabled = true;
}
public void AcaoConexao()
{
if (!Dados.GetStatusConexao())
{
if (DesconectarPortaSerial())
{
AcaoDesconectar();
}
}
else
{
AcaoConectar();
}
}
public void AcaoDesconectar()
{
cmbPorta.Enabled = true;
cmbBaudRate.Enabled = true;
btnAtualizar.Enabled = true;
nudAmostragem.Enabled = true;
txtEnvios.ReadOnly = true;
txtEnvios.Text = "";
btnConectar.Text = "Conectar";
tmrLimpeza.Enabled = false;
}
public void AcaoConectar()
{
cmbPorta.Enabled = false;
cmbBaudRate.Enabled = false;
btnAtualizar.Enabled = false;
nudAmostragem.Enabled = false;
txtEnvios.ReadOnly = false;
txtEnvios.Text = "";
btnConectar.Text = "Desconectar";
tmrLimpeza.Enabled = true;
}
private void btnAtualizar_Click(object sender, EventArgs e)
{
AtualizarPortas();
}
delegate void AtualizarConsoleDelegate(string Texto);
private void AtualizarConsole(string Texto)
{
Texto += Environment.NewLine;
if (txaConsole.InvokeRequired)
{
txaConsole.Invoke(new AtualizarConsoleDelegate(AtualizarConsole), Texto);
}
else
{
txaConsole.Text += Texto;
}
}
public T CarregarParametros(object empty)
{
string nomeArquivo = "parameters" + Enum.GetName(typeof(T_Code), Dispositivo) + ".par";
if (!File.Exists(nomeArquivo))
{
var newConfig = empty;
File.WriteAllText(nomeArquivo, JsonConvert.SerializeObject(newConfig));
}
var configText = File.ReadAllText(nomeArquivo);
var Parametros = JsonConvert.DeserializeObject<T>(configText);
return Parametros;
}
public void SalvarParametros(DispositivoBaseModel newConfig)
{
File.WriteAllText("parameters" + Enum.GetName(typeof(T_Code), Dispositivo) + ".par", JsonConvert.SerializeObject(newConfig));
}
}
}