From c9f3bd69d79642f8d9707ecad4aaf9a4b687d942 Mon Sep 17 00:00:00 2001 From: Diego Freitas Date: Wed, 1 Jul 2026 13:26:08 -0300 Subject: [PATCH] melhoria na saude do atuador, bicos com ou sem movimento --- AgroBase/AgroBase/Forms/frmInstancial.cs | 2 +- .../AgroBase/Models/Modules/AtuadorModel.cs | 8 +- .../Models/Modules/SensoriamentoModel.cs | 6 +- .../Models/Operacoes/OperacaoModel.cs | 82 +++++++++++--- .../Services/HerbicideCounterService.cs | 70 +++--------- .../Operadores/HealthWorkerService.cs | 1 + .../AgroBase/Services/UdpReliableChannel.cs | 105 ++++++++++++++---- .../workers/health_worker/modulos/atuador.py | 70 +++++++----- AgroBase/OperationControl/Models/Variaveis.cs | 14 +-- 9 files changed, 230 insertions(+), 128 deletions(-) diff --git a/AgroBase/AgroBase/Forms/frmInstancial.cs b/AgroBase/AgroBase/Forms/frmInstancial.cs index 9ab40afd4..d309dca2c 100644 --- a/AgroBase/AgroBase/Forms/frmInstancial.cs +++ b/AgroBase/AgroBase/Forms/frmInstancial.cs @@ -135,7 +135,7 @@ 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(); VersionamentoService.IniciarRotinas(); diff --git a/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs b/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs index c1f5591e8..b783ea201 100644 --- a/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs +++ b/AgroBase/AgroBase/Models/Modules/AtuadorModel.cs @@ -764,7 +764,7 @@ namespace AgroBase.Models.Modules posicao = CanMessagePosicaoDados.Dados1, indice = 2, analise_health = true, - maximo = 100, + maximo = 120, minimo = 0, nominal = 0, unidade_medida = "mL/s" @@ -1181,6 +1181,7 @@ namespace AgroBase.Models.Modules Componente = S_Code.sBIC, Posicao = posicao, Inicializado = false, + ComMovimento = false, AnguloNeutro = 90, AnguloControle = 90, AnguloAbertura = 30, @@ -2074,6 +2075,7 @@ namespace AgroBase.Models.Modules public int Posicao { get; set; } public S_Code Componente { get; set; } = S_Code.sBIC; public bool AtuacaoNivelAlto { get; set; } + public bool ComMovimento { get; set; } public double AnguloNeutro { get; set; } public double AnguloControle { get; set; } public double AnguloAbertura { get; set; } @@ -2250,8 +2252,12 @@ namespace AgroBase.Models.Modules AtuacaoNivelAlto = AtuacaoNivelAlto, Atuacoes = Atuacoes, ComandoAtuar = ComandoAtuar, + ComMovimento = ComMovimento, AnguloAbertura = AnguloAbertura, AnguloControle = AnguloControle, + UltimoAnguloDesejado = UltimoAnguloDesejado, + UltimoComandoEnviado = UltimoComandoEnviado, + UltimoStatusDesejado = UltimoStatusDesejado, Inicializado = Inicializado, Mandatorio = Mandatorio, Componente = Componente, diff --git a/AgroBase/AgroBase/Models/Modules/SensoriamentoModel.cs b/AgroBase/AgroBase/Models/Modules/SensoriamentoModel.cs index 00a75f1a8..2cd8e5440 100644 --- a/AgroBase/AgroBase/Models/Modules/SensoriamentoModel.cs +++ b/AgroBase/AgroBase/Models/Modules/SensoriamentoModel.cs @@ -602,9 +602,9 @@ namespace AgroBase.Models.Modules posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, - maximo = 2200, - minimo = 1000, - nominal = 1700, + maximo = 2500, + minimo = 400, + nominal = 700, unidade_medida = "mA" }, new SensorValoresLeituraModel() diff --git a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs index 78f515bda..e5d617fa0 100644 --- a/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs +++ b/AgroBase/AgroBase/Models/Operacoes/OperacaoModel.cs @@ -14,7 +14,6 @@ using System.Drawing; using System.Globalization; using System.IO; using System.Linq; -using System.Runtime.InteropServices.ComTypes; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -30,15 +29,16 @@ namespace AgroBase.Models { get { - return tmrLogs.Interval; + return _tmrLogsOperacao.Interval; } set { - tmrLogs.SetInterval((int)value); + _tmrLogsOperacao.SetInterval((int)value); } } - private static AsyncTaskTimerModel tmrLogs; + private AsyncTaskTimerModel _tmrLogsOperacao; private int idxLog = 0; + private readonly SemaphoreSlim _salvarLogsGate = new SemaphoreSlim(1, 1); public double tmrLeiturasInterval { get @@ -55,8 +55,13 @@ namespace AgroBase.Models public OperacaoModel() { - tmrLogs?.Dispose(); - tmrLogs = new AsyncTaskTimerModel("tmrLogs", tmrLogs_Tick, 1000); + 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); @@ -200,8 +205,6 @@ namespace AgroBase.Models if (CarregarModulos) { - tmrLogs?.Stop(); - var SenConectado = (DispositivosService)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Sen); var AtuConectado = (DispositivosService)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Atu); var MvdConectado = (DispositivosService)Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == T_Code.Mvd); @@ -1059,7 +1062,7 @@ namespace AgroBase.Models op.Sensoriamento.UltimoRegistroLog = agora; op.idxLog = 0; - tmrLogs?.Start(); + op.IniciarTimerLogsOperacao(); await op.RealizarCalibragemInicialAsync(true); @@ -1087,9 +1090,9 @@ namespace AgroBase.Models op.Sensoriamento.Operacao.DataFim = DateTime.Now; - tmrLogs?.Stop(); + op.PararTimerLogsOperacao(); - op.SalvarLogs(false); + op.SalvarLogs(true); op.Sensoriamento.Operacao.Finalizando = false; op.Trajetoria?.AutonomiaCorredor?.Parar(); @@ -1194,6 +1197,33 @@ namespace AgroBase.Models } + 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) ?? ""; @@ -2628,7 +2658,24 @@ namespace AgroBase.Models { var op = this; - if (op.Sensoriamento.Operacao.OperacaoIniciada) + if (!ReferenceEquals(Variaveis.OperacaoEmAndamento, op)) + { + Variaveis.MostrarLog($"[OperacaoModel.tmrLogs_Tick] Timer órfão parado. TimerHash={GetHashCode()}, OperacaoTimer={ID}, OperacaoAtual={Variaveis.OperacaoEmAndamento?.ID}"); + + PararTimerLogsOperacao(); + return; + } + + if (op.Sensoriamento?.Operacao?.OperacaoIniciada != true) + return; + + if (!await _salvarLogsGate.WaitAsync(0)) + { + Variaveis.MostrarLog($"[OperacaoModel.tmrLogs_Tick] Tick ignorado porque SalvarLogs ainda está em execução. Operacao={ID}, idxLog={idxLog}"); + return; + } + + try { op.SalvarLogs(false); @@ -2639,9 +2686,13 @@ namespace AgroBase.Models if (op.idxLog % 5 == 0 && !op.Sensoriamento.Operacao.Calibrando) { - Task.Run(async () => await op.RealizarCalibragemInicialAsync(false)); + _ = Task.Run(async () => await op.RealizarCalibragemInicialAsync(false)); } } + finally + { + _salvarLogsGate.Release(); + } } public void SalvarLogs(bool Fim) @@ -3594,6 +3645,7 @@ namespace AgroBase.Models Atuacoes = bico.Atuacoes, TempoAtuado = bico.TempoAtuado, AnguloAbertura = bico.AnguloAbertura, + ComMovimento = bico.ComMovimento, AnguloControle = bico.AnguloControle }).ToList() }; @@ -4649,7 +4701,7 @@ namespace AgroBase.Models DadosPerformance = dadosPerformance, LivoxLidar = dadosLivox, CoolerControl = dadosCooler, - Logs = Logs != null ? Logs.Where(x => x?.Momento >= ultimoRegistroLog).ToList() : new List(), + Logs = Logs != null ? Logs.Where(x => x != null && x.Momento > ultimoRegistroLog).ToList() : new List(), UltimoRegistroLog = ultimoRegistroLog, }; @@ -5108,6 +5160,7 @@ namespace AgroBase.Models public int Atuacoes { get; set; } public double TempoAtuado { get; set; } public double AnguloAbertura { get; set; } + public bool ComMovimento { get; set; } public double AnguloControle { get; set; } public AtuadorBicoLogModel Clone() @@ -5124,6 +5177,7 @@ namespace AgroBase.Models Atuacoes = Atuacoes, TempoAtuado = TempoAtuado, AnguloAbertura = AnguloAbertura, + ComMovimento = ComMovimento, AnguloControle = AnguloControle }; } diff --git a/AgroBase/AgroBase/Services/HerbicideCounterService.cs b/AgroBase/AgroBase/Services/HerbicideCounterService.cs index ae7045a63..6a1edde30 100644 --- a/AgroBase/AgroBase/Services/HerbicideCounterService.cs +++ b/AgroBase/AgroBase/Services/HerbicideCounterService.cs @@ -610,8 +610,7 @@ namespace AgroBase.Services return; } - var agitador = - op?.DispAtu?.Dados?.AgitadorDeCalda; + var agitador = op?.DispAtu?.Dados?.AgitadorDeCalda; if (!(agitador?.Inicializado ?? false)) return; @@ -634,32 +633,20 @@ namespace AgroBase.Services !operacaoConcluida && PulverizadorLiberado; - bool bicosAtuando = - op.DispAtu?.Dados?.BicosPulverizadores? - .Any(x => - x.Comandar && - x.ComandoAtuar) - ?? false; + bool bicosAtuando = op.DispAtu?.Dados?.BicosPulverizadores?.Any(x => x.Comandar && x.ComandoAtuar) ?? false; double potenciaFinal = 0; DateTime agora = DateTime.Now; - if ( - operacaoAtiva && - !_agitadorOperacaoAtivaAnterior - ) + if (operacaoAtiva && !_agitadorOperacaoAtivaAnterior) { - _agitadorBoostAte = - agora.AddMilliseconds( - AtuAgitadorBoostRetomadaMs - ); + _agitadorBoostAte = agora.AddMilliseconds(AtuAgitadorBoostRetomadaMs); _agitadorUltimaTroca = agora; _agitadorIntermitenteLigado = true; } - bool emBoost = - agora < _agitadorBoostAte; + bool emBoost = agora < _agitadorBoostAte; switch (modo) { @@ -672,18 +659,15 @@ namespace AgroBase.Services { if (emBoost) { - potenciaFinal = - AtuAgitadorPotenciaBoost; + potenciaFinal = AtuAgitadorPotenciaBoost; } else if (bicosAtuando) { - potenciaFinal = - AtuAgitadorPotenciaContinua; + potenciaFinal = AtuAgitadorPotenciaContinua; } else { - potenciaFinal = - AtuAgitadorPotenciaManutencao; + potenciaFinal = AtuAgitadorPotenciaManutencao; } } break; @@ -697,44 +681,27 @@ namespace AgroBase.Services } else if (emBoost) { - potenciaFinal = - AtuAgitadorPotenciaBoost; + potenciaFinal = AtuAgitadorPotenciaBoost; } else { - int tempoAtualMs = - _agitadorIntermitenteLigado - ? AtuAgitadorTempoLigadoMs - : AtuAgitadorTempoDesligadoMs; + int tempoAtualMs = _agitadorIntermitenteLigado ? AtuAgitadorTempoLigadoMs : AtuAgitadorTempoDesligadoMs; - if ( - (agora - _agitadorUltimaTroca) - .TotalMilliseconds >= - tempoAtualMs - ) + if ((agora - _agitadorUltimaTroca).TotalMilliseconds >= tempoAtualMs) { - _agitadorIntermitenteLigado = - !_agitadorIntermitenteLigado; + _agitadorIntermitenteLigado = !_agitadorIntermitenteLigado; _agitadorUltimaTroca = agora; } - potenciaFinal = - _agitadorIntermitenteLigado - ? AtuAgitadorPotenciaIntermitente - : 0; + potenciaFinal = _agitadorIntermitenteLigado ? AtuAgitadorPotenciaIntermitente : 0; } break; } - potenciaFinal = - Math.Min( - potenciaFinal, - PotenciaLimitePorNivel(PercentualAtual) - ); + potenciaFinal = Math.Min(potenciaFinal, PotenciaLimitePorNivel(PercentualAtual)); - potenciaFinal = - Clamp(potenciaFinal, 0, 100); + potenciaFinal = Clamp(potenciaFinal, 0, 100); /* * Este método é a fonte de verdade do agitador. @@ -742,12 +709,9 @@ namespace AgroBase.Services agitador.PotenciaSP = potenciaFinal; agitador.PressaoSP = -1; - agitador.ComandoAtuar = - agitador.Comandar && - potenciaFinal > 0; + agitador.ComandoAtuar = agitador.Comandar && potenciaFinal > 0; - _agitadorOperacaoAtivaAnterior = - operacaoAtiva; + _agitadorOperacaoAtivaAnterior = operacaoAtiva; } } } \ No newline at end of file diff --git a/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs b/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs index fd06e969a..42dbb5c66 100644 --- a/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs +++ b/AgroBase/AgroBase/Services/Operadores/HealthWorkerService.cs @@ -969,6 +969,7 @@ namespace AgroBase.Services.Operadores estado_leitura = bico._EstadoLeitura, angulo_leitura = bico._AnguloBicoLeitura, + com_movimento = bico.ComMovimento, angulo_neutro = bico.AnguloNeutro, angulo_controle = bico.AnguloControle, angulo_abertura = bico.AnguloAbertura, diff --git a/AgroBase/AgroBase/Services/UdpReliableChannel.cs b/AgroBase/AgroBase/Services/UdpReliableChannel.cs index f4faf212b..f209c9286 100644 --- a/AgroBase/AgroBase/Services/UdpReliableChannel.cs +++ b/AgroBase/AgroBase/Services/UdpReliableChannel.cs @@ -57,54 +57,121 @@ public sealed class UdpReliableChannel : IDisposable } } - public void Start(int localPort) + public bool Start(int localPort) { - if (_udp != null) return; + lock (_sockLock) + { + if (_udp != null || _running || _stopping) + return true; - _seqTx = 0; // opcional - _lastSeqRx = 0; // importante - _running = true; + try + { + _seqTx = 0; + _lastSeqRx = 0; + _running = true; + _stopping = false; - _udp = new UdpClient(localPort); - _udp.Client.ReceiveBufferSize = 1 << 20; - _udp.Client.SendBufferSize = 1 << 20; + _udp = new UdpClient(localPort); + _udp.Client.ReceiveBufferSize = 1 << 20; + _udp.Client.SendBufferSize = 1 << 20; - _rxThread = new Thread(RxLoop) { IsBackground = true, Name = "UdpReliableChannel.Rx" }; - _rxThread.Start(); + _rxThread = new Thread(RxLoop) + { + IsBackground = true, + Name = "UdpReliableChannel.Rx" + }; - if (EnableHeartbeat) - StartHeartbeat(); + _rxThread.Start(); + + if (EnableHeartbeat) + StartHeartbeat(); + + return true; + } + catch (SocketException ex) + { + _running = false; + _stopping = false; + + try { _udp?.Close(); } catch { } + try { _udp?.Dispose(); } catch { } + + _udp = null; + _rxThread = null; + + // 10048 = address already in use + if (ex.SocketErrorCode == SocketError.AddressAlreadyInUse) + { + // Não relança. Quem chamou decide tentar depois. + return false; + } + + return false; + } + catch + { + _running = false; + _stopping = false; + + try { _udp?.Close(); } catch { } + try { _udp?.Dispose(); } catch { } + + _udp = null; + _rxThread = null; + + return false; + } + } } public void Stop() { + UdpClient udpParaFechar = null; + Thread threadParaAguardar = null; + lock (_sockLock) { + if (_stopping) + return; + _stopping = true; _running = false; + + udpParaFechar = _udp; + threadParaAguardar = _rxThread; } - // pare heartbeat antes de matar socket StopHeartbeat(); - try { _udp?.Close(); } catch { } - try { _udp?.Dispose(); } catch { } + try { udpParaFechar?.Close(); } catch { } + try { udpParaFechar?.Dispose(); } catch { } try { - if (_rxThread != null && _rxThread.IsAlive) - _rxThread.Join(2000); // ou sem timeout se preferir travar até fechar + if ( + threadParaAguardar != null && + threadParaAguardar.IsAlive && + Thread.CurrentThread.ManagedThreadId != threadParaAguardar.ManagedThreadId + ) + { + threadParaAguardar.Join(1000); + } } catch { } lock (_sockLock) { - _udp = null; - _rxThread = null; + if (ReferenceEquals(_udp, udpParaFechar)) + _udp = null; + + if (ReferenceEquals(_rxThread, threadParaAguardar)) + _rxThread = null; + _lastSeqRx = 0; foreach (var kv in _pendingAck) kv.Value.TrySetResult(false); + _pendingAck.Clear(); _stopping = false; diff --git a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/health_worker/modulos/atuador.py b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/health_worker/modulos/atuador.py index c31f066c1..21ab6186c 100644 --- a/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/health_worker/modulos/atuador.py +++ b/AgroBase/AgroBase/bin/x64/Debug/Python/Scripts/workers/health_worker/modulos/atuador.py @@ -554,27 +554,38 @@ class ModuloAtuador(ModuloDiagnosticoBase): def _avaliar_comando_bico(self, item, ctx, motivos, condicoes): dados = item["dados"] label = dados.get("label") + comando_presente = ( "comando_atuar" in dados or "estado_desejado" in dados or "status_desejado_fisico" in dados or "ultimo_status_desejado" in dados ) + comando = self._estado_desejado_ligado(dados) estado = self._get(dados, "estado_leitura", self._campo_atual(dados, "EstadoLeitura", 0)) estado_on = self._estado_ligado(estado) - angulo = self._float( - self._get(dados, "angulo_leitura", self._campo_atual(dados, "ServoAnguloLeitura", 0)), - 0, - ) + usa_servo = dados.get("com_movimento", False) - angulo_neutro = self._float(dados.get("angulo_neutro", 90), 90) - angulo_controle = self._float(dados.get("angulo_controle", dados.get("angulo_sp", 90)), 90) - angulo_desejado = self._float( - dados.get("angulo_desejado", angulo_controle if comando else angulo_neutro), - angulo_controle if comando else angulo_neutro, - ) + angulo = None + angulo_desejado = None + angulo_neutro = None + angulo_controle = None + + if usa_servo: + angulo = self._float( + self._get(dados, "angulo_leitura", self._campo_atual(dados, "ServoAnguloLeitura", 0)), + 0, + ) + + angulo_neutro = self._float(dados.get("angulo_neutro", 90), 90) + angulo_controle = self._float(dados.get("angulo_controle", dados.get("angulo_sp", 90)), 90) + + angulo_desejado = self._float( + dados.get("angulo_desejado", angulo_controle if comando else angulo_neutro), + angulo_controle if comando else angulo_neutro, + ) ultimo_comando_ms = self._float(dados.get("ultimo_comando_ms", 999999), 999999) tem_idade_comando = ultimo_comando_ms < 900000 @@ -585,13 +596,16 @@ class ModuloAtuador(ModuloDiagnosticoBase): return 92, { "comando_disponivel": False, "estado_on": estado_on, + "usa_servo": usa_servo, "angulo": angulo, + "angulo_desejado": angulo_desejado, } if tem_idade_comando and ultimo_comando_ms < self.COMANDO_GRACE_MS: return 96, { "comando_atuar": comando, "estado_on": estado_on, + "usa_servo": usa_servo, "angulo": angulo, "angulo_desejado": angulo_desejado, "ultimo_comando_ms": ultimo_comando_ms, @@ -634,32 +648,36 @@ class ModuloAtuador(ModuloDiagnosticoBase): score = min(score, 25 if severidade > 90 else 65) - erro_ang = abs(angulo - angulo_desejado) + if usa_servo and angulo is not None and angulo_desejado is not None: + erro_ang = abs(angulo - angulo_desejado) - if erro_ang > self.ANGULO_TOL_BICO_GRAUS and (comando or estado_on): - motivos.append(f"Ângulo do bico distante do desejado ({angulo:.1f}°/{angulo_desejado:.1f}°)") - condicoes.append({ - "label": "Ângulo bico", - "valor": angulo, - "severidade": min(75, max(30, int(erro_ang * 3))), - "classe": "processo", - "descricao": f"Ângulo do bico {label} distante do desejado", - "acoes": [ - "Verificar servo/posição mecânica do bico.", - "Conferir neutro e ângulo de abertura configurados.", - ], - }) - score = min(score, 78) + if erro_ang > self.ANGULO_TOL_BICO_GRAUS and (comando or estado_on): + motivos.append(f"Ângulo do bico distante do desejado ({angulo:.1f}°/{angulo_desejado:.1f}°)") + condicoes.append({ + "label": "Ângulo bico", + "valor": angulo, + "severidade": min(75, max(30, int(erro_ang * 3))), + "classe": "processo", + "descricao": f"Ângulo do bico {label} distante do desejado", + "acoes": [ + "Verificar servo/posição mecânica do bico.", + "Conferir neutro e ângulo de abertura configurados.", + ], + }) + score = min(score, 78) return int(max(0, min(100, round(score)))), { "comando_disponivel": True, "comando_atuar": comando, "estado_on": estado_on, + "usa_servo": usa_servo, "angulo": angulo, "angulo_desejado": angulo_desejado, + "angulo_neutro": angulo_neutro, + "angulo_controle": angulo_controle, "ultimo_comando_ms": ultimo_comando_ms, } - + # ============================================================ # Bombas # ============================================================ diff --git a/AgroBase/OperationControl/Models/Variaveis.cs b/AgroBase/OperationControl/Models/Variaveis.cs index 44aa53ba4..6ca3e43a8 100644 --- a/AgroBase/OperationControl/Models/Variaveis.cs +++ b/AgroBase/OperationControl/Models/Variaveis.cs @@ -350,23 +350,15 @@ namespace OperationControl.Models HeartbeatPayload = new byte[] { 0 } }; - channel.Start( - VariaveisPortas.Ethernet_UDP_TX - ); + channel.Start(VariaveisPortas.Ethernet_UDP_TX); UdpChannel = channel; - ControlSenderDir = new ManualControlSender( - UdpChannel, - (byte)AgroBase.Models.Enums.T_Code.Dir - ); + ControlSenderDir = new ManualControlSender(UdpChannel, (byte)AgroBase.Models.Enums.T_Code.Dir); ControlSenderDir.Start(); - ControlSenderMov = new ManualControlSender( - UdpChannel, - (byte)AgroBase.Models.Enums.T_Code.Mov - ); + ControlSenderMov = new ManualControlSender(UdpChannel, (byte)AgroBase.Models.Enums.T_Code.Mov); ControlSenderMov.Start();