ajuste no gerenciamento de cameras no lado do c#, versionamento de arquivos e atualizacao das metricas do atuador
This commit is contained in:
parent
4de10bdb67
commit
824f2bad58
|
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||
using System.Windows.Forms;
|
||||
using AgroBase.Models;
|
||||
using AgroBase.Services;
|
||||
using AgroBase.Services.Operadores;
|
||||
using Microsoft.Web.WebView2.WinForms;
|
||||
using Newtonsoft.Json;
|
||||
using static MqttService;
|
||||
|
|
@ -27,7 +28,7 @@ namespace AgroBase.Forms
|
|||
cameraSolo = new CameraSoloModel()
|
||||
{
|
||||
Nome = "T",
|
||||
Posicao = Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo.Count(),
|
||||
Posicao = CameraWorkerService.CamerasSolo.Count(),
|
||||
ArquivoLeitura = "ervas_T.json",
|
||||
browser = null,
|
||||
camera = new CameraService(),
|
||||
|
|
|
|||
|
|
@ -36,9 +36,10 @@ namespace AgroBase.Forms.IHM
|
|||
});
|
||||
FuncoesGlobais.DefinirEventosPicBtn(picSalvar, "Erro ao salvar parâmetros!", async () =>
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho = CameraCaminho.Clone();
|
||||
Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo = new List<OAKCameraModel>(CamerasSolo);
|
||||
|
||||
VariaveisEquipamento.Parametros.camera_caminhho_id = CameraCaminho.Id;
|
||||
VariaveisEquipamento.Parametros.camera_ervas_id = CamerasSolo?.Select(x => x.Id)?.ToList();
|
||||
VariaveisEquipamento.Parametros.SalvarParametros();
|
||||
|
||||
CustomDialog.ShowDialog(
|
||||
"Sucesso",
|
||||
"Configuração de câmeras salva com sucesso!",
|
||||
|
|
@ -258,7 +259,7 @@ namespace AgroBase.Forms.IHM
|
|||
private async Task AtualizarCameras()
|
||||
{
|
||||
flwCamerasSolo.Controls.Clear();
|
||||
var cameras = CameraWorkerService.GetListaCameras();
|
||||
var cameras = CameraWorkerService.ListaCameras;
|
||||
ListaCameras = cameras.Select(x => new OAKCameraModel()
|
||||
{
|
||||
Index = cameras.IndexOf(x),
|
||||
|
|
@ -268,8 +269,8 @@ namespace AgroBase.Forms.IHM
|
|||
Id = x.mx_id,
|
||||
}).ToList();
|
||||
|
||||
CameraCaminho = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho?.Clone();
|
||||
CamerasSolo = new List<OAKCameraModel>(Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo);
|
||||
CameraCaminho = CameraWorkerService.CameraCaminho?.Clone();
|
||||
CamerasSolo = new List<OAKCameraModel>(CameraWorkerService.CamerasSolo);
|
||||
|
||||
for (int i = 0; i < Variaveis.OperacaoEmAndamento.Parametros.QtdCamerasSolo; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1467,7 +1467,7 @@ namespace AgroBase.Forms.IHM
|
|||
}
|
||||
});
|
||||
|
||||
foreach (var camera in Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo)
|
||||
foreach (var camera in CameraWorkerService.CamerasSolo)
|
||||
{
|
||||
Testes.AddRange(new List<ColunasDiagnosticoModel>()
|
||||
{
|
||||
|
|
@ -1508,7 +1508,7 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
List<string> CamerasIDs = CameraService.ObterListaCameras().Values.ToList();
|
||||
|
||||
string IDcamRua = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho.Id;//.Replace("\\", "#").ToLower();
|
||||
string IDcamRua = CameraWorkerService.CameraCaminho.Id;//.Replace("\\", "#").ToLower();
|
||||
|
||||
bool RuaConfigurado = !string.IsNullOrEmpty(IDcamRua) && IDcamRua != "Sem video";
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, RuaConfigurado ? 1 : 0);
|
||||
|
|
@ -1519,9 +1519,9 @@ namespace AgroBase.Forms.IHM
|
|||
bool RuaVideo = await VerificaImagemCamera(CamerasIDs, IDcamRua, RuaConectado);
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, RuaVideo ? 1 : 0);
|
||||
|
||||
foreach (var camera in Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo)
|
||||
foreach (var camera in CameraWorkerService.CamerasSolo)
|
||||
{
|
||||
string IDcamSolo = (Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo[0].Id);//.Replace("\\", "#").ToLower();
|
||||
string IDcamSolo = (CameraWorkerService.CamerasSolo[0].Id);//.Replace("\\", "#").ToLower();
|
||||
|
||||
bool SoloConfigurado = !string.IsNullOrEmpty(IDcamSolo) && IDcamSolo != "Sem video";
|
||||
idx = PreencheDadosLinha(grid, Testes, idx, SoloConfigurado ? 1 : 0);
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ namespace AgroBase.Forms.IHM
|
|||
private async Task AtualizarControlesUI()
|
||||
{
|
||||
var Labels = this.Controls.OfType<Label>().Where(y => y.Name.Contains("lblD_")).ToList();
|
||||
var listaCameras = CameraWorkerService.GetListaCameras();
|
||||
var listaCameras = CameraWorkerService.ListaCameras;
|
||||
foreach (var lbl in Labels)
|
||||
{
|
||||
T_Code Dispositivo = (T_Code)Enum.Parse(typeof(T_Code), lbl.Name.Split('_')[1]);
|
||||
|
|
@ -172,7 +172,7 @@ namespace AgroBase.Forms.IHM
|
|||
bool modDesconectado = Modulo == null || Modulo.Status == StatusModulo.Desconectado;
|
||||
int idx = Convert.ToInt32(Mod_ID);
|
||||
Mod_ID = T_Code.Cam.ToString() + "_" + Mod_ID;
|
||||
var CameraSolo = Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo.Count() > idx ? Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo[idx] : null;
|
||||
var CameraSolo = CameraWorkerService.CamerasSolo.Count() > idx ? CameraWorkerService.CamerasSolo[idx] : null;
|
||||
lbl.ForeColor = modDesconectado || CameraSolo?.Id == null ?
|
||||
Color.Black
|
||||
: !listaCameras.Any(x => x.mx_id == CameraSolo.Id) ?
|
||||
|
|
@ -183,7 +183,7 @@ namespace AgroBase.Forms.IHM
|
|||
{
|
||||
var Modulo = SerialService.DispositivosMapeados.FirstOrDefault(x => x.Dispositivo == Dispositivo);
|
||||
bool modDesconectado = Modulo == null || Modulo.Status == StatusModulo.Desconectado;
|
||||
var CameraCaminho = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho;
|
||||
var CameraCaminho = CameraWorkerService.CameraCaminho;
|
||||
lbl.ForeColor = modDesconectado || CameraCaminho?.Id == null ?
|
||||
Color.Black
|
||||
: !listaCameras.Any(x => x.mx_id == CameraCaminho.Id)
|
||||
|
|
@ -195,7 +195,7 @@ namespace AgroBase.Forms.IHM
|
|||
var Modulo = SerialService.DispositivosMapeados.FirstOrDefault(x => x.Dispositivo == T_Code.Snr);
|
||||
bool modDesconectado = Modulo == null || Modulo.Status == StatusModulo.Desconectado;
|
||||
var saudeImu = HealthWorkerService.ModulosSaude.FirstOrDefault(x => x.modulo == Dispositivo);
|
||||
var CameraCaminho = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho;
|
||||
var CameraCaminho = CameraWorkerService.CameraCaminho;
|
||||
lbl.ForeColor =
|
||||
modDesconectado || saudeImu == null ? Color.Black
|
||||
: saudeImu.status == StatusModulo.Conectado ? Color.Blue
|
||||
|
|
|
|||
|
|
@ -68,11 +68,11 @@ namespace AgroBase.Forms.Operacoes
|
|||
nudPotenciaAgitador.Value = 100;
|
||||
|
||||
flwCamerasSolo.Controls.Clear();
|
||||
for (int i = 0; i < Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo.Count(); i++)
|
||||
for (int i = 0; i < CameraWorkerService.CamerasSolo.Count(); i++)
|
||||
{
|
||||
Panel pnlCam = new Panel()
|
||||
{
|
||||
Name = "pnlCamSolo_" + Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo[i].Name,
|
||||
Name = "pnlCamSolo_" + CameraWorkerService.CamerasSolo[i].Name,
|
||||
Width = 290,
|
||||
Height = 166,
|
||||
BackgroundImageLayout = ImageLayout.Zoom,
|
||||
|
|
@ -230,7 +230,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
try
|
||||
{
|
||||
var frame = await WeedWorkerService.GetCameraFrame(TipoFrameCamera.Debug);
|
||||
Panel pnl = FuncoesGlobais.FindControlRecursive<Panel>(flwCamerasSolo, "pnlCamSolo_" + Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo[0].Name);
|
||||
Panel pnl = FuncoesGlobais.FindControlRecursive<Panel>(flwCamerasSolo, "pnlCamSolo_" + CameraWorkerService.CamerasSolo[0].Name);
|
||||
AtualizarImagemPainel(pnl, frame?.image());
|
||||
}
|
||||
finally
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using AgroBase.Models;
|
||||
using AgroBase.Models.Modules;
|
||||
using AgroBase.Services;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
@ -69,7 +70,7 @@ namespace AgroBase.Forms.Sensoriamento
|
|||
Cameras = CameraService.ObterListaCameras();
|
||||
cmbCaminho.Items.Clear();
|
||||
cmbCaminho.Items.AddRange(Cameras.Values.ToArray());
|
||||
string IDrua = ((SensoriamentoModel)Disp.Dados).CameraCaminho.Id;
|
||||
string IDrua = CameraWorkerService.CameraCaminho.Id;
|
||||
if (Cameras.Any(x => x.Value == IDrua))
|
||||
{
|
||||
cmbCaminho.SelectedIndex = cmbCaminho.Items.IndexOf(IDrua);
|
||||
|
|
@ -79,7 +80,7 @@ namespace AgroBase.Forms.Sensoriamento
|
|||
cmbCaminho.Text = IDrua;
|
||||
}
|
||||
|
||||
var CamerasSolo = ((SensoriamentoModel)Disp.Dados).CamerasSolo;
|
||||
var CamerasSolo = CameraWorkerService.CamerasSolo;
|
||||
|
||||
cmbSoloEsq.Items.Clear();
|
||||
cmbSoloEsq.Items.AddRange(Cameras.Values.ToArray());
|
||||
|
|
@ -196,7 +197,7 @@ namespace AgroBase.Forms.Sensoriamento
|
|||
_Disp.Dados._EnderecoCAN_Rx = FuncoesGlobais.StringToHexByte(txtEnderecoCAN_Rx.Text);
|
||||
_Disp.Dados.RequisitarDados = chbRequisitarDados.Checked;
|
||||
_Disp.Dados.Sensores = Sensores.ToList();
|
||||
_Disp.Dados.CameraCaminho.Id = cmbCaminho.Text;
|
||||
CameraWorkerService.CameraCaminho.Id = cmbCaminho.Text;
|
||||
//_Disp.Dados.CamerasSolo.Clear();
|
||||
//_Disp.Dados.CameraID_Solo.AddRange(new string[] { cmbSoloEsq.Text, cmbSoloDir.Text });
|
||||
_Disp.SalvarParametros(_Disp.Dados);
|
||||
|
|
|
|||
|
|
@ -141,6 +141,8 @@ namespace AgroBase.Forms
|
|||
RedisService.Iniciar();
|
||||
RedisService.LimparDadosIniciais();
|
||||
|
||||
GeneralJoystick.IniciarRotinas();
|
||||
|
||||
await Variaveis.IniciarMqttAsync(_appCts.Token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
|
|
@ -148,10 +150,9 @@ namespace AgroBase.Forms
|
|||
* Hoje pode ficar comentado se UDP não for usado no rover,
|
||||
* mas o método fica aqui no lugar certo do lifecycle.
|
||||
*/
|
||||
//Variaveis.IniciarUDP();
|
||||
Variaveis.IniciarUDP();
|
||||
|
||||
APIService.IniciarRotinas();
|
||||
GeneralJoystick.IniciarRotinas();
|
||||
VersionamentoService.IniciarRotinas();
|
||||
|
||||
LivoxManagerProcess.Start();
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace AgroBase.Forms
|
|||
private void AtualizarListaCameras()
|
||||
{
|
||||
cmbCameras.Items.Clear();
|
||||
cmbCameras.Items.AddRange(CameraWorkerService.GetListaCameras().Select(x => x.modelo).ToArray());
|
||||
cmbCameras.Items.AddRange(CameraWorkerService.ListaCameras.Select(x => x.modelo).ToArray());
|
||||
cmbCameras.SelectedIndex = -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,10 +84,10 @@ namespace AgroBase.Forms
|
|||
var Camera = ListaCameras[cmbDispositivo.SelectedIndex];
|
||||
if (Camera.imu == null) return;
|
||||
|
||||
if (Camera.mx_id == Variaveis.OperacaoEmAndamento.DispSen?.Dados?.CameraCaminho?.Id)
|
||||
Camera.imu = Variaveis.OperacaoEmAndamento.DispSen.Dados?.CameraCaminho?.cam?.imu;
|
||||
else if (Variaveis.OperacaoEmAndamento.DispSen.Dados?.CamerasSolo?.Any(x => x?.Id == Camera.mx_id) ?? false)
|
||||
Camera.imu = Variaveis.OperacaoEmAndamento.DispSen.Dados?.CamerasSolo?.FirstOrDefault(x => x?.Id == Camera.mx_id)?.cam?.imu;
|
||||
if (Camera.mx_id == CameraWorkerService.CameraCaminho?.Id)
|
||||
Camera.imu = CameraWorkerService.CameraCaminho?.cam?.imu;
|
||||
else if (CameraWorkerService.CamerasSolo?.Any(x => x?.Id == Camera.mx_id) ?? false)
|
||||
Camera.imu = CameraWorkerService.CamerasSolo?.FirstOrDefault(x => x?.Id == Camera.mx_id)?.cam?.imu;
|
||||
|
||||
Imu = new OperacaoSensoriamentoLogImuModel()
|
||||
{
|
||||
|
|
@ -108,7 +108,7 @@ namespace AgroBase.Forms
|
|||
|
||||
private void AtualizarListaCameras()
|
||||
{
|
||||
ListaCameras = CameraWorkerService.GetListaCameras();
|
||||
ListaCameras = CameraWorkerService.ListaCameras;
|
||||
cmbDispositivo.Items.Clear();
|
||||
cmbDispositivo.Items.AddRange(ListaCameras.Select(x => x.modelo).ToArray());
|
||||
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ namespace AgroBase.Models.Modules
|
|||
private HashSet<int> _bombasAtivasIntervaloAnterior = new HashSet<int>();
|
||||
private Dictionary<int, double> _potenciaBombasIntervaloAnterior = new Dictionary<int, double>();
|
||||
private double _vazaoIntervaloAnteriorMLs;
|
||||
private const double IntervaloMaximoIntegracaoSeg = 0.5;
|
||||
private const double IntervaloMaximoIntegracaoSeg = 2.0;
|
||||
private const double IdadeMaximaTelemetriaSeg = 2.5;
|
||||
private double _tempoMovimentoAnteriorSeg;
|
||||
|
||||
|
|
@ -382,10 +382,20 @@ namespace AgroBase.Models.Modules
|
|||
Variaveis.OperacaoEmAndamento.Iniciado &&
|
||||
!operacaoConcluida;
|
||||
|
||||
bool atuadorComTelemetriaRecente =
|
||||
DadosLeitura != null &&
|
||||
DadosLeitura.UltimoComandoRespondido != DateTime.MinValue &&
|
||||
DadosLeitura
|
||||
.UltimoComandoRespondido
|
||||
.AddMilliseconds(TempoLimiteConexao) > agora;
|
||||
|
||||
bool atuadorTemEstrutura =
|
||||
(BicosPulverizadores?.Count ?? 0) > 0;
|
||||
|
||||
bool atuadorDisponivel =
|
||||
operacaoAtiva &&
|
||||
DadosLeitura != null &&
|
||||
DadosLeitura.Conectado;
|
||||
atuadorTemEstrutura &&
|
||||
atuadorComTelemetriaRecente;
|
||||
|
||||
bool pulverizadorAutomatico =
|
||||
Variaveis.OperacaoEmAndamento
|
||||
|
|
@ -470,8 +480,7 @@ namespace AgroBase.Models.Modules
|
|||
_ultimoTickMetricas) /
|
||||
(double)Stopwatch.Frequency;
|
||||
|
||||
if (dt > 0 &&
|
||||
dt <= IntervaloMaximoIntegracaoSeg)
|
||||
if (dt > 0 && dt <= IntervaloMaximoIntegracaoSeg)
|
||||
{
|
||||
double deltaMovimentoSeg = 0;
|
||||
|
||||
|
|
@ -506,6 +515,12 @@ namespace AgroBase.Models.Modules
|
|||
* Não inventa tempo nem volume.
|
||||
*/
|
||||
ZerarVazoesInstantaneas();
|
||||
|
||||
if (dt > IntervaloMaximoIntegracaoSeg)
|
||||
{
|
||||
Variaveis.MostrarLog("[ATU/METRICAS] Integração ignorada por dt alto: " + dt.ToString("0.000") + "s");
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Alerta, 50, "[ATU/METRICAS] Integração ignorada por dt alto: " + dt.ToString("0.000") + "s");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1320,7 +1335,7 @@ namespace AgroBase.Models.Modules
|
|||
Dados.BombasPressurizadoras.ForEach(x => x.Funcoes = x.Funcoes.Distinct().ToList());
|
||||
|
||||
ReiniciarLeituras(Dados);
|
||||
PrepararAtuadorParaOperacao(Dados);
|
||||
PrepararAtuadorParaOperacao(Dados, resetarComandos: true);
|
||||
}
|
||||
|
||||
public void ReiniciarLeituras(AtuadorModel Dados)
|
||||
|
|
@ -1337,13 +1352,18 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
x.ComandoAtuar = false;
|
||||
x.AnguloControle = 0;
|
||||
|
||||
x.Atuacoes = 0;
|
||||
|
||||
x.VazaoInstantaneaMLs = 0;
|
||||
x.VolumeVazadoML = 0;
|
||||
x.VazaoMediaMLs = 0;
|
||||
x.TempoAtuado = 0;
|
||||
x.TempoAtuadoEmMovimento = 0;
|
||||
x.TempoComFluxo = 0;
|
||||
|
||||
x.ReiniciarHistoricoAtuacao(true);
|
||||
|
||||
x.ValoresLeituras.ForEach(l =>
|
||||
{
|
||||
l.atual = new CanCommandFreqModel<dynamic>();
|
||||
|
|
@ -1386,10 +1406,19 @@ namespace AgroBase.Models.Modules
|
|||
}
|
||||
}
|
||||
|
||||
private void PrepararAtuadorParaOperacao(AtuadorModel Dados)
|
||||
public void PrepararAtuadorParaOperacao()
|
||||
{
|
||||
PrepararAtuadorParaOperacao(this, resetarComandos: false);
|
||||
}
|
||||
|
||||
private void PrepararAtuadorParaOperacao(AtuadorModel Dados, bool resetarComandos)
|
||||
{
|
||||
var dadosAtuador = Dados;
|
||||
var controle = Variaveis.OperacaoEmAndamento.Parametros?.Controle;
|
||||
var controle =
|
||||
Variaveis
|
||||
.OperacaoEmAndamento
|
||||
.Parametros?
|
||||
.Controle;
|
||||
|
||||
if (dadosAtuador == null || controle == null)
|
||||
return;
|
||||
|
|
@ -1398,7 +1427,13 @@ namespace AgroBase.Models.Modules
|
|||
|
||||
if (bomba != null)
|
||||
{
|
||||
bomba.ComandoAtuar = false;
|
||||
if (resetarComandos)
|
||||
bomba.ComandoAtuar = false;
|
||||
|
||||
/*
|
||||
* Estes setpoints precisam existir antes do primeiro comando
|
||||
* físico da bomba em operação automática.
|
||||
*/
|
||||
bomba.PotenciaSP = 100;
|
||||
bomba.PressaoSP = controle.AtuPressaoLinha;
|
||||
bomba.Controle.Modo = controle.AtuModoControle;
|
||||
|
|
@ -1408,12 +1443,113 @@ namespace AgroBase.Models.Modules
|
|||
|
||||
if (agitador != null)
|
||||
{
|
||||
agitador.ComandoAtuar = false;
|
||||
if (resetarComandos)
|
||||
agitador.ComandoAtuar = false;
|
||||
|
||||
/*
|
||||
* O agitador tem a própria fonte de verdade em
|
||||
* HerbicideCounterService.AtualizarAgitadorCalda().
|
||||
*/
|
||||
agitador.PotenciaSP = 0;
|
||||
agitador.PressaoSP = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void SincronizarBombaPressurizadoraAutomatica(bool forcar = false)
|
||||
{
|
||||
var operacao = Variaveis.OperacaoEmAndamento;
|
||||
|
||||
var controle =
|
||||
operacao?
|
||||
.Parametros?
|
||||
.Controle;
|
||||
|
||||
var bomba = BombaPressurizadora;
|
||||
|
||||
if (operacao == null || controle == null || bomba == null || !bomba.Inicializado)
|
||||
return;
|
||||
|
||||
bool pulverizadorAutomatico = controle.PulverizadorAutomatico;
|
||||
|
||||
if (!pulverizadorAutomatico)
|
||||
return;
|
||||
|
||||
bool operacaoConcluida = operacao.Sensoriamento?.StatusOperacao == StatusOperacao.Concluido;
|
||||
|
||||
bool atuacaoPermitida =
|
||||
operacao.Iniciado &&
|
||||
!operacao.Finalizando &&
|
||||
!operacao.Emergencia &&
|
||||
!operacaoConcluida &&
|
||||
!operacao.Pausa;
|
||||
|
||||
/*
|
||||
* Reaplica setpoints sempre antes de sincronizar.
|
||||
* Assim, se ReiniciarLeituras() zerou a bomba no início da operação,
|
||||
* ela não fica presa em potência/pressão zero.
|
||||
*/
|
||||
PrepararAtuadorParaOperacao();
|
||||
|
||||
bool statusDesejado =
|
||||
bomba.Comandar &&
|
||||
atuacaoPermitida &&
|
||||
ContadorCarga.PulverizadorLiberado;
|
||||
|
||||
/*
|
||||
* ComandoAtuar passa a representar também o comando lógico automático.
|
||||
* Isso deixa o log BombaLigada coerente com o que o software deseja.
|
||||
*/
|
||||
bomba.ComandoAtuar = statusDesejado;
|
||||
|
||||
double potenciaEfetiva =
|
||||
statusDesejado
|
||||
? bomba.PotenciaSP
|
||||
: 0;
|
||||
|
||||
double pressaoEfetiva =
|
||||
bomba.Sensor_ID_Num > -1
|
||||
? (
|
||||
statusDesejado
|
||||
? bomba.PressaoSP
|
||||
: 0
|
||||
)
|
||||
: bomba.PressaoSP;
|
||||
|
||||
Estado estadoDesejado =
|
||||
statusDesejado
|
||||
? Estado.Ligado
|
||||
: Estado.Desligado;
|
||||
|
||||
bool estadoDivergente =
|
||||
estadoDesejado != bomba._EstadoLeitura;
|
||||
|
||||
bool potenciaDivergente =
|
||||
Math.Abs(
|
||||
bomba._PotenciaSP -
|
||||
potenciaEfetiva
|
||||
) > 1.0;
|
||||
|
||||
bool pressaoDivergente =
|
||||
bomba.Sensor_ID_Num > -1 &&
|
||||
Math.Abs(
|
||||
bomba._PressaoSP -
|
||||
pressaoEfetiva
|
||||
) > 0.05;
|
||||
|
||||
if (forcar ||
|
||||
estadoDivergente ||
|
||||
potenciaDivergente ||
|
||||
pressaoDivergente)
|
||||
{
|
||||
EnviarComandoFisicoBomba(
|
||||
bomba,
|
||||
statusDesejado,
|
||||
potenciaEfetiva,
|
||||
pressaoEfetiva
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> VerificaDispositivoConectado()
|
||||
{
|
||||
if (!CanManager.CanService.IsConnected) return false;
|
||||
|
|
@ -1797,15 +1933,19 @@ namespace AgroBase.Models.Modules
|
|||
*
|
||||
* Ela não depende de um ComandoAtuar antigo.
|
||||
*/
|
||||
else if (
|
||||
ehBombaPrincipal &&
|
||||
pulverizadorAutomatico
|
||||
)
|
||||
else if (ehBombaPrincipal && pulverizadorAutomatico)
|
||||
{
|
||||
statusDesejado =
|
||||
bomba.Comandar &&
|
||||
atuacaoPermitida &&
|
||||
ContadorCarga.PulverizadorLiberado;
|
||||
|
||||
/*
|
||||
* Mantém o modelo coerente com o comando automático.
|
||||
* Sem isso, o log BombaLigada pode ficar false mesmo quando
|
||||
* o controle automático deseja a bomba ligada.
|
||||
*/
|
||||
bomba.ComandoAtuar = statusDesejado;
|
||||
}
|
||||
/*
|
||||
* Agitador e comandos manuais.
|
||||
|
|
|
|||
|
|
@ -56,8 +56,6 @@ namespace AgroBase.Models.Modules
|
|||
public List<SensorSinaleiroModel> Sinaleiros { get; set; }
|
||||
public List<SensorReleModel> Reles { get; set; }
|
||||
public List<SensorServoModel> Servos { get; set; }
|
||||
public OAKCameraModel CameraCaminho { get; set; } = new OAKCameraModel();
|
||||
public List<OAKCameraModel> CamerasSolo { get; set; } = new List<OAKCameraModel>();
|
||||
public UltrasonicA05Configuracoes ConfiguracaoSensorUltrassom { get; set; }
|
||||
private SenHandler _SenHandler = new SenHandler();
|
||||
public LoRaEspService loRaService { get; set; } = new LoRaEspService();
|
||||
|
|
@ -86,8 +84,6 @@ namespace AgroBase.Models.Modules
|
|||
_EnderecoCAN_Rx = 0x11,
|
||||
_TaxaAmostragem = 1000,
|
||||
RequisitarDados = true,
|
||||
CameraCaminho = new OAKCameraModel(),
|
||||
CamerasSolo = new List<OAKCameraModel>(Variaveis.OperacaoEmAndamento.Parametros.QtdCamerasSolo ?? VariaveisEquipamento.QuantidadeCamerasSolo),
|
||||
// 21 ~ 23
|
||||
Sinaleiros = new List<SensorSinaleiroModel>()
|
||||
{
|
||||
|
|
@ -1169,7 +1165,7 @@ namespace AgroBase.Models.Modules
|
|||
Descricao = "Luminosidade Ambiente",
|
||||
ID_Num = 31,
|
||||
Componente = S_Code.sLUZ,
|
||||
Aferir = true,
|
||||
Aferir = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
|
|
@ -1221,7 +1217,7 @@ namespace AgroBase.Models.Modules
|
|||
Descricao = "Indice de radiacao UV Ambiente",
|
||||
ID_Num = 32,
|
||||
Componente = S_Code.sIUV,
|
||||
Aferir = true,
|
||||
Aferir = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
|
|
@ -1271,7 +1267,7 @@ namespace AgroBase.Models.Modules
|
|||
Descricao = "Gas e Fumaca",
|
||||
ID_Num = 33,
|
||||
Componente = S_Code.sGAS,
|
||||
Aferir = true,
|
||||
Aferir = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
|
|
@ -1329,7 +1325,7 @@ namespace AgroBase.Models.Modules
|
|||
Descricao = "Monoxido de carbono",
|
||||
ID_Num = 34,
|
||||
Componente = S_Code.sGAS,
|
||||
Aferir = true,
|
||||
Aferir = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
|
|
@ -1387,7 +1383,7 @@ namespace AgroBase.Models.Modules
|
|||
Descricao = "Qualidade do ar",
|
||||
ID_Num = 35,
|
||||
Componente = S_Code.sQAR,
|
||||
Aferir = true,
|
||||
Aferir = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
|
|
@ -1475,7 +1471,7 @@ namespace AgroBase.Models.Modules
|
|||
Descricao = "Temperatura e Umidade Ambiente",
|
||||
ID_Num = 36,
|
||||
Componente = S_Code.sSHT,
|
||||
Aferir = true,
|
||||
Aferir = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
|
|
@ -1538,7 +1534,7 @@ namespace AgroBase.Models.Modules
|
|||
Descricao = "Chuva",
|
||||
ID_Num = 37,
|
||||
Componente = S_Code.sCHV,
|
||||
Aferir = true,
|
||||
Aferir = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
|
|
@ -1589,8 +1585,8 @@ namespace AgroBase.Models.Modules
|
|||
Descricao = "Angulo Direcional ET",
|
||||
ID_Num = 91,
|
||||
Componente = S_Code.sMAG,
|
||||
Aferir = true,
|
||||
Mandatorio = true,
|
||||
Aferir = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
FuncoesPinout.I2C,
|
||||
|
|
@ -1644,8 +1640,8 @@ namespace AgroBase.Models.Modules
|
|||
Descricao = "Angulo Direcional DT",
|
||||
ID_Num = 92,
|
||||
Componente = S_Code.sMAG,
|
||||
Aferir = true,
|
||||
Mandatorio = true,
|
||||
Aferir = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
FuncoesPinout.I2C,
|
||||
|
|
@ -1699,8 +1695,8 @@ namespace AgroBase.Models.Modules
|
|||
Descricao = "Angulo Direcional EF",
|
||||
ID_Num = 93,
|
||||
Componente = S_Code.sMAG,
|
||||
Aferir = true,
|
||||
Mandatorio = true,
|
||||
Aferir = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
FuncoesPinout.I2C,
|
||||
|
|
@ -1754,8 +1750,8 @@ namespace AgroBase.Models.Modules
|
|||
Descricao = "Angulo Direcional DF",
|
||||
ID_Num = 94,
|
||||
Componente = S_Code.sMAG,
|
||||
Aferir = true,
|
||||
Mandatorio = true,
|
||||
Aferir = false,
|
||||
Mandatorio = false,
|
||||
Funcoes = new List<FuncoesPinout>()
|
||||
{
|
||||
FuncoesPinout.I2C,
|
||||
|
|
@ -2409,24 +2405,6 @@ namespace AgroBase.Models.Modules
|
|||
Sinaleiros.First(x => x.ID == "LEDOP").Comportamento = VariaveisEquipamento.ComportamentoLedPorStatus(StatusLED.Piscando, status_operacao: _statusOperacao);
|
||||
}
|
||||
|
||||
public void AtualizarDadosCameras()
|
||||
{
|
||||
if (CameraCaminho?.Id != null)
|
||||
{
|
||||
var att = CameraWorkerService.AtualizarDadosCamera(CameraCaminho.Id);
|
||||
if (att != null) CameraCaminho = att;
|
||||
}
|
||||
for (int i = 0; i < CamerasSolo?.Count; i++)
|
||||
{
|
||||
if (CamerasSolo[i]?.Id != null)
|
||||
{
|
||||
var att = CameraWorkerService.AtualizarDadosCamera(CamerasSolo[i].Id);
|
||||
if (att != null) CamerasSolo[i] = att;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class SensorModel
|
||||
|
|
|
|||
|
|
@ -1188,6 +1188,10 @@ namespace AgroBase.Models
|
|||
Variaveis.OperacaoEmAndamento.Sensoriamento.UltimoRegistroLog = DateTime.Now;
|
||||
tmrLogs?.Start();
|
||||
|
||||
var dispSen = Variaveis.OperacaoEmAndamento.DispSen;
|
||||
var dispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
|
||||
var dispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Iniciado = true;
|
||||
Variaveis.OperacaoEmAndamento.Simulando = false;
|
||||
Variaveis.OperacaoEmAndamento.Treinando = false;
|
||||
|
|
@ -1204,9 +1208,10 @@ namespace AgroBase.Models
|
|||
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.AtualizarDados();
|
||||
|
||||
Variaveis.OperacaoEmAndamento.DispMvd?.Dados?.ReiniciarLeituras(DispMvd?.Dados);
|
||||
Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.ReiniciarLeituras(DispAtu?.Dados);
|
||||
Variaveis.OperacaoEmAndamento.DispSen?.Dados?.ReiniciarLeituras(DispSen?.Dados);
|
||||
dispMvd?.Dados?.ReiniciarLeituras(dispMvd?.Dados);
|
||||
dispAtu?.Dados?.ReiniciarLeituras(dispAtu?.Dados);
|
||||
dispSen?.Dados?.ReiniciarLeituras(dispSen?.Dados);
|
||||
dispAtu?.Dados?.PrepararAtuadorParaOperacao();
|
||||
|
||||
Variaveis.OperacaoEmAndamento.ModsCalibragem = new Dictionary<T_Code, Dictionary<string, bool>>()
|
||||
{
|
||||
|
|
@ -1222,19 +1227,36 @@ namespace AgroBase.Models
|
|||
Variaveis.OperacaoEmAndamento.Controle.Reiniciar();
|
||||
Variaveis.OperacaoEmAndamento.ControleAnterior.Reiniciar();
|
||||
|
||||
double distanciaPercorrida = DispMvd?.Dados?.DistanciaPercorridaTotal ?? 0;
|
||||
double tempoAtuado = DispAtu?.Dados?.TempoAtuado ?? 0;
|
||||
Variaveis.OperacaoEmAndamento.DispSen?.Dados?.ContadorCarga?.AtualizarConsumo(distanciaPercorrida);
|
||||
Variaveis.OperacaoEmAndamento.DispSen?.Dados?.ContadorCarga?.IniciarOperacao(distanciaPercorrida);
|
||||
Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.ContadorCarga?.IniciarOperacao(distanciaPercorrida, tempoAtuado);
|
||||
double distanciaPercorrida = dispMvd?.Dados?.DistanciaPercorridaTotal ?? 0;
|
||||
double tempoAtuado = dispAtu?.Dados?.TempoAtuado ?? 0;
|
||||
dispSen?.Dados?.ContadorCarga?.AtualizarConsumo(distanciaPercorrida);
|
||||
dispSen?.Dados?.ContadorCarga?.IniciarOperacao(distanciaPercorrida);
|
||||
dispAtu?.Dados?.ContadorCarga?.IniciarOperacao(distanciaPercorrida, tempoAtuado);
|
||||
|
||||
Variaveis.OperacaoEmAndamento.GPSTrajetoria = new List<GPSModel>();
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Trajetoria?.ProjetarTrajetoriaFixa();
|
||||
Variaveis.OperacaoEmAndamento.Trajetoria.VerificacaoInicialMeioRuaConcluida = false;
|
||||
RedisService.Publish(CmdKey.ManagerWorkerRx, JsonConvert.SerializeObject(new { cmd = ManagerWorkerCommandType.IniciarMPC }));
|
||||
Trajetoria?.ProjetarTrajetoriaFixa();
|
||||
Trajetoria.VerificacaoInicialMeioRuaConcluida = false;
|
||||
|
||||
/*
|
||||
* Mantém a operação bloqueada enquanto calibra/prepara.
|
||||
* O Manager/MPC só deve começar depois da calibração.
|
||||
*/
|
||||
Pausa = true;
|
||||
|
||||
await RealizarCalibragemInicialAsync(true);
|
||||
|
||||
Pausa = false;
|
||||
|
||||
RedisService.Publish(
|
||||
CmdKey.ManagerWorkerRx,
|
||||
JsonConvert.SerializeObject(
|
||||
new
|
||||
{
|
||||
cmd = ManagerWorkerCommandType.IniciarMPC
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public async Task FinalizarOperacao()
|
||||
|
|
@ -1291,8 +1313,14 @@ namespace AgroBase.Models
|
|||
{
|
||||
if (Variaveis.OperacaoEmAndamento.Calibrando) return;
|
||||
|
||||
bool modsCalibrados = Variaveis.OperacaoEmAndamento.ModsCalibragem.All(x => x.Value.Values.Count > 0 && x.Value.Values.All(y => y == true));
|
||||
if (!forcar && modsCalibrados) return;
|
||||
var modsCalibragem = Variaveis.OperacaoEmAndamento.ModsCalibragem;
|
||||
|
||||
bool modsCalibrados = modsCalibragem.All(x => x.Value.Values.Count > 0 && x.Value.Values.All(y => y == true));
|
||||
if (!forcar && modsCalibrados)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(T_Code.Mod, StatusModulo.Operante, 100, "Todos os módulos já foram calibrados anteriormente, não irá calibrar novamente.");
|
||||
return;
|
||||
}
|
||||
|
||||
var DispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
|
||||
var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
|
||||
|
|
@ -1301,9 +1329,9 @@ namespace AgroBase.Models
|
|||
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
|
||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||
|
||||
bool calibragemAtuNecessaria = pControle.PulverizadorAutomatico && (DispAtu?.Dados != null && sv.Contains(s.FirstOrDefault(x => x.modulo == T_Code.Atu)?.status ?? StatusModulo.Desconectado) && (forcar || Variaveis.OperacaoEmAndamento.ModsCalibragem[T_Code.Atu].Any(x => !x.Value) || !Variaveis.OperacaoEmAndamento.ModsCalibragem[T_Code.Atu].Any()));
|
||||
bool calibragemDirNecessaria = (DispMvd?.Dados != null && sv.Contains(s.FirstOrDefault(x => x.modulo == T_Code.Dir)?.status ?? StatusModulo.Desconectado) && (forcar || Variaveis.OperacaoEmAndamento.ModsCalibragem[T_Code.Dir].Any(x => !x.Value) || !Variaveis.OperacaoEmAndamento.ModsCalibragem[T_Code.Dir].Any()));
|
||||
bool calibragemMovNecessaria = (DispMvd?.Dados != null && sv.Contains(s.FirstOrDefault(x => x.modulo == T_Code.Mov)?.status ?? StatusModulo.Desconectado) && (forcar || Variaveis.OperacaoEmAndamento.ModsCalibragem[T_Code.Mov].Any(x => !x.Value) || !Variaveis.OperacaoEmAndamento.ModsCalibragem[T_Code.Mov].Any()));
|
||||
bool calibragemAtuNecessaria = pControle.PulverizadorAutomatico && (DispAtu?.Dados != null && sv.Contains(s.FirstOrDefault(x => x.modulo == T_Code.Atu)?.status ?? StatusModulo.Desconectado) && (forcar || modsCalibragem[T_Code.Atu].Any(x => !x.Value) || !modsCalibragem[T_Code.Atu].Any()));
|
||||
bool calibragemDirNecessaria = (DispMvd?.Dados != null && sv.Contains(s.FirstOrDefault(x => x.modulo == T_Code.Dir)?.status ?? StatusModulo.Desconectado) && (forcar || modsCalibragem[T_Code.Dir].Any(x => !x.Value) || !modsCalibragem[T_Code.Dir].Any()));
|
||||
bool calibragemMovNecessaria = (DispMvd?.Dados != null && sv.Contains(s.FirstOrDefault(x => x.modulo == T_Code.Mov)?.status ?? StatusModulo.Desconectado) && (forcar || modsCalibragem[T_Code.Mov].Any(x => !x.Value) || !modsCalibragem[T_Code.Mov].Any()));
|
||||
|
||||
if (!calibragemAtuNecessaria && !calibragemDirNecessaria && !calibragemMovNecessaria) return;
|
||||
|
||||
|
|
@ -1633,6 +1661,8 @@ namespace AgroBase.Models
|
|||
}
|
||||
case T_Code.Atu:
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.SincronizarBombaPressurizadoraAutomatica();
|
||||
|
||||
for (int i = 0; i < _Controle.Bicos.Count; i++)
|
||||
{
|
||||
Estado comandoEstado = _Controle.Bicos[i].ComandoAtuar ? Estado.Ligado : Estado.Desligado;
|
||||
|
|
@ -2971,6 +3001,27 @@ namespace AgroBase.Models
|
|||
SalvarLogLine(T_Code.Dir.ToString(), logDir);
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
var dispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
|
||||
var dispAtu = Variaveis.OperacaoEmAndamento.DispAtu;
|
||||
|
||||
dispAtu?.Dados?.AtualizarMetricasOperacao();
|
||||
|
||||
dispAtu?.Dados?.ContadorCarga?.AtualizarConsumo(
|
||||
dispMvd?.Dados?.DistanciaPercorridaTotal ?? 0,
|
||||
Variaveis.OperacaoEmAndamento.TempoDecorridoSegs,
|
||||
dispMvd?.Dados?.VelocidadeMedia ?? 0
|
||||
);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Variaveis.MostrarLog(
|
||||
"[SalvarLogs/ATU] Erro ao atualizar métricas antes do log: " +
|
||||
ex.Message
|
||||
);
|
||||
}
|
||||
|
||||
AtuSensoriamentoLogModel logAtu = new AtuSensoriamentoLogModel()
|
||||
{
|
||||
Momento = Agora,
|
||||
|
|
@ -3041,7 +3092,7 @@ namespace AgroBase.Models
|
|||
atu = T_Code.Atu.ToString(),
|
||||
sen = T_Code.Sen.ToString(),
|
||||
cam_caminho = T_Code.Snr.ToString(),
|
||||
cam_solo = Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo.Select((x, i) => x.Dispositivo.ToString() + i).ToList(),
|
||||
cam_solo = CameraWorkerService.CamerasSolo.Select((x, i) => x.Dispositivo.ToString() + i).ToList(),
|
||||
};
|
||||
File.WriteAllText(ArquivoOp, JsonConvert.SerializeObject(data));
|
||||
}
|
||||
|
|
@ -3078,9 +3129,9 @@ namespace AgroBase.Models
|
|||
|
||||
private void SalvarLogCameraSolo()
|
||||
{
|
||||
foreach (var Camera in Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo)
|
||||
foreach (var Camera in CameraWorkerService.CamerasSolo)
|
||||
{
|
||||
string camera_name = Camera.Dispositivo.ToString() + Variaveis.OperacaoEmAndamento.DispSen.Dados.CamerasSolo.IndexOf(Camera);
|
||||
string camera_name = Camera.Dispositivo.ToString() + CameraWorkerService.CamerasSolo.IndexOf(Camera);
|
||||
string Caminho = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/" + camera_name;
|
||||
if (!Directory.Exists(Caminho))
|
||||
{
|
||||
|
|
@ -3104,7 +3155,9 @@ namespace AgroBase.Models
|
|||
|
||||
private void SalvarLogCameraCaminho()
|
||||
{
|
||||
var Camera = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho;
|
||||
var Camera = CameraWorkerService.CameraCaminho;
|
||||
if (Camera == null)
|
||||
return;
|
||||
|
||||
string Caminho = Variaveis.CaminhoOperacoes + Variaveis.OperacaoEmAndamento.ID + "/" + Camera.Dispositivo;
|
||||
if (!Directory.Exists(Caminho))
|
||||
|
|
@ -3602,6 +3655,7 @@ namespace AgroBase.Models
|
|||
public List<ManagerWorkerMessageResponseModulosPendentesModel> ModulosSaude { get; set; }
|
||||
public List<DispositivoDetalhesModel> DispositivosMapeados { get; set; }
|
||||
public Dictionary<T_Code, Dictionary<string, bool>> ModsCalibragem { get; set; }
|
||||
public Dictionary<string, Dictionary<string, bool>> ModsCalibragemView { get; set; }
|
||||
public CanServiceTipo TipoCanAtivo { get; set; }
|
||||
public List<OperacaoSensoriamentoLogErrosModel> Logs { get; set; }
|
||||
public DateTime UltimoRegistroLog { get; set; } = DateTime.MinValue;
|
||||
|
|
@ -3631,6 +3685,7 @@ namespace AgroBase.Models
|
|||
Variaveis.OperacaoEmAndamento.DadosPerformance.AtualizarDadosPerformance();
|
||||
VisualWorkerService.AtualizarAnalise();
|
||||
WeedWorkerService.AtualizarAnalise();
|
||||
CameraWorkerService.AtualizarDadosCameras();
|
||||
GPSService.AtualizaDadosRedis();
|
||||
LivoxManagerProcess.AtualizarLeitura();
|
||||
MovimentacaoMovimentoCompensadoModel.AtualizarDados();
|
||||
|
|
@ -3649,7 +3704,6 @@ namespace AgroBase.Models
|
|||
double tmp_max = Math.Max(Variaveis.OperacaoEmAndamento.DadosPerformance?.GPU_temp ?? 0, Variaveis.OperacaoEmAndamento.DadosPerformance?.CPU_temp ?? 0);
|
||||
_DispMvd?.Dados?.AtualizarDadosFreio();
|
||||
_DispSen?.Dados?.AtualizarStatusSinaleiros(Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido, Variaveis.OperacaoEmAndamento.StatusAtual);
|
||||
_DispSen?.Dados?.AtualizarDadosCameras();
|
||||
_DispAtu?.Dados?.AtualizarMetricasOperacao();
|
||||
_Cooler?.Atualizar(tmp_max, DateTime.Now);
|
||||
_Bateria?.AtualizarConsumo(_DispMvd?.Dados?.DistanciaPercorridaTotal ?? 0);
|
||||
|
|
@ -3665,7 +3719,7 @@ namespace AgroBase.Models
|
|||
var bombaLinha = _DispAtu?.Dados?.BombaPressurizadora;
|
||||
var dadosAtuador = _DispAtu != null ? new OperacaoSensoriamentoLogAtuModel()
|
||||
{
|
||||
QtdCamerasSolo = _DispSen.Dados.CamerasSolo.Count,
|
||||
QtdCamerasSolo = CameraWorkerService.CamerasSolo.Count,
|
||||
CapacidadeReservatorio = VariaveisEquipamento.CapacidadeReservatorio,
|
||||
HerbicidaConsumido = _Reservatorio.VolumeConsumidoTotal_L,
|
||||
HerbicidaConsumidoOperacao = _Reservatorio.VolumeConsumidoOperacao_L,
|
||||
|
|
@ -3885,6 +3939,7 @@ namespace AgroBase.Models
|
|||
ModulosSaude = HealthWorkerService.ModulosSaude.ToList(),
|
||||
DispositivosMapeados = new List<DispositivoDetalhesModel>(SerialService.DispositivosMapeados),
|
||||
ModsCalibragem = new Dictionary<T_Code, Dictionary<string, bool>>(Variaveis.OperacaoEmAndamento.ModsCalibragem),
|
||||
ModsCalibragemView = Variaveis.OperacaoEmAndamento.ModsCalibragem?.ToDictionary(x => x.Key.ToString(), x => new Dictionary<string, bool>(x.Value ?? new Dictionary<string, bool>())) ?? new Dictionary<string, Dictionary<string, bool>>(),
|
||||
Logs = Logs != null ? Logs.Where(x => x?.Momento >= UltimoRegistroLog).ToList() : new List<OperacaoSensoriamentoLogErrosModel>(),
|
||||
CoolerControl = dadosCooler
|
||||
};
|
||||
|
|
@ -3936,6 +3991,7 @@ namespace AgroBase.Models
|
|||
ModulosSaude = new List<ManagerWorkerMessageResponseModulosPendentesModel>(ModulosSaude),
|
||||
DispositivosMapeados = new List<DispositivoDetalhesModel>(DispositivosMapeados),
|
||||
ModsCalibragem = new Dictionary<T_Code, Dictionary<string, bool>>(ModsCalibragem),
|
||||
ModsCalibragemView = new Dictionary<string, Dictionary<string, bool>>(ModsCalibragemView),
|
||||
Logs = new List<OperacaoSensoriamentoLogErrosModel>(Logs ?? new List<OperacaoSensoriamentoLogErrosModel>()),
|
||||
UltimoRegistroLog = UltimoRegistroLog,
|
||||
CoolerControl = CoolerControl?.Clone(),
|
||||
|
|
|
|||
|
|
@ -1149,12 +1149,8 @@ namespace AgroBase.Models.Operacoes
|
|||
|
||||
private void AtualizarCameras()
|
||||
{
|
||||
CameraWorkerService.GetListaCameras();
|
||||
|
||||
Cameras = CameraWorkerService.ListaCameras != null
|
||||
? new List<CameraWorkerItemModel>(
|
||||
CameraWorkerService.ListaCameras
|
||||
)
|
||||
? new List<CameraWorkerItemModel>(CameraWorkerService.ListaCameras)
|
||||
: new List<CameraWorkerItemModel>();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,22 +34,30 @@ namespace AgroBase.Models.Operadores
|
|||
|
||||
public class CameraWorkerItemModel
|
||||
{
|
||||
public T_Code dispositivo { get; set; }
|
||||
// Novos campos identificados no seu JSON
|
||||
public double timestamp { get; set; }
|
||||
public bool presente_scan { get; set; }
|
||||
public string status_scan { get; set; }
|
||||
public double manager_reset_ts { get; set; }
|
||||
public bool iniciando { get; set; } // Presente no JSON
|
||||
|
||||
// Campos que já existiam na sua classe
|
||||
public string mx_id { get; set; }
|
||||
public string versao { get; set; }
|
||||
public string modelo { get; set; }
|
||||
public bool iniciado { get; set; }
|
||||
public bool rodando { get; set; }
|
||||
|
||||
// Campos opcionais (coloque '?' para evitar erros se forem nulos ou ausentes)
|
||||
public T_Code dispositivo { get; set; }
|
||||
public string versao { get; set; }
|
||||
public string modelo { get; set; }
|
||||
public bool tem_depth { get; set; }
|
||||
public bool tem_imu { get; set; }
|
||||
|
||||
public bool streaming { get; set; }
|
||||
public double fps { get; set; }
|
||||
public int stream_w { get; set; }
|
||||
public int stream_h { get; set; }
|
||||
public double stream_kbps { get; set; }
|
||||
public double stream_last_frame { get; set; }
|
||||
|
||||
public SaudeWorkerModel saude { get; set; }
|
||||
public CameraWorkerItemPerformanceModel performance { get; set; }
|
||||
public OAKImuDataModel imu { get; set; }
|
||||
|
|
@ -60,8 +68,8 @@ namespace AgroBase.Models.Operadores
|
|||
{
|
||||
Id = mx_id,
|
||||
Dispositivo = dispositivo,
|
||||
Version = versao,
|
||||
Name = modelo,
|
||||
Version = versao ?? "Desconhecida",
|
||||
Name = modelo ?? "Desconhecido",
|
||||
cam = this
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,31 +136,59 @@ namespace AgroBase.Services
|
|||
private double _distanciaTotalAnterior_m;
|
||||
private double _tempoTotalAnterior_s;
|
||||
|
||||
private bool _inicioOperacaoPendente;
|
||||
private double _distanciaInicioOperacaoPendente_m;
|
||||
private double _tempoInicioOperacaoPendente_s;
|
||||
|
||||
private bool _inicializado;
|
||||
|
||||
public void IniciarOperacao(double distanciaTotalMetrosAtual, double tempoTotalSegundosAtual)
|
||||
{
|
||||
/*
|
||||
* Antes, se o contador ainda não tivesse recebido uma leitura
|
||||
* válida do reservatório, o início era ignorado.
|
||||
*
|
||||
* Isso fazia VolumeConsumidoOperacao_L ficar zero durante toda
|
||||
* a operação quando a primeira leitura válida chegava depois
|
||||
* do comando de iniciar.
|
||||
*/
|
||||
if (!_inicializado)
|
||||
{
|
||||
OperacaoAtiva = true;
|
||||
OperacaoFinalizada = false;
|
||||
|
||||
_inicioOperacaoPendente = true;
|
||||
_distanciaInicioOperacaoPendente_m =
|
||||
distanciaTotalMetrosAtual;
|
||||
_tempoInicioOperacaoPendente_s =
|
||||
tempoTotalSegundosAtual;
|
||||
|
||||
ResetarJanelas();
|
||||
return;
|
||||
}
|
||||
|
||||
_volumeInicialOperacao_L = VolumeAtual_L;
|
||||
|
||||
_distanciaTotalAnterior_m = distanciaTotalMetrosAtual;
|
||||
_tempoTotalAnterior_s = tempoTotalSegundosAtual;
|
||||
_distanciaTotalAnterior_m =
|
||||
distanciaTotalMetrosAtual;
|
||||
_tempoTotalAnterior_s =
|
||||
tempoTotalSegundosAtual;
|
||||
|
||||
OperacaoAtiva = true;
|
||||
OperacaoFinalizada = false;
|
||||
_inicioOperacaoPendente = false;
|
||||
|
||||
ResetarJanelas();
|
||||
}
|
||||
|
||||
public void FinalizarOperacao()
|
||||
{
|
||||
if (!OperacaoAtiva)
|
||||
if (!OperacaoAtiva && !_inicioOperacaoPendente)
|
||||
return;
|
||||
|
||||
OperacaoAtiva = false;
|
||||
OperacaoFinalizada = true;
|
||||
_inicioOperacaoPendente = false;
|
||||
}
|
||||
|
||||
public void AtualizarConsumo(double distanciaTotalMetrosAtual, double tempoTotalSegundosAtual, double velocidadeAtual_m_s)
|
||||
|
|
@ -202,6 +230,26 @@ namespace AgroBase.Services
|
|||
if (!_inicializado)
|
||||
{
|
||||
Inicializar(distanciaTotalMetrosAtual, tempoTotalSegundosAtual);
|
||||
|
||||
if (OperacaoAtiva || _inicioOperacaoPendente)
|
||||
{
|
||||
/*
|
||||
* Primeira leitura válida depois do comando de iniciar.
|
||||
* A operação passa a usar o volume atual como referência
|
||||
* inicial, sem perder o estado de OperacaoAtiva.
|
||||
*/
|
||||
_volumeInicialOperacao_L = VolumeAtual_L;
|
||||
|
||||
_distanciaTotalAnterior_m = distanciaTotalMetrosAtual;
|
||||
_tempoTotalAnterior_s = tempoTotalSegundosAtual;
|
||||
|
||||
OperacaoAtiva = true;
|
||||
OperacaoFinalizada = false;
|
||||
_inicioOperacaoPendente = false;
|
||||
|
||||
ResetarJanelas();
|
||||
}
|
||||
|
||||
AtualizarAutonomia(velocidadeAtual_m_s);
|
||||
return;
|
||||
}
|
||||
|
|
@ -341,10 +389,21 @@ namespace AgroBase.Services
|
|||
|
||||
private void AtualizarHerbicidaPorAtuacao()
|
||||
{
|
||||
int qtdAtuacoes = Variaveis.OperacaoEmAndamento.Controle?.Bicos?.Sum(x => x.Atuacoes) ?? 0;
|
||||
int qtdAtuacoes =
|
||||
Variaveis
|
||||
.OperacaoEmAndamento
|
||||
.DispAtu?
|
||||
.Dados?
|
||||
.BicosPulverizadores?
|
||||
.Sum(x => x?.Atuacoes ?? 0)
|
||||
?? 0;
|
||||
|
||||
if (qtdAtuacoes > 0)
|
||||
HerbicidaPorAtuacao_L = VolumeConsumidoOperacao_L / qtdAtuacoes;
|
||||
HerbicidaPorAtuacao_L =
|
||||
VolumeConsumidoOperacao_L /
|
||||
qtdAtuacoes;
|
||||
else
|
||||
HerbicidaPorAtuacao_L = 0;
|
||||
}
|
||||
|
||||
private void AtualizarAutonomia(double velocidadeAtual_m_s)
|
||||
|
|
@ -399,9 +458,9 @@ namespace AgroBase.Services
|
|||
velocidadeReferencia_m_s =
|
||||
FuncoesMatematicas.CalculaVelocidadeMsPercentual(
|
||||
Variaveis.OperacaoEmAndamento
|
||||
.Parametros
|
||||
.Controle
|
||||
.MovVelocidadeCErvasPercent
|
||||
.Parametros?
|
||||
.Controle?
|
||||
.MovVelocidadeCErvasPercent ?? 30
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -476,6 +535,10 @@ namespace AgroBase.Services
|
|||
_distanciaTotalAnterior_m = 0;
|
||||
_tempoTotalAnterior_s = 0;
|
||||
|
||||
_inicioOperacaoPendente = false;
|
||||
_distanciaInicioOperacaoPendente_m = 0;
|
||||
_tempoInicioOperacaoPendente_s = 0;
|
||||
|
||||
ResetarJanelas();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
using AgroBase.Models.Operadores;
|
||||
using AgroBase.Models;
|
||||
using AgroBase.Models.Operadores;
|
||||
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;
|
||||
using System.Threading.Tasks;
|
||||
using static AgroBase.Models.Enums;
|
||||
using static AgroBase.Models.Operadores.OperadoresModels;
|
||||
|
||||
namespace AgroBase.Services.Operadores
|
||||
{
|
||||
|
|
@ -14,17 +14,87 @@ namespace AgroBase.Services.Operadores
|
|||
{
|
||||
public CameraWorkerModel DadosLeitura = new CameraWorkerModel();
|
||||
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
|
||||
private static List<CameraWorkerItemModel> CamerasConectadas = new List<CameraWorkerItemModel>();
|
||||
public static List<CameraWorkerItemModel> ListaCameras => CamerasConectadas.Skip(1).ToList();
|
||||
|
||||
private static readonly object _cameraLock = new object();
|
||||
private static readonly object _refreshLock = new object();
|
||||
|
||||
private static readonly JsonSerializerSettings _jsonSettings =
|
||||
new JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
MissingMemberHandling = MissingMemberHandling.Ignore,
|
||||
Error = (sender, args) =>
|
||||
{
|
||||
args.ErrorContext.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
private static List<CameraWorkerItemModel> CamerasConectadas =
|
||||
CriarListaVaziaComPlaceholder();
|
||||
|
||||
private static DateTime _ultimoRefreshUtc = DateTime.MinValue;
|
||||
private static bool _refreshEmAndamento;
|
||||
|
||||
/*
|
||||
* Pode chamar AtualizarDadosCameras() em tmrLeitura_Tick sem medo.
|
||||
* Se o tick estiver em 100 ms, este throttle evita martelar Redis.
|
||||
*/
|
||||
private static readonly TimeSpan IntervaloMinimoRefresh =
|
||||
TimeSpan.FromMilliseconds(500);
|
||||
|
||||
private bool DebugMode = true;
|
||||
|
||||
public static List<CameraWorkerItemModel> ListaCameras
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_cameraLock)
|
||||
{
|
||||
return CamerasConectadas.Skip(1).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static OAKCameraModel CameraCaminho
|
||||
{
|
||||
get
|
||||
{
|
||||
CameraWorkerItemModel item =
|
||||
ListaCameras.FirstOrDefault(
|
||||
x => x.dispositivo == T_Code.Snr
|
||||
);
|
||||
|
||||
return item?.ToOAK();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<OAKCameraModel> CamerasSolo
|
||||
{
|
||||
get
|
||||
{
|
||||
return ListaCameras
|
||||
.Where(x => x.dispositivo == T_Code.Cam)
|
||||
.Select(x => x.ToOAK())
|
||||
.Where(x => x != null)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public void MostrarLog(string message, int limite = 500)
|
||||
{
|
||||
if (DebugMode)
|
||||
{
|
||||
Console.WriteLine($"[CameraWorker] {message.Substring(0, Math.Min(limite, message.Length))}{(message.Length > limite ? "..." : "")}");
|
||||
}
|
||||
if (!DebugMode)
|
||||
return;
|
||||
|
||||
message = message ?? string.Empty;
|
||||
|
||||
Console.WriteLine(
|
||||
"[CameraWorker] " +
|
||||
message.Substring(
|
||||
0,
|
||||
Math.Min(limite, message.Length)
|
||||
) +
|
||||
(message.Length > limite ? "..." : "")
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<bool> IniciarProcessamento()
|
||||
|
|
@ -35,7 +105,9 @@ namespace AgroBase.Services.Operadores
|
|||
DadosLeitura.Iniciado = true;
|
||||
|
||||
bool pronto() => DadosLeitura.Pronto;
|
||||
|
||||
await FuncoesGlobais.AguardarCondicaoAsync(pronto, 5000);
|
||||
|
||||
if (pronto())
|
||||
{
|
||||
MostrarLog("Processamento iniciado com sucesso");
|
||||
|
|
@ -51,28 +123,39 @@ namespace AgroBase.Services.Operadores
|
|||
{
|
||||
try
|
||||
{
|
||||
var comando = JsonConvert.DeserializeObject<ComandoRedis>(mensagem);
|
||||
if (string.IsNullOrWhiteSpace(mensagem))
|
||||
return;
|
||||
|
||||
var comando =
|
||||
JsonConvert.DeserializeObject<ComandoRedis>(
|
||||
mensagem,
|
||||
_jsonSettings
|
||||
);
|
||||
|
||||
if (comando == null)
|
||||
return;
|
||||
|
||||
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()}");
|
||||
MostrarLog("Comando recebido: cmd = " + cmd);
|
||||
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
|
||||
{
|
||||
|
|
@ -82,51 +165,295 @@ namespace AgroBase.Services.Operadores
|
|||
|
||||
public void AtualizarSaude()
|
||||
{
|
||||
Saude = OperadoresModels.AtualizarSaude(CtxKey.DadosCameraWorker);
|
||||
Saude =
|
||||
OperadoresModels.AtualizarSaude(
|
||||
CtxKey.DadosCameraWorker
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Lê câmeras diretamente do Redis e retorna uma lista nova.
|
||||
/// Não atualiza o snapshot global. Para runtime, use AtualizarDadosCameras().
|
||||
/// </summary>
|
||||
public static List<CameraWorkerItemModel> GetListaCameras()
|
||||
{
|
||||
CamerasConectadas = new List<CameraWorkerItemModel>()
|
||||
return LerCamerasDoRedis();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Atualiza o snapshot global das câmeras.
|
||||
/// Pode ser chamado no tmrLeitura_Tick. Internamente possui throttle.
|
||||
/// </summary>
|
||||
public static void AtualizarDadosCameras()
|
||||
{
|
||||
AtualizarDadosCameras(false);
|
||||
}
|
||||
|
||||
public static void AtualizarDadosCameras(bool forcar)
|
||||
{
|
||||
DateTime agoraUtc = DateTime.UtcNow;
|
||||
|
||||
if (!forcar &&
|
||||
agoraUtc - _ultimoRefreshUtc < IntervaloMinimoRefresh)
|
||||
{
|
||||
new CameraWorkerItemModel()
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_refreshLock)
|
||||
{
|
||||
if (_refreshEmAndamento)
|
||||
return;
|
||||
|
||||
if (!forcar &&
|
||||
DateTime.UtcNow - _ultimoRefreshUtc <
|
||||
IntervaloMinimoRefresh)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_refreshEmAndamento = true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
List<CameraWorkerItemModel> novaLista =
|
||||
LerCamerasDoRedis();
|
||||
|
||||
lock (_cameraLock)
|
||||
{
|
||||
CamerasConectadas = novaLista;
|
||||
_ultimoRefreshUtc = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(
|
||||
"[CameraWorkerService] Erro ao atualizar câmeras: " +
|
||||
ex.Message
|
||||
);
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock (_refreshLock)
|
||||
{
|
||||
_refreshEmAndamento = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static OAKCameraModel AtualizarDadosCamera(string mx_id)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(mx_id))
|
||||
return null;
|
||||
|
||||
CameraWorkerItemModel camera = LerCameraDoRedis(mx_id);
|
||||
|
||||
if (camera == null ||
|
||||
string.IsNullOrWhiteSpace(camera.mx_id))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
lock (_cameraLock)
|
||||
{
|
||||
int index =
|
||||
CamerasConectadas.FindIndex(
|
||||
x => x.mx_id == mx_id
|
||||
);
|
||||
|
||||
if (index >= 0)
|
||||
CamerasConectadas[index] = camera;
|
||||
else
|
||||
CamerasConectadas.Add(camera);
|
||||
|
||||
OrdenarCamerasMantendoPlaceholder(CamerasConectadas);
|
||||
}
|
||||
|
||||
return camera.ToOAK();
|
||||
}
|
||||
|
||||
private static List<CameraWorkerItemModel> LerCamerasDoRedis()
|
||||
{
|
||||
var resultado = CriarListaVaziaComPlaceholder();
|
||||
|
||||
string camerasStr = RedisService.Get(CtxKey.DadosCameras);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(camerasStr))
|
||||
return resultado;
|
||||
|
||||
Dictionary<string, CameraWorkerItemModel> cameras;
|
||||
|
||||
try
|
||||
{
|
||||
cameras =
|
||||
JsonConvert.DeserializeObject<
|
||||
Dictionary<string, CameraWorkerItemModel>
|
||||
>(
|
||||
camerasStr,
|
||||
_jsonSettings
|
||||
);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(
|
||||
"[CameraWorkerService] Falha ao ler índice de câmeras: " +
|
||||
ex.Message
|
||||
);
|
||||
|
||||
return resultado;
|
||||
}
|
||||
|
||||
if (cameras == null || cameras.Count == 0)
|
||||
return resultado;
|
||||
|
||||
foreach (string key in cameras.Keys.ToList())
|
||||
{
|
||||
CameraWorkerItemModel camera = LerCameraDoRedis(key);
|
||||
|
||||
if (camera == null)
|
||||
continue;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(camera.mx_id))
|
||||
continue;
|
||||
|
||||
resultado.Add(camera);
|
||||
}
|
||||
|
||||
OrdenarCamerasMantendoPlaceholder(resultado);
|
||||
|
||||
return resultado;
|
||||
}
|
||||
|
||||
private static CameraWorkerItemModel LerCameraDoRedis(
|
||||
string redisIdOuMxId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(redisIdOuMxId))
|
||||
return null;
|
||||
|
||||
string cameraStr =
|
||||
RedisService.Get(
|
||||
RedisService.CamKey(redisIdOuMxId)
|
||||
);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cameraStr))
|
||||
return null;
|
||||
|
||||
CameraWorkerItemModel camera;
|
||||
|
||||
try
|
||||
{
|
||||
camera =
|
||||
JsonConvert.DeserializeObject<CameraWorkerItemModel>(
|
||||
cameraStr,
|
||||
_jsonSettings
|
||||
);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(
|
||||
"[CameraWorkerService] Falha ao ler câmera " +
|
||||
redisIdOuMxId + ": " + ex.Message
|
||||
);
|
||||
|
||||
Console.WriteLine(
|
||||
"[CameraWorkerService] JSON câmera: " +
|
||||
cameraStr
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (camera == null ||
|
||||
string.IsNullOrWhiteSpace(camera.mx_id))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string imuStr =
|
||||
RedisService.Get(
|
||||
RedisService.CamImuKey(camera.mx_id)
|
||||
);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(imuStr))
|
||||
{
|
||||
try
|
||||
{
|
||||
var imu =
|
||||
JsonConvert.DeserializeObject<OAKImuModel>(
|
||||
imuStr,
|
||||
_jsonSettings
|
||||
);
|
||||
|
||||
camera.imu = imu?.dados;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(
|
||||
"[CameraWorkerService] Falha ao ler IMU da câmera " +
|
||||
camera.mx_id + ": " + ex.Message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return camera;
|
||||
}
|
||||
|
||||
private static List<CameraWorkerItemModel>
|
||||
CriarListaVaziaComPlaceholder()
|
||||
{
|
||||
return new List<CameraWorkerItemModel>
|
||||
{
|
||||
new CameraWorkerItemModel
|
||||
{
|
||||
dispositivo = T_Code.Vzo,
|
||||
modelo = "Sem Video"
|
||||
}
|
||||
};
|
||||
|
||||
var cameras_str = RedisService.Get(CtxKey.DadosCameras);
|
||||
var cameras = JsonConvert.DeserializeObject<Dictionary<string, CameraWorkerItemModel>>(cameras_str);
|
||||
|
||||
if (cameras.Any())
|
||||
{
|
||||
foreach (var cam in cameras)
|
||||
{
|
||||
var camera_str = RedisService.Get(RedisService.CamKey(cam.Key)) ?? "";
|
||||
var camera = JsonConvert.DeserializeObject<CameraWorkerItemModel>(camera_str);
|
||||
if (camera?.mx_id == null) continue;
|
||||
CamerasConectadas.Add(camera);
|
||||
}
|
||||
}
|
||||
|
||||
return CamerasConectadas;
|
||||
}
|
||||
|
||||
public static OAKCameraModel AtualizarDadosCamera(string mx_id)
|
||||
private static void OrdenarCamerasMantendoPlaceholder(
|
||||
List<CameraWorkerItemModel> cameras)
|
||||
{
|
||||
var cam = CamerasConectadas.FirstOrDefault(x => x.mx_id == mx_id);
|
||||
if (cam == null) return null;
|
||||
var camera_str = RedisService.Get(RedisService.CamKey(cam.mx_id)) ?? "";
|
||||
var camera = JsonConvert.DeserializeObject<CameraWorkerItemModel>(camera_str);
|
||||
if (camera?.mx_id == null) return null;
|
||||
var imu_str = RedisService.Get(RedisService.CamImuKey(cam.mx_id)) ?? "";
|
||||
var imu = JsonConvert.DeserializeObject<OAKImuModel>(imu_str);
|
||||
camera.imu = imu?.dados;
|
||||
cam = camera;
|
||||
return camera.ToOAK();
|
||||
if (cameras == null || cameras.Count <= 1)
|
||||
return;
|
||||
|
||||
CameraWorkerItemModel placeholder =
|
||||
cameras.FirstOrDefault(
|
||||
x => x.dispositivo == T_Code.Vzo &&
|
||||
x.modelo == "Sem Video"
|
||||
);
|
||||
|
||||
var reais =
|
||||
cameras
|
||||
.Where(x =>
|
||||
!(x.dispositivo == T_Code.Vzo &&
|
||||
x.modelo == "Sem Video"))
|
||||
.OrderBy(PrioridadeCamera)
|
||||
.ThenBy(x => x.mx_id)
|
||||
.ToList();
|
||||
|
||||
cameras.Clear();
|
||||
|
||||
if (placeholder != null)
|
||||
cameras.Add(placeholder);
|
||||
else
|
||||
cameras.Add(CriarListaVaziaComPlaceholder()[0]);
|
||||
|
||||
cameras.AddRange(reais);
|
||||
}
|
||||
|
||||
private static int PrioridadeCamera(CameraWorkerItemModel camera)
|
||||
{
|
||||
if (camera == null)
|
||||
return 99;
|
||||
|
||||
if (camera.dispositivo == T_Code.Snr)
|
||||
return 0;
|
||||
|
||||
if (camera.dispositivo == T_Code.Cam)
|
||||
return 1;
|
||||
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,8 +216,8 @@ namespace AgroBase.Services.Operadores
|
|||
("qtd_bicos", VariaveisEquipamento.QuantidadeBicosPulverizadores),
|
||||
("percentual_reservatorio_min", VariaveisEquipamento.PercentualReservatorioMin),
|
||||
("percentual_tensao_bateria_min", VariaveisEquipamento.PercentualTensaoBateriaMin),
|
||||
("camera_caminho_id", Variaveis.OperacaoEmAndamento.DispSen?.Dados?.CameraCaminho?.Id ?? ""),
|
||||
("camera_solo_id", Variaveis.OperacaoEmAndamento.DispSen?.Dados?.CamerasSolo?.FirstOrDefault()?.Id ?? ""),
|
||||
("camera_caminho_id", VariaveisEquipamento.Parametros.camera_caminhho_id ?? ""),
|
||||
("camera_solo_id", VariaveisEquipamento.Parametros.camera_ervas_id?.FirstOrDefault() ?? ""),
|
||||
("path_ia_model_ruas_seg", VersionamentoService.ArquivoModeloSegStreetDetector.CaminhoCompleto),
|
||||
("path_ia_labelmap_ruas_seg", VersionamentoService.ArquivoLabelmapSegStreetDetector.CaminhoCompleto),
|
||||
("path_ia_norm_stats_ruas_seg", VersionamentoService.ArquivoModeloNormstatsStreetDetector.CaminhoCompleto),
|
||||
|
|
@ -320,9 +320,9 @@ namespace AgroBase.Services.Operadores
|
|||
),
|
||||
("Snr", new
|
||||
{
|
||||
percentual_altura_solo = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho?.PercentualAlturaSolo ?? 0.1,
|
||||
distancia_maxima = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho?.DistanciaMaximaVisao ?? 5000,
|
||||
distancia_minima = Variaveis.OperacaoEmAndamento.DispSen.Dados.CameraCaminho?.DistanciaMinimaVisao ?? 300
|
||||
percentual_altura_solo = CameraWorkerService.CameraCaminho?.PercentualAlturaSolo ?? 0.1,
|
||||
distancia_maxima = CameraWorkerService.CameraCaminho?.DistanciaMaximaVisao ?? 5000,
|
||||
distancia_minima = CameraWorkerService.CameraCaminho?.DistanciaMinimaVisao ?? 300
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -121,7 +121,7 @@ class CameraManager:
|
|||
|
||||
dispositivos_serializados = list(set(dispositivos_serializados))
|
||||
|
||||
#self.mostrar_log("Dispositivos Serializados", dispositivos_serializados)
|
||||
#print("Dispositivos Serializados", dispositivos_serializados)
|
||||
|
||||
cameras_mapeadas = ContextoGlobalRedis.get_cameras() or {}
|
||||
|
||||
|
|
@ -138,6 +138,7 @@ class CameraManager:
|
|||
}
|
||||
else:
|
||||
#cam_existente["timestamp"] = agora
|
||||
#cam_existente["mx_id"] = mx_id
|
||||
cam_existente["presente_scan"] = True
|
||||
cam_existente["status_scan"] = "detectada"
|
||||
|
||||
|
|
@ -191,15 +192,23 @@ class CameraManager:
|
|||
|
||||
ContextoGlobalRedis.set(CtxKey.DadosCameras, cameras_mapeadas)
|
||||
|
||||
#self.mostrar_log("Cameras Mapeadas", cameras_mapeadas)
|
||||
#print("Cameras Mapeadas", cameras_mapeadas)
|
||||
|
||||
equipamento = ContextoGlobalRedis.get_equipamento() or {}
|
||||
|
||||
visual_worker_camera_id = equipamento.get("camera_caminho_id")
|
||||
weed_worker_camera_id = equipamento.get("camera_solo_id")
|
||||
|
||||
#self.mostrar_log(
|
||||
# "[CameraManager] IDs configurados | "
|
||||
# f"visual_worker_camera_id={visual_worker_camera_id!r} | "
|
||||
# f"weed_worker_camera_id={weed_worker_camera_id!r} | "
|
||||
# f"detectadas={list(cameras_mapeadas.keys())}"
|
||||
#)
|
||||
|
||||
# 3) Só tenta iniciar se a câmera estiver realmente válida
|
||||
if self._camera_pode_iniciar(visual_worker_camera_id, cameras_mapeadas, agora):
|
||||
#self.mostrar_log(f"[CameraManager] Enviando iniciar VisualWorker para câmera {visual_worker_camera_id}")
|
||||
ContextoGlobalRedis.publicar_comando(
|
||||
CmdKey.VisualWorkerRx,
|
||||
{
|
||||
|
|
@ -209,6 +218,7 @@ class CameraManager:
|
|||
)
|
||||
|
||||
if self._camera_pode_iniciar(weed_worker_camera_id, cameras_mapeadas, agora):
|
||||
#self.mostrar_log(f"[CameraManager] Enviando iniciar WeedWorker para câmera {weed_worker_camera_id}")
|
||||
ContextoGlobalRedis.publicar_comando(
|
||||
CmdKey.WeedWorkerRx,
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue