using AgroBase.Comum; using AgroBase.Forms; using AgroBase.Forms.Operacoes; using AgroBase.Models.Modules; using AgroBase.Models.Operacoes; using AgroBase.Services; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using static AgroBase.Models.Enums; using System.Drawing; using System.Text; using System.Windows.Forms.DataVisualization.Charting; using OpenHardwareMonitor.Hardware; using CefSharp.WinForms; using System.Diagnostics; using System.Threading; namespace AgroBase.Models { public class OperacaoModel { public OperacaoModel(ModoOperacao Modo) { this.Modo = Modo; if (Variaveis.OperacaoEmAndamento != null) { tmrLogs?.Dispose(); tmrLogs = new AsyncTaskTimerModel("tmrLogs", tmrLogs_Tick, 1000); tmrLeituras?.Dispose(); tmrLeituras = new AsyncTaskTimerModel("tmrLeitura", tmrLeituras_Tick, 500, chartGraficos); tmrLeituras.Start(); if (computer == null) { computer = new Computer() { CPUEnabled = true, GPUEnabled = true, RAMEnabled = true, HDDEnabled = true, }; try { computer.Open(); } catch (ArgumentOutOfRangeException ex) { } catch (Exception ex) { } } } } public ModoOperacao Modo { get; set; } public string Descricao { get; set; } public OperacaoMapaGPSModel OpMapaGPS { get; set; } = new OperacaoMapaGPSModel(); public OperacaoControleModel Controle { get; set; } = new OperacaoControleModel(); public OperacaoControleModel ControleAnterior { get; set; } = new OperacaoControleModel(); public DispositivosService DispMvd { get; set; } public DispositivosService DispSen { get; set; } public DispositivosService DispAtu { get; set; } public MapasModel Mapa { get; set; } = new MapasModel(); public OperacaoSensoriamentoLogModel Sensoriamento { get; set; } = new OperacaoSensoriamentoLogModel(); public Form frmOperacao { get; set; } private StatusOperacao _EtapaAtual; private StatusOperacao _EtapaAnteriorParada = StatusOperacao.Parado; public bool Emergencia { get; set; } = false; public StatusOperacao StatusAtual { get { StatusOperacao etapaAtual = _EtapaAtual; // Se a operação não estiver iniciada if (!Variaveis.OperacaoEmAndamento.Iniciado) { // Etapa atual não é Finalizado, então a etapa é Parametrizando if (_EtapaAtual != StatusOperacao.Concluido) { etapaAtual = StatusOperacao.Parametrizando; } else { //etapaAtual = StatusOperacao.NaoIniciado; } } // Operação em andamento else { // Se a operacao atual for manual if (Variaveis.OperacaoEmAndamento.Modo == ModoOperacao.Manual) { etapaAtual = StatusOperacao.EmAndamento; } // Se o trajeto foi finalizado else if (Variaveis.OperacaoEmAndamento.OpMapaGPS.Concluido && _EtapaAtual != StatusOperacao.Concluido) { etapaAtual = StatusOperacao.Concluido; } // Etapa atual é finalizada, então finaliza a operação else if (_EtapaAtual == StatusOperacao.Concluido) { if (Variaveis.OperacaoEmAndamento.Iniciado && !Variaveis.OperacaoEmAndamento.Finalizando) { Variaveis.OperacaoEmAndamento.FinalizarOperacao(); } } // Se a operação tiver algum item mandatório interrompido else if (!Variaveis.OperacaoEmAndamento.OperacaoLiberada) { // Da primeira vez, salva a etapa atual anterior à parada para possível retomada if (etapaAtual != StatusOperacao.Parado) { _EtapaAnteriorParada = etapaAtual; } etapaAtual = StatusOperacao.Parado; } // Se a etapa atual for parado, mas a operação foi liberada, retoma de onde parou else if (etapaAtual == StatusOperacao.Parado && Variaveis.OperacaoEmAndamento.OperacaoLiberada) { Variaveis.OperacaoEmAndamento.TempoAguardando = DateTime.Now; etapaAtual = StatusOperacao.Aguardando; } // Contagem regressiva para iniciar a operação else if (Variaveis.OperacaoEmAndamento.TempoAguardando.AddSeconds(Variaveis.OperacaoEmAndamento.TempoIniciarOperacao) > DateTime.Now) { etapaAtual = StatusOperacao.Aguardando; } else if (_EtapaAnteriorParada != StatusOperacao.Parado) { etapaAtual = _EtapaAnteriorParada; _EtapaAnteriorParada = StatusOperacao.Parado; } else { etapaAtual = StatusOperacao.EmAndamento; } } _EtapaAtual = etapaAtual; //_EtapaAtual = StatusOperacao.EmAndamento; Variaveis.OperacaoEmAndamento.Sensoriamento.StatusOperacao = _EtapaAtual; return _EtapaAtual; } } public (bool, List) ModulosConectados { get { Variaveis.OperacaoEmAndamento.ModulosMandatorios.ForEach(Modulo => { Modulo.Conectado = SerialService.DispositivosMapeados.Any(x => x.Dispositivo == Modulo.Dispositivo && x.Conectado); }); bool _modulosConectados = (Variaveis.OperacaoEmAndamento.ModulosMandatorios.Any(x => x.Mandatorio) && Variaveis.OperacaoEmAndamento.ModulosMandatorios.Where(x => x.Mandatorio).All(x => x.Conectado)) || (Variaveis.OperacaoEmAndamento.ModulosMandatorios.All(x => !x.Mandatorio) && Variaveis.OperacaoEmAndamento.ModulosMandatorios.Any(x => x.Conectado)); List _modsComFalha = Variaveis.OperacaoEmAndamento.ModulosMandatorios.Where(x => x.Mandatorio && !x.Conectado).Select(x => x.Dispositivo).ToList(); return (_modulosConectados, _modsComFalha); } } public bool DispositivosIndividuaisConectados { get { bool _dispositivosConectados = true; // Verificação dos motores BLDC if (Variaveis.OperacaoEmAndamento.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Bld && x.Conectado)) { (bool _EsqOperante, List _EsqModsInoperantes) = Variaveis.OperacaoEmAndamento.DispMvd.Dados.StatusModulosBLD(Direcao.Esquerda); (bool _DirOperante, List _DirModsInoperantes) = Variaveis.OperacaoEmAndamento.DispMvd.Dados.StatusModulosBLD(Direcao.Direita); // Se qualquer lado estiver completamente inoperante, o robô não pode operar corretamente if (!_EsqOperante || !_DirOperante) { _dispositivosConectados = false; } } // Verificação dos motores MKS if (Variaveis.OperacaoEmAndamento.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Mks && x.Conectado)) { (bool _MksOperante, List _MksModsInoperantes) = Variaveis.OperacaoEmAndamento.DispMvd.Dados.StatusModulosMKS(Variaveis.OperacaoEmAndamento.Controle.TipoMovimento); if (!_MksOperante) { _dispositivosConectados = false; } } // Verificação dos componentes ATU if (Variaveis.OperacaoEmAndamento.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Atu && x.Conectado)) { (bool _AtuOperante, List _AtuModsInoperantes) = Variaveis.OperacaoEmAndamento.DispAtu.Dados.StatusModulosATU(); if (!_AtuOperante) { _dispositivosConectados = false; } } // Verificação dos componentes SEN if (Variaveis.OperacaoEmAndamento.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Sen && x.Conectado)) { (bool _SenOperante, List _SenModsInoperantes) = Variaveis.OperacaoEmAndamento.DispSen.Dados.StatusModulosSEN(); if (!_SenOperante) { _dispositivosConectados = false; } } return _dispositivosConectados; } } public bool OperacaoLiberada { get { (bool _modsConectados, List _modsComFalha) = Variaveis.OperacaoEmAndamento.ModulosConectados; bool _operacaoLiberada = _modsConectados; if (_operacaoLiberada && Variaveis.OperacaoEmAndamento.ParametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.CameraSolo && x.Mandatorio) && Variaveis.OperacaoEmAndamento.CamerasSolo.Count(x => x.Iniciada) < Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo) _operacaoLiberada = false; if (_operacaoLiberada && Variaveis.OperacaoEmAndamento.ParametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Kinect && x.Mandatorio) && (!KinectService.Iniciado || KinectService.Leitura == null)) _operacaoLiberada = false; if (_operacaoLiberada && Variaveis.OperacaoEmAndamento.ParametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Mapa && x.Mandatorio) && !Variaveis.OperacaoEmAndamento.Mapa.mapaService.Carregado) _operacaoLiberada = false; if (_operacaoLiberada && Variaveis.OperacaoEmAndamento.ParametrosMandatorios.Any(x => x.Parametro == ParametrosOperacao.Joystick && x.Mandatorio && GeneralJoystick.JoystickConectado == null)) _operacaoLiberada = false; if (_operacaoLiberada && !Variaveis.OperacaoEmAndamento.DispositivosIndividuaisConectados) _operacaoLiberada = false; if (frmInstancial.frmPrincipal.chbDebugMode.Checked) _operacaoLiberada = true; if (Variaveis.OperacaoEmAndamento.Emergencia) _operacaoLiberada = false; return _operacaoLiberada; } } public string ErroOperacaoLiberada { get { string MensagemErro = "Para iniciar a operação " + Enum.GetName(typeof(ModoOperacao), Modo) + ", é necessário que todos os módulos mandatórios estejam devidamente conectados ao equipamento, ou pelo menos um dos módulos:\r\n"; ModulosMandatorios.ForEach(Modulo => { MensagemErro += Enum.GetName(typeof(T_Code), Modulo.Dispositivo) + ": ( " + (Modulo.Conectado ? "OK" : " ") + " ) - Mandatório: " + (Modulo.Mandatorio ? "Sim" : "Não") + "\r\n"; }); return MensagemErro; } } public bool Iniciado { get; set; } public bool Simulando { get; set; } = false; public bool Finalizando { get; set; } = false; public long TimestampInicio { get; set; } public long TimestampFim { get; set; } public TimeSpan Tempo { get { return TimeSpan.FromTicks(Variaveis.OperacaoEmAndamento.Iniciado ? ((Variaveis.OperacaoEmAndamento.TimestampFim > 0 ? Variaveis.OperacaoEmAndamento.TimestampFim : DateTime.Now.Ticks) - Variaveis.OperacaoEmAndamento.TimestampInicio) : 0); } } public DateTime TempoAguardando { get; set; } public List ModulosMandatorios { get; set; } = new List(); public List ParametrosMandatorios { get; set; } = new List(); public List GPSTrajetoria { get; set; } = new List(); public List> GPSTrajetoriaRua { get; set; } = new List>(); public double CapacidadeReservatorio { get; set; } = 30; public int QuantidadeCamerasSolo { get; set; } = 2; public List CamerasSolo { get; set; } = new List(); public CameraCaminhoModel CameraCaminhoKinect { get; set; } public int TempoIniciarOperacao { get; set; } = 25; public string ID { get; set; } public double tmrLogsInterval { get { return tmrLogs.Interval; } set { tmrLogs.SetInterval((int)value); } } private static AsyncTaskTimerModel tmrLogs; private static AsyncTaskTimerModel tmrLeituras; public Chart chartGraficos = new Chart(); private static Computer computer; public string PerformanceStr { get { return FuncoesGlobais.MontarStringPerformance( Sensoriamento.GPU_load, Sensoriamento.CPU_load, Sensoriamento.RAM_usage, Sensoriamento.GPU_temp, Sensoriamento.CPU_temp ); } } #region PARAMETRIZACAO public bool SalvarParametrizacaoOperacao(string descricao, string capacidade, string pressao, string duracao, string percentual, string angulo, string velocidadeMp, int velocidadeServasPercent, int velocidadeCervasPercent, UltrasonicA05Configuracoes ConfigUltrassom, bool sonarAtivado) { if (string.IsNullOrEmpty(descricao)) { MessageBox.Show("Preencha a descrição para identificação da operação!", "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } double.TryParse(capacidade, out double capacidadeReservatorio); double.TryParse(pressao, out double pressaoLinha); int.TryParse(duracao, out int duracaoAtuacao); int.TryParse(percentual, out int percentualAtuacao); int.TryParse(angulo, out int anguloMaximo); int.TryParse(velocidadeMp, out int velocidadeMovimento); OperacaoParametrosModel Parametros = new OperacaoParametrosModel() { Modo = Variaveis.OperacaoEmAndamento.Modo, Descricao = descricao, AtuCapacidadeReservatorio = capacidadeReservatorio, AtuDuracaoAtuacao = duracaoAtuacao, AtuPercentualDeteccaoVertical = percentualAtuacao, AtuPressaoLinha = pressaoLinha, DirAnguloMaximo = anguloMaximo, DirVelocidadeMovimento = velocidadeMovimento, MovVelocidadeCErvasPercent = velocidadeCervasPercent, MovVelocidadeSErvasPercent = velocidadeServasPercent, ModulosMandatorios = Variaveis.OperacaoEmAndamento.ModulosMandatorios, Mapa = Variaveis.OperacaoEmAndamento.Mapa, ConfiguracaoUltrassom = ConfigUltrassom, SonarAtivado = sonarAtivado }; Parametros.Mapa.lblMapa = null; Parametros.Mapa.pnlMapa = null; Parametros.Mapa.chromiumWebBrowser = null; Parametros.Mapa.mapaService.pythonProcess = null; string ParametrosJson = JsonConvert.SerializeObject(Parametros, Formatting.None); SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = "Arquivo de Operação (*.opr)|*.opr"; saveFileDialog.DefaultExt = "opr"; saveFileDialog.AddExtension = true; saveFileDialog.InitialDirectory = Variaveis.CaminhoSistema + Variaveis.CaminhoOperacoes; saveFileDialog.FileName = descricao; if (saveFileDialog.ShowDialog() == DialogResult.OK) { string filePath = saveFileDialog.FileName; File.WriteAllText(filePath, ParametrosJson, Encoding.UTF8); MessageBox.Show("Operação salva com sucesso!", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); } return true; } public (bool, List) CarregarParametrizacaoOperacao(Panel pnlMapa, Label lblMapa, string opPath = "") { string path = Variaveis.CaminhoSistema + Variaveis.CaminhoOperacoes + MapasVariaveisModel.NomeArquivoMapaInterativoSaida; OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "Arquivo de Operação (*.opr)|*.opr"; openFileDialog.DefaultExt = "opr"; openFileDialog.AddExtension = true; openFileDialog.InitialDirectory = Variaveis.CaminhoSistema + Variaveis.CaminhoOperacoes; if (!string.IsNullOrEmpty(opPath) || openFileDialog.ShowDialog() == DialogResult.OK) { string filePath = !string.IsNullOrEmpty(opPath) ? opPath : openFileDialog.FileName; string ParametrosJson = File.ReadAllText(filePath, Encoding.UTF8); var Parametros = JsonConvert.DeserializeObject(ParametrosJson); CarregarParametrosOperacaoPadrao(Parametros.Modo); OperacaoControleModel controle = new OperacaoControleModel() { RPM_Max = (int)(VariaveisEquipamento.RPM_Max_Roda * (Parametros.MovVelocidadeSErvasPercent / 100.0)), RPM_Min = (int)(VariaveisEquipamento.RPM_Max_Roda * (Parametros.MovVelocidadeCErvasPercent / 100.0)), Angulo_Max = Parametros.DirAnguloMaximo, Angulo_Min = Parametros.DirAnguloMaximo * -1, VelocidadeMP = Parametros.DirVelocidadeMovimento, TempoAtuacao = Parametros.AtuDuracaoAtuacao, PercentualInicioPulverizacao = Parametros.AtuPercentualDeteccaoVertical / 100.0, PressaoLinha = Parametros.AtuPressaoLinha, Angulo = 0, Direcao = Direcao.Parado, PercentualVelocidadeSP = 0, PIDdirecional = new PIDModel(), TiposControle = Variaveis.OperacaoEmAndamento.Controle.TiposControle.ToList(), SonarAtivado = Parametros.SonarAtivado, }; Variaveis.OperacaoEmAndamento.ModulosMandatorios = Parametros.ModulosMandatorios.ToList(); Variaveis.OperacaoEmAndamento.CapacidadeReservatorio = Parametros.AtuCapacidadeReservatorio; Variaveis.OperacaoEmAndamento.Controle = controle; Variaveis.OperacaoEmAndamento.Descricao = Parametros.Descricao; if (Variaveis.OperacaoEmAndamento.DispSen == null) { Variaveis.OperacaoEmAndamento.DispSen = new DispositivosService(); } Variaveis.OperacaoEmAndamento.DispSen.Dados.ConfiguracaoSensorUltrassom = Parametros.ConfiguracaoUltrassom; List ruasSelecionadas = new List(); if (Parametros.Mapa.mapaService.DadosMapa != null) { ruasSelecionadas = Parametros.Mapa.RuasPercorrer.ToList(); string geoJson = JsonConvert.SerializeObject(Parametros.Mapa.mapaService.DadosMapa, Formatting.None); File.WriteAllText(path, geoJson, Encoding.UTF8); Variaveis.OperacaoEmAndamento.Mapa = Parametros.Mapa; /*Panel pnlMapa = FuncoesGlobais.FindControlRecursive(Variaveis.OperacaoEmAndamento.frmOperacao, "pnlMapa"); Label lblMapa = FuncoesGlobais.FindControlRecursive