Separado componentes Monitoramento e Diagnostico

This commit is contained in:
Diego Freitas 2026-03-11 17:11:17 -03:00
parent c28d18257a
commit 59c1326d0a
20 changed files with 1475 additions and 1366 deletions

View File

@ -46,6 +46,12 @@
<Compile Update="Views\ConfigConexao\ConfigConexaoView.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Views\Operacao\DiagnosticoView.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Views\Operacao\MonitoramentoView.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Views\Operacao\OperacaoBottomView.xaml.cs">
<SubType>Code</SubType>
</Compile>
@ -117,6 +123,12 @@
<Page Update="Views\ConfigConexao\ConfigConexaoView.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Views\Operacao\DiagnosticoView.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Views\Operacao\MonitoramentoView.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Views\Operacao\OperacaoBottomView.xaml">
<SubType>Designer</SubType>
</Page>

View File

@ -5,6 +5,8 @@ using System.Windows.Input;
using System.Windows.Threading;
using OperationControl.Helpers;
using OperationControl.Models;
using Brush = System.Windows.Media.Brush;
using Brushes = System.Windows.Media.Brushes;
namespace OperationControl.ViewModels
{

View File

@ -80,8 +80,8 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
private string _bicoAnguloTexto = "00°";
public string BicoAnguloTexto { get => _bicoAnguloTexto; set => SetProperty(ref _bicoAnguloTexto, value); }
private string _bicoAnguloAbertura = "0";
public string BicoAnguloAbertura { get => _bicoAnguloAbertura; set => SetProperty(ref _bicoAnguloAbertura, value); }
private double _bicoAnguloAbertura = 0;
public double BicoAnguloAbertura { get => _bicoAnguloAbertura; set => SetProperty(ref _bicoAnguloAbertura, value); }
private string _txtBicoComando = "—";
public string TxtBicoComando { get => _txtBicoComando; set => SetProperty(ref _txtBicoComando, value); }
@ -138,14 +138,14 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
#region DIRECIONAL
public ObservableCollection<string> DirMovimentosDisponiveis { get; } = new();
public ObservableCollection<string> DirDirecoesDisponiveis { get; } = new();
public ObservableCollection<TipoMovimentoDirecional> DirMovimentosDisponiveis { get; } = new();
public ObservableCollection<Direcao> DirDirecoesDisponiveis { get; } = new();
private string _dirMovimentoSelecionado;
public string DirMovimentoSelecionado { get => _dirMovimentoSelecionado; set => SetProperty(ref _dirMovimentoSelecionado, value); }
private TipoMovimentoDirecional _dirMovimentoSelecionado;
public TipoMovimentoDirecional DirMovimentoSelecionado { get => _dirMovimentoSelecionado; set => SetProperty(ref _dirMovimentoSelecionado, value); }
private string _dirDirecaoSelecionada;
public string DirDirecaoSelecionada { get => _dirDirecaoSelecionada; set => SetProperty(ref _dirDirecaoSelecionada, value); }
private Direcao _dirDirecaoSelecionada;
public Direcao DirDirecaoSelecionada { get => _dirDirecaoSelecionada; set => SetProperty(ref _dirDirecaoSelecionada, value); }
private double _dirAngulo;
public double DirAngulo
@ -359,11 +359,11 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
private bool _npcCoolerSaida;
public bool NpcCoolerSaida { get => _npcCoolerSaida; set => SetProperty(ref _npcCoolerSaida, value); }
private string _npcCoolerTempOn = "0";
public string NpcCoolerTempOn { get => _npcCoolerTempOn; set => SetProperty(ref _npcCoolerTempOn, value); }
private double _npcCoolerTempOn = 0;
public double NpcCoolerTempOn { get => _npcCoolerTempOn; set => SetProperty(ref _npcCoolerTempOn, value); }
private string _npcCoolerTempTurbo = "0";
public string NpcCoolerTempTurbo { get => _npcCoolerTempTurbo; set => SetProperty(ref _npcCoolerTempTurbo, value); }
private double _npcCoolerTempTurbo = 0;
public double NpcCoolerTempTurbo { get => _npcCoolerTempTurbo; set => SetProperty(ref _npcCoolerTempTurbo, value); }
private string _txtNpcCoolerModo = "—";
public string TxtNpcCoolerModo { get => _txtNpcCoolerModo; set => SetProperty(ref _txtNpcCoolerModo, value); }
@ -409,11 +409,10 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
public DiagnosticoOpcoesViewModel()
{
foreach (var nome in Enum.GetNames(typeof(TipoMovimentoDirecional)))
DirMovimentosDisponiveis.Add(nome);
DirDirecoesDisponiveis = new ObservableCollection<Direcao>() { Direcao.Parado, Direcao.Esquerda, Direcao.Direita };
foreach (var nome in Enum.GetNames(typeof(Direcao)))
DirDirecoesDisponiveis.Add(nome);
foreach (var modo in Enum.GetValues<TipoMovimentoDirecional>())
DirMovimentosDisponiveis.Add(modo);
foreach (var modo in Enum.GetValues<CoolerMode>())
NpcCoolerModosDisponiveis.Add(modo);
@ -443,13 +442,16 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
NpcCoolerEnviarCommand = new RelayCommand(_ => NpcCoolerEnviar());
}
public void Atualizar(DiagnosticoModuloItemViewModel item, OperacaoParametrosModel dados)
public void Atualizar(DiagnosticoModuloItemViewModel item, OperacaoParametrosModel dados, bool clicado)
{
_itemAtual = item;
_dadosAtual = dados;
ResetarVisibilidades();
ResetarCampos();
if (clicado)
{
ResetarVisibilidades();
ResetarCampos();
}
if (_itemAtual == null || _dadosAtual?.DadosLeitura == null)
{
@ -466,22 +468,25 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
{
case S_Code.sMOD:
MostrarOpcoesAtuador = true;
BarraAltura = rover.Controle?.AlturaBarra ?? 0;
if (clicado)
{
BarraAltura = rover.Controle?.AlturaBarra ?? 0;
}
break;
case S_Code.sBIC:
MostrarOpcoesBico = true;
PreencherBico(rover);
PreencherBico(rover, clicado);
break;
case S_Code.sBMB:
MostrarOpcoesBomba = true;
PreencherBomba(rover);
PreencherBomba(rover, clicado);
break;
case S_Code.sSRV:
MostrarOpcoesServo = true;
PreencherServoAtuador(rover);
PreencherServoAtuador(rover, clicado);
break;
default:
@ -499,12 +504,12 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
case S_Code.sRLE:
MostrarOpcoesRele = true;
PreencherRele(rover);
PreencherRele(rover, clicado);
break;
case S_Code.sSRV:
MostrarOpcoesServo = true;
PreencherServoSensoriamento(rover);
PreencherServoSensoriamento(rover, clicado);
break;
default:
@ -515,22 +520,22 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
case T_Code.Dir:
MostrarOpcoesDirecional = true;
PreencherDirecional(rover);
PreencherDirecional(rover, clicado);
break;
case T_Code.Gps:
MostrarOpcoesGps = true;
PreencherGps(rover);
PreencherGps(rover, clicado);
break;
case T_Code.Trj:
MostrarOpcoesTrajetoria = true;
PreencherTrajetoria(rover);
PreencherTrajetoria(rover, clicado);
break;
case T_Code.Npc:
MostrarOpcoesNpc = true;
PreencherNpc(rover);
PreencherNpc(rover, clicado);
break;
default:
@ -541,7 +546,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
#region PREENCHIMENTO
private void PreencherBico(OperacaoParametrosDadosModel rover)
private void PreencherBico(OperacaoParametrosDadosModel rover, bool clicado)
{
var bico = rover?.Atuador?.Bicos?.FirstOrDefault(x => x.ID == _itemAtual.LabelModulo);
BicoTitulo = $"Bico {_itemAtual.LabelModulo} - Testes";
@ -551,11 +556,14 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
TxtBicoVazao = $"{bico?.VazaoInstantaneaMLs ?? 0:0.##} mL/s";
TxtBicoPressao = $"{rover?.Atuador?.PressaoLinhaPsi ?? 0:0.##} psi";
TxtBicoAtuacoes = $"{bico?.QtdAtuacoes ?? 0}";
BicoAngulo = bico?.ComandoAngulo ?? 0;
BicoAnguloAbertura = (bico?.AnguloAbertura ?? 0).ToString();
if (clicado)
{
BicoAngulo = bico?.ComandoAngulo ?? 0;
BicoAnguloAbertura = bico?.AnguloAbertura ?? 0;
}
}
private void PreencherBomba(OperacaoParametrosDadosModel rover)
private void PreencherBomba(OperacaoParametrosDadosModel rover, bool clicado)
{
var bomba = rover?.Atuador?.Bombas?.FirstOrDefault(x => x.ID == _itemAtual.LabelModulo);
BombaTitulo = $"Bomba {_itemAtual.LabelModulo} - Testes";
@ -563,10 +571,13 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
TxtBombaStatusReal = (bomba?.LeituraEstado ?? false) ? "Ligado" : "Desligado";
TxtBombaPressaoLinha = $"{rover?.Atuador?.PressaoLinhaPsi ?? 0:0.##} psi";
TxtBombaPotencia = $"{bomba?.Potencia ?? 0:0.#} %";
BombaPressaoAlvo = bomba?.Potencia ?? 0;
if (clicado)
{
BombaPressaoAlvo = bomba?.Potencia ?? 0;
}
}
private void PreencherDirecional(OperacaoParametrosDadosModel rover)
private void PreencherDirecional(OperacaoParametrosDadosModel rover, bool clicado)
{
var mod = rover?.Direcional?.Modulos?.FirstOrDefault(x => x.Mod_ID == _itemAtual.LabelModulo);
DirTitulo = $"Direcional {_itemAtual.LabelModulo} - Testes";
@ -574,23 +585,29 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
TxtDirSentido = $"{mod?.SentidoReal ?? Sentido.Parado}";
TxtDirAnguloSP = $"{mod?.Angulo_SP ?? 0:0.00}°";
TxtDirAngulo = $"{mod?.AnguloDriver ?? 0:0.00}°";
DirAngulo = mod?.Angulo_SP ?? 0;
if (clicado)
{
DirAngulo = mod?.Angulo_SP ?? 0;
}
}
private void PreencherGps(OperacaoParametrosDadosModel rover)
private void PreencherGps(OperacaoParametrosDadosModel rover, bool clicado)
{
var dados = rover?.Gnss;
GpsLeverArmLateral = (dados?.LeverArmLateral ?? 0) / 10.0;
GpsLeverArmFrontal = (dados?.LeverArmFrontal ?? 0) / 10.0;
TxtGpsCorrecao = $"{dados?.QualidadeFix ?? TiposCorrecaoGPS.SemCorrecao}";
TxtGpsIdade = $"{dados?.IdadeCorrecao ?? -1}";
TxtGpsPrecisao = $"{dados?.PrecisaoCm ?? -1}";
TxtGpsNSatelites = $"{dados?.NumeroSatelites ?? 0}";
TxtGpsDistBase = "0";
TxtGpsOrientacao = $"{dados?.OrientacaoReal ?? 0}";
if (clicado)
{
GpsLeverArmLateral = (dados?.LeverArmLateral ?? 0) / 10.0;
GpsLeverArmFrontal = (dados?.LeverArmFrontal ?? 0) / 10.0;
}
}
private void PreencherTrajetoria(OperacaoParametrosDadosModel rover)
private void PreencherTrajetoria(OperacaoParametrosDadosModel rover, bool clicado)
{
var dados = rover?.Trajetoria?.AutonomiaCorredor;
TxtTrajetoriaDistCorredor = $"{dados?.DistanciaCorredor_m ?? 0:0.00} m";
@ -600,11 +617,14 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
TxtTrajetoriaBatOk = (dados?.BateriaSuficiente ?? false) ? "Sim" : "Não";
TxtTrajetoriaHerbOk = (dados?.HerbicidaSuficiente ?? false) ? "Sim" : "Não";
TrajetoriaPodeConfirmar = !(dados?.Liberado ?? false);
TrajetoriaBatLiberada = true; // dados?.BateriaSuficiente ?? false;
TrajetoriaHerbLiberado = true; // dados?.HerbicidaSuficiente ?? false;
if (clicado)
{
TrajetoriaBatLiberada = dados?.BateriaSuficiente ?? false;
TrajetoriaHerbLiberado = dados?.HerbicidaSuficiente ?? false;
}
}
private void PreencherRele(OperacaoParametrosDadosModel rover)
private void PreencherRele(OperacaoParametrosDadosModel rover, bool clicado)
{
var rele = rover?.Sensoriamento?.Reles?.FirstOrDefault(x => x.ID == _itemAtual.LabelModulo);
ReleTitulo = $"Relé {_itemAtual.LabelModulo} - Testes";
@ -612,37 +632,45 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
TxtReleStatusReal = (rele?.LeituraEstado ?? false) ? "Ligado" : "Desligado";
}
private void PreencherServoSensoriamento(OperacaoParametrosDadosModel rover)
private void PreencherServoSensoriamento(OperacaoParametrosDadosModel rover, bool clicado)
{
var servo = rover?.Sensoriamento?.Servos?.FirstOrDefault(x => x.ID == _itemAtual.LabelModulo);
TxtServoComando = $"{servo?.ComandoAngulo ?? 0}°";
TxtServoLeitura = $"{servo?.LeituraAngulo ?? 0}°";
TxtServoIncremental = (servo?.Incremental ?? false) ? "Incremental" : "Decremental";
ServoAngulo = servo?.ComandoAngulo ?? 0;
if (clicado)
{
ServoAngulo = servo?.ComandoAngulo ?? 0;
}
}
private void PreencherServoAtuador(OperacaoParametrosDadosModel rover)
private void PreencherServoAtuador(OperacaoParametrosDadosModel rover, bool clicado)
{
var servo = rover?.Atuador?.Servos?.FirstOrDefault(x => x.ID == _itemAtual.LabelModulo);
TxtServoComando = $"{servo?.ComandoAngulo ?? 0}°";
TxtServoLeitura = $"{servo?.LeituraAngulo ?? 0}°";
TxtServoIncremental = (servo?.Incremental ?? false) ? "Incremental" : "Decremental";
ServoAngulo = servo?.ComandoAngulo ?? 0;
if (clicado)
{
ServoAngulo = servo?.ComandoAngulo ?? 0;
}
}
private void PreencherNpc(OperacaoParametrosDadosModel rover)
private void PreencherNpc(OperacaoParametrosDadosModel rover, bool clicado)
{
var dados = rover?.Refrigeracao;
TxtNpcCoolerModo = $"{dados?.Modo}";
TxtNpcCoolerTemperatura = $"{dados?.Temperatura ?? 0:0.00} °C";
TxtNpcCoolerEntrada = $"{dados?.EstadoEntrada} ({dados?.LeituraEntrada})";
TxtNpcCoolerSaida = $"{dados?.EstadoSaida} ({dados?.LeituraSaida})";
NpcCoolerModoSelecionado = dados?.Modo ?? CoolerMode.Off;
NpcCoolerEntrada = (dados?.EstadoEntrada ?? Estado.Desligado) == Estado.Ligado;
NpcCoolerSaida = (dados?.EstadoSaida ?? Estado.Desligado) == Estado.Ligado;
NpcCoolerTempOn = $"{dados?.TemperaturaLigar ?? 0}";
NpcCoolerTempTurbo = $"{dados?.TemperaturaTurbo ?? 0}";
if (clicado)
{
NpcCoolerModoSelecionado = dados?.Modo ?? CoolerMode.Off;
NpcCoolerEntrada = (dados?.EstadoEntrada ?? Estado.Desligado) == Estado.Ligado;
NpcCoolerSaida = (dados?.EstadoSaida ?? Estado.Desligado) == Estado.Ligado;
NpcCoolerTempOn = dados?.TemperaturaLigar ?? 0;
NpcCoolerTempTurbo = dados?.TemperaturaTurbo ?? 0;
}
}
#endregion
@ -668,7 +696,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
{
BarraAltura = 0;
BicoAngulo = 0;
BicoAnguloAbertura = "0";
BicoAnguloAbertura = 0;
BombaPressaoAlvo = 0;
DirAngulo = 0;
GpsLeverArmLateral = 0;
@ -678,8 +706,8 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
ServoAngulo = 0;
NpcCoolerEntrada = false;
NpcCoolerSaida = false;
NpcCoolerTempOn = "0";
NpcCoolerTempTurbo = "0";
NpcCoolerTempOn = 0;
NpcCoolerTempTurbo = 0;
}
#endregion
@ -689,13 +717,19 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
private void SensoriamentoReiniciar()
{
if (_itemAtual?.Modulo != T_Code.Sen) return;
VariaveisControleOperacao.EnviarComandoSensoriamento(_itemAtual.LabelModulo, true);
if (MessageBox.Show("Tem certeza que deseja reiniciar o módulo Sensoriamento?", "Reiniciar Módulo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
VariaveisControleOperacao.EnviarComandoSensoriamento(_itemAtual.LabelModulo, true);
}
}
private void AtuadorReiniciar()
{
if (_itemAtual?.Modulo != T_Code.Atu) return;
VariaveisControleOperacao.EnviarComandoAtuador(_itemAtual.LabelModulo, true);
if (MessageBox.Show("Tem certeza que deseja reiniciar o módulo Atuador?", "Reiniciar Módulo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
VariaveisControleOperacao.EnviarComandoAtuador(_itemAtual.LabelModulo, true);
}
}
private void BarraMover()
@ -725,8 +759,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
private void BicoSalvarAnguloAbertura()
{
if (_itemAtual?.Modulo != T_Code.Atu || _itemAtual.SCode != S_Code.sBIC) return;
if (!int.TryParse(BicoAnguloAbertura, out int ang)) return;
VariaveisControleOperacao.EnviarComandoAtuador(_itemAtual.LabelModulo, angulo_abertura: ang);
VariaveisControleOperacao.EnviarComandoAtuador(_itemAtual.LabelModulo, angulo_abertura: BicoAnguloAbertura);
}
private void BombaLigar()
@ -744,36 +777,35 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
private void DirReferenciar()
{
if (_itemAtual?.Modulo != T_Code.Dir) return;
VariaveisControleOperacao.EnviarComandoReferenciamento(mod_id: _itemAtual.LabelModulo);
if (MessageBox.Show("Tem certeza que deseja realizar o referenciamento?", "Referenciar", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
VariaveisControleOperacao.EnviarComandoReferenciamento(mod_id: _itemAtual.LabelModulo);
}
}
private void DirMovimentar()
{
if (_itemAtual?.Modulo != T_Code.Dir) return;
if (string.IsNullOrWhiteSpace(DirMovimentoSelecionado) || string.IsNullOrWhiteSpace(DirDirecaoSelecionada)) return;
var tipo = (TipoMovimentoDirecional)Enum.Parse(typeof(TipoMovimentoDirecional), DirMovimentoSelecionado);
var direcao = (Direcao)Enum.Parse(typeof(Direcao), DirDirecaoSelecionada);
VariaveisControleOperacao.EnviarComandoDirecional(direcao, Convert.ToInt32(DirAngulo), tipo, mod_id: _itemAtual.LabelModulo);
VariaveisControleOperacao.EnviarComandoDirecional(DirDirecaoSelecionada, DirAngulo, DirMovimentoSelecionado, mod_id: _itemAtual.LabelModulo);
}
private void GpsSalvar()
{
VariaveisControleOperacao.EnviarComandoLeverArm(
lateral: GpsLeverArmLateral * 10.0,
frontal: GpsLeverArmFrontal * 10.0);
if (MessageBox.Show("Tem certeza que deseja redefinir o lever arm do GNSS?", "Lever Arm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
VariaveisControleOperacao.EnviarComandoLeverArm(lateral: GpsLeverArmLateral * 10.0, frontal: GpsLeverArmFrontal * 10.0);
}
}
private void TrajetoriaConfirmar()
{
if (_itemAtual?.Modulo != T_Code.Trj) return;
var trj = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Trajetoria;
int idxCorredor = trj?.PontoAtualIdxCorredor ?? 0;
VariaveisControleOperacao.EnviarConfirmacaoHumanaTrajetoria(
idxCorredor,
TrajetoriaBatLiberada,
TrajetoriaHerbLiberado);
if (MessageBox.Show($"Tem certeza que deseja liberar a operação no corredor {idxCorredor + 1}?", "Liberação", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
VariaveisControleOperacao.EnviarConfirmacaoHumanaTrajetoria(idxCorredor, TrajetoriaBatLiberada, TrajetoriaHerbLiberado);
}
}
private void ReleLigar()
@ -816,15 +848,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
var entrada = NpcCoolerEntrada ? Estado.Ligado : Estado.Desligado;
var saida = NpcCoolerSaida ? Estado.Ligado : Estado.Desligado;
double.TryParse(NpcCoolerTempOn, out double tempOn);
double.TryParse(NpcCoolerTempTurbo, out double tempTurbo);
VariaveisControleOperacao.EnviarComandoCoolerControl(
modo,
entrada: entrada,
saida: saida,
temp_on: tempOn,
temp_turbo: tempTurbo);
VariaveisControleOperacao.EnviarComandoCoolerControl(modo, entrada: entrada, saida: saida, temp_on: NpcCoolerTempOn, temp_turbo: NpcCoolerTempTurbo);
}
#endregion

View File

@ -36,7 +36,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
_moduloSelecionado.Selecionado = true;
OnPropertyChanged();
AtualizarResumoModuloSelecionado();
AtualizarResumoModuloSelecionado(true);
}
}
@ -173,8 +173,22 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
ModuloSelecionado = item;
}
#region RESUMO
public void AbrirModuloPorAlerta(T_Code modulo, string? modId)
{
ModuloSelecionado = DiagnosticoModulos.FirstOrDefault(x => x.Modulo == modulo && x.LabelModulo == modId);
if (ModuloSelecionado == null)
ModuloSelecionado = DiagnosticoModulos.FirstOrDefault(x => x.Modulo == modulo && x.SCode == S_Code.sMOD);
if (ModuloSelecionado == null)
ModuloSelecionado = DiagnosticoModulos.FirstOrDefault(x => x.Modulo == modulo);
}
#region RESUMO
private string _impedimentoOperacaoTexto = "Impedimento: Nenhum";
public string ImpedimentoOperacaoTexto
{
get => _impedimentoOperacaoTexto;
set => SetProperty(ref _impedimentoOperacaoTexto, value);
}
private string _tituloModuloSelecionado = "Nenhum módulo selecionado";
public string TituloModuloSelecionado
{
@ -292,11 +306,17 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
set => SetProperty(ref _infoIdVisual, value);
}
private void AtualizarResumoModuloSelecionado()
private void AtualizarResumoModuloSelecionado(bool clicado)
{
CondicoesOperacionais.Clear();
LogsModuloSelecionado.Clear();
var impedimento = _dadosOperacaoAtual?.DadosLeitura?.Operacao?.ImpedimentoErro;
if (string.IsNullOrWhiteSpace(impedimento))
ImpedimentoOperacaoTexto = "Impedimento: Nenhum";
else
ImpedimentoOperacaoTexto = $"Impedimento: " + impedimento.Replace("\r\n", "\n").Replace("\n\n", "; ").Replace("\n", "; ").Trim();
if (ModuloSelecionado == null || _dadosOperacaoAtual == null)
{
TituloModuloSelecionado = "Nenhum módulo selecionado";
@ -360,8 +380,11 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
InfoLatencia = $"Latência: {dispositivo?.Latencia ?? 0} ms";
ImpedimentoModuloSelecionado = $"Impedimento: {(string.IsNullOrWhiteSpace(motivos) ? "Nenhum" : motivos)}";
MandatorioSelecionado = item.Mandatorio;
EmUsoSelecionado = item.EmUso;
if (clicado)
{
MandatorioSelecionado = item.Mandatorio;
EmUsoSelecionado = item.EmUso;
}
if (saudeModulo?.condicoes_operacionais != null)
{
@ -381,7 +404,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
LogsModuloSelecionado.Add($"{log.Momento:HH:mm:ss.fff} - {log.Mensagem}");
}
OpcoesVM?.Atualizar(ModuloSelecionado, _dadosOperacaoAtual);
OpcoesVM?.Atualizar(ModuloSelecionado, _dadosOperacaoAtual, clicado);
AtualizarGraficoModuloSelecionado();
}
@ -400,7 +423,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
item.Iniciado = ObterIniciado(item, dados);
}
AtualizarResumoModuloSelecionado();
AtualizarResumoModuloSelecionado(false);
}
private StatusModulo ObterStatusModulo(DiagnosticoModuloItemViewModel item, OperacaoParametrosModel dados)
@ -581,7 +604,7 @@ namespace OperationControl.ViewModels.Views.Operacao.Diagnostico
ModuloSelecionado.Mandatorio = MandatorioSelecionado;
ModuloSelecionado.EmUso = EmUsoSelecionado;
AtualizarResumoModuloSelecionado();
AtualizarResumoModuloSelecionado(true);
}

View File

@ -0,0 +1,13 @@
using OperationControl.ViewModels.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OperationControl.ViewModels.Views.Operacao.Monitoramento
{
public class MonitoramentoViewModel : NotifyBase
{
}
}

View File

@ -3,23 +3,38 @@ using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Threading;
using static AgroBase.Models.Enums;
using Application = System.Windows.Application;
namespace OperationControl.ViewModels.Views.Operacao
{
public class OperacaoBottomViewModel : INotifyPropertyChanged
{
public ObservableCollection<AlertaModel> AlertasAtivos { get; } = new();
private AlertaModel _toastAlerta;
private AlertaModel _alertaSelecionado;
public AlertaModel ToastAlerta
{
get => _toastAlerta;
set
{
if (_toastAlerta == value) return;
_toastAlerta = value;
OnPropertyChanged(nameof(ToastAlerta));
}
}
private readonly DispatcherTimer _toastTimer;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
// EVENTO PARA O PAI TRATAR A NAVEGAÇÃO
public event Action<AlertaModel> SolicitarAbrirDiagnostico;
public OperacaoBottomViewModel()
{
AlertasAtivos = new ObservableCollection<AlertaModel>();
_toastTimer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(5)
Interval = TimeSpan.FromSeconds(6)
};
_toastTimer.Tick += (s, e) =>
@ -29,115 +44,17 @@ namespace OperationControl.ViewModels.Views.Operacao
};
}
public ObservableCollection<AlertaModel> AlertasAtivos { get; }
public AlertaModel ToastAlerta
{
get => _toastAlerta;
set
{
if (_toastAlerta != value)
{
_toastAlerta = value;
OnPropertyChanged(nameof(ToastAlerta));
}
}
}
public AlertaModel AlertaSelecionado
{
get => _alertaSelecionado;
set
{
if (_alertaSelecionado != value)
{
_alertaSelecionado = value;
OnPropertyChanged(nameof(AlertaSelecionado));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public event Action<AlertaModel> AlertaSelecionadoChanged;
public void SelecionarAlerta(AlertaModel alerta)
{
if (alerta == null) return;
AlertaSelecionado = alerta;
AlertaSelecionadoChanged?.Invoke(alerta);
SolicitarAbrirDiagnostico?.Invoke(alerta);
}
public void AdicionarAlerta(string roverId, T_Code modulo, SeveridadeAlerta severidade, string mensagem, string modId = null)
public void LimparToast()
{
if (!Application.Current.Dispatcher.CheckAccess())
{
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
AdicionarAlerta(roverId, modulo, severidade, mensagem, modId)));
return;
}
var existente = AlertasAtivos.FirstOrDefault(x =>
x.Rover_ID == roverId &&
x.Modulo == modulo &&
x.Mod_ID == modId);
if (existente == null)
{
var alerta = new AlertaModel
{
Rover_ID = roverId,
Modulo = modulo,
Mod_ID = modId,
Severidade = severidade,
Mensagem = mensagem,
Timestamp = DateTime.Now
};
AlertasAtivos.Insert(0, alerta);
MostrarToast(alerta);
}
else
{
existente.Mensagem = mensagem;
existente.Severidade = severidade;
existente.Timestamp = DateTime.Now;
// caso o model nao implemente INotifyPropertyChanged,
// forçamos um refresh simples:
RecarregarAlerta(existente);
}
OnPropertyChanged(nameof(AlertasAtivos));
}
public void RemoverAlerta(string roverId, T_Code modulo, SeveridadeAlerta? severidade = null, string modId = null)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
RemoverAlerta(roverId, modulo, severidade, modId)));
return;
}
var alerta = AlertasAtivos.FirstOrDefault(x =>
x.Rover_ID == roverId &&
x.Modulo == modulo &&
x.Mod_ID == modId &&
(severidade != null ? x.Severidade == severidade : true));
if (alerta != null)
{
AlertasAtivos.Remove(alerta);
if (ReferenceEquals(ToastAlerta, alerta))
ToastAlerta = null;
if (ReferenceEquals(AlertaSelecionado, alerta))
AlertaSelecionado = null;
}
OnPropertyChanged(nameof(AlertasAtivos));
_toastTimer.Stop();
ToastAlerta = null;
}
public void MostrarToast(AlertaModel alerta)
@ -147,47 +64,67 @@ namespace OperationControl.ViewModels.Views.Operacao
_toastTimer.Start();
}
public void LimparToast()
public void AdicionarAlerta(string roverId, AgroBase.Models.Enums.T_Code modulo, SeveridadeAlerta severidade, string mensagem, string? modId = null)
{
_toastTimer.Stop();
ToastAlerta = null;
}
public void DefinirAlertas(params AlertaModel[] alertas)
{
if (!Application.Current.Dispatcher.CheckAccess())
App.Current.Dispatcher.BeginInvoke(new Action(() =>
{
Application.Current.Dispatcher.BeginInvoke(new Action(() => DefinirAlertas(alertas)));
return;
}
var existente = AlertasAtivos.FirstOrDefault(x =>
x.Rover_ID == roverId &&
x.Modulo == modulo &&
x.Mod_ID == modId);
AlertasAtivos.Clear();
if (existente == null)
{
var alerta = new AlertaModel
{
Rover_ID = roverId,
Modulo = modulo,
Mod_ID = modId,
Severidade = severidade,
Mensagem = mensagem,
Timestamp = DateTime.Now
};
if (alertas != null)
{
foreach (var alerta in alertas)
AlertasAtivos.Add(alerta);
}
OnPropertyChanged(nameof(AlertasAtivos));
MostrarToast(alerta);
}
else
{
existente.Mensagem = mensagem;
existente.Severidade = severidade;
}
}));
}
private void RecarregarAlerta(AlertaModel alerta)
public void RemoverAlerta(string roverId, AgroBase.Models.Enums.T_Code modulo, SeveridadeAlerta? severidade = null, string? modId = null)
{
var idx = AlertasAtivos.IndexOf(alerta);
if (idx >= 0)
App.Current.Dispatcher.BeginInvoke(new Action(() =>
{
AlertasAtivos.RemoveAt(idx);
AlertasAtivos.Insert(idx, alerta);
}
var alerta = AlertasAtivos.FirstOrDefault(x =>
x.Rover_ID == roverId &&
x.Modulo == modulo &&
x.Mod_ID == modId &&
(severidade != null ? x.Severidade == severidade : true));
if (alerta != null)
AlertasAtivos.Remove(alerta);
}));
}
private void OnPropertyChanged(string nome)
public void ClicarNoAlerta(AlertaModel alerta)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
if (alerta == null) return;
SelecionarAlerta(alerta);
}
public void ClicarNoToast()
{
var alerta = ToastAlerta;
if (alerta == null) return;
LimparToast();
SelecionarAlerta(alerta);
}
public void AtualizarListaAlertasRoverSelecionado(string rover_id)
{
@ -244,6 +181,6 @@ namespace OperationControl.ViewModels.Views.Operacao
}
}
}
}
}

View File

@ -1,14 +1,11 @@
using OperationControl.Controls;
using OperationControl.Models;
using OperationControl.ViewModels.Views.Operacao.Diagnostico;
using System.ComponentModel;
namespace OperationControl.ViewModels.Views.Operacao
{
public class OperacaoCenterViewModel : INotifyPropertyChanged
{
public DiagnosticoViewModel DiagnosticoVM { get; set; } = new DiagnosticoViewModel();
public OperacaoCenterViewModel()
{

View File

@ -24,7 +24,7 @@ namespace OperationControl.ViewModels.Views.Operacao
Rovers = new ObservableCollection<RoverCardModel>();
ToggleCollapseCommand = new RelayCommand(_ => ToggleCollapse());
SelecionarRoverCommand = new RelayCommand(p => SelecionarRover(p as RoverCardModel));
SelecionarRoverCommand = new RelayCommand(p => SelecionarRover((p as RoverCardModel).NumeroSerie));
SelecionarSecaoCommand = new RelayCommand(p =>
{
if (p is SecaoRightBar secao)
@ -133,8 +133,9 @@ namespace OperationControl.ViewModels.Views.Operacao
IsCollapsed = !IsCollapsed;
}
public void SelecionarRover(RoverCardModel rover)
public void SelecionarRover(string roverId)
{
var rover = Rovers.FirstOrDefault(x => x.NumeroSerie == roverId);
RoverSelecionado = rover;
if (RoverSelecionado != null)

View File

@ -8,6 +8,7 @@ using OperationControl.Views.Operacao;
using AgroBase.Models.Operacoes;
using Newtonsoft.Json.Linq;
using OperationControl.ViewModels.Views.Operacao;
using OperationControl.Controls;
namespace OperationControl.ViewModels
{
@ -25,6 +26,8 @@ namespace OperationControl.ViewModels
public readonly OperacaoRightView _viewOperacaoRight;
public readonly OperacaoBottomView _viewOperacaoBottom;
public OperacaoBottomViewModel BottomVM => _viewOperacaoBottom?._vm;
private DockStep _currentStep;
public DockWindowViewModel()
@ -56,7 +59,7 @@ namespace OperationControl.ViewModels
_viewOperacaoRight._vm.SalvarParametrosSolicitado += OnSalvarParametrosSolicitado;
_viewOperacaoBottom = new OperacaoBottomView();
_viewOperacaoBottom._vm.AlertaSelecionadoChanged += OnAlertaSelecionadoChanged;
_viewOperacaoBottom._vm.SolicitarAbrirDiagnostico += AbrirDiagnosticoPeloAlerta;
// Commands
BackCommand = new RelayCommand(_ => GoBack(), _ => CanGoBack);
@ -331,6 +334,7 @@ namespace OperationControl.ViewModels
CenterContent = _viewPreparacaoMapa;
BottomContent = _viewPreparacaoMapaBottom;
RightContent = CriarBotaoNextSimples();
CriarMarcadorBase(_viewPreparacaoMapa?.MapaPreparacao);
break;
case DockStep.ParametrizacaoRover:
@ -339,6 +343,7 @@ namespace OperationControl.ViewModels
CenterContent = _viewOperacaoCenter;
RightContent = _viewOperacaoRight;
BottomContent = _viewOperacaoBottom;
CriarMarcadorBase(_viewOperacaoCenter?.MapaOperacao);
if (!string.IsNullOrWhiteSpace(_ultimoMapaCarregado))
_viewOperacaoCenter?.MapaOperacao?.LoadMapFile(_ultimoMapaCarregado);
@ -391,12 +396,28 @@ namespace OperationControl.ViewModels
private string? _ultimoMapaCarregado;
private void CriarMarcadorBase(MapViewControl Mapa)
{
string markerId = VariaveisControleOperacao.BaseMarkerID;
if (!Mapa?.markers?.Added(markerId) ?? false)
{
Mapa?.markers?.AddMarker(
markerId,
true,
lat: Variaveis.GpsService?.UltimaLeitura?.Latitude,
lon: Variaveis.GpsService?.UltimaLeitura?.Longitude,
heading: Variaveis.GpsService?.UltimaLeitura?.OrientacaoReal,
label: "Base"
);
}
}
private void OnCarregarMapaSolicitado(string caminhoArquivo)
{
try
{
_ultimoMapaCarregado = caminhoArquivo;
_viewPreparacaoMapa?.MapControl?.LoadMapFile(caminhoArquivo);
_viewPreparacaoMapa?.MapaPreparacao?.LoadMapFile(caminhoArquivo);
MapaCarregado = true;
_viewPreparacaoMapaBottom?._vm.AtualizarProgresso(0, $"Mapa carregado: {System.IO.Path.GetFileName(caminhoArquivo)}");
}
@ -516,26 +537,24 @@ namespace OperationControl.ViewModels
}
private void OnAlertaSelecionadoChanged(AlertaModel alerta)
private void AbrirDiagnosticoPeloAlerta(AlertaModel alerta)
{
if (alerta == null) return;
if (alerta == null)
return;
AtualizarTopOperacaoAlerta(
$"ALERTA {alerta.Rover_ID}",
$"{alerta.Titulo}: {alerta.Mensagem}"
);
// depois você pode navegar para diagnostico, abrir popup, focar modulo, etc
_viewOperacaoRight?._vm?.SelecionarRover(alerta.Rover_ID);
_viewOperacaoRight?._vm?.SelecionarSecao(SecaoRightBar.Diagnostico);
_viewOperacaoCenter?.Diagnostico?._vm?.AbrirModuloPorAlerta(alerta.Modulo, alerta.Mod_ID);
}
public void AdicionarAlerta(string roverId, AgroBase.Models.Enums.T_Code modulo, SeveridadeAlerta severidade, string mensagem, string modId = null)
{
(_viewOperacaoBottom.DataContext as OperacaoBottomViewModel)?.AdicionarAlerta(roverId, modulo, severidade, mensagem, modId);
_viewOperacaoBottom?._vm?.AdicionarAlerta(roverId, modulo, severidade, mensagem, modId);
}
public void RemoverAlerta(string roverId, AgroBase.Models.Enums.T_Code modulo, SeveridadeAlerta? severidade = null, string modId = null)
{
(_viewOperacaoBottom.DataContext as OperacaoBottomViewModel)?.RemoverAlerta(roverId, modulo, severidade, modId);
_viewOperacaoBottom?._vm?.RemoverAlerta(roverId, modulo, severidade, modId);
}
@ -640,8 +659,8 @@ namespace OperationControl.ViewModels
r.InfestacaoPercentual = obj.Atuador?.PercentualErvasTerreno ?? 0;
});
_viewOperacaoCenter?._vm?.DiagnosticoVM?.AtualizarDados(rover);
_viewOperacaoCenter?.AtualizarGraficoDiagnostico(_viewOperacaoCenter?._vm?.DiagnosticoVM);
_viewOperacaoCenter?.Diagnostico?._vm?.AtualizarDados(rover);
_viewOperacaoCenter?.Diagnostico?.AtualizarGraficos();
}
}
@ -657,8 +676,8 @@ namespace OperationControl.ViewModels
{
if (!VariaveisControleOperacao.BaseEmFoco)
{
_viewOperacaoCenter?.PararStreamCameraFrontal();
_viewOperacaoCenter?.PararStreamCameraErvas();
_viewOperacaoCenter?.Monitoramento?.PararStreamCameraFrontal();
_viewOperacaoCenter?.Monitoramento?.PararStreamCameraErvas();
VariaveisControleOperacao.EnviarComandoIniciarUDP(VariaveisControleOperacao.RoverEmFoco?.IP, false);
}
VariaveisControleOperacao.RoverEmFoco?.RuasPercorrer?.Clear();
@ -678,8 +697,8 @@ namespace OperationControl.ViewModels
AtualizarDadosTela(VariaveisControleOperacao.RoverEmFoco);
VariaveisControleOperacao.RequisitarParametrosOperacao();
_viewOperacaoCenter?.IniciarStreamCameraFrontal();
_viewOperacaoCenter?.IniciarStreamCameraErvas();
_viewOperacaoCenter?.Monitoramento?.IniciarStreamCameraFrontal();
_viewOperacaoCenter?.Monitoramento?.IniciarStreamCameraErvas();
VariaveisControleOperacao.EnviarComandoIniciarUDP(VariaveisControleOperacao.RoverEmFoco?.IP, true);
_viewOperacaoCenter?._vm?.SelecionarRoverLista(rover);

View File

@ -0,0 +1,678 @@
<UserControl x:Class="OperationControl.Views.Operacao.DiagnosticoView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OperationControl.Views.Operacao"
xmlns:scott="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
mc:Ignorable="d"
d:DesignHeight="900"
d:DesignWidth="1600">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
<Style x:Key="DiagnosticoModuloButtonStyle" TargetType="Button">
<Setter Property="Width" Value="58"/>
<Setter Property="Height" Value="24"/>
<Setter Property="FontSize" Value="10"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Padding" Value="4,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="10"
SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Bd" Property="Opacity" Value="0.92"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Bd" Property="Opacity" Value="0.82"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Bd" Property="Opacity" Value="0.45"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid Margin="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1.55*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<!-- COLUNA ESQUERDA | MAPA VISUAL DO ROBÔ -->
<Border Grid.Column="0"
Margin="0,0,10,0"
Padding="16"
CornerRadius="10"
Background="#202020"
BorderBrush="#353535"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- CABEÇALHO -->
<StackPanel Grid.Row="0" Margin="0,0,0,12">
<TextBlock Text="Diagnóstico do rover"
FontSize="18"
FontWeight="SemiBold"
Foreground="#E6E6E6"/>
<TextBlock Text="{Binding ImpedimentoOperacaoTexto}"
Margin="0,6,0,0"
FontSize="12"
Foreground="#B8B8B8"
TextWrapping="Wrap"/>
</StackPanel>
<!-- ÁREA DO ROBÔ -->
<Viewbox Grid.Row="1" Stretch="Uniform">
<Grid Width="700" Height="820">
<Border CornerRadius="12"
Background="#1A1A1A"
BorderBrush="#2F2F2F"
BorderThickness="1"/>
<Image Source="/Resources/robo_superior.jpg"
Width="800"
Height="750"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<ItemsControl ItemsSource="{Binding DiagnosticoModulos}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Left}" />
<Setter Property="Canvas.Top" Value="{Binding Top}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding TextoExibicao}"
Style="{StaticResource DiagnosticoModuloButtonStyle}"
Background="{Binding BackgroundBrush}"
Foreground="{Binding ForegroundBrush}"
BorderBrush="{Binding BorderBrushColor}"
BorderThickness="{Binding BorderThicknessValue}"
Command="{Binding DataContext.SelecionarModuloCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
CommandParameter="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Viewbox>
</Grid>
</Border>
<!-- COLUNA DIREITA | DETALHES -->
<Border Grid.Column="1"
Margin="10,0,0,0"
Padding="16"
CornerRadius="10"
Background="#202020"
BorderBrush="#353535"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- TÍTULO -->
<StackPanel Grid.Row="0">
<TextBlock Text="{Binding TituloModuloSelecionado}"
FontSize="18"
FontWeight="SemiBold"
Foreground="#E6E6E6"/>
<TextBlock Text="{Binding DescricaoModuloSelecionado}"
Margin="0,6,0,0"
FontSize="12"
Foreground="#A8A8A8"
TextWrapping="Wrap"/>
</StackPanel>
<!-- RESUMO -->
<Border Grid.Row="1"
Margin="0,14,0,12"
Padding="12"
Background="#181818"
BorderBrush="#2F2F2F"
BorderThickness="1"
CornerRadius="8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<WrapPanel Grid.Row="0" Margin="0,0,0,8">
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding InfoModulo}" Foreground="#D8D8D8" FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding InfoLabel}" Foreground="#D8D8D8" FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding InfoSCode}" Foreground="#D8D8D8" FontSize="12"/>
</Border>
</WrapPanel>
<WrapPanel Grid.Row="1" Margin="0,0,0,8">
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding InfoStatus}" Foreground="#D8D8D8" FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding InfoSaude}" Foreground="#D8D8D8" FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding InfoIniciado}" Foreground="#D8D8D8" FontSize="12"/>
</Border>
</WrapPanel>
<WrapPanel Grid.Row="2" Margin="0,0,0,8">
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding InfoCan}" Foreground="#D8D8D8" FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding InfoLatencia}" Foreground="#D8D8D8" FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding InfoIdVisual}" Foreground="#D8D8D8" FontSize="12"/>
</Border>
</WrapPanel>
<TextBlock Grid.Row="3"
Text="{Binding ImpedimentoModuloSelecionado}"
Foreground="#C8C8C8"
FontSize="12"
TextWrapping="Wrap"/>
</Grid>
</Border>
<!-- AÇÕES -->
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,0,0,12">
<CheckBox Content="Mandatório"
Margin="0,0,14,0"
Foreground="#D8D8D8"
VerticalAlignment="Center"
IsChecked="{Binding MandatorioSelecionado, Mode=TwoWay}"/>
<CheckBox Content="Em uso"
Margin="0,0,14,0"
Foreground="#D8D8D8"
VerticalAlignment="Center"
IsChecked="{Binding EmUsoSelecionado, Mode=TwoWay}"/>
<Button Content="Salvar"
Width="80"
Height="28"
Background="#2E5C8A"
Foreground="White"
BorderBrush="#4F7EAD"
Command="{Binding SalvarSaudeCommand}"/>
</StackPanel>
<!-- TABS -->
<TabControl Grid.Row="3"
Background="#181818"
BorderBrush="#2F2F2F"
Foreground="#DDDDDD">
<TabItem Header="Condições Operacionais">
<Grid Background="#181818">
<ListBox ItemsSource="{Binding CondicoesOperacionais}"
Margin="8"
Background="#121212"
Foreground="#DDDDDD"
BorderBrush="#2D2D2D"/>
</Grid>
</TabItem>
<TabItem Header="Acompanhamento">
<Grid Background="#181818">
<scott:WpfPlot x:Name="pltSaude_Acompanhamento" Margin="8"/>
</Grid>
</TabItem>
<TabItem Header="Opções">
<Grid Background="#181818">
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
Padding="8">
<Grid>
<TextBlock Text="Nenhum teste disponível para este módulo."
FontSize="12"
Foreground="#A8A8A8"
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextWrapping="Wrap"
Visibility="{Binding OpcoesVM.MostrarOpcoesSemDados, Converter={StaticResource BoolToVisibilityConverter}}"/>
<StackPanel Visibility="{Binding OpcoesVM.MostrarOpcoesSensoriamento, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="Reinicia o módulo" Foreground="#DDDDDD"/>
<Button Content="Reiniciar" Width="90" Margin="8,0,0,0" Command="{Binding OpcoesVM.SensoriamentoReiniciarCommand}"/>
</StackPanel>
</StackPanel>
<StackPanel Visibility="{Binding OpcoesVM.MostrarOpcoesAtuador, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="Reinicia o módulo" Foreground="#DDDDDD"/>
<Button Content="Reiniciar" Width="90" Margin="8,0,0,0" Command="{Binding OpcoesVM.AtuadorReiniciarCommand}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="Altura" Foreground="#DDDDDD"/>
<Slider Width="120" Margin="8,0" Minimum="50" Maximum="80" Value="{Binding OpcoesVM.BarraAltura, Mode=TwoWay}"/>
<Label Content="{Binding OpcoesVM.BarraAlturaTexto}" Foreground="#DDDDDD"/>
<Button Content="Mover" Width="60" Margin="8,0,0,0" Command="{Binding OpcoesVM.BarraMoverCommand}"/>
</StackPanel>
</StackPanel>
<StackPanel Visibility="{Binding OpcoesVM.MostrarOpcoesBico, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="{Binding OpcoesVM.BicoTitulo}" FontWeight="Bold" Foreground="#DDDDDD" Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal">
<Button Content="Ligar" Width="80" Margin="0,0,5,0" Command="{Binding OpcoesVM.BicoLigarCommand}"/>
<Button Content="Desligar" Width="80" Command="{Binding OpcoesVM.BicoDesligarCommand}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<Label Content="Movimento" Foreground="#DDDDDD"/>
<Slider Width="160" Margin="8,0" Minimum="-90" Maximum="90" Value="{Binding OpcoesVM.BicoAngulo, Mode=TwoWay}"/>
<Label Content="{Binding OpcoesVM.BicoAnguloTexto}" Foreground="#DDDDDD"/>
<Button Content="Mover" Width="60" Margin="8,0,0,0" Command="{Binding OpcoesVM.BicoMoverCommand}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<Label Content="Ângulo abertura" Foreground="#DDDDDD"/>
<TextBox Width="60" Margin="8,0" Text="{Binding OpcoesVM.BicoAnguloAbertura, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Salvar" Width="60" Command="{Binding OpcoesVM.BicoSalvarAnguloAberturaCommand}"/>
</StackPanel>
<TextBlock Text="Bico - Leituras" Foreground="#DDDDDD" FontWeight="SemiBold" Margin="0,10,0,4"/>
<UniformGrid Rows="2" Columns="3">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Comando enviado" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtBicoComando}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Status real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtBicoStatusReal}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Tempo ligado" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtBicoTempoLigado}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Vazão" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtBicoVazao}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Pressão" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtBicoPressao}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Atuações" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtBicoAtuacoes}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<StackPanel Visibility="{Binding OpcoesVM.MostrarOpcoesBomba, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="{Binding OpcoesVM.BombaTitulo}" FontWeight="Bold" Foreground="#DDDDDD" Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal">
<Button Content="Ligar" Width="80" Margin="0,0,5,0" Command="{Binding OpcoesVM.BombaLigarCommand}"/>
<Button Content="Desligar" Width="80" Margin="0,0,10,0" Command="{Binding OpcoesVM.BombaDesligarCommand}"/>
<TextBlock Text="Pressão alvo:" VerticalAlignment="Center" Margin="0,0,5,0" FontSize="10" Foreground="#DDDDDD"/>
<Slider Width="120" Minimum="0" Maximum="150" Margin="0,0,5,0" Value="{Binding OpcoesVM.BombaPressaoAlvo, Mode=TwoWay}"/>
<Label Content="{Binding OpcoesVM.BombaPressaoAlvoTexto}" VerticalAlignment="Center" FontSize="10" Foreground="#DDDDDD"/>
</StackPanel>
<UniformGrid Rows="2" Columns="2" Margin="0,10,0,0">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Comando enviado" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtBombaComando}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Status real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtBombaStatusReal}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Pressão linha" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtBombaPressaoLinha}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Potência" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtBombaPotencia}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<StackPanel Visibility="{Binding OpcoesVM.MostrarOpcoesDirecional, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="{Binding OpcoesVM.DirTitulo}" FontWeight="Bold" Foreground="#DDDDDD" Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal">
<Button Content="Referenciar" Width="90" Margin="0,0,5,0" Command="{Binding OpcoesVM.DirReferenciarCommand}"/>
<Button Content="Mover" Width="80" Command="{Binding OpcoesVM.DirMovimentarCommand}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<ComboBox Width="130" Margin="0,0,8,0" ItemsSource="{Binding OpcoesVM.DirMovimentosDisponiveis}" SelectedItem="{Binding OpcoesVM.DirMovimentoSelecionado, Mode=TwoWay}"/>
<ComboBox Width="130" Margin="0,0,8,0" ItemsSource="{Binding OpcoesVM.DirDirecoesDisponiveis}" SelectedItem="{Binding OpcoesVM.DirDirecaoSelecionada, Mode=TwoWay}"/>
<Slider Width="120" Minimum="0" Maximum="180" Margin="0,0,8,0" Value="{Binding OpcoesVM.DirAngulo, Mode=TwoWay}"/>
<Label Content="{Binding OpcoesVM.DirAnguloTexto}" Foreground="#DDDDDD"/>
</StackPanel>
<UniformGrid Rows="2" Columns="2" Margin="0,10,0,0">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Sentido controle" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtDirSentidoSP}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Sentido real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtDirSentido}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Ângulo controle" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtDirAnguloSP}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Ângulo real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtDirAngulo}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<StackPanel Visibility="{Binding OpcoesVM.MostrarOpcoesGps, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="Lever Arm" FontWeight="Bold" Foreground="#DDDDDD" Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Label Content="Lateral" Foreground="#DDDDDD"/>
<Slider Width="110" Minimum="-5" Maximum="5" Margin="8,0" Value="{Binding OpcoesVM.GpsLeverArmLateral, Mode=TwoWay}"/>
<Label Content="{Binding OpcoesVM.GpsLeverArmLateralTexto}" Foreground="#DDDDDD" Margin="0,0,10,0"/>
<Label Content="Frontal" Foreground="#DDDDDD"/>
<Slider Width="110" Minimum="-10" Maximum="10" Margin="8,0" Value="{Binding OpcoesVM.GpsLeverArmFrontal, Mode=TwoWay}"/>
<Label Content="{Binding OpcoesVM.GpsLeverArmFrontalTexto}" Foreground="#DDDDDD"/>
</StackPanel>
<Button Content="Salvar" Width="80" Margin="0,0,0,8" Command="{Binding OpcoesVM.GpsSalvarCommand}"/>
<UniformGrid Rows="2" Columns="3">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Correção" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtGpsCorrecao}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Idade" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtGpsIdade}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Precisão" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtGpsPrecisao}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Satélites" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtGpsNSatelites}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Distância base" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtGpsDistBase}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Orientação" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtGpsOrientacao}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<StackPanel Visibility="{Binding OpcoesVM.MostrarOpcoesTrajetoria, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="Status do trabalho" FontWeight="Bold" Foreground="#DDDDDD" Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<CheckBox Content="Bateria Liberada" Margin="0,0,12,0" Foreground="#DDDDDD" IsChecked="{Binding OpcoesVM.TrajetoriaBatLiberada, Mode=TwoWay}"/>
<CheckBox Content="Pulverizador Liberado" Margin="0,0,12,0" Foreground="#DDDDDD" IsChecked="{Binding OpcoesVM.TrajetoriaHerbLiberado, Mode=TwoWay}"/>
<Button Content="Confirmar" Width="80" Command="{Binding OpcoesVM.TrajetoriaConfirmarCommand}" IsEnabled="{Binding OpcoesVM.TrajetoriaPodeConfirmar}"/>
</StackPanel>
<UniformGrid Rows="2" Columns="3">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Distância corredor" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtTrajetoriaDistCorredor}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Distância segura bateria" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtTrajetoriaDistBateria}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Distância segura pulverizador" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtTrajetoriaDistPulverizador}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Status" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtTrajetoriaStatus}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Bateria suficiente" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtTrajetoriaBatOk}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Herbicida suficiente" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtTrajetoriaHerbOk}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<StackPanel Visibility="{Binding OpcoesVM.MostrarOpcoesRele, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="{Binding OpcoesVM.ReleTitulo}" FontWeight="Bold" Foreground="#DDDDDD" Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal">
<Button Content="Ligar" Width="80" Margin="0,0,5,0" Command="{Binding OpcoesVM.ReleLigarCommand}"/>
<Button Content="Desligar" Width="80" Command="{Binding OpcoesVM.ReleDesligarCommand}"/>
</StackPanel>
<UniformGrid Rows="1" Columns="2" Margin="0,10,0,0">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Comando enviado" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtReleComando}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Status real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtReleStatusReal}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<StackPanel Visibility="{Binding OpcoesVM.MostrarOpcoesServo, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="Servo - Testes" FontWeight="Bold" Foreground="#DDDDDD" Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal">
<Label Content="Controle" Foreground="#DDDDDD"/>
<Slider Width="160" Margin="8,0" Minimum="0" Maximum="90" Value="{Binding OpcoesVM.ServoAngulo, Mode=TwoWay}"/>
<Label Content="{Binding OpcoesVM.ServoAnguloTexto}" Foreground="#DDDDDD"/>
<Button Content="Enviar" Width="80" Margin="8,0,0,0" Command="{Binding OpcoesVM.ServoEnviarCommand}"/>
</StackPanel>
<UniformGrid Rows="1" Columns="3" Margin="0,10,0,0">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Comando enviado" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtServoComando}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Status real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtServoLeitura}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Modo" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtServoIncremental}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<StackPanel Visibility="{Binding OpcoesVM.MostrarOpcoesNpc, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Label Content="Modo de Controle" Foreground="#DDDDDD"/>
<ComboBox Width="120" Margin="8,0" ItemsSource="{Binding OpcoesVM.NpcCoolerModosDisponiveis}" SelectedItem="{Binding OpcoesVM.NpcCoolerModoSelecionado, Mode=TwoWay}"/>
<CheckBox Content="Entrada" Margin="10,0,0,0" Foreground="#DDDDDD" IsChecked="{Binding OpcoesVM.NpcCoolerEntrada, Mode=TwoWay}"/>
<CheckBox Content="Saída" Margin="10,0,0,0" Foreground="#DDDDDD" IsChecked="{Binding OpcoesVM.NpcCoolerSaida, Mode=TwoWay}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Label Content="Temperatura ligar" Foreground="#DDDDDD"/>
<TextBox Width="50" Margin="8,0" Text="{Binding OpcoesVM.NpcCoolerTempOn, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Label Content="Temperatura turbo" Foreground="#DDDDDD" Margin="12,0,0,0"/>
<TextBox Width="50" Margin="8,0" Text="{Binding OpcoesVM.NpcCoolerTempTurbo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Enviar" Width="80" Margin="10,0,0,0" Command="{Binding OpcoesVM.NpcCoolerEnviarCommand}"/>
</StackPanel>
<UniformGrid Rows="2" Columns="2">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Modo controle" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtNpcCoolerModo}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Temperatura" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtNpcCoolerTemperatura}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Cooler entrada" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtNpcCoolerEntrada}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Cooler saída" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding OpcoesVM.TxtNpcCoolerSaida}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
</TabItem>
<TabItem Header="Logs">
<Grid Background="#181818">
<ListBox ItemsSource="{Binding LogsModuloSelecionado}"
Margin="8"
Background="#121212"
Foreground="#DDDDDD"
BorderBrush="#2D2D2D"/>
</Grid>
</TabItem>
</TabControl>
</Grid>
</Border>
</Grid>
</UserControl>

View File

@ -0,0 +1,66 @@
using OperationControl.ViewModels.Views.Operacao.Diagnostico;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace OperationControl.Views.Operacao
{
/// <summary>
/// Interaction logic for DiagnosticoView.xaml
/// </summary>
public partial class DiagnosticoView : System.Windows.Controls.UserControl
{
public DiagnosticoViewModel _vm;
public DiagnosticoView()
{
InitializeComponent();
_vm = new DiagnosticoViewModel();
DataContext = _vm;
}
public void AtualizarGraficos()
{
if (pltSaude_Acompanhamento == null)
return;
var plot = pltSaude_Acompanhamento.Plot;
plot.Clear();
bool temSeries = false;
foreach (var serie in _vm.SeriesGrafico)
{
if (serie.Valores.Count == 0)
continue;
double[] ys = serie.Valores.ToArray();
double[] xs = Enumerable.Range(0, ys.Length).Select(i => (double)i).ToArray();
var scatter = plot.Add.Scatter(xs, ys);
scatter.LegendText = string.IsNullOrWhiteSpace(serie.Unidade)
? serie.Label
: $"{serie.Label} ({serie.Unidade})";
temSeries = true;
}
if (temSeries)
plot.ShowLegend(ScottPlot.Alignment.UpperLeft);
plot.Axes.AutoScale();
pltSaude_Acompanhamento.Refresh();
}
}
}

View File

@ -0,0 +1,219 @@
<UserControl x:Class="OperationControl.Views.Operacao.MonitoramentoView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OperationControl.Views.Operacao"
xmlns:controls="clr-namespace:OperationControl.Controls"
mc:Ignorable="d"
d:DesignHeight="900"
d:DesignWidth="1600">
<Grid Margin="12">
<Grid.RowDefinitions>
<RowDefinition Height="2.2*"/>
<RowDefinition Height="1.3*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- CÂMERA FRONTAL -->
<Border Grid.Row="0" Grid.Column="0"
Margin="0,0,6,6"
Padding="10"
CornerRadius="10"
Background="#202020"
BorderBrush="#353535"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Margin="0,0,0,8">
<TextBlock Text="Câmera frontal"
DockPanel.Dock="Left"
FontSize="12"
FontWeight="SemiBold"
Foreground="#E6E6E6"
VerticalAlignment="Center"/>
<ComboBox x:Name="cmbCameraFrontalFrameTipo"
Width="130"
Height="26"
HorizontalAlignment="Right"
SelectionChanged="cmbCameraFrontalFrameTipo_SelectionChanged"/>
<TextBlock Text="12 fps • 230 kbps • CaminhandoRua"
Margin="12,0,8,0"
Foreground="#AFAFAF"
FontSize="11"
VerticalAlignment="Center"
HorizontalAlignment="Right"/>
</DockPanel>
<Grid Grid.Row="1" Background="Black">
<TextBlock Text="SEM SINAL"
Foreground="Gray"
FontSize="18"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<Image x:Name="imgVideoFront"
Stretch="Uniform"
RenderOptions.BitmapScalingMode="LowQuality"/>
</Grid>
</Grid>
</Border>
<!-- CÂMERA DE ERVAS -->
<Border Grid.Row="0" Grid.Column="1"
Margin="6,0,0,6"
Padding="10"
CornerRadius="10"
Background="#202020"
BorderBrush="#353535"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Margin="0,0,0,8">
<TextBlock Text="Câmera de ervas"
DockPanel.Dock="Left"
FontSize="12"
FontWeight="SemiBold"
Foreground="#E6E6E6"
VerticalAlignment="Center"/>
<ComboBox x:Name="cmbCameraTraseiraFrameTipo"
Width="130"
Height="26"
HorizontalAlignment="Right"
SelectionChanged="cmbCameraTraseiraFrameTipo_SelectionChanged"/>
<TextBlock Text="10 fps • 193 kbps • 5,41% erva • 0,00% cana"
Margin="12,0,8,0"
Foreground="#AFAFAF"
FontSize="11"
VerticalAlignment="Center"
HorizontalAlignment="Right"/>
</DockPanel>
<Grid Grid.Row="1" Background="Black">
<TextBlock Text="SEM SINAL"
Foreground="Gray"
FontSize="18"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<Image x:Name="imgVideoWeed"
Stretch="Uniform"
RenderOptions.BitmapScalingMode="LowQuality"/>
</Grid>
</Grid>
</Border>
<!-- MAPA -->
<Border Grid.Row="1" Grid.Column="0"
Margin="0,6,6,0"
Padding="10"
CornerRadius="10"
Background="#202020"
BorderBrush="#353535"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="Mapa e posição do rover"
Margin="0,0,0,8"
FontSize="12"
FontWeight="SemiBold"
Foreground="#E6E6E6"/>
<controls:MapViewControl x:Name="MapaMonitoramento" MarkerClicked="MAP_MarkerClicked" StreetMapClicked="MAP_StreetMapClicked" Grid.Row="1" Latitude="-22.1726572492617" Longitude="-47.3952163870556" Scale="5000" />
</Grid>
</Border>
<!-- ÁREA DIREITA INFERIOR -->
<Grid Grid.Row="1" Grid.Column="1" Margin="6,6,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="1.15*"/>
<RowDefinition Height="0.85*"/>
</Grid.RowDefinitions>
<!-- PULVERIZADOR -->
<Border Grid.Row="0"
Margin="0,0,0,6"
Padding="10"
CornerRadius="10"
Background="#202020"
BorderBrush="#353535"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="Pulverizador"
Margin="0,0,0,8"
FontSize="12"
FontWeight="SemiBold"
Foreground="#E6E6E6"/>
<Grid Grid.Row="1">
<controls:PulverizadorIndicator x:Name="ATU"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"/>
</Grid>
</Grid>
</Border>
<!-- AÇÕES RÁPIDAS -->
<Border Grid.Row="1"
Padding="10"
CornerRadius="10"
Background="#202020"
BorderBrush="#353535"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="Ações rápidas"
Margin="0,0,0,8"
FontSize="12"
FontWeight="SemiBold"
Foreground="#E6E6E6"/>
<UniformGrid Grid.Row="1" Rows="2" Columns="2" Margin="0,4,0,0">
<Button Content="Retorno à base" Margin="4"/>
<Button Content="Parametrização" Margin="4"/>
<Button Content="Pausar operação" Margin="4"/>
<Button Content="Diagnóstico" Margin="4"/>
</UniformGrid>
</Grid>
</Border>
</Grid>
</Grid>
</UserControl>

View File

@ -0,0 +1,99 @@
using OperationControl.Controls;
using OperationControl.Models;
using OperationControl.ViewModels.Views.Operacao.Monitoramento;
using System.Windows.Controls;
namespace OperationControl.Views.Operacao
{
/// <summary>
/// Interaction logic for MonitoramentoView.xaml
/// </summary>
public partial class MonitoramentoView : System.Windows.Controls.UserControl
{
public MonitoramentoViewModel _vm;
private TcpVideoReceiver videoFront;
private TcpVideoReceiver videoWeed;
public MonitoramentoView()
{
InitializeComponent();
_vm = new MonitoramentoViewModel();
DataContext = _vm;
videoFront = new TcpVideoReceiver(5000, imgVideoFront);
videoWeed = new TcpVideoReceiver(5002, imgVideoWeed);
cmbCameraFrontalFrameTipo.Items.Clear();
foreach (var m in Enum.GetNames(typeof(AgroBase.Models.Enums.TipoFrameCamera)))
cmbCameraFrontalFrameTipo.Items.Add(m);
cmbCameraFrontalFrameTipo.SelectedIndex = 0;
cmbCameraTraseiraFrameTipo.Items.Clear();
foreach (var m in Enum.GetNames(typeof(AgroBase.Models.Enums.TipoFrameCamera)))
cmbCameraTraseiraFrameTipo.Items.Add(m);
cmbCameraTraseiraFrameTipo.SelectedIndex = 0;
}
#region MAPA
private void MAP_MarkerClicked(object? sender, MapMarkerManager.MarkerClickedEventArgs e)
{
}
private void MAP_StreetMapClicked(object? sender, MapViewControl.StreetMapClickedEventArgs e)
{
}
#endregion
#region CAMERA FRONTAL
private void cmbCameraFrontalFrameTipo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (VariaveisControleOperacao.SelectedRoverId == VariaveisControleOperacao.BaseMarkerID) return;
PararStreamCameraFrontal();
IniciarStreamCameraFrontal();
}
public void IniciarStreamCameraFrontal()
{
videoFront.Iniciar();
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Snr, true, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraFrontalFrameTipo.SelectedIndex));
}
public void PararStreamCameraFrontal(bool finalizar = false)
{
videoFront.Parar();
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Snr, false, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraFrontalFrameTipo.SelectedIndex));
}
#endregion
#region CAMERA ERVAS
private void cmbCameraTraseiraFrameTipo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (VariaveisControleOperacao.SelectedRoverId == VariaveisControleOperacao.BaseMarkerID) return;
PararStreamCameraErvas();
IniciarStreamCameraErvas();
}
public void IniciarStreamCameraErvas()
{
videoWeed.Iniciar();
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Cam, true, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraTraseiraFrameTipo.SelectedIndex));
}
public void PararStreamCameraErvas(bool finalizar = false)
{
videoWeed.Parar();
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Cam, false, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraTraseiraFrameTipo.SelectedIndex));
}
#endregion
}
}

View File

@ -134,70 +134,5 @@
</TextBlock>
</Grid>
</Border>
<!-- Toast -->
<Border x:Name="brdToastAlerta"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="0,-78,20,0"
Padding="10,8"
CornerRadius="8"
Background="#1C1F23"
BorderBrush="#3A424F"
BorderThickness="1"
Cursor="Hand"
Visibility="{Binding ToastAlerta, Converter={StaticResource NullToVisibilityConverter}}"
MouseLeftButtonUp="ToastAlerta_MouseLeftButtonUp">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Opacity" Value="0.95"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ToastAlerta.Severidade}" Value="Warning">
<Setter Property="BorderBrush" Value="#EFBF2F"/>
</DataTrigger>
<DataTrigger Binding="{Binding ToastAlerta.Severidade}" Value="Error">
<Setter Property="BorderBrush" Value="#FF5656"/>
</DataTrigger>
<DataTrigger Binding="{Binding ToastAlerta.Severidade}" Value="Critical">
<Setter Property="BorderBrush" Value="#FF5656"/>
<Setter Property="Background" Value="#3A171C"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ToastAlerta.Icone}"
FontSize="16"
Margin="0,0,6,0"/>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Border Background="#2F3B4A"
CornerRadius="4"
Padding="4,1"
Margin="0,0,6,0">
<TextBlock Text="{Binding ToastAlerta.Rover_ID}"
Foreground="White"
FontSize="10"
FontWeight="Bold"/>
</Border>
<TextBlock Text="{Binding ToastAlerta.Titulo}"
FontWeight="Bold"
Foreground="#F5F7FA"
FontSize="11"/>
</StackPanel>
<TextBlock Text="{Binding ToastAlerta.Mensagem}"
Foreground="#B7C0CC"
FontSize="10"
TextWrapping="Wrap"
MaxWidth="320"/>
</StackPanel>
</StackPanel>
</Border>
</Grid>
</UserControl>

View File

@ -1,6 +1,5 @@
using OperationControl.Models;
using OperationControl.ViewModels.Views.Operacao;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace OperationControl.Views.Operacao
@ -30,39 +29,8 @@ namespace OperationControl.Views.Operacao
{
if (sender is Border border && border.DataContext is AlertaModel alerta)
{
_vm?.SelecionarAlerta(alerta);
System.Windows.MessageBox.Show(
$"Rover: {alerta.Rover_ID}\n" +
$"Módulo: {alerta.Modulo}\n" +
$"Severidade: {alerta.Severidade}\n" +
$"Mensagem: {alerta.Mensagem}\n\n" +
$"Aqui depois podemos navegar para a ação correspondente.",
"Alerta selecionado",
MessageBoxButton.OK,
MessageBoxImage.Information);
_vm?.ClicarNoAlerta(alerta);
}
}
private void ToastAlerta_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var alerta = _vm?.ToastAlerta;
if (alerta == null)
return;
_vm.LimparToast();
_vm.SelecionarAlerta(alerta);
System.Windows.MessageBox.Show(
$"Toast clicado\n\n" +
$"Rover: {alerta.Rover_ID}\n" +
$"Módulo: {alerta.Modulo}\n" +
$"Severidade: {alerta.Severidade}\n" +
$"Mensagem: {alerta.Mensagem}\n\n" +
$"Aqui depois podemos disparar a navegação ou foco no diagnóstico.",
"Toast de alerta",
MessageBoxButton.OK,
MessageBoxImage.Information);
}
}
}

View File

@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OperationControl.Views.Operacao"
xmlns:controls="clr-namespace:OperationControl.Controls"
xmlns:views="clr-namespace:OperationControl.Views.Operacao"
xmlns:scott="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
mc:Ignorable="d"
d:DesignHeight="450"
@ -12,46 +13,6 @@
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
<Style x:Key="DiagnosticoModuloButtonStyle" TargetType="Button">
<Setter Property="Width" Value="58"/>
<Setter Property="Height" Value="24"/>
<Setter Property="FontSize" Value="10"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Padding" Value="4,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="10"
SnapsToDevicePixels="True">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Bd" Property="Opacity" Value="0.92"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Bd" Property="Opacity" Value="0.82"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Bd" Property="Opacity" Value="0.45"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid Background="#181818">
@ -65,826 +26,12 @@
<!-- DIAGNÓSTICO -->
<Grid Visibility="{Binding ExibirDiagnostico, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid Margin="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1.55*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<!-- COLUNA ESQUERDA | MAPA VISUAL DO ROBÔ -->
<Border Grid.Column="0"
Margin="0,0,10,0"
Padding="16"
CornerRadius="10"
Background="#202020"
BorderBrush="#353535"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- CABEÇALHO -->
<StackPanel Grid.Row="0" Margin="0,0,0,12">
<TextBlock Text="Diagnóstico do rover"
FontSize="18"
FontWeight="SemiBold"
Foreground="#E6E6E6"/>
<TextBlock Text="Impedimento: Nenhum"
Margin="0,6,0,0"
FontSize="12"
Foreground="#B8B8B8"
TextWrapping="Wrap"/>
</StackPanel>
<!-- ÁREA DO ROBÔ -->
<Viewbox Grid.Row="1" Stretch="Uniform">
<Grid Width="700" Height="820">
<!-- fundo -->
<Border CornerRadius="12"
Background="#1A1A1A"
BorderBrush="#2F2F2F"
BorderThickness="1"/>
<!-- imagem do robô -->
<Image Source="/Resources/robo_superior.jpg"
Width="800"
Height="750"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<!-- overlay com módulos -->
<ItemsControl ItemsSource="{Binding DiagnosticoVM.DiagnosticoModulos}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Left}" />
<Setter Property="Canvas.Top" Value="{Binding Top}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding TextoExibicao}"
Style="{StaticResource DiagnosticoModuloButtonStyle}"
Background="{Binding BackgroundBrush}"
Foreground="{Binding ForegroundBrush}"
BorderBrush="{Binding BorderBrushColor}"
BorderThickness="{Binding BorderThicknessValue}"
Command="{Binding DataContext.DiagnosticoVM.SelecionarModuloCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
CommandParameter="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Viewbox>
</Grid>
</Border>
<!-- COLUNA DIREITA | DETALHES -->
<Border Grid.Column="1"
Margin="10,0,0,0"
Padding="16"
CornerRadius="10"
Background="#202020"
BorderBrush="#353535"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- TÍTULO -->
<StackPanel Grid.Row="0">
<TextBlock Text="{Binding DiagnosticoVM.TituloModuloSelecionado}"
FontSize="18"
FontWeight="SemiBold"
Foreground="#E6E6E6"/>
<TextBlock Text="{Binding DiagnosticoVM.DescricaoModuloSelecionado}"
Margin="0,6,0,0"
FontSize="12"
Foreground="#A8A8A8"
TextWrapping="Wrap"/>
</StackPanel>
<!-- RESUMO -->
<Border Grid.Row="1"
Margin="0,14,0,12"
Padding="12"
Background="#181818"
BorderBrush="#2F2F2F"
BorderThickness="1"
CornerRadius="8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- LINHA 1 -->
<WrapPanel Grid.Row="0" Margin="0,0,0,8">
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding DiagnosticoVM.InfoModulo}"
Foreground="#D8D8D8"
FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding DiagnosticoVM.InfoLabel}"
Foreground="#D8D8D8"
FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding DiagnosticoVM.InfoSCode}"
Foreground="#D8D8D8"
FontSize="12"/>
</Border>
</WrapPanel>
<!-- LINHA 2 -->
<WrapPanel Grid.Row="1" Margin="0,0,0,8">
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding DiagnosticoVM.InfoStatus}"
Foreground="#D8D8D8"
FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding DiagnosticoVM.InfoSaude}"
Foreground="#D8D8D8"
FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding DiagnosticoVM.InfoIniciado}"
Foreground="#D8D8D8"
FontSize="12"/>
</Border>
</WrapPanel>
<!-- LINHA 3 -->
<WrapPanel Grid.Row="2" Margin="0,0,0,8">
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding DiagnosticoVM.InfoCan}"
Foreground="#D8D8D8"
FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding DiagnosticoVM.InfoLatencia}"
Foreground="#D8D8D8"
FontSize="12"/>
</Border>
<Border Background="#2B2B2B" CornerRadius="6" Padding="8,4" Margin="0,0,8,8">
<TextBlock Text="{Binding DiagnosticoVM.InfoIdVisual}"
Foreground="#D8D8D8"
FontSize="12"/>
</Border>
</WrapPanel>
<!-- LINHA 4 -->
<TextBlock Grid.Row="3"
Text="{Binding DiagnosticoVM.ImpedimentoModuloSelecionado}"
Foreground="#C8C8C8"
FontSize="12"
TextWrapping="Wrap"/>
</Grid>
</Border>
<!-- AÇÕES -->
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,0,0,12">
<CheckBox Content="Mandatório" Margin="0,0,14,0" Foreground="#D8D8D8" VerticalAlignment="Center" IsChecked="{Binding DiagnosticoVM.MandatorioSelecionado, Mode=TwoWay}"/>
<CheckBox Content="Em uso" Margin="0,0,14,0" Foreground="#D8D8D8" VerticalAlignment="Center" IsChecked="{Binding DiagnosticoVM.EmUsoSelecionado, Mode=TwoWay}"/>
<Button Content="Salvar" Width="80" Height="28" Background="#2E5C8A" Foreground="White" BorderBrush="#4F7EAD" Command="{Binding DiagnosticoVM.SalvarSaudeCommand}"/>
</StackPanel>
<!-- TABS -->
<TabControl Grid.Row="3"
Background="#181818"
BorderBrush="#2F2F2F"
Foreground="#DDDDDD">
<TabItem Header="Condições Operacionais">
<Grid Background="#181818">
<ListBox ItemsSource="{Binding DiagnosticoVM.CondicoesOperacionais}" Margin="8" Background="#121212" Foreground="#DDDDDD" BorderBrush="#2D2D2D"/>
</Grid>
</TabItem>
<TabItem Header="Acompanhamento">
<Grid Background="#181818">
<scott:WpfPlot x:Name="pltSaude_Acompanhamento" Margin="8"/>
</Grid>
</TabItem>
<TabItem Header="Opções">
<Grid Background="#181818">
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
Padding="8">
<Grid>
<!-- SEM DADOS -->
<TextBlock Text="Nenhum teste disponível para este módulo."
FontSize="12"
Foreground="#A8A8A8"
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextWrapping="Wrap"
Visibility="{Binding DiagnosticoVM.OpcoesVM.MostrarOpcoesSemDados, Converter={StaticResource BoolToVisibilityConverter}}"/>
<!-- SENSORIAMENTO -->
<StackPanel Visibility="{Binding DiagnosticoVM.OpcoesVM.MostrarOpcoesSensoriamento, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="Reinicia o módulo" Foreground="#DDDDDD"/>
<Button Content="Reiniciar"
Width="90"
Margin="8,0,0,0"
Command="{Binding DiagnosticoVM.OpcoesVM.SensoriamentoReiniciarCommand}"/>
</StackPanel>
</StackPanel>
<!-- ATUADOR -->
<StackPanel Visibility="{Binding DiagnosticoVM.OpcoesVM.MostrarOpcoesAtuador, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="Reinicia o módulo" Foreground="#DDDDDD"/>
<Button Content="Reiniciar"
Width="90"
Margin="8,0,0,0"
Command="{Binding DiagnosticoVM.OpcoesVM.AtuadorReiniciarCommand}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<Label Content="Altura" Foreground="#DDDDDD"/>
<Slider Width="120"
Margin="8,0"
Minimum="50"
Maximum="80"
Value="{Binding DiagnosticoVM.OpcoesVM.BarraAltura, Mode=TwoWay}"/>
<Label Content="{Binding DiagnosticoVM.OpcoesVM.BarraAlturaTexto}" Foreground="#DDDDDD"/>
<Button Content="Mover"
Width="60"
Margin="8,0,0,0"
Command="{Binding DiagnosticoVM.OpcoesVM.BarraMoverCommand}"/>
</StackPanel>
</StackPanel>
<!-- BICO -->
<StackPanel Visibility="{Binding DiagnosticoVM.OpcoesVM.MostrarOpcoesBico, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.BicoTitulo}"
FontWeight="Bold"
Foreground="#DDDDDD"
Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal">
<Button Content="Ligar"
Width="80"
Margin="0,0,5,0"
Command="{Binding DiagnosticoVM.OpcoesVM.BicoLigarCommand}"/>
<Button Content="Desligar"
Width="80"
Command="{Binding DiagnosticoVM.OpcoesVM.BicoDesligarCommand}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<Label Content="Movimento" Foreground="#DDDDDD"/>
<Slider Width="160"
Margin="8,0"
Minimum="-90"
Maximum="90"
Value="{Binding DiagnosticoVM.OpcoesVM.BicoAngulo, Mode=TwoWay}"/>
<Label Content="{Binding DiagnosticoVM.OpcoesVM.BicoAnguloTexto}" Foreground="#DDDDDD"/>
<Button Content="Mover"
Width="60"
Margin="8,0,0,0"
Command="{Binding DiagnosticoVM.OpcoesVM.BicoMoverCommand}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<Label Content="Ângulo abertura" Foreground="#DDDDDD"/>
<TextBox Width="60"
Margin="8,0"
Text="{Binding DiagnosticoVM.OpcoesVM.BicoAnguloAbertura, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Salvar"
Width="60"
Command="{Binding DiagnosticoVM.OpcoesVM.BicoSalvarAnguloAberturaCommand}"/>
</StackPanel>
<TextBlock Text="Bico - Leituras"
Foreground="#DDDDDD"
FontWeight="SemiBold"
Margin="0,10,0,4"/>
<UniformGrid Rows="2" Columns="3" Margin="0,0,0,0">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Comando enviado" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtBicoComando}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Status real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtBicoStatusReal}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Tempo ligado" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtBicoTempoLigado}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Vazão" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtBicoVazao}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Pressão" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtBicoPressao}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Atuações" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtBicoAtuacoes}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<!-- BOMBA -->
<StackPanel Visibility="{Binding DiagnosticoVM.OpcoesVM.MostrarOpcoesBomba, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.BombaTitulo}"
FontWeight="Bold"
Foreground="#DDDDDD"
Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal">
<Button Content="Ligar"
Width="80"
Margin="0,0,5,0"
Command="{Binding DiagnosticoVM.OpcoesVM.BombaLigarCommand}"/>
<Button Content="Desligar"
Width="80"
Margin="0,0,10,0"
Command="{Binding DiagnosticoVM.OpcoesVM.BombaDesligarCommand}"/>
<TextBlock Text="Pressão alvo:"
VerticalAlignment="Center"
Margin="0,0,5,0"
FontSize="10"
Foreground="#DDDDDD"/>
<Slider Width="120"
Minimum="0"
Maximum="150"
Margin="0,0,5,0"
Value="{Binding DiagnosticoVM.OpcoesVM.BombaPressaoAlvo, Mode=TwoWay}"/>
<Label Content="{Binding DiagnosticoVM.OpcoesVM.BombaPressaoAlvoTexto}"
VerticalAlignment="Center"
FontSize="10"
Foreground="#DDDDDD"/>
</StackPanel>
<UniformGrid Rows="2" Columns="2" Margin="0,10,0,0">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Comando enviado" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtBombaComando}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Status real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtBombaStatusReal}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Pressão linha" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtBombaPressaoLinha}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Potência" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtBombaPotencia}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<!-- DIRECIONAL -->
<StackPanel Visibility="{Binding DiagnosticoVM.OpcoesVM.MostrarOpcoesDirecional, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.DirTitulo}"
FontWeight="Bold"
Foreground="#DDDDDD"
Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal">
<Button Content="Referenciar"
Width="90"
Margin="0,0,5,0"
Command="{Binding DiagnosticoVM.OpcoesVM.DirReferenciarCommand}"/>
<Button Content="Mover"
Width="80"
Command="{Binding DiagnosticoVM.OpcoesVM.DirMovimentarCommand}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,8,0,0">
<ComboBox Width="130"
Margin="0,0,8,0"
ItemsSource="{Binding DiagnosticoVM.OpcoesVM.DirMovimentosDisponiveis}"
SelectedItem="{Binding DiagnosticoVM.OpcoesVM.DirMovimentoSelecionado, Mode=TwoWay}"/>
<ComboBox Width="130"
Margin="0,0,8,0"
ItemsSource="{Binding DiagnosticoVM.OpcoesVM.DirDirecoesDisponiveis}"
SelectedItem="{Binding DiagnosticoVM.OpcoesVM.DirDirecaoSelecionada, Mode=TwoWay}"/>
<Slider Width="120"
Minimum="0"
Maximum="180"
Margin="0,0,8,0"
Value="{Binding DiagnosticoVM.OpcoesVM.DirAngulo, Mode=TwoWay}"/>
<Label Content="{Binding DiagnosticoVM.OpcoesVM.DirAnguloTexto}"
Foreground="#DDDDDD"/>
</StackPanel>
<UniformGrid Rows="2" Columns="2" Margin="0,10,0,0">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Sentido controle" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtDirSentidoSP}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Sentido real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtDirSentido}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Ângulo controle" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtDirAnguloSP}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Ângulo real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtDirAngulo}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<!-- GPS -->
<StackPanel Visibility="{Binding DiagnosticoVM.OpcoesVM.MostrarOpcoesGps, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="Lever Arm"
FontWeight="Bold"
Foreground="#DDDDDD"
Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Label Content="Lateral" Foreground="#DDDDDD"/>
<Slider Width="110"
Minimum="-5"
Maximum="5"
Margin="8,0"
Value="{Binding DiagnosticoVM.OpcoesVM.GpsLeverArmLateral, Mode=TwoWay}"/>
<Label Content="{Binding DiagnosticoVM.OpcoesVM.GpsLeverArmLateralTexto}" Foreground="#DDDDDD" Margin="0,0,10,0"/>
<Label Content="Frontal" Foreground="#DDDDDD"/>
<Slider Width="110"
Minimum="-10"
Maximum="10"
Margin="8,0"
Value="{Binding DiagnosticoVM.OpcoesVM.GpsLeverArmFrontal, Mode=TwoWay}"/>
<Label Content="{Binding DiagnosticoVM.OpcoesVM.GpsLeverArmFrontalTexto}" Foreground="#DDDDDD"/>
</StackPanel>
<Button Content="Salvar"
Width="80"
Margin="0,0,0,8"
Command="{Binding DiagnosticoVM.OpcoesVM.GpsSalvarCommand}"/>
<UniformGrid Rows="2" Columns="3">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Correção" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtGpsCorrecao}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Idade" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtGpsIdade}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Precisão" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtGpsPrecisao}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Satélites" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtGpsNSatelites}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Distância base" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtGpsDistBase}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Orientação" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtGpsOrientacao}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<!-- TRAJETORIA -->
<StackPanel Visibility="{Binding DiagnosticoVM.OpcoesVM.MostrarOpcoesTrajetoria, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="Status do trabalho"
FontWeight="Bold"
Foreground="#DDDDDD"
Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<CheckBox Content="Bateria Liberada"
Margin="0,0,12,0"
Foreground="#DDDDDD"
IsChecked="{Binding DiagnosticoVM.OpcoesVM.TrajetoriaBatLiberada, Mode=TwoWay}"/>
<CheckBox Content="Pulverizador Liberado"
Margin="0,0,12,0"
Foreground="#DDDDDD"
IsChecked="{Binding DiagnosticoVM.OpcoesVM.TrajetoriaHerbLiberado, Mode=TwoWay}"/>
<Button Content="Confirmar"
Width="80"
Command="{Binding DiagnosticoVM.OpcoesVM.TrajetoriaConfirmarCommand}"
IsEnabled="{Binding DiagnosticoVM.OpcoesVM.TrajetoriaPodeConfirmar}"/>
</StackPanel>
<UniformGrid Rows="2" Columns="3">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Distância corredor" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtTrajetoriaDistCorredor}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Distância segura bateria" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtTrajetoriaDistBateria}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Distância segura pulverizador" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtTrajetoriaDistPulverizador}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Status" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtTrajetoriaStatus}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Bateria suficiente" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtTrajetoriaBatOk}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Herbicida suficiente" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtTrajetoriaHerbOk}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<!-- RELÉ -->
<StackPanel Visibility="{Binding DiagnosticoVM.OpcoesVM.MostrarOpcoesRele, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.ReleTitulo}"
FontWeight="Bold"
Foreground="#DDDDDD"
Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal">
<Button Content="Ligar"
Width="80"
Margin="0,0,5,0"
Command="{Binding DiagnosticoVM.OpcoesVM.ReleLigarCommand}"/>
<Button Content="Desligar"
Width="80"
Command="{Binding DiagnosticoVM.OpcoesVM.ReleDesligarCommand}"/>
</StackPanel>
<UniformGrid Rows="1" Columns="2" Margin="0,10,0,0">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Comando enviado" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtReleComando}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Status real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtReleStatusReal}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<!-- SERVO -->
<StackPanel Visibility="{Binding DiagnosticoVM.OpcoesVM.MostrarOpcoesServo, Converter={StaticResource BoolToVisibilityConverter}}">
<TextBlock Text="Servo - Testes"
FontWeight="Bold"
Foreground="#DDDDDD"
Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal">
<Label Content="Controle" Foreground="#DDDDDD"/>
<Slider Width="160"
Margin="8,0"
Minimum="0"
Maximum="90"
Value="{Binding DiagnosticoVM.OpcoesVM.ServoAngulo, Mode=TwoWay}"/>
<Label Content="{Binding DiagnosticoVM.OpcoesVM.ServoAnguloTexto}" Foreground="#DDDDDD"/>
<Button Content="Enviar"
Width="80"
Margin="8,0,0,0"
Command="{Binding DiagnosticoVM.OpcoesVM.ServoEnviarCommand}"/>
</StackPanel>
<UniformGrid Rows="1" Columns="3" Margin="0,10,0,0">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Comando enviado" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtServoComando}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Status real" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtServoLeitura}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Modo" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtServoIncremental}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
<!-- NPC -->
<StackPanel Visibility="{Binding DiagnosticoVM.OpcoesVM.MostrarOpcoesNpc, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Label Content="Modo de Controle" Foreground="#DDDDDD"/>
<ComboBox Width="120"
Margin="8,0"
ItemsSource="{Binding DiagnosticoVM.OpcoesVM.NpcCoolerModosDisponiveis}"
SelectedItem="{Binding DiagnosticoVM.OpcoesVM.NpcCoolerModoSelecionado, Mode=TwoWay}"/>
<CheckBox Content="Entrada"
Margin="10,0,0,0"
Foreground="#DDDDDD"
IsChecked="{Binding DiagnosticoVM.OpcoesVM.NpcCoolerEntrada, Mode=TwoWay}"/>
<CheckBox Content="Saída"
Margin="10,0,0,0"
Foreground="#DDDDDD"
IsChecked="{Binding DiagnosticoVM.OpcoesVM.NpcCoolerSaida, Mode=TwoWay}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<Label Content="Temperatura ligar" Foreground="#DDDDDD"/>
<TextBox Width="50"
Margin="8,0"
Text="{Binding DiagnosticoVM.OpcoesVM.NpcCoolerTempOn, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Label Content="Temperatura turbo" Foreground="#DDDDDD" Margin="12,0,0,0"/>
<TextBox Width="50"
Margin="8,0"
Text="{Binding DiagnosticoVM.OpcoesVM.NpcCoolerTempTurbo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Enviar"
Width="80"
Margin="10,0,0,0"
Command="{Binding DiagnosticoVM.OpcoesVM.NpcCoolerEnviarCommand}"/>
</StackPanel>
<UniformGrid Rows="2" Columns="2">
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Modo controle" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtNpcCoolerModo}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Temperatura" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtNpcCoolerTemperatura}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Cooler entrada" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtNpcCoolerEntrada}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
<Border BorderBrush="#444" BorderThickness="1" Margin="2" Padding="4">
<StackPanel>
<TextBlock Text="Cooler saída" FontSize="10" Foreground="#AAAAAA"/>
<TextBlock Text="{Binding DiagnosticoVM.OpcoesVM.TxtNpcCoolerSaida}" Foreground="#DDDDDD"/>
</StackPanel>
</Border>
</UniformGrid>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
</TabItem>
<TabItem Header="Logs">
<Grid Background="#181818">
<ListBox ItemsSource="{Binding DiagnosticoVM.LogsModuloSelecionado}" Margin="8" Background="#121212" Foreground="#DDDDDD" BorderBrush="#2D2D2D"/>
</Grid>
</TabItem>
</TabControl>
</Grid>
</Border>
</Grid>
<views:DiagnosticoView x:Name="areaDiagnostico" />
</Grid>
<!-- MONITORAMENTO -->
<Grid Visibility="{Binding ExibirMonitoramento, Converter={StaticResource BoolToVisibilityConverter}}">
<Border Margin="12" Padding="20" CornerRadius="10" Background="#202020" BorderBrush="#353535" BorderThickness="1">
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="{Binding TituloCentro}" HorizontalAlignment="Center" FontSize="24" FontWeight="SemiBold" Foreground="#DDDDDD" TextAlignment="Center"/>
<TextBlock Text="{Binding SubtituloCentro}" HorizontalAlignment="Center" Margin="0,14,0,0" FontSize="14" Foreground="#AAAAAA" TextAlignment="Center" TextWrapping="Wrap" MaxWidth="500"/>
</StackPanel>
</Grid>
</Border>
<Border x:Name="brdCameraFrontal" BorderBrush="Black" BorderThickness="1" CornerRadius="8" Margin="1453,0,7,735">
<Canvas>
<Label Content="Câmera frontal | 12 fps | 230 kbps | 0,00% cana | 43 cm - 27 cm | 12,95° | CaminhandoRua" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="-3"/>
<!--<vlc:VideoView x:Name="VideoFront" Background="Black" Height="237" Width="438" HorizontalAlignment="Center" Canvas.Top="25" VerticalAlignment="Top" Canvas.Left="10"/>-->
<Grid Width="438" Height="237" Canvas.Top="25" Canvas.Left="10" Background="Black">
<TextBlock Text="SEM SINAL" Foreground="Gray" FontSize="18" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Image x:Name="imgVideoFront" Stretch="Uniform" RenderOptions.BitmapScalingMode="LowQuality" />
</Grid>
<ComboBox x:Name="cmbCameraFrontalFrameTipo" Canvas.Left="10" Canvas.Top="25" HorizontalAlignment="Left" VerticalAlignment="Center" Width="100" SelectionChanged="cmbCameraFrontalFrameTipo_SelectionChanged" />
</Canvas>
</Border>
<Border x:Name="brdCameraTraseira" BorderBrush="Black" BorderThickness="1" CornerRadius="8" Margin="1453,281,7,491">
<Canvas>
<Label Content="Câmera traseira | 10 fps | 193 kbps | 5,41% erva | 0,00% cana" FontSize="10" HorizontalAlignment="Center" VerticalAlignment="Top" Canvas.Top="-3"/>
<!--<vlc:VideoView x:Name="VideoWeed" Background="Black" Height="200" Width="438" HorizontalAlignment="Center" Canvas.Top="25" VerticalAlignment="Top" Canvas.Left="10"/>-->
<Grid Width="438" Height="200" Canvas.Top="25" Canvas.Left="10" Background="Black">
<TextBlock Text="SEM SINAL" Foreground="Gray" FontSize="18" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Image x:Name="imgVideoWeed" Stretch="Uniform" RenderOptions.BitmapScalingMode="LowQuality" />
</Grid>
<ComboBox x:Name="cmbCameraTraseiraFrameTipo" Canvas.Left="10" Canvas.Top="25" HorizontalAlignment="Left" VerticalAlignment="Center" Width="100" SelectionChanged="cmbCameraTraseiraFrameTipo_SelectionChanged" />
</Canvas>
</Border>
<views:MonitoramentoView x:Name="areaMonitor"/>
</Grid>
</Grid>

View File

@ -2,6 +2,7 @@
using OperationControl.Models;
using OperationControl.ViewModels.Views.Operacao;
using OperationControl.ViewModels.Views.Operacao.Diagnostico;
using OperationControl.ViewModels.Views.Operacao.Monitoramento;
using System.Windows.Controls;
namespace OperationControl.Views.Operacao
@ -12,70 +13,16 @@ namespace OperationControl.Views.Operacao
public partial class OperacaoCenterView : System.Windows.Controls.UserControl
{
public OperacaoCenterViewModel _vm;
public MonitoramentoView Monitoramento => areaMonitor;
public DiagnosticoView Diagnostico => areaDiagnostico;
public OperacaoCenterView()
{
InitializeComponent();
_vm = new OperacaoCenterViewModel();
DataContext = _vm;
videoFront = new TcpVideoReceiver(5000, imgVideoFront);
videoWeed = new TcpVideoReceiver(5002, imgVideoWeed);
}
private TcpVideoReceiver videoFront;
private TcpVideoReceiver videoWeed;
#region CAMERA FRONTAL
private void cmbCameraFrontalFrameTipo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (VariaveisControleOperacao.SelectedRoverId == VariaveisControleOperacao.BaseMarkerID) return;
PararStreamCameraFrontal();
IniciarStreamCameraFrontal();
}
public void IniciarStreamCameraFrontal()
{
videoFront.Iniciar();
var t = ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraFrontalFrameTipo.SelectedIndex);
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Snr, true, AgroBase.Models.Enums.TipoFrameCamera.Rgb);
}
public void PararStreamCameraFrontal(bool finalizar = false)
{
videoFront.Parar();
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Snr, false, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraFrontalFrameTipo.SelectedIndex));
}
#endregion
#region CAMERA ERVAS
private void cmbCameraTraseiraFrameTipo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (VariaveisControleOperacao.SelectedRoverId == VariaveisControleOperacao.BaseMarkerID) return;
PararStreamCameraErvas();
IniciarStreamCameraErvas();
}
public void IniciarStreamCameraErvas()
{
videoWeed.Iniciar();
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Cam, true, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraTraseiraFrameTipo.SelectedIndex));
}
public void PararStreamCameraErvas(bool finalizar = false)
{
videoWeed.Parar();
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Cam, false, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraTraseiraFrameTipo.SelectedIndex));
}
#endregion
private void MAP_MarkerClicked(object? sender, MapMarkerManager.MarkerClickedEventArgs e)
{
_vm.ProcessarMarkerClicked(e);
@ -86,28 +33,5 @@ namespace OperationControl.Views.Operacao
_vm.ProcessarStreetMapClicked(e);
}
public void AtualizarGraficoDiagnostico(DiagnosticoViewModel vm)
{
if (vm == null || pltSaude_Acompanhamento == null)
return;
var plot = pltSaude_Acompanhamento.Plot;
plot.Clear();
foreach (var serie in vm.SeriesGrafico)
{
if (serie.Valores.Count == 0)
continue;
double[] ys = serie.Valores.ToArray();
double[] xs = Enumerable.Range(0, ys.Length).Select(i => (double)i).ToArray();
plot.Add.Scatter(xs, ys);
}
plot.Axes.AutoScale();
pltSaude_Acompanhamento.Refresh();
}
}
}

View File

@ -21,8 +21,6 @@ namespace OperationControl.Views
/// </summary>
public partial class PreparacaoMapaView : System.Windows.Controls.UserControl
{
public MapViewControl MapControl => MapaPreparacao;
public PreparacaoMapaView()
{
InitializeComponent();

View File

@ -4,92 +4,145 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:OperationControl.Windows"
xmlns:localHelpers="clr-namespace:OperationControl.Helpers"
xmlns:conv="clr-namespace:OperationControl.Converters"
mc:Ignorable="d"
Title="DockWindow" Height="1025" Width="1920" WindowStartupLocation="CenterScreen" WindowState="Maximized">
<Window.Resources>
<!--<localHelpers:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>-->
<conv:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<!-- Topo -->
<RowDefinition Height="*"/>
<!-- Centro -->
<RowDefinition Height="120"/>
<!-- Rodapé -->
</Grid.RowDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<!-- Topo -->
<RowDefinition Height="*"/>
<!-- Centro -->
<RowDefinition Height="120"/>
<!-- Rodapé -->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding LeftPanelWidth}"/>
<!-- Lateral esquerda (voltar) -->
<ColumnDefinition Width="*"/>
<!-- Centro -->
<ColumnDefinition Width="{Binding RightPanelWidth}"/>
<!-- Lateral direita (avançar) -->
</Grid.ColumnDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding LeftPanelWidth}"/>
<!-- Lateral esquerda (voltar) -->
<ColumnDefinition Width="*"/>
<!-- Centro -->
<ColumnDefinition Width="{Binding RightPanelWidth}"/>
<!-- Lateral direita (avançar) -->
</Grid.ColumnDefinitions>
<!-- Topo (span em 3 colunas) -->
<Border Grid.Row="0" Grid.ColumnSpan="3"
Background="#222"
Padding="8">
<ContentControl Content="{Binding TopContent}"/>
</Border>
<!-- Topo (span em 3 colunas) -->
<Border Grid.Row="0" Grid.ColumnSpan="3"
Background="#222"
Padding="8">
<ContentControl Content="{Binding TopContent}"/>
</Border>
<!-- Área central principal -->
<Border Grid.Row="1" Grid.Column="1"
Margin="8"
<!-- Área central principal -->
<Border Grid.Row="1" Grid.Column="1"
Margin="8"
BorderThickness="1"
BorderBrush="Gray">
<ContentControl Content="{Binding CenterContent}"/>
</Border>
<!-- Rodapé (span 3 colunas) -->
<Border Grid.Row="2" Grid.ColumnSpan="3"
Background="#181818"
Padding="8">
<ContentControl Content="{Binding BottomContent}"/>
</Border>
<!-- Lateral esquerda -->
<Grid Grid.Row="1" Grid.Column="0" Margin="8">
<ContentControl Content="{Binding LeftContent}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="Content" Value="{x:Null}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding LeftContent}" Value="{x:Null}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Grid>
<Button Content="⮜"
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="40"
Height="40"
Command="{Binding BackCommand}"
IsEnabled="{Binding CanGoBack}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
<!-- Lateral direita -->
<Border Grid.Row="1" Grid.Column="2"
Margin="8"
BorderThickness="1"
BorderBrush="#404040"
Background="#1C1C1C">
<ContentControl Content="{Binding RightContent}"/>
</Border>
</Grid>
<!-- Overlay global -->
<Grid Panel.ZIndex="9999">
<Border HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="0,20,20,0"
Padding="10,8"
CornerRadius="8"
Background="#1C1F23"
BorderBrush="#3A424F"
BorderThickness="1"
BorderBrush="Gray">
<ContentControl Content="{Binding CenterContent}"/>
</Border>
Cursor="Hand"
Visibility="{Binding BottomVM.ToastAlerta, Converter={StaticResource NullToVisibilityConverter}}"
MouseLeftButtonUp="ToastAlerta_MouseLeftButtonUp">
<!-- Rodapé (span 3 colunas) -->
<Border Grid.Row="2" Grid.ColumnSpan="3"
Background="#181818"
Padding="8">
<ContentControl Content="{Binding BottomContent}"/>
</Border>
<Border.Style>
<Style TargetType="Border">
<Setter Property="Opacity" Value="0.95"/>
<!-- Lateral esquerda -->
<Grid Grid.Row="1" Grid.Column="0" Margin="8">
<ContentControl Content="{Binding LeftContent}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="Content" Value="{x:Null}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding LeftContent}" Value="{x:Null}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Grid>
<Button Content="⮜"
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="40"
Height="40"
Command="{Binding BackCommand}"
IsEnabled="{Binding CanGoBack}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<DataTrigger Binding="{Binding BottomVM.ToastAlerta.Severidade}" Value="Warning">
<Setter Property="BorderBrush" Value="#EFBF2F"/>
</DataTrigger>
<DataTrigger Binding="{Binding BottomVM.ToastAlerta.Severidade}" Value="Error">
<Setter Property="BorderBrush" Value="#FF5656"/>
</DataTrigger>
<DataTrigger Binding="{Binding BottomVM.ToastAlerta.Severidade}" Value="Critical">
<Setter Property="BorderBrush" Value="#FF5656"/>
<Setter Property="Background" Value="#3A171C"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
</Border.Style>
<!-- Lateral direita -->
<Border Grid.Row="1" Grid.Column="2"
Margin="8"
BorderThickness="1"
BorderBrush="#404040"
Background="#1C1C1C">
<ContentControl Content="{Binding RightContent}"/>
</Border>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding BottomVM.ToastAlerta.Icone}" FontSize="16" Margin="0,0,6,0"/>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Border Background="#2F3B4A" CornerRadius="4" Padding="4,1" Margin="0,0,6,0">
<TextBlock Text="{Binding BottomVM.ToastAlerta.Rover_ID}" Foreground="White" FontSize="10" FontWeight="Bold"/>
</Border>
<TextBlock Text="{Binding BottomVM.ToastAlerta.Titulo}" FontWeight="Bold" Foreground="#F5F7FA" FontSize="11"/>
</StackPanel>
<TextBlock Text="{Binding BottomVM.ToastAlerta.Mensagem}" Foreground="#B7C0CC" FontSize="10" TextWrapping="Wrap" MaxWidth="320"/>
</StackPanel>
</StackPanel>
</Border>
</Grid>
</Grid>
</Window>

View File

@ -1,17 +1,6 @@
using OperationControl.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace OperationControl.Windows
{
@ -27,5 +16,10 @@ namespace OperationControl.Windows
_vm = new DockWindowViewModel();
DataContext = _vm;
}
private void ToastAlerta_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_vm.BottomVM?.ClicarNoToast();
}
}
}