Criado seção de histórico
This commit is contained in:
parent
523d6924c3
commit
51c9f51f4f
|
|
@ -403,7 +403,7 @@ namespace AgroBase.Models.Modules
|
||||||
RPM_SP = RpmCorrigido;
|
RPM_SP = RpmCorrigido;
|
||||||
FatorCompensacaoCurvasAnterior = FatorCompensacaoCurvas;
|
FatorCompensacaoCurvasAnterior = FatorCompensacaoCurvas;
|
||||||
|
|
||||||
Variaveis.OperacaoEmAndamento.SimulacaoRpmControle = Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP;
|
Variaveis.OperacaoEmAndamento.SimulacaoRpmControle = _Controle.PercentualVelocidadeSP;
|
||||||
//Console.WriteLine($"RPM Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoRpmControle}");
|
//Console.WriteLine($"RPM Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoRpmControle}");
|
||||||
|
|
||||||
switch (DirecaoAtual)
|
switch (DirecaoAtual)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
@ -615,4 +616,132 @@ public class EthernetService
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class StatusRedeInfo
|
||||||
|
{
|
||||||
|
public bool AdaptadorEncontrado { get; set; }
|
||||||
|
public bool AdaptadorOperacional { get; set; }
|
||||||
|
public bool CaboConectado { get; set; }
|
||||||
|
public bool IpValido { get; set; }
|
||||||
|
public bool GatewayValido { get; set; }
|
||||||
|
|
||||||
|
public string NomeInterface { get; set; } = "";
|
||||||
|
public string Ip { get; set; } = "";
|
||||||
|
public string Mascara { get; set; } = "";
|
||||||
|
public string Gateway { get; set; } = "";
|
||||||
|
|
||||||
|
public bool RedeOk { get; set; }
|
||||||
|
public string Detalhes { get; set; } = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StatusRedeInfo ObterStatusRede(string nomeInterface = null, bool exigirGateway = false)
|
||||||
|
{
|
||||||
|
var info = new StatusRedeInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var interfaces = NetworkInterface.GetAllNetworkInterfaces()
|
||||||
|
.Where(ni =>
|
||||||
|
ni.NetworkInterfaceType != NetworkInterfaceType.Loopback &&
|
||||||
|
ni.NetworkInterfaceType != NetworkInterfaceType.Tunnel &&
|
||||||
|
ni.Description.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) < 0 &&
|
||||||
|
ni.Name.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) < 0)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
NetworkInterface niSelecionada = null;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(nomeInterface))
|
||||||
|
{
|
||||||
|
niSelecionada = interfaces.FirstOrDefault(ni =>
|
||||||
|
ni.Name.Equals(nomeInterface, StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
ni.Description.Equals(nomeInterface, StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
ni.Name.IndexOf(nomeInterface, StringComparison.OrdinalIgnoreCase) >= 0 ||
|
||||||
|
ni.Description.IndexOf(nomeInterface, StringComparison.OrdinalIgnoreCase) >= 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
niSelecionada = interfaces
|
||||||
|
.Where(ni =>
|
||||||
|
ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet ||
|
||||||
|
ni.NetworkInterfaceType == NetworkInterfaceType.GigabitEthernet ||
|
||||||
|
ni.Description.IndexOf("Ethernet", StringComparison.OrdinalIgnoreCase) >= 0 ||
|
||||||
|
ni.Name.IndexOf("Ethernet", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||||
|
.OrderByDescending(ni => ni.OperationalStatus == OperationalStatus.Up)
|
||||||
|
.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (niSelecionada == null)
|
||||||
|
{
|
||||||
|
info.Detalhes = "Nenhum adaptador de rede compatível encontrado.";
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.AdaptadorEncontrado = true;
|
||||||
|
info.NomeInterface = niSelecionada.Name;
|
||||||
|
info.AdaptadorOperacional = niSelecionada.OperationalStatus == OperationalStatus.Up;
|
||||||
|
info.CaboConectado = info.AdaptadorOperacional;
|
||||||
|
|
||||||
|
var props = niSelecionada.GetIPProperties();
|
||||||
|
|
||||||
|
var ipv4 = props.UnicastAddresses
|
||||||
|
.FirstOrDefault(a => a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
|
||||||
|
|
||||||
|
var gateway = props.GatewayAddresses
|
||||||
|
.FirstOrDefault(g => g.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
|
||||||
|
|
||||||
|
if (ipv4 != null)
|
||||||
|
{
|
||||||
|
info.Ip = ipv4.Address.ToString();
|
||||||
|
info.Mascara = ipv4.IPv4Mask?.ToString() ?? "";
|
||||||
|
info.IpValido = IpEhValido(info.Ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gateway != null)
|
||||||
|
{
|
||||||
|
info.Gateway = gateway.Address.ToString();
|
||||||
|
info.GatewayValido = IpEhValido(info.Gateway);
|
||||||
|
}
|
||||||
|
|
||||||
|
info.RedeOk =
|
||||||
|
info.AdaptadorEncontrado &&
|
||||||
|
info.CaboConectado &&
|
||||||
|
info.IpValido &&
|
||||||
|
(!exigirGateway || info.GatewayValido);
|
||||||
|
|
||||||
|
info.Detalhes =
|
||||||
|
$"{info.NomeInterface}\n" +
|
||||||
|
$"Cabo: {(info.CaboConectado ? "Conectado" : "Desconectado")}\n" +
|
||||||
|
$"IP: {(!string.IsNullOrWhiteSpace(info.Ip) ? info.Ip : "Não definido")}\n" +
|
||||||
|
$"Máscara: {(!string.IsNullOrWhiteSpace(info.Mascara) ? info.Mascara : "Não definida")}\n" +
|
||||||
|
$"Gateway: {(!string.IsNullOrWhiteSpace(info.Gateway) ? info.Gateway : "Não definido")}\n" +
|
||||||
|
$"Rede OK: {(info.RedeOk ? "Sim" : "Não")}";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
info.RedeOk = false;
|
||||||
|
info.Detalhes = "Erro ao obter status da rede: " + ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IpEhValido(string ip)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(ip))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!IPAddress.TryParse(ip, out var endereco))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (IPAddress.Any.Equals(endereco))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// APIPA: geralmente indica ausência de DHCP/conectividade útil
|
||||||
|
if (ip.StartsWith("169.254."))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
<ComboBox x:Name="CmbBaseMap" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,10,0" Width="189" SelectionChanged="OnBaseMapChanged"/>
|
<ComboBox x:Name="CmbBaseMap" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,10,0" Width="189" SelectionChanged="OnBaseMapChanged"/>
|
||||||
|
|
||||||
<Button Content="Carregar Mapa" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,10,10" Padding="8,4" Background="#2ECC71" Foreground="White" FontWeight="Bold" Click="OnLoadMapClicked"/>
|
<Button Content="Carregar Mapa" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,10,10" Padding="8,4" Background="#2ECC71" Foreground="White" FontWeight="Bold" Click="OnLoadMapClicked" Visibility="Collapsed"/>
|
||||||
<!--<Button Content="Centralizar" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,10,10" Padding="8,4" Background="#2ECC71" Foreground="White" FontWeight="Bold" Click="OnCenterAreaClicked"/>-->
|
<!--<Button Content="Centralizar" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,10,10" Padding="8,4" Background="#2ECC71" Foreground="White" FontWeight="Bold" Click="OnCenterAreaClicked"/>-->
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
@ -930,6 +930,14 @@ namespace OperationControl.Controls
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void LimparRastrosRover(string? roverId, bool limparPredicao = true)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(roverId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
markers?.ClearMarkerTrail(roverId, limparPredicao);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MapMarkerManager
|
public class MapMarkerManager
|
||||||
|
|
@ -1089,6 +1097,19 @@ namespace OperationControl.Controls
|
||||||
UpdateFeatures();
|
UpdateFeatures();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void ClearMarkerTrail(string id, bool clearPrediction = true)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(id)) return;
|
||||||
|
|
||||||
|
var marker = _features.FirstOrDefault(x => x.Id == id);
|
||||||
|
if (marker == null) return;
|
||||||
|
|
||||||
|
marker.ClearTrajectory(clearPrediction);
|
||||||
|
_map.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class MapMarkerDictionaryModel
|
public class MapMarkerDictionaryModel
|
||||||
{
|
{
|
||||||
public void CreateTrajectory(MapControl _map)
|
public void CreateTrajectory(MapControl _map)
|
||||||
|
|
@ -1344,6 +1365,34 @@ namespace OperationControl.Controls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void ClearTrajectory(bool clearPrediction = true)
|
||||||
|
{
|
||||||
|
_trajFeatures.Clear();
|
||||||
|
|
||||||
|
if (_trajLayer != null)
|
||||||
|
{
|
||||||
|
_trajLayer.DataSource = new MemoryProvider(_trajFeatures);
|
||||||
|
_trajLayer.DataHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clearPrediction)
|
||||||
|
{
|
||||||
|
_predFeatures.Clear();
|
||||||
|
|
||||||
|
if (_predLayer != null)
|
||||||
|
{
|
||||||
|
_predLayer.DataSource = new MemoryProvider(_predFeatures);
|
||||||
|
_predLayer.DataHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reseta a posição base do rastro para a posição atual do rover,
|
||||||
|
// evitando que ao voltar a andar ele desenhe uma linha gigante do passado.
|
||||||
|
var (x, y) = Mapsui.Projections.SphericalMercator.FromLonLat(Lon, Lat);
|
||||||
|
Position = new Coordinate(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#region TRAJETORIA
|
#region TRAJETORIA
|
||||||
|
|
||||||
private MemoryProvider _trajProvider;
|
private MemoryProvider _trajProvider;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ namespace OperationControl.Models
|
||||||
? $"{Modulo} ({Mod_ID})"
|
? $"{Modulo} ({Mod_ID})"
|
||||||
: Modulo.ToString();
|
: Modulo.ToString();
|
||||||
|
|
||||||
return $"[{Rover_ID}] {mod} — {ResumoSeveridade}";
|
//return $"[{Rover_ID}] {mod} — {ResumoSeveridade}";
|
||||||
|
return $"{mod} — {ResumoSeveridade}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,7 @@ namespace OperationControl.Models
|
||||||
{
|
{
|
||||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
{
|
{
|
||||||
(Dock?.DataContext as DockWindowViewModel)?.AdicionarAlerta(roverId, modulo, severidade, mensagem, modId);
|
Dock?._vm?.AdicionarAlerta(roverId, modulo, severidade, mensagem, modId);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -212,7 +212,7 @@ namespace OperationControl.Models
|
||||||
{
|
{
|
||||||
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
{
|
{
|
||||||
(Dock?.DataContext as DockWindowViewModel)?.RemoverAlerta(roverId, modulo, severidade, modId);
|
Dock?._vm?.RemoverAlerta(roverId, modulo, severidade, modId);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using OperationControl.Services;
|
||||||
using AgroMonitor;
|
using AgroMonitor;
|
||||||
using Application = System.Windows.Application;
|
using Application = System.Windows.Application;
|
||||||
using AgroBase.Models.Operacoes;
|
using AgroBase.Models.Operacoes;
|
||||||
|
using OperationControl.Windows;
|
||||||
|
|
||||||
namespace OperationControl.Models
|
namespace OperationControl.Models
|
||||||
{
|
{
|
||||||
|
|
@ -15,6 +16,8 @@ namespace OperationControl.Models
|
||||||
public static UdpReliableChannel UdpChannel;
|
public static UdpReliableChannel UdpChannel;
|
||||||
public static ManualControlSender ControlSenderDir;
|
public static ManualControlSender ControlSenderDir;
|
||||||
public static ManualControlSender ControlSenderMov;
|
public static ManualControlSender ControlSenderMov;
|
||||||
|
public static AppShell? Shell => ((App)Application.Current)?.Shell;
|
||||||
|
public static DockWindow? Dock => Shell?.Dock;
|
||||||
|
|
||||||
public static void MostrarLog(string message)
|
public static void MostrarLog(string message)
|
||||||
{
|
{
|
||||||
|
|
@ -163,11 +166,11 @@ namespace OperationControl.Models
|
||||||
rover.UltimoContato = DateTime.Now;
|
rover.UltimoContato = DateTime.Now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
((App)Application.Current).Shell.Main?.AtualizarDadosTela_Telemetria(device_id);
|
//((App)Application.Current).Shell.Main?.AtualizarDadosTela_Telemetria(device_id);
|
||||||
|
|
||||||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
{
|
{
|
||||||
((App)Application.Current).Shell.Dock?._vm?.AtualizarDadosTela(rover);
|
Variaveis.Dock?._vm?.AtualizarDadosTela(rover);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -195,9 +198,9 @@ namespace OperationControl.Models
|
||||||
RoversNaRede[index] = obj;
|
RoversNaRede[index] = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
((App)Application.Current).Shell.Main?.AtualizarDadosTela_ParametrosOperacao(obj.Controle);
|
//((App)Application.Current).Shell.Main?.AtualizarDadosTela_ParametrosOperacao(obj.Controle);
|
||||||
((App)Application.Current).Shell.Main?.MAP?.CarregarDadosMapa(obj.Mapa, obj.RuasPercorrer);
|
//((App)Application.Current).Shell.Main?.MAP?.CarregarDadosMapa(obj.Mapa, obj.RuasPercorrer);
|
||||||
((App)Application.Current).Shell.Dock?._vm?.AtualizarParametrosRover(obj);
|
Variaveis.Dock?._vm?.AtualizarParametrosRover(obj);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -211,7 +214,7 @@ namespace OperationControl.Models
|
||||||
{
|
{
|
||||||
dispositivos_ids = dispositivos_ids.Union(RoversNaRede.Select(x => x.RoverId).ToList()).ToList();
|
dispositivos_ids = dispositivos_ids.Union(RoversNaRede.Select(x => x.RoverId).ToList()).ToList();
|
||||||
}
|
}
|
||||||
((App)Application.Current).Shell.Main?.AtualizarListaDispositivos(dispositivos_ids);
|
//((App)Application.Current).Shell.Main?.AtualizarListaDispositivos(dispositivos_ids);
|
||||||
|
|
||||||
RequisitarParametrosOperacao();
|
RequisitarParametrosOperacao();
|
||||||
}
|
}
|
||||||
|
|
@ -244,24 +247,24 @@ namespace OperationControl.Models
|
||||||
rover.DadosLeitura.Momento = DateTime.Now;
|
rover.DadosLeitura.Momento = DateTime.Now;
|
||||||
if (rover.DadosLeitura.Operacao == null) rover.DadosLeitura.Operacao = new OperacaoParametrosDadosOperacaoModel();
|
if (rover.DadosLeitura.Operacao == null) rover.DadosLeitura.Operacao = new OperacaoParametrosDadosOperacaoModel();
|
||||||
rover.DadosLeitura.Operacao.Status = AgroBase.Models.Enums.StatusOperacao.Erro;
|
rover.DadosLeitura.Operacao.Status = AgroBase.Models.Enums.StatusOperacao.Erro;
|
||||||
((App)Application.Current)?.Shell?.Main?.AtualizarDadosTela_Telemetria(rover.RoverId);
|
//((App)Application.Current)?.Shell?.Main?.AtualizarDadosTela_Telemetria(rover.RoverId);
|
||||||
((App)Application.Current)?.Shell?.Main?.AdicionarAlerta(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb, SeveridadeAlerta.Critical, "Perda de comunicação com o equipamento!");
|
//((App)Application.Current)?.Shell?.Main?.AdicionarAlerta(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb, SeveridadeAlerta.Critical, "Perda de comunicação com o equipamento!");
|
||||||
|
|
||||||
|
|
||||||
((App)Application.Current)?.Shell?.AdicionarAlertaDock(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb, SeveridadeAlerta.Critical, "Perda de comunicação com o equipamento!");
|
Variaveis.Shell?.AdicionarAlertaDock(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb, SeveridadeAlerta.Critical, "Perda de comunicação com o equipamento!");
|
||||||
((App)Application.Current)?.Shell?.Dock?._vm?._viewOperacaoCenter?.Mapa?.markers?.UpdateMarkerInfo(rover.RoverId, status: AgroBase.Models.Enums.StatusOperacao.Erro);
|
Variaveis.Dock?._vm?._viewOperacaoCenter?.Mapa?.markers?.UpdateMarkerInfo(rover.RoverId, status: AgroBase.Models.Enums.StatusOperacao.Erro);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
((App)Application.Current)?.Shell?.Main?.RemoverAlerta(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb);
|
//((App)Application.Current)?.Shell?.Main?.RemoverAlerta(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb);
|
||||||
((App)Application.Current)?.Shell?.RemoverAlertaDock(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb);
|
Variaveis.Shell?.RemoverAlertaDock(rover.RoverId, AgroBase.Models.Enums.T_Code.Ipb);
|
||||||
}
|
}
|
||||||
((App)Application.Current)?.Shell?.Dock?._vm?.AtualizarBarraSuperior(rover);
|
Variaveis.Shell?.Dock?._vm?.AtualizarBarraSuperior(rover);
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.Current?.Dispatcher?.BeginInvoke(new Action(() =>
|
Application.Current?.Dispatcher?.BeginInvoke(new Action(() =>
|
||||||
{
|
{
|
||||||
((App)Application.Current)?.Shell?.Dock?._vm?.AtualizarListaRovers(rovers_atual);
|
Variaveis.Shell?.Dock?._vm?.AtualizarListaRovers(rovers_atual);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,9 @@
|
||||||
<Compile Update="Views\Operacao\Monitoramento\DiagnosticoView.xaml.cs">
|
<Compile Update="Views\Operacao\Monitoramento\DiagnosticoView.xaml.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Update="Views\Operacao\Monitoramento\HistoricoView.xaml.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Update="Views\Operacao\Monitoramento\MonitoramentoView.xaml.cs">
|
<Compile Update="Views\Operacao\Monitoramento\MonitoramentoView.xaml.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
@ -138,6 +141,9 @@
|
||||||
<Page Update="Views\Operacao\Monitoramento\DiagnosticoView.xaml">
|
<Page Update="Views\Operacao\Monitoramento\DiagnosticoView.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Update="Views\Operacao\Monitoramento\HistoricoView.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
<Page Update="Views\Operacao\Monitoramento\MonitoramentoView.xaml">
|
<Page Update="Views\Operacao\Monitoramento\MonitoramentoView.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
|
|
|
||||||
|
|
@ -368,8 +368,7 @@ namespace OperationControl.Services
|
||||||
}
|
}
|
||||||
|
|
||||||
Models.Variaveis.MostrarLog(mensagem);
|
Models.Variaveis.MostrarLog(mensagem);
|
||||||
((App)Application.Current)?.Shell?.Dock?._vm?._viewPreparacaoMapaBottom?._vm?.FinalizarFixacao(sucesso, mensagem);
|
Models.Variaveis.Dock?._vm?.FinalizarFixacaoBase(sucesso, mensagem);
|
||||||
((App)Application.Current)?.Shell?.Dock?._vm?.FinalizarFixacaoBase(sucesso, mensagem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ConfigurarModuloBase(string porta_usb = "com3", string porta_saida = "com2", int tempo_fixacao = 60)
|
private async Task ConfigurarModuloBase(string porta_usb = "com3", string porta_saida = "com2", int tempo_fixacao = 60)
|
||||||
|
|
@ -1223,9 +1222,9 @@ namespace OperationControl.Services
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
((App)Application.Current).Shell.Main?.AtualizarDadosTela_Telemetria(VariaveisControleOperacao.BaseMarkerID);
|
//((App)Application.Current).Shell.Main?.AtualizarDadosTela_Telemetria(VariaveisControleOperacao.BaseMarkerID);
|
||||||
|
|
||||||
((App)Application.Current).Shell.Dock?._vm?.AtualizarDadosGnss(UltimaLeitura);
|
Models.Variaveis.Dock?._vm?.AtualizarDadosGnss(UltimaLeitura);
|
||||||
}
|
}
|
||||||
catch (Exception exUi)
|
catch (Exception exUi)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -248,21 +248,17 @@ namespace OperationControl.ViewModels
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 1) Escolhe a interface “ativa” ou a que você usa pra ponte IP
|
var interfaces = EthernetService.ObterNomesInterfaces()
|
||||||
// Se você já tem isso fixo, melhor ainda: use sempre a mesma.
|
.Where(x => x.Contains(AppShell.Mock ? "Ativa" : "Ethernet"))
|
||||||
var interfaces = EthernetService.ObterNomesInterfaces().Where(x => x.Contains("Ativa")).Select(x => x.Split('(')[0].Trim()).ToList();
|
.Select(x => x.Split('(')[0].Trim())
|
||||||
var iface = interfaces[0]; // <-- se tiver
|
.ToList();
|
||||||
// ou se você já sabe o nome: var iface = "Ethernet 2";
|
|
||||||
|
|
||||||
var ip = EthernetService.ObterIpAtual(iface);
|
string? iface = interfaces.FirstOrDefault();
|
||||||
var sub = EthernetService.ObterSubnetMaskAtual(iface);
|
|
||||||
var gw = EthernetService.ObterIpGateway(iface);
|
|
||||||
|
|
||||||
DetalhesRede = $"{iface}\nIP: {ip}\nMáscara: {sub}\nGateway: {gw}";
|
var status = EthernetService.ObterStatusRede(iface, exigirGateway: false);
|
||||||
|
|
||||||
// 2) Define RedeOk do jeito que faz sentido pra você:
|
RedeOk = status.RedeOk;
|
||||||
// exemplo simples: tem IP válido + gateway válido
|
DetalhesRede = status.Detalhes;
|
||||||
RedeOk = !string.IsNullOrWhiteSpace(ip) && ip != "0.0.0.0";
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,397 @@
|
||||||
|
using OperationControl.Models;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
namespace OperationControl.ViewModels.Views.Operacao.Monitoramento
|
||||||
|
{
|
||||||
|
public class HistoricoViewModel : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
public HistoricoViewModel()
|
||||||
|
{
|
||||||
|
EventosView = CollectionViewSource.GetDefaultView(Eventos);
|
||||||
|
EventosView.Filter = FiltrarEvento;
|
||||||
|
|
||||||
|
_ordenacaoSelecionada = "Mais recentes";
|
||||||
|
|
||||||
|
AplicarOrdenacao();
|
||||||
|
AtualizarFiltros();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MotivoTopBarModel> _eventosTopBarAnteriores = new();
|
||||||
|
|
||||||
|
private ObservableCollection<HistoricoOperacaoItemModel> _eventos = new();
|
||||||
|
public ObservableCollection<HistoricoOperacaoItemModel> Eventos
|
||||||
|
{
|
||||||
|
get => _eventos;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_eventos = value;
|
||||||
|
OnPropertyChanged(nameof(Eventos));
|
||||||
|
|
||||||
|
EventosView = CollectionViewSource.GetDefaultView(Eventos);
|
||||||
|
EventosView.Filter = FiltrarEvento;
|
||||||
|
AplicarOrdenacao();
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(EventosView));
|
||||||
|
OnPropertyChanged(nameof(QuantidadeEventos));
|
||||||
|
OnPropertyChanged(nameof(QuantidadeEventosFiltrados));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ICollectionView _eventosView;
|
||||||
|
public ICollectionView EventosView
|
||||||
|
{
|
||||||
|
get => _eventosView;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_eventosView = value;
|
||||||
|
OnPropertyChanged(nameof(EventosView));
|
||||||
|
OnPropertyChanged(nameof(QuantidadeEventosFiltrados));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int QuantidadeEventos => Eventos?.Count ?? 0;
|
||||||
|
|
||||||
|
public int QuantidadeEventosFiltrados
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (EventosView == null) return 0;
|
||||||
|
return EventosView.Cast<object>().Count();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _textoBusca;
|
||||||
|
public string TextoBusca
|
||||||
|
{
|
||||||
|
get => _textoBusca;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_textoBusca == value) return;
|
||||||
|
_textoBusca = value;
|
||||||
|
OnPropertyChanged(nameof(TextoBusca));
|
||||||
|
AtualizarFiltros();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _roverIdSelecionado;
|
||||||
|
public string RoverIdSelecionado
|
||||||
|
{
|
||||||
|
get => _roverIdSelecionado;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_roverIdSelecionado == value) return;
|
||||||
|
_roverIdSelecionado = value;
|
||||||
|
OnPropertyChanged(nameof(RoverIdSelecionado));
|
||||||
|
AtualizarFiltros();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _tipoTransicaoSelecionado = "Todos";
|
||||||
|
public string TipoTransicaoSelecionado
|
||||||
|
{
|
||||||
|
get => _tipoTransicaoSelecionado;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_tipoTransicaoSelecionado == value) return;
|
||||||
|
_tipoTransicaoSelecionado = value;
|
||||||
|
OnPropertyChanged(nameof(TipoTransicaoSelecionado));
|
||||||
|
AtualizarFiltros();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _statusSelecionado = "Todos";
|
||||||
|
public string StatusSelecionado
|
||||||
|
{
|
||||||
|
get => _statusSelecionado;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_statusSelecionado == value) return;
|
||||||
|
_statusSelecionado = value;
|
||||||
|
OnPropertyChanged(nameof(StatusSelecionado));
|
||||||
|
AtualizarFiltros();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _fonteSelecionada = "Todas";
|
||||||
|
public string FonteSelecionada
|
||||||
|
{
|
||||||
|
get => _fonteSelecionada;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_fonteSelecionada == value) return;
|
||||||
|
_fonteSelecionada = value;
|
||||||
|
OnPropertyChanged(nameof(FonteSelecionada));
|
||||||
|
AtualizarFiltros();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _ordenacaoSelecionada;
|
||||||
|
public string OrdenacaoSelecionada
|
||||||
|
{
|
||||||
|
get => _ordenacaoSelecionada;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_ordenacaoSelecionada == value) return;
|
||||||
|
_ordenacaoSelecionada = value;
|
||||||
|
OnPropertyChanged(nameof(OrdenacaoSelecionada));
|
||||||
|
AplicarOrdenacao();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> TiposTransicaoDisponiveis { get; } = new()
|
||||||
|
{
|
||||||
|
"Todos",
|
||||||
|
"INICIO",
|
||||||
|
"FIM",
|
||||||
|
"MUDANCA"
|
||||||
|
};
|
||||||
|
|
||||||
|
public List<string> StatusDisponiveis { get; } = new()
|
||||||
|
{
|
||||||
|
"Todos",
|
||||||
|
"Falha",
|
||||||
|
"Alerta",
|
||||||
|
"Desconectado",
|
||||||
|
"Operante",
|
||||||
|
"Conectado"
|
||||||
|
};
|
||||||
|
|
||||||
|
public List<string> FontesDisponiveis { get; } = new()
|
||||||
|
{
|
||||||
|
"Todas",
|
||||||
|
"Normal",
|
||||||
|
"Comunicacao",
|
||||||
|
"Emergencia",
|
||||||
|
"Pausa",
|
||||||
|
"Controle",
|
||||||
|
"Trajetoria",
|
||||||
|
"ModuloCritico",
|
||||||
|
"NCP",
|
||||||
|
"AlertaModulo"
|
||||||
|
};
|
||||||
|
|
||||||
|
public List<string> OrdenacoesDisponiveis { get; } = new()
|
||||||
|
{
|
||||||
|
"Mais recentes",
|
||||||
|
"Mais antigos",
|
||||||
|
"Título (A-Z)",
|
||||||
|
"Fonte (A-Z)",
|
||||||
|
"Status"
|
||||||
|
};
|
||||||
|
|
||||||
|
private bool FiltrarEvento(object obj)
|
||||||
|
{
|
||||||
|
if (obj is not HistoricoOperacaoItemModel ev)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// filtro padrão por rover selecionado
|
||||||
|
if (!string.IsNullOrWhiteSpace(RoverIdSelecionado) &&
|
||||||
|
!string.Equals(ev.RoverId, RoverIdSelecionado, StringComparison.OrdinalIgnoreCase))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(TipoTransicaoSelecionado) &&
|
||||||
|
TipoTransicaoSelecionado != "Todos" &&
|
||||||
|
!string.Equals(ev.TipoTransicao, TipoTransicaoSelecionado, StringComparison.OrdinalIgnoreCase))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(StatusSelecionado) &&
|
||||||
|
StatusSelecionado != "Todos" &&
|
||||||
|
!string.Equals(ev.StatusVisual.ToString(), StatusSelecionado, StringComparison.OrdinalIgnoreCase))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(FonteSelecionada) &&
|
||||||
|
FonteSelecionada != "Todas" &&
|
||||||
|
!string.Equals(ev.Fonte, FonteSelecionada, StringComparison.OrdinalIgnoreCase))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(TextoBusca))
|
||||||
|
{
|
||||||
|
var busca = TextoBusca.Trim();
|
||||||
|
|
||||||
|
bool encontrou =
|
||||||
|
(ev.Titulo?.Contains(busca, StringComparison.OrdinalIgnoreCase) ?? false) ||
|
||||||
|
(ev.Descricao?.Contains(busca, StringComparison.OrdinalIgnoreCase) ?? false) ||
|
||||||
|
(ev.Fonte?.Contains(busca, StringComparison.OrdinalIgnoreCase) ?? false) ||
|
||||||
|
(ev.RoverId?.Contains(busca, StringComparison.OrdinalIgnoreCase) ?? false) ||
|
||||||
|
(ev.TipoTransicao?.Contains(busca, StringComparison.OrdinalIgnoreCase) ?? false) ||
|
||||||
|
(ev.Modulo?.ToString().Contains(busca, StringComparison.OrdinalIgnoreCase) ?? false);
|
||||||
|
|
||||||
|
if (!encontrou)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AtualizarFiltros()
|
||||||
|
{
|
||||||
|
EventosView?.Refresh();
|
||||||
|
OnPropertyChanged(nameof(QuantidadeEventosFiltrados));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AplicarOrdenacao()
|
||||||
|
{
|
||||||
|
if (EventosView == null) return;
|
||||||
|
|
||||||
|
using (EventosView.DeferRefresh())
|
||||||
|
{
|
||||||
|
EventosView.SortDescriptions.Clear();
|
||||||
|
|
||||||
|
switch (OrdenacaoSelecionada)
|
||||||
|
{
|
||||||
|
case "Mais antigos":
|
||||||
|
EventosView.SortDescriptions.Add(new SortDescription(nameof(HistoricoOperacaoItemModel.DataHora), ListSortDirection.Ascending));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Título (A-Z)":
|
||||||
|
EventosView.SortDescriptions.Add(new SortDescription(nameof(HistoricoOperacaoItemModel.Titulo), ListSortDirection.Ascending));
|
||||||
|
EventosView.SortDescriptions.Add(new SortDescription(nameof(HistoricoOperacaoItemModel.DataHora), ListSortDirection.Descending));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Fonte (A-Z)":
|
||||||
|
EventosView.SortDescriptions.Add(new SortDescription(nameof(HistoricoOperacaoItemModel.Fonte), ListSortDirection.Ascending));
|
||||||
|
EventosView.SortDescriptions.Add(new SortDescription(nameof(HistoricoOperacaoItemModel.DataHora), ListSortDirection.Descending));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Status":
|
||||||
|
EventosView.SortDescriptions.Add(new SortDescription(nameof(HistoricoOperacaoItemModel.StatusVisual), ListSortDirection.Ascending));
|
||||||
|
EventosView.SortDescriptions.Add(new SortDescription(nameof(HistoricoOperacaoItemModel.DataHora), ListSortDirection.Descending));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
EventosView.SortDescriptions.Add(new SortDescription(nameof(HistoricoOperacaoItemModel.DataHora), ListSortDirection.Descending));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(QuantidadeEventosFiltrados));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LimparBusca()
|
||||||
|
{
|
||||||
|
TextoBusca = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetarFiltros()
|
||||||
|
{
|
||||||
|
RoverIdSelecionado = VariaveisControleOperacao.SelectedRoverId;
|
||||||
|
TextoBusca = string.Empty;
|
||||||
|
TipoTransicaoSelecionado = "Todos";
|
||||||
|
StatusSelecionado = "Todos";
|
||||||
|
FonteSelecionada = "Todas";
|
||||||
|
OrdenacaoSelecionada = "Mais recentes";
|
||||||
|
AtualizarFiltros();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CompararERegistrarMudancasEventos(string roverId, List<MotivoTopBarModel> eventosAtuais)
|
||||||
|
{
|
||||||
|
string Chave(MotivoTopBarModel e) =>
|
||||||
|
$"{e.Fonte}|{e.Titulo}|{e.Descricao}|{e.Modulo}|{e.StatusVisual}";
|
||||||
|
|
||||||
|
var atuais = eventosAtuais?
|
||||||
|
.GroupBy(Chave)
|
||||||
|
.ToDictionary(g => g.Key, g => g.First())
|
||||||
|
?? new Dictionary<string, MotivoTopBarModel>();
|
||||||
|
|
||||||
|
var anteriores = _eventosTopBarAnteriores?
|
||||||
|
.GroupBy(Chave)
|
||||||
|
.ToDictionary(g => g.Key, g => g.First())
|
||||||
|
?? new Dictionary<string, MotivoTopBarModel>();
|
||||||
|
|
||||||
|
foreach (var chave in anteriores.Keys.Except(atuais.Keys))
|
||||||
|
RegistrarLogEvento(roverId, "FIM", anteriores[chave]);
|
||||||
|
|
||||||
|
foreach (var chave in atuais.Keys.Except(anteriores.Keys))
|
||||||
|
RegistrarLogEvento(roverId, "INICIO", atuais[chave]);
|
||||||
|
|
||||||
|
_eventosTopBarAnteriores = eventosAtuais?
|
||||||
|
.Select(x => new MotivoTopBarModel
|
||||||
|
{
|
||||||
|
Prioridade = x.Prioridade,
|
||||||
|
Fonte = x.Fonte,
|
||||||
|
Titulo = x.Titulo,
|
||||||
|
Descricao = x.Descricao,
|
||||||
|
StatusVisual = x.StatusVisual,
|
||||||
|
Modulo = x.Modulo
|
||||||
|
})
|
||||||
|
.ToList() ?? new List<MotivoTopBarModel>();
|
||||||
|
|
||||||
|
_roverIdSelecionado = VariaveisControleOperacao.SelectedRoverId;
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(QuantidadeEventos));
|
||||||
|
OnPropertyChanged(nameof(QuantidadeEventosFiltrados));
|
||||||
|
OnPropertyChanged(nameof(RoverIdSelecionado));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegistrarLogEvento(string roverId, string tipoTransicao, MotivoTopBarModel ev)
|
||||||
|
{
|
||||||
|
if (ev == null) return;
|
||||||
|
|
||||||
|
var item = new HistoricoOperacaoItemModel
|
||||||
|
{
|
||||||
|
DataHora = DateTime.Now,
|
||||||
|
RoverId = roverId,
|
||||||
|
Tipo = TipoHistoricoOperacao.Operacao,
|
||||||
|
TipoTransicao = tipoTransicao,
|
||||||
|
Fonte = ev.Fonte,
|
||||||
|
Titulo = ev.Titulo,
|
||||||
|
Descricao = ev.Descricao,
|
||||||
|
StatusVisual = ev.StatusVisual,
|
||||||
|
Modulo = ev.Modulo
|
||||||
|
};
|
||||||
|
|
||||||
|
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
Eventos.Insert(0, item);
|
||||||
|
|
||||||
|
if (Eventos.Count > 2000)
|
||||||
|
Eventos.RemoveAt(Eventos.Count - 1);
|
||||||
|
|
||||||
|
AtualizarFiltros();
|
||||||
|
OnPropertyChanged(nameof(QuantidadeEventos));
|
||||||
|
OnPropertyChanged(nameof(QuantidadeEventosFiltrados));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegistrarHistoricoAlerta(string tipoTransicao, AlertaModel alerta)
|
||||||
|
{
|
||||||
|
if (alerta == null) return;
|
||||||
|
|
||||||
|
var item = new HistoricoOperacaoItemModel
|
||||||
|
{
|
||||||
|
DataHora = DateTime.Now,
|
||||||
|
RoverId = alerta.Rover_ID,
|
||||||
|
Tipo = TipoHistoricoOperacao.Alerta,
|
||||||
|
TipoTransicao = tipoTransicao,
|
||||||
|
Fonte = "AlertaModulo",
|
||||||
|
Titulo = alerta.Titulo,
|
||||||
|
Descricao = alerta.Mensagem,
|
||||||
|
SeveridadeAlerta = alerta.Severidade,
|
||||||
|
Modulo = alerta.Modulo,
|
||||||
|
ModId = alerta.Mod_ID
|
||||||
|
};
|
||||||
|
|
||||||
|
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
Eventos.Insert(0, item);
|
||||||
|
|
||||||
|
if (Eventos.Count > 2000)
|
||||||
|
Eventos.RemoveAt(Eventos.Count - 1);
|
||||||
|
|
||||||
|
AtualizarFiltros();
|
||||||
|
OnPropertyChanged(nameof(QuantidadeEventos));
|
||||||
|
OnPropertyChanged(nameof(QuantidadeEventosFiltrados));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
private void OnPropertyChanged(string nome)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using OperationControl.Models;
|
using OperationControl.Models;
|
||||||
|
using OperationControl.ViewModels.Views.Operacao.Monitoramento;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
@ -8,6 +9,7 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
{
|
{
|
||||||
public class OperacaoBottomViewModel : INotifyPropertyChanged
|
public class OperacaoBottomViewModel : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
|
private HistoricoViewModel? historicoVm => Variaveis.Dock?._vm?._viewOperacaoCenter?.Historico?._vm;
|
||||||
public ObservableCollection<AlertaModel> AlertasAtivos { get; } = new();
|
public ObservableCollection<AlertaModel> AlertasAtivos { get; } = new();
|
||||||
|
|
||||||
private AlertaModel _toastAlerta;
|
private AlertaModel _toastAlerta;
|
||||||
|
|
@ -87,11 +89,21 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
|
|
||||||
AlertasAtivos.Add(alerta);
|
AlertasAtivos.Add(alerta);
|
||||||
MostrarToast(alerta);
|
MostrarToast(alerta);
|
||||||
|
|
||||||
|
historicoVm?.RegistrarHistoricoAlerta("INICIO", alerta);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
bool mudouMensagem = existente.Mensagem != mensagem;
|
||||||
|
bool mudouSeveridade = existente.Severidade != severidade;
|
||||||
|
|
||||||
existente.Mensagem = mensagem;
|
existente.Mensagem = mensagem;
|
||||||
existente.Severidade = severidade;
|
existente.Severidade = severidade;
|
||||||
|
|
||||||
|
if (mudouMensagem || mudouSeveridade)
|
||||||
|
{
|
||||||
|
historicoVm?.RegistrarHistoricoAlerta("MUDANCA", existente);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +119,10 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
(severidade != null ? x.Severidade == severidade : true));
|
(severidade != null ? x.Severidade == severidade : true));
|
||||||
|
|
||||||
if (alerta != null)
|
if (alerta != null)
|
||||||
|
{
|
||||||
|
historicoVm?.RegistrarHistoricoAlerta("FIM", alerta);
|
||||||
AlertasAtivos.Remove(alerta);
|
AlertasAtivos.Remove(alerta);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,6 +281,8 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
{
|
{
|
||||||
var alertaRemover = mapaAtual[chave];
|
var alertaRemover = mapaAtual[chave];
|
||||||
|
|
||||||
|
historicoVm?.RegistrarHistoricoAlerta("FIM", alertaRemover);
|
||||||
|
|
||||||
AlertasAtivos.Remove(alertaRemover);
|
AlertasAtivos.Remove(alertaRemover);
|
||||||
|
|
||||||
if (ToastAlerta == alertaRemover)
|
if (ToastAlerta == alertaRemover)
|
||||||
|
|
@ -284,6 +301,8 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
esperado.CriadoEm = agora;
|
esperado.CriadoEm = agora;
|
||||||
AlertasAtivos.Add(esperado);
|
AlertasAtivos.Add(esperado);
|
||||||
MostrarToast(esperado);
|
MostrarToast(esperado);
|
||||||
|
|
||||||
|
historicoVm?.RegistrarHistoricoAlerta("INICIO", esperado);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -296,11 +315,11 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
{
|
{
|
||||||
existente.Mensagem = esperado.Mensagem;
|
existente.Mensagem = esperado.Mensagem;
|
||||||
existente.Severidade = esperado.Severidade;
|
existente.Severidade = esperado.Severidade;
|
||||||
|
|
||||||
// Se quiser que Timestamp represente "última mudança", mantém isso:
|
|
||||||
existente.AtualizadoEm = agora;
|
existente.AtualizadoEm = agora;
|
||||||
|
|
||||||
MostrarToast(existente);
|
MostrarToast(existente);
|
||||||
|
|
||||||
|
historicoVm?.RegistrarHistoricoAlerta("MUDANCA", existente);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
OnPropertyChanged(nameof(ExibirMapa));
|
OnPropertyChanged(nameof(ExibirMapa));
|
||||||
OnPropertyChanged(nameof(ExibirDiagnostico));
|
OnPropertyChanged(nameof(ExibirDiagnostico));
|
||||||
OnPropertyChanged(nameof(ExibirMonitoramento));
|
OnPropertyChanged(nameof(ExibirMonitoramento));
|
||||||
|
OnPropertyChanged(nameof(ExibirHistorico));
|
||||||
OnPropertyChanged(nameof(TituloCentro));
|
OnPropertyChanged(nameof(TituloCentro));
|
||||||
OnPropertyChanged(nameof(SubtituloCentro));
|
OnPropertyChanged(nameof(SubtituloCentro));
|
||||||
}
|
}
|
||||||
|
|
@ -49,6 +50,7 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
public bool ExibirMapa => ConteudoAtual == OperacaoCenterConteudo.Mapa;
|
public bool ExibirMapa => ConteudoAtual == OperacaoCenterConteudo.Mapa;
|
||||||
public bool ExibirDiagnostico => ConteudoAtual == OperacaoCenterConteudo.Diagnostico;
|
public bool ExibirDiagnostico => ConteudoAtual == OperacaoCenterConteudo.Diagnostico;
|
||||||
public bool ExibirMonitoramento => ConteudoAtual == OperacaoCenterConteudo.Monitoramento;
|
public bool ExibirMonitoramento => ConteudoAtual == OperacaoCenterConteudo.Monitoramento;
|
||||||
|
public bool ExibirHistorico => ConteudoAtual == OperacaoCenterConteudo.Historico;
|
||||||
|
|
||||||
public string TituloCentro
|
public string TituloCentro
|
||||||
{
|
{
|
||||||
|
|
@ -101,6 +103,7 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
SecaoRightBar.Controle => OperacaoCenterConteudo.Monitoramento,
|
SecaoRightBar.Controle => OperacaoCenterConteudo.Monitoramento,
|
||||||
SecaoRightBar.Parametrizacao => OperacaoCenterConteudo.Mapa,
|
SecaoRightBar.Parametrizacao => OperacaoCenterConteudo.Mapa,
|
||||||
SecaoRightBar.Menu => OperacaoCenterConteudo.Monitoramento,
|
SecaoRightBar.Menu => OperacaoCenterConteudo.Monitoramento,
|
||||||
|
SecaoRightBar.Historico => OperacaoCenterConteudo.Historico,
|
||||||
|
|
||||||
_ => OperacaoCenterConteudo.Mapa
|
_ => OperacaoCenterConteudo.Mapa
|
||||||
};
|
};
|
||||||
|
|
@ -142,6 +145,7 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
{
|
{
|
||||||
Mapa = 1,
|
Mapa = 1,
|
||||||
Diagnostico = 2,
|
Diagnostico = 2,
|
||||||
Monitoramento = 3
|
Monitoramento = 3,
|
||||||
|
Historico = 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -338,6 +338,7 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
|
Variaveis.Dock?._vm?._viewOperacaoCenter?.Mapa?.LimparRastrosRover(VariaveisControleOperacao.RoverEmFoco?.RoverId);
|
||||||
if ((dadosRover?.Operacao?.Status ?? StatusOperacao.NaoIniciado) == StatusOperacao.Concluido)
|
if ((dadosRover?.Operacao?.Status ?? StatusOperacao.NaoIniciado) == StatusOperacao.Concluido)
|
||||||
{
|
{
|
||||||
VariaveisControleOperacao.EnviarComandoIniciarOperacao(false, false);
|
VariaveisControleOperacao.EnviarComandoIniciarOperacao(false, false);
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool EmMenu => SecaoAtual == SecaoRightBar.Menu || SecaoAtual == SecaoRightBar.Diagnostico;
|
public bool EmMenu => new List<SecaoRightBar>() { SecaoRightBar.Menu, SecaoRightBar.Diagnostico, SecaoRightBar.Historico }.Contains(SecaoAtual);
|
||||||
public bool EmResumo => SecaoAtual == SecaoRightBar.Resumo;
|
public bool EmResumo => SecaoAtual == SecaoRightBar.Resumo;
|
||||||
public bool EmParametrizacao => SecaoAtual == SecaoRightBar.Parametrizacao;
|
public bool EmParametrizacao => SecaoAtual == SecaoRightBar.Parametrizacao;
|
||||||
public bool EmControle => SecaoAtual == SecaoRightBar.Controle;
|
public bool EmControle => SecaoAtual == SecaoRightBar.Controle;
|
||||||
|
|
@ -264,7 +264,8 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
Resumo = 2,
|
Resumo = 2,
|
||||||
Diagnostico = 3,
|
Diagnostico = 3,
|
||||||
Parametrizacao = 4,
|
Parametrizacao = 4,
|
||||||
Controle = 5
|
Controle = 5,
|
||||||
|
Historico = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using Brushes = System.Windows.Media.Brushes;
|
||||||
using ColorConverter = System.Windows.Media.ColorConverter;
|
using ColorConverter = System.Windows.Media.ColorConverter;
|
||||||
using Color = System.Windows.Media.Color;
|
using Color = System.Windows.Media.Color;
|
||||||
using static AgroBase.Models.Enums;
|
using static AgroBase.Models.Enums;
|
||||||
|
using OperationControl.Models;
|
||||||
|
|
||||||
namespace OperationControl.ViewModels.Views.Operacao
|
namespace OperationControl.ViewModels.Views.Operacao
|
||||||
{
|
{
|
||||||
|
|
@ -173,4 +174,159 @@ namespace OperationControl.ViewModels.Views.Operacao
|
||||||
public StatusModulo StatusVisual { get; set; }
|
public StatusModulo StatusVisual { get; set; }
|
||||||
public T_Code? Modulo { get; set; }
|
public T_Code? Modulo { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class LogEventoOperacaoModel
|
||||||
|
{
|
||||||
|
public DateTime DataHora { get; set; }
|
||||||
|
public string RoverId { get; set; }
|
||||||
|
public string TipoTransicao { get; set; } // INICIO / FIM / MUDANCA
|
||||||
|
public string Fonte { get; set; }
|
||||||
|
public string Titulo { get; set; }
|
||||||
|
public string Descricao { get; set; }
|
||||||
|
public StatusModulo StatusVisual { get; set; }
|
||||||
|
public T_Code? Modulo { get; set; }
|
||||||
|
|
||||||
|
public string Hora => DataHora.ToString("HH:mm:ss");
|
||||||
|
public string DataHoraCompleta => DataHora.ToString("dd/MM/yyyy HH:mm:ss");
|
||||||
|
|
||||||
|
public string Subtitulo
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var moduloTxt = Modulo?.ToString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(moduloTxt))
|
||||||
|
return $"{Fonte} • {moduloTxt} • {RoverId}";
|
||||||
|
|
||||||
|
return $"{Fonte} • {RoverId}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Brush CorAccent
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return StatusVisual switch
|
||||||
|
{
|
||||||
|
StatusModulo.Falha => Brushes.IndianRed,
|
||||||
|
StatusModulo.Desconectado => Brushes.DarkRed,
|
||||||
|
StatusModulo.Alerta => Brushes.Goldenrod,
|
||||||
|
StatusModulo.Operante => Brushes.ForestGreen,
|
||||||
|
StatusModulo.Conectado => Brushes.SteelBlue,
|
||||||
|
_ => Brushes.Gray
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Brush CorBadge
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return TipoTransicao switch
|
||||||
|
{
|
||||||
|
"INICIO" => Brushes.OrangeRed,
|
||||||
|
"FIM" => Brushes.SeaGreen,
|
||||||
|
"MUDANCA" => Brushes.SteelBlue,
|
||||||
|
_ => Brushes.DimGray
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HistoricoOperacaoItemModel
|
||||||
|
{
|
||||||
|
public DateTime DataHora { get; set; }
|
||||||
|
public string RoverId { get; set; }
|
||||||
|
|
||||||
|
public TipoHistoricoOperacao Tipo { get; set; } // Operacao ou Alerta
|
||||||
|
public string TipoTransicao { get; set; } // INICIO / FIM / MUDANCA
|
||||||
|
|
||||||
|
public string Fonte { get; set; } // ex: Controle, Trajetoria, AlertaModulo
|
||||||
|
public string Titulo { get; set; }
|
||||||
|
public string Descricao { get; set; }
|
||||||
|
|
||||||
|
public StatusModulo? StatusVisual { get; set; } // para eventos operacionais
|
||||||
|
public SeveridadeAlerta? SeveridadeAlerta { get; set; } // para alertas
|
||||||
|
|
||||||
|
public T_Code? Modulo { get; set; }
|
||||||
|
public string? ModId { get; set; }
|
||||||
|
|
||||||
|
public string Hora => DataHora.ToString("HH:mm:ss");
|
||||||
|
public string DataHoraCompleta => DataHora.ToString("dd/MM/yyyy HH:mm:ss");
|
||||||
|
|
||||||
|
public string Subtitulo
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var partes = new List<string>();
|
||||||
|
|
||||||
|
partes.Add(Tipo == TipoHistoricoOperacao.Alerta ? "Alerta" : "Operação");
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(Fonte))
|
||||||
|
partes.Add(Fonte);
|
||||||
|
|
||||||
|
if (Modulo.HasValue)
|
||||||
|
partes.Add(Modulo.Value.ToString());
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(ModId))
|
||||||
|
partes.Add(ModId);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(RoverId))
|
||||||
|
partes.Add(RoverId);
|
||||||
|
|
||||||
|
return string.Join(" • ", partes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Brush CorAccent
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Tipo == TipoHistoricoOperacao.Alerta)
|
||||||
|
{
|
||||||
|
return SeveridadeAlerta switch
|
||||||
|
{
|
||||||
|
Models.SeveridadeAlerta.Warning => Brushes.Goldenrod,
|
||||||
|
Models.SeveridadeAlerta.Error => Brushes.IndianRed,
|
||||||
|
Models.SeveridadeAlerta.Critical => Brushes.DarkRed,
|
||||||
|
_ => Brushes.SteelBlue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return StatusVisual switch
|
||||||
|
{
|
||||||
|
StatusModulo.Falha => Brushes.IndianRed,
|
||||||
|
StatusModulo.Desconectado => Brushes.DarkRed,
|
||||||
|
StatusModulo.Alerta => Brushes.Goldenrod,
|
||||||
|
StatusModulo.Operante => Brushes.ForestGreen,
|
||||||
|
StatusModulo.Conectado => Brushes.SteelBlue,
|
||||||
|
_ => Brushes.Gray
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Brush CorBadge
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return TipoTransicao switch
|
||||||
|
{
|
||||||
|
"INICIO" => Brushes.OrangeRed,
|
||||||
|
"FIM" => Brushes.SeaGreen,
|
||||||
|
"MUDANCA" => Brushes.SteelBlue,
|
||||||
|
_ => Brushes.DimGray
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TipoHistoricoOperacao
|
||||||
|
{
|
||||||
|
Operacao = 0,
|
||||||
|
Alerta = 1
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -374,6 +374,9 @@ namespace OperationControl.ViewModels
|
||||||
double tempoSemResposta = (DateTime.Now - rover.UltimoContato).TotalSeconds;
|
double tempoSemResposta = (DateTime.Now - rover.UltimoContato).TotalSeconds;
|
||||||
bool semComunicacao = !AppShell.Mock && tempoSemResposta >= VariaveisControleOperacao.TempoRoverVivo;
|
bool semComunicacao = !AppShell.Mock && tempoSemResposta >= VariaveisControleOperacao.TempoRoverVivo;
|
||||||
|
|
||||||
|
// ============================
|
||||||
|
// 0) Perda de comunicação
|
||||||
|
// ============================
|
||||||
if (semComunicacao)
|
if (semComunicacao)
|
||||||
{
|
{
|
||||||
eventos.Add(new MotivoTopBarModel
|
eventos.Add(new MotivoTopBarModel
|
||||||
|
|
@ -386,11 +389,11 @@ namespace OperationControl.ViewModels
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.ModulosSaude?.All(x => (x?.status ?? StatusModulo.Desconectado) == StatusModulo.Desconectado) ?? false)
|
|
||||||
{
|
|
||||||
// ============================
|
// ============================
|
||||||
// 0) NCP desconectado
|
// 0) NCP desconectado
|
||||||
// ============================
|
// ============================
|
||||||
|
if (obj.ModulosSaude?.All(x => (x?.status ?? StatusModulo.Desconectado) == StatusModulo.Desconectado) ?? false)
|
||||||
|
{
|
||||||
eventos.Add(new MotivoTopBarModel
|
eventos.Add(new MotivoTopBarModel
|
||||||
{
|
{
|
||||||
Prioridade = 1100,
|
Prioridade = 1100,
|
||||||
|
|
@ -484,6 +487,14 @@ namespace OperationControl.ViewModels
|
||||||
(x?.Utilizar ?? false) &&
|
(x?.Utilizar ?? false) &&
|
||||||
(x?.Mandatorio ?? false)
|
(x?.Mandatorio ?? false)
|
||||||
) ?? false)
|
) ?? false)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
(mod?.status ?? StatusModulo.Desconectado) == StatusModulo.Alerta &&
|
||||||
|
(rover?.ModulosMandatorios?.Any(x =>
|
||||||
|
(x?.Dispositivo ?? T_Code.Vzo) == (mod?.modulo ?? T_Code.Vzo) &&
|
||||||
|
(x?.Utilizar ?? false) &&
|
||||||
|
(x?.Mandatorio ?? false)
|
||||||
|
) ?? false)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.ToList() ?? new List<AgroBase.Models.Operadores.ManagerWorkerMessageResponseModulosPendentesModel>();
|
.ToList() ?? new List<AgroBase.Models.Operadores.ManagerWorkerMessageResponseModulosPendentesModel>();
|
||||||
|
|
@ -500,8 +511,32 @@ namespace OperationControl.ViewModels
|
||||||
(x?.Utilizar ?? false) &&
|
(x?.Utilizar ?? false) &&
|
||||||
(x?.Mandatorio ?? false)
|
(x?.Mandatorio ?? false)
|
||||||
) ?? false);
|
) ?? false);
|
||||||
|
bool moduloMandatorioAlerta =
|
||||||
|
(modulo?.status ?? StatusModulo.Desconectado) == StatusModulo.Alerta &&
|
||||||
|
(rover?.ModulosMandatorios?.Any(x =>
|
||||||
|
(x?.Dispositivo ?? T_Code.Vzo) == (modulo?.modulo ?? T_Code.Vzo) &&
|
||||||
|
(x?.Utilizar ?? false) &&
|
||||||
|
(x?.Mandatorio ?? false)
|
||||||
|
) ?? false);
|
||||||
|
|
||||||
// Caso 1: condições operacionais severas
|
// Caso 1: módulo mandatório não operante
|
||||||
|
if (moduloMandatorioNaoOperante)
|
||||||
|
{
|
||||||
|
var statusTexto = (modulo?.status ?? StatusModulo.Desconectado).ToString();
|
||||||
|
string motivos = string.Join("; ", modulo?.motivos ?? new List<string>() { "Desconhecido" });
|
||||||
|
|
||||||
|
eventos.Add(new MotivoTopBarModel
|
||||||
|
{
|
||||||
|
Prioridade = 620,
|
||||||
|
Fonte = "ModuloCritico",
|
||||||
|
Titulo = "MÓDULO MANDATÓRIO NÃO OPERACIONAL",
|
||||||
|
Descricao = $"{nomeModulo}: módulo mandatório em estado '{statusTexto}': {motivos}",
|
||||||
|
StatusVisual = StatusModulo.Falha,
|
||||||
|
Modulo = modulo?.modulo
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Caso 2: condições operacionais severas
|
||||||
if (temCondicaoSevera)
|
if (temCondicaoSevera)
|
||||||
{
|
{
|
||||||
var descricoesCriticas = modulo?.condicoes_operacionais?
|
var descricoesCriticas = modulo?.condicoes_operacionais?
|
||||||
|
|
@ -515,7 +550,7 @@ namespace OperationControl.ViewModels
|
||||||
{
|
{
|
||||||
eventos.Add(new MotivoTopBarModel
|
eventos.Add(new MotivoTopBarModel
|
||||||
{
|
{
|
||||||
Prioridade = 600,
|
Prioridade = 610,
|
||||||
Fonte = "ModuloCritico",
|
Fonte = "ModuloCritico",
|
||||||
Titulo = "CONDIÇÕES OPERACIONAIS CRÍTICAS",
|
Titulo = "CONDIÇÕES OPERACIONAIS CRÍTICAS",
|
||||||
Descricao = $"{nomeModulo}: {desc}",
|
Descricao = $"{nomeModulo}: {desc}",
|
||||||
|
|
@ -525,18 +560,19 @@ namespace OperationControl.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Caso 2: módulo mandatório não operante
|
// Caso 3: módulo mandatório em alerta
|
||||||
if (moduloMandatorioNaoOperante)
|
if (moduloMandatorioAlerta)
|
||||||
{
|
{
|
||||||
var statusTexto = (modulo?.status ?? StatusModulo.Desconectado).ToString();
|
var statusTexto = (modulo?.status ?? StatusModulo.Desconectado).ToString();
|
||||||
|
string motivos = string.Join("; ", modulo?.motivos ?? new List<string>() { "Desconhecido" });
|
||||||
|
|
||||||
eventos.Add(new MotivoTopBarModel
|
eventos.Add(new MotivoTopBarModel
|
||||||
{
|
{
|
||||||
Prioridade = 610,
|
Prioridade = 600,
|
||||||
Fonte = "ModuloCritico",
|
Fonte = "ModuloCritico",
|
||||||
Titulo = "MÓDULO MANDATÓRIO NÃO OPERACIONAL",
|
Titulo = "MÓDULO MANDATÓRIO EM ALERTA",
|
||||||
Descricao = $"{nomeModulo}: módulo mandatório em estado '{statusTexto}'",
|
Descricao = $"{nomeModulo}: módulo mandatório em estado '{statusTexto}': {motivos}",
|
||||||
StatusVisual = StatusModulo.Falha,
|
StatusVisual = StatusModulo.Alerta,
|
||||||
Modulo = modulo?.modulo
|
Modulo = modulo?.modulo
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -565,6 +601,20 @@ namespace OperationControl.ViewModels
|
||||||
.ThenBy(x => x.Fonte)
|
.ThenBy(x => x.Fonte)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
if (!eventosOrdenados.Any())
|
||||||
|
{
|
||||||
|
eventosOrdenados.Add(new MotivoTopBarModel
|
||||||
|
{
|
||||||
|
Prioridade = 0,
|
||||||
|
Fonte = "Normal",
|
||||||
|
Titulo = "ROVER OPERANDO NORMALMENTE",
|
||||||
|
Descricao = "Trajetória, controle e operação em condição normal.",
|
||||||
|
StatusVisual = obj.StatusRover == StatusModulo.Desconectado
|
||||||
|
? StatusModulo.Desconectado
|
||||||
|
: StatusModulo.Operante
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
// 7) Monta visual final
|
// 7) Monta visual final
|
||||||
// ============================
|
// ============================
|
||||||
|
|
@ -627,6 +677,8 @@ namespace OperationControl.ViewModels
|
||||||
resumo = (obj.Operacao?.Status ?? StatusOperacao.NaoIniciado).ToString();
|
resumo = (obj.Operacao?.Status ?? StatusOperacao.NaoIniciado).ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_viewOperacaoCenter?.Historico?._vm?.CompararERegistrarMudancasEventos(rover.RoverId, eventosOrdenados);
|
||||||
|
|
||||||
// Segurança extra: evita linha vazia
|
// Segurança extra: evita linha vazia
|
||||||
if (string.IsNullOrWhiteSpace(linha2))
|
if (string.IsNullOrWhiteSpace(linha2))
|
||||||
linha2 = "Sem detalhes adicionais.";
|
linha2 = "Sem detalhes adicionais.";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,382 @@
|
||||||
|
<UserControl x:Class="OperationControl.Views.Operacao.Monitoramento.HistoricoView"
|
||||||
|
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.Monitoramento"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="900"
|
||||||
|
d:DesignWidth="1600">
|
||||||
|
|
||||||
|
<UserControl.Resources>
|
||||||
|
|
||||||
|
<!-- Campo base escuro -->
|
||||||
|
<Style x:Key="DarkInputTextBoxStyle" TargetType="TextBox">
|
||||||
|
<Setter Property="Height" Value="36"/>
|
||||||
|
<Setter Property="Padding" Value="10,6"/>
|
||||||
|
<Setter Property="Foreground" Value="White"/>
|
||||||
|
<Setter Property="Background" Value="#111315"/>
|
||||||
|
<Setter Property="BorderBrush" Value="#323842"/>
|
||||||
|
<Setter Property="BorderThickness" Value="1"/>
|
||||||
|
<Setter Property="CaretBrush" Value="White"/>
|
||||||
|
<Setter Property="FontSize" Value="13"/>
|
||||||
|
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||||
|
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="TextBox">
|
||||||
|
<Border x:Name="Bd"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
CornerRadius="10">
|
||||||
|
<ScrollViewer x:Name="PART_ContentHost"
|
||||||
|
Margin="0"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</Border>
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsKeyboardFocused" Value="True">
|
||||||
|
<Setter TargetName="Bd" Property="BorderBrush" Value="#4C89FF"/>
|
||||||
|
<Setter TargetName="Bd" Property="Background" Value="#14181D"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter TargetName="Bd" Property="BorderBrush" Value="#46505C"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsEnabled" Value="False">
|
||||||
|
<Setter TargetName="Bd" Property="Opacity" Value="0.65"/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<!-- ComboBox escuro -->
|
||||||
|
<Style x:Key="DarkComboBoxStyle" TargetType="ComboBox">
|
||||||
|
<Setter Property="Height" Value="36"/>
|
||||||
|
<Setter Property="Foreground" Value="White"/>
|
||||||
|
<Setter Property="Background" Value="#111315"/>
|
||||||
|
<Setter Property="BorderBrush" Value="#323842"/>
|
||||||
|
<Setter Property="BorderThickness" Value="1"/>
|
||||||
|
<Setter Property="FontSize" Value="13"/>
|
||||||
|
<Setter Property="Padding" Value="10,6"/>
|
||||||
|
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||||
|
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="ComboBox">
|
||||||
|
<Grid>
|
||||||
|
<Border x:Name="Bd"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
CornerRadius="10"/>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="36"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- texto selecionado -->
|
||||||
|
<ContentPresenter Grid.Column="0"
|
||||||
|
Margin="12,0,8,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
RecognizesAccessKey="True"
|
||||||
|
Content="{TemplateBinding SelectionBoxItem}"
|
||||||
|
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"/>
|
||||||
|
|
||||||
|
<!-- seta -->
|
||||||
|
<Border Grid.Column="1"
|
||||||
|
Background="Transparent">
|
||||||
|
<Path Width="10"
|
||||||
|
Height="6"
|
||||||
|
Stretch="Fill"
|
||||||
|
Fill="#C8D0DA"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Data="M 0 0 L 10 0 L 5 6 Z"/>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<!-- área clicável -->
|
||||||
|
<ToggleButton Grid.ColumnSpan="2"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderThickness="0"
|
||||||
|
Focusable="False"
|
||||||
|
ClickMode="Press"
|
||||||
|
IsChecked="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
|
||||||
|
<ToggleButton.Template>
|
||||||
|
<ControlTemplate TargetType="ToggleButton">
|
||||||
|
<Border Background="Transparent"/>
|
||||||
|
</ControlTemplate>
|
||||||
|
</ToggleButton.Template>
|
||||||
|
</ToggleButton>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Popup x:Name="Popup"
|
||||||
|
Placement="Bottom"
|
||||||
|
AllowsTransparency="True"
|
||||||
|
Focusable="False"
|
||||||
|
StaysOpen="False"
|
||||||
|
IsOpen="{TemplateBinding IsDropDownOpen}"
|
||||||
|
PopupAnimation="Fade">
|
||||||
|
<Border Margin="0,4,0,0"
|
||||||
|
Background="#1A1D21"
|
||||||
|
BorderBrush="#323842"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="10"
|
||||||
|
MinWidth="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}">
|
||||||
|
<ScrollViewer MaxHeight="320"
|
||||||
|
CanContentScroll="True">
|
||||||
|
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained"/>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Border>
|
||||||
|
</Popup>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsKeyboardFocusWithin" Value="True">
|
||||||
|
<Setter TargetName="Bd" Property="BorderBrush" Value="#4C89FF"/>
|
||||||
|
<Setter TargetName="Bd" Property="Background" Value="#14181D"/>
|
||||||
|
</Trigger>
|
||||||
|
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter TargetName="Bd" Property="BorderBrush" Value="#46505C"/>
|
||||||
|
</Trigger>
|
||||||
|
|
||||||
|
<Trigger Property="IsEnabled" Value="False">
|
||||||
|
<Setter TargetName="Bd" Property="Opacity" Value="0.65"/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
<Setter Property="ItemContainerStyle">
|
||||||
|
<Setter.Value>
|
||||||
|
<Style TargetType="ComboBoxItem">
|
||||||
|
<Setter Property="Foreground" Value="White"/>
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Setter Property="Padding" Value="10,6"/>
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="ComboBoxItem">
|
||||||
|
<Border x:Name="ItemBorder"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
Padding="{TemplateBinding Padding}">
|
||||||
|
<ContentPresenter />
|
||||||
|
</Border>
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsHighlighted" Value="True">
|
||||||
|
<Setter TargetName="ItemBorder" Property="Background" Value="#2A313A"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsSelected" Value="True">
|
||||||
|
<Setter TargetName="ItemBorder" Property="Background" Value="#314256"/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<!-- Botão secundário, caso use depois -->
|
||||||
|
<Style x:Key="DarkSmallButtonStyle" TargetType="Button">
|
||||||
|
<Setter Property="Height" Value="36"/>
|
||||||
|
<Setter Property="Padding" Value="14,6"/>
|
||||||
|
<Setter Property="Foreground" Value="White"/>
|
||||||
|
<Setter Property="Background" Value="#20252B"/>
|
||||||
|
<Setter Property="BorderBrush" Value="#323842"/>
|
||||||
|
<Setter Property="BorderThickness" Value="1"/>
|
||||||
|
<Setter Property="FontSize" Value="13"/>
|
||||||
|
<Setter Property="Cursor" Value="Hand"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="Button">
|
||||||
|
<Border x:Name="Bd"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
CornerRadius="10">
|
||||||
|
<ContentPresenter HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</Border>
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter TargetName="Bd" Property="Background" Value="#2A3138"/>
|
||||||
|
<Setter TargetName="Bd" Property="BorderBrush" Value="#46505C"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsPressed" Value="True">
|
||||||
|
<Setter TargetName="Bd" Property="Background" Value="#151A1F"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsEnabled" Value="False">
|
||||||
|
<Setter TargetName="Bd" Property="Opacity" Value="0.65"/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</UserControl.Resources>
|
||||||
|
|
||||||
|
<Grid Background="#111315">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- CABEÇALHO -->
|
||||||
|
<StackPanel Grid.Row="0" Margin="16,16,16,0">
|
||||||
|
<Border Padding="18" CornerRadius="14" Background="#1A1D21" BorderBrush="#2A2E35" BorderThickness="1">
|
||||||
|
<StackPanel>
|
||||||
|
<DockPanel LastChildFill="False">
|
||||||
|
<StackPanel DockPanel.Dock="Left">
|
||||||
|
<TextBlock Text="Histórico operacional" FontSize="22" FontWeight="SemiBold" Foreground="White"/>
|
||||||
|
<TextBlock Margin="0,6,0,0" FontSize="13" Foreground="#B8C0CC">
|
||||||
|
<Run Text="Exibindo "/>
|
||||||
|
<Run Text="{Binding QuantidadeEventosFiltrados, Mode=OneWay}"/>
|
||||||
|
<Run Text=" eventos filtrados de "/>
|
||||||
|
<Run Text="{Binding QuantidadeEventos, Mode=OneWay}"/>
|
||||||
|
<Run Text=" eventos"/>
|
||||||
|
</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</DockPanel>
|
||||||
|
|
||||||
|
<StackPanel Margin="0,16,0,0">
|
||||||
|
<TextBlock Text="Busca e filtros" Margin="2,0,0,10" FontSize="12" Foreground="#8F99A5"/>
|
||||||
|
|
||||||
|
<WrapPanel>
|
||||||
|
<TextBox Width="260" Margin="0,0,10,10" Text="{Binding TextoBusca, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource DarkInputTextBoxStyle}" ToolTip="Buscar por título, descrição, fonte, módulo..." />
|
||||||
|
|
||||||
|
<ComboBox Width="150" Margin="0,0,10,10" ItemsSource="{Binding TiposTransicaoDisponiveis}" SelectedItem="{Binding TipoTransicaoSelecionado}" Style="{StaticResource DarkComboBoxStyle}" />
|
||||||
|
|
||||||
|
<ComboBox Width="150" Margin="0,0,10,10" ItemsSource="{Binding StatusDisponiveis}" SelectedItem="{Binding StatusSelecionado}" Style="{StaticResource DarkComboBoxStyle}" />
|
||||||
|
|
||||||
|
<ComboBox Width="170" Margin="0,0,10,10" ItemsSource="{Binding FontesDisponiveis}" SelectedItem="{Binding FonteSelecionada}" Style="{StaticResource DarkComboBoxStyle}" />
|
||||||
|
|
||||||
|
<ComboBox Width="160" Margin="0,0,10,10" ItemsSource="{Binding OrdenacoesDisponiveis}" SelectedItem="{Binding OrdenacaoSelecionada}" Style="{StaticResource DarkComboBoxStyle}" />
|
||||||
|
|
||||||
|
<Border Background="#111315" BorderBrush="#323842" BorderThickness="1" CornerRadius="10" Height="36" Padding="12,6" Margin="0,0,10,10">
|
||||||
|
<TextBlock VerticalAlignment="Center" Foreground="#B8C0CC" FontSize="12" Text="{Binding RoverIdSelecionado, StringFormat=Rover: {0}}" />
|
||||||
|
</Border>
|
||||||
|
</WrapPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- LISTA -->
|
||||||
|
<Border Grid.Row="1"
|
||||||
|
Margin="16,0,16,16"
|
||||||
|
Padding="8"
|
||||||
|
CornerRadius="14"
|
||||||
|
Background="#16191D"
|
||||||
|
BorderBrush="#2A2E35"
|
||||||
|
BorderThickness="1">
|
||||||
|
|
||||||
|
<ListBox ItemsSource="{Binding EventosView}"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderThickness="0"
|
||||||
|
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||||
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||||
|
VirtualizingPanel.IsVirtualizing="True"
|
||||||
|
VirtualizingPanel.VirtualizationMode="Recycling">
|
||||||
|
|
||||||
|
<ListBox.ItemContainerStyle>
|
||||||
|
<Style TargetType="ListBoxItem">
|
||||||
|
<Setter Property="Padding" Value="0"/>
|
||||||
|
<Setter Property="Margin" Value="0,0,0,10"/>
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderThickness" Value="0"/>
|
||||||
|
<Setter Property="Focusable" Value="False"/>
|
||||||
|
</Style>
|
||||||
|
</ListBox.ItemContainerStyle>
|
||||||
|
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Border Background="#1D2126"
|
||||||
|
CornerRadius="12"
|
||||||
|
BorderBrush="#2B3138"
|
||||||
|
BorderThickness="1"
|
||||||
|
Padding="0">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="6"/>
|
||||||
|
<ColumnDefinition Width="110"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="110"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- barra lateral -->
|
||||||
|
<Border Grid.Column="0"
|
||||||
|
Background="{Binding CorAccent}"
|
||||||
|
CornerRadius="12,0,0,12"/>
|
||||||
|
|
||||||
|
<!-- hora -->
|
||||||
|
<StackPanel Grid.Column="1"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="16,14,10,14">
|
||||||
|
<TextBlock Text="{Binding Hora}"
|
||||||
|
FontSize="20"
|
||||||
|
FontWeight="Bold"
|
||||||
|
Foreground="White"
|
||||||
|
HorizontalAlignment="Left"/>
|
||||||
|
<TextBlock Text="{Binding DataHoraCompleta}"
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
FontSize="11"
|
||||||
|
Foreground="#9DA7B3"
|
||||||
|
TextWrapping="Wrap"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- conteúdo -->
|
||||||
|
<StackPanel Grid.Column="2"
|
||||||
|
Margin="8,14,16,14">
|
||||||
|
<TextBlock Text="{Binding Titulo}"
|
||||||
|
FontSize="16"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="White"
|
||||||
|
TextWrapping="Wrap"/>
|
||||||
|
|
||||||
|
<TextBlock Text="{Binding Descricao}"
|
||||||
|
Margin="0,8,0,0"
|
||||||
|
FontSize="13"
|
||||||
|
Foreground="#D0D7E2"
|
||||||
|
TextWrapping="Wrap"/>
|
||||||
|
|
||||||
|
<TextBlock Text="{Binding Subtitulo}"
|
||||||
|
Margin="0,10,0,0"
|
||||||
|
FontSize="12"
|
||||||
|
Foreground="#8F99A5"
|
||||||
|
TextWrapping="Wrap"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- badge -->
|
||||||
|
<StackPanel Grid.Column="3"
|
||||||
|
Margin="0,14,14,14"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
HorizontalAlignment="Right">
|
||||||
|
<Border Background="{Binding CorBadge}"
|
||||||
|
CornerRadius="10"
|
||||||
|
Padding="10,4">
|
||||||
|
<TextBlock Text="{Binding TipoTransicao}"
|
||||||
|
Foreground="White"
|
||||||
|
FontSize="11"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
HorizontalAlignment="Center"/>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
using OperationControl.ViewModels.Views.Operacao.Monitoramento;
|
||||||
|
|
||||||
|
namespace OperationControl.Views.Operacao.Monitoramento
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interação lógica para HistoricoView.xam
|
||||||
|
/// </summary>
|
||||||
|
public partial class HistoricoView : System.Windows.Controls.UserControl
|
||||||
|
{
|
||||||
|
public HistoricoViewModel _vm;
|
||||||
|
|
||||||
|
public HistoricoView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
_vm = new HistoricoViewModel();
|
||||||
|
DataContext = _vm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -33,5 +33,10 @@
|
||||||
<views:MonitoramentoView x:Name="areaMonitor"/>
|
<views:MonitoramentoView x:Name="areaMonitor"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<!-- HSITORICO -->
|
||||||
|
<Grid Visibility="{Binding ExibirHistorico, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
|
<views:HistoricoView x:Name="areaHistorico"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
@ -13,6 +13,7 @@ namespace OperationControl.Views.Operacao
|
||||||
public MapViewControl Mapa => _vm?.ConteudoAtual == OperacaoCenterConteudo.Mapa ? areaMapa : _vm?.ConteudoAtual == OperacaoCenterConteudo.Monitoramento ? Monitoramento?.MapaMonitoramento : null;
|
public MapViewControl Mapa => _vm?.ConteudoAtual == OperacaoCenterConteudo.Mapa ? areaMapa : _vm?.ConteudoAtual == OperacaoCenterConteudo.Monitoramento ? Monitoramento?.MapaMonitoramento : null;
|
||||||
public MonitoramentoView Monitoramento => areaMonitor;
|
public MonitoramentoView Monitoramento => areaMonitor;
|
||||||
public DiagnosticoView Diagnostico => areaDiagnostico;
|
public DiagnosticoView Diagnostico => areaDiagnostico;
|
||||||
|
public HistoricoView Historico => areaHistorico;
|
||||||
|
|
||||||
public OperacaoCenterView()
|
public OperacaoCenterView()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,8 @@
|
||||||
<Button Content="Controle ▶" Style="{StaticResource MenuButtonStyle}" Command="{Binding SelecionarSecaoCommand}" CommandParameter="Controle"/>
|
<Button Content="Controle ▶" Style="{StaticResource MenuButtonStyle}" Command="{Binding SelecionarSecaoCommand}" CommandParameter="Controle"/>
|
||||||
|
|
||||||
<Button Content="Resumo ▶" Style="{StaticResource MenuButtonStyle}" Command="{Binding SelecionarSecaoCommand}" CommandParameter="Resumo"/>
|
<Button Content="Resumo ▶" Style="{StaticResource MenuButtonStyle}" Command="{Binding SelecionarSecaoCommand}" CommandParameter="Resumo"/>
|
||||||
|
|
||||||
|
<Button Content="Histórico" Style="{StaticResource MenuButtonStyle}" Command="{Binding SelecionarSecaoCommand}" CommandParameter="Historico"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- RESUMO -->
|
<!-- RESUMO -->
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue