agrobot_base/AgroBase/AgroBase/Forms/IHM/frmMenu.cs

410 lines
14 KiB
C#

using AgroBase.Forms.IHM.Controls;
using AgroBase.Models;
using AgroBase.Models.Components;
using AgroBase.Properties;
using AgroBase.Services;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using static AgroBase.Models.Enums;
namespace AgroBase.Forms.IHM
{
public partial class frmMenu : Form
{
private bool _sincronizando;
/// <summary>
/// Estes eventos deixam os atalhos de campo prontos para receber
/// a implementação real sem precisar alterar o componente visual.
/// </summary>
public event EventHandler AjustarLeverArmSolicitado;
public event EventHandler<TelaSolicitadaEventArgs> TelaSolicitada;
public frmMenu()
{
InitializeComponent();
VincularAcaoAsync(tileOperacao, "Erro ao carregar operação!", AbrirOperacaoAsync);
VincularAcaoAsync(tileModoManual, "Erro ao carregar modo de controle manual!", AbrirModoManualAsync);
VincularAcaoAsync(tileDiagnosticos, "Erro ao processar diagnósticos!", AbrirDiagnosticoAsync);
VincularAcaoAsync(tileAjustes, "Erro ao realizar ajustes!", AbrirAjustesAsync);
VincularAcaoAsync(tileTestes, "Erro ao processar testes!", AbrirTestesAsync);
VincularAcaoAsync(tileDesligar, "Erro ao desligar equipamento!", DesligarEquipamentoAsync);
VincularAcaoAsync(btnSincronizarArquivos, "Erro ao procurar por atualizações!", ProcurarAtualizacoesAsync);
VincularAcaoAsync(pnlAtualizacoes, "Erro ao procurar por atualizações!", ProcurarAtualizacoesAsync);
VincularCliqueRecursivo(
pnlAtualizacoes,
async delegate
{
await ExecutarAcaoSeguraAsync(
"Erro ao procurar por atualizações!",
ProcurarAtualizacoesAsync);
});
btnDebugMode.Click += BtnDebugMode_Click;
btnAjustarLeverArm.Click += BtnAjustarLeverArm_Click;
rowFalhas.Click += LblCodigoFalha_Click;
}
private void frmIHMMenu_Load(object sender, EventArgs e)
{
lblVersao.Text = "● IHM Rover • v " + Variaveis.Versao;
AtualizarControlesUI();
}
private void frmIHMMenu_FormClosed(object sender, FormClosedEventArgs e)
{
}
public void AtualizarControlesUI()
{
bool mqttConectado = Variaveis.MqttServiceLocal != null && Variaveis.MqttServiceLocal.StatusConexao();
bool iaConectada = VariaveisOperacao.Operadores != null && VariaveisOperacao.Operadores.Conectado;
var operacao = Variaveis.OperacaoEmAndamento;
bool operacaoLiberada = operacao?.Sensoriamento?.Operacao?.OperacaoLiberada == true;
string erroOperacao = operacao?.Sensoriamento?.Operacao?.ErroOperacaoLiberada;
bool existeFalha = !string.IsNullOrWhiteSpace(erroOperacao);
bool internetDisponivel = APIService.HasInternet;
bool baseConectada = VariaveisOperacao.PosicaoBase?.Inicializado ?? false;
btnDebugMode.Texto = Variaveis.DebugMode ? "Desligar Debug Mode" : "Ligar Debug Mode";
rowOperacaoLiberada.SetStatus(operacaoLiberada ? "Sim" : "Não", operacaoLiberada ? HmiTheme.Success : HmiTheme.Danger);
rowMqtt.SetStatus(mqttConectado ? "Conectado" : "Desconectado", mqttConectado ? HmiTheme.Success : HmiTheme.Danger);
rowIA.SetStatus(iaConectada ? "Conectada" : "Desconectada", iaConectada ? HmiTheme.Success : HmiTheme.Danger);
rowFalhas.SetStatus(existeFalha ? "Ver detalhes" : "Nenhuma", existeFalha ? HmiTheme.Warning : HmiTheme.Success);
tileOperacao.SetStatus(operacaoLiberada ? "Pronta para iniciar" : "Aguardando liberação", operacaoLiberada ? HmiTheme.Success : HmiTheme.Warning);
tileDiagnosticos.SetStatus(existeFalha ? "Existe uma falha ativa" : "Saúde geral normal", existeFalha ? HmiTheme.Warning : HmiTheme.Info);
tileDiagnosticos.AccentColor = existeFalha ? HmiTheme.Warning : HmiTheme.Info;
bool pronto = operacaoLiberada && mqttConectado && iaConectada;
lblRoverProntidao.Text = pronto ? "Pronto para operação" : "Aguardando condições";
lblRoverProntidao.ForeColor = pronto ? HmiTheme.Success : HmiTheme.Warning;
lblRoverDot.ForeColor = pronto ? HmiTheme.Success : HmiTheme.Warning;
lblConexaoFooter.Text = baseConectada ? "▮▮▮ Base conectada" : "▯▯▯ Base desconectada";
lblConexaoFooter.ForeColor = baseConectada ? HmiTheme.Success : HmiTheme.Danger;
picWifi.Image = internetDisponivel ? Resources.wifi_on : Resources.wifi_off;
lblStatus.Text = SerialService.LastUIMessage;
if (!_sincronizando)
{
lblAtualizacaoResumo.Text = internetDisponivel ? "Internet disponível" : "Sem internet";
lblAtualizacaoResumo.ForeColor = internetDisponivel ? HmiTheme.Success : HmiTheme.Danger;
if (pgbAtualizacaoArquivos.Value == 0)
{
lblProgressoAtualizacao.Text = internetDisponivel ? "Toque para sincronizar" : "Conecte o equipamento";
}
}
}
public void AtualizarProgressoSyncArquivos(string msg, double val)
{
BeginInvoke((MethodInvoker)(() =>
{
try
{
lblProgressoAtualizacao.Text = msg;
FuncoesGlobais.PreencheValorProgressBar(pgbAtualizacaoArquivos, val);
}
catch { }
}));
}
private Task AbrirAjustesAsync()
{
TelaSolicitada?.Invoke(this, new TelaSolicitadaEventArgs(TipoTelaIHM.Ajustes));
return Task.CompletedTask;
}
private Task AbrirDiagnosticoAsync()
{
TelaSolicitada?.Invoke(this, new TelaSolicitadaEventArgs(TipoTelaIHM.Diagnostico));
return Task.CompletedTask;
}
private Task AbrirOperacaoAsync()
{
TelaSolicitada?.Invoke(this, new TelaSolicitadaEventArgs(TipoTelaIHM.Operacao));
return Task.CompletedTask;
}
private Task AbrirTestesAsync()
{
TelaSolicitada?.Invoke(this, new TelaSolicitadaEventArgs(TipoTelaIHM.Testes));
return Task.CompletedTask;
}
private async Task AbrirModoManualAsync()
{
Variaveis.OperacaoEmAndamento = OperacaoModel.CarregarParametrosOperacaoPadrao(ModoOperacao.Manual, CarregarModulos: true);
var op = Variaveis.OperacaoEmAndamento;
bool operacaoLiberada = op?.Sensoriamento?.Operacao?.OperacaoLiberada == true;
if (operacaoLiberada)
{
var frm = new frmDialogoMapa();
frm.Show();
frm.InicializarModoManual();
}
else
{
string erro = op?.Sensoriamento?.Operacao?.ErroOperacaoLiberada ?? "Não foi possível liberar a operação manual.";
CustomDialog.ShowDialog(
"Iniciar Operação Manual",
erro ?? string.Empty,
MessageBoxIcon.Error,
new Dictionary<(string, dynamic), Action>()
{
{ ("OK", null), delegate { } }
});
}
await Task.CompletedTask;
}
private async Task DesligarEquipamentoAsync()
{
if (Variaveis.UsarIHM)
{
var resultado = CustomDialog.ShowDialog(
"Desligar",
"Deseja desligar o equipamento?",
MessageBoxIcon.Question,
new Dictionary<(string, DialogResult?), Action>()
{
{ ("Sim", DialogResult.Yes), delegate { } },
{ ("Não", DialogResult.No), delegate { } }
});
if (resultado == DialogResult.Yes)
{
frmInstancial.frmIHM.Close();
if (Variaveis.Producao)
Process.Start("shutdown", "/s /t 0");
}
}
else
{
Close();
}
await Task.CompletedTask;
}
private async Task ProcurarAtualizacoesAsync()
{
if (_sincronizando)
return;
if (!APIService.HasInternet)
{
CustomDialog.ShowDialog(
"Equipamento Desconectado",
"Impossível procurar por atualizações.",
MessageBoxIcon.Warning,
new Dictionary<(string, dynamic), Action>()
{
{ ("OK", null), delegate { } }
});
return;
}
_sincronizando = true;
lblAtualizacaoResumo.Text = "Sincronizando...";
lblAtualizacaoResumo.ForeColor = HmiTheme.Info;
lblProgressoAtualizacao.Text = "Procurando arquivos...";
btnSincronizarArquivos.Enabled = false;
try
{
await VersionamentoService.AtualizarArquivoVersionamento(true);
var arquivosNaoEncontrados =
VersionamentoService.ArquivosNaoEncontrados.ToList();
bool sucesso = !arquivosNaoEncontrados.Any();
lblAtualizacaoResumo.Text =
sucesso
? "Sem pendências"
: "Atualização incompleta";
lblAtualizacaoResumo.ForeColor =
sucesso
? HmiTheme.Success
: HmiTheme.Warning;
lblProgressoAtualizacao.Text =
sucesso
? "Sincronização concluída"
: "Verifique os arquivos pendentes";
CustomDialog.ShowDialog(
"Resultado",
"Atualização concluída com " +
(sucesso ? "sucesso" : "falha") +
"!\r\n\r\n" +
(!sucesso
? "Arquivos não encontrados:\r\n\r\n" +
string.Join("\r\n", arquivosNaoEncontrados)
: "Nenhum arquivo pendente!"),
sucesso
? MessageBoxIcon.Asterisk
: MessageBoxIcon.Error,
new Dictionary<(string, dynamic), Action>()
{
{ ("OK", null), delegate { } }
});
}
finally
{
_sincronizando = false;
btnSincronizarArquivos.Enabled = true;
AtualizarControlesUI();
}
}
private void BtnDebugMode_Click(object sender, EventArgs e)
{
Variaveis.DebugMode = !Variaveis.DebugMode;
btnDebugMode.Texto = Variaveis.DebugMode ? "Desligar Debug Mode" : "Ligar Debug Mode";
}
private void BtnAjustarLeverArm_Click(object sender, EventArgs e)
{
if (AjustarLeverArmSolicitado != null)
{
AjustarLeverArmSolicitado(this, EventArgs.Empty);
return;
}
ExibirAtalhoNaoVinculado(
"Ajustar Lever Arm",
"O layout já está pronto. Vincule a tela ou o diálogo no evento " +
"AjustarLeverArmSolicitado.");
}
private void LblCodigoFalha_Click(object sender, EventArgs e)
{
var operacao = Variaveis.OperacaoEmAndamento;
string descricaoFalha = operacao?.Sensoriamento?.Operacao?.ErroOperacaoLiberada;
if (string.IsNullOrWhiteSpace(descricaoFalha))
descricaoFalha = "Nenhuma falha ativa.";
CustomDialog.ShowDialog(
"Detalhes da Operação",
descricaoFalha,
MessageBoxIcon.Information,
new Dictionary<(string, dynamic), Action>()
{
{ ("OK", null), delegate { } }
});
}
private void ExibirAtalhoNaoVinculado(string titulo, string mensagem)
{
CustomDialog.ShowDialog(
titulo,
mensagem,
MessageBoxIcon.Information,
new Dictionary<(string, dynamic), Action>()
{
{ ("OK", null), delegate { } }
});
}
private void VincularAcaoAsync(Control control, string mensagemErro, Func<Task> acao)
{
control.Click += async delegate
{
await ExecutarAcaoSeguraAsync(
mensagemErro,
acao);
};
}
private async Task ExecutarAcaoSeguraAsync(string mensagemErro, Func<Task> acao)
{
try
{
await acao();
}
catch (Exception ex)
{
CustomDialog.ShowDialog(
"Erro",
mensagemErro + "\r\n\r\n" + ex.Message,
MessageBoxIcon.Error,
new Dictionary<(string, dynamic), Action>()
{
{ ("OK", null), delegate { } }
});
}
}
private void VincularCliqueRecursivo(Control control, Func<Task> acao)
{
foreach (Control filho in control.Controls)
{
filho.Cursor = Cursors.Hand;
filho.Click += async delegate
{
await acao();
};
if (filho.HasChildren)
VincularCliqueRecursivo(filho, acao);
}
}
}
public enum TipoTelaIHM
{
Menu,
Operacao,
Ajustes,
Diagnostico,
Testes
}
public class TelaSolicitadaEventArgs : EventArgs
{
public TipoTelaIHM Tela { get; private set; }
public TelaSolicitadaEventArgs(TipoTelaIHM tela)
{
Tela = tela;
}
}
}