agrobot_base/AgroBase/AgroBase/Services/SerialService.cs

229 lines
9.1 KiB
C#

using AgroBase.Forms;
using AgroBase.Models;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading;
using System.Windows.Forms;
using static AgroBase.Models.Enuns;
namespace AgroBase.Services
{
public class SerialService
{
public static string BeginLine = "@";
public static string EndLine = "$";
public static string BeginSensor = "#";
public static string SplitMessage = ";";
public static string SplitParams = ",";
public static string ProtocoloCheck = BeginLine + SplitMessage + 0 + SplitMessage + ((int)F_Code.Chk).ToString() + SplitMessage + "check" + EndLine;
public static List<T_Code> DispositivosMotores = new List<T_Code>() { T_Code.Mov, T_Code.Dir };
public class DispositivoDetalhesModel
{
public string PortaCOM { get; set; }
public T_Code Dispositivo { get; set; }
public bool Erro { get; set; }
public int Versao { get; set; }
}
public static List<DispositivoDetalhesModel> DispositivosMapeados = new List<DispositivoDetalhesModel>();
public static List<SerialPort> PortasAguardandoResposta = new List<SerialPort>();
public static List<SerialPort> PortasComErro = new List<SerialPort>();
private static Dictionary<string, int> TentativasPortas = new Dictionary<string, int>();
public static void RealizarVarreduraPortasUSB()
{
PortasAguardandoResposta.ForEach(Porta =>
{
Porta.Close();
PortasComErro.Add(Porta);
});
List<SerialPort> PortasSucesso = new List<SerialPort>();
PortasComErro.ForEach(Porta =>
{
Porta.DataReceived -= _Porta_DataReceived;
PortasAguardandoResposta.Remove(Porta);
if (PZEMService.PortaPZEM == null)
{
PZEMService.AtualizarPortaCOM(Porta);
}
if (TentativasPortas.TryGetValue(Porta.PortName, out int tentativas))
{
TentativasPortas[Porta.PortName] = tentativas + 1;
}
else
{
TentativasPortas.Add(Porta.PortName, 1);
}
if (TentativasPortas[Porta.PortName] > 5)
{
Porta.Close();
PortasSucesso.Add(Porta);
TentativasPortas.Remove(Porta.PortName);
Porta.DataReceived += _Porta_DataReceived;
}
});
PortasSucesso.ForEach(x => PortasComErro.Remove(x));
var dispositivosMapeados = DispositivosMapeados.ToList();
var Portas = SerialPort.GetPortNames();
var PortasNaoMapeadas = Portas.Where(x => !dispositivosMapeados.Select(y => y.PortaCOM).Contains(x) && !PortasComErro.Select(y => y.PortName).Contains(x)).ToList();
if (GPSService.PortaGPS != null)
{
PortasNaoMapeadas = PortasNaoMapeadas.Where(x => x != GPSService.PortaGPS.PortName).ToList();
}
if (PZEMService.PortaPZEM != null)
{
PortasNaoMapeadas = PortasNaoMapeadas.Where(x => x != PZEMService.PortaPZEM.PortName).ToList();
PortasComErro.Remove(PZEMService.PortaPZEM);
}
for (int i = 0; i < PortasNaoMapeadas.Count(); i++)
{
string PortaCom = PortasNaoMapeadas[i].ToString();
SerialPort _Porta = new SerialPort() { PortName = PortaCom, BaudRate = 115200 };
_Porta.DataReceived -= _Porta_DataReceived;
_Porta.DataReceived += _Porta_DataReceived;
string CodigoTest = ProtocoloCheck;
try
{
_Porta.Open();
_Porta.Write(CodigoTest);
PortasAguardandoResposta.Add(_Porta);
}
catch (Exception ex)
{
_Porta.Close();
Console.WriteLine(ex.Message.ToString());
PortasComErro.Add(_Porta);
}
}
var DispositivosRemovidos = dispositivosMapeados.Where(x => !Portas.Contains(x.PortaCOM)).ToList();
foreach (var Dispositivo in DispositivosRemovidos)
{
DispositivosMapeados.Remove(Dispositivo);
}
AtualizarDispositivos();
}
public static void AtualizarDispositivos()
{
Variaveis.DispositivosConexaoInicial.ForEach(Dispositivo =>
{
bool DispositivoConectado = false;
if (Dispositivo == T_Code.Gps)
{
try
{
if (!GPSService.PortaGPS.IsOpen)
{
GPSService.IniciarRecepcaoDados();
}
DispositivoConectado = GPSService.PortaGPS.IsOpen;
}
catch
{
DispositivoConectado = false;
}
}
else
{
IDispositivosService dispositivoService = Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == Dispositivo);
if (dispositivoService == null)
{
dispositivoService = DispositivosServiceFactory.CreateDispositivoService(
Dispositivo,
"Nome: " + Enum.GetName(typeof(T_Code), Dispositivo),
"Descrição: " + Enum.GetName(typeof(T_Code), Dispositivo),
new SerialPort()
);
Variaveis.DispositivosConectados.Add(dispositivoService);
Control controle = dispositivoService.InstanciarDispositivo(Variaveis.DispositivosConectados.Count - 1);
controle.Location = new System.Drawing.Point(controle.Location.X, controle.Location.Y + (Variaveis.DispositivosConectados.Count * 50));
frmInstancial.frmPrincipal.pnlLateral.Controls.Add(controle);
frmInstancial.frmPrincipal.cmbDispositivos.Items.Add(dispositivoService._Descricao);
}
dispositivoService.AtualizarPortas();
if (dispositivoService.PortaCOM() != "" && !dispositivoService._Porta.IsOpen && frmInstancial.frmPrincipal.chbConexaoautomatica.Checked)
{
dispositivoService.btnConectar_Click(new object(), new EventArgs());
}
DispositivoConectado = dispositivoService._Porta.IsOpen;
}
});
}
private static void _Porta_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var Porta = ((SerialPort)sender);
try
{
string Recebido = Porta.ReadLine();
if (Recebido.Length > 2)
{
T_Code Dispositivo = T_Code.Vzo;
F_Code Verificacao = F_Code.Nda;
int Versao = 0;
if (Recebido.Contains("$GPTXT"))
{
GPSService.AtualizarPortaGPS(Porta);
Dispositivo = T_Code.Gps;
}
else
{
var Dados = Recebido.Split(';');
int code = 0;
int.TryParse(Dados[0], out code);
if (code == 0)
{
//Porta.Close();
return;
}
if ((F_Code)code == F_Code.Msg)
{
return;
}
Dispositivo = (T_Code)(int.Parse(Dados[0]));
int.TryParse(Dados[1], out int check);
Verificacao = (F_Code)check;
int.TryParse(Dados[2], out int versao);
Versao = versao;
}
if (Dispositivo != T_Code.Vzo)
{
DispositivosMapeados.Add(new DispositivoDetalhesModel()
{
PortaCOM = Porta.PortName,
Dispositivo = Dispositivo,
Erro = Verificacao == F_Code.Err,
Versao = Versao,
});
}
Porta.Close();
PortasAguardandoResposta.Remove(Porta);
}
}
catch (Exception ex)
{
Console.WriteLine("Erro ao receber dados da porta " + Porta.PortName);
}
}
}
}