569 lines
20 KiB
C#
569 lines
20 KiB
C#
using OperationControl.Helpers;
|
|
using OperationControl.Models;
|
|
using System.ComponentModel;
|
|
using System.Windows;
|
|
using System.Windows.Input;
|
|
using static AgroBase.Models.Enums;
|
|
using Brush = System.Windows.Media.Brush;
|
|
using Brushes = System.Windows.Media.Brushes;
|
|
using SolidColorBrush = System.Windows.Media.SolidColorBrush;
|
|
using Color = System.Windows.Media.Color;
|
|
using AgroBase.Models.Operacoes;
|
|
|
|
namespace OperationControl.ViewModels.Views.Operacao
|
|
{
|
|
public class OperacaoLeftViewModel : INotifyPropertyChanged
|
|
{
|
|
public ICommand AlternarOperacaoCommand { get; }
|
|
public ICommand ParadaEmergenciaCommand { get; }
|
|
public ICommand CancelarOperacaoCommand { get; }
|
|
public ICommand ReconfigurarGnssCommand { get; }
|
|
private bool _operacaoPausada => (VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Pausa ?? false);
|
|
private bool _operacaoEmExecucao;
|
|
public bool OperacaoEmExecucao
|
|
{
|
|
get => _operacaoEmExecucao;
|
|
set
|
|
{
|
|
if (_operacaoEmExecucao != value)
|
|
{
|
|
_operacaoEmExecucao = value;
|
|
OnPropertyChanged(nameof(OperacaoEmExecucao));
|
|
OnPropertyChanged(nameof(TextoBotaoOperacao));
|
|
OnPropertyChanged(nameof(CorBotaoOperacao));
|
|
OnPropertyChanged(nameof(BordaBotaoOperacao));
|
|
}
|
|
}
|
|
}
|
|
|
|
public string TextoBotaoOperacao => _operacaoPausada ? "▶ Retomar Operação" : OperacaoEmExecucao ? "⏸ Pausar Operação" : "▶ Iniciar Operação";
|
|
|
|
public Brush CorBotaoOperacao =>
|
|
OperacaoEmExecucao && !_operacaoPausada
|
|
? new SolidColorBrush(Color.FromRgb(120, 88, 20))
|
|
: new SolidColorBrush(Color.FromRgb(30, 90, 58));
|
|
|
|
public Brush BordaBotaoOperacao =>
|
|
OperacaoEmExecucao && !_operacaoPausada
|
|
? new SolidColorBrush(Color.FromRgb(170, 130, 40))
|
|
: new SolidColorBrush(Color.FromRgb(74, 138, 91));
|
|
|
|
|
|
private bool _roverSelecionado;
|
|
public bool RoverSelecionado
|
|
{
|
|
get => _roverSelecionado;
|
|
set
|
|
{
|
|
if (_roverSelecionado != value)
|
|
{
|
|
_roverSelecionado = value;
|
|
OnPropertyChanged(nameof(RoverSelecionado));
|
|
OnPropertyChanged(nameof(NomeRover));
|
|
OnPropertyChanged(nameof(OpacityPainel));
|
|
OnPropertyChanged(nameof(RoverNaoSelecionado));
|
|
OnPropertyChanged(nameof(VisibilidadeAcoesRover));
|
|
OnPropertyChanged(nameof(VisibilidadeConfiguracaoGnss));
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool RoverNaoSelecionado => !RoverSelecionado;
|
|
|
|
public Visibility VisibilidadeAcoesRover => RoverSelecionado ? Visibility.Visible : Visibility.Collapsed;
|
|
|
|
public Visibility VisibilidadeConfiguracaoGnss => !RoverSelecionado ? Visibility.Visible : Visibility.Collapsed;
|
|
|
|
private string _nomeRover = "Nenhum rover selecionado";
|
|
public string NomeRover
|
|
{
|
|
get => RoverSelecionado ? _nomeRover : "Nenhum rover selecionado";
|
|
set
|
|
{
|
|
if (_nomeRover != value)
|
|
{
|
|
_nomeRover = value;
|
|
OnPropertyChanged(nameof(NomeRover));
|
|
}
|
|
}
|
|
}
|
|
|
|
public double OpacityPainel => RoverSelecionado ? 1.0 : 0.45;
|
|
|
|
private string _velocidade = "--";
|
|
public string Velocidade
|
|
{
|
|
get => VelocidadeValor(_velocidade);
|
|
set
|
|
{
|
|
if (_velocidade != value)
|
|
{
|
|
_velocidade = value;
|
|
OnPropertyChanged(nameof(Velocidade));
|
|
}
|
|
}
|
|
}
|
|
|
|
private string _anguloDirecional = "--";
|
|
public string AnguloDirecional
|
|
{
|
|
get => RoverSelecionado ? $"{_anguloDirecional}°" : "--";
|
|
set
|
|
{
|
|
if (_anguloDirecional != value)
|
|
{
|
|
_anguloDirecional = value;
|
|
OnPropertyChanged(nameof(AnguloDirecional));
|
|
}
|
|
}
|
|
}
|
|
|
|
private TipoMovimentoDirecional _tipoMovimento = TipoMovimentoDirecional.Diagnostico;
|
|
public TipoMovimentoDirecional TipoMovimento
|
|
{
|
|
get => _tipoMovimento;
|
|
set
|
|
{
|
|
if (_tipoMovimento != value)
|
|
{
|
|
_tipoMovimento = value;
|
|
OnPropertyChanged(nameof(TipoMovimento));
|
|
}
|
|
}
|
|
}
|
|
|
|
private string _temperatura = "--";
|
|
public string Temperatura
|
|
{
|
|
get => TemperaturaValor(_temperatura);
|
|
set
|
|
{
|
|
if (_temperatura != value)
|
|
{
|
|
_temperatura = value;
|
|
OnPropertyChanged(nameof(Temperatura));
|
|
}
|
|
}
|
|
}
|
|
|
|
private string _bateria = "--";
|
|
public string Bateria
|
|
{
|
|
get => PercentualOuTracos(_bateria);
|
|
set
|
|
{
|
|
if (_bateria != value)
|
|
{
|
|
_bateria = value;
|
|
OnPropertyChanged(nameof(Bateria));
|
|
}
|
|
}
|
|
}
|
|
|
|
private string _reservatorio = "--";
|
|
public string Reservatorio
|
|
{
|
|
get => PercentualOuTracos(_reservatorio);
|
|
set
|
|
{
|
|
if (_reservatorio != value)
|
|
{
|
|
_reservatorio = value;
|
|
OnPropertyChanged(nameof(Reservatorio));
|
|
}
|
|
}
|
|
}
|
|
|
|
private string _saudeRede = "--";
|
|
public string SaudeRede
|
|
{
|
|
get => ValorOuTracos(_saudeRede);
|
|
set
|
|
{
|
|
if (_saudeRede != value)
|
|
{
|
|
_saudeRede = value;
|
|
OnPropertyChanged(nameof(SaudeRede));
|
|
}
|
|
}
|
|
}
|
|
|
|
private string _saudeGnss = "--";
|
|
public string SaudeGnss
|
|
{
|
|
get => ValorOuTracos(_saudeGnss);
|
|
set
|
|
{
|
|
if (_saudeGnss != value)
|
|
{
|
|
_saudeGnss = value;
|
|
OnPropertyChanged(nameof(SaudeGnss));
|
|
}
|
|
}
|
|
}
|
|
|
|
private string _distanciaBase = "--";
|
|
public string DistanciaBase
|
|
{
|
|
get => DistanciaOuTracos(_distanciaBase);
|
|
set
|
|
{
|
|
if (_distanciaBase != value)
|
|
{
|
|
_distanciaBase = value;
|
|
OnPropertyChanged(nameof(DistanciaBase));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public Brush CorTemperatura =>
|
|
!RoverSelecionado ? Brushes.Gray :
|
|
_temperaturaNumerica >= 55 ? Brushes.OrangeRed :
|
|
_temperaturaNumerica >= 45 ? Brushes.Gold :
|
|
Brushes.LightGreen;
|
|
|
|
public Brush CorBateria =>
|
|
!RoverSelecionado ? Brushes.Gray :
|
|
_bateriaNumerica <= 20 ? Brushes.OrangeRed :
|
|
_bateriaNumerica <= 40 ? Brushes.Gold :
|
|
Brushes.LightGreen;
|
|
|
|
public Brush CorReservatorio =>
|
|
!RoverSelecionado ? Brushes.Gray :
|
|
_reservatorioNumerico <= 15 ? Brushes.OrangeRed :
|
|
_reservatorioNumerico <= 35 ? Brushes.Gold :
|
|
Brushes.LightGreen;
|
|
|
|
public Brush CorRede =>
|
|
!RoverSelecionado ? Brushes.Gray :
|
|
CorPorTexto(_saudeRede);
|
|
|
|
public Brush CorGnss =>
|
|
!RoverSelecionado ? Brushes.Gray :
|
|
CorPorTexto(_saudeGnss);
|
|
|
|
public Brush CorDistBase =>
|
|
!RoverSelecionado ? Brushes.Gray :
|
|
_distanciaBaseNumerico <= 50 ? Brushes.LimeGreen :
|
|
_distanciaBaseNumerico <= 150 ? Brushes.Green :
|
|
_distanciaBaseNumerico <= 400 ? Brushes.YellowGreen :
|
|
_distanciaBaseNumerico <= 800 ? Brushes.Gold :
|
|
_distanciaBaseNumerico <= 1200 ? Brushes.OrangeRed :
|
|
Brushes.DarkRed;
|
|
|
|
private double _temperaturaNumerica;
|
|
private double _bateriaNumerica;
|
|
private double _reservatorioNumerico;
|
|
private double _distanciaBaseNumerico;
|
|
|
|
public OperacaoLeftViewModel()
|
|
{
|
|
AlternarOperacaoCommand = new RelayCommand(_ => AlternarOperacao());
|
|
ParadaEmergenciaCommand = new RelayCommand(_ => ExecutarParadaEmergencia());
|
|
CancelarOperacaoCommand = new RelayCommand(_ => CancelarOperacao());
|
|
ReconfigurarGnssCommand = new RelayCommand(_ => ReconfigurarGnss());
|
|
|
|
DefinirSemRover();
|
|
}
|
|
|
|
public void DefinirSemRover()
|
|
{
|
|
RoverSelecionado = false;
|
|
NomeRover = "Nenhum rover selecionado";
|
|
_temperaturaNumerica = 0;
|
|
_bateriaNumerica = 0;
|
|
_reservatorioNumerico = 0;
|
|
_distanciaBaseNumerico = 0;
|
|
|
|
Velocidade = "--";
|
|
AnguloDirecional = "--";
|
|
TipoMovimento = TipoMovimentoDirecional.Diagnostico;
|
|
Temperatura = "--";
|
|
Bateria = "--";
|
|
Reservatorio = "--";
|
|
SaudeRede = "--";
|
|
SaudeGnss = "--";
|
|
DistanciaBase = "--";
|
|
|
|
OnPropertyChanged(nameof(CorTemperatura));
|
|
OnPropertyChanged(nameof(CorBateria));
|
|
OnPropertyChanged(nameof(CorReservatorio));
|
|
OnPropertyChanged(nameof(CorRede));
|
|
OnPropertyChanged(nameof(CorGnss));
|
|
OnPropertyChanged(nameof(CorDistBase));
|
|
}
|
|
|
|
public void AtualizarRover(string descricao, OperacaoParametrosDadosControleModel? controle, double temperaturaC, double bateriaPct, double reservatorioPct, string saudeRede, string saudeGnss, double distanciaBase, bool op_iniciada)
|
|
{
|
|
RoverSelecionado = true;
|
|
NomeRover = descricao;
|
|
|
|
_temperaturaNumerica = temperaturaC;
|
|
_bateriaNumerica = bateriaPct;
|
|
_reservatorioNumerico = reservatorioPct;
|
|
_distanciaBaseNumerico = distanciaBase;
|
|
|
|
Velocidade = $"{controle?.PercentualVelocidadeSPKmh ?? 0:F2}";
|
|
AnguloDirecional = $"{controle?.Angulo ?? 0:F1}";
|
|
TipoMovimento = controle?.TipoMovimento ?? TipoMovimentoDirecional.RodasDianteiras;
|
|
Temperatura = temperaturaC.ToString("0.0");
|
|
Bateria = bateriaPct.ToString("0");
|
|
Reservatorio = reservatorioPct.ToString("0");
|
|
SaudeRede = saudeRede;
|
|
SaudeGnss = saudeGnss;
|
|
DistanciaBase = $"{distanciaBase:F2}";
|
|
|
|
OperacaoEmExecucao = op_iniciada;
|
|
|
|
OnPropertyChanged(nameof(CorTemperatura));
|
|
OnPropertyChanged(nameof(CorBateria));
|
|
OnPropertyChanged(nameof(CorReservatorio));
|
|
OnPropertyChanged(nameof(CorRede));
|
|
OnPropertyChanged(nameof(CorGnss));
|
|
OnPropertyChanged(nameof(CorDistBase));
|
|
OnPropertyChanged(nameof(OperacaoEmExecucao));
|
|
OnPropertyChanged(nameof(TextoBotaoOperacao));
|
|
OnPropertyChanged(nameof(CorBotaoOperacao));
|
|
OnPropertyChanged(nameof(BordaBotaoOperacao));
|
|
}
|
|
|
|
private void AlternarOperacao()
|
|
{
|
|
var dadosRover = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura;
|
|
if (dadosRover?.Operacao?.Iniciada ?? false)
|
|
{
|
|
bool PauseActivated = dadosRover?.Operacao?.Pausa ?? false;
|
|
PauseActivated = !PauseActivated;
|
|
VariaveisControleOperacao.EnviarComandoParada(pausa: PauseActivated);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* =========================================================
|
|
* 1. VALIDAÇÃO DA PARAMETRIZAÇÃO
|
|
* =========================================================
|
|
*/
|
|
|
|
if (
|
|
(
|
|
dadosRover?.Operacao?.Modo ??
|
|
AgroBase.Models.Enums.ModoOperacao.NaoDefinido
|
|
)
|
|
==
|
|
AgroBase.Models.Enums.ModoOperacao.MapaGPS
|
|
&&
|
|
!(
|
|
VariaveisControleOperacao
|
|
.RoverEmFoco?
|
|
.RuasPercorrer?
|
|
.Any()
|
|
??
|
|
false
|
|
)
|
|
)
|
|
{
|
|
System.Windows.MessageBox.Show(
|
|
"Para iniciar a operação automática, " +
|
|
"é necessário carregar um mapa e selecionar " +
|
|
"as ruas onde o equipamento irá operar!",
|
|
"Parametrização",
|
|
MessageBoxButton.OK,
|
|
MessageBoxImage.Warning
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* =========================================================
|
|
* 2. AUTORIZAÇÃO DA ESTAÇÃO GNSS
|
|
* =========================================================
|
|
*
|
|
* O Left Bar não conhece as regras da estação.
|
|
* Ele apenas pergunta ao Dock se o início está liberado.
|
|
*/
|
|
|
|
bool inicioAutorizado =
|
|
Variaveis.Dock?
|
|
._vm?
|
|
.AutorizarInicioOperacao()
|
|
??
|
|
false;
|
|
|
|
|
|
if (!inicioAutorizado)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* =========================================================
|
|
* 3. CONFIRMAÇÃO HUMANA
|
|
* =========================================================
|
|
*/
|
|
|
|
if (
|
|
System.Windows.MessageBox.Show(
|
|
"Deseja iniciar a operação com os parâmetros atuais?",
|
|
"Iniciar Operação",
|
|
MessageBoxButton.YesNo,
|
|
MessageBoxImage.Question
|
|
)
|
|
!=
|
|
MessageBoxResult.Yes
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* =========================================================
|
|
* 4. FLUXO DE INÍCIO JÁ EXISTENTE
|
|
* =========================================================
|
|
*/
|
|
|
|
Task.Run(
|
|
async () =>
|
|
{
|
|
Variaveis.Dock?
|
|
._vm?
|
|
.LimparMovimentoRover(
|
|
VariaveisControleOperacao
|
|
.RoverEmFoco?
|
|
.RoverId
|
|
);
|
|
|
|
|
|
/*
|
|
* Se a operação anterior terminou,
|
|
* primeiro reseta seu estado.
|
|
*/
|
|
if (
|
|
(
|
|
dadosRover?
|
|
.Operacao?
|
|
.Status
|
|
??
|
|
StatusOperacao.NaoIniciado
|
|
)
|
|
==
|
|
StatusOperacao.Concluido
|
|
)
|
|
{
|
|
VariaveisControleOperacao
|
|
.EnviarComandoIniciarOperacao(
|
|
false,
|
|
false
|
|
);
|
|
|
|
|
|
await Task.Delay(
|
|
2000
|
|
);
|
|
}
|
|
|
|
|
|
/*
|
|
* Mock / AddRover continuam funcionando
|
|
* normalmente como simulador.
|
|
*/
|
|
bool simulador =
|
|
AppShell.Mock ||
|
|
AppShell.AddRover;
|
|
|
|
|
|
VariaveisControleOperacao
|
|
.EnviarComandoIniciarOperacao(
|
|
true,
|
|
simulador
|
|
);
|
|
|
|
|
|
await Task.Delay(
|
|
1000
|
|
);
|
|
|
|
|
|
/*
|
|
* Depois do comando ainda preservamos
|
|
* a validação que já existia no rover.
|
|
*/
|
|
if (
|
|
!(
|
|
dadosRover?
|
|
.Operacao?
|
|
.Liberada
|
|
??
|
|
false
|
|
)
|
|
)
|
|
{
|
|
System.Windows.MessageBox.Show(
|
|
$"{VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.ImpedimentoErro}",
|
|
"Operação iniciada com impedimento!",
|
|
MessageBoxButton.OK,
|
|
MessageBoxImage.Warning
|
|
);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
private void ExecutarParadaEmergencia()
|
|
{
|
|
bool EmergencyActivated = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Emergencia ?? false;
|
|
EmergencyActivated = !EmergencyActivated;
|
|
//VariaveisControleOperacao.EnviarComandoParada(emergencia: EmergencyActivated);
|
|
_ = VariaveisControleOperacao.EnviarComandoParadaUDP(emergencia: EmergencyActivated);
|
|
}
|
|
|
|
private void CancelarOperacao()
|
|
{
|
|
if (System.Windows.MessageBox.Show("Deseja finalizar a operação em andamento?", "Finalizar Operação", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
|
|
{
|
|
VariaveisControleOperacao.EnviarComandoIniciarOperacao(false);
|
|
Models.Variaveis.Dock?._vm?._viewOperacaoCenter?.Mapa?.LimparPontosSelecionados();
|
|
}
|
|
}
|
|
|
|
private void ReconfigurarGnss()
|
|
{
|
|
Variaveis.Dock?._vm?.IrParaConfiguracaoGnss();
|
|
}
|
|
|
|
|
|
private string ValorOuTracos(string valor) => RoverSelecionado ? valor : "--";
|
|
private string VelocidadeValor(string valor) => RoverSelecionado ? $"{valor} km/h" : "--";
|
|
private string TemperaturaValor(string valor) => RoverSelecionado ? $"{valor} °C" : "--";
|
|
private string PercentualOuTracos(string valor) => RoverSelecionado ? $"{valor}%" : "--";
|
|
private string DistanciaOuTracos(string valor) => RoverSelecionado ? $"{valor} m" : "--";
|
|
|
|
private Brush CorPorTexto(string valor)
|
|
{
|
|
var txt = (valor ?? "").Trim().ToLower();
|
|
|
|
if (txt.Contains("excelente") || txt.Contains("ótima") || txt.Contains("otima") || txt.Contains("boa") || txt.Contains("rtk fixed"))
|
|
return Brushes.LightGreen;
|
|
|
|
if (txt.Contains("média") || txt.Contains("media") || txt.Contains("regular") || txt.Contains("float") || txt.Contains("3d"))
|
|
return Brushes.Gold;
|
|
|
|
if (txt.Contains("ruim") || txt.Contains("sem") || txt.Contains("offline") || txt.Contains("falha"))
|
|
return Brushes.OrangeRed;
|
|
|
|
return Brushes.LightGray;
|
|
}
|
|
|
|
public event PropertyChangedEventHandler? PropertyChanged;
|
|
private void OnPropertyChanged(string nome)
|
|
{
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
|
}
|
|
}
|
|
}
|