410 lines
14 KiB
C#
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;
|
|
}
|
|
}
|
|
|
|
}
|