alguns guards e limpeza na operacao atual como instancia
This commit is contained in:
parent
719a71917d
commit
c98972129c
|
|
@ -76,8 +76,6 @@ namespace AgroBase.Forms.Direcional
|
|||
chbUsar.Checked = Modulo.DirMotor.UsarAnguloSensor;
|
||||
}
|
||||
}
|
||||
|
||||
txtIP.Text = Disp.Dados.IP_Dir;
|
||||
}
|
||||
|
||||
private void frmDirConfig_FormClosing(object sender, FormClosingEventArgs e)
|
||||
|
|
@ -126,14 +124,12 @@ namespace AgroBase.Forms.Direcional
|
|||
}
|
||||
}
|
||||
|
||||
Disp.Dados.IP_Dir = txtIP.Text;
|
||||
|
||||
Disp.SalvarParametros(Disp.Dados);
|
||||
}
|
||||
|
||||
private void cmbTipoMovimento_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = (TipoMovimentoDirecional)cmbTipoMovimento.SelectedIndex;
|
||||
Variaveis.OperacaoEmAndamento.DefinirTipoMovimentoControle((TipoMovimentoDirecional)cmbTipoMovimento.SelectedIndex);
|
||||
AtualizarConfiguracaoSentido();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -707,7 +707,7 @@ namespace AgroBase.Forms.IHM
|
|||
TipoMovimentoDirecional _oldTipoMovimento = Variaveis.OperacaoEmAndamento.Controle.TipoMovimento;
|
||||
double _oldPercentualVelocidade = Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP;
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = TipoMovimentoDirecional.Diagnostico;
|
||||
Variaveis.OperacaoEmAndamento.DefinirTipoMovimentoControle(TipoMovimentoDirecional.Diagnostico);
|
||||
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP = 20;
|
||||
|
||||
DispositivosService<MovimentacaoUnificadaModel> Dispositivo = (DispositivosService<MovimentacaoUnificadaModel>)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == Enums.T_Code.Mvd);
|
||||
|
|
@ -788,7 +788,7 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
}
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = _oldTipoMovimento;
|
||||
Variaveis.OperacaoEmAndamento.DefinirTipoMovimentoControle(_oldTipoMovimento);
|
||||
Variaveis.OperacaoEmAndamento.Controle.PercentualVelocidadeSP = _oldPercentualVelocidade;
|
||||
|
||||
return true;
|
||||
|
|
@ -952,7 +952,7 @@ namespace AgroBase.Forms.IHM
|
|||
return false;
|
||||
}
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = TipoMovimentoDirecional.Diagnostico;
|
||||
Variaveis.OperacaoEmAndamento.DefinirTipoMovimentoControle(TipoMovimentoDirecional.Diagnostico);
|
||||
Variaveis.OperacaoEmAndamento.Controle.Angulo = 25;
|
||||
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento = 30;
|
||||
|
||||
|
|
@ -1001,7 +1001,7 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
}
|
||||
|
||||
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = _oldTipoMovimento;
|
||||
Variaveis.OperacaoEmAndamento.DefinirTipoMovimentoControle(_oldTipoMovimento);
|
||||
Variaveis.OperacaoEmAndamento.Controle.Angulo = _oldAngulo;
|
||||
Variaveis.OperacaoEmAndamento.Parametros.Controle.DirVelocidadeMovimento = _oldVelocidadeMP;
|
||||
|
||||
|
|
|
|||
|
|
@ -624,7 +624,7 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
private void CmbModoControle_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = (Enums.TipoMovimentoDirecional)cmbModoControle.SelectedIndex;
|
||||
Variaveis.OperacaoEmAndamento.DefinirTipoMovimentoControle((Enums.TipoMovimentoDirecional)cmbModoControle.SelectedIndex);
|
||||
}
|
||||
|
||||
private void tkbVelocidade_Scroll(object sender, EventArgs e)
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
frmDialogo = new frmDialogoMapa();
|
||||
frmDialogo.Show();
|
||||
frmDialogo.Hide();
|
||||
(bool sucesso, List<string> ruas) = Variaveis.OperacaoEmAndamento.CarregarParametrizacaoOperacao(frmDialogo.pnlMapa, frmDialogo.lblMapaCarregado, path);
|
||||
bool sucesso = Variaveis.OperacaoEmAndamento.CarregarParametrizacaoOperacao(frmDialogo.pnlMapa, frmDialogo.lblMapaCarregado, path);
|
||||
|
||||
bool condicaoOperacaoCarregada() => Variaveis.OperacaoEmAndamento.Trajetoria?.CorredorAtual != null;
|
||||
bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoOperacaoCarregada, 15000, 200);
|
||||
|
|
@ -221,7 +221,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
throw new Exception("Erro ao carregar a trajetória do mapa!");
|
||||
}
|
||||
|
||||
ruasSelecionadas = ruas;
|
||||
ruasSelecionadas = new List<string>();
|
||||
|
||||
foreach (var chb in fpnlInformacoes.Controls.OfType<CheckBox>())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@ namespace AgroBase.Forms.Movimentacao
|
|||
nudRPMMax.Value = (int)Disp.Dados.RPM_Max_MotorBLDC;
|
||||
nudReducao.Value = (int)Disp.Dados.ReducaoMotorBLDC;
|
||||
nudDiametroRoda.Value = (int)(Disp.Dados.DiametroRoda * 1000);
|
||||
txtIP.Text = Disp.Dados.IP_Mov;
|
||||
}
|
||||
|
||||
private void frmMovConfig_FormClosing(object sender, FormClosingEventArgs e)
|
||||
|
|
@ -153,14 +152,13 @@ namespace AgroBase.Forms.Movimentacao
|
|||
Disp.Dados.RPM_Max_MotorBLDC = Convert.ToInt32(nudRPMMax.Value);
|
||||
Disp.Dados.ReducaoMotorBLDC = Convert.ToInt32(nudReducao.Value);
|
||||
Disp.Dados.DiametroRoda = Convert.ToDouble(nudDiametroRoda.Value / 1000);
|
||||
Disp.Dados.IP_Mov = txtIP.Text;
|
||||
|
||||
Disp.SalvarParametros(Disp.Dados);
|
||||
}
|
||||
|
||||
private void cmbTipoMovimento_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
Variaveis.OperacaoEmAndamento.Controle.TipoMovimento = (TipoMovimentoDirecional)cmbTipoMovimento.SelectedIndex;
|
||||
Variaveis.OperacaoEmAndamento.DefinirTipoMovimentoControle((TipoMovimentoDirecional)cmbTipoMovimento.SelectedIndex);
|
||||
AtualizarConfiguracaoSentido();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using AgroBase.Services;
|
|||
using AgroBase.Models.Modules;
|
||||
using System.Threading.Tasks;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AgroBase.Forms.Operacoes
|
||||
{
|
||||
|
|
@ -761,16 +762,18 @@ namespace AgroBase.Forms.Operacoes
|
|||
|
||||
private void cmbTipoMovimento_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
op.Controle.TipoMovimento = (TipoMovimentoDirecional)cmbTipoMovimento.SelectedIndex;
|
||||
op.DefinirTipoMovimentoControle((TipoMovimentoDirecional)cmbTipoMovimento.SelectedIndex);
|
||||
}
|
||||
|
||||
private void chbPulverizador_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
op.Parametros.Controle.PulverizadorAutomatico = ((CheckBox)sender).Checked;
|
||||
|
||||
if (!op.Parametros.Controle.PulverizadorAutomatico && op.Controle.Bicos.Any(x => x.ComandoAtuar))
|
||||
var bicos = op.DispAtu?.Dados?.BicosPulverizadores ?? new List<AtuadorBicoModel>();
|
||||
|
||||
if (!op.Parametros.Controle.PulverizadorAutomatico && bicos.Any(x => x.ComandoAtuar))
|
||||
{
|
||||
op.Controle.Bicos.ForEach(b => b.ComandoAtuar = false);
|
||||
bicos.ForEach(b => b.ComandoAtuar = false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
|
||||
GPSModel pos = GPSService.UltimaLeitura.Clone();
|
||||
GPSService.UltimaLeitura = LogsGPS.FirstOrDefault();
|
||||
(bool sucesso, List<string> ruas) = op.CarregarParametrizacaoOperacao(null, null, ofd.FileName.Replace("data.lgop", "operacao.opr"));
|
||||
bool sucesso = op.CarregarParametrizacaoOperacao(null, null, ofd.FileName.Replace("data.lgop", "operacao.opr"));
|
||||
bool condicaoOperacaoCarregada() => op.Trajetoria?.CorredorAtual != null;
|
||||
bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoOperacaoCarregada, 15000, 200);
|
||||
GPSService.UltimaLeitura = pos;
|
||||
|
|
@ -1211,7 +1211,7 @@ namespace AgroBase.Forms.Operacoes
|
|||
txtVelocidade.Text = (LogMov.VelocidadeMediaMs * 3.6).ToString("0.00") + " km/h (" + LogMov.VelocidadeMediaMs.ToString("0.00") + " m/s)";
|
||||
txtDirecaoControle.Text = (LogCtrl?.TiposControle?.FirstOrDefault(x => x.Tipo == Enums.T_Code.Dir)?.DirecaoAtual ?? Enums.Direcao.Parado).ToString() + " (" + (LogCtrl?.Latencia ?? 0).ToString("0.00") + " s)";
|
||||
txtVelocidadeControle.Text = ((LogCtrl?.PercentualVelocidadeSP ?? 0) / VariaveisEquipamento.RPM_Max_Roda * 100).ToString() + " rpm";
|
||||
txtErvasIdentificadas.Text = $"{LogCtrl?.Bicos?.Sum(x => x.Atuacoes) ?? 0}";
|
||||
txtErvasIdentificadas.Text = $"{LogAtu?.Bicos?.Sum(x => x.Atuacoes) ?? 0}";
|
||||
|
||||
txtDistanciasLaterais.Text = (LogTrj.DistanciaEsquerda * 100.0).ToString("0.00") + " cm / " + (LogTrj.DistanciaDireita * 100.0).ToString("0.00") + " cm";
|
||||
txtErroLateral.Text = (LogCtrl.ErroLateral * 100.0).ToString("0.00") + " cm";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using AgroBase.Forms.IHM;
|
||||
using AgroBase.Models;
|
||||
using AgroBase.Services;
|
||||
using AgroBase.Services.Operadores;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -11,8 +10,6 @@ namespace AgroBase.Forms
|
|||
{
|
||||
public partial class frmInstancial : Form
|
||||
{
|
||||
public static readonly bool IniciarWorkers = true;
|
||||
|
||||
public static AsyncTaskTimerModel tmrVarreduraDispositivos;
|
||||
|
||||
public static frmPrincipal frmPrincipal = new frmPrincipal();
|
||||
|
|
@ -105,6 +102,8 @@ namespace AgroBase.Forms
|
|||
if (_startupConcluido)
|
||||
return;
|
||||
|
||||
Variaveis.OperacaoEmAndamento = OperacaoModel.CarregarParametrosOperacaoPadrao(Enums.ModoOperacao.NaoDefinido, true);
|
||||
|
||||
_shutdownIniciado = false;
|
||||
Variaveis.Fechando = false;
|
||||
|
||||
|
|
@ -142,7 +141,7 @@ namespace AgroBase.Forms
|
|||
|
||||
LivoxManagerProcess.Start();
|
||||
|
||||
await VariaveisOperacao.Operadores.IniciarProcessamento(IniciarWorkers).ConfigureAwait(false);
|
||||
await VariaveisOperacao.Operadores.IniciarProcessamento(Variaveis.IniciarWorkers).ConfigureAwait(false);
|
||||
|
||||
AudioAlertaService.SelecionarVoz(VariaveisEquipamento.VozAlerta);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ namespace AgroBase.Forms
|
|||
private async Task AtualizarParametros()
|
||||
{
|
||||
(bool sucesso, LoRaParametrosModel par) = (false, null);
|
||||
if (Variaveis.IsAgroMonitor)
|
||||
if (!Variaveis.IsAgroBase)
|
||||
{
|
||||
(sucesso, par) = await LoRaBaseService.RequisitarParametrosModuloAsync();
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ namespace AgroBase.Forms
|
|||
|
||||
private async Task tmrLeitura_Tick()
|
||||
{
|
||||
if (Variaveis.IsAgroMonitor)
|
||||
if (!Variaveis.IsAgroBase)
|
||||
{
|
||||
var MensagemDisponivel = LoRaBaseService.MensagemPendente;
|
||||
if (MensagemDisponivel != null)
|
||||
|
|
@ -152,7 +152,7 @@ namespace AgroBase.Forms
|
|||
private async Task ConfigurarModulo()
|
||||
{
|
||||
(bool Sucesso, LoRaParametrosModel par) = (false, null);
|
||||
if (Variaveis.IsAgroMonitor)
|
||||
if (!Variaveis.IsAgroBase)
|
||||
{
|
||||
(Sucesso, par) = await LoRaBaseService.ConfigurarModuloAsync(Parametros);
|
||||
}
|
||||
|
|
@ -202,7 +202,7 @@ namespace AgroBase.Forms
|
|||
}
|
||||
}
|
||||
|
||||
if (Variaveis.IsAgroMonitor)
|
||||
if (!Variaveis.IsAgroBase)
|
||||
{
|
||||
LoRaBaseService.EnviarDadosLoRa(payload.ToArray(), destinatario);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace AgroBase
|
|||
|
||||
cmbModoOperacao.Items.Clear();
|
||||
cmbModoOperacao.Items.AddRange(Enum.GetNames(typeof(ModoOperacao)));
|
||||
cmbModoOperacao.SelectedIndex = (int)(Variaveis.OperacaoEmAndamento.Parametros?.Modo ?? ModoOperacao.NaoDefinido);
|
||||
cmbModoOperacao.SelectedIndex = (int)(Variaveis.OperacaoEmAndamento?.Parametros?.Modo ?? ModoOperacao.NaoDefinido);
|
||||
}
|
||||
|
||||
private async void frmPrincipal_FormClosing(object sender, FormClosingEventArgs e)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace AgroBase.Models
|
|||
|
||||
public void AtualizarDados()
|
||||
{
|
||||
var saude = Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorSaude?.ModulosSaude;
|
||||
var saude = Variaveis.OperacaoEmAndamento?.Sensoriamento?.OperadorSaude?.ModulosSaude ?? new System.Collections.Generic.List<Operadores.ManagerWorkerMessageResponseModulosPendentesModel>();
|
||||
Status = saude?.FirstOrDefault(x => x.modulo == Dispositivo)?.status ?? StatusModulo.Desconectado;
|
||||
Saude = saude?.FirstOrDefault(x => x.modulo == Dispositivo)?.saude ?? 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1895,6 +1895,8 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
|
||||
if (!op.Sensoriamento.Operacao.ModsCalibragem.ContainsKey(T_Code.Atu))
|
||||
op.Sensoriamento.Operacao.ModsCalibragem.Add(T_Code.Atu, new Dictionary<string, bool>());
|
||||
var calAtu = op.Sensoriamento.Operacao.ModsCalibragem[Dispositivo];
|
||||
|
||||
// Ligar bomba
|
||||
|
|
|
|||
|
|
@ -677,9 +677,9 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
|
||||
var ctrl = op.Controle;
|
||||
var disp = op.DispMvd?.Dados?.Modulos;
|
||||
if (op.Sensoriamento?.Operacao?.StatusOperacaoAtual != StatusOperacao.EmAndamento || ctrl == null || disp == null || !MovimentosCompensar.Contains(ctrl.TipoMovimento))
|
||||
var ctrl = op?.Controle;
|
||||
var disp = op?.DispMvd?.Dados?.Modulos;
|
||||
if (op?.Sensoriamento?.Operacao?.StatusOperacaoAtual != StatusOperacao.EmAndamento || ctrl == null || disp == null || !MovimentosCompensar.Contains(ctrl.TipoMovimento))
|
||||
{
|
||||
compensacoes = (disp ?? Enumerable.Empty<ModuloMvdModel>()).ToDictionary(x => x.Modulo_ID, x => 1.0);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ namespace AgroBase.Models.Modules
|
|||
public double ReducaoMotorBLDC { get; set; } = 5;
|
||||
public double RPM_Max_MotorBLDC { get; set; } = 500;
|
||||
|
||||
public string IP_Mov { get; set; } = Variaveis.FaixaIPethernet + ".10";
|
||||
public string IP_Dir { get; set; } = Variaveis.FaixaIPethernet + ".11";
|
||||
public DateTime UltimoTickRegistrador = DateTime.MinValue;
|
||||
|
||||
public static int LogsManter { get; set; } = 60;
|
||||
|
|
@ -506,7 +504,7 @@ namespace AgroBase.Models.Modules
|
|||
|
||||
TipoMovimentoDirecional tipoControle = op.Controle.TipoMovimento;
|
||||
|
||||
op.Controle.TipoMovimento = TipoMovimentoDirecional.Diagnostico;
|
||||
op.DefinirTipoMovimentoControle(TipoMovimentoDirecional.Diagnostico);
|
||||
var ModsRef = Modulos.Where(x => x.DirMotor.Comandar && x.DirMotor.Inicializado && (ModsReferenciar != null ? ModsReferenciar.Contains(x.DirMotor.Mod_ID) : true)).ToList();
|
||||
foreach (var Modulo in ModsRef)
|
||||
{
|
||||
|
|
@ -515,7 +513,7 @@ namespace AgroBase.Models.Modules
|
|||
|
||||
bool ReferenciamentoConcluido() => !MKS057DCanService.Referenciando;
|
||||
await FuncoesGlobais.AguardarCondicaoAsync(ReferenciamentoConcluido, 2 * 1000 * 60, 1000);
|
||||
op.Controle.TipoMovimento = tipoControle;
|
||||
op.DefinirTipoMovimentoControle(tipoControle);
|
||||
}
|
||||
|
||||
return Modulos.All(x => x.DirMotor.Referenciado);
|
||||
|
|
@ -568,7 +566,7 @@ namespace AgroBase.Models.Modules
|
|||
|
||||
if (DispMvd.Dados.Modulos.Any(x => x.DirMotor.Inicializado))
|
||||
{
|
||||
op.Controle.TipoMovimento = TipoMovimentoDirecional.Diagnostico;
|
||||
op.DefinirTipoMovimentoControle(TipoMovimentoDirecional.Diagnostico);
|
||||
var ModsRef = Modulos.Where(x => x.DirMotor.Comandar).ToList(); // && x.DirMotor.Inicializado
|
||||
foreach (var Modulo in ModsRef)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,6 +25,72 @@ namespace AgroBase.Models
|
|||
{
|
||||
public class OperacaoModel
|
||||
{
|
||||
#region TIMERS
|
||||
|
||||
public double tmrLeiturasInterval
|
||||
{
|
||||
get
|
||||
{
|
||||
return tmrLeituras?.Interval ?? 500;
|
||||
}
|
||||
set
|
||||
{
|
||||
tmrLeituras?.SetInterval((int)value);
|
||||
}
|
||||
}
|
||||
private AsyncTaskTimerModel tmrLeituras;
|
||||
private AsyncTaskTimerModel tmrComunicacao;
|
||||
public void IniciarTimersSistema()
|
||||
{
|
||||
if (!Variaveis.IsAgroBase)
|
||||
return;
|
||||
|
||||
if (!ReferenceEquals(Variaveis.OperacaoEmAndamento, this))
|
||||
{
|
||||
Variaveis.MostrarLog(
|
||||
$"[OperacaoModel.IniciarTimersSistema] Ignorado: instância não é atual. " +
|
||||
$"Hash={GetHashCode()}, AtualHash={Variaveis.OperacaoEmAndamento?.GetHashCode()}"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
tmrLeituras?.Stop();
|
||||
tmrLeituras?.Dispose();
|
||||
tmrLeituras = new AsyncTaskTimerModel($"tmrLeitura_{GetHashCode()}", tmrLeituras_Tick, 500);
|
||||
tmrLeituras.Start();
|
||||
|
||||
tmrComunicacao?.Stop();
|
||||
tmrComunicacao?.Dispose();
|
||||
tmrComunicacao = new AsyncTaskTimerModel($"tmrComunicacao_{GetHashCode()}", tmrComunicacao_Tick, 1000);
|
||||
tmrComunicacao.Start();
|
||||
|
||||
Variaveis.MostrarLog(
|
||||
$"[OperacaoModel.IniciarTimersSistema] Timers iniciados. Hash={GetHashCode()}, Modo={Parametros?.Modo}"
|
||||
);
|
||||
}
|
||||
public void PararTimersSistema()
|
||||
{
|
||||
try
|
||||
{
|
||||
tmrLeituras?.Stop();
|
||||
tmrLeituras?.Dispose();
|
||||
tmrLeituras = null;
|
||||
|
||||
tmrComunicacao?.Stop();
|
||||
tmrComunicacao?.Dispose();
|
||||
tmrComunicacao = null;
|
||||
|
||||
Variaveis.MostrarLog(
|
||||
$"[OperacaoModel.PararTimersSistema] Timers do sistema parados. Operacao={ID}, Hash={GetHashCode()}, idxLog={idxLog}"
|
||||
);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Variaveis.MostrarLog("[OperacaoModel.PararTimersSistema] Erro ao parar timers do sistema: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public double tmrLogsInterval
|
||||
{
|
||||
get
|
||||
|
|
@ -39,40 +105,35 @@ namespace AgroBase.Models
|
|||
private AsyncTaskTimerModel _tmrLogsOperacao;
|
||||
private int idxLog = 0;
|
||||
private readonly SemaphoreSlim _salvarLogsGate = new SemaphoreSlim(1, 1);
|
||||
public double tmrLeiturasInterval
|
||||
private void IniciarTimerLogsOperacao()
|
||||
{
|
||||
get
|
||||
if (!Variaveis.IsAgroBase)
|
||||
return;
|
||||
|
||||
_tmrLogsOperacao?.Stop();
|
||||
_tmrLogsOperacao?.Dispose();
|
||||
|
||||
_tmrLogsOperacao = new AsyncTaskTimerModel($"tmrLogs_{ID}", tmrLogs_Tick, 1000);
|
||||
|
||||
_tmrLogsOperacao.Start();
|
||||
|
||||
Variaveis.MostrarLog($"[OperacaoModel.IniciarTimerLogsOperacao] Timer de logs iniciado. Operacao={ID}, Hash={GetHashCode()}");
|
||||
}
|
||||
private void PararTimerLogsOperacao()
|
||||
{
|
||||
try
|
||||
{
|
||||
return tmrLeituras.Interval;
|
||||
_tmrLogsOperacao?.Stop();
|
||||
|
||||
Variaveis.MostrarLog($"[OperacaoModel.PararTimerLogsOperacao] Timer de logs parado. Operacao={ID}, Hash={GetHashCode()}, idxLog={idxLog}");
|
||||
}
|
||||
set
|
||||
catch (Exception ex)
|
||||
{
|
||||
tmrLeituras.SetInterval((int)value);
|
||||
Variaveis.MostrarLog("[OperacaoModel.PararTimerLogsOperacao] Erro ao parar timer de logs: " + ex.Message);
|
||||
}
|
||||
}
|
||||
private static AsyncTaskTimerModel tmrLeituras;
|
||||
private static AsyncTaskTimerModel tmrComunicacao;
|
||||
|
||||
public OperacaoModel()
|
||||
{
|
||||
Variaveis.MostrarLog("[OperacaoModel.ctor] StackTrace: " + Environment.StackTrace);
|
||||
|
||||
Variaveis.MostrarLog(
|
||||
$"[OperacaoModel.ctor] Nova instância. Hash={GetHashCode()}, " +
|
||||
$"OperacaoAtual={Variaveis.OperacaoEmAndamento?.ID}, " +
|
||||
$"HashAtual={Variaveis.OperacaoEmAndamento?.GetHashCode()}"
|
||||
);
|
||||
|
||||
tmrLeituras?.Dispose();
|
||||
tmrLeituras = new AsyncTaskTimerModel("tmrLeitura", tmrLeituras_Tick, 500);
|
||||
tmrLeituras.Start();
|
||||
|
||||
tmrComunicacao?.Dispose();
|
||||
tmrComunicacao = new AsyncTaskTimerModel("tmrComunicacao", tmrComunicacao_Tick, 1000);
|
||||
tmrComunicacao.Start();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
public StatusModulo Status { get; set; }
|
||||
public string Descricao { get; set; }
|
||||
|
|
@ -105,8 +166,27 @@ namespace AgroBase.Models
|
|||
|
||||
#region PARAMETRIZACAO
|
||||
|
||||
public (bool, List<string>) CarregarParametrizacaoOperacao(Panel pnlMapa, Label lblMapa, string opPath = "")
|
||||
private bool EhOperacaoAtual(string origem)
|
||||
{
|
||||
if (ReferenceEquals(Variaveis.OperacaoEmAndamento, this))
|
||||
return true;
|
||||
|
||||
Variaveis.MostrarLog(
|
||||
$"[OperacaoModel.{origem}] Ignorado: instância não é atual. " +
|
||||
$"Hash={GetHashCode()}, AtualHash={Variaveis.OperacaoEmAndamento?.GetHashCode()}, ID={ID}, AtualID={Variaveis.OperacaoEmAndamento?.ID}"
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CarregarParametrizacaoOperacao(Panel pnlMapa, Label lblMapa, string opPath = "")
|
||||
{
|
||||
if (Variaveis.OperacaoEmAndamento?.Sensoriamento?.Operacao?.OperacaoIniciada == true)
|
||||
{
|
||||
Variaveis.MostrarLog("[OperacaoModel.CarregarParametrizacaoOperacao] Ignorado: tentativa de carregar operação com operação iniciada.");
|
||||
return false;
|
||||
}
|
||||
|
||||
string path = Variaveis.CaminhoSistema + Variaveis.CaminhoOperacoes + MapasVariaveisModel.NomeArquivoMapaInterativoSaida;
|
||||
|
||||
OpenFileDialog openFileDialog = new OpenFileDialog();
|
||||
|
|
@ -118,54 +198,35 @@ namespace AgroBase.Models
|
|||
{
|
||||
string opr_path = !string.IsNullOrEmpty(opPath) ? opPath : openFileDialog.FileName;
|
||||
|
||||
if (!File.Exists(opr_path)) return (false, new List<string>());
|
||||
if (!File.Exists(opr_path)) return false;
|
||||
|
||||
string ParametrosJson = File.ReadAllText(opr_path, Encoding.UTF8);
|
||||
|
||||
var Parametros = JsonConvert.DeserializeObject<OperacaoParametrosModel>(ParametrosJson);
|
||||
|
||||
if (Parametros.Modo == null) return (false, new List<string>());
|
||||
if (Parametros.Modo == null) return false;
|
||||
|
||||
Variaveis.OperacaoEmAndamento = CarregarParametrosOperacaoPadrao((ModoOperacao)Parametros.Modo, CarregarModulos: true);
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
var newOp = CarregarParametrosOperacaoPadrao((ModoOperacao)Parametros.Modo, CarregarModulos: true);
|
||||
|
||||
op.Parametros = Parametros;
|
||||
op.DefinirComponentesEmUso();
|
||||
newOp.Parametros = Parametros;
|
||||
newOp.DefinirComponentesEmUso();
|
||||
|
||||
op.Descricao = Parametros.Descricao;
|
||||
op.OprPath = opr_path;
|
||||
if (op.DispSen == null)
|
||||
newOp.Descricao = Parametros.Descricao;
|
||||
newOp.OprPath = opr_path;
|
||||
if (newOp.DispSen == null)
|
||||
{
|
||||
op.DispSen = new DispositivosService<SensoriamentoModel>();
|
||||
newOp.DispSen = new DispositivosService<SensoriamentoModel>();
|
||||
}
|
||||
//Variaveis.OperacaoEmAndamento.DispSen.Dados.ConfiguracaoSensorUltrassom = Parametros.ConfiguracaoUltrassom;
|
||||
|
||||
List<string> ruasSelecionadas = new List<string>();
|
||||
//if (Parametros.Mapa.mapaService.DadosMapa != null)
|
||||
//{
|
||||
// ruasSelecionadas = Parametros.Mapa.RuasPercorrer.ToList();
|
||||
// string geoJson = JsonConvert.SerializeObject(Parametros.Mapa.mapaService.DadosMapa, Formatting.None);
|
||||
// File.WriteAllText(path, geoJson, Encoding.UTF8);
|
||||
// Variaveis.OperacaoEmAndamento.Mapa = Parametros.Mapa;
|
||||
//
|
||||
// /*Panel pnlMapa = FuncoesGlobais.FindControlRecursive<Panel>(Variaveis.OperacaoEmAndamento.frmOperacao, "pnlMapa");
|
||||
// Label lblMapa = FuncoesGlobais.FindControlRecursive<Label>(Variaveis.OperacaoEmAndamento.frmOperacao, "lblMapaCarregado");*/
|
||||
// Variaveis.OperacaoEmAndamento.Mapa.pnlMapa = pnlMapa;
|
||||
// Variaveis.OperacaoEmAndamento.Mapa.lblMapa = lblMapa;
|
||||
//
|
||||
// Variaveis.OperacaoEmAndamento.Mapa.btnCarregar_Click(new object(), new EventArgs(), path);
|
||||
//
|
||||
// //bool condicaoMapaCarregado() => Variaveis.OperacaoEmAndamento.Mapa.mapaService.Carregado;
|
||||
// //bool resultado = await FuncoesGlobais.AguardarCondicaoAsync(condicaoMapaCarregado, 5000, 200);
|
||||
//}
|
||||
|
||||
Variaveis.OperacaoEmAndamento = newOp;
|
||||
|
||||
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
|
||||
|
||||
return (true, ruasSelecionadas);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (false, new List<string>());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -256,7 +317,7 @@ namespace AgroBase.Models
|
|||
AtuDuracaoAtuacao = 200,
|
||||
AtuPercentualErvasBicoOff = 2,
|
||||
AtuPercentualErvasBicoOn = 1,
|
||||
AtuPercentualInicioPulverizacao = 70,
|
||||
AtuPercentualInicioPulverizacao = 85,
|
||||
AtuPressaoLinha = 22,
|
||||
AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao,
|
||||
AtuModoControle = ModoControleBomba.PID
|
||||
|
|
@ -367,7 +428,7 @@ namespace AgroBase.Models
|
|||
AtuDuracaoAtuacao = 200,
|
||||
AtuPercentualErvasBicoOff = 2,
|
||||
AtuPercentualErvasBicoOn = 1,
|
||||
AtuPercentualInicioPulverizacao = 70,
|
||||
AtuPercentualInicioPulverizacao = 85,
|
||||
AtuPressaoLinha = 22,
|
||||
AtuAgitadorModo = ModoAgitadorCalda.Continuo,
|
||||
AtuModoControle = ModoControleBomba.PID,
|
||||
|
|
@ -646,7 +707,7 @@ namespace AgroBase.Models
|
|||
AtuDuracaoAtuacao = 200,
|
||||
AtuPercentualErvasBicoOff = 2,
|
||||
AtuPercentualErvasBicoOn = 1,
|
||||
AtuPercentualInicioPulverizacao = 70,
|
||||
AtuPercentualInicioPulverizacao = 85,
|
||||
AtuPressaoLinha = 22,
|
||||
AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao,
|
||||
AtuModoControle = ModoControleBomba.PID,
|
||||
|
|
@ -745,7 +806,7 @@ namespace AgroBase.Models
|
|||
AtuDuracaoAtuacao = 200,
|
||||
AtuPercentualErvasBicoOff = 2,
|
||||
AtuPercentualErvasBicoOn = 1,
|
||||
AtuPercentualInicioPulverizacao = 70,
|
||||
AtuPercentualInicioPulverizacao = 85,
|
||||
AtuPressaoLinha = 22,
|
||||
AtuAgitadorModo = ModoAgitadorCalda.SemAgitacao,
|
||||
AtuModoControle = ModoControleBomba.PID,
|
||||
|
|
@ -966,47 +1027,60 @@ namespace AgroBase.Models
|
|||
});
|
||||
}
|
||||
|
||||
public (bool, List<string>) CarregarParamerosOperacaoBase(OperacaoParametrosModel Parametros)
|
||||
public static OperacaoModel CarregarParamerosOperacaoBase(OperacaoParametrosModel parametros)
|
||||
{
|
||||
if (Parametros.Modo == null) return (false, new List<string>());
|
||||
if (parametros?.Modo == null)
|
||||
return null;
|
||||
|
||||
Variaveis.OperacaoEmAndamento = CarregarParametrosOperacaoPadrao((ModoOperacao)Parametros.Modo, CarregarModulos: true);
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
var novaOp = CarregarParametrosOperacaoPadrao((ModoOperacao)parametros.Modo, CarregarModulos: true);
|
||||
|
||||
op.Descricao = Parametros.Descricao;
|
||||
op.OprPath = $"Base ({VariaveisEquipamento.Parametros.base_ip})";
|
||||
var p = op.Parametros;
|
||||
p.Descricao = Parametros.Descricao;
|
||||
p.CapacidadeReservatorio = Parametros.CapacidadeReservatorio;
|
||||
p.Controle = Parametros.Controle;
|
||||
p.QtdBicos = Parametros.QtdBicos;
|
||||
p.QtdCamerasSolo = Parametros.QtdCamerasSolo;
|
||||
p.TipoMapa = Parametros.TipoMapa;
|
||||
p.Mapa = Parametros.Mapa;
|
||||
p.RuasPercorrer = Parametros.RuasPercorrer;
|
||||
p.PontosRetorno = Parametros.PontosRetorno;
|
||||
p.ModulosMandatorios = Parametros.ModulosMandatorios;
|
||||
p.ParametrosMandatorios = Parametros.ParametrosMandatorios;
|
||||
novaOp.Descricao = parametros.Descricao;
|
||||
novaOp.OprPath = "";
|
||||
|
||||
op.DefinirComponentesEmUso();
|
||||
novaOp.Parametros.Descricao = parametros.Descricao;
|
||||
novaOp.Parametros.CapacidadeReservatorio = parametros.CapacidadeReservatorio;
|
||||
novaOp.Parametros.Controle = parametros.Controle;
|
||||
novaOp.Parametros.QtdBicos = parametros.QtdBicos;
|
||||
novaOp.Parametros.QtdCamerasSolo = parametros.QtdCamerasSolo;
|
||||
novaOp.Parametros.TipoMapa = parametros.TipoMapa;
|
||||
novaOp.Parametros.Mapa = parametros.Mapa;
|
||||
novaOp.Parametros.RuasPercorrer = parametros.RuasPercorrer;
|
||||
novaOp.Parametros.PontosRetorno = parametros.PontosRetorno;
|
||||
novaOp.Parametros.ModulosMandatorios = parametros.ModulosMandatorios;
|
||||
novaOp.Parametros.ParametrosMandatorios = parametros.ParametrosMandatorios;
|
||||
|
||||
List<string> ruasSelecionadas = Parametros.RuasPercorrer ?? new List<string>();
|
||||
if (Parametros.Mapa != null)
|
||||
novaOp.DefinirComponentesEmUso();
|
||||
|
||||
var ruasSelecionadas = parametros.RuasPercorrer ?? new List<string>();
|
||||
|
||||
if (parametros.Mapa != null)
|
||||
{
|
||||
op.Mapa = new MapasModel() { RuasPercorrer = ruasSelecionadas };
|
||||
op.Mapa.TipoMapa = p.TipoMapa;
|
||||
op.Mapa.PopularTrajetoriaMapa(Parametros.Mapa);
|
||||
novaOp.Mapa = new MapasModel() { RuasPercorrer = ruasSelecionadas };
|
||||
novaOp.Mapa.TipoMapa = novaOp.Parametros.TipoMapa;
|
||||
novaOp.Mapa.PopularTrajetoriaMapa(parametros.Mapa);
|
||||
}
|
||||
|
||||
Variaveis.OperacaoEmAndamento = novaOp;
|
||||
|
||||
RedisService.AtualizarCampos(CtxKey.DadosOperacao, ("configurado", false));
|
||||
|
||||
return (true, ruasSelecionadas);
|
||||
return novaOp;
|
||||
}
|
||||
|
||||
|
||||
public async Task IniciarOperacao()
|
||||
{
|
||||
if (!EhOperacaoAtual(nameof(IniciarOperacao)))
|
||||
return;
|
||||
|
||||
var op = this;
|
||||
|
||||
if (op.Sensoriamento?.Operacao?.OperacaoIniciada == true)
|
||||
{
|
||||
Variaveis.MostrarLog("[OperacaoModel.IniciarOperacao] Ignorado: operação já iniciada.");
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime agora = DateTime.Now;
|
||||
var dispSen = op.DispSen;
|
||||
var dispAtu = op.DispAtu;
|
||||
|
|
@ -1045,6 +1119,7 @@ namespace AgroBase.Models
|
|||
VisualWorkerService.ReiniciarLeituraAnalise();
|
||||
|
||||
op.Controle.Reiniciar();
|
||||
op.DefinirTipoMovimentoControle(TipoMovimentoDirecional.RodasDianteiras);
|
||||
op.ControleAnterior.Reiniciar();
|
||||
|
||||
double distanciaPercorrida = dispMvd?.Dados?.DistanciaPercorridaTotal ?? 0;
|
||||
|
|
@ -1071,6 +1146,9 @@ namespace AgroBase.Models
|
|||
{
|
||||
var op = this;
|
||||
|
||||
if (!EhOperacaoAtual(nameof(FinalizarOperacao)))
|
||||
return;
|
||||
|
||||
if (op.Sensoriamento.Operacao.Finalizando)
|
||||
return;
|
||||
|
||||
|
|
@ -1107,6 +1185,9 @@ namespace AgroBase.Models
|
|||
|
||||
public void ReiniciarOperacao(bool daBase)
|
||||
{
|
||||
if (!EhOperacaoAtual(nameof(ReiniciarOperacao)))
|
||||
return;
|
||||
|
||||
var op = this;
|
||||
|
||||
RedisService.AtualizarCampos(
|
||||
|
|
@ -1115,14 +1196,23 @@ namespace AgroBase.Models
|
|||
("iniciado", false)
|
||||
);
|
||||
|
||||
CarregarParamerosOperacaoBase(op.Parametros);
|
||||
var novaOp = CarregarParamerosOperacaoBase(op.Parametros);
|
||||
|
||||
if (novaOp == null)
|
||||
{
|
||||
Variaveis.MostrarLog("[OperacaoModel.ReiniciarOperacao] Falha ao recriar operação.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (daBase)
|
||||
op.EnviarParametorsOperacao();
|
||||
novaOp.EnviarParametorsOperacao();
|
||||
}
|
||||
|
||||
public async Task IniciarSimulacao()
|
||||
{
|
||||
if (!EhOperacaoAtual(nameof(IniciarSimulacao)))
|
||||
return;
|
||||
|
||||
var op = this;
|
||||
var dispSen = op.DispSen;
|
||||
var dispAtu = op.DispAtu;
|
||||
|
|
@ -1148,6 +1238,7 @@ namespace AgroBase.Models
|
|||
VisualWorkerService.ReiniciarLeituraAnalise();
|
||||
|
||||
op.Controle.Reiniciar();
|
||||
op.DefinirTipoMovimentoControle(TipoMovimentoDirecional.RodasDianteiras);
|
||||
op.ControleAnterior.Reiniciar();
|
||||
|
||||
op.GPSTrajetoria = new List<GPSModel>();
|
||||
|
|
@ -1159,6 +1250,9 @@ namespace AgroBase.Models
|
|||
|
||||
public void ReiniciarSimulacao()
|
||||
{
|
||||
if (!EhOperacaoAtual(nameof(ReiniciarSimulacao)))
|
||||
return;
|
||||
|
||||
this.ReiniciarOperacao(false);
|
||||
|
||||
var Topico = Variaveis.MqttServiceLocal.Topicos.FirstOrDefault(x => x.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa);
|
||||
|
|
@ -1171,6 +1265,9 @@ namespace AgroBase.Models
|
|||
|
||||
public void IniciarTreinamento()
|
||||
{
|
||||
if (!EhOperacaoAtual(nameof(IniciarTreinamento)))
|
||||
return;
|
||||
|
||||
var op = this;
|
||||
var dispSen = op.DispSen;
|
||||
var dispAtu = op.DispAtu;
|
||||
|
|
@ -1194,34 +1291,6 @@ namespace AgroBase.Models
|
|||
op.GPSTrajetoria = new List<GPSModel>();
|
||||
}
|
||||
|
||||
|
||||
private void IniciarTimerLogsOperacao()
|
||||
{
|
||||
_tmrLogsOperacao?.Stop();
|
||||
_tmrLogsOperacao?.Dispose();
|
||||
|
||||
_tmrLogsOperacao = new AsyncTaskTimerModel($"tmrLogs_{ID}", tmrLogs_Tick, 1000);
|
||||
|
||||
_tmrLogsOperacao.Start();
|
||||
|
||||
Variaveis.MostrarLog($"[OperacaoModel.IniciarTimerLogsOperacao] Timer de logs iniciado. Operacao={ID}, Hash={GetHashCode()}");
|
||||
}
|
||||
|
||||
private void PararTimerLogsOperacao()
|
||||
{
|
||||
try
|
||||
{
|
||||
_tmrLogsOperacao?.Stop();
|
||||
|
||||
Variaveis.MostrarLog($"[OperacaoModel.PararTimerLogsOperacao] Timer de logs parado. Operacao={ID}, Hash={GetHashCode()}, idxLog={idxLog}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Variaveis.MostrarLog("[OperacaoModel.PararTimerLogsOperacao] Erro ao parar timer de logs: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static string DeserializarDadosOperacao(string caminho, string arquivo)
|
||||
{
|
||||
string pastaBase = Path.GetDirectoryName(caminho) ?? "";
|
||||
|
|
@ -1279,16 +1348,32 @@ namespace AgroBase.Models
|
|||
{
|
||||
var op = this;
|
||||
|
||||
if (string.IsNullOrEmpty(op.OprPath)) return;
|
||||
if (string.IsNullOrWhiteSpace(op.ID))
|
||||
return;
|
||||
|
||||
var Caminho = Variaveis.CaminhoOperacoes + op.ID;
|
||||
if (!Directory.Exists(Caminho))
|
||||
string pastaOperacao = Path.Combine(Variaveis.CaminhoOperacoes, op.ID);
|
||||
Directory.CreateDirectory(pastaOperacao);
|
||||
|
||||
string caminhoOperacao = Path.Combine(pastaOperacao, "operacao.opr");
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(Caminho);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(op.OprPath) && File.Exists(op.OprPath))
|
||||
{
|
||||
File.Copy(op.OprPath, caminhoOperacao, overwrite: true);
|
||||
return;
|
||||
}
|
||||
|
||||
Caminho += "/operacao.opr";
|
||||
File.Copy(op.OprPath, Caminho);
|
||||
// Operação recebida da base: salva os parâmetros como .opr
|
||||
string json = JsonConvert.SerializeObject(op.Parametros, Formatting.Indented);
|
||||
File.WriteAllText(caminhoOperacao, json, Encoding.UTF8);
|
||||
|
||||
Variaveis.MostrarLog($"[OperacaoModel.SalvarOperacao] Operação salva a partir dos parâmetros. OprPath='{op.OprPath}'");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Variaveis.MostrarLog("[OperacaoModel.SalvarOperacao] Erro ao salvar operação: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1459,7 +1544,7 @@ namespace AgroBase.Models
|
|||
}
|
||||
finally
|
||||
{
|
||||
op.Controle.TipoMovimento = tipoControle;
|
||||
op.DefinirTipoMovimentoControle(tipoControle);
|
||||
|
||||
if (entrouEmCalibragem)
|
||||
{
|
||||
|
|
@ -1510,8 +1595,54 @@ namespace AgroBase.Models
|
|||
|
||||
#region CONTROLE DA OPERACAO
|
||||
|
||||
public void DefinirTipoMovimentoControle(TipoMovimentoDirecional value)
|
||||
{
|
||||
if (!EhOperacaoAtual(nameof(DefinirTipoMovimentoControle)))
|
||||
return;
|
||||
|
||||
var dispMvd = DispMvd;
|
||||
|
||||
if (dispMvd?.Dados?.Modulos != null && value != Controle.TipoMovimento)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case TipoMovimentoDirecional.RodasDianteiras:
|
||||
dispMvd.Dados.Modulos.ForEach(x =>
|
||||
{
|
||||
x.MovMotor.Comandar = true;
|
||||
x.DirMotor.Comandar = x.Modulo_ID.Contains("F");
|
||||
x.DirMotor.Angulo_SP = x.DirMotor.Comandar ? Controle.Angulo : 0;
|
||||
});
|
||||
break;
|
||||
|
||||
case TipoMovimentoDirecional.RodasTraseiras:
|
||||
dispMvd.Dados.Modulos.ForEach(x =>
|
||||
{
|
||||
x.MovMotor.Comandar = true;
|
||||
x.DirMotor.Comandar = x.Modulo_ID.Contains("T");
|
||||
x.DirMotor.Angulo_SP = x.DirMotor.Comandar ? Controle.Angulo : 0;
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
dispMvd.Dados.Modulos.ForEach(x =>
|
||||
{
|
||||
x.MovMotor.Comandar = true;
|
||||
x.DirMotor.Comandar = true;
|
||||
x.DirMotor.Angulo_SP = Controle.Angulo;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Controle.TipoMovimento = value;
|
||||
}
|
||||
|
||||
public void AtualizaInformacoesControleOperacao()
|
||||
{
|
||||
if (!EhOperacaoAtual(nameof(AtualizaInformacoesControleOperacao)))
|
||||
return;
|
||||
|
||||
var op = this;
|
||||
|
||||
var pControle = op.Parametros.Controle;
|
||||
|
|
@ -1531,6 +1662,9 @@ namespace AgroBase.Models
|
|||
|
||||
public void AtualizarDadosControle(bool ForcarEnvio, List<T_Code> Dispositivos)
|
||||
{
|
||||
if (!EhOperacaoAtual(nameof(AtualizarDadosControle)))
|
||||
return;
|
||||
|
||||
var op = this;
|
||||
|
||||
DateTime Agora = DateTime.Now;
|
||||
|
|
@ -1566,6 +1700,9 @@ namespace AgroBase.Models
|
|||
|
||||
public List<string> EnviarProtocoloComando(T_Code Tipo, bool ForcarEnvio)
|
||||
{
|
||||
if (!EhOperacaoAtual(nameof(EnviarProtocoloComando)))
|
||||
return new List<string>();
|
||||
|
||||
var op = this;
|
||||
|
||||
if (!op.Sensoriamento.Operacao.OperacaoIniciada && !ForcarEnvio)
|
||||
|
|
@ -1641,19 +1778,20 @@ namespace AgroBase.Models
|
|||
case T_Code.Atu:
|
||||
{
|
||||
op.DispAtu?.Dados?.SincronizarBombaPressurizadoraAutomatica();
|
||||
var bicos = op.DispAtu?.Dados?.BicosPulverizadores ?? new List<AtuadorBicoModel>();
|
||||
|
||||
for (int i = 0; i < _Controle.Bicos.Count; i++)
|
||||
for (int i = 0; i < bicos.Count; i++)
|
||||
{
|
||||
Estado comandoEstado = _Controle.Bicos[i].ComandoAtuar ? Estado.Ligado : Estado.Desligado;
|
||||
if (ForcarEnvio || comandoEstado != _Controle.Bicos[i]._EstadoLeitura)
|
||||
Estado comandoEstado = bicos[i].ComandoAtuar ? Estado.Ligado : Estado.Desligado;
|
||||
if (ForcarEnvio || comandoEstado != bicos[i]._EstadoLeitura)
|
||||
{
|
||||
GeneralJoystick.EnviarComandoAtuador(_Controle.Bicos[i].Componente, _Controle.Bicos[i].ID, Status: _Controle.Bicos[i].ComandoAtuar);
|
||||
GeneralJoystick.EnviarComandoAtuador(bicos[i].Componente, bicos[i].ID, Status: bicos[i].ComandoAtuar);
|
||||
}
|
||||
}
|
||||
|
||||
Protocolos = new List<string>()
|
||||
{
|
||||
string.Join(";", _Controle.Bicos.Select(x => x.ComandoAtuar ? "1" : "0")) + ";" + (ForcarEnvio ? "1": "0")
|
||||
string.Join(";", bicos.Select(x => x.ComandoAtuar ? "1" : "0")) + ";" + (ForcarEnvio ? "1": "0")
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
|
@ -1664,11 +1802,22 @@ namespace AgroBase.Models
|
|||
return Protocolos;
|
||||
}
|
||||
|
||||
|
||||
private async Task tmrLeituras_Tick()
|
||||
{
|
||||
if (Variaveis.IsAgroMonitor)
|
||||
if (!Variaveis.IsAgroBase)
|
||||
return;
|
||||
|
||||
if (!ReferenceEquals(Variaveis.OperacaoEmAndamento, this))
|
||||
{
|
||||
Variaveis.MostrarLog(
|
||||
$"[OperacaoModel.{nameof(tmrLeituras_Tick)}] Timer órfão ignorado. " +
|
||||
$"TimerHash={GetHashCode()}, AtualHash={Variaveis.OperacaoEmAndamento?.GetHashCode()}"
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var op = this;
|
||||
|
||||
op.Sensoriamento?.AtualizarDados();
|
||||
|
|
@ -1707,10 +1856,21 @@ namespace AgroBase.Models
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async Task tmrComunicacao_Tick()
|
||||
{
|
||||
if (!Variaveis.IsAgroBase)
|
||||
return;
|
||||
|
||||
if (!ReferenceEquals(Variaveis.OperacaoEmAndamento, this))
|
||||
{
|
||||
Variaveis.MostrarLog(
|
||||
$"[OperacaoModel.{nameof(tmrComunicacao_Tick)}] Timer órfão ignorado. " +
|
||||
$"TimerHash={GetHashCode()}, AtualHash={Variaveis.OperacaoEmAndamento?.GetHashCode()}"
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var service = Variaveis.MqttServiceBase;
|
||||
|
||||
if (service == null)
|
||||
|
|
@ -1788,9 +1948,9 @@ namespace AgroBase.Models
|
|||
// CAMPOS
|
||||
// ============================================================================
|
||||
|
||||
private readonly SemaphoreSlim _baseCommandGate = new SemaphoreSlim(1, 1);
|
||||
private readonly object _baseCommandDedupeLock = new object();
|
||||
private readonly Dictionary<string, DateTime> _baseCommandDedupe = new Dictionary<string, DateTime>();
|
||||
private static readonly SemaphoreSlim _baseCommandGate = new SemaphoreSlim(1, 1);
|
||||
private static readonly object _baseCommandDedupeLock = new object();
|
||||
private static readonly Dictionary<string, DateTime> _baseCommandDedupe = new Dictionary<string, DateTime>();
|
||||
private static readonly TimeSpan BaseCommandDedupeWindow = TimeSpan.FromMilliseconds(1500);
|
||||
|
||||
|
||||
|
|
@ -1859,14 +2019,34 @@ namespace AgroBase.Models
|
|||
|
||||
public async Task ExecutaComandoDaBaseAsync(OperacaoComandoBaseModel controleBase)
|
||||
{
|
||||
var op = this;
|
||||
|
||||
if (controleBase == null)
|
||||
return;
|
||||
|
||||
if (Variaveis.Fechando)
|
||||
return;
|
||||
|
||||
var opAtual = Variaveis.OperacaoEmAndamento;
|
||||
|
||||
if (opAtual == null)
|
||||
{
|
||||
Variaveis.MostrarLog("[OperacaoModel.ExecutaComandoDaBaseAsync] Ignorado: não existe OperacaoEmAndamento.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ReferenceEquals(this, opAtual))
|
||||
{
|
||||
Variaveis.MostrarLog(
|
||||
$"[OperacaoModel.ExecutaComandoDaBaseAsync] Comando recebido por instância antiga. " +
|
||||
$"ReceiverHash={GetHashCode()}, AtualHash={opAtual.GetHashCode()}, " +
|
||||
$"Cmd={controleBase.Dispositivo}/{controleBase.Tecla}. Redirecionando."
|
||||
);
|
||||
|
||||
await opAtual.ExecutaComandoDaBaseAsync(controleBase).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var op = opAtual;
|
||||
|
||||
if (op.EhComandoDuplicado(controleBase))
|
||||
return;
|
||||
|
||||
|
|
@ -1874,22 +2054,14 @@ namespace AgroBase.Models
|
|||
|
||||
try
|
||||
{
|
||||
/*
|
||||
* Comando remoto é rota crítica.
|
||||
* Processar em série evita:
|
||||
* - iniciar e finalizar operação ao mesmo tempo;
|
||||
* - atualizar parâmetros enquanto inicia operação;
|
||||
* - dois comandos de atuador disputando o mesmo estado local.
|
||||
*/
|
||||
await _baseCommandGate.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
entered = true;
|
||||
|
||||
await op.ExecutaComandoDaBaseInternoAsync(controleBase).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Variaveis.MostrarLog("[ComandoBase] Erro ao executar comando: " + ex);
|
||||
Variaveis.MostrarLog("[OperacaoModel.ExecutaComandoDaBaseAsync] Erro ao executar comando: " + ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
@ -1962,6 +2134,14 @@ namespace AgroBase.Models
|
|||
|
||||
private async Task ExecutarComandoModuloAsync(OperacaoComandoBaseModel controleBase, OperacaoModel op)
|
||||
{
|
||||
op = Variaveis.OperacaoEmAndamento;
|
||||
|
||||
if (op == null)
|
||||
return;
|
||||
|
||||
if (!ReferenceEquals(Variaveis.OperacaoEmAndamento, op))
|
||||
return;
|
||||
|
||||
var parametros = controleBase.Parametros;
|
||||
|
||||
switch (controleBase.Tecla)
|
||||
|
|
@ -1974,19 +2154,17 @@ namespace AgroBase.Models
|
|||
if (parametros == null)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Carga completa de parâmetros. Idealmente só antes
|
||||
* da operação estar iniciada.
|
||||
*/
|
||||
if (op.Sensoriamento.Operacao.OperacaoIniciada)
|
||||
if (Variaveis.OperacaoEmAndamento?.Sensoriamento?.Operacao?.OperacaoIniciada == true)
|
||||
{
|
||||
Variaveis.MostrarLog("[ComandoBase] Ignorando carga completa de parâmetros com operação iniciada.");
|
||||
Variaveis.MostrarLog("[OperacaoModel.ExecutarComandoModuloAsync] Ignorando carga completa de parâmetros com operação iniciada.");
|
||||
return;
|
||||
}
|
||||
|
||||
op.CarregarParamerosOperacaoBase(parametros);
|
||||
var novaOp = CarregarParamerosOperacaoBase(parametros);
|
||||
|
||||
if (novaOp != null)
|
||||
await novaOp.EnviarParametrosOperacaoAsync().ConfigureAwait(false);
|
||||
|
||||
await op.EnviarParametrosOperacaoAsync().ConfigureAwait(false);
|
||||
return;
|
||||
|
||||
case BotoesJoystick.Touchpad:
|
||||
|
|
@ -2200,7 +2378,7 @@ namespace AgroBase.Models
|
|||
|
||||
if (TryDeserializeValue(controleBase._comp_value, out angulo))
|
||||
{
|
||||
var bico = op.Controle.Bicos.FirstOrDefault(x => x.ID == controleBase._comp_id);
|
||||
var bico = dadosAtu.BicosPulverizadores?.FirstOrDefault(x => x.ID == controleBase._comp_id);
|
||||
|
||||
if (bico != null)
|
||||
bico.AnguloAbertura = angulo;
|
||||
|
|
@ -2367,7 +2545,7 @@ namespace AgroBase.Models
|
|||
controle.Angulo = (double)controleBase.Controle.AnguloSP;
|
||||
|
||||
if (controleBase.Controle.TipoMovimentoDirecional != null)
|
||||
controle.TipoMovimento = (TipoMovimentoDirecional)controleBase.Controle.TipoMovimentoDirecional;
|
||||
op.DefinirTipoMovimentoControle((TipoMovimentoDirecional)controleBase.Controle.TipoMovimentoDirecional);
|
||||
|
||||
if (controleBase.Controle.EmFreio != null)
|
||||
controle.EmFreio = (bool)controleBase.Controle.EmFreio;
|
||||
|
|
@ -2660,7 +2838,7 @@ namespace AgroBase.Models
|
|||
{
|
||||
Variaveis.MostrarLog($"[OperacaoModel.tmrLogs_Tick] Timer órfão parado. TimerHash={GetHashCode()}, OperacaoTimer={ID}, OperacaoAtual={Variaveis.OperacaoEmAndamento?.ID}");
|
||||
|
||||
PararTimerLogsOperacao();
|
||||
_tmrLogsOperacao?.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3246,57 +3424,8 @@ namespace AgroBase.Models
|
|||
}
|
||||
}
|
||||
public bool EmFreio { get; set; } = false;
|
||||
//public Direcao Direcao { get; set; } = Direcao.Parado;
|
||||
[JsonIgnore]
|
||||
public List<AtuadorBicoModel> Bicos => Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.BicosPulverizadores;
|
||||
public double AlturaBarra { get; set; }
|
||||
private TipoMovimentoDirecional _tipoMovimento = TipoMovimentoDirecional.Diagnostico;
|
||||
public TipoMovimentoDirecional TipoMovimento
|
||||
{
|
||||
get
|
||||
{
|
||||
return _tipoMovimento;
|
||||
}
|
||||
set
|
||||
{
|
||||
var DispMvd = Variaveis.OperacaoEmAndamento.DispMvd;
|
||||
if (DispMvd != null)
|
||||
{
|
||||
if (value != _tipoMovimento)
|
||||
{
|
||||
var _Controle = Variaveis.OperacaoEmAndamento.Controle;
|
||||
switch (value)
|
||||
{
|
||||
case TipoMovimentoDirecional.RodasDianteiras:
|
||||
DispMvd.Dados.Modulos.ForEach(x =>
|
||||
{
|
||||
x.MovMotor.Comandar = true;
|
||||
x.DirMotor.Comandar = x.Modulo_ID.Contains("F");
|
||||
x.DirMotor.Angulo_SP = x.DirMotor.Comandar ? _Controle.Angulo : 0;
|
||||
});
|
||||
break;
|
||||
case TipoMovimentoDirecional.RodasTraseiras:
|
||||
DispMvd.Dados.Modulos.ForEach(x =>
|
||||
{
|
||||
x.MovMotor.Comandar = true;
|
||||
x.DirMotor.Comandar = x.Modulo_ID.Contains("T");
|
||||
x.DirMotor.Angulo_SP = x.DirMotor.Comandar ? _Controle.Angulo : 0;
|
||||
});
|
||||
break;
|
||||
default:
|
||||
DispMvd.Dados.Modulos.ForEach(x =>
|
||||
{
|
||||
x.MovMotor.Comandar = true;
|
||||
x.DirMotor.Comandar = true;
|
||||
x.DirMotor.Angulo_SP = _Controle.Angulo;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_tipoMovimento = value;
|
||||
}
|
||||
}
|
||||
public TipoMovimentoDirecional TipoMovimento { get; set; } = TipoMovimentoDirecional.Diagnostico;
|
||||
public List<OperacaoControleTipoModel> TiposControle { get; set; } = new List<OperacaoControleTipoModel>();
|
||||
public List<MPCSimulacaoModel> SimulacaoMPC { get; set; } = new List<MPCSimulacaoModel>();
|
||||
public double Latencia { get; set; }
|
||||
|
|
@ -3306,11 +3435,9 @@ namespace AgroBase.Models
|
|||
|
||||
public void Reiniciar()
|
||||
{
|
||||
var _Parametros = Variaveis.OperacaoEmAndamento.Parametros.Controle;
|
||||
PercentualVelocidadeSP = 0; // _Parametros.MovimentoAutomatico ? 0 : _Parametros.MovVelocidadeCErvasPercent;
|
||||
Angulo = 0; // _Parametros.DirecionalAutomatico ? 0 : _Parametros.DirAnguloMaximo;
|
||||
PercentualVelocidadeSP = 0;
|
||||
Angulo = 0;
|
||||
EmFreio = false;
|
||||
TipoMovimento = TipoMovimentoDirecional.RodasDianteiras;
|
||||
TiposControle.ForEach(x =>
|
||||
{
|
||||
x.DirecaoAtual = Direcao.Parado;
|
||||
|
|
@ -3348,8 +3475,6 @@ namespace AgroBase.Models
|
|||
Motivos = new List<string>(Motivos ?? new List<string>())
|
||||
};
|
||||
|
||||
clone._tipoMovimento = _tipoMovimento;
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
|
@ -3472,6 +3597,7 @@ namespace AgroBase.Models
|
|||
OperacaoLiberada = RedisService.GetField(CtxKey.DadosOperacao, "liberado", false),
|
||||
OperacaoConfigurada = RedisService.GetField(CtxKey.DadosOperacao, "configurado", false),
|
||||
ErroOperacaoLiberada = RedisService.GetField<string>(CtxKey.DadosOperacao, "motivo_nao_liberado"),
|
||||
OperacaoLiberacaoDebug = RedisService.GetField<JObject>(CtxKey.DadosOperacao, "operacao_liberacao_debug"),
|
||||
StatusOperacaoAtual = (StatusOperacao)RedisService.GetField<int>(CtxKey.DadosOperacao, "status", 0),
|
||||
TempoAguardandoSeg = RedisService.GetField<long>(CtxKey.DadosOperacao, "tempo_aguardando", 0),
|
||||
|
||||
|
|
@ -3490,7 +3616,7 @@ namespace AgroBase.Models
|
|||
|
||||
var saude = OperadorSaude.ModulosSaude;
|
||||
var saudeAnterior = new List<ManagerWorkerMessageResponseModulosPendentesModel>(saude ?? new List<ManagerWorkerMessageResponseModulosPendentesModel>());
|
||||
saude = RedisService.GetField<ManagerWorkerMessageResponseModulosPendentesModel[]>(CtxKey.DadosOperacao, "status_modulos").ToList();
|
||||
saude = RedisService.GetField<ManagerWorkerMessageResponseModulosPendentesModel[]>(CtxKey.DadosOperacao, "status_modulos")?.ToList() ?? new List<ManagerWorkerMessageResponseModulosPendentesModel>();
|
||||
|
||||
foreach (var mod in saude)
|
||||
{
|
||||
|
|
@ -4544,7 +4670,7 @@ namespace AgroBase.Models
|
|||
{
|
||||
if (op == null) return;
|
||||
|
||||
HealthWorkerService.DadosLeitura.ModulosSaude = RedisService.GetField<ManagerWorkerMessageResponseModulosPendentesModel[]>(CtxKey.DadosOperacao, "status_modulos").ToList();
|
||||
HealthWorkerService.DadosLeitura.ModulosSaude = RedisService.GetField<ManagerWorkerMessageResponseModulosPendentesModel[]>(CtxKey.DadosOperacao, "status_modulos")?.ToList() ?? new List<ManagerWorkerMessageResponseModulosPendentesModel>();
|
||||
OperadorSaude = HealthWorkerService.DadosLeitura.Clone();
|
||||
OperadorSaude.Momento = agora;
|
||||
OperadorVisual = VisualWorkerService.DadosLeitura.Clone();
|
||||
|
|
@ -4743,6 +4869,7 @@ namespace AgroBase.Models
|
|||
public StatusOperacao StatusOperacaoAtual { get; set; }
|
||||
public StatusOperacao StatusOperacaoAnterior { get; set; }
|
||||
public string ErroOperacaoLiberada { get; set; }
|
||||
public JObject OperacaoLiberacaoDebug { get; set; }
|
||||
public bool OperacaoConfigurada { get; set; }
|
||||
public bool OperacaoLiberada { get; set; }
|
||||
public bool OperacaoIniciada { get; set; }
|
||||
|
|
@ -4779,6 +4906,7 @@ namespace AgroBase.Models
|
|||
ControleAutomatico = ControleAutomatico,
|
||||
Status = Status,
|
||||
ErroOperacaoLiberada = ErroOperacaoLiberada,
|
||||
OperacaoLiberacaoDebug = OperacaoLiberacaoDebug,
|
||||
OperacaoConfigurada = OperacaoConfigurada,
|
||||
OperacaoLiberada = OperacaoLiberada,
|
||||
OperacaoIniciada = OperacaoIniciada,
|
||||
|
|
|
|||
|
|
@ -968,12 +968,12 @@ namespace AgroBase.Models.Operacoes
|
|||
|
||||
private void AtualizarMovimentacao(OperacaoSensoriamentoConjuntoModel sen)
|
||||
{
|
||||
Movimentacao = sen.Movimentacao?.Clone();
|
||||
Movimentacao = sen?.Movimentacao?.Clone();
|
||||
}
|
||||
|
||||
private void AtualizarDirecional(OperacaoSensoriamentoConjuntoModel sen)
|
||||
{
|
||||
Direcional = sen.Direcional?.Clone();
|
||||
Direcional = sen?.Direcional?.Clone();
|
||||
}
|
||||
|
||||
private void AtualizarGnss(OperacaoSensoriamentoConjuntoModel sen)
|
||||
|
|
@ -1049,8 +1049,8 @@ namespace AgroBase.Models.Operacoes
|
|||
Imu = Imu?.Clone(),
|
||||
Atuador = CloneAtuador(Atuador),
|
||||
Sensoriamento = CloneSensoriamento(Sensoriamento),
|
||||
Movimentacao = Movimentacao.Clone(),
|
||||
Direcional = Direcional.Clone(),
|
||||
Movimentacao = Movimentacao?.Clone(),
|
||||
Direcional = Direcional?.Clone(),
|
||||
|
||||
Bateria = Bateria?.Clone(),
|
||||
Refrigeracao = Refrigeracao?.Clone(),
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ namespace AgroBase.Models
|
|||
{
|
||||
public class Variaveis
|
||||
{
|
||||
public static bool Producao { get; set; } = false;
|
||||
public static readonly bool IniciarWorkers = true;
|
||||
public static readonly bool Producao = false;
|
||||
public static bool DebugMode { get; set; } = true;
|
||||
public static bool Fechando { get; set; } = false;
|
||||
|
||||
|
|
@ -57,11 +58,35 @@ namespace AgroBase.Models
|
|||
public static string CaminhoParametros { get; } = "Parametros/";
|
||||
public static string CaminhoModelos { get; } = "C:\\AgroBaseModels\\";
|
||||
public static List<IDispositivosService> DispositivosConectados { get; set; } = new List<IDispositivosService>();
|
||||
public static OperacaoModel OperacaoEmAndamento { get; set; } = new OperacaoModel();
|
||||
public static MqttService MqttServiceLocal { get; private set; }
|
||||
public static MqttService MqttServiceBaseCritical { get; private set; }
|
||||
public static MqttService MqttServiceBaseTelemetry { get; private set; }
|
||||
|
||||
private static readonly object _opLock = new object();
|
||||
private static OperacaoModel _op;
|
||||
public static OperacaoModel OperacaoEmAndamento
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_opLock)
|
||||
return _op;
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (_opLock)
|
||||
{
|
||||
if (ReferenceEquals(_op, value))
|
||||
return;
|
||||
|
||||
_op?.PararTimersSistema();
|
||||
|
||||
_op = value;
|
||||
|
||||
_op?.IniciarTimersSistema();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compatibilidade temporária com o restante do projeto.
|
||||
/// Publicações antigas feitas por MqttServiceBase seguem pelo canal
|
||||
|
|
@ -105,16 +130,11 @@ namespace AgroBase.Models
|
|||
// return OperacaoEmAndamento.DispSen?.Dados?.LoRaParametrosBase;
|
||||
// }
|
||||
//}
|
||||
public static string FaixaIPwifi { get; set; } = "192.168.100";
|
||||
public static string FaixaIPethernet { get; set; } = "192.168.105";
|
||||
public static string IP_Host { get; set; } = FaixaIPwifi + ".105";
|
||||
public static string NomeRedeWifiEquipamento { get; set; } = "Agrobot";
|
||||
public static string SenhaRedeWifiEquipamento { get; set; } = "4321agro";
|
||||
public static bool IsAgroMonitor
|
||||
public static bool IsAgroBase
|
||||
{
|
||||
get
|
||||
{
|
||||
return CaminhoSistema.Contains("AgroMonitor");
|
||||
return CaminhoSistema.Contains("AgroBase");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ namespace AgroBase.Services
|
|||
// Inicializa o serviço Ethernet com IP e porta específicos
|
||||
public static async Task<bool> InicializarEthernetService()
|
||||
{
|
||||
string ipAddress = Variaveis.OperacaoEmAndamento.DispMvd.Dados.IP_Mov;
|
||||
string ipAddress = ""; // Variaveis.OperacaoEmAndamento.DispMvd.Dados.IP_Mov;
|
||||
int port = VariaveisPortas.Ethernet_TCP;
|
||||
|
||||
_ethernetService?.Disconnect();
|
||||
|
|
|
|||
|
|
@ -598,7 +598,7 @@ public class EthernetService
|
|||
_Interface = _Interface.Split('(')[0].Trim();
|
||||
string gateway = ObterIpGateway(_Interface);
|
||||
string ipAtual = ObterIpAtual(_Interface);
|
||||
string ip = Variaveis.IP_Host;
|
||||
string ip = VariaveisEquipamento.Parametros.rover_ip;
|
||||
string submask = ObterSubnetMaskAtual(_Interface);
|
||||
|
||||
if (fixo)
|
||||
|
|
|
|||
|
|
@ -85,20 +85,11 @@ namespace AgroBase.Services
|
|||
private static readonly object _workerLock = new object();
|
||||
private static readonly object _portLifecycleLock = new object();
|
||||
|
||||
private static readonly SemaphoreSlim _serialWriteLock =
|
||||
new SemaphoreSlim(1, 1);
|
||||
|
||||
private static readonly SemaphoreSlim _configurationLock =
|
||||
new SemaphoreSlim(1, 1);
|
||||
|
||||
private static readonly SemaphoreSlim _rtcmSignal =
|
||||
new SemaphoreSlim(0, int.MaxValue);
|
||||
|
||||
private static readonly SemaphoreSlim _logSignal =
|
||||
new SemaphoreSlim(0, int.MaxValue);
|
||||
|
||||
private static readonly SemaphoreSlim _localPublishSignal =
|
||||
new SemaphoreSlim(0, int.MaxValue);
|
||||
private static readonly SemaphoreSlim _serialWriteLock = new SemaphoreSlim(1, 1);
|
||||
private static readonly SemaphoreSlim _configurationLock = new SemaphoreSlim(1, 1);
|
||||
private static readonly SemaphoreSlim _rtcmSignal = new SemaphoreSlim(0, int.MaxValue);
|
||||
private static readonly SemaphoreSlim _logSignal = new SemaphoreSlim(0, int.MaxValue);
|
||||
private static readonly SemaphoreSlim _localPublishSignal = new SemaphoreSlim(0, int.MaxValue);
|
||||
|
||||
private static CancellationTokenSource _serviceCts;
|
||||
private static Task _nmeaWorkerTask;
|
||||
|
|
@ -118,20 +109,16 @@ namespace AgroBase.Services
|
|||
// BUFFERS E FILAS
|
||||
// ============================================================
|
||||
|
||||
private static readonly StringBuilder _nmeaBuffer =
|
||||
new StringBuilder(8192);
|
||||
private static readonly StringBuilder _nmeaBuffer = new StringBuilder(8192);
|
||||
|
||||
private const int MaxNmeaBufferChars = 64 * 1024;
|
||||
|
||||
private static readonly object _nmeaQueueLock = new object();
|
||||
private static readonly Queue<string> _nmeaQueue =
|
||||
new Queue<string>();
|
||||
private static readonly SemaphoreSlim _nmeaSignal =
|
||||
new SemaphoreSlim(0, int.MaxValue);
|
||||
private static readonly Queue<string> _nmeaQueue = new Queue<string>();
|
||||
private static readonly SemaphoreSlim _nmeaSignal = new SemaphoreSlim(0, int.MaxValue);
|
||||
private const int NmeaQueueCapacity = 512;
|
||||
|
||||
private static readonly Queue<RtcmEnvelope> _rtcmQueue =
|
||||
new Queue<RtcmEnvelope>();
|
||||
private static readonly Queue<RtcmEnvelope> _rtcmQueue = new Queue<RtcmEnvelope>();
|
||||
|
||||
private const int RtcmQueueCapacity = 48;
|
||||
private const int RtcmMaxAgeMs = 2500;
|
||||
|
|
@ -139,12 +126,10 @@ namespace AgroBase.Services
|
|||
|
||||
private static long _rtcmSequence;
|
||||
|
||||
private static readonly ConcurrentQueue<string> _gpsLogQueue =
|
||||
new ConcurrentQueue<string>();
|
||||
private static readonly ConcurrentQueue<string> _gpsLogQueue = new ConcurrentQueue<string>();
|
||||
|
||||
private static readonly object _localPublishLock = new object();
|
||||
private static readonly Dictionary<string, string> _localLatestPayload =
|
||||
new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
private static readonly Dictionary<string, string> _localLatestPayload = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
|
||||
// ============================================================
|
||||
// MÉTRICAS
|
||||
|
|
@ -291,7 +276,7 @@ namespace AgroBase.Services
|
|||
if (generation != Interlocked.Read(ref _portGeneration))
|
||||
return;
|
||||
|
||||
if (!Variaveis.IsAgroMonitor && CorrecaoRTK_Ntrip)
|
||||
if (Variaveis.IsAgroBase && CorrecaoRTK_Ntrip)
|
||||
await IniciarNtripAsync().ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -366,12 +351,7 @@ namespace AgroBase.Services
|
|||
).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task ConfigurarModuloRover(
|
||||
string porta_usb = "com3",
|
||||
string porta_entrada = "com2",
|
||||
int comprimento_antena = 100,
|
||||
int tolerancia_antena = 5,
|
||||
CancellationToken cancellationToken = default(CancellationToken))
|
||||
private static async Task ConfigurarModuloRover(string porta_usb = "com3", string porta_entrada = "com2", int comprimento_antena = 100, int tolerancia_antena = 5, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
await _configurationLock.WaitAsync(cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
|
@ -464,14 +444,9 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
private static async Task ConfigurarModuloBase(
|
||||
string porta_usb = "com3",
|
||||
string porta_saida = "com2",
|
||||
int tempo_fixacao = 60,
|
||||
CancellationToken cancellationToken = default(CancellationToken))
|
||||
private static async Task ConfigurarModuloBase(string porta_usb = "com3", string porta_saida = "com2", int tempo_fixacao = 60, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
await _configurationLock.WaitAsync(cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
await _configurationLock.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
Interlocked.Increment(ref _configurationRuns);
|
||||
|
||||
|
|
@ -537,9 +512,7 @@ namespace AgroBase.Services
|
|||
// RECEPÇÃO SERIAL / NMEA
|
||||
// ============================================================
|
||||
|
||||
private static void PortaGPS_DataReceived(
|
||||
object sender,
|
||||
SerialDataReceivedEventArgs e)
|
||||
private static void PortaGPS_DataReceived(object sender, SerialDataReceivedEventArgs e)
|
||||
{
|
||||
SerialPort porta = sender as SerialPort;
|
||||
|
||||
|
|
@ -599,8 +572,7 @@ namespace AgroBase.Services
|
|||
catch (SemaphoreFullException) { }
|
||||
}
|
||||
|
||||
private static async Task NmeaWorkerLoopAsync(
|
||||
CancellationToken cancellationToken)
|
||||
private static async Task NmeaWorkerLoopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
|
|
@ -638,8 +610,7 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
private static List<string> ExtrairSentencasCompletas(
|
||||
string recebido)
|
||||
private static List<string> ExtrairSentencasCompletas(string recebido)
|
||||
{
|
||||
var resultado = new List<string>();
|
||||
|
||||
|
|
@ -1487,14 +1458,9 @@ namespace AgroBase.Services
|
|||
// RTCM VIA MQTT / FILA DE ESCRITA
|
||||
// ============================================================
|
||||
|
||||
public static void AplicarCorrecaoRTK_Mqtt(
|
||||
byte[] correcao,
|
||||
int bytesRead)
|
||||
public static void AplicarCorrecaoRTK_Mqtt(byte[] correcao, int bytesRead)
|
||||
{
|
||||
if (correcao == null ||
|
||||
bytesRead <= 0 ||
|
||||
bytesRead > correcao.Length ||
|
||||
bytesRead > RtcmMaxPayloadBytes)
|
||||
if (correcao == null || bytesRead <= 0 || bytesRead > correcao.Length || bytesRead > RtcmMaxPayloadBytes)
|
||||
{
|
||||
Interlocked.Increment(ref _rtcmDroppedInvalid);
|
||||
return;
|
||||
|
|
@ -1506,9 +1472,7 @@ namespace AgroBase.Services
|
|||
EnfileirarRtcm(copia, RtcmSource.Mqtt);
|
||||
}
|
||||
|
||||
private static void EnfileirarRtcm(
|
||||
byte[] bytes,
|
||||
RtcmSource source)
|
||||
private static void EnfileirarRtcm(byte[] bytes, RtcmSource source)
|
||||
{
|
||||
EnsureBackgroundWorkersStarted();
|
||||
|
||||
|
|
@ -1547,8 +1511,7 @@ namespace AgroBase.Services
|
|||
catch (SemaphoreFullException) { }
|
||||
}
|
||||
|
||||
private static async Task RtcmWriterLoopAsync(
|
||||
CancellationToken cancellationToken)
|
||||
private static async Task RtcmWriterLoopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
|
|
@ -1684,8 +1647,7 @@ namespace AgroBase.Services
|
|||
|
||||
public static async Task IniciarNtripAsync()
|
||||
{
|
||||
if (Variaveis.IsAgroMonitor ||
|
||||
!CorrecaoRTK_Ntrip)
|
||||
if (!Variaveis.IsAgroBase || !CorrecaoRTK_Ntrip)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -1756,12 +1718,9 @@ namespace AgroBase.Services
|
|||
cts.Dispose();
|
||||
}
|
||||
|
||||
private static async Task AplicarCorrecaoRTK_Ntrip(
|
||||
CancellationToken cancellationToken)
|
||||
private static async Task AplicarCorrecaoRTK_Ntrip(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!Iniciado ||
|
||||
LoopRTK_Ntrip ||
|
||||
!APIService.HasInternet)
|
||||
if (!Iniciado || LoopRTK_Ntrip || !APIService.HasInternet)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -2003,10 +1962,7 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
private static async Task<NtripHeaderResult>
|
||||
ReadNtripHeaderAsync(
|
||||
NetworkStream stream,
|
||||
CancellationToken cancellationToken)
|
||||
private static async Task<NtripHeaderResult> ReadNtripHeaderAsync(NetworkStream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
var bytes = new List<byte>(2048);
|
||||
byte[] buffer = new byte[512];
|
||||
|
|
@ -2112,8 +2068,7 @@ namespace AgroBase.Services
|
|||
return PenultimaLeitura.Clone();
|
||||
}
|
||||
|
||||
private static bool PossuiHeadingValido(
|
||||
GPSModel leitura)
|
||||
private static bool PossuiHeadingValido(GPSModel leitura)
|
||||
{
|
||||
if (leitura == null)
|
||||
return false;
|
||||
|
|
@ -2161,6 +2116,9 @@ namespace AgroBase.Services
|
|||
|
||||
public static void AtualizarCoordenadasGPS()
|
||||
{
|
||||
if (!Variaveis.IsAgroBase)
|
||||
return;
|
||||
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
|
||||
PenultimaLeitura.Ntrip_ativado = UltimaLeitura.Ntrip_ativado;
|
||||
|
|
@ -2173,9 +2131,6 @@ namespace AgroBase.Services
|
|||
UltimaLeitura.LeverArmFrontal = LeverArm != null ? LeverArm.FrontalTotalCm : 0;
|
||||
UltimaLeitura.LeverArmLateral = LeverArm != null ? LeverArm.LateralTotalCm : 0;
|
||||
|
||||
if (Variaveis.IsAgroMonitor)
|
||||
return;
|
||||
|
||||
UltimasLeituras.Add(UltimaLeitura.Clone());
|
||||
|
||||
while (UltimasLeituras.Count > Math.Max(1, TaxaAmostragemHz))
|
||||
|
|
@ -2548,27 +2503,14 @@ namespace AgroBase.Services
|
|||
UltimaLeitura.AnguloCarroDefinido = anguloFinal;
|
||||
}
|
||||
|
||||
public static double FundirHeadingComMovimento(
|
||||
double headingDeg,
|
||||
double angMovDeg,
|
||||
double distLinearJanela,
|
||||
double velPercent = 0.0,
|
||||
bool rtkFix = true,
|
||||
double angFundidoAnterior = double.NaN,
|
||||
double alfaLowPass = 0.25)
|
||||
public static double FundirHeadingComMovimento(double headingDeg, double angMovDeg, double distLinearJanela, double velPercent = 0.0, bool rtkFix = true, double angFundidoAnterior = double.NaN, double alfaLowPass = 0.25)
|
||||
{
|
||||
double distMin = 0.03;
|
||||
double distFull = 0.25;
|
||||
double pesoMinHeading = 0.30;
|
||||
double fatorConfMovSemFix = 0.80;
|
||||
|
||||
double fd = Smoothstep(
|
||||
Norm(
|
||||
distLinearJanela,
|
||||
distMin,
|
||||
distFull
|
||||
)
|
||||
);
|
||||
double fd = Smoothstep(Norm(distLinearJanela, distMin, distFull));
|
||||
|
||||
double fv =
|
||||
FuncoesMatematicas.Clamp(
|
||||
|
|
@ -2612,10 +2554,7 @@ namespace AgroBase.Services
|
|||
return Normalize0To360(angMisto);
|
||||
}
|
||||
|
||||
private static double Norm(
|
||||
double value,
|
||||
double min,
|
||||
double max)
|
||||
private static double Norm(double value, double min, double max)
|
||||
{
|
||||
if (max <= min)
|
||||
return value >= max ? 1.0 : 0.0;
|
||||
|
|
@ -2639,10 +2578,7 @@ namespace AgroBase.Services
|
|||
return x * x * (3.0 - 2.0 * x);
|
||||
}
|
||||
|
||||
private static double MisturarAngulosCircular(
|
||||
double aDeg,
|
||||
double bDeg,
|
||||
double pesoA)
|
||||
private static double MisturarAngulosCircular(double aDeg, double bDeg, double pesoA)
|
||||
{
|
||||
double a = aDeg * Math.PI / 180.0;
|
||||
double b = bDeg * Math.PI / 180.0;
|
||||
|
|
@ -2659,23 +2595,14 @@ namespace AgroBase.Services
|
|||
180.0 / Math.PI;
|
||||
}
|
||||
|
||||
private static double LowPassAngle0to360(
|
||||
double atualDeg,
|
||||
double novoDeg,
|
||||
double alfa)
|
||||
private static double LowPassAngle0to360(double atualDeg, double novoDeg, double alfa)
|
||||
{
|
||||
double diff =
|
||||
NormalizeSigned180(
|
||||
novoDeg - atualDeg
|
||||
);
|
||||
double diff = NormalizeSigned180(novoDeg - atualDeg);
|
||||
|
||||
return Normalize0To360(
|
||||
atualDeg + alfa * diff
|
||||
);
|
||||
return Normalize0To360(atualDeg + alfa * diff);
|
||||
}
|
||||
|
||||
private static double NormalizeSigned180(
|
||||
double angDeg)
|
||||
private static double NormalizeSigned180(double angDeg)
|
||||
{
|
||||
angDeg = (angDeg + 180.0) % 360.0;
|
||||
|
||||
|
|
@ -2685,8 +2612,7 @@ namespace AgroBase.Services
|
|||
return angDeg - 180.0;
|
||||
}
|
||||
|
||||
private static double Normalize0To360(
|
||||
double angDeg)
|
||||
private static double Normalize0To360(double angDeg)
|
||||
{
|
||||
angDeg %= 360.0;
|
||||
|
||||
|
|
@ -2702,7 +2628,7 @@ namespace AgroBase.Services
|
|||
{
|
||||
GPSModel posicaoAtual;
|
||||
|
||||
if (Variaveis.OperacaoEmAndamento.Simulando)
|
||||
if (Variaveis.OperacaoEmAndamento?.Simulando == true)
|
||||
{
|
||||
lock (_stateLock)
|
||||
{
|
||||
|
|
@ -2835,8 +2761,7 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
private static async Task LogWriterLoopAsync(
|
||||
CancellationToken cancellationToken)
|
||||
private static async Task LogWriterLoopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var lote = new List<string>(300);
|
||||
|
||||
|
|
@ -3064,8 +2989,7 @@ namespace AgroBase.Services
|
|||
// MÉTRICAS
|
||||
// ============================================================
|
||||
|
||||
public static GpsTransportMetrics
|
||||
GetTransportMetrics()
|
||||
public static GpsTransportMetrics GetTransportMetrics()
|
||||
{
|
||||
int queueDepth;
|
||||
int nmeaQueueDepth;
|
||||
|
|
@ -3236,9 +3160,7 @@ namespace AgroBase.Services
|
|||
// HELPERS
|
||||
// ============================================================
|
||||
|
||||
private static void WriteSerialUnsafe(
|
||||
byte[] bytes,
|
||||
int count)
|
||||
private static void WriteSerialUnsafe(byte[] bytes, int count)
|
||||
{
|
||||
SerialPort porta = PortaGPS;
|
||||
|
||||
|
|
@ -3265,10 +3187,7 @@ namespace AgroBase.Services
|
|||
Stopwatch.Frequency;
|
||||
}
|
||||
|
||||
private static string GetField(
|
||||
string[] fields,
|
||||
int index,
|
||||
string fallback = "")
|
||||
private static string GetField(string[] fields, int index, string fallback = "")
|
||||
{
|
||||
return fields != null &&
|
||||
index >= 0 &&
|
||||
|
|
@ -3289,16 +3208,11 @@ namespace AgroBase.Services
|
|||
: value;
|
||||
}
|
||||
|
||||
private static bool TryParseDmm(
|
||||
string raw,
|
||||
string hemisphere,
|
||||
int degreeDigits,
|
||||
out double result)
|
||||
private static bool TryParseDmm(string raw, string hemisphere, int degreeDigits, out double result)
|
||||
{
|
||||
result = 0;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(raw) ||
|
||||
raw.Length <= degreeDigits)
|
||||
if (string.IsNullOrWhiteSpace(raw) || raw.Length <= degreeDigits)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3338,14 +3252,11 @@ namespace AgroBase.Services
|
|||
!double.IsInfinity(result);
|
||||
}
|
||||
|
||||
private static bool TryParseNmeaTime(
|
||||
string raw,
|
||||
out DateTime result)
|
||||
private static bool TryParseNmeaTime(string raw, out DateTime result)
|
||||
{
|
||||
result = default(DateTime);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(raw) ||
|
||||
raw.Length < 6)
|
||||
if (string.IsNullOrWhiteSpace(raw) || raw.Length < 6)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3397,17 +3308,11 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
private static bool TryParseRmcDateTime(
|
||||
string dateRaw,
|
||||
string timeRaw,
|
||||
out DateTime result)
|
||||
private static bool TryParseRmcDateTime(string dateRaw, string timeRaw, out DateTime result)
|
||||
{
|
||||
result = default(DateTime);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(dateRaw) ||
|
||||
dateRaw.Length != 6 ||
|
||||
string.IsNullOrWhiteSpace(timeRaw) ||
|
||||
timeRaw.Length < 6)
|
||||
if (string.IsNullOrWhiteSpace(dateRaw) || dateRaw.Length != 6 || string.IsNullOrWhiteSpace(timeRaw) || timeRaw.Length < 6)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3595,12 +3500,7 @@ namespace AgroBase.Services
|
|||
get { return (yFisico + yCampo) * 100.0; }
|
||||
}
|
||||
|
||||
public (double lat, double lon)
|
||||
FixLeverArmLatLon_Fast(
|
||||
double latAnt_deg,
|
||||
double lonAnt_deg,
|
||||
double headingDeg,
|
||||
double headingFreq)
|
||||
public (double lat, double lon) FixLeverArmLatLon_Fast(double latAnt_deg, double lonAnt_deg, double headingDeg, double headingFreq)
|
||||
{
|
||||
if (headingFreq < 1)
|
||||
return (latAnt_deg, lonAnt_deg);
|
||||
|
|
@ -3652,11 +3552,7 @@ namespace AgroBase.Services
|
|||
);
|
||||
}
|
||||
|
||||
public (double x, double y) GeodeticToENU(
|
||||
double lat,
|
||||
double lon,
|
||||
double lat0,
|
||||
double lon0)
|
||||
public (double x, double y) GeodeticToENU(double lat, double lon, double lat0, double lon0)
|
||||
{
|
||||
double latR = ToRad(lat);
|
||||
double lonR = ToRad(lon);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ namespace AgroBase.Services
|
|||
// Inicializa o serviço Ethernet com IP e porta específicos
|
||||
public static async Task<bool> InicializarEthernetService()
|
||||
{
|
||||
string ipAddress = Variaveis.OperacaoEmAndamento.DispMvd.Dados.IP_Dir;
|
||||
string ipAddress = ""; // Variaveis.OperacaoEmAndamento.DispMvd.Dados.IP_Dir;
|
||||
int port = VariaveisPortas.Ethernet_TCP;
|
||||
|
||||
_ethernetService?.Disconnect();
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ namespace AgroBase.Services
|
|||
// Inicializa o serviço Ethernet com IP e porta específicos
|
||||
public static async Task<bool> InicializarEthernetService()
|
||||
{
|
||||
string ipAddress = Variaveis.OperacaoEmAndamento.DispMvd.Dados.IP_Mov;
|
||||
string ipAddress = ""; // Variaveis.OperacaoEmAndamento.DispMvd.Dados.IP_Mov;
|
||||
int port = VariaveisPortas.Ethernet_TCP;
|
||||
|
||||
_ethernetService?.Disconnect();
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ namespace AgroBase.Services.Operadores
|
|||
private static void AtualizarDadosContextoLocal()
|
||||
{
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
if (op.Sensoriamento == null) return;
|
||||
if (op?.Sensoriamento == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -130,7 +130,7 @@ namespace AgroBase.Services.Operadores
|
|||
AtualizarDadosModulos();
|
||||
AtualizarDadosControleOperacao();
|
||||
|
||||
var _Sensoriamento = op.Sensoriamento;
|
||||
var _Sensoriamento = op?.Sensoriamento;
|
||||
|
||||
if (_Sensoriamento == null)
|
||||
{
|
||||
|
|
@ -378,7 +378,7 @@ namespace AgroBase.Services.Operadores
|
|||
{
|
||||
try
|
||||
{
|
||||
var pControle = Variaveis.OperacaoEmAndamento.Parametros.Controle;
|
||||
var pControle = Variaveis.OperacaoEmAndamento?.Parametros?.Controle;
|
||||
if (pControle == null)
|
||||
return;
|
||||
RedisService.AtualizarCampos(
|
||||
|
|
@ -414,9 +414,9 @@ namespace AgroBase.Services.Operadores
|
|||
var op = Variaveis.OperacaoEmAndamento;
|
||||
try
|
||||
{
|
||||
if (op.DispMvd == null) return;
|
||||
if (op.DispAtu == null) return;
|
||||
if (op.DispSen == null) return;
|
||||
if (op?.DispMvd == null) return;
|
||||
if (op?.DispAtu == null) return;
|
||||
if (op?.DispSen == null) return;
|
||||
|
||||
var _Sensoriamento = op.Sensoriamento;
|
||||
var agora_dt = DateTime.Now;
|
||||
|
|
|
|||
|
|
@ -420,13 +420,14 @@ namespace AgroBase.Services.Operadores
|
|||
|
||||
if (op.Parametros.Controle.PulverizadorAutomatico)
|
||||
{
|
||||
if (controle.Bicos != null && controle.Bicos.Any(x => x.ComandoAtuar))
|
||||
var bicos = op.DispAtu?.Dados?.BicosPulverizadores ?? new List<Models.Modules.AtuadorBicoModel>();
|
||||
if (bicos != null && bicos.Any(x => x.ComandoAtuar))
|
||||
{
|
||||
controle.Bicos.ForEach(x => x.ComandoAtuar = false);
|
||||
bicos.ForEach(x => x.ComandoAtuar = false);
|
||||
|
||||
RedisService.AtualizarCampos(
|
||||
CtxKey.DadosControle,
|
||||
("controle_bicos", controle.Bicos.ToDictionary(x => x.Posicao - 1, x => x.ComandoAtuar))
|
||||
("controle_bicos", bicos.ToDictionary(x => x.Posicao - 1, x => x.ComandoAtuar))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ namespace AgroBase.Services.Operadores
|
|||
{
|
||||
AtualizarImu();
|
||||
|
||||
DadosLeitura.Status = Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorSaude?.ModulosSaude?.FirstOrDefault(x => x.modulo == Enums.T_Code.Snr)?.status ?? Enums.StatusModulo.Desconectado;
|
||||
DadosLeitura.Status = Variaveis.OperacaoEmAndamento?.Sensoriamento?.OperadorSaude?.ModulosSaude?.FirstOrDefault(x => x.modulo == Enums.T_Code.Snr)?.status ?? Enums.StatusModulo.Desconectado;
|
||||
|
||||
string json = RedisService.Get(CtxKey.DadosVisualWorker);
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ namespace AgroBase.Services.Operadores
|
|||
|
||||
bool comandoMudou = false;
|
||||
var _Controle = op.Controle;
|
||||
foreach (var bico in _Controle.Bicos ?? new List<Models.Modules.AtuadorBicoModel>())
|
||||
foreach (var bico in op.DispAtu?.Dados.BicosPulverizadores ?? new List<Models.Modules.AtuadorBicoModel>())
|
||||
{
|
||||
novoComando.TryGetValue(bico.Posicao, out bool atuado);
|
||||
if (!(op.DispAtu?.Dados?.ContadorCarga?.PulverizadorLiberado ?? false)) atuado = false;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,13 @@ namespace AgroBase.Services
|
|||
{
|
||||
_redis = ConnectionMultiplexer.Connect(conexao);
|
||||
_db = _redis.GetDatabase();
|
||||
|
||||
AtualizarCampos(
|
||||
CtxKey.DadosOperacao,
|
||||
("motivo_nao_liberado", "Iniciando..."),
|
||||
("liberado", false),
|
||||
("configurado", false)
|
||||
);
|
||||
}
|
||||
|
||||
public static string ModKey(T_Code dispositivo)
|
||||
|
|
@ -159,13 +166,15 @@ namespace AgroBase.Services
|
|||
{
|
||||
if (!(Variaveis.OperacaoEmAndamento?.Sensoriamento?.OperadorSaude?.ModulosSaude?.Any() ?? false)) return;
|
||||
|
||||
var saude = Variaveis.OperacaoEmAndamento.Sensoriamento?.OperadorSaude?.ModulosSaude;
|
||||
var saude = Variaveis.OperacaoEmAndamento?.Sensoriamento?.OperadorSaude?.ModulosSaude;
|
||||
AtualizarCampos(
|
||||
CtxKey.DadosOperacao,
|
||||
("motivo_nao_liberado", "Sem comunicação com o núcleo de processamento central"),
|
||||
("liberado", false),
|
||||
("configurado", false)
|
||||
);
|
||||
Variaveis.OperacaoEmAndamento.Sensoriamento.Operacao.OperacaoLiberada = false;
|
||||
|
||||
foreach (var Mod in saude)
|
||||
{
|
||||
Mod.conectado = false;
|
||||
|
|
|
|||
|
|
@ -522,8 +522,7 @@ namespace AgroBase.Services
|
|||
);
|
||||
}
|
||||
|
||||
public static async Task RealizarVarreduraPortasUSB(
|
||||
CancellationToken cancellationToken)
|
||||
public static async Task RealizarVarreduraPortasUSB(CancellationToken cancellationToken)
|
||||
{
|
||||
if (Variaveis.Fechando ||
|
||||
Volatile.Read(ref _isClosing) == 1)
|
||||
|
|
@ -643,9 +642,7 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
private static async Task ExecutarVarreduraAsync(
|
||||
long generation,
|
||||
CancellationToken cancellationToken)
|
||||
private static async Task ExecutarVarreduraAsync(long generation, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
|
|
@ -654,15 +651,12 @@ namespace AgroBase.Services
|
|||
* consulta CAN. Assim a descoberta não precisa esperar
|
||||
* uma segunda varredura para encontrar os módulos.
|
||||
*/
|
||||
if (!Variaveis.IsAgroMonitor)
|
||||
if (Variaveis.IsAgroBase)
|
||||
{
|
||||
await AtualizarDispositivosAsync(
|
||||
cancellationToken
|
||||
).ConfigureAwait(false);
|
||||
await AtualizarDispositivosAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
List<DispositivoDetalhesModel> mappedSnapshot =
|
||||
GetDispositivosMapeadosSnapshot();
|
||||
List<DispositivoDetalhesModel> mappedSnapshot = GetDispositivosMapeadosSnapshot();
|
||||
|
||||
string[] ports = SerialPort.GetPortNames()
|
||||
.Where(x => !string.IsNullOrWhiteSpace(x))
|
||||
|
|
@ -670,10 +664,7 @@ namespace AgroBase.Services
|
|||
.OrderBy(PortSortKey)
|
||||
.ToArray();
|
||||
|
||||
Interlocked.Add(
|
||||
ref _portsEnumerated,
|
||||
ports.Length
|
||||
);
|
||||
Interlocked.Add(ref _portsEnumerated, ports.Length);
|
||||
|
||||
HashSet<string> mappedComPorts =
|
||||
new HashSet<string>(
|
||||
|
|
@ -696,19 +687,15 @@ namespace AgroBase.Services
|
|||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (generation !=
|
||||
Interlocked.Read(ref _scanGeneration))
|
||||
if (generation != Interlocked.Read(ref _scanGeneration))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await ProbePortAsync(
|
||||
portName,
|
||||
cancellationToken
|
||||
).ConfigureAwait(false);
|
||||
await ProbePortAsync(portName, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (!Variaveis.IsAgroMonitor)
|
||||
if (Variaveis.IsAgroBase)
|
||||
{
|
||||
ProcurarDispositivosUSB();
|
||||
ProcurarDispositivosEthernet();
|
||||
|
|
@ -718,30 +705,18 @@ namespace AgroBase.Services
|
|||
* Se estiver em Ethernet, Inicializar() resolve o transporte
|
||||
* sem depender de uma porta COM candidata.
|
||||
*/
|
||||
if (CanManager.TipoServico !=
|
||||
CanServiceTipo.Serial ||
|
||||
CanManager.CanService.Iniciado)
|
||||
if (CanManager.TipoServico != CanServiceTipo.Serial || CanManager.CanService.Iniciado)
|
||||
{
|
||||
await ProcurarDispositivosCAN(
|
||||
null,
|
||||
cancellationToken
|
||||
).ConfigureAwait(false);
|
||||
await ProcurarDispositivosCAN(null, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
await RemoverDispositivosAusentesAsync(
|
||||
ports,
|
||||
cancellationToken
|
||||
).ConfigureAwait(false);
|
||||
await RemoverDispositivosAusentesAsync(ports, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await AtualizarDispositivosAsync(
|
||||
cancellationToken
|
||||
).ConfigureAwait(false);
|
||||
await AtualizarDispositivosAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task ProbePortAsync(
|
||||
string portName,
|
||||
CancellationToken cancellationToken)
|
||||
private static async Task ProbePortAsync(string portName, CancellationToken cancellationToken)
|
||||
{
|
||||
Interlocked.Increment(ref _portsProbed);
|
||||
|
||||
|
|
@ -757,13 +732,9 @@ namespace AgroBase.Services
|
|||
{
|
||||
candidate = CriarPortaCandidata(portName);
|
||||
|
||||
if (Variaveis.IsAgroMonitor &&
|
||||
!LoRaBaseService.Iniciado)
|
||||
if (!Variaveis.IsAgroBase && !LoRaBaseService.Iniciado)
|
||||
{
|
||||
if (await ProcurarDispositivoLoRa(
|
||||
candidate,
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false))
|
||||
if (await ProcurarDispositivoLoRa(candidate, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
claimed = true;
|
||||
Interlocked.Increment(ref _loraFound);
|
||||
|
|
@ -773,10 +744,7 @@ namespace AgroBase.Services
|
|||
|
||||
if (!GPSService.Iniciado)
|
||||
{
|
||||
if (await ProcurarDispositivoGPS(
|
||||
candidate,
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false))
|
||||
if (await ProcurarDispositivoGPS(candidate, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
Interlocked.Increment(ref _gpsFound);
|
||||
|
||||
|
|
@ -788,22 +756,15 @@ namespace AgroBase.Services
|
|||
}
|
||||
}
|
||||
|
||||
if (Variaveis.IsAgroMonitor)
|
||||
if (!Variaveis.IsAgroBase)
|
||||
return;
|
||||
|
||||
if (CanManager.TipoServico ==
|
||||
CanServiceTipo.Serial &&
|
||||
!CanManager.CanService.Iniciado)
|
||||
if (CanManager.TipoServico == CanServiceTipo.Serial && !CanManager.CanService.Iniciado)
|
||||
{
|
||||
if (await ProcurarDispositivosCAN(
|
||||
candidate,
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false))
|
||||
if (await ProcurarDispositivosCAN(candidate, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
claimed = true;
|
||||
Interlocked.Increment(
|
||||
ref _canAdapterFound
|
||||
);
|
||||
Interlocked.Increment(ref _canAdapterFound);
|
||||
|
||||
AtualizarConsole(
|
||||
"Dispositivo encontrado no barramento CAN"
|
||||
|
|
@ -954,7 +915,7 @@ namespace AgroBase.Services
|
|||
|
||||
private static void ProcurarDispositivosUSB()
|
||||
{
|
||||
if (Variaveis.IsAgroMonitor)
|
||||
if (!Variaveis.IsAgroBase)
|
||||
return;
|
||||
|
||||
if (GeneralJoystick.JoystickConectado == null)
|
||||
|
|
@ -1746,7 +1707,7 @@ namespace AgroBase.Services
|
|||
{
|
||||
Variaveis.MostrarLog(message);
|
||||
|
||||
if (Variaveis.IsAgroMonitor)
|
||||
if (!Variaveis.IsAgroBase)
|
||||
return;
|
||||
|
||||
_pendingUiMessage = message;
|
||||
|
|
|
|||
|
|
@ -1163,20 +1163,16 @@ namespace AgroBase.Services
|
|||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private static void AtualizarConsole(
|
||||
string msg,
|
||||
int val)
|
||||
private static void AtualizarConsole(string msg, int val)
|
||||
{
|
||||
Console.WriteLine(msg);
|
||||
|
||||
try
|
||||
{
|
||||
if (Variaveis.IsAgroMonitor)
|
||||
if (!Variaveis.IsAgroBase)
|
||||
return;
|
||||
|
||||
if (frmInstancial.frmPrincipal == null ||
|
||||
!frmInstancial.frmPrincipal.Created ||
|
||||
frmInstancial.frmPrincipal.IsDisposed)
|
||||
if (frmInstancial.frmPrincipal == null || !frmInstancial.frmPrincipal.Created || frmInstancial.frmPrincipal.IsDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -1221,8 +1217,7 @@ namespace AgroBase.Services
|
|||
catch { }
|
||||
}
|
||||
|
||||
private static void AtualizarProgressoSeguro(
|
||||
double progresso)
|
||||
private static void AtualizarProgressoSeguro(double progresso)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ namespace AgroBase.Services
|
|||
public static bool Conectando { get; set; } = false;
|
||||
private static string InterfaceAtual { get; set; } = "";
|
||||
|
||||
|
||||
private static string NomeRedeWifiEquipamento = "";
|
||||
private static string IP_Host = "";
|
||||
|
||||
public static void IniciarRotinas()
|
||||
{
|
||||
tmrMonitoramento?.Dispose();
|
||||
|
|
@ -26,7 +30,7 @@ namespace AgroBase.Services
|
|||
|
||||
private static async Task tmrMonitoramento_Tick()
|
||||
{
|
||||
string nomeRede = Variaveis.NomeRedeWifiEquipamento;
|
||||
string nomeRede = NomeRedeWifiEquipamento;
|
||||
|
||||
if (!PerfilExiste)
|
||||
{
|
||||
|
|
@ -63,7 +67,7 @@ namespace AgroBase.Services
|
|||
}
|
||||
|
||||
var ip = EthernetService.ObterIpAtual(InterfaceAtual);
|
||||
if (!string.IsNullOrEmpty(ip) && ip != Variaveis.IP_Host)
|
||||
if (!string.IsNullOrEmpty(ip) && ip != IP_Host)
|
||||
{
|
||||
bool configurado = await EthernetService.ConfigurarIP(true, false);
|
||||
Variaveis.IniciarMQTT();
|
||||
|
|
@ -112,7 +116,7 @@ namespace AgroBase.Services
|
|||
|
||||
if (!PerfilExiste)
|
||||
{
|
||||
string nomeRede = Variaveis.NomeRedeWifiEquipamento;
|
||||
string nomeRede = NomeRedeWifiEquipamento;
|
||||
string xmlPerfil = $@"<?xml version=""1.0""?>
|
||||
<WLANProfile xmlns=""http://www.microsoft.com/networking/WLAN/profile/v1"">
|
||||
<name>{nomeRede}</name>
|
||||
|
|
@ -267,7 +271,7 @@ namespace AgroBase.Services
|
|||
|
||||
await Task.Delay(3000); // tempo para o sistema conectar de fato
|
||||
string ssidDepois = await ObterNomeRedeWifiAtual();
|
||||
WifiConectado = ssidDepois == Variaveis.NomeRedeWifiEquipamento;
|
||||
WifiConectado = ssidDepois == NomeRedeWifiEquipamento;
|
||||
|
||||
//WifiConectado = output.Contains("successfully");
|
||||
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ WEED_DEFAULT_CONFIG = {
|
|||
# Gate global: só libera bicos quando existe alvo suficiente no frame.
|
||||
"usar_radar_global_gate": True,
|
||||
"inverter_ordem_bicos": True,
|
||||
"inverter_sentido_vertical_bicos": True,
|
||||
|
||||
# Histerese global da fração de alvo no frame completo.
|
||||
"min_frac_erva_global_on": 0.0020,
|
||||
|
|
|
|||
|
|
@ -71,9 +71,6 @@ class WeedDetector:
|
|||
self.config.get("inverter_ordem_bicos", False)
|
||||
)
|
||||
|
||||
# TESTE INLINE:
|
||||
# False = lógica atual: erva caminha topo -> pé
|
||||
# True = lógica invertida: erva caminha pé -> topo
|
||||
self.inverter_sentido_vertical_bicos = bool(
|
||||
self.config.get("inverter_sentido_vertical_bicos", True)
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue