implementado matriz de custo ao MPC
|
|
@ -531,6 +531,7 @@
|
|||
<Compile Include="Models\OIDModel.cs" />
|
||||
<Compile Include="Models\Operacoes\OperacaoModel.cs" />
|
||||
<Compile Include="Models\Operacoes\OperacaoParametrosModel.cs" />
|
||||
<Compile Include="Models\Operadores\CameraWorkerModel.cs" />
|
||||
<Compile Include="Models\Operadores\HealthWorkerModel.cs" />
|
||||
<Compile Include="Models\Operadores\ManagerWorkerModel.cs" />
|
||||
<Compile Include="Models\Operadores\OperadoresModels.cs" />
|
||||
|
|
@ -580,6 +581,7 @@
|
|||
<Compile Include="Services\MqttService.cs" />
|
||||
<Compile Include="Services\OIDCanService.cs" />
|
||||
<Compile Include="Services\OIDService.cs" />
|
||||
<Compile Include="Services\Operadores\CameraWorkerService.cs" />
|
||||
<Compile Include="Services\Operadores\HealthWorkerService.cs" />
|
||||
<Compile Include="Services\Operadores\ManagerWorkerService.cs" />
|
||||
<Compile Include="Services\Operadores\OperadoresService.cs" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using AgroBase.Models;
|
||||
using AgroBase.Models.Components;
|
||||
using AgroBase.Services;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
|
@ -266,7 +267,7 @@ namespace AgroBase.Forms.IHM
|
|||
private async Task AtualizarCameras()
|
||||
{
|
||||
flwCamerasSolo.Controls.Clear();
|
||||
ListaCameras = await VariaveisOperacao.Operadores.AtualizarListaCameras();
|
||||
ListaCameras = CameraWorkerService.GetListaCameras();
|
||||
|
||||
CameraCaminho = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.Clone();
|
||||
CamerasSolo = new List<OAKCameraModel>(Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo);
|
||||
|
|
@ -356,7 +357,7 @@ namespace AgroBase.Forms.IHM
|
|||
CameraCaminho = CameraDisponivel(cmb.Text);
|
||||
if (CameraCaminho.Index > -1)
|
||||
{
|
||||
Bitmap rgb = await CameraCaminho.GetFrame();
|
||||
Bitmap rgb = await CameraCaminho.GetNewFrame();
|
||||
pic.Image = rgb;
|
||||
}
|
||||
else
|
||||
|
|
@ -376,7 +377,7 @@ namespace AgroBase.Forms.IHM
|
|||
CamerasSolo[idx] = CameraDisponivel(cmb.Text, idx);
|
||||
if (CamerasSolo[idx].Index > -1)
|
||||
{
|
||||
Bitmap rgb = await CamerasSolo[idx].GetFrame();
|
||||
Bitmap rgb = await CamerasSolo[idx].GetNewFrame();
|
||||
pic.Image = rgb;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using AgroBase.Models;
|
|||
using AgroBase.Models.Components;
|
||||
using AgroBase.Models.Modules;
|
||||
using AgroBase.Services;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
|
@ -235,7 +236,7 @@ namespace AgroBase.Forms.IHM
|
|||
PreencherDadosDiagnosticoSinaleiros(Diagnosticos.FirstOrDefault(x => x.Modulo == T_Code.Sen));
|
||||
PreencherDadosDiagnosticoReles(Diagnosticos.FirstOrDefault(x => x.Modulo == T_Code.Mks));
|
||||
PreencherDadosTabelaResultado(dgResultados);
|
||||
OperacaoModel.PopularTreeView(tvwFalhas, VariaveisOperacao.Operadores.ModulosSaude);
|
||||
OperacaoModel.PopularTreeView(tvwFalhas, HealthWorkerService.ModulosSaude);
|
||||
}
|
||||
|
||||
private async Task<bool> IniciarDiagnostico(int idx)
|
||||
|
|
@ -244,7 +245,7 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
if (idx == 9)
|
||||
{
|
||||
OperacaoModel.PopularTreeView(tvwFalhas, VariaveisOperacao.Operadores.ModulosSaude);
|
||||
OperacaoModel.PopularTreeView(tvwFalhas, HealthWorkerService.ModulosSaude);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using AgroBase.Models.Components;
|
|||
using AgroBase.Models.Operadores;
|
||||
using AgroBase.Properties;
|
||||
using AgroBase.Services;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
|
@ -132,11 +133,6 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
lblCodigoFalha.Click -= LblCodigoFalha_Click;
|
||||
lblCodigoFalha.Click += LblCodigoFalha_Click;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await VariaveisOperacao.Operadores.AtualizarListaCameras();
|
||||
});
|
||||
}
|
||||
|
||||
private async Task tmrDispositivos_Tick()
|
||||
|
|
@ -162,7 +158,7 @@ namespace AgroBase.Forms.IHM
|
|||
private async Task AtualizarControlesUI()
|
||||
{
|
||||
var Labels = this.Controls.OfType<Label>().Where(y => y.Name.Contains("lblD_")).ToList();
|
||||
var listaCameras = await VariaveisOperacao.Operadores.AtualizarListaCameras();
|
||||
var listaCameras = CameraWorkerService.GetListaCameras();
|
||||
foreach (var lbl in Labels)
|
||||
{
|
||||
T_Code Dispositivo = (T_Code)Enum.Parse(typeof(T_Code), lbl.Name.Split('_')[1]);
|
||||
|
|
@ -299,7 +295,7 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
var Modulo = SerialService.DispositivosMapeados.FirstOrDefault(x => x.Dispositivo == Dispositivo && (x.Mod_ID == Mod_ID || x.Mod_ID == null));
|
||||
|
||||
var saudeGeral = VariaveisOperacao.Operadores.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo);
|
||||
var saudeGeral = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo);
|
||||
ManagerWorkerMessageResponseModulosPendentesSaudeModel saudeIndividual = null;
|
||||
switch (Dispositivo)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1202,7 +1202,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
.ToList();
|
||||
|
||||
|
||||
var LogSnr = LogsSonar.FirstOrDefault(x => x.Leitura.MomentoLog == MomentoAtual);
|
||||
var LogSnr = LogsSonar.FirstOrDefault(x => x.UltimaMensagem == MomentoAtual);
|
||||
var LogOpe = LogsOperacao.FirstOrDefault(x => x.Momento == MomentoAtual);
|
||||
|
||||
MapaDinamico.AtualizarDados(
|
||||
|
|
@ -1454,7 +1454,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
|
||||
private void AtualizarInformacoesSonar()
|
||||
{
|
||||
var Log = LogsSonar.FirstOrDefault(x => x.Leitura.MomentoLog == MomentoAtual);
|
||||
var Log = LogsSonar.FirstOrDefault(x => x.UltimaMensagem == MomentoAtual);
|
||||
//txtEspacoLivreEsquerda.Text = Log.Leitura.obj.radar_2d.analise.corredor_perfil[1].esquerda_m.ToString("0.00");
|
||||
//txtEspacoLivreDireita.Text = Log.Leitura.obj.radar_2d.analise.corredor_perfil[1].direita_m.ToString("0.00");
|
||||
txtDesvioNecessario.Text = Log.Resumo.DesvioNecessario ? "Sim" : "Não";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using AgroBase.Models;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
|
@ -18,7 +19,7 @@ namespace AgroBase.Forms
|
|||
|
||||
private void btnAtualizar_Click(object sender, EventArgs e)
|
||||
{
|
||||
OperacaoModel.PopularTreeView(tvwFalhas, VariaveisOperacao.Operadores.ModulosSaude);
|
||||
OperacaoModel.PopularTreeView(tvwFalhas, HealthWorkerService.ModulosSaude);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ namespace AgroBase.Forms
|
|||
PythonService.EncerrarProcessos();
|
||||
|
||||
RedisService.Iniciar();
|
||||
RedisService.LimparDadosIniciais();
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using AgroBase.Models;
|
||||
using AgroBase.Models.Operadores;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
|
@ -39,7 +40,7 @@ namespace AgroBase.Forms
|
|||
private void AtualizarListaCameras()
|
||||
{
|
||||
cmbCameras.Items.Clear();
|
||||
cmbCameras.Items.AddRange(VariaveisOperacao.Operadores.CamerasConectadas.Select(x => x.Name).ToArray());
|
||||
cmbCameras.Items.AddRange(CameraWorkerService.GetListaCameras().Select(x => x.Name).ToArray());
|
||||
cmbCameras.SelectedIndex = -1;
|
||||
}
|
||||
|
||||
|
|
@ -58,34 +59,12 @@ namespace AgroBase.Forms
|
|||
|
||||
private async void btnAtualizarCameras_Click(object sender, EventArgs e)
|
||||
{
|
||||
VariaveisOperacao.Operadores.HealthWorker.AdicionarComandoNaFila(OperadoresModels.TipoComando.GetListaCameras);
|
||||
await VariaveisOperacao.Operadores.HealthWorker.AguardarNovosDados(OperadoresModels.TipoComando.GetListaCameras);
|
||||
AtualizarListaCameras();
|
||||
}
|
||||
|
||||
private async void btnIniciarProcessamento_Click(object sender, EventArgs e)
|
||||
{
|
||||
bool sucesso = false; // await VariaveisOperacao.Operadores.VisualWorker.IniciarCamera(Convert.ToInt32(txtDistanciaMax.Text), Convert.ToInt32(txtSessoesSolo.Text), Convert.ToInt32(txtPercentualSolo.Text));
|
||||
AtualizarLabelLeitura($", Comando: Configurar, Sucesso: {sucesso}");
|
||||
if (!sucesso)
|
||||
{
|
||||
MessageBox.Show("Selecione uma camera para iniciar o processamento!");
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Camera configurada com sucesso!");
|
||||
}
|
||||
}
|
||||
|
||||
private void EnviarComando(VisualWorkerCommandType cmd, dynamic payload = null)
|
||||
{
|
||||
bool sucesso = VariaveisOperacao.Operadores.VisualWorker.AdicionarComandoNaFila(cmd, payload);
|
||||
AtualizarLabelLeitura($", Comando: {cmd.ToString()}, Sucesso: {sucesso}");
|
||||
}
|
||||
|
||||
private void AtualizarLabelLeitura(string texto)
|
||||
{
|
||||
lblUltimaLeitura.Text = $"Ultima Leitura em: {VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.MomentoLog.ToString("dd/MM/yyyy HH:mm:ss.fff")} {texto}";
|
||||
|
||||
}
|
||||
|
||||
private void btnPing_Click(object sender, EventArgs e)
|
||||
|
|
@ -95,62 +74,56 @@ namespace AgroBase.Forms
|
|||
|
||||
private void btnCalibrarGrades_Click(object sender, EventArgs e)
|
||||
{
|
||||
//EnviarComando(VisualWorkerCommandType.Calibrar_Grades);
|
||||
VisualWorkerService.RecalibrarGridProfundidade();
|
||||
}
|
||||
|
||||
private void btnLeituraRGB_Click(object sender, EventArgs e)
|
||||
private async void btnLeituraRGB_Click(object sender, EventArgs e)
|
||||
{
|
||||
//EnviarComandoReqFrame(VisualWorkerCommandType.Get_RGB_Frame);
|
||||
EnviarComandoReqFrame(VisualWorkerFrameType.Rgb);
|
||||
}
|
||||
|
||||
private void btnLeituraHeatmap_Click(object sender, EventArgs e)
|
||||
{
|
||||
//EnviarComandoReqFrame(VisualWorkerCommandType.Get_Heatmap_Frame);
|
||||
EnviarComandoReqFrame(VisualWorkerFrameType.Heatmap);
|
||||
}
|
||||
|
||||
private void btnLeituraRadar2D_Click(object sender, EventArgs e)
|
||||
{
|
||||
//EnviarComandoReqFrame(VisualWorkerCommandType.Get_Radar_2D);
|
||||
EnviarComandoReqFrame(VisualWorkerFrameType.RadarTopDown);
|
||||
}
|
||||
|
||||
private void btnLeituraSegmentacaoSemantica_Click(object sender, EventArgs e)
|
||||
{
|
||||
//EnviarComandoReqFrame(VisualWorkerCommandType.Get_Segmentacao_Semantica);
|
||||
EnviarComandoReqFrame(VisualWorkerFrameType.Segmentacao);
|
||||
}
|
||||
|
||||
private async void EnviarComandoReqFrame(VisualWorkerCommandType comando)
|
||||
private async void EnviarComandoReqFrame(VisualWorkerFrameType tipo)
|
||||
{
|
||||
/*EnviarComando(comando);
|
||||
await VariaveisOperacao.Operadores.VisualWorker.AguardarNovosDados(comando);
|
||||
OAKCameraFrameModel frame =
|
||||
comando == VisualWorkerCommandType.Get_RGB_Frame ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.rgb_frame :
|
||||
comando == VisualWorkerCommandType.Get_Heatmap_Frame ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.heatmap_frame :
|
||||
comando == VisualWorkerCommandType.Get_Radar_2D ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.radar_2d?.frame :
|
||||
comando == VisualWorkerCommandType.Get_Segmentacao_Semantica ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.segmentacao?.mask_frame :
|
||||
new OAKCameraFrameModel();
|
||||
OAKCameraFrameModel frame = await VisualWorkerService.GetCameraFrame(tipo);
|
||||
|
||||
PictureBox pic =
|
||||
comando == VisualWorkerCommandType.Get_RGB_Frame ? picRGB :
|
||||
comando == VisualWorkerCommandType.Get_Heatmap_Frame ? picHeatmap :
|
||||
comando == VisualWorkerCommandType.Get_Radar_2D ? picRadar2D :
|
||||
comando == VisualWorkerCommandType.Get_Segmentacao_Semantica ? picSegmentacaoSemantica :
|
||||
tipo == VisualWorkerFrameType.Rgb ? picRGB :
|
||||
tipo == VisualWorkerFrameType.Heatmap ? picHeatmap :
|
||||
tipo == VisualWorkerFrameType.RadarTopDown ? picRadar2D :
|
||||
tipo == VisualWorkerFrameType.Segmentacao ? picSegmentacaoSemantica :
|
||||
new PictureBox();
|
||||
Label lbl =
|
||||
comando == VisualWorkerCommandType.Get_RGB_Frame ? lblLeituraRGB :
|
||||
comando == VisualWorkerCommandType.Get_Heatmap_Frame ? lblLeituraHeatmap :
|
||||
comando == VisualWorkerCommandType.Get_Radar_2D ? lblLeituraRadar2D :
|
||||
comando == VisualWorkerCommandType.Get_Segmentacao_Semantica ? lblLeituraSegmentacaoSemantica :
|
||||
tipo == VisualWorkerFrameType.Rgb ? lblLeituraRGB :
|
||||
tipo == VisualWorkerFrameType.Heatmap ? lblLeituraHeatmap :
|
||||
tipo == VisualWorkerFrameType.RadarTopDown ? lblLeituraRadar2D :
|
||||
tipo == VisualWorkerFrameType.Segmentacao ? lblLeituraSegmentacaoSemantica :
|
||||
new Label();
|
||||
|
||||
pic.Image?.Dispose();
|
||||
try { pic.Image = frame?.image; } catch { }
|
||||
lbl.Text = $"Leitura em: {FuncoesGlobais.TimestampToDate(frame?.timestamp ?? 0)}";
|
||||
try { pic.Image = frame?.image(); } catch { }
|
||||
lbl.Text = $"Leitura em: " + frame?.timestamp.ToString("dd/MM/yyyy HH:mm:ss");
|
||||
|
||||
if (comando == VisualWorkerCommandType.Get_Radar_2D && VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.radar_2d != null)
|
||||
if (tipo == VisualWorkerFrameType.RadarTopDown && VisualWorkerService.DadosLeitura.Analises != null)
|
||||
{
|
||||
pic.Image = VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.radar_2d.PlotarAnalsie(frame.image);
|
||||
//pic.Image = VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.radar_2d.PlotarAnalsie(frame.image);
|
||||
|
||||
PlotarGraficoPerfilCorredor(VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.radar_2d.analise.corredor_perfil);
|
||||
}*/
|
||||
PlotarGraficoPerfilCorredor(VisualWorkerService.DadosLeitura.Analises.corredor_prof);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnReqStatusDispositivo_Click(object sender, EventArgs e)
|
||||
|
|
@ -160,55 +133,32 @@ namespace AgroBase.Forms
|
|||
|
||||
private void btnReqAnomalias_Click(object sender, EventArgs e)
|
||||
{
|
||||
//EnviarComandoAnalise(VisualWorkerCommandType.Get_Analise_Anomalia);
|
||||
AtualizarDadosAnalise();
|
||||
}
|
||||
|
||||
private void btnReqSolo_Click(object sender, EventArgs e)
|
||||
{
|
||||
//EnviarComandoAnalise(VisualWorkerCommandType.Get_Analise_Solo);
|
||||
AtualizarDadosAnalise();
|
||||
}
|
||||
|
||||
private async void btnLeituraIMU_Click(object sender, EventArgs e)
|
||||
{
|
||||
/*EnviarComando(VisualWorkerCommandType.Get_IMU_Data);
|
||||
await VariaveisOperacao.Operadores.VisualWorker.AguardarNovosDados(VisualWorkerCommandType.Get_IMU_Data);
|
||||
pnlInclinacao.Invalidate();
|
||||
lblLeituraIMU.Text = $"Leitura em: {FuncoesGlobais.TimestampToDate(VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.imu?.timestamp ?? 0)}";*/
|
||||
lblLeituraIMU.Text = $"Leitura em: {FuncoesGlobais.TimestampToDate(VisualWorkerService.DadosLeitura.Imu?.timestamp ?? 0)}";
|
||||
}
|
||||
|
||||
private async void EnviarComandoAnalise(VisualWorkerCommandType comando)
|
||||
private void AtualizarDadosAnalise()
|
||||
{
|
||||
EnviarComando(comando, new { velocidade_ms = txtVelocidade.Text.Replace(",", "."), distancia_max = txtDistanciaMax.Text.Replace(",", "."), largura_min = txtSessoesSolo.Text.Replace(",", "."), altura_min = txtPercentualSolo.Text.Replace(",", ".") });
|
||||
await VariaveisOperacao.Operadores.VisualWorker.AguardarNovosDados(comando);
|
||||
AtualizarDadosAnalise(comando);
|
||||
}
|
||||
var analise = VisualWorkerService.DadosLeitura.Analises;
|
||||
|
||||
private void AtualizarDadosAnalise(VisualWorkerCommandType comando)
|
||||
{
|
||||
/*VisualWorkerMessageAnaliseModel analise =
|
||||
comando == VisualWorkerCommandType.Get_Analise_Anomalia ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.analise_anomalias :
|
||||
comando == VisualWorkerCommandType.Get_Analise_Solo ? VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.analise_solo :
|
||||
new VisualWorkerMessageAnaliseModel();
|
||||
|
||||
lblLeituraDebug.Text = $"Leitura em: {FuncoesGlobais.TimestampToDate(analise?.timestamp ?? 0)}";
|
||||
OAKCameraFrameModel frame = VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj.heatmap_frame;
|
||||
lblLeituraDebug.Text = $"Leitura em: " + (analise?.timestamp ?? DateTime.MinValue).ToString("dd/MM/yyyy HH:mm:ss");
|
||||
OAKCameraFrameModel frame = VisualWorkerService.DadosLeitura.CameraFrames[VisualWorkerFrameType.Heatmap];
|
||||
picDebug.Image?.Dispose();
|
||||
picDebug.Image = analise.PlotarAnalise(frame);
|
||||
|
||||
switch (comando)
|
||||
{
|
||||
case VisualWorkerCommandType.Get_Analise_Anomalia:
|
||||
{
|
||||
PreencherGridAnomalias(analise.anomalias ?? new List<VisualWorkerMessageAnaliseBBoxModel>());
|
||||
break;
|
||||
}
|
||||
case VisualWorkerCommandType.Get_Analise_Solo:
|
||||
{
|
||||
PreencherGridSolo(analise.solo?.bbox_list ?? new List<VisualWorkerMessageAnaliseBBoxModel>());
|
||||
PlotarGraficoPerfilSolo(analise.solo?.perfil ?? new List<double>());
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
PreencherGridAnomalias(analise.anomalias ?? new List<VisualWorkerMessageAnaliseBBoxModel>());
|
||||
//PreencherGridSolo(analise.solo?.bbox_list ?? new List<VisualWorkerMessageAnaliseBBoxModel>());
|
||||
PlotarGraficoPerfilSolo(analise.solo?.perfil ?? new List<double>());
|
||||
}
|
||||
|
||||
void ConfigurarGridDeteccoes(DataGridView dgv)
|
||||
|
|
@ -356,9 +306,9 @@ namespace AgroBase.Forms
|
|||
|
||||
private void pnlInclinacao_Paint(object sender, PaintEventArgs e)
|
||||
{
|
||||
/*Panel _pnlInclinacao = sender as Panel;
|
||||
double AnguloX = VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj?.imu?.roll ?? 0;
|
||||
double AnguloY = VariaveisOperacao.Operadores.VisualWorker.DadosLeitura.Leitura.obj?.imu?.pitch ?? 0;
|
||||
Panel _pnlInclinacao = sender as Panel;
|
||||
double AnguloX = VisualWorkerService.DadosLeitura.Imu?.roll ?? 0;
|
||||
double AnguloY = VisualWorkerService.DadosLeitura.Imu?.pitch ?? 0;
|
||||
|
||||
Graphics g = e.Graphics;
|
||||
int centerX = _pnlInclinacao.Width / 2;
|
||||
|
|
@ -413,7 +363,7 @@ namespace AgroBase.Forms
|
|||
|
||||
// Desenhar o círculo
|
||||
Brush brush = new SolidBrush(Color.Red);
|
||||
g.FillEllipse(brush, circlePosX - radius, circlePosY - radius, radius * 2, radius * 2);*/
|
||||
g.FillEllipse(brush, circlePosX - radius, circlePosY - radius, radius * 2, radius * 2);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ namespace AgroBase
|
|||
this.lblStripOperacaoLiberada = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.lblStripOperacaoStatus = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.lblStripMqtt = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.lblStripWifi = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.lblStripPython = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.gpbMovimentacao = new System.Windows.Forms.GroupBox();
|
||||
this.lblKmh = new System.Windows.Forms.Label();
|
||||
this.trkKmh = new System.Windows.Forms.TrackBar();
|
||||
|
|
@ -196,7 +196,7 @@ namespace AgroBase
|
|||
this.lblStripOperacaoLiberada,
|
||||
this.lblStripOperacaoStatus,
|
||||
this.lblStripMqtt,
|
||||
this.lblStripWifi});
|
||||
this.lblStripPython});
|
||||
this.generalStrip.Location = new System.Drawing.Point(0, 612);
|
||||
this.generalStrip.Name = "generalStrip";
|
||||
this.generalStrip.Padding = new System.Windows.Forms.Padding(1, 0, 10, 0);
|
||||
|
|
@ -235,11 +235,11 @@ namespace AgroBase
|
|||
this.lblStripMqtt.Size = new System.Drawing.Size(121, 17);
|
||||
this.lblStripMqtt.Text = "MQTT: Desconectado";
|
||||
//
|
||||
// lblStripWifi
|
||||
// lblStripPython
|
||||
//
|
||||
this.lblStripWifi.Name = "lblStripWifi";
|
||||
this.lblStripWifi.Size = new System.Drawing.Size(116, 17);
|
||||
this.lblStripWifi.Text = "Wi-Fi: Desconectado";
|
||||
this.lblStripPython.Name = "lblStripPython";
|
||||
this.lblStripPython.Size = new System.Drawing.Size(99, 17);
|
||||
this.lblStripPython.Text = "IA: Desconectado";
|
||||
//
|
||||
// gpbMovimentacao
|
||||
//
|
||||
|
|
@ -927,7 +927,7 @@ namespace AgroBase
|
|||
private System.Windows.Forms.CheckedListBox clbRotinas;
|
||||
private System.Windows.Forms.Button btnAtualizarRotinas;
|
||||
public System.Windows.Forms.ProgressBar pgbAtualizacaoArquivos;
|
||||
public System.Windows.Forms.ToolStripStatusLabel lblStripWifi;
|
||||
public System.Windows.Forms.ToolStripStatusLabel lblStripPython;
|
||||
private System.Windows.Forms.Button btnOID;
|
||||
private System.Windows.Forms.Button btnTreinamentoIA;
|
||||
private System.Windows.Forms.Button btnVisualWorker;
|
||||
|
|
|
|||
|
|
@ -98,11 +98,12 @@ namespace AgroBase
|
|||
AtualizaDadosGerais();
|
||||
|
||||
lblStripMqtt.Text = "MQTT: " + (Variaveis.MqttService.StatusConexao() ? "Conectado" : "Desconectado");
|
||||
lblStripWifi.Text = "Wi-Fi: " + (WifiService.WifiConectado ? "Conectado" : WifiService.Conectando ? "Conectando..." : WifiService.WifiDisponivel ? "Disponivel" : "Desconectado");
|
||||
|
||||
bool opLiberada = Variaveis.OperacaoEmAndamento.OperacaoLiberada;
|
||||
lblStripOperacaoLiberada.Text = "Operação Liberada: " + (opLiberada ? "Sim" : "Não");
|
||||
lblStripOperacaoLiberada.ForeColor = opLiberada ? Color.Green : Color.Red;
|
||||
|
||||
lblStripPython.Text = "IA: " + (VariaveisOperacao.Operadores.Conectado ? "Conectado" : "Desconectado");
|
||||
lblStripPython.ForeColor = VariaveisOperacao.Operadores.Conectado ? Color.Green : Color.Red;
|
||||
|
||||
lblStripOperacaoLiberada.Text = "Operação Liberada: " + (Variaveis.OperacaoEmAndamento.OperacaoLiberada ? "Sim" : "Não");
|
||||
lblStripOperacaoLiberada.ForeColor = Variaveis.OperacaoEmAndamento.OperacaoLiberada ? Color.Green : Color.Red;
|
||||
|
||||
Variaveis.DebugMode = chbDebugMode.Checked;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ namespace AgroBase.Forms
|
|||
int ticksControle = 0;
|
||||
List<GPSModel> passosOperacao = new List<GPSModel>();
|
||||
int idxPassoOperacao = 0;
|
||||
double velocidadeCarroMs = 0.0;
|
||||
|
||||
DateTime UltimaAtualizacaoGps = DateTime.MinValue;
|
||||
|
||||
|
|
@ -66,27 +67,45 @@ namespace AgroBase.Forms
|
|||
Variaveis.OperacaoEmAndamento.Iniciado = false;
|
||||
}
|
||||
|
||||
DateTime t0 = DateTime.Now;
|
||||
private async Task tmrLeitura_Tick()
|
||||
{
|
||||
double latencia_tick = (DateTime.Now - t0).TotalSeconds;
|
||||
t0 = DateTime.Now;
|
||||
int.TryParse(txtTempoGPS.Text, out int tempo);
|
||||
if (tempo > 0)
|
||||
{
|
||||
tempoGps = tempo;
|
||||
}
|
||||
tmrLeitura.SetInterval((int)tempoGps);
|
||||
ticksControleMax = (int)(Variaveis.OperacaoEmAndamento.Controle.TiposControle.First(x => x.Tipo == T_Code.Dir).DelayEnvioComando / tempoGps);
|
||||
|
||||
AtualizarDadosTela();
|
||||
Func<bool> funcAtt = new Func<bool>(() =>
|
||||
{
|
||||
AtualizarDadosTela();
|
||||
return true;
|
||||
});
|
||||
Task.Run(() => FuncoesGlobais.ExecutarMetodoComVerificacaoCrossThread(this, funcAtt));
|
||||
|
||||
if (chbAutomatico.Checked)
|
||||
{
|
||||
btnAcrescentarGPS_Click(btnAcrescentarGPS, new EventArgs());
|
||||
}
|
||||
|
||||
|
||||
DateTime t1 = DateTime.Now;
|
||||
double latencia_exec = (t1 - t0).TotalSeconds;
|
||||
double frequencia_exec = 1.0 / Math.Max(latencia_exec, 1e-6);
|
||||
double frequencia_tick = 1.0 / Math.Max(latencia_tick, 1e-6);
|
||||
//Console.WriteLine($"Tempo por tick GPS: {Math.Round(latencia_exec, 4)} s, Frequencia: {Math.Round(frequencia_exec, 2)} Hz | Tempo entre tick GPS: {Math.Round(latencia_tick, 4)}, Frequencia: {Math.Round(frequencia_tick, 2)} Hz");
|
||||
double novoDelay = Math.Max(tempoGps - (latencia_exec * 1000.0), 1);
|
||||
tmrLeitura.SetInterval((int)novoDelay);
|
||||
}
|
||||
|
||||
bool AtualizandoTela = false;
|
||||
private void AtualizarDadosTela()
|
||||
{
|
||||
if (AtualizandoTela)
|
||||
return;
|
||||
AtualizandoTela = true;
|
||||
|
||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
||||
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
|
||||
|
||||
|
|
@ -152,6 +171,8 @@ namespace AgroBase.Forms
|
|||
|
||||
Variaveis.OperacaoEmAndamento.Mapa.AtualizarRuasSelecionadas();
|
||||
}
|
||||
|
||||
AtualizandoTela = false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -199,14 +220,14 @@ namespace AgroBase.Forms
|
|||
{
|
||||
GPSModel novaPosicao = new GPSModel();
|
||||
double velocidadeMs = FuncoesMatematicas.CalculaVelocidadeMsPercentual(Variaveis.OperacaoEmAndamento.SimulacaoRpmControle);
|
||||
double velocidade = FuncoesMatematicas.ConverteMsParaKmh(velocidadeMs);
|
||||
velocidadeCarroMs = FuncoesMatematicas.ConverteMsParaKmh(velocidadeMs);
|
||||
|
||||
Variaveis.OperacaoEmAndamento.DispMvd.Dados.VelocidadeMedia = velocidadeMs;
|
||||
|
||||
TimeSpan tempoPassado =
|
||||
double tempoPassado =
|
||||
!chbAutomatico.Checked || UltimaAtualizacaoGps == DateTime.MinValue ? // esta no modo manual
|
||||
new TimeSpan((int)tempoGps * 10000) : // 1 tick do tempo gps
|
||||
DateTime.Now - UltimaAtualizacaoGps; // tempo decorrido entre ticks do timer de leitura
|
||||
(tempoGps / 1000.0) : // 1 tick do tempo gps
|
||||
(DateTime.Now - UltimaAtualizacaoGps).TotalSeconds; // tempo decorrido entre ticks do timer de leitura
|
||||
|
||||
// Obtém os parâmetros
|
||||
double anguloAtual = double.Parse(txtAnguloGPS.Text);
|
||||
|
|
@ -253,21 +274,54 @@ namespace AgroBase.Forms
|
|||
}
|
||||
|
||||
// Calcula a nova posicao do robo
|
||||
novaPosicao = VariaveisEquipamento.SimularNovaPosicao(tipoMovimento, anguloControle, velocidadeMs, tempoPassado.TotalSeconds, anguloAtual, _Gps);
|
||||
//GPSModel pos = NovaPosicaoSimulacao(velocidadeMs, tempoPassado);
|
||||
if (true || novaPosicao == null)
|
||||
{
|
||||
novaPosicao = VariaveisEquipamento.SimularNovaPosicao(tipoMovimento, anguloControle, velocidadeMs, tempoPassado, anguloAtual, _Gps);
|
||||
}
|
||||
|
||||
//Console.WriteLine($"C#: {DadosPosicao(novaPosicao)}");
|
||||
//Console.WriteLine($"Py: {DadosPosicao(pos)}");
|
||||
|
||||
// Atualiza a interface gráfica
|
||||
txtAnguloGPS.Text = novaPosicao.OrientacaoReal.ToString("0.00");
|
||||
txtVelocidade.Text = velocidade.ToString("0.00");
|
||||
txtVelocidade.Text = velocidadeCarroMs.ToString("0.00");
|
||||
txtDistanciaGPS.Text = novaPosicao.Distancia.ToString("0.0000");
|
||||
txtLatitude.Text = novaPosicao.Latitude.ToString();
|
||||
txtLongitude.Text = novaPosicao.Longitude.ToString();
|
||||
|
||||
|
||||
UltimaAtualizacaoGps = DateTime.Now;
|
||||
|
||||
AtualizarPosicaoGPS();
|
||||
|
||||
AtualizarDadosTela();
|
||||
if (!chbAutomatico.Checked)
|
||||
{
|
||||
AtualizarDadosTela();
|
||||
}
|
||||
}
|
||||
|
||||
private GPSModel NovaPosicaoSimulacao(double velocidadeMs, double tempo)
|
||||
{
|
||||
if (Variaveis.OperacaoEmAndamento.Controle.SimulacaoMPC.Count() > 1)
|
||||
{
|
||||
double distancia = velocidadeMs * tempo;
|
||||
MPCSimulacaoModel posicao = Variaveis.OperacaoEmAndamento.Controle.SimulacaoMPC[1];
|
||||
GPSModel novaPosicao = new GPSModel()
|
||||
{
|
||||
Latitude = posicao.latitude,
|
||||
Longitude = posicao.longitude,
|
||||
OrientacaoReal = posicao.orientacao,
|
||||
Distancia = distancia,
|
||||
};
|
||||
return novaPosicao;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private string DadosPosicao(GPSModel pos)
|
||||
{
|
||||
if (pos == null) return "";
|
||||
return $"Lat: {pos.Latitude}, Long: {pos.Longitude}, Theta: {pos.OrientacaoReal}, Distancia: {pos.Distancia}";
|
||||
}
|
||||
|
||||
private void btnIniciarSimulacao_Click(object sender, EventArgs e)
|
||||
|
|
@ -408,10 +462,7 @@ namespace AgroBase.Forms
|
|||
|
||||
private void chbAutomatico_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (chbAutomatico.Checked)
|
||||
{
|
||||
UltimaAtualizacaoGps = DateTime.Now.AddMilliseconds(-tempoGps);
|
||||
}
|
||||
UltimaAtualizacaoGps = DateTime.MinValue;
|
||||
}
|
||||
|
||||
private void btnReiniciar_Click(object sender, EventArgs e)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using static AgroBase.Models.Enums;
|
||||
|
||||
|
|
@ -46,21 +47,21 @@ namespace AgroBase.Models
|
|||
{
|
||||
get
|
||||
{
|
||||
return VariaveisOperacao.Operadores.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.status ?? StatusModulo.Desconectado;
|
||||
return HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.status ?? StatusModulo.Desconectado;
|
||||
}
|
||||
}
|
||||
public double Saude
|
||||
{
|
||||
get
|
||||
{
|
||||
return VariaveisOperacao.Operadores.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.saude ?? 0;
|
||||
return HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.saude ?? 0;
|
||||
}
|
||||
}
|
||||
public string Erros
|
||||
{
|
||||
get
|
||||
{
|
||||
var motivos = VariaveisOperacao.Operadores.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.motivos ?? new System.Collections.Generic.List<string>();
|
||||
var motivos = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo)?.motivos ?? new System.Collections.Generic.List<string>();
|
||||
return string.Join(", ", motivos);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
public enum T_Code
|
||||
{
|
||||
Vzo = -1,
|
||||
Imu = 53,
|
||||
Mov = 100,
|
||||
Dir = 101,
|
||||
Sen = 102,
|
||||
|
|
@ -170,10 +171,11 @@
|
|||
{
|
||||
NaoIniciado = 0,
|
||||
Parametrizando = 1,
|
||||
Aguardando = 2,
|
||||
EmAndamento = 3,
|
||||
Parado = 4,
|
||||
Concluido = 5
|
||||
Calibrando = 2,
|
||||
Aguardando = 3,
|
||||
EmAndamento = 4,
|
||||
Parado = 5,
|
||||
Concluido = 6
|
||||
}
|
||||
|
||||
public enum StatusCarroMapa
|
||||
|
|
|
|||
|
|
@ -191,4 +191,5 @@ public class MPCSimulacaoModel
|
|||
{
|
||||
public double latitude { get; set; }
|
||||
public double longitude { get; set; }
|
||||
public double orientacao { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using AgroBase.Services;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
|
@ -29,9 +30,10 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
get
|
||||
{
|
||||
return VariaveisOperacao.Operadores.ModulosSaude.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante);
|
||||
return HealthWorkerService.ModulosSaude.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante);
|
||||
}
|
||||
}
|
||||
public bool AtuPronto { get; set; } = false;
|
||||
|
||||
public static PinoutDataModel Pinout { get; set; }
|
||||
public static List<FuncoesPinout> Funcoes { get; set; } = new List<FuncoesPinout>()
|
||||
|
|
@ -449,6 +451,7 @@ namespace AgroBase.Models.Modules
|
|||
var Dados = _dados as AtuadorModel;
|
||||
Dados.DadosLeitura = new AtuadorMensagemJsonModel();
|
||||
Dados.DadosLeitura.Momento = DateTime.MinValue;
|
||||
Dados.AtuPronto = false;
|
||||
Dados.PercentualErvasTerreno = 0;
|
||||
Dados.BombasPressurizadoras.ForEach(x => x.Funcoes = x.Funcoes.Distinct().ToList());
|
||||
|
||||
|
|
@ -758,6 +761,49 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> RealizarTestesIniciais()
|
||||
{
|
||||
// Ligar bomba
|
||||
bool BombaOk = false;
|
||||
|
||||
var Bomba = BombasPressurizadoras.FirstOrDefault();
|
||||
if (Bomba.Inicializado)
|
||||
{
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, true, Bomba.ID);
|
||||
|
||||
bool AtingiuPressao() => PressaoLinha >= Variaveis.OperacaoEmAndamento.Controle.PressaoLinha;
|
||||
|
||||
await FuncoesGlobais.AguardarCondicaoAsync(AtingiuPressao, 10000, 200);
|
||||
|
||||
BombaOk = AtingiuPressao();
|
||||
}
|
||||
|
||||
// Testar os bicos
|
||||
foreach (var Bico in BicosPulverizadores)
|
||||
{
|
||||
if (Bico.Inicializado)
|
||||
{
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, true, Bico.ID);
|
||||
|
||||
await Task.Delay(200);
|
||||
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, false, Bico.ID);
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
return BombaOk;
|
||||
}
|
||||
|
||||
public async Task RealizarCalibragemAsync()
|
||||
{
|
||||
var DispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
|
||||
if (DispAtu != null)
|
||||
DispAtu.Dados.AtuPronto = await DispAtu.Dados.RealizarTestesIniciais();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class AtuadorBicoModel
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
}
|
||||
public bool Referenciando { get; set; } = false;
|
||||
public DateTime UltimoReferenciamento { get; set; }
|
||||
public bool Referenciado { get; set; } = false;
|
||||
|
||||
public bool Comandar { get; set; } = false;
|
||||
public bool Inicializado
|
||||
|
|
@ -303,7 +305,7 @@ namespace AgroBase.Models.Modules
|
|||
if (Comandar)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle = Angulo_SP;
|
||||
Console.WriteLine($"Angulo Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle}");
|
||||
//Console.WriteLine($"Angulo Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoAnguloControle}");
|
||||
}
|
||||
|
||||
int mx = Sentido_SP == Sentido.Antihorario ? -1 : 1;
|
||||
|
|
@ -328,6 +330,8 @@ namespace AgroBase.Models.Modules
|
|||
|
||||
await Task.Delay(1000);
|
||||
|
||||
Referenciado = false;
|
||||
|
||||
await SetZero();
|
||||
|
||||
bool Sucesso = false;
|
||||
|
|
@ -382,6 +386,7 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
await SetZero();
|
||||
Console.WriteLine($"[DIR {Mod_ID}] - Referenciamento Concluído!");
|
||||
Referenciado = true;
|
||||
}
|
||||
|
||||
DateTime Inicio = DateTime.Now;
|
||||
|
|
@ -390,6 +395,8 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
|
||||
Referenciando = false;
|
||||
|
||||
UltimoReferenciamento = DateTime.Now;
|
||||
}
|
||||
|
||||
private int DefineVelocidadeReferenciamento()
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ namespace AgroBase.Models.Modules
|
|||
RPM_SP = Convert.ToInt32(RPM_SP * FatorCompensacaoCurvas);
|
||||
|
||||
Variaveis.OperacaoEmAndamento.SimulacaoRpmControle = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Average(x => x.MovMotor.RPM_SP) / VariaveisEquipamento.RelacaoRPM;
|
||||
Console.WriteLine($"RPM Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoRpmControle}");
|
||||
//Console.WriteLine($"RPM Atualizado para {Variaveis.OperacaoEmAndamento.SimulacaoRpmControle}");
|
||||
|
||||
switch (DirecaoAtual)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@ namespace AgroBase.Models.Modules
|
|||
|
||||
}
|
||||
}
|
||||
public bool DirPronto { get; set; } = false;
|
||||
public bool MovPronto { get; set; } = false;
|
||||
|
||||
public int _TaxaAmostragem { get; set; } = 1000;
|
||||
public int _TaxaAmostragem { get; set; } = 250;
|
||||
|
||||
public double DistanciaPercorridaOperacao { get; set; } = 0;
|
||||
public double TempoEmAtividade { get; set; } = 0;
|
||||
|
|
@ -119,10 +121,14 @@ namespace AgroBase.Models.Modules
|
|||
public void LimparDados<T>(T _dados)
|
||||
{
|
||||
var Dados = _dados as MovimentacaoUnificadaModel;
|
||||
Dados.DirPronto = false;
|
||||
Dados.MovPronto = false;
|
||||
Dados.Modulos.ForEach(x =>
|
||||
{
|
||||
x.MovMotor.Leitura = null;
|
||||
x.DirMotor.Leitura = null;
|
||||
x.DirMotor.UltimoReferenciamento = DateTime.MinValue;
|
||||
x.DirMotor.Referenciado = false;
|
||||
x.DirMotor.Referenciando = false;
|
||||
});
|
||||
|
||||
|
|
@ -219,7 +225,10 @@ namespace AgroBase.Models.Modules
|
|||
|
||||
if (UltimaDirecao != Direcao.Parado)
|
||||
{
|
||||
VelocidadeMedia = FuncoesMatematicas.ConverteKmhParaMs(Modulos.Where(x => x.Conectado && x.MovMotor.ComandoLigado).DefaultIfEmpty().Average(x => x?.MovMotor?.VelocidadeInstantanea ?? 0));
|
||||
if (!Variaveis.OperacaoEmAndamento.Simulando)
|
||||
{
|
||||
VelocidadeMedia = FuncoesMatematicas.ConverteKmhParaMs(Modulos.Where(x => x.Conectado && x.MovMotor.ComandoLigado).DefaultIfEmpty().Average(x => x?.MovMotor?.VelocidadeInstantanea ?? 0));
|
||||
}
|
||||
double tempo = _TaxaAmostragem / 1000.0;
|
||||
double distancia = tempo * VelocidadeMedia;
|
||||
DistanciaPercorridaTotal += distancia;
|
||||
|
|
@ -368,7 +377,7 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
}
|
||||
|
||||
public async Task RealizarReferenciamentoDirecional()
|
||||
public async Task<bool> RealizarReferenciamentoDirecional()
|
||||
{
|
||||
if (!MKS057DCanService.Referenciando)
|
||||
{
|
||||
|
|
@ -385,8 +394,21 @@ namespace AgroBase.Models.Modules
|
|||
await FuncoesGlobais.AguardarCondicaoAsync(ReferenciamentoConcluido, 2 * 1000 * 60, 1000);
|
||||
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = tipoControle;
|
||||
}
|
||||
|
||||
return Modulos.All(x => x.DirMotor.Referenciado);
|
||||
}
|
||||
|
||||
public async Task RealizarCalibragemAsync()
|
||||
{
|
||||
var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
|
||||
if (DispMvd != null)
|
||||
{
|
||||
DispMvd.Dados.MovPronto = DispMvd.Dados.Modulos.All(x => x.MovMotor.Inicializado);
|
||||
DispMvd.Dados.DirPronto = DispMvd.Dados.Modulos.All(x => x.DirMotor.Inicializado);
|
||||
if (DispMvd.Dados.Modulos.Any(x => x.DirMotor.Inicializado))
|
||||
DispMvd.Dados.DirPronto &= await DispMvd.Dados.RealizarReferenciamentoDirecional();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using System.Globalization;
|
|||
using System.Data;
|
||||
using static AgroBase.Services.LoRaEspService;
|
||||
using System.Windows.Forms;
|
||||
using AgroBase.Services.Operadores;
|
||||
|
||||
namespace AgroBase.Models.Modules
|
||||
{
|
||||
|
|
@ -38,7 +39,7 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
get
|
||||
{
|
||||
return VariaveisOperacao.Operadores.ModulosSaude.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante);
|
||||
return HealthWorkerService.ModulosSaude.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante);
|
||||
}
|
||||
}
|
||||
public SensoriamentoMensagemJsonModel DadosLeitura { get; set; } = new SensoriamentoMensagemJsonModel();
|
||||
|
|
@ -1689,8 +1690,6 @@ namespace AgroBase.Models.Modules
|
|||
public void LimparDados<T>(T _dados)
|
||||
{
|
||||
var Dados = _dados as SensoriamentoModel;
|
||||
Dados.CameraCaminho.frames = new Dictionary<Operadores.OperadoresModels.TipoComando, System.Drawing.Bitmap>();
|
||||
Dados.CamerasSolo.ForEach(cam => cam.frames = new Dictionary<Operadores.OperadoresModels.TipoComando, System.Drawing.Bitmap>());
|
||||
Dados.DadosLeitura = new SensoriamentoMensagemJsonModel();
|
||||
Dados.Reles.ForEach(x =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
using System;
|
||||
using AgroBase.Models.Operadores;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Threading.Tasks;
|
||||
using static AgroBase.Models.Enums;
|
||||
using static AgroBase.Models.Operadores.OperadoresModels;
|
||||
|
||||
namespace AgroBase.Models
|
||||
{
|
||||
|
|
@ -31,19 +32,47 @@ namespace AgroBase.Models
|
|||
public double fx { get; set; }
|
||||
public double baseline { get; set; }
|
||||
|
||||
public Dictionary<TipoComando, Bitmap> frames { get; set; } = new Dictionary<TipoComando, Bitmap>();
|
||||
public double DistanciaMaximaVisao { get; set; } = 5000;
|
||||
public double DistanciaMinimaVisao { get; set; } = 500;
|
||||
public double PercentualAlturaSolo { get; set; } = 30;
|
||||
|
||||
public bool newData { get; set; }
|
||||
public void setVisto() => newData = false;
|
||||
|
||||
public async Task<Bitmap> GetFrame(TipoComando tipo = TipoComando.GetCameraFrame)
|
||||
public Dictionary<VisualWorkerFrameType, OAKCameraFrameModel> frames
|
||||
{
|
||||
VariaveisOperacao.Operadores.HealthWorker.AdicionarComandoNaFila(tipo, new { mx_id = Id });
|
||||
await VariaveisOperacao.Operadores.HealthWorker.AguardarNovosDados(tipo, 10000);
|
||||
Bitmap bmp = (VariaveisOperacao.Operadores.HealthWorker.DadosLeitura.Leitura.obj?.frame ?? new OAKCameraFrameModel()).image;
|
||||
frames[tipo] = bmp;
|
||||
get
|
||||
{
|
||||
switch (Dispositivo)
|
||||
{
|
||||
case T_Code.Snr:
|
||||
return VisualWorkerService.DadosLeitura.CameraFrames;
|
||||
default:
|
||||
return new Dictionary<VisualWorkerFrameType, OAKCameraFrameModel>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<Bitmap> GetNewFrame(VisualWorkerFrameType tipo = VisualWorkerFrameType.Rgb)
|
||||
{
|
||||
OAKCameraFrameModel frame = null;
|
||||
switch (Dispositivo)
|
||||
{
|
||||
case T_Code.Snr:
|
||||
frame = await VisualWorkerService.GetCameraFrame(tipo);
|
||||
break;
|
||||
}
|
||||
Bitmap bmp = frame?.image();
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public void SaveFrames(List<VisualWorkerFrameType> frames, string nome, string caminho)
|
||||
{
|
||||
switch (Dispositivo)
|
||||
{
|
||||
case T_Code.Snr:
|
||||
VisualWorkerService.SaveCameraFrames(frames, nome, caminho);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public OAKCameraModel Clone()
|
||||
{
|
||||
|
|
@ -63,8 +92,6 @@ namespace AgroBase.Models
|
|||
Version = Version,
|
||||
fx = fx,
|
||||
baseline = baseline,
|
||||
frames = new Dictionary<TipoComando, Bitmap>(frames),
|
||||
newData = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -114,38 +141,19 @@ namespace AgroBase.Models
|
|||
|
||||
public class OAKCameraFrameModel
|
||||
{
|
||||
public long timestamp { get; set; }
|
||||
public DateTime timestamp { get; set; } = DateTime.MinValue;
|
||||
public string frame { get; set; }
|
||||
public Bitmap image { get; set; } = null;
|
||||
|
||||
private bool _newData = true;
|
||||
public bool newData
|
||||
public Bitmap image()
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_newData)
|
||||
{
|
||||
_newData = false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
_newData = value;
|
||||
}
|
||||
return FuncoesGlobais.Base64ToBitmap(frame);
|
||||
}
|
||||
|
||||
public OAKCameraFrameModel Clone()
|
||||
{
|
||||
return new OAKCameraFrameModel()
|
||||
{
|
||||
timestamp = timestamp,
|
||||
frame = frame,
|
||||
image = FuncoesGlobais.Base64ToBitmap(frame),
|
||||
newData = true
|
||||
frame = frame
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ using System.Drawing;
|
|||
using System.Text;
|
||||
using static AgroBase.Services.OIDCanService.OidHandler;
|
||||
using AgroBase.Models.Operadores;
|
||||
using AgroBase.Services.Operadores;
|
||||
using AgroBase.Forms;
|
||||
|
||||
namespace AgroBase.Models
|
||||
{
|
||||
|
|
@ -53,13 +55,15 @@ namespace AgroBase.Models
|
|||
public Form frmOperacao { get; set; }
|
||||
|
||||
#region STATUS DE CONTEXTO
|
||||
public StatusOperacao StatusAtual { get; set; }
|
||||
public StatusOperacao StatusAtual { get; private set; } = StatusOperacao.NaoIniciado;
|
||||
public bool Emergencia { get; set; } = false;
|
||||
public bool OperacaoLiberada { get; set; }
|
||||
public bool OperacaoLiberada { get; private set; } = false;
|
||||
public bool OperacaoConfigurada { get; private set; } = false;
|
||||
public string ErroOperacaoLiberada { get; set; }
|
||||
public DateTime TempoAguardando { get; set; }
|
||||
public DateTime TempoAguardando { get; private set; } = DateTime.Now;
|
||||
public bool Iniciado { get; set; }
|
||||
public bool Finalizando { get; set; } = false;
|
||||
public bool Calibrando { get; set; } = false;
|
||||
public DateTime DataInicio { get; set; } = DateTime.MinValue;
|
||||
public DateTime DataFim { get; set; } = DateTime.MinValue;
|
||||
public double TempoDecorridoSegs
|
||||
|
|
@ -69,13 +73,28 @@ namespace AgroBase.Models
|
|||
return (StatusAtual == StatusOperacao.Parametrizando ? 0 : ((Variaveis.OperacaoEmAndamento.DataFim != DateTime.MinValue ? Variaveis.OperacaoEmAndamento.DataFim : DateTime.Now) - Variaveis.OperacaoEmAndamento.DataInicio).TotalSeconds);
|
||||
}
|
||||
}
|
||||
public bool MovimentoLiberado
|
||||
|
||||
public void AtualizarDadosContexto()
|
||||
{
|
||||
get
|
||||
{
|
||||
return StatusAtual == StatusOperacao.EmAndamento && !Finalizando && !MKS057DCanService.Referenciando;
|
||||
}
|
||||
DateTime t0 = DateTime.Now;
|
||||
HealthWorkerService.AtualizarDadosContexto();
|
||||
DateTime t1 = DateTime.Now;
|
||||
|
||||
Variaveis.OperacaoEmAndamento.StatusAtual = (StatusOperacao)RedisService.GetField<int>(CtxKey.DadosOperacao, "status", 0);
|
||||
Variaveis.OperacaoEmAndamento.OperacaoLiberada = RedisService.GetField(CtxKey.DadosOperacao, "liberado", false);
|
||||
Variaveis.OperacaoEmAndamento.OperacaoConfigurada = RedisService.GetField(CtxKey.DadosOperacao, "configurado", false);
|
||||
var tempoAguardando = RedisService.GetField<long>(CtxKey.DadosOperacao, "tempo_aguardando", 0);
|
||||
Variaveis.OperacaoEmAndamento.TempoAguardando = DateTimeOffset.FromUnixTimeSeconds(tempoAguardando).UtcDateTime.AddSeconds(tempoAguardando % 1).ToLocalTime();
|
||||
//Console.WriteLine(Variaveis.OperacaoEmAndamento.OperacaoConfigurada);
|
||||
HealthWorkerService.ModulosSaude = RedisService.GetField<ManagerWorkerMessageResponseModulosPendentesModel[]>(CtxKey.DadosOperacao, "status_modulos").ToList();
|
||||
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = RedisService.GetField<string>(CtxKey.DadosOperacao, "motivo_nao_liberado");
|
||||
DateTime t2 = DateTime.Now;
|
||||
|
||||
//Console.WriteLine($"Atualizacao de Contexto: {Math.Round((t1 - t0).TotalSeconds), 4}, Saude Modulos: {Math.Round((t2 - t1).TotalSeconds), 4}, Total: {Math.Round((t2 - t0).TotalSeconds),4}");
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
|
@ -89,7 +108,7 @@ namespace AgroBase.Models
|
|||
public List<OperacaoParametrosMandatoriosModel> ParametrosMandatorios { get; set; } = new List<OperacaoParametrosMandatoriosModel>();
|
||||
public double CapacidadeReservatorio { get; set; } = 30;
|
||||
public int QuantidadeCamerasSolo { get; set; } = 1;
|
||||
public int TempoIniciarOperacao { get; set; } = 25;
|
||||
public int TempoIniciarOperacao { get; set; } = 5;
|
||||
public string ID { get; set; }
|
||||
public double tmrLogsInterval
|
||||
{
|
||||
|
|
@ -249,7 +268,7 @@ namespace AgroBase.Models
|
|||
//bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoMapaCarregado, 5000, 200);
|
||||
}
|
||||
|
||||
VariaveisOperacao.Operadores.HealthWorker.EnviarDadosOperacao();
|
||||
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
|
||||
|
||||
return (true, ruasSelecionadas);
|
||||
}
|
||||
|
|
@ -593,7 +612,7 @@ namespace AgroBase.Models
|
|||
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
|
||||
|
||||
VariaveisOperacao.Operadores.HealthWorker?.EnviarDadosOperacao();
|
||||
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -618,7 +637,7 @@ namespace AgroBase.Models
|
|||
DispAtu?.Dados?.ReiniciarLeituras(DispAtu?.Dados);
|
||||
DispSen?.Dados?.ReiniciarLeituras(DispSen?.Dados);
|
||||
|
||||
VariaveisOperacao.Operadores.HealthWorker.EnviarDadosOperacao();
|
||||
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
|
||||
|
||||
Sensoriamento.AtualizarDados();
|
||||
|
||||
|
|
@ -669,49 +688,43 @@ namespace AgroBase.Models
|
|||
|
||||
public async Task RealizarCalibragemInicialAsync()
|
||||
{
|
||||
Console.WriteLine("Calibragem inicial inciada...");
|
||||
Variaveis.OperacaoEmAndamento.Calibrando = true;
|
||||
|
||||
var DispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
|
||||
if (DispAtu != null)
|
||||
{
|
||||
// Ligar bomba
|
||||
var Bomba = DispAtu.Dados.BombasPressurizadoras.FirstOrDefault();
|
||||
if (Bomba.Inicializado)
|
||||
{
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, true, Bomba.ID);
|
||||
|
||||
await Task.Delay(5000);
|
||||
}
|
||||
|
||||
// Testar os bicos
|
||||
for (int i = 0; i < DispAtu.Dados.QuantidadeBicos; i++)
|
||||
{
|
||||
var Bico = DispAtu.Dados.BicosPulverizadores[i];
|
||||
if (Bico.Inicializado)
|
||||
{
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, true, Bico.ID);
|
||||
|
||||
await Task.Delay(200);
|
||||
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, false, Bico.ID);
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
|
||||
var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
|
||||
if (DispMvd != null)
|
||||
|
||||
var tasks = new List<Task>();
|
||||
if (DispAtu?.Dados != null) tasks.Add(DispAtu.Dados.RealizarCalibragemAsync());
|
||||
if (DispMvd?.Dados != null) tasks.Add(DispMvd.Dados.RealizarCalibragemAsync());
|
||||
|
||||
if (tasks.Count == 0)
|
||||
{
|
||||
// Referenciar motores de passo
|
||||
if (DispMvd.Dados.Modulos.Any(x => x.DirMotor.Inicializado))
|
||||
{
|
||||
//GeneralJoystick.EnviaComandoMotor(Keys.R);
|
||||
}
|
||||
Console.WriteLine("Nenhuma calibragem foi iniciada.");
|
||||
Variaveis.OperacaoEmAndamento.Calibrando = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/*if (KinectService.Iniciado)
|
||||
try
|
||||
{
|
||||
KinectService.RecalibrarSubdivisoes();
|
||||
}*/
|
||||
var allTasks = Task.WhenAll(tasks);
|
||||
var completed = await Task.WhenAny(allTasks, Task.Delay(2 * 60 * 1000));
|
||||
|
||||
if (completed == allTasks)
|
||||
{
|
||||
Console.WriteLine("Calibragem finalizada com sucesso!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Timeout na calibragem. Continuando mesmo assim.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro durante calibragem: {ex.Message}");
|
||||
}
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Calibrando = false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -729,7 +742,9 @@ namespace AgroBase.Models
|
|||
DispAtu?.Dados?.ReiniciarLeituras(DispAtu.Dados);
|
||||
DispSen?.Dados?.ReiniciarLeituras(DispSen.Dados);
|
||||
|
||||
VariaveisOperacao.Operadores.HealthWorker.EnviarDadosOperacao();
|
||||
await RealizarCalibragemInicialAsync();
|
||||
|
||||
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
|
||||
|
||||
Sensoriamento?.AtualizarDados();
|
||||
|
||||
|
|
@ -741,7 +756,12 @@ namespace AgroBase.Models
|
|||
|
||||
public void ReiniciarSimulacao()
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.StatusAtual = StatusOperacao.Parametrizando;
|
||||
RedisService.AtualizarCampos(
|
||||
CtxKey.DadosOperacao,
|
||||
("status", StatusOperacao.Parametrizando),
|
||||
("iniciado", false)
|
||||
);
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Iniciado = false;
|
||||
Variaveis.OperacaoEmAndamento.Simulando = false;
|
||||
Variaveis.OperacaoEmAndamento.Mapa = new MapasModel();
|
||||
|
|
@ -818,25 +838,22 @@ namespace AgroBase.Models
|
|||
|
||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||
|
||||
if (ForcarEnvio || MovimentoLiberado)
|
||||
foreach (var Ctrl in _Controle.TiposControle)
|
||||
{
|
||||
foreach (var Ctrl in _Controle.TiposControle)
|
||||
if (ForcarEnvio || ((Agora - Ctrl.UltimoComando).TotalMilliseconds > Ctrl.DelayEnvioComando))
|
||||
{
|
||||
if (ForcarEnvio || ((Agora - Ctrl.UltimoComando).TotalMilliseconds > Ctrl.DelayEnvioComando))
|
||||
if (Ctrl.Tipo == T_Code.Atu && !_Controle.PulverizadorAutomatico)
|
||||
{
|
||||
if (Ctrl.Tipo == T_Code.Atu && !_Controle.PulverizadorAutomatico)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IDispositivosService disp = Ctrl.Tipo == T_Code.Atu ?
|
||||
(IDispositivosService)Variaveis.OperacaoEmAndamento.DispAtu :
|
||||
(IDispositivosService)Variaveis.OperacaoEmAndamento.DispMvd;
|
||||
|
||||
var Protocolos = EnviarProtocoloComando(disp, Ctrl.Tipo, ForcarEnvio);
|
||||
Ctrl.UltimoComando = Agora;
|
||||
Ctrl.Comandos.AddRange(Protocolos);
|
||||
return;
|
||||
}
|
||||
|
||||
IDispositivosService disp = Ctrl.Tipo == T_Code.Atu ?
|
||||
(IDispositivosService)Variaveis.OperacaoEmAndamento.DispAtu :
|
||||
(IDispositivosService)Variaveis.OperacaoEmAndamento.DispMvd;
|
||||
|
||||
var Protocolos = EnviarProtocoloComando(disp, Ctrl.Tipo, ForcarEnvio);
|
||||
Ctrl.UltimoComando = Agora;
|
||||
Ctrl.Comandos.AddRange(Protocolos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1078,7 +1095,7 @@ namespace AgroBase.Models
|
|||
VolumeReservatorio = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VolumeReservatorio,
|
||||
PressaoLinha_SP = Variaveis.OperacaoEmAndamento.Controle.PressaoLinha,
|
||||
PressaoLinha = Variaveis.OperacaoEmAndamento.DispAtu.Dados.PressaoLinha,
|
||||
PotenciaBomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia).atual.valor,
|
||||
PotenciaBomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia).atual.valor ?? 0,
|
||||
BombaLigada = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombasPressurizadoras.FirstOrDefault().ComandoAtuar,
|
||||
VazaoFluxoMLpSInstantanea = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSInstantanea,
|
||||
VazaoFluxoMLpSMedia = Variaveis.OperacaoEmAndamento.DispAtu.Dados.VazaoFluxoMLpSMedia,
|
||||
|
|
@ -1093,7 +1110,7 @@ namespace AgroBase.Models
|
|||
Atuado = Bico.ComandoAtuar,
|
||||
MediaNivelFluxo = Bico.MediaNivelFluxo,
|
||||
Posicao = Bico.Posicao,
|
||||
StatusBico = Bico.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor,
|
||||
StatusBico = Bico.ValoresLeituras.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura).atual.valor ?? false,
|
||||
Atuacoes = Bico.Atuacoes,
|
||||
TempoAtuado = Bico.TempoAtuado,
|
||||
}).ToList(),
|
||||
|
|
@ -1118,13 +1135,10 @@ namespace AgroBase.Models
|
|||
SalvarLog(T_Code.Sen.ToString(), logSen, false);
|
||||
|
||||
VisualWorkerModel logSnr = Variaveis.OperacaoEmAndamento.Sensoriamento.OperadorVisual?.Clone();
|
||||
logSnr.Leitura.MomentoLog = Agora;
|
||||
logSnr.UltimaMensagem = Agora;
|
||||
SalvarLog(T_Code.Snr.ToString(), logSnr, Fim);
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await SalvarLogCameraCaminho();
|
||||
});
|
||||
SalvarLogCameraCaminho();
|
||||
|
||||
string ArquivoOp = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/data.lgop";
|
||||
if (!File.Exists(ArquivoOp))
|
||||
|
|
@ -1184,67 +1198,19 @@ namespace AgroBase.Models
|
|||
}
|
||||
}
|
||||
|
||||
private async Task SalvarLogCameraCaminho()
|
||||
private void SalvarLogCameraCaminho()
|
||||
{
|
||||
var Camera = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho;
|
||||
|
||||
string Caminho = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/" + Camera.Name;
|
||||
string Caminho = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/" + Camera.Dispositivo;
|
||||
if (!Directory.Exists(Caminho))
|
||||
{
|
||||
Directory.CreateDirectory(Caminho);
|
||||
}
|
||||
|
||||
string caminhoRgb = Caminho + "/" + Variaveis.OperacaoEmAndamento.idxLog + "_rgb.jpg";
|
||||
string caminhoHeatmap = Caminho + "/" + Variaveis.OperacaoEmAndamento.idxLog + "_heat.jpg";
|
||||
string caminhoRadar = Caminho + "/" + Variaveis.OperacaoEmAndamento.idxLog + "_radar.jpg";
|
||||
string caminhoSegmentacao = Caminho + "/" + Variaveis.OperacaoEmAndamento.idxLog + "_seg.jpg";
|
||||
string nome = Variaveis.OperacaoEmAndamento.idxLog.ToString();
|
||||
|
||||
await VariaveisOperacao.Operadores.SalvarFramesSonar();
|
||||
}
|
||||
|
||||
private void SalvarLogKinect(DateTime Agora)
|
||||
{
|
||||
KinectModel logKnt = new KinectModel()
|
||||
{
|
||||
Momento = Agora,
|
||||
AccW = KinectService.Leitura.AccW,
|
||||
AccX = KinectService.Leitura.AccX,
|
||||
AccY = KinectService.Leitura.AccY,
|
||||
AccZ = KinectService.Leitura.AccZ,
|
||||
AnguloElevacao = KinectService.Leitura.AnguloElevacao,
|
||||
Colisao = KinectService.Leitura.Colisao,
|
||||
DistanciaDaDireita = KinectService.Leitura.DistanciaDaDireita,
|
||||
DistanciaDaEsquerda = KinectService.Leitura.DistanciaDaEsquerda,
|
||||
Obstaculos = new List<Obstaculo>(KinectService.Leitura.Obstaculos),
|
||||
Subdivisoes = new List<Subdivisao>(KinectService.Parametros.Subdivisoes),
|
||||
Pitch = KinectService.Leitura.Pitch,
|
||||
Roll = KinectService.Leitura.Roll,
|
||||
VelX = KinectService.Leitura.VelX,
|
||||
VelY = KinectService.Leitura.VelY,
|
||||
VelZ = KinectService.Leitura.VelZ,
|
||||
Yaw = KinectService.Leitura.Yaw,
|
||||
UltimoCalculo = KinectService.Leitura.UltimoCalculo,
|
||||
UltimoComandoRespondido = KinectService.Leitura.Momento,
|
||||
};
|
||||
SalvarLog(T_Code.Knt.ToString(), logKnt, false);
|
||||
|
||||
string Caminho = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/" + T_Code.Knt.ToString();
|
||||
if (!Directory.Exists(Caminho))
|
||||
{
|
||||
Directory.CreateDirectory(Caminho);
|
||||
}
|
||||
|
||||
string rgb = Caminho + "/rgb_" + Variaveis.OperacaoEmAndamento.idxLog + ".jpg";
|
||||
string heat = Caminho + "/heat_" + Variaveis.OperacaoEmAndamento.idxLog + ".jpg";
|
||||
|
||||
lock (KinectService._lockBitmapRGB)
|
||||
{
|
||||
FuncoesGlobais.SalvarImagemComprimida(KinectService.bitmapRGB, rgb, 75L, 512, 512);
|
||||
}
|
||||
lock (KinectService._lockBitmapHeat)
|
||||
{
|
||||
FuncoesGlobais.SalvarImagemComprimida(KinectService.bitmapHeat, heat, 30L);
|
||||
}
|
||||
Camera.SaveFrames(new List<VisualWorkerFrameType>() { VisualWorkerFrameType.Rgb, VisualWorkerFrameType.Heatmap, VisualWorkerFrameType.RadarTopDown, VisualWorkerFrameType.Segmentacao }, nome, Caminho);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1361,7 +1327,8 @@ namespace AgroBase.Models
|
|||
public double Angulo_Min { get; set; } = -30;
|
||||
public double VelocidadeMP { get; set; } = 50;
|
||||
|
||||
public double Angulo { get; set; } = 0;
|
||||
private double _angulo_sp = 0.0;
|
||||
public double Angulo { get; set; }
|
||||
public int RPM_SP
|
||||
{
|
||||
get
|
||||
|
|
@ -1376,7 +1343,8 @@ namespace AgroBase.Models
|
|||
return Convert.ToInt32(RPM_SP * VariaveisEquipamento.RelacaoRPM);
|
||||
}
|
||||
}
|
||||
public double PercentualVelocidadeSP { get; set; } = 0.0;
|
||||
private double _velocidade_sp = 0.0;
|
||||
public double PercentualVelocidadeSP { get; set; }
|
||||
public double PercentualVelocidadeMin
|
||||
{
|
||||
get
|
||||
|
|
@ -1606,33 +1574,12 @@ namespace AgroBase.Models
|
|||
public OperacaoControleModel Controle { get; set; }
|
||||
public VisualWorkerModel OperadorVisual { get; set; }
|
||||
|
||||
private void AtualizarDadosOperacaoRedis()
|
||||
{
|
||||
var operacao = RedisService.Get(CtxKey.DadosOperacao);
|
||||
var parametros = JsonConvert.DeserializeObject<Dictionary<string, object>>(operacao);
|
||||
bool configurado = Convert.ToBoolean(parametros["configurado"]);
|
||||
long tempoAguardando = (long)(parametros["tempo_aguardando"]);
|
||||
int op_status = Convert.ToInt32(parametros["status"]);
|
||||
StatusOperacao statusOperacao = (StatusOperacao)op_status;
|
||||
bool liberado = Convert.ToBoolean(parametros["liberado"]);
|
||||
List<ManagerWorkerMessageResponseModulosPendentesModel> status_modulos = JsonConvert.DeserializeObject<ManagerWorkerMessageResponseModulosPendentesModel[]>(parametros["status_modulos"].ToString()).ToList();
|
||||
|
||||
Variaveis.OperacaoEmAndamento.TempoAguardando = DateTimeOffset.FromUnixTimeSeconds(tempoAguardando).UtcDateTime.AddSeconds(tempoAguardando % 1).ToLocalTime();
|
||||
|
||||
Variaveis.OperacaoEmAndamento.StatusAtual = statusOperacao;
|
||||
Variaveis.OperacaoEmAndamento.OperacaoLiberada = liberado;
|
||||
|
||||
VariaveisOperacao.Operadores.ModulosSaude = new List<ManagerWorkerMessageResponseModulosPendentesModel>(status_modulos);
|
||||
|
||||
var mandatorios = Variaveis.OperacaoEmAndamento.ModulosMandatorios.Select(x => x.Dispositivo).ToList();
|
||||
var mods_com_falha = status_modulos.Where(x => mandatorios.Contains(x.modulo) && x.status == Enums.StatusModulo.Falha);
|
||||
var motivos_por_modulo = mods_com_falha.Select(x => $"{x.modulo}: {string.Join("; ", x.motivos)}");
|
||||
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = string.Join(Environment.NewLine + Environment.NewLine, motivos_por_modulo);
|
||||
}
|
||||
|
||||
|
||||
public void AtualizarDados()
|
||||
{
|
||||
AtualizarDadosOperacaoRedis();
|
||||
Variaveis.OperacaoEmAndamento.AtualizarDadosContexto();
|
||||
VisualWorkerService.AtualizarAnalise();
|
||||
|
||||
var _Trajetoria = Variaveis.OperacaoEmAndamento.Trajetoria;
|
||||
var _DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
|
||||
|
|
@ -1650,7 +1597,7 @@ namespace AgroBase.Models
|
|||
? _DispAtu.Dados.VolumeVazaoML / totalAtuacoes
|
||||
: 0.0;
|
||||
|
||||
/*var sIMU = VariaveisOperacao.Operadores.VisualWorker?.DadosLeitura?.Leitura?.obj?.imu;
|
||||
var sIMU = VisualWorkerService.DadosLeitura.Imu;
|
||||
var dadosIMU = sIMU != null ? new OperacaoSensoriamentoLogImuModel()
|
||||
{
|
||||
Iniciado = sIMU.timestamp > 0,
|
||||
|
|
@ -1658,8 +1605,7 @@ namespace AgroBase.Models
|
|||
InclinacaoFrontal = sIMU.pitch,
|
||||
Rotacao = sIMU.yaw,
|
||||
RotacaoCorrigida = sIMU.yaw_fixed,
|
||||
} : new OperacaoSensoriamentoLogImuModel();*/
|
||||
var dadosIMU = new OperacaoSensoriamentoLogImuModel();
|
||||
} : new OperacaoSensoriamentoLogImuModel();
|
||||
|
||||
var dadosAtuador = _DispAtu != null ? new OperacaoSensoriamentoLogAtuModel()
|
||||
{
|
||||
|
|
@ -1730,12 +1676,6 @@ namespace AgroBase.Models
|
|||
|
||||
var dadosGps = GPSService.UltimaLeitura.Clone();
|
||||
|
||||
var visualWorker = VariaveisOperacao.Operadores.VisualWorker?.DadosLeitura?.Clone();
|
||||
if (visualWorker == null)
|
||||
{
|
||||
visualWorker = new VisualWorkerModel();
|
||||
}
|
||||
|
||||
var dadosControle = _Controle.Clone();
|
||||
|
||||
var dadosPerformance = Variaveis.OperacaoEmAndamento.DadosPerformance.Clone();
|
||||
|
|
@ -1754,15 +1694,13 @@ namespace AgroBase.Models
|
|||
Bateria = dadosBateria,
|
||||
Trajetoria = dadosTrajetoria,
|
||||
Gps = dadosGps,
|
||||
OperadorVisual = visualWorker,
|
||||
OperadorVisual = new VisualWorkerModel(),
|
||||
Controle = dadosControle,
|
||||
DadosPerformance = dadosPerformance
|
||||
};
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento = dadosAtualizados;
|
||||
Variaveis.OperacaoEmAndamento.DispSen?.Dados?.ContadorCarga?.AtualizarConsumo();
|
||||
VariaveisOperacao.Operadores.HealthWorker?.EnviarDadosContexto();
|
||||
VariaveisOperacao.Operadores.HealthWorker?.EnviarDadosModulos();
|
||||
}
|
||||
|
||||
public OperacaoSensoriamentoLogModel Clone(bool comSonar = false)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
using static AgroBase.Models.Enums;
|
||||
using static AgroBase.Models.Operadores.OperadoresModels;
|
||||
|
||||
namespace AgroBase.Models.Operadores
|
||||
{
|
||||
public class CameraWorkerModel
|
||||
{
|
||||
public bool Iniciado { get; set; }
|
||||
public DateTime IniciadoEm { get; set; }
|
||||
public bool Pronto { get; set; }
|
||||
public DateTime ProntoEm { get; set; }
|
||||
public DateTime UltimaMensagem { get; set; }
|
||||
|
||||
public VisualWorkerModel Clone()
|
||||
{
|
||||
return new VisualWorkerModel()
|
||||
{
|
||||
Iniciado = Iniciado,
|
||||
IniciadoEm = IniciadoEm,
|
||||
Pronto = Pronto,
|
||||
ProntoEm = ProntoEm,
|
||||
};
|
||||
}
|
||||
|
||||
public void ReiniciarEstado()
|
||||
{
|
||||
Iniciado = false;
|
||||
IniciadoEm = DateTime.MinValue;
|
||||
Pronto = false;
|
||||
ProntoEm = DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
|
||||
public class CameraWorkerItemModel
|
||||
{
|
||||
public T_Code dispositivo { get; set; }
|
||||
public string mx_id { get; set; }
|
||||
public string versao { get; set; }
|
||||
public string modelo { get; set; }
|
||||
public bool iniciado { get; set; }
|
||||
public SaudeWorkerModel saude { get; set; }
|
||||
public CameraWorkerItemPerformanceModel performance { get; set; }
|
||||
}
|
||||
|
||||
public class CameraWorkerItemPerformanceModel
|
||||
{
|
||||
public double temperatura { get; set; }
|
||||
public double memoria_usada { get; set; }
|
||||
public bool executando { get; set; }
|
||||
public string velocidade { get; set; }
|
||||
}
|
||||
|
||||
public enum CameraWorkerCommandType
|
||||
{
|
||||
ScriptCarregado = 1,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -11,7 +11,8 @@ namespace AgroBase.Models.Operadores
|
|||
public DateTime IniciadoEm { get; set; }
|
||||
public bool Pronto { get; set; }
|
||||
public DateTime ProntoEm { get; set; }
|
||||
public WorkerMessageModel<HealthWorkerMessageResponseModel> Leitura { get; set; } = new WorkerMessageModel<HealthWorkerMessageResponseModel>();
|
||||
public DateTime UltimaMensagem { get; set; }
|
||||
//public WorkerMessageModel<HealthWorkerMessageResponseModel> Leitura { get; set; } = new WorkerMessageModel<HealthWorkerMessageResponseModel>();
|
||||
|
||||
public HealthWorkerModel Clone()
|
||||
{
|
||||
|
|
@ -21,7 +22,7 @@ namespace AgroBase.Models.Operadores
|
|||
IniciadoEm = IniciadoEm,
|
||||
Pronto = Pronto,
|
||||
ProntoEm = ProntoEm,
|
||||
Leitura = Leitura.Clone()
|
||||
//Leitura = Leitura.Clone()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -31,65 +32,16 @@ namespace AgroBase.Models.Operadores
|
|||
IniciadoEm = DateTime.MinValue;
|
||||
Pronto = false;
|
||||
ProntoEm = DateTime.MinValue;
|
||||
Leitura = new WorkerMessageModel<HealthWorkerMessageResponseModel>();
|
||||
//Leitura = new WorkerMessageModel<HealthWorkerMessageResponseModel>();
|
||||
}
|
||||
}
|
||||
|
||||
public class HealthWorkerMessageResponseModel
|
||||
{
|
||||
public TipoComando cmd { get; set; }
|
||||
public HealthWorkerMessageResponseCamerasModel cameras { get; set; }
|
||||
public OAKCameraFrameModel frame { get; set; }
|
||||
}
|
||||
|
||||
public class HealthWorkerMessageResponseCamerasModel
|
||||
{
|
||||
public long timestamp { get; set; }
|
||||
public List<HealthWorkerMessageResponseCamerasItensModel> itens { get; set; }
|
||||
private bool _newData = false;
|
||||
public bool newData
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_newData)
|
||||
{
|
||||
_newData = false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
_newData = value;
|
||||
}
|
||||
}
|
||||
|
||||
public HealthWorkerMessageResponseCamerasModel Clone()
|
||||
{
|
||||
return new HealthWorkerMessageResponseCamerasModel()
|
||||
{
|
||||
itens = new List<HealthWorkerMessageResponseCamerasItensModel>(itens),
|
||||
newData = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class HealthWorkerMessageResponseCamerasItensModel
|
||||
{
|
||||
public T_Code dispositivo { get; set; }
|
||||
public string mx_id { get; set; }
|
||||
public string versao { get; set; }
|
||||
public string modelo { get; set; }
|
||||
}
|
||||
|
||||
public enum HealthWorkerCommandType
|
||||
{
|
||||
SetDadosModulo = 1,
|
||||
SetDadosContexto = 2,
|
||||
SetDadosOperacao = 3,
|
||||
ScriptCarregado = 1,
|
||||
AtualizarPontosMapa = 2,
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using static AgroBase.Models.Enums;
|
||||
using static AgroBase.Models.Operadores.OperadoresModels;
|
||||
|
||||
namespace AgroBase.Models.Operadores
|
||||
{
|
||||
|
|
@ -11,7 +10,8 @@ namespace AgroBase.Models.Operadores
|
|||
public DateTime IniciadoEm { get; set; }
|
||||
public bool Pronto { get; set; }
|
||||
public DateTime ProntoEm { get; set; }
|
||||
public WorkerMessageModel<ManagerWorkerMessageResponseModel> Leitura { get; set; }
|
||||
public DateTime UltimaMensagem { get; set; }
|
||||
//public WorkerMessageModel<ManagerWorkerMessageResponseModel> Leitura { get; set; }
|
||||
|
||||
public ManagerWorkerModel Clone()
|
||||
{
|
||||
|
|
@ -21,7 +21,7 @@ namespace AgroBase.Models.Operadores
|
|||
IniciadoEm = IniciadoEm,
|
||||
Pronto = Pronto,
|
||||
ProntoEm = ProntoEm,
|
||||
Leitura = Leitura.Clone()
|
||||
//Leitura = Leitura.Clone()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ namespace AgroBase.Models.Operadores
|
|||
IniciadoEm = DateTime.MinValue;
|
||||
Pronto = false;
|
||||
ProntoEm = DateTime.MinValue;
|
||||
Leitura = new WorkerMessageModel<ManagerWorkerMessageResponseModel>();
|
||||
//Leitura = new WorkerMessageModel<ManagerWorkerMessageResponseModel>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +57,7 @@ namespace AgroBase.Models.Operadores
|
|||
{
|
||||
public T_Code modulo { get; set; }
|
||||
public StatusModulo status { get; set; }
|
||||
public bool conectado { get; set; }
|
||||
public double saude { get; set; }
|
||||
public List<string> motivos { get; set; }
|
||||
public List<ManagerWorkerMessageResponseModulosPendentesSaudeModel> saude_individual { get; set; }
|
||||
|
|
@ -82,8 +83,11 @@ namespace AgroBase.Models.Operadores
|
|||
|
||||
public enum ManagerWorkerCommandType
|
||||
{
|
||||
IniciarMPC = 1,
|
||||
EnviarDadosControle = 2,
|
||||
ScriptCarregado = 1,
|
||||
IniciarMPC = 2,
|
||||
AtualizarMPC = 3,
|
||||
EnviarDadosControle = 4,
|
||||
FinalizarOperacao = 5,
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
using System;
|
||||
using AgroBase.Services;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AgroBase.Models.Operadores
|
||||
{
|
||||
public class OperadoresModels
|
||||
{
|
||||
private static double HeartbeatWorkers = 2.0;
|
||||
|
||||
public enum TipoComando
|
||||
{
|
||||
SetDadosModulo = 1,
|
||||
|
|
@ -16,6 +20,39 @@ namespace AgroBase.Models.Operadores
|
|||
GetCameraFrame = 8,
|
||||
}
|
||||
|
||||
public interface IWorkerModel
|
||||
{
|
||||
void MostrarLog(string message, int limite = 500);
|
||||
Task<bool> IniciarProcessamento();
|
||||
void RedisCallback(string mensagem);
|
||||
void AtualizarSaude();
|
||||
SaudeWorkerModel Saude { get; set; }
|
||||
}
|
||||
|
||||
public static SaudeWorkerModel AtualizarSaude(string _CtxKey)
|
||||
{
|
||||
string unixTime = RedisService.GetField(_CtxKey, "momento", "0.0");
|
||||
DateTime momento = FuncoesGlobais.UnixToDateTime(unixTime);
|
||||
|
||||
double frequencia = RedisService.GetField(_CtxKey, "frequencia", 0.0);
|
||||
|
||||
double latencia = RedisService.GetField(_CtxKey, "latencia", 0.0);
|
||||
|
||||
double tempoDesconectado = (DateTime.Now - momento).TotalSeconds;
|
||||
bool conectado = tempoDesconectado < HeartbeatWorkers;
|
||||
|
||||
SaudeWorkerModel Saude = new SaudeWorkerModel()
|
||||
{
|
||||
momento = momento,
|
||||
frequencia = frequencia,
|
||||
latencia = latencia,
|
||||
conectado = conectado,
|
||||
tempo_desconectado = tempoDesconectado
|
||||
};
|
||||
|
||||
return Saude;
|
||||
}
|
||||
|
||||
public class WorkerMessageModel<T>
|
||||
{
|
||||
public DateTime AdicionadoEm { get; set; }
|
||||
|
|
@ -45,6 +82,15 @@ namespace AgroBase.Models.Operadores
|
|||
}
|
||||
}
|
||||
|
||||
public class SaudeWorkerModel
|
||||
{
|
||||
public DateTime momento { get; set; }
|
||||
public double frequencia { get; set; }
|
||||
public double latencia { get; set; }
|
||||
public bool conectado { get; set; }
|
||||
public double tempo_desconectado { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using static AgroBase.Models.Operadores.OperadoresModels;
|
||||
|
||||
namespace AgroBase.Models.Operadores
|
||||
{
|
||||
|
|
@ -12,7 +11,11 @@ namespace AgroBase.Models.Operadores
|
|||
public DateTime IniciadoEm { get; set; }
|
||||
public bool Pronto { get; set; }
|
||||
public DateTime ProntoEm { get; set; }
|
||||
public WorkerMessageModel<VisualWorkerMessageResponseModel> Leitura { get; set; } = new WorkerMessageModel<VisualWorkerMessageResponseModel>();
|
||||
public DateTime UltimaMensagem { get; set; }
|
||||
public Dictionary<VisualWorkerFrameType, OAKCameraFrameModel> CameraFrames { get; set; }
|
||||
//public WorkerMessageModel<VisualWorkerMessageResponseModel> Leitura { get; set; } = new WorkerMessageModel<VisualWorkerMessageResponseModel>();
|
||||
public VisualWorkerMessageAnaliseModel Analises { get; set; } = new VisualWorkerMessageAnaliseModel();
|
||||
public VisualWorkerMessageIMUModel Imu { get; set; } = new VisualWorkerMessageIMUModel();
|
||||
public VisualWorkerDadosModel Resumo { get; set; } = new VisualWorkerDadosModel();
|
||||
|
||||
public VisualWorkerModel Clone()
|
||||
|
|
@ -23,7 +26,10 @@ namespace AgroBase.Models.Operadores
|
|||
IniciadoEm = IniciadoEm,
|
||||
Pronto = Pronto,
|
||||
ProntoEm = ProntoEm,
|
||||
Leitura = Leitura.Clone(),
|
||||
CameraFrames = new Dictionary<VisualWorkerFrameType, OAKCameraFrameModel>(CameraFrames ?? new Dictionary<VisualWorkerFrameType, OAKCameraFrameModel>()),
|
||||
Analises = Analises.Clone(),
|
||||
Imu = Imu.Clone(),
|
||||
//Leitura = Leitura.Clone(),
|
||||
Resumo = Resumo.Clone(),
|
||||
};
|
||||
}
|
||||
|
|
@ -34,7 +40,10 @@ namespace AgroBase.Models.Operadores
|
|||
IniciadoEm = DateTime.MinValue;
|
||||
Pronto = false;
|
||||
ProntoEm = DateTime.MinValue;
|
||||
Leitura = new WorkerMessageModel<VisualWorkerMessageResponseModel>();
|
||||
CameraFrames = new Dictionary<VisualWorkerFrameType, OAKCameraFrameModel>();
|
||||
Analises = new VisualWorkerMessageAnaliseModel();
|
||||
Imu = new VisualWorkerMessageIMUModel();
|
||||
//Leitura = new WorkerMessageModel<VisualWorkerMessageResponseModel>();
|
||||
Resumo = new VisualWorkerDadosModel();
|
||||
}
|
||||
}
|
||||
|
|
@ -119,26 +128,6 @@ namespace AgroBase.Models.Operadores
|
|||
public double yaw { get; set; }
|
||||
public double yaw_fixed { get; set; }
|
||||
|
||||
private bool _newData = false;
|
||||
public bool newData
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_newData)
|
||||
{
|
||||
_newData = false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
_newData = value;
|
||||
}
|
||||
}
|
||||
public VisualWorkerMessageIMUModel Clone()
|
||||
{
|
||||
return new VisualWorkerMessageIMUModel()
|
||||
|
|
@ -147,7 +136,6 @@ namespace AgroBase.Models.Operadores
|
|||
roll = roll,
|
||||
pitch = pitch,
|
||||
yaw = yaw,
|
||||
newData = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -190,48 +178,31 @@ namespace AgroBase.Models.Operadores
|
|||
|
||||
public class VisualWorkerMessageAnaliseModel
|
||||
{
|
||||
public long timestamp { get; set; }
|
||||
public DateTime timestamp { get; set; }
|
||||
public List<VisualWorkerMessageAnaliseBBoxModel> anomalias { get; set; }
|
||||
public List<VisualWorkerMessageAnaliseBBoxModel> sombras { get; set; }
|
||||
public VisualWorkerMessageAnaliseSoloModel solo { get; set; }
|
||||
public List<VisualWorkerMessageRadar2DPerfilModel> corredor_prof { get; set; }
|
||||
public List<VisualWorkerMessageRadar2DPerfilModel> corredor_seg { get; set; }
|
||||
|
||||
private bool _newData = false;
|
||||
public bool newData
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_newData)
|
||||
{
|
||||
_newData = false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
_newData = value;
|
||||
}
|
||||
}
|
||||
public VisualWorkerMessageAnaliseModel Clone()
|
||||
{
|
||||
return new VisualWorkerMessageAnaliseModel()
|
||||
{
|
||||
timestamp = timestamp,
|
||||
anomalias = new List<VisualWorkerMessageAnaliseBBoxModel>(anomalias ?? new List<VisualWorkerMessageAnaliseBBoxModel>()),
|
||||
sombras = new List<VisualWorkerMessageAnaliseBBoxModel>(sombras ?? new List<VisualWorkerMessageAnaliseBBoxModel>()),
|
||||
solo = solo?.Clone(),
|
||||
newData = true
|
||||
corredor_prof = new List<VisualWorkerMessageRadar2DPerfilModel>(corredor_prof ?? new List<VisualWorkerMessageRadar2DPerfilModel>()),
|
||||
corredor_seg = new List<VisualWorkerMessageRadar2DPerfilModel>(corredor_seg ?? new List<VisualWorkerMessageRadar2DPerfilModel>()),
|
||||
};
|
||||
}
|
||||
|
||||
public Bitmap PlotarAnalise(OAKCameraFrameModel frame)
|
||||
{
|
||||
if (frame?.image == null) return null;
|
||||
Bitmap img = frame?.image();
|
||||
if (img == null) return null;
|
||||
|
||||
try { frame.image.Clone(); } catch { return null; }
|
||||
|
||||
Bitmap img = new Bitmap(frame.image);
|
||||
using (Graphics g = Graphics.FromImage(img))
|
||||
{
|
||||
Pen penObstaculo = new Pen(Color.Red, 2);
|
||||
|
|
@ -254,7 +225,7 @@ namespace AgroBase.Models.Operadores
|
|||
// 🔸 Desenhar Bounding Boxes (Anomalias + Solo)
|
||||
List<VisualWorkerMessageAnaliseBBoxModel> bboxes = new List<VisualWorkerMessageAnaliseBBoxModel>();
|
||||
if (anomalias != null) bboxes.AddRange(anomalias);
|
||||
if (solo?.bbox_list != null) bboxes.AddRange(solo.bbox_list);
|
||||
//if (solo?.bbox_list != null) bboxes.AddRange(solo.bbox_list);
|
||||
|
||||
foreach (var bbox in bboxes)
|
||||
{
|
||||
|
|
@ -272,7 +243,11 @@ namespace AgroBase.Models.Operadores
|
|||
fill = brushLombada;
|
||||
}
|
||||
|
||||
var rect = new Rectangle(bbox.bbox[0], bbox.bbox[1], bbox.bbox[2], bbox.bbox[3]);
|
||||
int x = (int)(bbox.bbox[0] * imgWidth);
|
||||
int y = (int)(bbox.bbox[1] * imgHeight);
|
||||
int w = (int)(bbox.bbox[2] * imgWidth);
|
||||
int h = (int)(bbox.bbox[3] * imgHeight);
|
||||
var rect = new Rectangle(x, y, w, h);
|
||||
|
||||
// 🔸 Preencher com opacidade
|
||||
g.FillRectangle(fill, rect);
|
||||
|
|
@ -288,7 +263,7 @@ namespace AgroBase.Models.Operadores
|
|||
// 🔸 Linha da faixa do solo
|
||||
if (solo != null)
|
||||
{
|
||||
int yInicio = solo.y_inicio;
|
||||
int yInicio = imgHeight - (int)(solo.percent_y * imgHeight);
|
||||
g.DrawLine(penFaixaSolo, 0, yInicio, imgWidth, yInicio);
|
||||
}
|
||||
|
||||
|
|
@ -296,9 +271,9 @@ namespace AgroBase.Models.Operadores
|
|||
if (solo?.perfil != null && solo.perfil.Count > 1)
|
||||
{
|
||||
var perfil = solo.perfil;
|
||||
int setores = solo.n_setores;
|
||||
int yInicio = solo.y_inicio;
|
||||
int alturaRegiao = solo.altura_regiao;
|
||||
int setores = solo.perfil.Count;
|
||||
int yInicio = imgHeight - (int)(solo.percent_y * imgHeight);
|
||||
int alturaRegiao = imgHeight / solo.perfil.Count;
|
||||
|
||||
double maxZ = perfil.Max();
|
||||
double minZ = perfil.Min();
|
||||
|
|
@ -331,20 +306,24 @@ namespace AgroBase.Models.Operadores
|
|||
public class VisualWorkerMessageAnaliseSoloModel
|
||||
{
|
||||
public List<double> perfil { get; set; }
|
||||
public List<VisualWorkerMessageAnaliseBBoxModel> bbox_list { get; set; }
|
||||
public int y_inicio { get; set; }
|
||||
public int altura_regiao { get; set; }
|
||||
public int n_setores { get; set; }
|
||||
public double percent_y { get; set; }
|
||||
public double inclinacao { get; set; }
|
||||
//public List<VisualWorkerMessageAnaliseBBoxModel> bbox_list { get; set; }
|
||||
//public int y_inicio { get; set; }
|
||||
//public int altura_regiao { get; set; }
|
||||
//public int n_setores { get; set; }
|
||||
|
||||
public VisualWorkerMessageAnaliseSoloModel Clone()
|
||||
{
|
||||
return new VisualWorkerMessageAnaliseSoloModel()
|
||||
{
|
||||
perfil = new List<double>(perfil),
|
||||
bbox_list = new List<VisualWorkerMessageAnaliseBBoxModel>(bbox_list),
|
||||
y_inicio = y_inicio,
|
||||
altura_regiao = altura_regiao,
|
||||
n_setores = n_setores,
|
||||
percent_y = percent_y,
|
||||
inclinacao = inclinacao,
|
||||
//bbox_list = new List<VisualWorkerMessageAnaliseBBoxModel>(bbox_list),
|
||||
//y_inicio = y_inicio,
|
||||
//altura_regiao = altura_regiao,
|
||||
//n_setores = n_setores,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -352,7 +331,7 @@ namespace AgroBase.Models.Operadores
|
|||
public class VisualWorkerMessageAnaliseBBoxModel
|
||||
{
|
||||
public string tipo { get; set; }
|
||||
public List<int> bbox { get; set; } // [x, y, w, h]
|
||||
public List<double> bbox { get; set; } // [x, y, w, h]
|
||||
public List<double> centro_percentual { get; set; } // [x%, y%]
|
||||
public double? distancia_m { get; set; }
|
||||
public double? largura_m { get; set; }
|
||||
|
|
@ -398,7 +377,7 @@ namespace AgroBase.Models.Operadores
|
|||
|
||||
public Bitmap PlotarAnalsie(Bitmap img)
|
||||
{
|
||||
try
|
||||
/*try
|
||||
{
|
||||
using (Graphics g = Graphics.FromImage(img))
|
||||
{
|
||||
|
|
@ -443,7 +422,7 @@ namespace AgroBase.Models.Operadores
|
|||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}*/
|
||||
return img;
|
||||
}
|
||||
}
|
||||
|
|
@ -535,10 +514,21 @@ namespace AgroBase.Models.Operadores
|
|||
|
||||
public enum VisualWorkerCommandType
|
||||
{
|
||||
SalvarFrames = 1,
|
||||
IniciarCameraManager = 2,
|
||||
AtualizarSaudeCamera = 3,
|
||||
GetCameraFrame = 4,
|
||||
ScriptCarregado = 1,
|
||||
CalibrarProfundidade = 2,
|
||||
IniciarCameraManager = 3,
|
||||
AtualizarSaudeCamera = 4,
|
||||
GetCameraFrame = 5,
|
||||
SaveCameraFrames = 6,
|
||||
}
|
||||
|
||||
public enum VisualWorkerFrameType
|
||||
{
|
||||
Rgb = 1,
|
||||
Heatmap = 2,
|
||||
RadarTopDown = 3,
|
||||
Segmentacao = 4,
|
||||
Debug = 5
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using AgroBase.Services;
|
||||
using AgroBase.Models.Operadores;
|
||||
using AgroBase.Services;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -632,6 +633,8 @@ namespace AgroBase.Models
|
|||
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
|
||||
|
||||
//Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
|
||||
|
||||
RedisService.Publish(CmdKey.ManagerWorkerRx, JsonConvert.SerializeObject(new { cmd = ManagerWorkerCommandType.AtualizarMPC }));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1084,6 +1087,8 @@ namespace AgroBase.Models
|
|||
AtualizarDadosTrajetoria();
|
||||
|
||||
LoopAtualizaDados();
|
||||
|
||||
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
|
||||
}
|
||||
|
||||
private (int, int) AtualizaIndiceRuaLateralCorredor(int i, int idxDir, int incDir, int incEsq)
|
||||
|
|
|
|||
|
|
@ -91,16 +91,16 @@ namespace AgroBase.Models
|
|||
|
||||
public static class VariaveisEquipamento
|
||||
{
|
||||
public static double LarguraEsquerda { get; } = 42.0;
|
||||
public static double LarguraDireita { get; } = 42.0;
|
||||
public static double ComprimentoFrente { get; } = 57.0;
|
||||
public static double ComprimentoTras { get; } = 57.0;
|
||||
public static double LarguraEsquerda { get; } = 62.0;
|
||||
public static double LarguraDireita { get; } = 22.0;
|
||||
public static double ComprimentoFrente { get; } = 7.0;
|
||||
public static double ComprimentoTras { get; } = 107.0;
|
||||
public static double DistanciaEntreEixos { get; } = 92.0;
|
||||
public static double LarguraEquipamentoMm
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((LarguraEsquerda + LarguraDireita + 20.0) * 10.0);
|
||||
return ((LarguraEsquerda + LarguraDireita + 10.0) * 10.0);
|
||||
}
|
||||
}
|
||||
public static double TensaoMinimaBateria { get; set; } = 20.0;
|
||||
|
|
@ -312,7 +312,7 @@ namespace AgroBase.Models
|
|||
double longitude = PosicaoAtual.Longitude;
|
||||
|
||||
// Conversão de ângulo de graus para radianos
|
||||
double anguloRad = anguloAtual * (Math.PI / 180);
|
||||
double anguloRad = novoAngulo * (Math.PI / 180);
|
||||
|
||||
// Raio da Terra em metros
|
||||
double raioTerra = GPSUtils.RaioDaTerra;
|
||||
|
|
@ -1151,6 +1151,14 @@ namespace AgroBase.Models
|
|||
}
|
||||
}
|
||||
|
||||
public static DateTime UnixToDateTime(string unixTime)
|
||||
{
|
||||
double time = Convert.ToDouble(unixTime.Replace(".", ","));
|
||||
var dateTime = DateTimeOffset.FromUnixTimeMilliseconds((long)(time * 1000)).ToLocalTime();
|
||||
DateTime momento = dateTime.DateTime;
|
||||
return momento;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FuncoesMatematicas
|
||||
|
|
|
|||
|
|
@ -729,7 +729,11 @@ namespace AgroBase.Services
|
|||
//Variaveis.OperacaoEmAndamento.DispSen.Dados?.DadosLeitura?.SensoresIMU?.FirstOrDefault()?.AtualizarOffset(UltimaLeitura);
|
||||
}
|
||||
|
||||
if (gpsIniciado)
|
||||
if (Variaveis.OperacaoEmAndamento.Simulando)
|
||||
{
|
||||
anguloFinal = UltimaLeitura.OrientacaoMovimento;
|
||||
}
|
||||
else if (gpsIniciado)
|
||||
{
|
||||
// O GPS está disponível
|
||||
//anguloFinal = UltimaLeitura.OrientacaoReal;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
using AgroBase.Models.Operadores;
|
||||
using AgroBase.Models;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using static AgroBase.Models.Operadores.OperadoresModels;
|
||||
using System.Collections.Generic;
|
||||
using static AgroBase.Models.Enums;
|
||||
using System.Linq;
|
||||
|
||||
namespace AgroBase.Services.Operadores
|
||||
{
|
||||
public class CameraWorkerService : IWorkerModel
|
||||
{
|
||||
public CameraWorkerModel DadosLeitura = new CameraWorkerModel();
|
||||
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
|
||||
private static List<OAKCameraModel> CamerasConectadas = new List<OAKCameraModel>();
|
||||
|
||||
private bool DebugMode = true;
|
||||
|
||||
public void MostrarLog(string message, int limite = 500)
|
||||
{
|
||||
if (DebugMode)
|
||||
{
|
||||
Console.WriteLine($"[CameraWorker] {message.Substring(0, Math.Min(limite, message.Length))}{(message.Length > limite ? "..." : "")}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> IniciarProcessamento()
|
||||
{
|
||||
RedisService.Subscribe(CmdKey.CameraWorkerTx, RedisCallback);
|
||||
|
||||
DadosLeitura.IniciadoEm = DateTime.Now;
|
||||
DadosLeitura.Iniciado = true;
|
||||
|
||||
bool pronto() => DadosLeitura.Pronto;
|
||||
await FuncoesGlobais.AguardarCondicaoAsync(pronto, 5000);
|
||||
if (pronto())
|
||||
{
|
||||
MostrarLog("Processamento iniciado com sucesso");
|
||||
return true;
|
||||
}
|
||||
|
||||
MostrarLog("Timeout ao iniciar script");
|
||||
DadosLeitura.ReiniciarEstado();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void RedisCallback(string mensagem)
|
||||
{
|
||||
try
|
||||
{
|
||||
var comando = JsonConvert.DeserializeObject<ComandoRedis>(mensagem);
|
||||
|
||||
var cmd = (CameraWorkerCommandType)comando.cmd;
|
||||
|
||||
//MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case CameraWorkerCommandType.ScriptCarregado:
|
||||
DadosLeitura.Pronto = true;
|
||||
DadosLeitura.ProntoEm = DateTime.Now;
|
||||
MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
|
||||
break;
|
||||
|
||||
default:
|
||||
MostrarLog($"Comando não reconhecido: {comando.cmd}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MostrarLog($"Erro ao deserializar resposta: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
DadosLeitura.UltimaMensagem = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
public void AtualizarSaude()
|
||||
{
|
||||
Saude = OperadoresModels.AtualizarSaude(CtxKey.DadosCameraWorker);
|
||||
}
|
||||
|
||||
|
||||
public static List<OAKCameraModel> GetListaCameras()
|
||||
{
|
||||
CamerasConectadas = new List<OAKCameraModel>()
|
||||
{
|
||||
new OAKCameraModel()
|
||||
{
|
||||
Dispositivo = T_Code.Vzo,
|
||||
Index = -1,
|
||||
Name = "Sem Video"
|
||||
}
|
||||
};
|
||||
|
||||
var cameras_str = RedisService.Get(CtxKey.DadosCameras);
|
||||
var cameras = JsonConvert.DeserializeObject<Dictionary<string, CameraWorkerItemModel>>(cameras_str);
|
||||
|
||||
if (cameras.Any())
|
||||
{
|
||||
CamerasConectadas.AddRange(cameras.Values.Select(x => new OAKCameraModel()
|
||||
{
|
||||
Dispositivo = x.dispositivo,
|
||||
Version = x.versao,
|
||||
Name = x.modelo,
|
||||
Id = x.mx_id,
|
||||
}).ToList());
|
||||
}
|
||||
|
||||
return CamerasConectadas;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -2,31 +2,23 @@
|
|||
using AgroBase.Models.Operadores;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static AgroBase.Models.Enums;
|
||||
using static AgroBase.Models.Operadores.OperadoresModels;
|
||||
using static MqttService;
|
||||
|
||||
namespace AgroBase.Services.Operadores
|
||||
{
|
||||
public class HealthWorkerService
|
||||
public class HealthWorkerService : IWorkerModel
|
||||
{
|
||||
private string TopicoMQTT_Tx = "operador/health/rx";
|
||||
private MqttTopicosModel topicoTx;
|
||||
private string TopicoMQTT_Rx = "operador/health/tx";
|
||||
private MqttTopicosModel topicoRx;
|
||||
public HealthWorkerModel DadosLeitura = new HealthWorkerModel();
|
||||
public AsyncTaskTimerModel tmrFila;
|
||||
public int TimeoutRespostaComando = 10;
|
||||
public ConcurrentDictionary<TipoComando, WorkerMessageModel<HealthWorkerMessageResponseModel>> FilaComandos = new ConcurrentDictionary<TipoComando, WorkerMessageModel<HealthWorkerMessageResponseModel>>();
|
||||
private Dictionary<TipoComando, Func<bool>> mapaRespostas;
|
||||
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
|
||||
public static List<ManagerWorkerMessageResponseModulosPendentesModel> ModulosSaude = new List<ManagerWorkerMessageResponseModulosPendentesModel>();
|
||||
|
||||
private bool DebugMode = true;
|
||||
private static bool AtualizandoRedis = false;
|
||||
|
||||
private void MostrarLog(string message, int limite = 500)
|
||||
public void MostrarLog(string message, int limite = 500)
|
||||
{
|
||||
if (DebugMode)
|
||||
{
|
||||
|
|
@ -36,24 +28,11 @@ namespace AgroBase.Services.Operadores
|
|||
|
||||
public async Task<bool> IniciarProcessamento()
|
||||
{
|
||||
topicoRx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Rx, true, 2, MqttCallback);
|
||||
topicoTx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Tx);
|
||||
|
||||
RedisService.Subscribe(CmdKey.HealthWorkerTx, RedisCallback);
|
||||
|
||||
mapaRespostas = new Dictionary<TipoComando, Func<bool>>
|
||||
{
|
||||
{ TipoComando.GetListaCameras, () => DadosLeitura.Leitura.obj?.cameras?.newData ?? false },
|
||||
{ TipoComando.GetCameraFrame, () => DadosLeitura.Leitura.obj?.frame?.newData ?? false },
|
||||
};
|
||||
|
||||
DadosLeitura.IniciadoEm = DateTime.Now;
|
||||
DadosLeitura.Iniciado = true;
|
||||
|
||||
tmrFila?.Dispose();
|
||||
tmrFila = new AsyncTaskTimerModel("tmrHealthWorker_Fila", tmrFila_Tick, 10);
|
||||
tmrFila.Start();
|
||||
|
||||
bool pronto() => DadosLeitura.Pronto;
|
||||
await FuncoesGlobais.AguardarCondicaoAsync(pronto, 5000);
|
||||
if (pronto())
|
||||
|
|
@ -67,339 +46,358 @@ namespace AgroBase.Services.Operadores
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool AdicionarComandoNaFila(TipoComando cmd, dynamic payload = null)
|
||||
public void RedisCallback(string mensagem)
|
||||
{
|
||||
WorkerMessageModel<HealthWorkerMessageResponseModel> msg = new WorkerMessageModel<HealthWorkerMessageResponseModel>()
|
||||
try
|
||||
{
|
||||
AdicionadoEm = DateTime.Now,
|
||||
payload = new
|
||||
var comando = JsonConvert.DeserializeObject<ComandoRedis>(mensagem);
|
||||
|
||||
var cmd = (HealthWorkerCommandType)comando.cmd;
|
||||
|
||||
//MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
cmd = cmd,
|
||||
dados = payload
|
||||
}
|
||||
};
|
||||
|
||||
bool sucesso = FilaComandos.TryAdd(cmd, msg);
|
||||
if (!sucesso)
|
||||
{
|
||||
MostrarLog($"Mensagem {cmd} nao adicionada na fila");
|
||||
}
|
||||
|
||||
return sucesso;
|
||||
}
|
||||
|
||||
private async Task tmrFila_Tick()
|
||||
{
|
||||
DateTime agora = DateTime.Now;
|
||||
// remove as mensagens antigas que nao responderam para permitir envair novamente
|
||||
foreach (var item in FilaComandos.Where(x => x.Value.Enviado && agora > x.Value.EnviadoEm.AddSeconds(TimeoutRespostaComando)))
|
||||
{
|
||||
FilaComandos.TryRemove(item.Key, out var _);
|
||||
}
|
||||
// pega a mensagem mais antiga
|
||||
var msg = FilaComandos.Where(x => !x.Value.Enviado).OrderBy(x => x.Value.AdicionadoEm).FirstOrDefault();
|
||||
if (msg.Value == null) return;
|
||||
|
||||
var mensagem = new
|
||||
{
|
||||
comando = (int)msg.Key,
|
||||
dispositivo = (int)T_Code.Snr,
|
||||
payload = msg.Value.payload
|
||||
};
|
||||
|
||||
await Variaveis.MqttService.PublishAsync(topicoTx, JsonConvert.SerializeObject(mensagem), true);
|
||||
|
||||
msg.Value.Enviado = true;
|
||||
msg.Value.EnviadoEm = DateTime.Now;
|
||||
}
|
||||
|
||||
private async Task<bool> MqttCallback(MqttTopicosMensagensModel Mensagem)
|
||||
{
|
||||
if (!DadosLeitura.Pronto && Mensagem.Momento > DadosLeitura.IniciadoEm && Mensagem.Mensagem == "OK")
|
||||
{
|
||||
DadosLeitura.ProntoEm = DateTime.Now;
|
||||
DadosLeitura.Pronto = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var msgRx = JsonConvert.DeserializeObject<WorkerMessageModel<HealthWorkerMessageResponseModel>>(Mensagem.Mensagem);
|
||||
|
||||
if (msgRx == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FilaComandos.TryGetValue(msgRx.obj.cmd, out var msgTx);
|
||||
if (msgTx != null)
|
||||
{
|
||||
FilaComandos.TryRemove(msgRx.obj.cmd, out var msg);
|
||||
}
|
||||
|
||||
AtualizarDadosLeitura(msgRx);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void RedisCallback(string mensagem)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void AtualizarDadosLeitura(WorkerMessageModel<HealthWorkerMessageResponseModel> msg)
|
||||
{
|
||||
if (DadosLeitura.Leitura.obj == null)
|
||||
{
|
||||
DadosLeitura.Leitura.obj = new HealthWorkerMessageResponseModel();
|
||||
}
|
||||
switch (msg.obj.cmd)
|
||||
{
|
||||
case TipoComando.GetListaCameras:
|
||||
{
|
||||
DadosLeitura.Leitura.obj.cameras = msg.obj.cameras.Clone();
|
||||
case HealthWorkerCommandType.ScriptCarregado:
|
||||
DadosLeitura.Pronto = true;
|
||||
DadosLeitura.ProntoEm = DateTime.Now;
|
||||
MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
|
||||
break;
|
||||
}
|
||||
case TipoComando.GetCameraFrame:
|
||||
{
|
||||
DadosLeitura.Leitura.obj.frame = msg.obj.frame.Clone();
|
||||
|
||||
default:
|
||||
MostrarLog($"Comando não reconhecido: {comando.cmd}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
DadosLeitura.Leitura.MomentoLog = DateTime.Now;
|
||||
}
|
||||
|
||||
public async Task AguardarNovosDados(TipoComando cmd, int timeout = 1000)
|
||||
{
|
||||
if (mapaRespostas.TryGetValue(cmd, out var condicao))
|
||||
catch (Exception ex)
|
||||
{
|
||||
await FuncoesGlobais.AguardarCondicaoAsync(condicao, timeout, 10);
|
||||
MostrarLog($"Erro ao deserializar resposta: {ex.Message}");
|
||||
}
|
||||
else
|
||||
finally
|
||||
{
|
||||
MostrarLog($"Comando {cmd} não suportado no AguardarResposta.");
|
||||
DadosLeitura.UltimaMensagem = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
public void EnviarDadosContexto()
|
||||
public void AtualizarSaude()
|
||||
{
|
||||
Saude = OperadoresModels.AtualizarSaude(CtxKey.DadosHealthWorker);
|
||||
}
|
||||
|
||||
|
||||
private static void AtualizarDadosContextoLocal()
|
||||
{
|
||||
RedisService.AtualizarCampos(
|
||||
CtxKey.DadosOperacao,
|
||||
("debug_mode", Variaveis.DebugMode),
|
||||
("iniciado", Variaveis.OperacaoEmAndamento.Iniciado),
|
||||
("finalizando", Variaveis.OperacaoEmAndamento.Finalizando),
|
||||
("calibrando", Variaveis.OperacaoEmAndamento.Calibrando),
|
||||
("emergencia", Variaveis.OperacaoEmAndamento.Emergencia)
|
||||
);
|
||||
}
|
||||
|
||||
public static void AtualizarDadosContexto()
|
||||
{
|
||||
if (AtualizandoRedis)
|
||||
return;
|
||||
AtualizandoRedis = true;
|
||||
|
||||
AtualizarDadosContextoLocal();
|
||||
AtualizarDadosModulos();
|
||||
|
||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
||||
if (_Sensoriamento.Trajetoria == null) return;
|
||||
|
||||
var dados = new
|
||||
if (_Sensoriamento == null)
|
||||
{
|
||||
Trajetoria = new
|
||||
{
|
||||
status = (int)_Sensoriamento.Trajetoria.StatusCarro,
|
||||
manobrando = _Sensoriamento.Trajetoria.ManobrandoEntreRuas,
|
||||
erro_angular = _Sensoriamento.Trajetoria.ErroOrientacaoAngularCombinado,
|
||||
idx_proximo_ponto = _Sensoriamento.Trajetoria.ProximoPonto.idxPonto,
|
||||
CorredorAtual = new
|
||||
AtualizandoRedis = false;
|
||||
return;
|
||||
}
|
||||
|
||||
RedisService.AtualizarCampos(
|
||||
CtxKey.DadosContexto,
|
||||
("Trajetoria", _Sensoriamento.Trajetoria != null ? new
|
||||
{
|
||||
concluido = _Sensoriamento.Trajetoria.CorredorAtual.Concluido,
|
||||
dentro = _Sensoriamento.Trajetoria.CorredorAtual.Dentro,
|
||||
ultimo = _Sensoriamento.Trajetoria.CorredorAtual.Ultimo,
|
||||
largura = _Sensoriamento.Trajetoria.CorredorAtual.Largura,
|
||||
progresso = _Sensoriamento.Trajetoria.CorredorAtual.Progresso,
|
||||
dist_esq = _Sensoriamento.Trajetoria.DistanciaEsquerda,
|
||||
dist_dir = _Sensoriamento.Trajetoria.DistanciaDireita,
|
||||
angulo = _Sensoriamento.Trajetoria.AnguloCaminho,
|
||||
},
|
||||
},
|
||||
Gerais = new
|
||||
{
|
||||
velocidade_ms = _Sensoriamento.Movimentacao.VelocidadeMedia,
|
||||
ervas_no_radar = _Sensoriamento.Atuador.ErvasNoRadar,
|
||||
},
|
||||
};
|
||||
status = (int)_Sensoriamento.Trajetoria.StatusCarro,
|
||||
manobrando = _Sensoriamento.Trajetoria.ManobrandoEntreRuas,
|
||||
erro_angular = _Sensoriamento.Trajetoria.ErroOrientacaoAngularCombinado,
|
||||
idx_proximo_ponto = _Sensoriamento.Trajetoria.ProximoPonto.idxPonto,
|
||||
CorredorAtual = new
|
||||
{
|
||||
concluido = _Sensoriamento.Trajetoria.CorredorAtual.Concluido,
|
||||
dentro = _Sensoriamento.Trajetoria.CorredorAtual.Dentro,
|
||||
ultimo = _Sensoriamento.Trajetoria.CorredorAtual.Ultimo,
|
||||
largura = _Sensoriamento.Trajetoria.CorredorAtual.Largura,
|
||||
progresso = _Sensoriamento.Trajetoria.CorredorAtual.Progresso,
|
||||
dist_esq = _Sensoriamento.Trajetoria.DistanciaEsquerda,
|
||||
dist_dir = _Sensoriamento.Trajetoria.DistanciaDireita,
|
||||
angulo = _Sensoriamento.Trajetoria.AnguloCaminho,
|
||||
},
|
||||
} : null
|
||||
),
|
||||
("Gerais", new
|
||||
{
|
||||
velocidade_ms = _Sensoriamento.Movimentacao != null ? _Sensoriamento.Movimentacao.VelocidadeMedia : 0,
|
||||
ervas_no_radar = _Sensoriamento.Atuador != null ? _Sensoriamento.Atuador.ErvasNoRadar : 0,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
var comando = new
|
||||
{
|
||||
cmd = (int)HealthWorkerCommandType.SetDadosContexto,
|
||||
@params = dados
|
||||
};
|
||||
|
||||
RedisService.Publish(CmdKey.HealthWorkerRx, JsonConvert.SerializeObject(comando));
|
||||
AtualizandoRedis = false;
|
||||
}
|
||||
|
||||
public void EnviarDadosOperacao()
|
||||
private static void AtualizarDadosEquipamento()
|
||||
{
|
||||
if (Variaveis.OperacaoEmAndamento.DispMvd == null) return;
|
||||
RedisService.AtualizarCampos(
|
||||
CtxKey.DadosEquipamento,
|
||||
("largura", VariaveisEquipamento.LarguraEquipamentoMm / 1000.0),
|
||||
("distancia_entre_eixos", VariaveisEquipamento.DistanciaEntreEixos / 100.0),
|
||||
("percentual_reservatorio_min", VariaveisEquipamento.PercentualReservatorioMin),
|
||||
("percentual_tensao_bateria_min", VariaveisEquipamento.PercentualTensaoBateriaMin)
|
||||
);
|
||||
}
|
||||
|
||||
public static void AtualizarDadosOperacao()
|
||||
{
|
||||
if (AtualizandoRedis)
|
||||
return;
|
||||
AtualizandoRedis = true;
|
||||
|
||||
AtualizarDadosEquipamento();
|
||||
|
||||
if (Variaveis.OperacaoEmAndamento.DispMvd == null)
|
||||
{
|
||||
AtualizandoRedis = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||
|
||||
var dados = new
|
||||
{
|
||||
modo = (int)Variaveis.OperacaoEmAndamento.Modo,
|
||||
debug_mode = Variaveis.DebugMode,
|
||||
iniciado = Variaveis.OperacaoEmAndamento.Iniciado,
|
||||
finalizando = Variaveis.OperacaoEmAndamento.Finalizando,
|
||||
emergencia = Variaveis.OperacaoEmAndamento.Emergencia,
|
||||
tempo_aguardar_inicio_operacao = Variaveis.OperacaoEmAndamento.TempoIniciarOperacao,
|
||||
sonar_ativado = _Controle.SonarAtivado,
|
||||
modulos_mandatorios = Variaveis.OperacaoEmAndamento.ModulosMandatorios.Select(x => (int)x.Dispositivo).ToArray(),
|
||||
parametros_mandatorios = Variaveis.OperacaoEmAndamento.ParametrosMandatorios.Select(x => (int)x.Parametro).ToArray(),
|
||||
Mov = new
|
||||
{
|
||||
percent_vel_max = _Controle.PercentualVelocidadeMax,
|
||||
percent_vel_min = _Controle.PercentualVelocidadeMin,
|
||||
},
|
||||
Dir = new
|
||||
{
|
||||
angulo_max = _Controle.Angulo_Max,
|
||||
vel_movimento = _Controle.VelocidadeMP,
|
||||
tipo_controle = (int)_Controle.TipoControleDirecional,
|
||||
mpc = new
|
||||
RedisService.AtualizarCampos(
|
||||
CtxKey.DadosOperacao,
|
||||
("configurado", true),
|
||||
("modo", Variaveis.OperacaoEmAndamento.Modo),
|
||||
("tempo_aguardar_inicio_operacao", Variaveis.OperacaoEmAndamento.TempoIniciarOperacao),
|
||||
("modulos_mandatorios", Variaveis.OperacaoEmAndamento.ModulosMandatorios.Select(x => (int)x.Dispositivo).ToArray()),
|
||||
("parametros_mandatorios", Variaveis.OperacaoEmAndamento.ParametrosMandatorios.Select(x => (int)x.Parametro).ToArray()),
|
||||
("Mov", new
|
||||
{
|
||||
pontos = Variaveis.OperacaoEmAndamento.Trajetoria?._TrajetoriaFixa?
|
||||
.Select(p => new
|
||||
{
|
||||
lat = p.Posicao.Latitude,
|
||||
lon = p.Posicao.Longitude,
|
||||
tipo = (int)p.Tipo,
|
||||
distanciaMargem = p.LarguraCorredor * 0.8
|
||||
})
|
||||
.ToList(),
|
||||
horizonte = 2.5,
|
||||
angulo_max_graus = _Controle.Angulo_Max,
|
||||
distancia_entre_eixos = (VariaveisEquipamento.DistanciaEntreEixos / 100.0),
|
||||
largura_equipamento = (VariaveisEquipamento.LarguraEquipamentoMm / 1000.0),
|
||||
velocidade_min = FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Controle.PercentualVelocidadeMin),
|
||||
velocidade_max = FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Controle.PercentualVelocidadeMax)
|
||||
percent_vel_max = _Controle.PercentualVelocidadeMax,
|
||||
percent_vel_min = _Controle.PercentualVelocidadeMin,
|
||||
}
|
||||
},
|
||||
Atu = new
|
||||
{
|
||||
percent_vertical_deteccao = _Controle.PercentualInicioPulverizacao,
|
||||
capacidade_reservatorio = Variaveis.OperacaoEmAndamento.CapacidadeReservatorio,
|
||||
pressao_linha = _Controle.PressaoLinha,
|
||||
},
|
||||
Snr = new
|
||||
{
|
||||
mx_id = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.Id
|
||||
}
|
||||
};
|
||||
),
|
||||
("Dir", new
|
||||
{
|
||||
angulo_max = _Controle.Angulo_Max,
|
||||
vel_movimento = _Controle.VelocidadeMP,
|
||||
tipo_controle = (int)_Controle.TipoControleDirecional,
|
||||
mpc = new
|
||||
{
|
||||
pontos = Variaveis.OperacaoEmAndamento.Trajetoria?._TrajetoriaFixa?
|
||||
.Select(p => new
|
||||
{
|
||||
lat = p.Posicao.Latitude,
|
||||
lon = p.Posicao.Longitude,
|
||||
tipo = (int)p.Tipo,
|
||||
distanciaMargem = p.LarguraCorredor * 0.8
|
||||
})
|
||||
.ToList(),
|
||||
horizonte = 2.5,
|
||||
angulo_max_graus = _Controle.Angulo_Max,
|
||||
velocidade_min = FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Controle.PercentualVelocidadeMin),
|
||||
velocidade_max = FuncoesMatematicas.CalculaVelocidadeMsPercentual(_Controle.PercentualVelocidadeMax)
|
||||
}
|
||||
}
|
||||
),
|
||||
("Atu", new
|
||||
{
|
||||
percent_vertical_deteccao = _Controle.PercentualInicioPulverizacao,
|
||||
capacidade_reservatorio = Variaveis.OperacaoEmAndamento.CapacidadeReservatorio,
|
||||
pressao_linha = _Controle.PressaoLinha,
|
||||
}
|
||||
),
|
||||
("Snr", new
|
||||
{
|
||||
mx_id = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.Id,
|
||||
percentual_altura_solo = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.PercentualAlturaSolo,
|
||||
distancia_maxima = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.DistanciaMaximaVisao,
|
||||
distancia_minima = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.DistanciaMinimaVisao
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
var comando = new
|
||||
if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS && (Variaveis.OperacaoEmAndamento.Trajetoria?._TrajetoriaFixa?.Count() ?? 0) > 0)
|
||||
{
|
||||
cmd = (int)HealthWorkerCommandType.SetDadosOperacao,
|
||||
@params = dados
|
||||
};
|
||||
var comando = new
|
||||
{
|
||||
cmd = HealthWorkerCommandType.AtualizarPontosMapa
|
||||
};
|
||||
RedisService.Publish(CmdKey.HealthWorkerRx, JsonConvert.SerializeObject(comando));
|
||||
}
|
||||
|
||||
RedisService.Publish(CmdKey.HealthWorkerRx, JsonConvert.SerializeObject(comando));
|
||||
AtualizandoRedis = false;
|
||||
}
|
||||
|
||||
public void EnviarDadosModulos()
|
||||
private static void AtualizarDadosModulos()
|
||||
{
|
||||
if (Variaveis.OperacaoEmAndamento.DispMvd == null) return;
|
||||
|
||||
var _Sensoriamento = Variaveis.OperacaoEmAndamento.Sensoriamento;
|
||||
var agora = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
|
||||
var dados = new
|
||||
//Console.WriteLine(RedisService.Get(RedisService.ModKey(Enums.T_Code.Gps)));
|
||||
//Console.WriteLine(RedisService.Get(RedisService.ModKey(Enums.T_Code.Dir)));
|
||||
//Console.WriteLine(RedisService.Get(RedisService.ModKey(Enums.T_Code.Mov)));
|
||||
//Console.WriteLine(RedisService.Get(RedisService.ModKey(Enums.T_Code.Sen)));
|
||||
|
||||
//RedisService.SetObject(RedisService.ModKey(Enums.T_Code.Gps), string.Empty);
|
||||
//RedisService.SetObject(RedisService.ModKey(Enums.T_Code.Dir), string.Empty);
|
||||
//RedisService.SetObject(RedisService.ModKey(Enums.T_Code.Mov), string.Empty);
|
||||
//RedisService.SetObject(RedisService.ModKey(Enums.T_Code.Sen), string.Empty);
|
||||
|
||||
if (_Sensoriamento.Gps != null)
|
||||
{
|
||||
Gps = new
|
||||
{
|
||||
conectado = GPSService.Iniciado,
|
||||
freq_base = GPSService.TaxaAmostragemHz,
|
||||
lat = _Sensoriamento.Gps.Latitude,
|
||||
lon = _Sensoriamento.Gps.Longitude,
|
||||
theta = _Sensoriamento.Gps.AnguloCarroDefinido,
|
||||
fix = (int)_Sensoriamento.Gps.QualidadeFix,
|
||||
rtk = GPSService.UltimoEnvioCorrecaoRTK.AddSeconds(5) > DateTime.Now,
|
||||
hAcc = _Sensoriamento.Gps.PrecisaoCm,
|
||||
nSatelites = _Sensoriamento.Gps.NumeroSatelites.valor,
|
||||
freq = _Sensoriamento.Gps.NumeroSatelites.frequencia,
|
||||
},
|
||||
Dir = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Select(x => new
|
||||
{
|
||||
conectado = x.DirMotor.Inicializado,
|
||||
freq_base = Variaveis.OperacaoEmAndamento.DispMvd.Dados.tmrRegistradorDIR.IntervalHz,
|
||||
endereco = x.DirMotor._EnderecoCAN_Tx,
|
||||
mod_id = x.Modulo_ID,
|
||||
angulo = x.DirMotor.Angulo,
|
||||
angulo_sp = x.DirMotor.Angulo_SP,
|
||||
comandar = x.DirMotor.Comandar,
|
||||
in1_atuado = x.DirMotor.IN1_Atuado,
|
||||
sentido = x.DirMotor.Sentido,
|
||||
sentido_sp = x.DirMotor.Sentido_SP,
|
||||
sentido_real = x.DirMotor.SentidoReal,
|
||||
freq = new
|
||||
{
|
||||
io = x.DirMotor.Leitura?.NumeroPulsos?.frequencia ?? 0,
|
||||
pulsos = x.DirMotor.Leitura?.EntradaIN1?.frequencia ?? 0,
|
||||
}
|
||||
}).ToArray(),
|
||||
Mov = Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos.Select(x => new
|
||||
{
|
||||
conectado = x.MovMotor.Inicializado,
|
||||
freq_base = Variaveis.OperacaoEmAndamento.DispMvd.Dados.tmrRegistradorMOV.IntervalHz,
|
||||
endereco = x.MovMotor._EnderecoCAN_Tx,
|
||||
mod_id = x.Modulo_ID,
|
||||
cod_erro = x.MovMotor.CodigoAlarme,
|
||||
rpm = x.MovMotor.RPM_Roda,
|
||||
rpm_sp = x.MovMotor.RPM_SP_Leitura,
|
||||
tensao = x.MovMotor.Tensao,
|
||||
corrente_motor = x.MovMotor.Corrente_Motor,
|
||||
corrente_barramento = x.MovMotor.Corrente_Barramento,
|
||||
temperatura_driver = x.MovMotor.TemperaturaDriver,
|
||||
temperatura_motor = x.MovMotor.Temperatura,
|
||||
freado = x.MovMotor.Leitura?.Freado ?? false,
|
||||
freq = new
|
||||
{
|
||||
erro = x.MovMotor.Leitura?.CodigoAlarme?.frequencia ?? 0,
|
||||
rpm = x.MovMotor.Leitura?.ERPM?.frequencia ?? 0,
|
||||
tensao = x.MovMotor.Leitura?.Tensao?.frequencia ?? 0,
|
||||
corrente_motor = x.MovMotor.Leitura?.CorrenteMotor?.frequencia ?? 0,
|
||||
corrente_barramento = x.MovMotor.Leitura?.CorrenteBarramento?.frequencia ?? 0,
|
||||
temperatura = x.MovMotor.Leitura?.Temperatura?.frequencia ?? 0,
|
||||
}
|
||||
}).ToArray(),
|
||||
Sen = new
|
||||
{
|
||||
conectado = Variaveis.OperacaoEmAndamento.DispSen.Dados.Conectado,
|
||||
freq_base = Variaveis.OperacaoEmAndamento.DispSen.Dados.tmrRegistrador.IntervalHz,
|
||||
sensores = Variaveis.OperacaoEmAndamento.DispSen.Dados.Sensores.Select(x => new
|
||||
{
|
||||
conectado = x.Inicializado,
|
||||
id = x.ID_Num,
|
||||
label = x.ID,
|
||||
tipo = (int)x.Componente,
|
||||
aferir = x.Aferir,
|
||||
mandatorio = x.Mandatorio,
|
||||
dados = x.ValoresLeituras.Where(y => y.analise_health).Select(y => new
|
||||
{
|
||||
label = y.funcao.ToString(),
|
||||
nominal = y.nominal,
|
||||
maximo = y.maximo,
|
||||
minimo = y.minimo,
|
||||
atual = y.atual.valor,
|
||||
freq = y.atual.frequencia
|
||||
}),
|
||||
}).ToArray(),
|
||||
servos = Variaveis.OperacaoEmAndamento.DispSen.Dados.Servos.Select(x => new
|
||||
{
|
||||
conectado = x.Inicializado,
|
||||
id = x.ID_Num,
|
||||
label = x.ID,
|
||||
controlar = x.Controlar,
|
||||
mandatorio = x.Mandatorio,
|
||||
angulo_sp = x._AnguloControle,
|
||||
dados = x.ValoresLeituras.Where(y => y.analise_health).Select(y => new
|
||||
{
|
||||
label = y.funcao.ToString(),
|
||||
atual = y.atual.valor,
|
||||
freq = y.atual.frequencia
|
||||
}),
|
||||
}).ToArray(),
|
||||
},
|
||||
};
|
||||
RedisService.AtualizarCampos(
|
||||
RedisService.ModKey(Enums.T_Code.Gps),
|
||||
("timestamp", agora),
|
||||
("conectado", GPSService.Iniciado),
|
||||
("freq_base", GPSService.TaxaAmostragemHz),
|
||||
("lat", _Sensoriamento.Gps.Latitude),
|
||||
("lon", _Sensoriamento.Gps.Longitude),
|
||||
("theta", _Sensoriamento.Gps.AnguloCarroDefinido),
|
||||
("fix", (int)_Sensoriamento.Gps.QualidadeFix),
|
||||
("rtk", GPSService.UltimoEnvioCorrecaoRTK.AddSeconds(5) > DateTime.Now),
|
||||
("hAcc", _Sensoriamento.Gps.PrecisaoCm),
|
||||
("nSatelites", _Sensoriamento.Gps.NumeroSatelites.valor),
|
||||
("freq", _Sensoriamento.Gps.NumeroSatelites.frequencia)
|
||||
);
|
||||
}
|
||||
|
||||
var comando = new
|
||||
foreach (var mod in Variaveis.OperacaoEmAndamento.DispMvd.Dados.Modulos)
|
||||
{
|
||||
cmd = (int)HealthWorkerCommandType.SetDadosModulo,
|
||||
@params = dados
|
||||
};
|
||||
int endereco_dir = mod.DirMotor._EnderecoCAN_Tx;
|
||||
RedisService.AtualizarCampos(
|
||||
RedisService.ModKey(Enums.T_Code.Dir),
|
||||
($"{endereco_dir}.timestamp", agora),
|
||||
($"{endereco_dir}.conectado", mod.DirMotor.Inicializado),
|
||||
($"{endereco_dir}.freq_base", Variaveis.OperacaoEmAndamento.DispMvd.Dados.tmrRegistradorDIR.IntervalHz),
|
||||
($"{endereco_dir}.endereco", mod.DirMotor._EnderecoCAN_Tx),
|
||||
($"{endereco_dir}.mod_id", mod.Modulo_ID),
|
||||
($"{endereco_dir}.angulo", mod.DirMotor.Angulo),
|
||||
($"{endereco_dir}.angulo_sp", mod.DirMotor.Angulo_SP),
|
||||
($"{endereco_dir}.comandar", mod.DirMotor.Comandar),
|
||||
($"{endereco_dir}.referenciado", mod.DirMotor.Referenciado),
|
||||
($"{endereco_dir}.in1_atuado", mod.DirMotor.IN1_Atuado),
|
||||
($"{endereco_dir}.sentido", mod.DirMotor.Sentido),
|
||||
($"{endereco_dir}.sentido_sp", mod.DirMotor.Sentido_SP),
|
||||
($"{endereco_dir}.sentido_real", mod.DirMotor.SentidoReal),
|
||||
($"{endereco_dir}.freq.io", mod.DirMotor.Leitura?.NumeroPulsos?.frequencia ?? 0),
|
||||
($"{endereco_dir}.freq.pulsos", mod.DirMotor.Leitura?.EntradaIN1?.frequencia ?? 0)
|
||||
);
|
||||
|
||||
RedisService.Publish(CmdKey.HealthWorkerRx, JsonConvert.SerializeObject(comando));
|
||||
int endereco_mov = mod.MovMotor._EnderecoCAN_Tx;
|
||||
RedisService.AtualizarCampos(
|
||||
RedisService.ModKey(Enums.T_Code.Mov),
|
||||
($"{endereco_mov}.timestamp", agora),
|
||||
($"{endereco_mov}.conectado", mod.MovMotor.Inicializado),
|
||||
($"{endereco_mov}.freq_base", Variaveis.OperacaoEmAndamento.DispMvd.Dados.tmrRegistradorMOV.IntervalHz),
|
||||
($"{endereco_mov}.endereco", mod.MovMotor._EnderecoCAN_Tx),
|
||||
($"{endereco_mov}.mod_id", mod.Modulo_ID),
|
||||
($"{endereco_mov}.cod_erro", mod.MovMotor.CodigoAlarme),
|
||||
($"{endereco_mov}.rpm", mod.MovMotor.RPM_Roda),
|
||||
($"{endereco_mov}.rpm_sp", mod.MovMotor.RPM_SP_Leitura),
|
||||
($"{endereco_mov}.tensao", mod.MovMotor.Tensao),
|
||||
($"{endereco_mov}.corrente_motor", mod.MovMotor.Corrente_Motor),
|
||||
($"{endereco_mov}.corrente_barramento", mod.MovMotor.Corrente_Barramento),
|
||||
($"{endereco_mov}.temperatura_driver", mod.MovMotor.TemperaturaDriver),
|
||||
($"{endereco_mov}.temperatura_motor", mod.MovMotor.Temperatura),
|
||||
($"{endereco_mov}.freado", mod.MovMotor.Leitura?.Freado ?? false),
|
||||
($"{endereco_mov}.freq.erro", mod.MovMotor.Leitura?.CodigoAlarme?.frequencia ?? 0),
|
||||
($"{endereco_mov}.freq.rpm", mod.MovMotor.Leitura?.ERPM?.frequencia ?? 0),
|
||||
($"{endereco_mov}.freq.tensao", mod.MovMotor.Leitura?.Tensao?.frequencia ?? 0),
|
||||
($"{endereco_mov}.freq.corrente_motor", mod.MovMotor.Leitura?.CorrenteMotor?.frequencia ?? 0),
|
||||
($"{endereco_mov}.freq.corrente_barramento", mod.MovMotor.Leitura?.CorrenteBarramento?.frequencia ?? 0),
|
||||
($"{endereco_mov}.freq.temperatura", mod.MovMotor.Leitura?.Temperatura?.frequencia ?? 0)
|
||||
);
|
||||
}
|
||||
|
||||
var sensoresAtualizados = new List<(string caminho, object valor)>();
|
||||
foreach (var sensor in Variaveis.OperacaoEmAndamento.DispSen.Dados.Sensores)
|
||||
{
|
||||
int tipo = (int)sensor.Componente;
|
||||
int id = sensor.ID_Num;
|
||||
string basePath = $"sensores.{tipo}.{id}";
|
||||
|
||||
var saude = RedisService.GetField<object>(RedisService.ModKey(Enums.T_Code.Sen), $"{basePath}.saude");
|
||||
|
||||
var dados = sensor.ValoresLeituras
|
||||
.Where(y => y.analise_health)
|
||||
.Select(y => new
|
||||
{
|
||||
label = y.funcao.ToString(),
|
||||
nominal = y.nominal,
|
||||
maximo = y.maximo,
|
||||
minimo = y.minimo,
|
||||
atual = y.atual.valor,
|
||||
freq = y.atual.frequencia
|
||||
})
|
||||
.ToList();
|
||||
|
||||
var sensorObj = new
|
||||
{
|
||||
conectado = sensor.Inicializado,
|
||||
id,
|
||||
label = sensor.ID,
|
||||
tipo,
|
||||
aferir = sensor.Aferir,
|
||||
mandatorio = sensor.Mandatorio,
|
||||
dados,
|
||||
timestamp = agora,
|
||||
saude = saude ?? new { }
|
||||
};
|
||||
|
||||
sensoresAtualizados.Add(($"{basePath}", sensorObj));
|
||||
}
|
||||
RedisService.AtualizarCampos(RedisService.ModKey(Enums.T_Code.Sen), sensoresAtualizados.ToArray());
|
||||
|
||||
var servosAtualizados = new List<(string caminho, object valor)>();
|
||||
foreach (var servo in Variaveis.OperacaoEmAndamento.DispSen.Dados.Servos)
|
||||
{
|
||||
int id = servo.ID_Num;
|
||||
string basePath = $"servos.{id}";
|
||||
|
||||
var saude = RedisService.GetField<object>(RedisService.ModKey(Enums.T_Code.Sen), $"{basePath}.saude");
|
||||
|
||||
var dados = servo.ValoresLeituras
|
||||
.Where(y => y.analise_health)
|
||||
.Select(y => new
|
||||
{
|
||||
label = y.funcao.ToString(),
|
||||
atual = y.atual.valor,
|
||||
freq = y.atual.frequencia
|
||||
})
|
||||
.ToList();
|
||||
|
||||
var servoObj = new
|
||||
{
|
||||
conectado = servo.Inicializado,
|
||||
id,
|
||||
label = servo.ID,
|
||||
controlar = servo.Controlar,
|
||||
mandatorio = servo.Mandatorio,
|
||||
angulo_sp = servo._AnguloControle,
|
||||
dados,
|
||||
timestamp = agora,
|
||||
saude = saude ?? new { }
|
||||
};
|
||||
|
||||
servosAtualizados.Add(($"{basePath}", servoObj));
|
||||
}
|
||||
RedisService.AtualizarCampos(RedisService.ModKey(Enums.T_Code.Sen), servosAtualizados.ToArray());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,21 +6,17 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static AgroBase.Models.Operadores.OperadoresModels;
|
||||
using static MqttService;
|
||||
|
||||
namespace AgroBase.Services.Operadores
|
||||
{
|
||||
public class ManagerWorkerService
|
||||
public class ManagerWorkerService : IWorkerModel
|
||||
{
|
||||
private string TopicoMQTT_Tx = "operador/manager/rx";
|
||||
private MqttTopicosModel topicoTx;
|
||||
private string TopicoMQTT_Rx = "operador/manager/tx";
|
||||
private MqttTopicosModel topicoRx;
|
||||
public ManagerWorkerModel DadosLeitura = new ManagerWorkerModel();
|
||||
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
|
||||
|
||||
private bool DebugMode = true;
|
||||
|
||||
private void MostrarLog(string message, int limite = 500)
|
||||
public void MostrarLog(string message, int limite = 500)
|
||||
{
|
||||
if (DebugMode)
|
||||
{
|
||||
|
|
@ -30,9 +26,6 @@ namespace AgroBase.Services.Operadores
|
|||
|
||||
public async Task<bool> IniciarProcessamento()
|
||||
{
|
||||
topicoRx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Rx, true, 2, MqttCallback);
|
||||
topicoTx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Tx);
|
||||
|
||||
RedisService.Subscribe(CmdKey.ManagerWorkerTx, RedisCallback);
|
||||
|
||||
DadosLeitura.IniciadoEm = DateTime.Now;
|
||||
|
|
@ -51,32 +44,7 @@ namespace AgroBase.Services.Operadores
|
|||
return false;
|
||||
}
|
||||
|
||||
private async Task<bool> MqttCallback(MqttTopicosMensagensModel Mensagem)
|
||||
{
|
||||
if (!DadosLeitura.Pronto && Mensagem.Momento > DadosLeitura.IniciadoEm && Mensagem.Mensagem == "OK")
|
||||
{
|
||||
DadosLeitura.ProntoEm = DateTime.Now;
|
||||
DadosLeitura.Pronto = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
DadosLeitura.Leitura = JsonConvert.DeserializeObject<WorkerMessageModel<ManagerWorkerMessageResponseModel>>(Mensagem.Mensagem);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MostrarLog($"Erro ao deserializar mensagem: {e.Message}");
|
||||
}
|
||||
if (DadosLeitura.Leitura != null)
|
||||
{
|
||||
AtualizarDadosLeitura(DadosLeitura.Leitura);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void RedisCallback(string mensagem)
|
||||
public void RedisCallback(string mensagem)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -84,13 +52,19 @@ namespace AgroBase.Services.Operadores
|
|||
|
||||
var cmd = (ManagerWorkerCommandType)comando.cmd;
|
||||
|
||||
MostrarLog($"📥 Comando recebido: cmd = {cmd.ToString()}");
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case ManagerWorkerCommandType.ScriptCarregado:
|
||||
DadosLeitura.Pronto = true;
|
||||
DadosLeitura.ProntoEm = DateTime.Now;
|
||||
MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
|
||||
break;
|
||||
case ManagerWorkerCommandType.EnviarDadosControle:
|
||||
if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS)
|
||||
{
|
||||
if (comando.@params == null)
|
||||
break;
|
||||
|
||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||
var novoComando = new ManagerWorkerMessageResponseComandoModel()
|
||||
{
|
||||
|
|
@ -104,69 +78,37 @@ namespace AgroBase.Services.Operadores
|
|||
_Controle.Angulo = novoComando.angulo;
|
||||
_Controle.TipoMovimento = novoComando.tipo_movimento;
|
||||
_Controle.PercentualVelocidadeSP = novoComando.percentual_velocidade;
|
||||
_Controle.SimulacaoMPC = novoComando.simulacao.Select(x => new MPCSimulacaoModel() { latitude = x[0], longitude = x[1] }).ToList();
|
||||
_Controle.SimulacaoMPC = novoComando.simulacao.Select(x => new MPCSimulacaoModel() { latitude = x[0], longitude = x[1], orientacao = x[2] }).ToList();
|
||||
Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
|
||||
}
|
||||
|
||||
if (Variaveis.OperacaoEmAndamento.StatusAtual == Enums.StatusOperacao.Concluido && Variaveis.OperacaoEmAndamento.Iniciado)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Variaveis.OperacaoEmAndamento.FinalizarOperacao();
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ManagerWorkerCommandType.FinalizarOperacao:
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Variaveis.OperacaoEmAndamento.FinalizarOperacao();
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
MostrarLog($"⚠️ Comando não reconhecido: {comando.cmd}");
|
||||
MostrarLog($"Comando não reconhecido: {comando.cmd}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MostrarLog($"❌ Erro ao deserializar resposta: {ex.Message}");
|
||||
MostrarLog($"Erro ao deserializar resposta: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void AtualizarDadosLeitura(WorkerMessageModel<ManagerWorkerMessageResponseModel> msg)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.TempoAguardando = DateTimeOffset.FromUnixTimeSeconds(msg.obj.tempo_aguardando).UtcDateTime.AddSeconds(msg.obj.tempo_aguardando % 1).ToLocalTime();
|
||||
|
||||
Variaveis.OperacaoEmAndamento.StatusAtual = msg.obj.status_operacao;
|
||||
Variaveis.OperacaoEmAndamento.OperacaoLiberada = msg.obj.operacao_liberada;
|
||||
|
||||
VariaveisOperacao.Operadores.ModulosSaude = new System.Collections.Generic.List<ManagerWorkerMessageResponseModulosPendentesModel>(msg.obj.status_modulos);
|
||||
|
||||
var mandatorios = Variaveis.OperacaoEmAndamento.ModulosMandatorios.Select(x => x.Dispositivo).ToList();
|
||||
var mods_com_falha = msg.obj.status_modulos.Where(x => mandatorios.Contains(x.modulo) && x.status == Enums.StatusModulo.Falha);
|
||||
var motivos_por_modulo = mods_com_falha.Select(x => $"{x.modulo}: {string.Join("; ", x.motivos)}");
|
||||
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = string.Join(Environment.NewLine + Environment.NewLine, motivos_por_modulo);
|
||||
|
||||
if (Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS)
|
||||
finally
|
||||
{
|
||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||
if (msg.obj.comando != null)
|
||||
{
|
||||
_Controle.Angulo = msg.obj.comando.angulo;
|
||||
_Controle.TipoMovimento = msg.obj.comando.tipo_movimento;
|
||||
_Controle.PercentualVelocidadeSP = msg.obj.comando.percentual_velocidade;
|
||||
_Controle.SimulacaoMPC = msg.obj.comando.simulacao.Select(x => new MPCSimulacaoModel() { latitude = x[0], longitude = x[1] }).ToList();
|
||||
Variaveis.OperacaoEmAndamento.AtualizaInformacoesControleOperacao();
|
||||
}
|
||||
|
||||
if (Variaveis.OperacaoEmAndamento.StatusAtual == Enums.StatusOperacao.Concluido && Variaveis.OperacaoEmAndamento.Iniciado)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Variaveis.OperacaoEmAndamento.FinalizarOperacao();
|
||||
});
|
||||
}
|
||||
DadosLeitura.UltimaMensagem = DateTime.Now;
|
||||
}
|
||||
|
||||
DadosLeitura.Leitura.MomentoLog = DateTime.Now;
|
||||
}
|
||||
|
||||
public void AtualizarSaude()
|
||||
{
|
||||
Saude = OperadoresModels.AtualizarSaude(CtxKey.DadosManagerWorker);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
using AgroBase.Models;
|
||||
using AgroBase.Models.Operadores;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static AgroBase.Models.Enums;
|
||||
using static AgroBase.Models.Operadores.OperadoresModels;
|
||||
|
|
@ -16,13 +12,13 @@ namespace AgroBase.Services.Operadores
|
|||
{
|
||||
private Process pythonProcess;
|
||||
|
||||
public ManagerWorkerService ManagerWorker;
|
||||
public VisualWorkerService VisualWorker;
|
||||
public HealthWorkerService HealthWorker;
|
||||
|
||||
public List<OAKCameraModel> CamerasConectadas = new List<OAKCameraModel>();
|
||||
public List<Bitmap> FramesSonar = new List<Bitmap>();
|
||||
public List<ManagerWorkerMessageResponseModulosPendentesModel> ModulosSaude = new List<ManagerWorkerMessageResponseModulosPendentesModel>();
|
||||
public List<IWorkerModel> Workers = new List<IWorkerModel>()
|
||||
{
|
||||
new ManagerWorkerService(),
|
||||
new VisualWorkerService(),
|
||||
new HealthWorkerService(),
|
||||
new CameraWorkerService(),
|
||||
};
|
||||
|
||||
private bool iniciarScript = false;
|
||||
private int TimeoutDesconexao = 3;
|
||||
|
|
@ -46,27 +42,16 @@ namespace AgroBase.Services.Operadores
|
|||
|
||||
private void IniciarOperadores()
|
||||
{
|
||||
foreach (var worker in Workers)
|
||||
{
|
||||
worker.IniciarProcessamento();
|
||||
}
|
||||
|
||||
if (iniciarScript)
|
||||
{
|
||||
Encerrar();
|
||||
pythonProcess = PythonService.RunScript(Path.Combine("workers", "main.py"), new string[] { });
|
||||
pythonProcess = PythonService.RunScript(Path.Combine("workers", "main_async.py"), new string[] { });
|
||||
}
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
ManagerWorker = new ManagerWorkerService();
|
||||
await ManagerWorker.IniciarProcessamento();
|
||||
});
|
||||
Task.Run(async () =>
|
||||
{
|
||||
VisualWorker = new VisualWorkerService();
|
||||
await VisualWorker.IniciarProcessamento();
|
||||
});
|
||||
Task.Run(async () =>
|
||||
{
|
||||
HealthWorker = new HealthWorkerService();
|
||||
await HealthWorker.IniciarProcessamento();
|
||||
});
|
||||
}
|
||||
|
||||
public bool Encerrar()
|
||||
|
|
@ -82,91 +67,51 @@ namespace AgroBase.Services.Operadores
|
|||
|
||||
private async Task tmrHearthbeat_Tick()
|
||||
{
|
||||
// Houve leitura nos ultimos 3 segundos
|
||||
TempoDesconectado = (DateTime.Now - (ManagerWorker.DadosLeitura.Leitura?.MomentoLog ?? DateTime.MinValue)).TotalSeconds;
|
||||
Conectado = TempoDesconectado < TimeoutDesconexao;
|
||||
Conectado = true;
|
||||
foreach (var worker in Workers)
|
||||
{
|
||||
worker.AtualizarSaude();
|
||||
Conectado &= worker.Saude.conectado;
|
||||
}
|
||||
|
||||
if (!Conectado)
|
||||
{
|
||||
if (Variaveis.OperacaoEmAndamento.Iniciado && Variaveis.OperacaoEmAndamento.Modo == Enums.ModoOperacao.MapaGPS)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.StatusAtual = Enums.StatusOperacao.Parado;
|
||||
Variaveis.OperacaoEmAndamento.OperacaoLiberada = false;
|
||||
Variaveis.OperacaoEmAndamento.Controle.Angulo = 0;
|
||||
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP = 0;
|
||||
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(true);
|
||||
RedisService.AtualizarCampos(
|
||||
CtxKey.DadosOperacao,
|
||||
("status", StatusOperacao.Parado),
|
||||
("liberado", false),
|
||||
("configurado", false)
|
||||
);
|
||||
|
||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||
|
||||
_Controle.Angulo = 0;
|
||||
_Controle.PercentualVelocidadeSP = 0;
|
||||
RedisService.AtualizarCampos(
|
||||
CtxKey.DadosControle,
|
||||
("angulo_sp", _Controle.Angulo),
|
||||
("velocidade_sp", _Controle.PercentualVelocidadeSP)
|
||||
);
|
||||
|
||||
Variaveis.OperacaoEmAndamento.AtualizarDadosControle(false);
|
||||
}
|
||||
|
||||
Variaveis.OperacaoEmAndamento.ErroOperacaoLiberada = "Sem comunicação com o núcleo de processamento central";
|
||||
RedisService.DefinirEquipamentoDesconectado();
|
||||
|
||||
// A cada 10 segundos desconectado, tenta reiniciar o nucleo de processamento
|
||||
if (TempoDesconectado % 10 == 0)
|
||||
if (TempoDesconectado > 0 && TempoDesconectado % 10 == 0)
|
||||
{
|
||||
IniciarOperadores();
|
||||
}
|
||||
}
|
||||
else if (!ManagerWorker.DadosLeitura.Leitura.obj.configurado)
|
||||
else if (!Variaveis.OperacaoEmAndamento.OperacaoConfigurada)
|
||||
{
|
||||
HealthWorker.EnviarDadosOperacao();
|
||||
HealthWorkerService.AtualizarDadosOperacao();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<OAKCameraModel>> AtualizarListaCameras()
|
||||
{
|
||||
HealthWorker.AdicionarComandoNaFila(TipoComando.GetListaCameras);
|
||||
await HealthWorker.AguardarNovosDados(TipoComando.GetListaCameras, 5000);
|
||||
|
||||
CamerasConectadas = new List<OAKCameraModel>()
|
||||
{
|
||||
new OAKCameraModel()
|
||||
{
|
||||
Dispositivo = T_Code.Vzo,
|
||||
Index = -1,
|
||||
Name = "Sem Video"
|
||||
}
|
||||
};
|
||||
|
||||
if (HealthWorker.DadosLeitura.Leitura.obj?.cameras?.itens?.Any() ?? false)
|
||||
{
|
||||
CamerasConectadas.AddRange(HealthWorker.DadosLeitura.Leitura.obj?.cameras?.itens?.Select(x => new OAKCameraModel()
|
||||
{
|
||||
Dispositivo = x.dispositivo,
|
||||
Version = x.versao,
|
||||
Name = x.modelo,
|
||||
Id = x.mx_id,
|
||||
}).ToList());
|
||||
}
|
||||
|
||||
return CamerasConectadas;
|
||||
}
|
||||
|
||||
public async Task<List<Bitmap>> SalvarFramesSonar()
|
||||
{
|
||||
var frames = new List<Bitmap>();
|
||||
|
||||
VisualWorker.AdicionarComandoNaFila(VisualWorkerCommandType.SalvarFrames);
|
||||
await VisualWorker.AguardarNovosDados(VisualWorkerCommandType.SalvarFrames, 5000);
|
||||
|
||||
var uris = VisualWorker.DadosLeitura.Leitura?.obj?.save_frames?.frames;
|
||||
|
||||
if (uris != null)
|
||||
{
|
||||
foreach (var uri in uris)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(uri) && File.Exists(uri))
|
||||
{
|
||||
using (var img = Image.FromFile(uri))
|
||||
{
|
||||
frames.Add((Bitmap)img.Clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FramesSonar = frames;
|
||||
|
||||
return FramesSonar;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,31 +2,21 @@
|
|||
using AgroBase.Models.Operadores;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static AgroBase.Models.Enums;
|
||||
using static AgroBase.Models.Operadores.OperadoresModels;
|
||||
using static MqttService;
|
||||
|
||||
namespace AgroBase.Services.Operadores
|
||||
{
|
||||
public class VisualWorkerService
|
||||
public class VisualWorkerService : IWorkerModel
|
||||
{
|
||||
public string TopicoMQTT_Tx = "operador/visual/rx";
|
||||
private MqttTopicosModel topicoTx;
|
||||
public string TopicoMQTT_Rx = "operador/visual/tx";
|
||||
private MqttTopicosModel topicoRx;
|
||||
public VisualWorkerModel DadosLeitura = new VisualWorkerModel();
|
||||
public AsyncTaskTimerModel tmrFila;
|
||||
public int TimeoutRespostaComando = 10;
|
||||
public ConcurrentDictionary<VisualWorkerCommandType, WorkerMessageModel<VisualWorkerMessageResponseModel>> FilaComandos = new ConcurrentDictionary<VisualWorkerCommandType, WorkerMessageModel<VisualWorkerMessageResponseModel>>();
|
||||
private Dictionary<VisualWorkerCommandType, Func<bool>> mapaRespostas;
|
||||
|
||||
public static VisualWorkerModel DadosLeitura = new VisualWorkerModel();
|
||||
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
|
||||
|
||||
private bool DebugMode = true;
|
||||
|
||||
private void MostrarLog(string message, int limite = 500)
|
||||
public void MostrarLog(string message, int limite = 500)
|
||||
{
|
||||
if (DebugMode)
|
||||
{
|
||||
|
|
@ -36,23 +26,11 @@ namespace AgroBase.Services.Operadores
|
|||
|
||||
public async Task<bool> IniciarProcessamento()
|
||||
{
|
||||
topicoRx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Rx, true, 2, MqttCallback);
|
||||
topicoTx = await Variaveis.MqttService.AdicionarNovoTopico(TopicoMQTT_Tx);
|
||||
|
||||
RedisService.Subscribe(CmdKey.VisualWorkerTx, RedisCallback);
|
||||
|
||||
mapaRespostas = new Dictionary<VisualWorkerCommandType, Func<bool>>
|
||||
{
|
||||
{ VisualWorkerCommandType.SalvarFrames, () => DadosLeitura.Leitura.obj?.save_frames?.newData ?? false },
|
||||
};
|
||||
|
||||
DadosLeitura.IniciadoEm = DateTime.Now;
|
||||
DadosLeitura.Iniciado = true;
|
||||
|
||||
tmrFila?.Dispose();
|
||||
tmrFila = new AsyncTaskTimerModel("tmrVisualWorker_Fila", tmrFila_Tick, 10);
|
||||
tmrFila.Start();
|
||||
|
||||
bool pronto() => DadosLeitura.Pronto;
|
||||
await FuncoesGlobais.AguardarCondicaoAsync(pronto, 5000);
|
||||
if (pronto())
|
||||
|
|
@ -66,80 +44,7 @@ namespace AgroBase.Services.Operadores
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool AdicionarComandoNaFila(VisualWorkerCommandType cmd, dynamic payload = null)
|
||||
{
|
||||
WorkerMessageModel<VisualWorkerMessageResponseModel> msg = new WorkerMessageModel<VisualWorkerMessageResponseModel>()
|
||||
{
|
||||
AdicionadoEm = DateTime.Now,
|
||||
payload = payload,
|
||||
obj = new VisualWorkerMessageResponseModel()
|
||||
{
|
||||
cmd = cmd,
|
||||
}
|
||||
};
|
||||
|
||||
bool sucesso = FilaComandos.TryAdd(cmd, msg);
|
||||
if (!sucesso)
|
||||
{
|
||||
MostrarLog($"Mensagem {cmd} nao adicionada na fila");
|
||||
}
|
||||
|
||||
return sucesso;
|
||||
}
|
||||
|
||||
private async Task tmrFila_Tick()
|
||||
{
|
||||
DateTime agora = DateTime.Now;
|
||||
// remove as mensagens antigas que nao responderam para permitir envair novamente
|
||||
foreach (var item in FilaComandos.Where(x => x.Value.Enviado && agora > x.Value.EnviadoEm.AddSeconds(TimeoutRespostaComando)))
|
||||
{
|
||||
FilaComandos.TryRemove(item.Key, out var _);
|
||||
}
|
||||
// pega a mensagem mais antiga
|
||||
var msg = FilaComandos.Where(x => !x.Value.Enviado).OrderBy(x => x.Value.AdicionadoEm).FirstOrDefault();
|
||||
if (msg.Value == null) return;
|
||||
|
||||
var mensagem = new
|
||||
{
|
||||
comando = (int)msg.Value.obj.cmd,
|
||||
dispositivo = (int)T_Code.Snr,
|
||||
payload = msg.Value.payload
|
||||
};
|
||||
|
||||
await Variaveis.MqttService.PublishAsync(topicoTx, JsonConvert.SerializeObject(mensagem), true);
|
||||
|
||||
msg.Value.Enviado = true;
|
||||
msg.Value.EnviadoEm = DateTime.Now;
|
||||
}
|
||||
|
||||
private async Task<bool> MqttCallback(MqttTopicosMensagensModel Mensagem)
|
||||
{
|
||||
if (!DadosLeitura.Pronto && Mensagem.Momento > DadosLeitura.IniciadoEm && Mensagem.Mensagem == "OK")
|
||||
{
|
||||
DadosLeitura.ProntoEm = DateTime.Now;
|
||||
DadosLeitura.Pronto = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var msgRx = JsonConvert.DeserializeObject<WorkerMessageModel<VisualWorkerMessageResponseModel>>(Mensagem.Mensagem);
|
||||
|
||||
if (msgRx == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FilaComandos.TryGetValue(msgRx.obj.cmd, out var msgTx);
|
||||
if (msgTx != null)
|
||||
{
|
||||
FilaComandos.TryRemove(msgTx.obj.cmd, out var msg);
|
||||
}
|
||||
|
||||
AtualizarDadosLeitura(msgRx);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void RedisCallback(string mensagem)
|
||||
public void RedisCallback(string mensagem)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -147,54 +52,123 @@ namespace AgroBase.Services.Operadores
|
|||
|
||||
var cmd = (VisualWorkerCommandType)comando.cmd;
|
||||
|
||||
MostrarLog($"📥 Comando recebido: cmd = {cmd.ToString()}");
|
||||
//MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case VisualWorkerCommandType.GetCameraFrame:
|
||||
var frameModel = JsonConvert.DeserializeObject<OAKCameraFrameModel>(comando.@params.ToString());
|
||||
case VisualWorkerCommandType.ScriptCarregado:
|
||||
DadosLeitura.Pronto = true;
|
||||
DadosLeitura.ProntoEm = DateTime.Now;
|
||||
MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
|
||||
break;
|
||||
|
||||
case VisualWorkerCommandType.GetCameraFrame:
|
||||
VisualWorkerFrameType tipo = (VisualWorkerFrameType)Convert.ToInt32(comando.@params["tipo"].ToString());
|
||||
DadosLeitura.CameraFrames[tipo] = new OAKCameraFrameModel()
|
||||
{
|
||||
frame = comando.@params["frame"].ToString(),
|
||||
timestamp = FuncoesGlobais.UnixToDateTime(comando.@params["timestamp"].ToString()),
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
MostrarLog($"⚠️ Comando não reconhecido: {comando.cmd}");
|
||||
MostrarLog($"Comando não reconhecido: {comando.cmd}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MostrarLog($"❌ Erro ao deserializar resposta: {ex.Message}");
|
||||
MostrarLog($"Erro ao deserializar resposta: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
DadosLeitura.UltimaMensagem = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
private void AtualizarDadosLeitura(WorkerMessageModel<VisualWorkerMessageResponseModel> msg)
|
||||
public void AtualizarSaude()
|
||||
{
|
||||
if (DadosLeitura.Leitura.obj == null)
|
||||
{
|
||||
DadosLeitura.Leitura.obj = new VisualWorkerMessageResponseModel();
|
||||
}
|
||||
switch (msg.obj.cmd)
|
||||
{
|
||||
case VisualWorkerCommandType.SalvarFrames:
|
||||
{
|
||||
DadosLeitura.Leitura.obj.save_frames = msg.obj.save_frames.Clone();
|
||||
break;
|
||||
}
|
||||
}
|
||||
DadosLeitura.Leitura.MomentoLog = DateTime.Now;
|
||||
Saude = OperadoresModels.AtualizarSaude(CtxKey.DadosVisualWorker);
|
||||
}
|
||||
|
||||
public async Task AguardarNovosDados(VisualWorkerCommandType cmd, int timeout = 1000)
|
||||
|
||||
public static void RecalibrarGridProfundidade(int qtd_frames = 50)
|
||||
{
|
||||
if (mapaRespostas.TryGetValue(cmd, out var condicao))
|
||||
{
|
||||
await FuncoesGlobais.AguardarCondicaoAsync(condicao, timeout, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
MostrarLog($"Comando {cmd} não suportado no AguardarResposta.");
|
||||
}
|
||||
var comando = new {
|
||||
cmd = VisualWorkerCommandType.CalibrarProfundidade,
|
||||
@params = qtd_frames
|
||||
};
|
||||
RedisService.Publish(CmdKey.VisualWorkerRx, JsonConvert.SerializeObject(comando));
|
||||
}
|
||||
|
||||
public static async Task<OAKCameraFrameModel> GetCameraFrame(VisualWorkerFrameType tipo = VisualWorkerFrameType.Rgb)
|
||||
{
|
||||
DateTime Inicio = DateTime.Now;
|
||||
|
||||
var comando = new
|
||||
{
|
||||
cmd = VisualWorkerCommandType.GetCameraFrame,
|
||||
@params = tipo,
|
||||
};
|
||||
RedisService.Publish(CmdKey.VisualWorkerRx, JsonConvert.SerializeObject(comando));
|
||||
|
||||
bool Frame() => DadosLeitura.CameraFrames.TryGetValue(tipo, out var frame) && (frame?.timestamp ?? DateTime.MinValue) > Inicio;
|
||||
|
||||
await FuncoesGlobais.AguardarCondicaoAsync(Frame, 1000, 100);
|
||||
|
||||
DadosLeitura.CameraFrames.TryGetValue(tipo, out OAKCameraFrameModel _frame);
|
||||
|
||||
return _frame;
|
||||
}
|
||||
|
||||
public static void SaveCameraFrames(List<VisualWorkerFrameType> frames, string nome, string caminho)
|
||||
{
|
||||
var comando = new
|
||||
{
|
||||
cmd = VisualWorkerCommandType.SaveCameraFrames,
|
||||
@params = new
|
||||
{
|
||||
nome = nome,
|
||||
caminho = caminho,
|
||||
tipos = frames.Select(x => (int)x).ToArray(),
|
||||
},
|
||||
};
|
||||
RedisService.Publish(CmdKey.VisualWorkerRx, JsonConvert.SerializeObject(comando));
|
||||
}
|
||||
|
||||
public static void AtualizarAnalise()
|
||||
{
|
||||
DadosLeitura.Imu = JsonConvert.DeserializeObject<VisualWorkerMessageIMUModel>(RedisService.Get(RedisService.ModKey(Enums.T_Code.Imu)));
|
||||
|
||||
var json = RedisService.Get(CtxKey.DadosVisualWorker);
|
||||
var dados = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
|
||||
|
||||
DateTime timestamp = FuncoesGlobais.UnixToDateTime(dados["ts_analise"].ToString());
|
||||
|
||||
//var matrizes = JsonConvert.DeserializeObject<Dictionary<string, object>>(dados["matrizes"].ToString());
|
||||
//var confianca = JsonConvert.DeserializeObject<List<List<double>>>(JsonConvert.SerializeObject(matrizes["confianca"]));
|
||||
//var custo = JsonConvert.DeserializeObject<List<List<double>>>(JsonConvert.SerializeObject(matrizes["custo"]));
|
||||
|
||||
var anomalias = JsonConvert.DeserializeObject<Dictionary<string, object>>(dados["anomalias"].ToString());
|
||||
var deteccoes = JsonConvert.DeserializeObject<List<VisualWorkerMessageAnaliseBBoxModel>>(JsonConvert.SerializeObject(anomalias["deteccoes"]));
|
||||
var sombras = JsonConvert.DeserializeObject<List<VisualWorkerMessageAnaliseBBoxModel>>(JsonConvert.SerializeObject(anomalias["sombras"]));
|
||||
|
||||
var corredor = JsonConvert.DeserializeObject<Dictionary<string, object>>(dados["perfil_corredor"].ToString());
|
||||
var segmentacao = JsonConvert.DeserializeObject<List<VisualWorkerMessageRadar2DPerfilModel>>(JsonConvert.SerializeObject(corredor["segmentacao"]));
|
||||
var profundidade = JsonConvert.DeserializeObject<List<VisualWorkerMessageRadar2DPerfilModel>>(JsonConvert.SerializeObject(corredor["profundidade"]));
|
||||
|
||||
var solo = JsonConvert.DeserializeObject<VisualWorkerMessageAnaliseSoloModel>(JsonConvert.SerializeObject(dados["solo"]));
|
||||
|
||||
DadosLeitura.Analises = new VisualWorkerMessageAnaliseModel()
|
||||
{
|
||||
timestamp = timestamp,
|
||||
solo = solo,
|
||||
anomalias = deteccoes,
|
||||
sombras = sombras,
|
||||
corredor_prof = profundidade,
|
||||
corredor_seg = segmentacao,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
using StackExchange.Redis;
|
||||
using AgroBase.Models.Operadores;
|
||||
using AgroBase.Services.Operadores;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static AgroBase.Models.Enums;
|
||||
|
||||
namespace AgroBase.Services
|
||||
{
|
||||
|
|
@ -15,16 +21,109 @@ namespace AgroBase.Services
|
|||
_db = _redis.GetDatabase();
|
||||
}
|
||||
|
||||
public static string ModKey(T_Code dispositivo)
|
||||
{
|
||||
return CtxKey.DadosModulo + dispositivo.ToString();
|
||||
}
|
||||
|
||||
public static string Get(string chave)
|
||||
{
|
||||
return _db.StringGet(chave);
|
||||
}
|
||||
|
||||
public static void Set(string chave, string valor)
|
||||
private static void Set(string chave, string valor)
|
||||
{
|
||||
_db.StringSet(chave, valor);
|
||||
}
|
||||
|
||||
public static void SetObject(string chave, object valor)
|
||||
{
|
||||
try
|
||||
{
|
||||
string json = JsonConvert.SerializeObject(valor, Formatting.None);
|
||||
Set(chave, json); // chama o método original que salva string
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Erro ao salvar objeto no Redis: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void AtualizarCampos(string chave, params (string campo, object valor)[] campos)
|
||||
{
|
||||
var dict = campos.ToDictionary(x => x.campo, x => x.valor);
|
||||
AtualizarCampos(chave, dict);
|
||||
}
|
||||
|
||||
private static void AtualizarCampos(string chave, Dictionary<string, object> novosCampos)
|
||||
{
|
||||
try
|
||||
{
|
||||
string jsonAtual = Get(chave);
|
||||
if (jsonAtual == "\"\"")
|
||||
jsonAtual = "";
|
||||
JObject root = string.IsNullOrWhiteSpace(jsonAtual) ? new JObject() : JObject.Parse(jsonAtual);
|
||||
|
||||
foreach (var campo in novosCampos)
|
||||
{
|
||||
// Exemplo de campo: "Operacao.status"
|
||||
string[] partes = campo.Key.Split('.');
|
||||
|
||||
JObject atual = root;
|
||||
for (int i = 0; i < partes.Length - 1; i++)
|
||||
{
|
||||
if (atual[partes[i]] == null || atual[partes[i]].Type != JTokenType.Object)
|
||||
{
|
||||
atual[partes[i]] = new JObject();
|
||||
}
|
||||
atual = (JObject)atual[partes[i]];
|
||||
}
|
||||
|
||||
atual[partes.Last()] = JToken.FromObject(campo.Value);
|
||||
}
|
||||
|
||||
Set(chave, root.ToString(Formatting.None));
|
||||
var d = Get(chave);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ Erro ao atualizar campos Redis: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static T GetField<T>(string chave, string caminhoCampo = "", T valorDefault = default(T))
|
||||
{
|
||||
try
|
||||
{
|
||||
string json = Get(chave);
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
return valorDefault;
|
||||
|
||||
JObject obj = JObject.Parse(json);
|
||||
string[] partes = caminhoCampo.Split('.');
|
||||
|
||||
JToken atual = obj;
|
||||
foreach (var parte in partes)
|
||||
{
|
||||
if (atual == null || atual.Type == JTokenType.Null)
|
||||
return valorDefault;
|
||||
|
||||
// Acesso seguro para JObject
|
||||
if (atual is JObject jo && jo.TryGetValue(parte, out var prox))
|
||||
atual = prox;
|
||||
else
|
||||
return valorDefault;
|
||||
}
|
||||
|
||||
return atual.ToObject<T>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ Erro ao obter campo '{caminhoCampo}': {ex.Message}");
|
||||
return valorDefault;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Publish(string canal, string mensagem)
|
||||
{
|
||||
var pub = _redis.GetSubscriber();
|
||||
|
|
@ -38,6 +137,39 @@ namespace AgroBase.Services
|
|||
callback(msg);
|
||||
});
|
||||
}
|
||||
|
||||
public static void LimparDadosIniciais()
|
||||
{
|
||||
Set(CtxKey.DadosCameras, JsonConvert.SerializeObject(new Dictionary<string, CameraWorkerItemModel>()));
|
||||
DefinirEquipamentoDesconectado();
|
||||
}
|
||||
|
||||
public static void DefinirEquipamentoDesconectado()
|
||||
{
|
||||
AtualizarCampos(
|
||||
CtxKey.DadosOperacao,
|
||||
("motivo_nao_liberado", "Sem comunicação com o núcleo de processamento central"),
|
||||
("liberado", false),
|
||||
("configurado", false)
|
||||
);
|
||||
foreach (var Mod in HealthWorkerService.ModulosSaude)
|
||||
{
|
||||
Mod.conectado = false;
|
||||
Mod.saude = 0;
|
||||
Mod.status = StatusModulo.Desconectado;
|
||||
Mod.saude_individual = new List<ManagerWorkerMessageResponseModulosPendentesSaudeModel>();
|
||||
Mod.motivos = new List<string>() { "Desconectado" };
|
||||
AtualizarCampos(
|
||||
ModKey(Mod.modulo),
|
||||
("saude", Mod)
|
||||
);
|
||||
}
|
||||
AtualizarCampos(
|
||||
CtxKey.DadosOperacao,
|
||||
("status_modulos", HealthWorkerService.ModulosSaude)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class ComandoRedis
|
||||
|
|
@ -53,7 +185,11 @@ namespace AgroBase.Services
|
|||
public const string DadosOperacao = "ctx:dados_operacao";
|
||||
public const string DadosContexto = "ctx:dados_contexto";
|
||||
public const string DadosControle = "ctx:dados_controle";
|
||||
public const string DadosEquipamento = "ctx:dados_equipamento";
|
||||
public const string DadosVisualWorker = "ctx:dados_visual_worker";
|
||||
public const string DadosManagerWorker = "ctx:dados_manager_worker";
|
||||
public const string DadosHealthWorker = "ctx:dados_health_worker";
|
||||
public const string DadosCameraWorker = "ctx:dados_camera_worker";
|
||||
}
|
||||
|
||||
public static class CmdKey
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using AgroBase.Forms;
|
||||
using AgroBase.Models;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
|
@ -236,7 +237,9 @@ namespace AgroBase.Services
|
|||
DispositivosMapeados.Remove(Dispositivo);
|
||||
}
|
||||
|
||||
foreach (var cam in VariaveisOperacao.Operadores.CamerasConectadas.Where(x => x.Index > -1))
|
||||
var cameras = CameraWorkerService.GetListaCameras().Where(x => x.Index > -1).ToList();
|
||||
|
||||
foreach (var cam in cameras)
|
||||
{
|
||||
if (!DispositivosMapeados.Any(x => x.Dispositivo == cam.Dispositivo))
|
||||
{
|
||||
|
|
@ -251,7 +254,7 @@ namespace AgroBase.Services
|
|||
|
||||
foreach (var cam in DispositivosMapeados.Where(x => x.Tipo == TipoConexao.USB))
|
||||
{
|
||||
if (!VariaveisOperacao.Operadores.CamerasConectadas.Any(x => x.Dispositivo == cam.Dispositivo))
|
||||
if (!cameras.Any(x => x.Dispositivo == cam.Dispositivo))
|
||||
{
|
||||
DispositivosMapeados.Remove(cam);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
0:00:00 Startup
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
|
||||
0:00:00 Microsoft.NewBrowser_Popup
|
||||
0:00:00 Microsoft.BrowserList.AddBrowser
|
||||
0:00:00 Browser1 Insert active Tab1 at 0
|
||||
0:00:00 Tab1 StartNav1 #auto_toplevel
|
||||
0:00:00 Tab1 StartNav2 #typed
|
||||
0:00:00 Tab1 FinishNav1
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:00 Tab1 FinishNav2
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:17 Widget Closed: StatusBubble
|
||||
0:37:43 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
|
||||
0:00:00 Startup
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
|
||||
0:00:00 Microsoft.NewBrowser_Popup
|
||||
0:00:00 Microsoft.BrowserList.AddBrowser
|
||||
0:00:00 Browser1 Insert active Tab1 at 0
|
||||
0:00:00 Tab1 StartNav1 #auto_toplevel
|
||||
0:00:00 Tab1 StartNav2 #typed
|
||||
0:00:00 Tab1 FinishNav1
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:00 Tab1 FinishNav2
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:26 Widget Closed: StatusBubble
|
||||
1:06:55 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
|
||||
0:00:00 Startup
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
|
||||
0:00:00 Microsoft.NewBrowser_Popup
|
||||
0:00:00 Microsoft.BrowserList.AddBrowser
|
||||
0:00:00 Browser1 Insert active Tab1 at 0
|
||||
0:00:00 Tab1 StartNav1 #auto_toplevel
|
||||
0:00:00 Tab1 StartNav2 #typed
|
||||
0:00:00 Tab1 FinishNav1
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:00 Tab1 FinishNav2
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:21 Widget Closed: StatusBubble
|
||||
0:05:18 Widget Closed: StatusBubble
|
||||
0:08:17 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
|
||||
0:00:00 Startup
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
|
||||
0:00:00 Microsoft.NewBrowser_Popup
|
||||
0:00:00 Microsoft.BrowserList.AddBrowser
|
||||
0:00:00 Browser1 Insert active Tab1 at 0
|
||||
0:00:00 Tab1 StartNav1 #auto_toplevel
|
||||
0:00:00 Tab1 StartNav2 #typed
|
||||
0:00:00 Tab1 FinishNav1
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:00 Tab1 FinishNav2
|
||||
0:00:00 Tab1 PageLoad
|
||||
3:37:51 Widget Closed: StatusBubble
|
||||
6:54:19 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
|
||||
0:00:00 Startup
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
|
||||
0:00:00 Microsoft.NewBrowser_Popup
|
||||
0:00:00 Microsoft.BrowserList.AddBrowser
|
||||
0:00:00 Browser1 Insert active Tab1 at 0
|
||||
0:00:00 Tab1 StartNav1 #auto_toplevel
|
||||
0:00:00 Tab1 StartNav2 #typed
|
||||
0:00:00 Tab1 FinishNav1
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:00 Tab1 FinishNav2
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:30:02 Widget Closed: StatusBubble
|
||||
1:24:04 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
|
||||
0:00:00 Startup
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
|
||||
0:00:00 Microsoft.NewBrowser_Popup
|
||||
0:00:00 Microsoft.BrowserList.AddBrowser
|
||||
0:00:00 Browser1 Insert active Tab1 at 0
|
||||
0:00:00 Tab1 StartNav1 #auto_toplevel
|
||||
0:00:00 Tab1 StartNav2 #typed
|
||||
0:00:00 Tab1 FinishNav1
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:00 Tab1 FinishNav2
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:41 Widget Closed: StatusBubble
|
||||
0:02:00 Widget Closed: StatusBubble
|
||||
0:06:37 Widget Closed: StatusBubble
|
||||
4:46:27 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
|
||||
0:00:00 Startup
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
|
||||
0:00:00 Microsoft.NewBrowser_Popup
|
||||
0:00:00 Microsoft.BrowserList.AddBrowser
|
||||
0:00:00 Browser1 Insert active Tab1 at 0
|
||||
0:00:00 Tab1 StartNav1 #auto_toplevel
|
||||
0:00:00 Tab1 StartNav2 #typed
|
||||
0:00:00 Tab1 FinishNav1
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:00 Tab1 FinishNav2
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:05:25 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
|
||||
0:00:00 Startup
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
|
||||
0:00:00 Microsoft.NewBrowser_Popup
|
||||
0:00:00 Microsoft.BrowserList.AddBrowser
|
||||
0:00:00 Browser1 Insert active Tab1 at 0
|
||||
0:00:00 Tab1 StartNav1 #auto_toplevel
|
||||
0:00:00 Tab1 StartNav2 #typed
|
||||
0:00:00 Tab1 FinishNav1
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:00 Tab1 FinishNav2
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:22 Widget Closed: StatusBubble
|
||||
0:03:52 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
|
||||
0:00:00 Startup
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
|
||||
0:00:00 Microsoft.NewBrowser_Popup
|
||||
0:00:00 Microsoft.BrowserList.AddBrowser
|
||||
0:00:00 Browser1 Insert active Tab1 at 0
|
||||
0:00:00 Tab1 StartNav1 #auto_toplevel
|
||||
0:00:00 Tab1 StartNav2 #typed
|
||||
0:00:00 Tab1 FinishNav1
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:00 Tab1 FinishNav2
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:10 Widget Closed: StatusBubble
|
||||
0:03:06 Widget Closed: StatusBubble
|
||||
0:16:21 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
|
||||
0:00:00 Startup
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpEphemeralProfiles
|
||||
0:00:00 Microsoft.DeleteProfileHelper.CleanUpDeletedProfiles
|
||||
0:00:00 Microsoft.NewBrowser_Popup
|
||||
0:00:00 Microsoft.BrowserList.AddBrowser
|
||||
0:00:00 Browser1 Insert active Tab1 at 0
|
||||
0:00:00 Tab1 StartNav1 #auto_toplevel
|
||||
0:00:00 Tab1 StartNav2 #typed
|
||||
0:00:00 Tab1 FinishNav1
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:00 Tab1 FinishNav2
|
||||
0:00:00 Tab1 PageLoad
|
||||
0:00:36 Widget Closed: StatusBubble
|
||||
0:04:19 Microsoft.UnloadController.IsUnclosableApp_IsNotWebApp
|
||||
|
|
@ -1,12 +1,5 @@
|
|||
{
|
||||
"epochs": [ {
|
||||
"calculation_time": "13393963069284106",
|
||||
"config_version": 0,
|
||||
"model_version": "0",
|
||||
"padded_top_topics_start_index": 0,
|
||||
"taxonomy_version": 0,
|
||||
"top_topics_and_observing_domains": [ ]
|
||||
}, {
|
||||
"calculation_time": "13394567869286013",
|
||||
"config_version": 0,
|
||||
"model_version": "0",
|
||||
|
|
@ -20,7 +13,21 @@
|
|||
"padded_top_topics_start_index": 0,
|
||||
"taxonomy_version": 0,
|
||||
"top_topics_and_observing_domains": [ ]
|
||||
}, {
|
||||
"calculation_time": "13395881044629269",
|
||||
"config_version": 0,
|
||||
"model_version": "0",
|
||||
"padded_top_topics_start_index": 0,
|
||||
"taxonomy_version": 0,
|
||||
"top_topics_and_observing_domains": [ ]
|
||||
}, {
|
||||
"calculation_time": "13396617367014463",
|
||||
"config_version": 0,
|
||||
"model_version": "0",
|
||||
"padded_top_topics_start_index": 0,
|
||||
"taxonomy_version": 0,
|
||||
"top_topics_and_observing_domains": [ ]
|
||||
} ],
|
||||
"hex_encoded_hmac_key": "40F346D3248C3AFDF2BEE1FE496DBD32F7CED6E5AE98B881ABC421AA7E7B5642",
|
||||
"next_scheduled_calculation_time": "13395777469290985"
|
||||
"next_scheduled_calculation_time": "13397222167014715"
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
|
@ -1,3 +1,3 @@
|
|||
2025/06/27-20:56:49.222 2104 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2025/06/27-20:56:49.231 2104 Recovering log #3
|
||||
2025/06/27-20:56:49.234 2104 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
|
||||
2025/07/11-13:13:55.663 6de4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2025/07/11-13:13:55.671 6de4 Recovering log #3
|
||||
2025/07/11-13:13:55.675 6de4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
2025/06/27-07:21:30.670 746c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2025/06/27-07:21:30.676 746c Recovering log #3
|
||||
2025/06/27-07:21:30.679 746c Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
|
||||
2025/07/11-12:34:04.813 7d74 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/MANIFEST-000001
|
||||
2025/07/11-12:34:04.820 7d74 Recovering log #3
|
||||
2025/07/11-12:34:04.824 7d74 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Local Storage\leveldb/000003.log
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"net":{"http_server_properties":{"servers":[{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13395628615843983","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":7016},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:6d4:dc00:ad47:84dd:a027:10ff","used_quic":true},"version":5},"network_qualities":{"CAASABiAgICA+P////8B":"4G","CAESABiAgICA+P////8B":"4G","CAISABiAgICA+P////8B":"4G","CAYSABiAgICA+P////8B":"Offline"}}}
|
||||
{"net":{"http_server_properties":{"servers":[{"alternative_service":[{"advertised_alpns":["h3"],"expiration":"13396810500919879","port":443,"protocol_str":"quic"}],"anonymization":["DAAAAAcAAABmaWxlOi8vAA==",false,0],"network_stats":{"srtt":6500},"server":"https://tile.openstreetmap.org","supports_spdy":true}],"supports_quic":{"address":"2804:d78:60b:6f00:1cb:7dd5:9647:ea0","used_quic":true},"version":5},"network_qualities":{"CAASABiAgICA+P////8B":"4G","CAESABiAgICA+P////8B":"4G","CAISABiAgICA+P////8B":"4G","CAYSABiAgICA+P////8B":"Offline"}}}
|
||||
|
|
@ -1 +1 @@
|
|||
{"sts":[{"expiry":1782604614.73,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1751068614.730003}],"version":2}
|
||||
{"sts":[{"expiry":1783786447.236962,"host":"bWGAftl61rqoc0YzqPncsLvQQh/iC2Bdp3ejUeGC83w=","mode":"force-https","sts_include_subdomains":true,"sts_observed":1752250447.236964}],"version":2}
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
2025/06/27-20:57:03.060 2104 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
|
||||
2025/06/27-20:57:03.061 2104 Recovering log #3
|
||||
2025/06/27-20:57:03.064 2104 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
|
||||
2025/07/11-13:18:15.006 6de4 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
|
||||
2025/07/11-13:18:15.007 6de4 Recovering log #3
|
||||
2025/07/11-13:18:15.010 6de4 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
2025/06/27-07:56:02.137 746c Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
|
||||
2025/06/27-07:56:02.138 746c Recovering log #3
|
||||
2025/06/27-07:56:02.141 746c Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
|
||||
2025/07/11-12:50:26.119 7d74 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/MANIFEST-000001
|
||||
2025/07/11-12:50:26.121 7d74 Recovering log #3
|
||||
2025/07/11-12:50:26.124 7d74 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Session Storage/000003.log
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
2025/06/27-20:56:49.144 3264 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2025/06/27-20:56:49.146 3264 Recovering log #3
|
||||
2025/06/27-20:56:49.146 3264 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000003.log
|
||||
2025/07/11-13:13:55.583 58ac Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2025/07/11-13:13:55.584 58ac Recovering log #3
|
||||
2025/07/11-13:13:55.585 58ac Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000003.log
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
2025/06/27-07:21:30.596 aec Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2025/06/27-07:21:30.597 aec Recovering log #3
|
||||
2025/06/27-07:21:30.598 aec Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000003.log
|
||||
2025/07/11-12:34:04.743 6ec0 Reusing MANIFEST C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/MANIFEST-000001
|
||||
2025/07/11-12:34:04.744 6ec0 Recovering log #3
|
||||
2025/07/11-12:34:04.745 6ec0 Reusing old log C:\ZendionInc\agrobot_base\AgroBase\AgroBase\bin\x64\Debug\AgroBase.exe.WebView2\EBWebView\Default\Site Characteristics Database/000003.log
|
||||
|
|
|
|||