2025-05-30 20:11:31 +00:00
using AgroBase.Services ;
2025-07-11 16:38:08 +00:00
using AgroBase.Services.Operadores ;
2024-01-03 10:52:37 +00:00
using System ;
using System.Collections.Generic ;
2024-10-29 19:53:27 +00:00
using System.Drawing ;
2024-01-03 10:52:37 +00:00
using System.Linq ;
using System.Threading.Tasks ;
2024-10-29 19:53:27 +00:00
using System.Windows.Forms ;
2024-07-26 19:54:25 +00:00
using static AgroBase . Models . Enums ;
2024-01-03 10:52:37 +00:00
namespace AgroBase.Models.Modules
{
public class AtuadorModel : DispositivoBaseModel
{
2025-04-09 21:11:40 +00:00
public T_Code Dispositivo { get ; set ; } = T_Code . Atu ;
2024-06-08 01:20:23 +00:00
public string Modulo_ID { get ; set ; } = T_Code . Atu . ToString ( ) ;
2025-05-01 18:27:01 +00:00
public byte _EnderecoCAN_Tx { get ; set ; } = 0x13 ;
public byte _EnderecoCAN_Rx { get ; set ; } = 0x14 ;
2025-04-09 21:11:40 +00:00
public int _TaxaAmostragem { get ; set ; } = 1000 ;
2025-07-23 15:14:50 +00:00
public double FrequenciaBase
{
get
{
return 1.0 / ( _TaxaAmostragem / 1000.0 ) ;
}
}
2025-04-09 21:11:40 +00:00
public bool RequisitarDados { get ; set ; } = true ;
2025-12-09 12:19:36 +00:00
public static int TempoLimiteConexao { get ; set ; } = 8000 ;
2025-07-23 15:14:50 +00:00
public bool Conectado
{
get
{
2025-12-10 16:37:47 +00:00
DateTime Agora = DateTime . Now ;
bool modConectado = DadosLeitura . UltimoComandoRespondido . AddMilliseconds ( TempoLimiteConexao ) > Agora ;
return modConectado ;
2025-07-23 15:14:50 +00:00
}
}
2025-05-30 20:11:31 +00:00
public bool ConexaoAtiva
2025-04-09 21:11:40 +00:00
{
get
{
2025-07-11 16:38:08 +00:00
return HealthWorkerService . ModulosSaude . Any ( x = > x . modulo = = Dispositivo & & x . status = = StatusModulo . Operante ) ;
2025-04-09 21:11:40 +00:00
}
}
2025-07-11 16:38:08 +00:00
public bool AtuPronto { get ; set ; } = false ;
2025-04-09 21:11:40 +00:00
2025-12-05 18:25:29 +00:00
public double AnguloBarraEsquerda { get ; set ; }
public double AnguloBarraDireita { get ; set ; }
2024-04-15 10:57:37 +00:00
public static PinoutDataModel Pinout { get ; set ; }
2024-04-01 11:03:25 +00:00
public static List < FuncoesPinout > Funcoes { get ; set ; } = new List < FuncoesPinout > ( )
2024-04-15 10:57:37 +00:00
{
2024-04-01 11:03:25 +00:00
FuncoesPinout . SDA ,
FuncoesPinout . SCL ,
} ;
2025-11-24 16:05:50 +00:00
//public int QuantidadeBicos { get; set; } = 4;
2025-08-22 18:36:19 +00:00
public double DensidadeHerbicida { get ; set ; } = 1.0 ;
2025-12-15 13:41:05 +00:00
public List < AtuadorBicoModel > BicosPulverizadores { get ; set ; }
public List < AtuadorBombaModel > BombasPressurizadoras { get ; set ; }
public List < SensorModel > Sensores { get ; set ; }
2024-04-02 18:33:15 +00:00
public string ScriptDeteccaoErvas { get ; set ; } = PythonService . ScriptWeedDetector ;
2024-04-01 11:03:25 +00:00
2024-11-27 17:38:56 +00:00
public AsyncTaskTimerModel tmrRegistrador ;
2024-12-05 12:52:28 +00:00
private int _TempoReconexaoComponentes = 5 ;
2024-11-29 20:28:25 +00:00
private int _VezesLeituraReconexao = 0 ;
public AtuadorMensagemJsonModel DadosLeitura { get ; set ; } = new AtuadorMensagemJsonModel ( ) ;
2025-04-09 21:11:40 +00:00
public AtuHandler _AtuHandler = new AtuHandler ( ) ;
2024-11-27 17:38:56 +00:00
2025-12-15 13:41:05 +00:00
private SensorModel SensorAnguloBarraEsquerda
2025-12-05 18:25:29 +00:00
{
get
{
var sMAG = Sensores ? . FirstOrDefault ( x = > x . Componente = = S_Code . sMAG & & x . ID . Contains ( "ESQ" ) ) ;
return sMAG ;
}
}
2025-12-15 13:41:05 +00:00
private SensorModel SensorAnguloBarraDireita
2025-12-05 18:25:29 +00:00
{
get
{
var sMAG = Sensores ? . FirstOrDefault ( x = > x . Componente = = S_Code . sMAG & & x . ID . Contains ( "DIR" ) ) ;
return sMAG ;
}
}
2026-04-02 17:38:24 +00:00
2025-12-09 16:47:53 +00:00
public HerbicideCounterService ContadorCarga = new HerbicideCounterService ( VariaveisEquipamento . CapacidadeReservatorio , VariaveisEquipamento . DensidadeHerbicida ) ;
2024-04-01 11:03:25 +00:00
#region VAZAO
2026-05-21 22:48:36 +00:00
2025-12-16 17:17:26 +00:00
private SensorModel SensorFluxoLinha = > Sensores . FirstOrDefault ( x = > x . Componente = = S_Code . sFLX & & x . ID = = "FLXLN" ) ;
2026-05-21 22:48:36 +00:00
2024-04-01 11:03:25 +00:00
public double VolumeVazaoAferido { get ; set ; } = 0 ;
2026-05-21 22:48:36 +00:00
public double VazaoMaximaSensor_LMin { get ; set ; } = 20.0 ;
2025-12-16 17:17:26 +00:00
public double VazaoFluxoMLpSInstantanea = > SensorFluxoLinha ? . ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . Fluxo ) ? . atual ? . valor ? ? 0 ;
2026-05-21 22:48:36 +00:00
2025-12-16 17:17:26 +00:00
public double VazaoFluxoMLpSInstantaneaCalc
2024-12-05 12:52:28 +00:00
{
2024-04-01 11:03:25 +00:00
get
{
2025-12-16 19:33:06 +00:00
int pulsos = ( int ) ( SensorFluxoLinha ? . ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . QtdPulsos ) ? . atual ? . valor ? ? 0.0 ) ;
2026-05-21 22:48:36 +00:00
2025-12-16 19:33:06 +00:00
int periodo = ( int ) ( SensorFluxoLinha ? . ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . Periodo ) ? . atual ? . valor ? ? 0.0 ) ;
2025-12-16 17:17:26 +00:00
2026-05-21 22:48:36 +00:00
if ( pulsos < = 0 | | periodo < = 0 )
return 0.0 ;
double frequencia = ( double ) pulsos / periodo * 1000.0 ;
// Fabricante: F = 8.1*q - 3, q em L/min
2025-12-16 17:17:26 +00:00
double q_L_min = ( frequencia + 3.0 ) / 8.1 ;
2026-05-21 22:48:36 +00:00
if ( q_L_min < 0 )
q_L_min = 0 ;
if ( q_L_min > VazaoMaximaSensor_LMin )
q_L_min = VazaoMaximaSensor_LMin ;
return q_L_min * 1000.0 / 60.0 ;
}
}
public double VazaoFluxoMLpSReferencia
{
get
{
double direta = VazaoFluxoMLpSInstantanea ;
if ( direta > 0 )
return direta ;
return VazaoFluxoMLpSInstantaneaCalc ;
2024-04-01 11:03:25 +00:00
}
}
2026-05-21 22:48:36 +00:00
private DateTime _ultimoRegistroVazao = DateTime . MinValue ;
2025-12-19 12:01:58 +00:00
public double VazaoMediaMLs { get ; set ; }
public double VolumeVazadoML { get ; set ; }
public double TempoAtuado { get ; set ; }
2026-05-21 22:48:36 +00:00
private List < AtuadorBicoModel > bicosAtivosAnterior = new List < AtuadorBicoModel > ( ) ;
2024-10-29 19:53:27 +00:00
public void AtualizaTempoAtuadoGeral ( )
2024-10-10 19:58:57 +00:00
{
2025-12-18 20:14:27 +00:00
DateTime agora = DateTime . Now ;
2026-05-21 22:48:36 +00:00
var bicosAtivos = BicosPulverizadores . Where ( x = > x . Inicializado & & x . ComandoAtuar ) . ToList ( ) ;
2024-10-29 19:53:27 +00:00
2025-12-18 20:14:27 +00:00
bool algumBicoAtivo = bicosAtivos . Count > 0 ;
2025-12-19 12:01:58 +00:00
bool algumBicoAtivoAnterior = bicosAtivosAnterior ? . Any ( ) ? ? false ;
if ( algumBicoAtivo & & ! algumBicoAtivoAnterior )
2026-05-21 22:48:36 +00:00
_ultimoRegistroVazao = agora ;
2025-12-18 20:14:27 +00:00
2025-12-19 12:01:58 +00:00
if ( ! algumBicoAtivo & & algumBicoAtivoAnterior )
2024-10-10 19:58:57 +00:00
{
2025-12-19 12:01:58 +00:00
AtualizaVazaoEVolume ( bicosAtivosAnterior , agora ) ;
2025-12-18 20:14:27 +00:00
_ultimoRegistroVazao = DateTime . MinValue ;
foreach ( var b in BicosPulverizadores )
b . VazaoInstantaneaMLs = 0 ;
2024-10-10 19:58:57 +00:00
}
2024-10-29 19:53:27 +00:00
2026-05-21 22:48:36 +00:00
if ( algumBicoAtivo )
AtualizaVazaoEVolume ( bicosAtivos , agora ) ;
VazaoMediaMLs = TempoAtuado > 0 ? VolumeVazadoML / TempoAtuado : 0 ;
2025-12-18 20:14:27 +00:00
2025-12-19 12:01:58 +00:00
AtualizaPercentualErvas ( ) ;
2024-10-10 19:58:57 +00:00
2025-12-19 12:01:58 +00:00
bicosAtivosAnterior = new List < AtuadorBicoModel > ( bicosAtivos ) ;
2024-10-10 19:58:57 +00:00
}
2026-05-21 22:48:36 +00:00
2025-12-18 20:14:27 +00:00
private void AtualizaVazaoEVolume ( List < AtuadorBicoModel > bicosAtivos , DateTime agora )
2024-12-05 12:52:28 +00:00
{
2025-12-18 20:14:27 +00:00
if ( bicosAtivos = = null | | bicosAtivos . Count = = 0 )
return ;
2026-05-21 22:48:36 +00:00
if ( _ultimoRegistroVazao = = DateTime . MinValue )
{
_ultimoRegistroVazao = agora ;
2024-12-05 12:52:28 +00:00
return ;
2026-05-21 22:48:36 +00:00
}
2024-12-05 12:52:28 +00:00
2025-12-18 20:14:27 +00:00
double dt = ( agora - _ultimoRegistroVazao ) . TotalSeconds ;
_ultimoRegistroVazao = agora ;
2026-05-21 22:48:36 +00:00
if ( dt < = 0 | | dt > 2.0 )
return ;
double vazaoTotalInst = VazaoFluxoMLpSReferencia ;
if ( vazaoTotalInst < = 0 )
{
foreach ( var bico in bicosAtivos )
bico . VazaoInstantaneaMLs = 0 ;
return ;
}
2025-12-19 12:01:58 +00:00
VolumeVazadoML + = vazaoTotalInst * dt ;
TempoAtuado + = dt ;
2025-12-18 20:14:27 +00:00
double vazaoPorBicoInst = vazaoTotalInst / bicosAtivos . Count ;
2024-12-05 12:52:28 +00:00
2025-12-18 20:14:27 +00:00
foreach ( var bico in bicosAtivos )
2024-12-05 12:52:28 +00:00
{
2025-12-18 20:14:27 +00:00
bico . VazaoInstantaneaMLs = vazaoPorBicoInst ;
bico . VolumeVazadoML + = vazaoPorBicoInst * dt ;
2025-12-19 12:01:58 +00:00
bico . TempoAtuado + = dt ;
2024-12-05 12:52:28 +00:00
2026-05-21 22:48:36 +00:00
bico . VazaoMediaMLs = bico . TempoAtuado > 0
? bico . VolumeVazadoML / bico . TempoAtuado
: 0 ;
2025-12-19 12:01:58 +00:00
}
}
2026-05-21 22:48:36 +00:00
2025-12-19 12:01:58 +00:00
private void AtualizaPercentualErvas ( )
{
2026-05-21 22:48:36 +00:00
double tempoTotalOperacao = Variaveis . OperacaoEmAndamento . Sensoriamento ? . Movimentacao ? . TempoMovimentoSegs ? ? 0 ;
PercentualErvasTerreno = tempoTotalOperacao > 0 ? Math . Round ( ( TempoAtuado / tempoTotalOperacao ) * 100.0 , 2 ) : 0 ;
2024-12-05 12:52:28 +00:00
}
2024-04-01 11:03:25 +00:00
#endregion
#region PRESSAO
2025-12-16 17:17:26 +00:00
private SensorModel SensorPressaoLinha
2024-12-02 19:12:39 +00:00
{
get
{
2025-12-16 17:17:26 +00:00
return Sensores . FirstOrDefault ( x = > x . Componente = = S_Code . sPRS & & x . ID = = "PRSLN" ) ;
2024-12-02 19:12:39 +00:00
}
}
2025-12-16 17:17:26 +00:00
public double _PressaoVmin { get ; set ; } = 0.0 ;
public double _PressaoVmax { get ; set ; } = 4.5 ;
public double _PressaoMax { get ; set ; } = 174.045 ; // 1,2 MPa
public double PressaoLinha = > SensorPressaoLinha ? . ValoresLeituras . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . Pressao ) ? . atual ? . valor ? ? 0 ;
2024-04-01 11:03:25 +00:00
public double PressaoLinhaCalc
{
get
{
2025-12-16 17:17:26 +00:00
double _LeituraPressao = SensorPressaoLinha ? . ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . LeituraBruta ) ? . atual ? . valor ? ? 0 ;
2024-05-20 10:16:23 +00:00
double tensao = FuncoesMatematicas . Map ( _LeituraPressao , 0 , 4095 , 0 , 3300 ) / 1000.0 ;
double pressao = FuncoesMatematicas . Map ( tensao , _PressaoVmin , _PressaoVmax , 0 , _PressaoMax ) ;
2024-04-01 11:03:25 +00:00
return pressao ;
}
}
#endregion
2024-01-03 10:52:37 +00:00
2025-02-06 19:01:41 +00:00
public double PercentualErvasTerreno { get ; set ; } = 0 ;
2024-01-03 10:52:37 +00:00
public static AtuadorModel CarregarParametrosIniciais ( )
{
AtuadorModel Atuador = new AtuadorModel ( )
{
2025-05-30 20:11:31 +00:00
_EnderecoCAN_Tx = 0x12 ,
_EnderecoCAN_Rx = 0x12 ,
2025-04-09 21:11:40 +00:00
_TaxaAmostragem = 1000 ,
2026-03-21 01:48:37 +00:00
RequisitarDados = true ,
// 11 ~ 50
Sensores = new List < SensorModel > ( )
2024-04-01 11:03:25 +00:00
{
2026-03-21 01:48:37 +00:00
// pressao 11 ~ 20
new SensorModel ( )
2024-04-01 11:03:25 +00:00
{
2026-03-21 01:48:37 +00:00
ID = "PRSLN" ,
ID_Num = 11 ,
Descricao = "Pressão na linha principal" ,
Componente = S_Code . sPRS ,
Aferir = true ,
2025-05-07 16:54:45 +00:00
Mandatorio = true ,
2024-11-29 20:28:25 +00:00
Funcoes = new List < FuncoesPinout > ( )
{
2026-03-21 01:48:37 +00:00
FuncoesPinout . Pressao ,
2025-05-30 20:11:31 +00:00
} ,
2026-03-21 01:48:37 +00:00
Parametros = new List < SensorParametroModel > ( )
2025-05-30 20:11:31 +00:00
{
2026-03-21 01:48:37 +00:00
new SensorParametroModel ( )
2025-05-30 20:11:31 +00:00
{
2026-03-21 01:48:37 +00:00
Descricao = "Vmin" ,
Valor = "0" ,
QtdBytes = 1 ,
Escalar = false ,
Enviar = false
2025-05-30 20:11:31 +00:00
} ,
2026-03-21 01:48:37 +00:00
new SensorParametroModel ( )
2025-05-30 20:11:31 +00:00
{
2026-03-21 01:48:37 +00:00
Descricao = "Vmax" ,
Valor = "4.5" ,
QtdBytes = 1 ,
Escalar = true ,
Enviar = false
2025-05-30 20:11:31 +00:00
} ,
2026-03-21 01:48:37 +00:00
new SensorParametroModel ( )
{
Descricao = "Pmax" ,
Valor = "174" ,
QtdBytes = 1 ,
Escalar = false ,
Enviar = false
} ,
} ,
ValoresLeituras = new List < SensorValoresLeituraModel > ( )
{
2025-05-30 20:11:31 +00:00
new SensorValoresLeituraModel ( )
{
2026-03-21 01:48:37 +00:00
funcao = FuncoesPinout . Iniciado ,
posicao = CanMessagePosicaoDados . Status ,
indice = 0 ,
2025-05-30 20:11:31 +00:00
} ,
new SensorValoresLeituraModel ( )
{
2026-03-21 01:48:37 +00:00
funcao = FuncoesPinout . LeituraBruta ,
2025-05-30 20:11:31 +00:00
posicao = CanMessagePosicaoDados . Dados1 ,
2026-03-21 01:48:37 +00:00
indice = 0 ,
2025-05-30 20:11:31 +00:00
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Pressao ,
posicao = CanMessagePosicaoDados . Dados1 ,
2026-03-21 01:48:37 +00:00
indice = 1 ,
analise_health = true ,
maximo = 120 ,
minimo = 0 ,
nominal = 85 ,
unidade_medida = "PSI"
2025-05-30 20:11:31 +00:00
}
2024-11-29 20:28:25 +00:00
}
2026-03-21 01:48:37 +00:00
} ,
// fluxo 21 ~ 30
2024-02-21 19:40:38 +00:00
new SensorModel ( )
{
ID = "FLXLN" ,
2026-03-21 01:48:37 +00:00
ID_Num = 21 ,
2024-02-21 19:40:38 +00:00
Descricao = "Fluxo na linha principal" ,
Componente = S_Code . sFLX ,
2025-04-09 21:11:40 +00:00
Aferir = true ,
2026-03-21 01:48:37 +00:00
Mandatorio = true ,
2024-02-21 19:40:38 +00:00
Funcoes = new List < FuncoesPinout > ( )
{
FuncoesPinout . Fluxo ,
} ,
2025-05-30 20:11:31 +00:00
Parametros = new List < SensorParametroModel > ( ) ,
ValoresLeituras = new List < SensorValoresLeituraModel > ( )
{
new SensorValoresLeituraModel ( )
{
2026-03-21 01:48:37 +00:00
funcao = FuncoesPinout . Iniciado ,
posicao = CanMessagePosicaoDados . Status ,
2025-05-30 20:11:31 +00:00
indice = 0 ,
} ,
new SensorValoresLeituraModel ( )
2025-12-16 17:17:26 +00:00
{
funcao = FuncoesPinout . QtdPulsos ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 0 ,
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Periodo ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 1 ,
} ,
new SensorValoresLeituraModel ( )
2025-05-30 20:11:31 +00:00
{
funcao = FuncoesPinout . Fluxo ,
2026-03-21 01:48:37 +00:00
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 2 ,
analise_health = true ,
maximo = 20 ,
minimo = 0 ,
nominal = 0 ,
2025-05-30 20:11:31 +00:00
unidade_medida = "mL/s"
}
}
2024-02-21 19:40:38 +00:00
} ,
2026-06-09 13:39:44 +00:00
// massa 31 ~ 35
2024-02-21 19:40:38 +00:00
new SensorModel ( )
{
ID = "MASRS" ,
2026-03-21 01:48:37 +00:00
ID_Num = 31 ,
2024-02-21 19:40:38 +00:00
Descricao = "Massa do reservatório de herbicida" ,
Componente = S_Code . sMAS ,
2025-04-09 21:11:40 +00:00
Aferir = true ,
2026-03-21 01:48:37 +00:00
Mandatorio = true ,
2024-02-21 19:40:38 +00:00
Funcoes = new List < FuncoesPinout > ( )
{
FuncoesPinout . DT ,
FuncoesPinout . SCK ,
} ,
2025-04-09 21:11:40 +00:00
Parametros = new List < SensorParametroModel > ( )
2025-05-01 18:27:01 +00:00
{
new SensorParametroModel ( )
{
2026-03-21 01:48:37 +00:00
Descricao = "Offset" ,
2025-05-01 18:27:01 +00:00
Enviar = true ,
2025-12-10 16:37:47 +00:00
Escalar = true ,
2025-05-01 18:27:01 +00:00
QtdBytes = 2 ,
2025-12-16 19:33:06 +00:00
Valor = "0.0"
2025-05-01 18:27:01 +00:00
}
2025-05-30 20:11:31 +00:00
} ,
ValoresLeituras = new List < SensorValoresLeituraModel > ( )
{
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Iniciado ,
posicao = CanMessagePosicaoDados . Status ,
indice = 0 ,
} ,
new SensorValoresLeituraModel ( )
{
2025-12-16 17:17:26 +00:00
funcao = FuncoesPinout . LeituraBruta ,
2025-05-30 20:11:31 +00:00
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 0 ,
2025-12-16 17:17:26 +00:00
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Massa ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 1 ,
2025-05-30 20:11:31 +00:00
analise_health = true ,
maximo = 35 ,
minimo = 0 ,
nominal = 30 ,
unidade_medida = "Kg"
}
2025-05-01 18:27:01 +00:00
}
2024-02-21 19:40:38 +00:00
} ,
2026-06-09 13:39:44 +00:00
// pressao 36 ~ 40
new SensorModel ( )
{
ID = "BOTLAV" ,
ID_Num = 36 ,
Descricao = "Botão para lavagem do sistema hidráulico" ,
Componente = S_Code . sBOT ,
Aferir = true ,
Mandatorio = false ,
Funcoes = new List < FuncoesPinout > ( )
{
FuncoesPinout . Botao ,
} ,
Parametros = new List < SensorParametroModel > ( ) ,
ValoresLeituras = new List < SensorValoresLeituraModel > ( )
{
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Iniciado ,
posicao = CanMessagePosicaoDados . Status ,
indice = 0 ,
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Botao ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 0 ,
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . LeituraBruta ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 1 ,
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . EstadoLeitura ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 2 ,
} ,
}
} ,
2026-03-21 01:48:37 +00:00
// magnetico 41 ~ 50
2025-12-04 13:51:11 +00:00
new SensorModel ( )
{
ID = "MAGESQ" ,
Descricao = "Angulo Barra Esquerda" ,
2026-03-21 01:48:37 +00:00
ID_Num = 41 ,
2025-12-04 13:51:11 +00:00
Componente = S_Code . sMAG ,
Aferir = true ,
Mandatorio = true ,
Funcoes = new List < FuncoesPinout > ( )
{
FuncoesPinout . I2C ,
} ,
Parametros = new List < SensorParametroModel > ( )
{
new SensorParametroModel ( )
{
Descricao = "Endereço I2C" ,
Valor = "0x36" ,
QtdBytes = 1 ,
Escalar = false ,
Enviar = true
} ,
new SensorParametroModel ( )
{
Descricao = "Canal MUX" ,
Valor = "0" ,
QtdBytes = 1 ,
Escalar = false ,
Enviar = true
} ,
} ,
ValoresLeituras = new List < SensorValoresLeituraModel > ( )
{
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Iniciado ,
posicao = CanMessagePosicaoDados . Status ,
indice = 0 ,
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . LeituraBruta ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 0 ,
unidade_medida = ""
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . LeituraAngulo ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 1 ,
unidade_medida = "°"
} ,
}
} ,
new SensorModel ( )
{
ID = "MAGDIR" ,
Descricao = "Angulo Barra Direita" ,
2026-03-21 01:48:37 +00:00
ID_Num = 42 ,
2025-12-04 13:51:11 +00:00
Componente = S_Code . sMAG ,
Aferir = true ,
Mandatorio = true ,
Funcoes = new List < FuncoesPinout > ( )
{
FuncoesPinout . I2C ,
} ,
Parametros = new List < SensorParametroModel > ( )
{
new SensorParametroModel ( )
{
Descricao = "Endereço I2C" ,
Valor = "0x36" ,
QtdBytes = 1 ,
Escalar = false ,
Enviar = true
} ,
new SensorParametroModel ( )
{
Descricao = "Canal MUX" ,
Valor = "1" ,
QtdBytes = 1 ,
Escalar = false ,
Enviar = true
} ,
} ,
ValoresLeituras = new List < SensorValoresLeituraModel > ( )
{
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Iniciado ,
posicao = CanMessagePosicaoDados . Status ,
indice = 0 ,
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . LeituraBruta ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 0 ,
unidade_medida = ""
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . LeituraAngulo ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 1 ,
unidade_medida = "°"
} ,
}
} ,
2024-02-21 19:40:38 +00:00
} ,
2026-04-02 17:38:24 +00:00
// 51 ~ 60
2026-03-21 01:48:37 +00:00
BombasPressurizadoras = new List < AtuadorBombaModel > ( )
2025-12-16 17:17:26 +00:00
{
2026-03-21 01:48:37 +00:00
new AtuadorBombaModel ( )
2025-12-16 17:17:26 +00:00
{
2026-03-21 01:48:37 +00:00
ID = "BMBLN" ,
ID_Num = 51 ,
Sensor_ID_Num = 11 ,
ComandoAtuar = false ,
2026-04-02 17:38:24 +00:00
PressaoSP = 100 ,
2026-03-21 01:48:37 +00:00
Componente = S_Code . sBMB ,
Comandar = true ,
Mandatorio = true ,
2025-12-16 17:17:26 +00:00
Funcoes = new List < FuncoesPinout > ( )
{
2026-04-01 17:03:04 +00:00
FuncoesPinout . IN1 ,
FuncoesPinout . IN2 ,
2025-12-16 17:17:26 +00:00
} ,
ValoresLeituras = new List < SensorValoresLeituraModel > ( )
{
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Iniciado ,
posicao = CanMessagePosicaoDados . Status ,
indice = 0 ,
} ,
new SensorValoresLeituraModel ( )
{
2026-03-21 01:48:37 +00:00
funcao = FuncoesPinout . EstadoLeitura ,
2025-12-16 17:17:26 +00:00
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 0 ,
} ,
new SensorValoresLeituraModel ( )
{
2026-04-02 17:38:24 +00:00
funcao = FuncoesPinout . PotenciaSP ,
2026-03-21 01:48:37 +00:00
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 1 ,
2025-12-16 17:17:26 +00:00
} ,
new SensorValoresLeituraModel ( )
{
2026-04-02 17:38:24 +00:00
funcao = FuncoesPinout . Potencia ,
2025-12-16 17:17:26 +00:00
posicao = CanMessagePosicaoDados . Dados1 ,
2026-03-21 01:48:37 +00:00
indice = 2 ,
2025-12-16 17:17:26 +00:00
} ,
2026-03-21 01:48:37 +00:00
new SensorValoresLeituraModel ( )
{
2026-04-02 17:38:24 +00:00
funcao = FuncoesPinout . PressaoSP ,
2026-03-21 01:48:37 +00:00
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 3 ,
2026-04-02 17:38:24 +00:00
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Pressao ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 4 ,
2026-06-09 13:39:44 +00:00
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . ModoControleBomba ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 5 ,
2026-03-21 01:48:37 +00:00
}
2026-06-09 13:39:44 +00:00
} ,
Controle = new AtuadorBombaModel . BombaModoControleModel ( )
{
Modo = ModoControleBomba . PID ,
PotenciaMinPID = 40 ,
Kp = 6.0 ,
Ki = 0.2 ,
Kd = 0.0 ,
2025-12-16 17:17:26 +00:00
}
} ,
2026-03-21 01:48:37 +00:00
new AtuadorBombaModel ( )
2025-12-16 17:17:26 +00:00
{
2026-03-21 01:48:37 +00:00
ID = "BMBAGT" ,
ID_Num = 52 ,
Sensor_ID_Num = - 1 ,
ComandoAtuar = false ,
Componente = S_Code . sBMB ,
2026-04-02 17:38:24 +00:00
PotenciaSP = 100 ,
2026-03-21 01:48:37 +00:00
Comandar = true ,
Mandatorio = true ,
2025-12-16 17:17:26 +00:00
Funcoes = new List < FuncoesPinout > ( )
{
2026-04-01 17:03:04 +00:00
FuncoesPinout . IN1 ,
FuncoesPinout . IN2 ,
2025-12-16 17:17:26 +00:00
} ,
ValoresLeituras = new List < SensorValoresLeituraModel > ( )
{
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Iniciado ,
posicao = CanMessagePosicaoDados . Status ,
indice = 0 ,
} ,
new SensorValoresLeituraModel ( )
{
2026-03-21 01:48:37 +00:00
funcao = FuncoesPinout . EstadoLeitura ,
2025-12-16 17:17:26 +00:00
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 0 ,
} ,
2026-03-21 01:48:37 +00:00
new SensorValoresLeituraModel ( )
{
2026-04-02 17:38:24 +00:00
funcao = FuncoesPinout . PotenciaSP ,
2026-03-21 01:48:37 +00:00
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 1 ,
} ,
new SensorValoresLeituraModel ( )
{
2026-04-02 17:38:24 +00:00
funcao = FuncoesPinout . Potencia ,
2026-03-21 01:48:37 +00:00
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 2 ,
} ,
new SensorValoresLeituraModel ( )
{
2026-04-02 17:38:24 +00:00
funcao = FuncoesPinout . PressaoSP ,
2026-03-21 01:48:37 +00:00
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 3 ,
2026-04-02 17:38:24 +00:00
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Pressao ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 4 ,
2026-06-09 13:39:44 +00:00
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . ModoControleBomba ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 5 ,
2026-03-21 01:48:37 +00:00
}
2026-06-09 13:39:44 +00:00
} ,
Controle = new AtuadorBombaModel . BombaModoControleModel ( )
{
Modo = ModoControleBomba . OnOff ,
2025-12-16 17:17:26 +00:00
}
2026-03-21 01:48:37 +00:00
} ,
2025-12-16 17:17:26 +00:00
} ,
2026-04-02 17:38:24 +00:00
// 61 ~ 70
2026-03-21 01:48:37 +00:00
BicosPulverizadores = new List < AtuadorBicoModel > ( ) ,
2026-04-02 17:38:24 +00:00
2024-01-03 10:52:37 +00:00
} ;
2025-11-24 16:05:50 +00:00
for ( int i = 0 ; i < Variaveis . OperacaoEmAndamento . Parametros . QtdBicos ; i + + )
2024-01-03 10:52:37 +00:00
{
2025-04-09 21:11:40 +00:00
int posicao = ( i + 1 ) ;
2024-01-03 10:52:37 +00:00
Atuador . BicosPulverizadores . Add ( new AtuadorBicoModel ( )
{
2025-04-09 21:11:40 +00:00
ID = "B" + posicao . ToString ( "00" ) ,
2026-03-21 01:48:37 +00:00
ID_Num = 60 + posicao ,
2024-11-29 20:28:25 +00:00
Componente = S_Code . sBIC ,
2025-04-09 21:11:40 +00:00
Posicao = posicao ,
2025-12-02 18:42:15 +00:00
Inicializado = false ,
2026-04-01 11:26:37 +00:00
AnguloNeutro = 90 ,
AnguloControle = 90 ,
2026-02-26 19:57:22 +00:00
AnguloAbertura = 30 ,
2025-04-09 21:11:40 +00:00
Comandar = true ,
2025-05-07 16:54:45 +00:00
Mandatorio = true ,
2024-12-02 19:12:39 +00:00
ComandoAtuar = false ,
2025-04-09 21:11:40 +00:00
AtuacaoNivelAlto = true ,
2024-01-03 10:52:37 +00:00
Funcoes = new List < FuncoesPinout > ( )
{
FuncoesPinout . Solenoide ,
2026-03-21 01:48:37 +00:00
FuncoesPinout . Servo ,
2024-01-03 10:52:37 +00:00
} ,
2025-12-18 20:14:27 +00:00
VazaoMediaMLs = 0 ,
2025-05-30 20:11:31 +00:00
ValoresLeituras = new List < SensorValoresLeituraModel > ( )
{
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . Iniciado ,
posicao = CanMessagePosicaoDados . Status ,
indice = 0 ,
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . EstadoLeitura ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 0 ,
2025-12-16 17:17:26 +00:00
} ,
new SensorValoresLeituraModel ( )
{
funcao = FuncoesPinout . ServoAnguloLeitura ,
posicao = CanMessagePosicaoDados . Dados1 ,
indice = 1 ,
2025-05-30 20:11:31 +00:00
}
}
2024-01-03 10:52:37 +00:00
} ) ;
}
return Atuador ;
}
2024-12-02 19:12:39 +00:00
public void LimparDados < T > ( T _dados )
2024-07-18 18:00:14 +00:00
{
2024-12-02 19:12:39 +00:00
var Dados = _dados as AtuadorModel ;
2024-11-29 20:28:25 +00:00
Dados . DadosLeitura = new AtuadorMensagemJsonModel ( ) ;
Dados . DadosLeitura . Momento = DateTime . MinValue ;
2025-07-11 16:38:08 +00:00
Dados . AtuPronto = false ;
2025-02-06 19:01:41 +00:00
Dados . PercentualErvasTerreno = 0 ;
2024-12-02 19:12:39 +00:00
Dados . BombasPressurizadoras . ForEach ( x = > x . Funcoes = x . Funcoes . Distinct ( ) . ToList ( ) ) ;
2026-04-02 17:38:24 +00:00
2024-10-29 19:53:27 +00:00
ReiniciarLeituras ( Dados ) ;
}
2024-12-02 19:12:39 +00:00
public void ReiniciarLeituras ( AtuadorModel Dados )
2024-10-29 19:53:27 +00:00
{
2024-11-29 20:28:25 +00:00
Dados . Sensores . ForEach ( x = >
{
2025-06-06 20:46:08 +00:00
x . ValoresLeituras . ForEach ( l = >
{
l . atual = new CanCommandFreqModel < dynamic > ( ) ;
} ) ;
2024-11-29 20:28:25 +00:00
} ) ;
2024-10-29 19:53:27 +00:00
Dados . BicosPulverizadores . ForEach ( x = >
{
2024-12-02 19:12:39 +00:00
x . ComandoAtuar = false ;
2026-03-21 01:48:37 +00:00
x . AnguloControle = 0 ;
2025-12-19 12:01:58 +00:00
x . VazaoInstantaneaMLs = 0 ;
x . VolumeVazadoML = 0 ;
x . VazaoMediaMLs = 0 ;
x . TempoAtuado = 0 ;
x . Atuacoes = 0 ;
2025-06-06 20:46:08 +00:00
x . ValoresLeituras . ForEach ( l = >
{
l . atual = new CanCommandFreqModel < dynamic > ( ) ;
} ) ;
2024-07-18 18:00:14 +00:00
} ) ;
2024-10-29 19:53:27 +00:00
2024-11-29 20:28:25 +00:00
Dados . BombasPressurizadoras . ForEach ( x = >
2024-07-18 18:00:14 +00:00
{
2024-12-02 19:12:39 +00:00
x . ComandoAtuar = false ;
2026-04-02 17:38:24 +00:00
x . PotenciaSP = 0 ;
x . PressaoSP = 0 ;
2025-06-06 20:46:08 +00:00
x . ValoresLeituras . ForEach ( l = >
{
l . atual = new CanCommandFreqModel < dynamic > ( ) ;
} ) ;
2024-07-18 18:00:14 +00:00
} ) ;
2024-10-29 19:53:27 +00:00
2024-07-18 18:00:14 +00:00
Dados . VolumeVazaoAferido = 0 ;
2024-12-05 12:52:28 +00:00
Dados . _ultimoRegistroVazao = DateTime . MinValue ;
2025-12-19 12:01:58 +00:00
Dados . VolumeVazadoML = 0 ;
Dados . VazaoMediaMLs = 0 ;
2024-10-10 19:58:57 +00:00
Dados . TempoAtuado = 0 ;
2025-12-19 12:01:58 +00:00
Dados . AnguloBarraDireita = 0 ;
Dados . AnguloBarraEsquerda = 0 ;
Dados . PercentualErvasTerreno = 0 ;
2024-07-18 18:00:14 +00:00
}
2025-05-06 18:47:59 +00:00
public async Task < bool > VerificaDispositivoConectado ( )
2024-01-03 10:52:37 +00:00
{
2025-07-17 17:53:42 +00:00
if ( ! CanManager . CanService . IsConnected ) return false ;
2024-06-08 01:20:23 +00:00
2025-05-06 18:47:59 +00:00
if ( Variaveis . OperacaoEmAndamento . DispAtu = = null ) return false ;
2024-11-29 20:28:25 +00:00
2025-07-17 17:53:42 +00:00
CanManager . CanService . RegistrarHandler ( _EnderecoCAN_Rx , _AtuHandler ) ;
2024-06-08 01:20:23 +00:00
2025-05-06 18:47:59 +00:00
RequisitarDadosModulo ( Variaveis . ID_Num_sMOD , CanMessagePosicaoDados . Status , CanMessagePosicaoDados . Status , true ) ;
DateTime Inicio = DateTime . Now ;
bool Respondido ( ) = > Variaveis . OperacaoEmAndamento . DispAtu . Dados . DadosLeitura . UltimoComandoRespondido > Inicio ;
await FuncoesGlobais . AguardarCondicaoAsync ( Respondido , 500 , 50 ) ;
2024-06-08 01:20:23 +00:00
2025-07-23 15:14:50 +00:00
if ( Conectado )
2024-12-02 19:12:39 +00:00
{
2025-05-06 18:47:59 +00:00
DefinirDispositivo ( ) ;
Variaveis . OperacaoEmAndamento . DispAtu ? . EnviarProtocolosConfiguracao ( ) ;
2024-12-02 19:12:39 +00:00
}
2024-11-29 20:28:25 +00:00
2025-07-23 15:14:50 +00:00
return Conectado ;
2024-11-29 20:28:25 +00:00
}
2025-04-09 21:11:40 +00:00
private void DefinirDispositivo ( )
2024-11-29 20:28:25 +00:00
{
2025-04-09 21:11:40 +00:00
if ( ! SerialService . DispositivosMapeados . Any ( x = > x . Dispositivo = = Dispositivo & & x . Mod_ID = = Modulo_ID ) )
{
SerialService . DispositivosMapeados . Add ( new DispositivoDetalhesModel ( )
{
Dispositivo = DadosLeitura . Dispositivo ,
2025-07-17 17:53:42 +00:00
Endereco = CanManager . CanService . _portName ,
2025-04-09 21:11:40 +00:00
Versao = DadosLeitura . Versao . ToString ( ) ,
2025-05-06 18:47:59 +00:00
Mod_ID = Modulo_ID
2025-04-09 21:11:40 +00:00
} ) ;
2025-10-21 19:23:36 +00:00
Variaveis . OperacaoEmAndamento . ModsCalibragem [ Dispositivo ] = new Dictionary < string , bool > ( ) ;
2026-03-25 14:40:06 +00:00
Variaveis . OperacaoEmAndamento . Sensoriamento . InserirLog ( Dispositivo , StatusModulo . Conectado , 0 , "Dispositivo conectado" ) ;
2025-04-09 21:11:40 +00:00
}
2024-11-29 20:28:25 +00:00
}
2024-06-28 20:14:24 +00:00
2025-05-01 18:27:01 +00:00
public void RequisitarDadosModulo ( int ID_Num , CanMessagePosicaoDados posicaoTx , CanMessagePosicaoDados posicaoRx , bool aguardaResposta )
2024-11-29 20:28:25 +00:00
{
2025-05-01 18:27:01 +00:00
Variaveis . OperacaoEmAndamento . DispAtu ? . AdicionarMensagemFila ( ID_Num , posicaoTx , posicaoRx , null , aguardaResposta ) ;
2024-11-29 20:28:25 +00:00
}
2024-06-08 01:20:23 +00:00
2025-12-18 18:11:30 +00:00
public ( int , CanMessagePosicaoDados , byte [ ] ) ProtocoloComandoReset ( )
{
return (
Variaveis . ID_Num_sMOD ,
CanMessagePosicaoDados . Command1 ,
new byte [ ]
{
( byte ) Estado . Reset
}
) ;
}
2025-05-01 18:27:01 +00:00
public List < ( int , CanMessagePosicaoDados , byte [ ] ) > ProtocoloConfiguracao ( bool Conectar )
2024-11-29 20:28:25 +00:00
{
2025-04-09 21:11:40 +00:00
// Inicializar o dicionário
2025-05-01 18:27:01 +00:00
List < ( int , CanMessagePosicaoDados , byte [ ] ) > config = new List < ( int , CanMessagePosicaoDados , byte [ ] ) > ( ) ;
2025-04-09 21:11:40 +00:00
2025-04-10 20:59:50 +00:00
if ( ! DadosLeitura . Conectado )
2025-04-09 21:11:40 +00:00
{
// Adicionar configuração do ProtocoloMOD
var protocoloMOD = ModConfig ( Conectar ) ;
2025-04-14 12:52:19 +00:00
config . AddRange ( protocoloMOD ) ;
2025-04-09 21:11:40 +00:00
}
2025-04-24 21:11:33 +00:00
bool configurarTodos = ! DadosLeitura . Conectado & & Conectar ;
2025-04-10 20:59:50 +00:00
// Adicionar configurações dos Sensores que devem ser aferidos
2026-04-08 18:35:31 +00:00
//var sensoresConfig = SensoresConfig(Conectar, configurarTodos);
//config.AddRange(sensoresConfig);
2025-04-10 20:59:50 +00:00
2025-04-09 21:11:40 +00:00
// Adicionar configurações dos Bicos
2026-04-08 18:35:31 +00:00
//var bicosConfig = BicosConfig(Conectar, configurarTodos);
//config.AddRange(bicosConfig);
2025-04-09 21:11:40 +00:00
// Adicionar configurações das Bombas
2026-04-08 18:35:31 +00:00
//var bombasConfig = BombasConfig(Conectar, configurarTodos);
//config.AddRange(bombasConfig);
2025-04-09 21:11:40 +00:00
return config ;
2024-01-03 10:52:37 +00:00
}
2024-11-29 20:28:25 +00:00
2025-05-01 18:27:01 +00:00
private List < ( int , CanMessagePosicaoDados , byte [ ] ) > ModConfig ( bool Conectar )
2024-11-29 20:28:25 +00:00
{
2025-07-23 15:14:50 +00:00
var config = new List < byte >
2025-04-09 21:11:40 +00:00
{
( byte ) ( Conectar ? 1 : 0 ) ,
2026-04-08 20:10:57 +00:00
( byte ) ( _TaxaAmostragem / 1000 ) ,
2025-04-09 21:11:40 +00:00
( byte ) ( RequisitarDados ? 1 : 0 ) ,
} ;
2025-07-23 15:14:50 +00:00
config . AddRange ( PinoutModel . PinoProtocolo ( Pinout , Funcoes , false ) ) ;
2025-04-14 12:52:19 +00:00
2025-05-01 18:27:01 +00:00
return new List < ( int , CanMessagePosicaoDados , byte [ ] ) >
2025-04-14 12:52:19 +00:00
{
2025-07-23 15:14:50 +00:00
( Variaveis . ID_Num_sMOD , CanMessagePosicaoDados . Config1 , config . ToArray ( ) ) ,
2025-04-14 12:52:19 +00:00
} ;
2024-11-29 20:28:25 +00:00
}
2025-05-01 18:27:01 +00:00
private List < ( int , CanMessagePosicaoDados , byte [ ] ) > SensoresConfig ( bool Conectar , bool ConfigurarTodos )
2024-06-28 20:14:24 +00:00
{
2025-05-01 18:27:01 +00:00
var config = new List < ( int , CanMessagePosicaoDados , byte [ ] ) > ( ) ;
2024-06-28 20:14:24 +00:00
2025-04-24 21:11:33 +00:00
foreach ( var sensor in Sensores . Where ( x = > ( x . Aferir & & ( ConfigurarTodos ? true : x . Inicializado ! = Conectar ) ) | | ( ! x . Aferir & & x . Inicializado ) ) )
2024-06-28 20:14:24 +00:00
{
2025-04-24 21:11:33 +00:00
if ( ! sensor . Aferir & & sensor . Inicializado )
{
Conectar = false ;
}
2025-05-01 18:27:01 +00:00
( CanMessagePosicaoDados posicao , byte [ ] payload ) = sensor . ProtocoloConfiguracao ( Pinout , Conectar , Dispositivo ) ;
2025-04-09 21:11:40 +00:00
if ( payload ! = null )
{
2025-05-01 18:27:01 +00:00
config . Add ( ( sensor . ID_Num , posicao , payload ) ) ;
2025-04-09 21:11:40 +00:00
}
}
return config ;
}
2024-06-28 20:14:24 +00:00
2025-05-01 18:27:01 +00:00
private List < ( int , CanMessagePosicaoDados , byte [ ] ) > BicosConfig ( bool Conectar , bool ConfigurarTodos )
2025-04-09 21:11:40 +00:00
{
2025-05-01 18:27:01 +00:00
var config = new List < ( int , CanMessagePosicaoDados , byte [ ] ) > ( ) ;
2025-04-09 21:11:40 +00:00
2025-04-24 21:11:33 +00:00
foreach ( var bico in BicosPulverizadores . Where ( x = > ( x . Comandar & & ( ConfigurarTodos ? true : x . Inicializado ! = Conectar ) ) | | ( ! x . Comandar & & x . Inicializado ) ) )
2025-04-09 21:11:40 +00:00
{
2025-04-24 21:11:33 +00:00
if ( ! bico . Comandar & & bico . Inicializado )
{
Conectar = false ;
}
2025-05-01 18:27:01 +00:00
( CanMessagePosicaoDados posicao , var payload ) = bico . ProtocoloConfiguracao ( Pinout , Conectar ) ;
2025-04-09 21:11:40 +00:00
if ( payload ! = null )
{
2025-05-01 18:27:01 +00:00
config . Add ( ( bico . ID_Num , posicao , payload ) ) ;
2025-04-09 21:11:40 +00:00
}
2024-06-28 20:14:24 +00:00
}
2025-04-09 21:11:40 +00:00
return config ;
2024-06-28 20:14:24 +00:00
}
2024-01-03 10:52:37 +00:00
2025-05-01 18:27:01 +00:00
private List < ( int , CanMessagePosicaoDados , byte [ ] ) > BombasConfig ( bool Conectar , bool ConfigurarTodos )
2024-01-03 10:52:37 +00:00
{
2025-05-01 18:27:01 +00:00
var config = new List < ( int , CanMessagePosicaoDados , byte [ ] ) > ( ) ;
2025-04-09 21:11:40 +00:00
2025-04-24 21:11:33 +00:00
foreach ( var bomba in BombasPressurizadoras . Where ( x = > ( x . Comandar & & ( ConfigurarTodos ? true : x . Inicializado ! = Conectar ) ) | | ( ! x . Comandar & & x . Inicializado ) ) )
2025-04-09 21:11:40 +00:00
{
2025-04-24 21:11:33 +00:00
if ( ! bomba . Comandar & & bomba . Inicializado )
{
Conectar = false ;
}
2025-05-01 18:27:01 +00:00
List < ( CanMessagePosicaoDados , byte [ ] ) > dados = bomba . ProtocoloConfiguracao ( Pinout , Conectar ) ;
foreach ( var dado in dados )
2025-04-09 21:11:40 +00:00
{
2025-05-01 18:27:01 +00:00
config . Add ( ( bomba . ID_Num , dado . Item1 , dado . Item2 ) ) ;
2025-04-09 21:11:40 +00:00
}
}
return config ;
2024-11-29 20:28:25 +00:00
}
2024-11-27 17:38:56 +00:00
2025-12-16 17:17:26 +00:00
2024-01-03 10:52:37 +00:00
public void IniciarRegistrador ( )
{
2024-11-29 20:28:25 +00:00
if ( ! ( tmrRegistrador ? . IsRunning ? ? false ) )
2024-11-27 17:38:56 +00:00
{
LimparDados ( this ) ;
PararRegistrador ( ) ;
tmrRegistrador = new AsyncTaskTimerModel ( "tmrRegistrador_" + T_Code . Atu . ToString ( ) , tmrRegistrador_Tick , _TaxaAmostragem ) ;
tmrRegistrador . Start ( ) ;
}
}
2024-01-03 10:52:37 +00:00
2024-11-27 17:38:56 +00:00
public void PararRegistrador ( )
{
tmrRegistrador ? . Dispose ( ) ;
2024-01-03 10:52:37 +00:00
}
2024-11-27 17:38:56 +00:00
public async Task tmrRegistrador_Tick ( )
2024-06-14 09:37:22 +00:00
{
2025-12-18 18:11:30 +00:00
if ( Variaveis . Fechando ) return ;
2025-03-27 11:47:00 +00:00
2024-11-27 17:38:56 +00:00
tmrRegistrador . SetInterval ( _TaxaAmostragem ) ;
2024-12-05 12:52:28 +00:00
if ( SerialService . DispositivosMapeados . Any ( x = > x . Dispositivo = = T_Code . Atu ) & & ( _VezesLeituraReconexao > = _TempoReconexaoComponentes ) )
2024-11-29 20:28:25 +00:00
{
Variaveis . OperacaoEmAndamento . DispAtu ? . EnviarProtocolosConfiguracao ( ) ;
_VezesLeituraReconexao = 0 ;
}
else
{
_VezesLeituraReconexao + + ;
}
2025-04-10 20:59:50 +00:00
if ( DadosLeitura . Conectado )
2024-11-29 20:28:25 +00:00
{
2024-12-03 20:55:25 +00:00
if ( RequisitarDados )
{
2025-05-01 18:27:01 +00:00
RequisitarDadosModulo ( Variaveis . ID_Num_sTOD , CanMessagePosicaoDados . DadosAll , CanMessagePosicaoDados . DadosAll , true ) ;
2024-12-03 20:55:25 +00:00
}
2025-09-16 13:31:32 +00:00
VerificaControleLeitura ( ) ;
2024-11-29 20:28:25 +00:00
}
2025-04-16 16:44:06 +00:00
AtualizaComponentesIniciados ( ) ;
}
2024-11-29 20:28:25 +00:00
2025-09-16 13:31:32 +00:00
private void VerificaControleLeitura ( )
{
2025-12-18 18:11:30 +00:00
if ( Variaveis . Fechando ) return ;
2026-04-01 11:26:37 +00:00
bool operacaoConcluida = Variaveis . OperacaoEmAndamento . Sensoriamento . StatusOperacao = = StatusOperacao . Concluido ;
2026-04-02 17:38:24 +00:00
bool pulverizadorAutomatico = Variaveis . OperacaoEmAndamento . Parametros ? . Controle ? . PulverizadorAutomatico ? ? false ;
2026-04-01 11:26:37 +00:00
foreach ( var bico in BicosPulverizadores . Where ( x = > x . Inicializado ) )
2025-09-16 13:31:32 +00:00
{
2026-04-01 11:26:37 +00:00
bool statusDesejado = bico . Comandar & & bico . ComandoAtuar ;
if ( pulverizadorAutomatico )
statusDesejado & = ! operacaoConcluida & & Variaveis . OperacaoEmAndamento . Iniciado ;
Estado estadoDesejado = statusDesejado ? Estado . Ligado : Estado . Desligado ;
double anguloDesejado = statusDesejado ? bico . AnguloControle : bico . AnguloNeutro ;
bool estadoDivergente = estadoDesejado ! = bico . _EstadoLeitura ;
bool anguloDivergente = statusDesejado & & Math . Abs ( anguloDesejado - bico . _AnguloBicoLeitura ) > 0.01 ;
if ( estadoDivergente | | anguloDivergente )
2025-09-16 13:31:32 +00:00
{
2026-04-01 11:26:37 +00:00
GeneralJoystick . EnviarComandoAtuador (
bico . Componente ,
bico . ID ,
Status : statusDesejado ,
2026-04-02 17:38:24 +00:00
Valores : new List < double? > ( ) { anguloDesejado }
2026-04-01 11:26:37 +00:00
) ;
2025-09-16 13:31:32 +00:00
}
2025-12-17 19:27:06 +00:00
}
2025-09-16 13:31:32 +00:00
2026-04-01 11:26:37 +00:00
foreach ( var bomba in BombasPressurizadoras . Where ( x = > x . Inicializado ) )
2025-12-17 19:27:06 +00:00
{
2026-04-01 11:26:37 +00:00
bool statusDesejado = bomba . Comandar & & bomba . ComandoAtuar ;
if ( pulverizadorAutomatico )
statusDesejado & = ContadorCarga . PulverizadorLiberado & & ! operacaoConcluida & & Variaveis . OperacaoEmAndamento . Iniciado ;
Estado estadoDesejado = statusDesejado ? Estado . Ligado : Estado . Desligado ;
2026-04-02 17:38:24 +00:00
double potenciaDesejada = statusDesejado ? bomba . PotenciaSP : 0 ;
double pressaoDesejada = statusDesejado ? bomba . PressaoSP : 0 ;
2025-10-24 11:45:47 +00:00
2026-04-01 11:26:37 +00:00
bool estadoDivergente = estadoDesejado ! = bomba . _EstadoLeitura ;
2026-04-02 17:38:24 +00:00
bool potenciaDivergente = Math . Abs ( bomba . _PotenciaSP - potenciaDesejada ) > 1 ;
2026-04-01 11:26:37 +00:00
bool pressaoDivergente = bomba . Sensor_ID_Num > - 1 & & Math . Abs ( bomba . _PressaoSP - pressaoDesejada ) > 0.05 ;
2026-04-02 17:38:24 +00:00
if ( estadoDivergente | | potenciaDivergente | | pressaoDivergente )
2026-04-01 11:26:37 +00:00
{
GeneralJoystick . EnviarComandoAtuador (
bomba . Componente ,
bomba . ID ,
Status : statusDesejado ,
2026-06-09 13:39:44 +00:00
Valores : new List < double? > ( ) { potenciaDesejada , pressaoDesejada } ,
Comando : CanMessagePosicaoDados . Command1
2026-04-01 11:26:37 +00:00
) ;
2025-09-16 13:31:32 +00:00
}
2025-12-17 19:27:06 +00:00
}
2025-09-16 13:31:32 +00:00
}
2025-04-16 16:44:06 +00:00
private void AtualizaComponentesIniciados ( )
{
DateTime Agora = DateTime . Now ;
bool modConectado = DadosLeitura . UltimoComandoRespondido . AddMilliseconds ( TempoLimiteConexao ) > Agora ;
if ( ! modConectado & & DadosLeitura . Conectado )
{
DadosLeitura . Conectado = false ;
}
2025-05-30 20:11:31 +00:00
foreach ( var bomba in BombasPressurizadoras . Where ( x = > x . Inicializado & & x . UltimaLeitura . AddMilliseconds ( TempoLimiteConexao ) < Agora ) )
2025-04-16 16:44:06 +00:00
{
2025-05-30 20:11:31 +00:00
bomba . Inicializado = false ;
2025-04-16 16:44:06 +00:00
}
2025-05-30 20:11:31 +00:00
foreach ( var bico in BicosPulverizadores . Where ( x = > x . Inicializado & & x . UltimaLeitura . AddMilliseconds ( TempoLimiteConexao ) < Agora ) )
2025-04-16 16:44:06 +00:00
{
2025-05-30 20:11:31 +00:00
bico . Inicializado = false ;
2025-04-16 16:44:06 +00:00
}
2025-05-30 20:11:31 +00:00
foreach ( var sensor in Sensores . Where ( x = > x . Inicializado & & x . UltimaLeitura . AddMilliseconds ( TempoLimiteConexao ) < Agora ) )
2025-04-16 16:44:06 +00:00
{
2025-05-30 20:11:31 +00:00
sensor . Inicializado = false ;
2025-04-16 16:44:06 +00:00
}
}
2025-07-11 16:38:08 +00:00
2025-10-24 11:45:47 +00:00
public async Task < bool > RealizarTestesIniciais ( bool forcar )
2025-07-11 16:38:08 +00:00
{
2026-04-01 11:26:37 +00:00
var calAtu = Variaveis . OperacaoEmAndamento . ModsCalibragem [ Dispositivo ] ;
2025-07-11 16:38:08 +00:00
2025-10-21 19:23:36 +00:00
// Ligar bomba
foreach ( var Bomba in BombasPressurizadoras . Where ( x = > x . Comandar ) )
2025-07-11 16:38:08 +00:00
{
2025-10-21 19:23:36 +00:00
calAtu . TryGetValue ( Bomba . ID , out var cal ) ;
2025-10-24 11:45:47 +00:00
if ( ! forcar & & cal & & calAtu [ Bomba . ID ] ) continue ;
2025-10-21 19:23:36 +00:00
calAtu [ Bomba . ID ] = false ;
// Sem herbicida no reservatorio, bomba nao precisa ligar
2025-12-09 16:47:53 +00:00
if ( ! Bomba . Inicializado | | ContadorCarga . PercentualAtual < VariaveisEquipamento . PercentualReservatorioMin )
2025-10-21 19:23:36 +00:00
{
2026-04-01 11:26:37 +00:00
Variaveis . MostrarLog ( $"[AtuadorModel] [RealizarTestesIniciais] Bomba não iniciada ou nível do reservatório baixo, não irá ligar a bomba {Bomba.ID}" ) ;
continue ;
2025-10-21 19:23:36 +00:00
}
2026-04-02 17:38:24 +00:00
Bomba . PotenciaSP = 100 ;
2026-06-09 13:39:44 +00:00
if ( Bomba . ID = = "BMBLN" )
{
Bomba . Controle . Modo = Variaveis . OperacaoEmAndamento . Parametros . Controle . AtuModoControle ;
GeneralJoystick . EnviarComandoAtuador ( Bomba . Componente , Bomba . ID , Status : true , Valores : new List < double? > ( ) { ( int ) Bomba . Controle . Modo , Bomba . Controle . PotenciaMinPID , Bomba . Controle . Kp , Bomba . Controle . Ki , Bomba . Controle . Kd } , Comando : CanMessagePosicaoDados . Command2 , Forcar : true ) ;
Bomba . PressaoSP = Variaveis . OperacaoEmAndamento . Parametros . Controle . AtuPressaoLinha ;
GeneralJoystick . EnviarComandoAtuador ( Bomba . Componente , Bomba . ID , Status : true , Valores : new List < double? > ( ) { Bomba . PotenciaSP , Bomba . PressaoSP } , Comando : CanMessagePosicaoDados . Command1 , Forcar : true ) ;
}
else
{
Bomba . PressaoSP = - 1 ;
GeneralJoystick . EnviarComandoAtuador ( Bomba . Componente , Bomba . ID , Status : true , Valores : new List < double? > ( ) { Bomba . PotenciaSP , Bomba . PressaoSP } , Comando : CanMessagePosicaoDados . Command1 , Forcar : true ) ;
}
2026-04-01 11:26:37 +00:00
if ( Bomba . Sensor_ID_Num = = - 1 )
{
Variaveis . MostrarLog ( $"[AtuadorModel] [RealizarTestesIniciais] Bomba {Bomba.ID} não possui um sensor de pressão, será controlada mecanicamente pelo pressostato" ) ;
calAtu [ Bomba . ID ] = true ;
continue ;
}
2025-07-11 16:38:08 +00:00
2025-10-21 19:23:36 +00:00
await FuncoesGlobais . AguardarCondicaoAsync ( Bomba . AtingiuPressao , 3000 , 200 ) ;
bool BombaOk = Bomba . AtingiuPressao ( ) ;
if ( BombaOk )
{
calAtu [ Bomba . ID ] = true ;
}
else
{
foreach ( var Bico in BicosPulverizadores . Where ( x = > x . Comandar & & x . Inicializado ) )
{
2026-04-01 11:26:37 +00:00
GeneralJoystick . EnviarComandoAtuador ( Bico . Componente , Bico . ID , Status : true , Forcar : true ) ;
2025-10-21 19:23:36 +00:00
}
2025-07-11 16:38:08 +00:00
2025-10-21 19:23:36 +00:00
await Task . Delay ( 3000 ) ;
2025-07-11 16:38:08 +00:00
2025-10-21 19:23:36 +00:00
foreach ( var Bico in BicosPulverizadores . Where ( x = > x . Comandar & & x . Inicializado ) )
{
2026-04-01 11:26:37 +00:00
GeneralJoystick . EnviarComandoAtuador ( Bico . Componente , Bico . ID , Status : false , Forcar : true ) ;
2025-10-21 19:23:36 +00:00
}
await FuncoesGlobais . AguardarCondicaoAsync ( Bomba . AtingiuPressao , 4000 , 200 ) ;
BombaOk = Bomba . AtingiuPressao ( ) ;
2026-04-01 11:26:37 +00:00
calAtu [ Bomba . ID ] = BombaOk ;
2025-10-21 19:23:36 +00:00
}
2025-07-11 16:38:08 +00:00
}
// Testar os bicos
2025-10-21 19:23:36 +00:00
foreach ( var Bico in BicosPulverizadores . Where ( x = > x . Comandar ) )
2025-07-11 16:38:08 +00:00
{
2025-10-21 19:23:36 +00:00
calAtu . TryGetValue ( Bico . ID , out var cal ) ;
2025-10-24 11:45:47 +00:00
if ( ! forcar & & cal & & calAtu [ Bico . ID ] ) continue ;
2025-10-21 19:23:36 +00:00
calAtu [ Bico . ID ] = false ;
2025-07-11 16:38:08 +00:00
if ( Bico . Inicializado )
{
2026-04-01 11:26:37 +00:00
GeneralJoystick . EnviarComandoAtuador ( Bico . Componente , Bico . ID , Status : true , Forcar : true ) ;
2025-07-11 16:38:08 +00:00
await Task . Delay ( 200 ) ;
2026-04-01 11:26:37 +00:00
GeneralJoystick . EnviarComandoAtuador ( Bico . Componente , Bico . ID , Status : false , Forcar : true ) ;
await Task . Delay ( 200 ) ;
2025-10-21 19:23:36 +00:00
calAtu [ Bico . ID ] = true ;
2025-07-11 16:38:08 +00:00
}
}
await Task . Delay ( 1000 ) ;
2025-10-21 19:23:36 +00:00
bool sucesso = calAtu . All ( x = > x . Value ) ;
return sucesso ;
2025-07-11 16:38:08 +00:00
}
2025-10-24 11:45:47 +00:00
public List < Task > RealizarCalibragemAsync ( bool forcar )
2025-07-11 16:38:08 +00:00
{
2025-07-17 11:19:42 +00:00
List < Task > tasks = new List < Task > ( ) ;
2025-07-11 16:38:08 +00:00
var DispAtu = Variaveis . OperacaoEmAndamento . DispAtu ;
if ( DispAtu ! = null )
2025-10-24 11:45:47 +00:00
{
tasks . Add ( DispAtu . Dados . RealizarTestesIniciais ( forcar ) . ContinueWith ( t = > {
2025-07-17 11:19:42 +00:00
if ( t . IsFaulted )
2026-04-01 11:26:37 +00:00
Variaveis . MostrarLog ( $"[AtuadorModel] [RealizarCalibragemAsync] Erro no referenciamento do módulo {Modulo_ID}: {t.Exception?.InnerException?.Message}" ) ;
2025-07-17 11:19:42 +00:00
if ( t . IsCompleted )
2025-10-21 19:23:36 +00:00
{
var calAtu = Variaveis . OperacaoEmAndamento . ModsCalibragem [ T_Code . Atu ] ;
var v = calAtu . Select ( x = > $"{x.Key} " + ( x . Value ? "Sim" : "Não" ) ) ;
2026-04-01 11:26:37 +00:00
Variaveis . MostrarLog ( $"[AtuadorModel] [RealizarCalibragemAsync] Task de referenciamento do módulo {Modulo_ID} finalizada: " + string . Join ( ", " , v ) ) ;
2025-10-21 19:23:36 +00:00
}
2025-07-17 11:19:42 +00:00
} ) ) ;
2025-10-24 11:45:47 +00:00
}
2025-07-17 11:19:42 +00:00
return tasks ;
2025-07-11 16:38:08 +00:00
}
2025-12-05 18:25:29 +00:00
public void RequisitarDadosSensoresExternos ( )
{
if ( SensorAnguloBarraEsquerda ! = null )
RequisitarDadosModulo ( SensorAnguloBarraEsquerda . ID_Num , CanMessagePosicaoDados . Dados1 , CanMessagePosicaoDados . Dados1 , true ) ;
if ( SensorAnguloBarraDireita ! = null )
RequisitarDadosModulo ( SensorAnguloBarraDireita . ID_Num , CanMessagePosicaoDados . Dados1 , CanMessagePosicaoDados . Dados1 , true ) ;
}
public void AtualizarDadosSensoresExternos ( S_Code componente , int id_num )
{
switch ( componente )
{
case S_Code . sMAG :
{
var sensor = Sensores . FirstOrDefault ( x = > x . ID_Num = = id_num ) ;
2025-12-17 19:27:06 +00:00
if ( sensor = = null ) return ;
2025-12-05 18:25:29 +00:00
double angulo = sensor . ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . LeituraAngulo ) ? . atual ? . valor ? ? double . NaN ;
if ( sensor . ID_Num = = SensorAnguloBarraEsquerda . ID_Num )
AnguloBarraEsquerda = angulo ;
else if ( sensor . ID_Num = = SensorAnguloBarraDireita . ID_Num )
AnguloBarraDireita = angulo ;
}
break ;
2025-12-17 19:27:06 +00:00
case S_Code . sBIC :
{
var bico = BicosPulverizadores . FirstOrDefault ( x = > x . ID_Num = = id_num ) ;
if ( bico = = null ) return ;
2025-12-19 12:01:58 +00:00
if ( bico . _estadoLeituraAnterior = = Estado . Desligado & & bico . _EstadoLeitura = = Estado . Ligado )
2025-12-17 19:27:06 +00:00
{
2025-12-19 12:01:58 +00:00
bico . Atuacoes + + ;
bico . _estadoLeituraAnterior = bico . _EstadoLeitura ;
2025-12-17 19:27:06 +00:00
}
}
break ;
2025-12-05 18:25:29 +00:00
}
}
2024-01-03 10:52:37 +00:00
}
public class AtuadorBicoModel
{
public string ID { get ; set ; }
2025-04-09 21:11:40 +00:00
public int ID_Num { get ; set ; }
2024-01-03 10:52:37 +00:00
public int Posicao { get ; set ; }
2024-11-29 20:28:25 +00:00
public S_Code Componente { get ; set ; } = S_Code . sBIC ;
public bool AtuacaoNivelAlto { get ; set ; }
2026-04-01 11:26:37 +00:00
public double AnguloNeutro { get ; set ; }
2025-12-02 18:42:15 +00:00
public double AnguloControle { get ; set ; }
public double AnguloAbertura { get ; set ; }
2025-12-17 19:27:06 +00:00
public bool ComandoAtuar { get ; set ; }
2024-01-03 10:52:37 +00:00
public bool Comandar { get ; set ; }
2025-05-07 16:54:45 +00:00
public bool Mandatorio { get ; set ; }
public bool Liberado
{
get
{
return ! Mandatorio | | ( Comandar & & Inicializado ) ;
}
}
2024-01-03 10:52:37 +00:00
public List < FuncoesPinout > Funcoes { get ; set ; }
2025-12-18 20:14:27 +00:00
public double VazaoMediaMLs { get ; set ; }
public double VazaoInstantaneaMLs { get ; set ; }
public double VolumeVazadoML { get ; set ; }
2025-05-30 20:11:31 +00:00
public bool Inicializado { get ; set ; }
public DateTime UltimaLeitura
2024-11-29 20:28:25 +00:00
{
get
{
2025-05-30 20:11:31 +00:00
return ValoresLeituras . OrderByDescending ( x = > x . atual . lidoEm ) . FirstOrDefault ( ) ? . atual ? . lidoEm ? ? DateTime . MinValue ;
2024-11-29 20:28:25 +00:00
}
}
2025-12-15 13:41:05 +00:00
public List < SensorValoresLeituraModel > ValoresLeituras { get ; set ; }
2025-12-19 12:01:58 +00:00
public Estado _estadoLeituraAnterior { get ; set ; } = Estado . Desligado ;
2025-12-17 19:27:06 +00:00
public Estado _EstadoLeitura = > ( Estado ) ( ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . EstadoLeitura ) ? . atual ? . valor ? ? 0 ) ;
2025-12-16 19:33:06 +00:00
public int _AnguloBicoLeitura = > ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . LeituraAngulo ) ? . atual ? . valor ? ? 0 ;
2024-01-03 10:52:37 +00:00
2025-05-01 18:27:01 +00:00
public ( CanMessagePosicaoDados , byte [ ] ) ProtocoloConfiguracao ( PinoutDataModel pinout , bool conectar )
2024-01-03 10:52:37 +00:00
{
2025-04-09 21:11:40 +00:00
var pino = pinout . Pinos . FirstOrDefault ( p = > p . ComponenteID = = ID ) ;
2025-05-01 18:27:01 +00:00
var data = new byte [ ]
2024-04-15 10:57:37 +00:00
{
2025-04-11 20:13:15 +00:00
( byte ) Componente ,
2025-04-09 21:11:40 +00:00
( byte ) ( conectar ? 1 : 0 ) ,
( byte ) ( AtuacaoNivelAlto ? 1 : 0 ) ,
2026-03-21 01:48:37 +00:00
0x00 , //(byte)Servo_ID_Num,
2025-04-09 21:11:40 +00:00
( byte ) ( pino ? . Barramento ? ? TiposBarramentos . CONTROLADOR ) ,
( byte ) ( pino ? . Pino ? ? PinoutUtils . PINO_INVALIDO )
2024-04-15 10:57:37 +00:00
} ;
2025-05-01 18:27:01 +00:00
return ( CanMessagePosicaoDados . Config1 , data ) ;
2024-01-03 10:52:37 +00:00
}
2025-05-01 18:27:01 +00:00
public ( int , CanMessagePosicaoDados , byte [ ] ) ProtocoloComando ( )
2024-01-03 10:52:37 +00:00
{
2025-04-09 21:11:40 +00:00
return (
2025-05-01 18:27:01 +00:00
ID_Num ,
CanMessagePosicaoDados . Command1 ,
2025-04-09 21:11:40 +00:00
new byte [ ]
{
2025-12-16 17:17:26 +00:00
( byte ) ( ComandoAtuar ? Estado . Ligado : Estado . Desligado ) ,
( byte ) AnguloControle
2025-04-09 21:11:40 +00:00
}
) ;
2024-01-03 10:52:37 +00:00
}
2024-03-11 20:04:48 +00:00
2025-12-17 19:27:06 +00:00
public List < List < double [ ] > > TrechosAtuado { get ; set ; } = new List < List < double [ ] > > ( ) ;
2025-12-19 12:01:58 +00:00
public int Atuacoes { get ; set ; } = 0 ;
public double TempoAtuado { get ; set ; } = 0 ;
2024-10-29 19:53:27 +00:00
2024-03-11 20:04:48 +00:00
public AtuadorBicoModel Clone ( )
{
AtuadorBicoModel clone = new AtuadorBicoModel ( )
{
2024-12-06 20:19:59 +00:00
Comandar = Comandar ,
AtuacaoNivelAlto = AtuacaoNivelAlto ,
Atuacoes = Atuacoes ,
ComandoAtuar = ComandoAtuar ,
2025-12-02 18:42:15 +00:00
AnguloAbertura = AnguloAbertura ,
AnguloControle = AnguloControle ,
Inicializado = Inicializado ,
Mandatorio = Mandatorio ,
2024-12-06 20:19:59 +00:00
Componente = Componente ,
Funcoes = Funcoes ,
ID = ID ,
2025-04-09 21:11:40 +00:00
ID_Num = ID_Num ,
2025-12-19 12:01:58 +00:00
VolumeVazadoML = VolumeVazadoML ,
TrechosAtuado = TrechosAtuado ,
VazaoInstantaneaMLs = VazaoInstantaneaMLs ,
_estadoLeituraAnterior = _estadoLeituraAnterior ,
2025-05-30 20:11:31 +00:00
ValoresLeituras = new List < SensorValoresLeituraModel > ( ValoresLeituras ) ,
2025-12-18 20:14:27 +00:00
VazaoMediaMLs = VazaoMediaMLs ,
2024-12-06 20:19:59 +00:00
Posicao = Posicao ,
2025-12-19 12:01:58 +00:00
TempoAtuado = TempoAtuado ,
2024-03-11 20:04:48 +00:00
} ;
return clone ;
}
2024-01-03 10:52:37 +00:00
}
2024-04-01 11:03:25 +00:00
public class AtuadorBombaModel
{
public string ID { get ; set ; }
2025-04-09 21:11:40 +00:00
public int ID_Num { get ; set ; }
2024-12-02 19:12:39 +00:00
public bool ComandoAtuar { get ; set ; }
2026-04-02 17:38:24 +00:00
public double PotenciaSP { get ; set ; }
public double PressaoSP { get ; set ; }
2024-11-29 20:28:25 +00:00
public S_Code Componente { get ; set ; } = S_Code . sBMB ;
2025-12-16 17:17:26 +00:00
public int Sensor_ID_Num { get ; set ; }
2024-04-01 11:03:25 +00:00
public bool Comandar { get ; set ; }
2025-05-07 16:54:45 +00:00
public bool Mandatorio { get ; set ; }
public bool Liberado
{
get
{
return ! Mandatorio | | ( Comandar & & Inicializado ) ;
}
}
2025-12-15 13:41:05 +00:00
public List < FuncoesPinout > Funcoes { get ; set ; }
2025-05-30 20:11:31 +00:00
public bool Inicializado { get ; set ; }
public DateTime UltimaLeitura
2024-12-02 19:12:39 +00:00
{
get
{
2025-05-30 20:11:31 +00:00
return ValoresLeituras . OrderByDescending ( x = > x . atual . lidoEm ) . FirstOrDefault ( ) ? . atual ? . lidoEm ? ? DateTime . MinValue ;
2024-12-03 20:55:25 +00:00
}
}
2025-12-15 13:41:05 +00:00
public List < SensorValoresLeituraModel > ValoresLeituras { get ; set ; }
2026-06-09 13:39:44 +00:00
public BombaModoControleModel Controle { get ; set ; }
2025-12-16 17:17:26 +00:00
public Estado _EstadoLeitura = > ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . EstadoLeitura ) ? . atual ? . valor ? ? Estado . Desligado ;
public double _Potencia = > ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . Potencia ) ? . atual ? . valor ? ? 0 ;
2025-12-17 19:27:06 +00:00
public bool _BombaLigada = > _Potencia > 0 ;
public double _PressaoSP = > ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . PressaoSP ) ? . atual ? . valor ? ? 0 ;
2026-04-02 17:38:24 +00:00
public double _PotenciaSP = > ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . PotenciaSP ) ? . atual ? . valor ? ? 0 ;
public double _PressaoAtual = > ValoresLeituras ? . FirstOrDefault ( x = > x . funcao = = FuncoesPinout . Pressao ) ? . atual ? . valor ? ? 0 ;
2025-12-16 17:17:26 +00:00
2024-04-01 11:03:25 +00:00
2024-11-29 20:28:25 +00:00
2024-04-01 11:03:25 +00:00
2024-11-29 20:28:25 +00:00
2025-05-01 18:27:01 +00:00
public List < ( CanMessagePosicaoDados , byte [ ] ) > ProtocoloConfiguracao ( PinoutDataModel pinout , bool conectar )
2024-04-01 11:03:25 +00:00
{
2025-04-14 12:52:19 +00:00
List < byte > config1 = new List < byte > ( )
2024-04-15 10:57:37 +00:00
{
2025-04-11 20:13:15 +00:00
( byte ) Componente ,
2025-04-09 21:11:40 +00:00
( byte ) ( conectar ? 1 : 0 ) ,
2026-04-02 17:38:24 +00:00
( byte ) PressaoSP ,
2025-12-16 17:17:26 +00:00
( byte ) Sensor_ID_Num ,
2026-04-01 17:03:04 +00:00
( byte ) ( pinout . Pinos . FirstOrDefault ( x = > x . ComponenteID = = ID & & x . Funcao = = FuncoesPinout . IN1 ) ? . Pino ? ? PinoutUtils . PINO_INVALIDO ) ,
( byte ) ( pinout . Pinos . FirstOrDefault ( x = > x . ComponenteID = = ID & & x . Funcao = = FuncoesPinout . IN2 ) ? . Pino ? ? PinoutUtils . PINO_INVALIDO ) ,
2025-04-14 12:52:19 +00:00
} ;
2025-04-10 20:59:50 +00:00
2025-05-01 18:27:01 +00:00
return new List < ( CanMessagePosicaoDados , byte [ ] ) > ( )
2025-04-16 16:44:06 +00:00
{
2025-05-01 18:27:01 +00:00
( CanMessagePosicaoDados . Config1 , config1 . ToArray ( ) ) ,
} ;
2024-04-01 11:03:25 +00:00
}
2026-06-09 13:39:44 +00:00
public ( int , CanMessagePosicaoDados , byte [ ] ) ProtocoloComando ( CanMessagePosicaoDados comando )
2024-04-01 11:03:25 +00:00
{
2026-06-09 13:39:44 +00:00
byte ConverterPIDParaByte ( double valor )
{
// Escala x10:
// 8.0 -> 80
// 0.4 -> 4
// 1.5 -> 15
valor = FuncoesMatematicas . Clamp ( valor , 0.0 , 25.5 ) ;
return ( byte ) Math . Round ( valor * 10.0 ) ;
}
switch ( comando )
{
case CanMessagePosicaoDados . Command1 :
return (
ID_Num ,
comando ,
new byte [ ]
{
( byte ) ( ComandoAtuar ? Estado . Ligado : Estado . Desligado ) ,
( byte ) ( PotenciaSP ) ,
( byte ) ( PressaoSP )
}
) ;
case CanMessagePosicaoDados . Command2 :
return (
ID_Num ,
comando ,
new byte [ ]
{
( byte ) Controle . Modo ,
( byte ) Controle . PotenciaMinPID ,
ConverterPIDParaByte ( Controle . Kp ) ,
ConverterPIDParaByte ( Controle . Ki ) ,
ConverterPIDParaByte ( Controle . Kd ) ,
}
) ;
default :
throw new ArgumentOutOfRangeException (
nameof ( comando ) ,
comando ,
"Comando CAN não suportado pela bomba pressurizadora." ) ;
}
2024-04-01 11:03:25 +00:00
}
2026-04-02 17:38:24 +00:00
public bool AtingiuPressao ( ) = > _PressaoAtual > = Variaveis . OperacaoEmAndamento . Parametros . Controle . AtuPressaoLinha ;
2025-10-21 19:23:36 +00:00
2026-06-09 13:39:44 +00:00
public class BombaModoControleModel
{
public ModoControleBomba Modo { get ; set ; } = ModoControleBomba . OnOff ;
public double PotenciaMinPID { get ; set ; } = 30.0 ;
public double Kp { get ; set ; } = 6.0 ;
public double Ki { get ; set ; } = 0.2 ;
public double Kd { get ; set ; } = 0.0 ;
}
2024-04-01 11:03:25 +00:00
}
2024-04-02 18:33:15 +00:00
public class CalibragemVazao
{
public bool Calibrando { get ; set ; } = false ;
public DateTime IniciadoEm { get ; set ; }
public double TempoCalibragem { get ; set ; } = 10000.0 ;
public double VolumeComputado { get ; set ; } = 0 ;
public List < double > PressoesAferidas { get ; set ; } = new List < double > ( ) ;
public double MassaInicial { get ; set ; } = 0.0 ;
public double MassaFinal { get ; set ; } = 0.0 ;
public int QtdPulsos { get ; set ; } = 0 ;
public double Periodo { get ; set ; } = 0.0 ;
public double PressaoMedia
{
get
{
return PressoesAferidas . Average ( ) ;
}
}
public double MassaPerdida
{
get
{
return ( MassaInicial - MassaFinal ) * 1000 ;
}
}
public double Q
{
get
{
return ( double ) VolumeComputado / ( double ) Periodo ;
}
}
public double VolumeCalculado { get ; set ; } = 0.0 ;
public double d
{
get
{
return ( double ) MassaPerdida / ( double ) VolumeComputado ;
}
}
public double x
{
get
{
return ( double ) VolumeComputado / ( double ) QtdPulsos ;
}
}
public double Q2
{
get
{
return ( double ) x * ( double ) QtdPulsos ;
}
}
}
2024-04-01 11:03:25 +00:00
2024-10-29 19:53:27 +00:00
public class AtuadorFuncoesGerais
{
public static void DesenharAtuadores ( object sender , PaintEventArgs e , List < AtuBicoSensoriamentoLogModel > Bicos , bool BombaLigada , double PressaoLinha , double TempoBombaAtuada )
{
Panel myPanel = ( Panel ) sender ;
// Habilita o double buffering temporariamente
myPanel . GetType ( ) . GetProperty ( "DoubleBuffered" ,
System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . NonPublic )
? . SetValue ( myPanel , true , null ) ;
Graphics g = e . Graphics ;
int QuantidadeBicos = Bicos . Count ;
int panelWidth = myPanel . Width ;
int circleDiameter = 40 ; // Diâmetro dos círculos grandes
int smallCircleDiameter = circleDiameter / 2 ; // Diâmetro dos círculos pequenos
int spaceBetweenCircles = ( panelWidth - ( circleDiameter * QuantidadeBicos ) ) / ( QuantidadeBicos + 1 ) ;
int yPosition = ( myPanel . Height - circleDiameter ) / 3 ; // Centralizado verticalmente
for ( int i = 0 ; i < QuantidadeBicos ; i + + )
{
int xPosition = spaceBetweenCircles + ( i * ( circleDiameter + spaceBetweenCircles ) ) ;
// Desenha o contorno do círculo
g . DrawEllipse ( Pens . Red , xPosition , yPosition , circleDiameter , circleDiameter ) ;
// Preenche o círculo se o bico estiver aceso
if ( Bicos [ i ] . Atuado )
{
g . FillEllipse ( Brushes . Red , xPosition , yPosition , circleDiameter , circleDiameter ) ;
}
// Número do bico
string bicoNumero = Bicos [ i ] . ID ;
Font font = new Font ( "Arial" , 10 , FontStyle . Bold ) ;
SizeF stringSize = g . MeasureString ( bicoNumero , font ) ;
float textXPosition = xPosition + ( circleDiameter - stringSize . Width ) / 2 ;
float textYPosition = yPosition + ( circleDiameter - stringSize . Height ) / 2 ;
g . DrawString ( bicoNumero , font , Brushes . Black , textXPosition , textYPosition ) ;
2024-12-05 12:52:28 +00:00
// Média de vazão (dentro do círculo, abaixo do número do bico)
string mediaFluxoTexto = $"{Bicos[i].MediaNivelFluxo:0.0} mL/s" ;
Font fontMediaFluxo = new Font ( "Arial" , 6 , FontStyle . Regular ) ;
SizeF stringSizeMediaFluxo = g . MeasureString ( mediaFluxoTexto , fontMediaFluxo ) ;
float textXPositionMediaFluxo = xPosition + circleDiameter + 3 ;
float textYPositionMediaFluxo = textYPosition + 3 ; // Abaixo do número do bico
g . DrawString ( mediaFluxoTexto , fontMediaFluxo , Brushes . Gray , textXPositionMediaFluxo , textYPositionMediaFluxo ) ;
2024-10-29 19:53:27 +00:00
// Quantidade de atuações (abaixo do círculo)
string bicoAtuacao = Bicos [ i ] . Atuacoes . ToString ( "000" ) ;
Font fontA = new Font ( "Arial" , 8 , FontStyle . Bold ) ;
SizeF stringSizeA = g . MeasureString ( bicoAtuacao , fontA ) ;
float textXPositionA = xPosition + ( circleDiameter - stringSizeA . Width ) / 2 ;
float textYPositionA = circleDiameter + yPosition + 5 ;
g . DrawString ( bicoAtuacao , fontA , Brushes . Black , textXPositionA , textYPositionA ) ;
// Tempo atuado em segundos (acima do círculo)
string tempoAtuadoSegundos = $"{(Bicos[i].TempoAtuado / 1000.0):0.0}s" ;
Font fontTempo = new Font ( "Arial" , 7 , FontStyle . Regular ) ;
SizeF stringSizeTempo = g . MeasureString ( tempoAtuadoSegundos , fontTempo ) ;
float textXPositionTempo = xPosition + ( circleDiameter - stringSizeTempo . Width ) / 2 ;
float textYPositionTempo = yPosition - stringSizeTempo . Height - 3 ;
g . DrawString ( tempoAtuadoSegundos , fontTempo , Brushes . Gray , textXPositionTempo , textYPositionTempo ) ;
// Círculo pequeno de status
int smallCircleXPosition = Convert . ToInt32 ( xPosition + circleDiameter - smallCircleDiameter / 1.3 ) ;
int smallCircleYPosition = Convert . ToInt32 ( yPosition + circleDiameter - smallCircleDiameter / 1.3 ) ;
Pen smallCirclePen = Pens . Blue ;
Brush smallCircleBrush = Bicos [ i ] . StatusBico ? Brushes . Blue : Brushes . Transparent ;
g . DrawEllipse ( smallCirclePen , smallCircleXPosition , smallCircleYPosition , smallCircleDiameter , smallCircleDiameter ) ;
g . FillEllipse ( smallCircleBrush , smallCircleXPosition , smallCircleYPosition , smallCircleDiameter , smallCircleDiameter ) ;
}
// Representação da bomba hidráulica no canto inferior direito
int bombaSize = 20 ; // Tamanho do círculo principal da bomba
int bombaXPosition = myPanel . Width - bombaSize - 20 ; // 20px de margem do canto direito
int bombaYPosition = myPanel . Height - bombaSize - 20 ; // 20px de margem do canto inferior
// Desenha o corpo da bomba (um círculo)
g . DrawEllipse ( Pens . Black , bombaXPosition , bombaYPosition , bombaSize , bombaSize ) ;
g . FillEllipse ( BombaLigada ? Brushes . Green : Brushes . Gray , bombaXPosition , bombaYPosition , bombaSize , bombaSize ) ;
// Define o centro do círculo para ajudar no desenho das hélices
int centerX = bombaXPosition + bombaSize / 2 ;
int centerY = bombaYPosition + bombaSize / 2 ;
int heliceSize = bombaSize - 6 ; // Ajuste para manter as hélices dentro do círculo
// Desenha hélices no formato de arcos ou semi-círculos dentro do círculo
Pen helicePen = new Pen ( Color . Black , 1 ) ;
g . DrawArc ( helicePen , centerX - heliceSize / 2 , centerY - heliceSize / 2 , heliceSize , heliceSize , 45 , 180 ) ;
g . DrawArc ( helicePen , centerX - heliceSize / 2 , centerY - heliceSize / 2 , heliceSize , heliceSize , 225 , 180 ) ;
// Desenha o "cano" da bomba (retângulo)
int tuboLargura = 5 ;
int tuboAltura = 15 ;
int tuboXPosition = bombaXPosition + bombaSize / 2 - tuboLargura / 2 ;
int tuboYPosition = bombaYPosition - tuboAltura ;
g . FillRectangle ( Brushes . Black , tuboXPosition , tuboYPosition , tuboLargura , tuboAltura ) ;
// Texto para o tempo de atuação acima da bomba
string tempoAtuacaoTexto = $"{(TempoBombaAtuada / 1000.0):0.0}s" ;
Font fontTempoAtuacao = new Font ( "Arial" , 6 , FontStyle . Regular ) ;
SizeF stringSizeTempoAtuacao = g . MeasureString ( tempoAtuacaoTexto , fontTempoAtuacao ) ;
float textXPositionTempoAtuacao = bombaXPosition + bombaSize / 2 - stringSizeTempoAtuacao . Width / 2 ;
float textYPositionTempoAtuacao = bombaYPosition - stringSizeTempoAtuacao . Height - 16 ; // 2px acima do círculo
g . DrawString ( tempoAtuacaoTexto , fontTempoAtuacao , Brushes . Gray , textXPositionTempoAtuacao , textYPositionTempoAtuacao ) ;
// Texto pequeno para a pressão ao lado da bomba
string pressaoTexto = $"{PressaoLinha:0.0} psi" ;
Font fontPressao = new Font ( "Arial" , 6 , FontStyle . Regular ) ;
SizeF stringSizePressao = g . MeasureString ( pressaoTexto , fontPressao ) ;
float textXPositionPressao = bombaXPosition + bombaSize / 2 - stringSizePressao . Width / 2 ;
float textYPositionPressao = bombaYPosition + bombaSize + 2 ; // 2px abaixo do círculo
g . DrawString ( pressaoTexto , fontPressao , Brushes . Black , textXPositionPressao , textYPositionPressao ) ;
}
}
2024-11-29 20:28:25 +00:00
public class AtuadorMensagemJsonModel
{
2024-12-05 17:11:38 +00:00
public DateTime Momento { get ; set ; }
2024-11-29 20:28:25 +00:00
public bool Conectado { get ; set ; }
2025-04-09 21:11:40 +00:00
public T_Code Dispositivo { get ; set ; }
public int Versao { get ; set ; }
2024-11-29 20:28:25 +00:00
public string Mod_ID { get ; set ; }
2024-12-05 17:11:38 +00:00
public int QualidadeWifi { get ; set ; }
public int LatenciaLoop { get ; set ; }
2025-12-16 17:17:26 +00:00
public List < AtuadorBicoModel > BicosPulverizadores { get ; set ; }
public List < AtuadorBombaModel > BombasPressurizadoras { get ; set ; }
public List < SensorModel > Sensores { get ; set ; }
public List < SensorServoModel > Servos { get ; set ; }
2025-04-09 21:11:40 +00:00
public DateTime UltimoComandoRespondido { get ; set ; }
}
public class AtuHandler : ICanMessageHandler
{
2025-05-06 18:47:59 +00:00
public T_Code Dispositivo { get ; set ; } = Variaveis . OperacaoEmAndamento . DispAtu ? . Dados ? . Dispositivo ? ? T_Code . Atu ;
2025-04-10 20:59:50 +00:00
private double ConverterByteParaDouble ( byte [ ] data , int idx )
{
int raw = ( data [ idx ] < < 8 ) | data [ idx + 1 ] ;
short _short = ( short ) raw ;
double _value = _short / 100.0 ;
return _value ;
}
2025-12-04 13:51:11 +00:00
private ushort Converter2BytesU16 ( byte [ ] data , int idx )
{
return ( ushort ) ( ( data [ idx ] < < 8 ) | data [ idx + 1 ] ) ;
}
private double ConverterAngle100 ( byte [ ] data , int idx )
{
ushort v = ( ushort ) ( ( data [ idx ] < < 8 ) | data [ idx + 1 ] ) ;
return v / 100.0 ;
}
2025-04-11 20:13:15 +00:00
private S_Code DetectarComponenteDoID_Num ( int ID_Num )
{
if ( ID_Num = = Variaveis . ID_Num_sMOD ) return S_Code . sMOD ;
2025-07-24 16:15:42 +00:00
if ( ID_Num = = Variaveis . ID_Num_sTOD ) return S_Code . sTOD ;
2025-04-11 20:13:15 +00:00
var Disp = Variaveis . OperacaoEmAndamento . DispAtu . Dados ;
var sensor = Disp . Sensores . FirstOrDefault ( x = > x . ID_Num = = ID_Num ) ;
var bico = Disp . BicosPulverizadores . FirstOrDefault ( x = > x . ID_Num = = ID_Num ) ;
var bomba = Disp . BombasPressurizadoras . FirstOrDefault ( x = > x . ID_Num = = ID_Num ) ;
2026-04-02 17:38:24 +00:00
2026-03-21 01:48:37 +00:00
return sensor ? . Componente ? ? bico ? . Componente ? ? bomba ? . Componente ? ? S_Code . sVZO ;
2025-04-11 20:13:15 +00:00
}
2025-07-23 15:14:50 +00:00
private void AtualizarDados ( int CompID_Num , CanMessagePosicaoDados Posicao , S_Code componente , List < dynamic > Parametros )
2025-04-11 20:13:15 +00:00
{
2025-05-30 20:11:31 +00:00
var Dados = Variaveis . OperacaoEmAndamento . DispAtu . Dados ;
2025-04-11 20:13:15 +00:00
2025-05-30 20:11:31 +00:00
var sensor = Dados . Sensores . FirstOrDefault ( x = > x . ID_Num = = CompID_Num ) ;
var bomba = Dados . BombasPressurizadoras . FirstOrDefault ( x = > x . ID_Num = = CompID_Num ) ;
var bico = Dados . BicosPulverizadores . FirstOrDefault ( x = > x . ID_Num = = CompID_Num ) ;
List < SensorValoresLeituraModel > valoresLeituras = new List < SensorValoresLeituraModel > ( ) ;
if ( sensor ! = null ) valoresLeituras = sensor . ValoresLeituras ;
else if ( bomba ! = null ) valoresLeituras = bomba . ValoresLeituras ;
else if ( bico ! = null ) valoresLeituras = bico . ValoresLeituras ;
for ( int i = 0 ; i < valoresLeituras . Where ( x = > x . posicao = = Posicao ) . Count ( ) ; i + + )
2025-04-11 20:13:15 +00:00
{
2025-07-23 15:14:50 +00:00
try
2025-05-30 20:11:31 +00:00
{
2025-07-23 15:14:50 +00:00
var valor = valoresLeituras . FirstOrDefault ( x = > x . posicao = = Posicao & & x . indice = = i ) ;
if ( valor ! = null )
{
var v = Parametros . Count > i ? ( Parametros [ i ] ) : - 1 ;
if ( v is sbyte | | v is byte | | v is short | | v is ushort | | v is int | | v is uint | | v is long | | v is ulong | | v is float | | v is double | | v is decimal )
{
v + = valor . offset ;
valor . atual . valor = v ;
}
else
{
valor . atual . valor = v ;
}
if ( Posicao = = CanMessagePosicaoDados . Status )
{
if ( sensor ! = null )
sensor . Inicializado = v ;
if ( bomba ! = null )
bomba . Inicializado = v ;
if ( bico ! = null )
bico . Inicializado = v ;
}
}
}
catch ( Exception ex )
{
2025-05-30 20:11:31 +00:00
}
2025-04-11 20:13:15 +00:00
}
}
2025-04-10 20:59:50 +00:00
2025-04-09 21:11:40 +00:00
public void ProcessarMensagem ( CanMessage mensagem )
{
2025-05-01 18:27:01 +00:00
CanMessagePosicaoDados posicao = ( CanMessagePosicaoDados ) mensagem . DataRx [ 0 ] ;
byte ID_Num = mensagem . DataRx [ 1 ] ;
2025-04-09 21:11:40 +00:00
var data = mensagem . DataRx ;
2025-04-11 20:13:15 +00:00
S_Code componente = DetectarComponenteDoID_Num ( ID_Num ) ;
2025-07-23 15:14:50 +00:00
var Dados = Variaveis . OperacaoEmAndamento . DispAtu . Dados ;
2025-07-24 16:15:42 +00:00
//Console.WriteLine($"[ATU] Componente={componente.ToString()}, ID_Num={ID_Num}, Data={FuncoesGlobais.ConverterComandoBytesParaTexto(data)}");
2025-04-11 20:13:15 +00:00
2025-05-30 20:11:31 +00:00
switch ( componente )
2025-04-09 21:11:40 +00:00
{
2025-05-30 20:11:31 +00:00
case S_Code . sMOD :
2025-04-09 21:11:40 +00:00
{
2025-05-30 20:11:31 +00:00
switch ( posicao )
2025-04-11 20:13:15 +00:00
{
2025-05-30 20:11:31 +00:00
case CanMessagePosicaoDados . Status :
{
T_Code tipoModulo = ( T_Code ) data [ 2 ] ;
bool conectado = data [ 3 ] = = 1 ;
int versao = data [ 4 ] ;
2025-04-09 21:11:40 +00:00
2025-08-22 18:36:19 +00:00
//Console.WriteLine($"[ATU] Resposta {ID_Num} recebida. Tipo={tipoModulo}, Conectado={conectado}, Versão={versao}");
2025-04-09 21:11:40 +00:00
2025-05-30 20:11:31 +00:00
Dados . DadosLeitura . Conectado = conectado ;
Dados . DadosLeitura . Dispositivo = tipoModulo ;
Dados . DadosLeitura . Versao = versao ;
break ;
}
2025-04-11 20:13:15 +00:00
}
2025-05-30 20:11:31 +00:00
break ;
}
case S_Code . sTOD :
{
switch ( posicao )
2025-04-11 20:13:15 +00:00
{
2025-05-30 20:11:31 +00:00
case CanMessagePosicaoDados . DadosAll :
{
double latenciaLoop = ConverterByteParaDouble ( data , 2 ) * 100 ;
Dados . DadosLeitura . LatenciaLoop = Convert . ToInt32 ( latenciaLoop ) ;
2025-08-22 18:36:19 +00:00
//Console.WriteLine($"[ATU] Ciclo concluido. Latencia de loop: {latenciaLoop} ms");
2025-05-30 20:11:31 +00:00
break ;
}
2025-04-11 20:13:15 +00:00
}
break ;
2025-04-09 21:11:40 +00:00
}
2025-05-30 20:11:31 +00:00
case S_Code . sBIC :
2025-04-10 20:59:50 +00:00
{
2025-05-30 20:11:31 +00:00
switch ( posicao )
2025-04-10 20:59:50 +00:00
{
2025-07-23 15:14:50 +00:00
case CanMessagePosicaoDados . Status :
{
bool Iniciado = data [ 2 ] = = 1 ;
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { Iniciado } ) ;
break ;
}
2025-05-30 20:11:31 +00:00
case CanMessagePosicaoDados . Dados1 :
2025-04-10 20:59:50 +00:00
{
2025-04-11 20:13:15 +00:00
Estado estado = ( Estado ) data [ 2 ] ;
2025-12-16 17:17:26 +00:00
int angulo = data [ 3 ] ;
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { estado , angulo } ) ;
2025-04-10 20:59:50 +00:00
break ;
}
2025-05-30 20:11:31 +00:00
}
break ;
}
case S_Code . sFLX :
{
switch ( posicao )
{
2025-07-23 15:14:50 +00:00
case CanMessagePosicaoDados . Status :
{
bool Iniciado = data [ 2 ] = = 1 ;
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { Iniciado } ) ;
break ;
}
2025-05-30 20:11:31 +00:00
case CanMessagePosicaoDados . Dados1 :
2025-04-10 20:59:50 +00:00
{
2025-12-16 17:17:26 +00:00
int qtdPulsos = data [ 2 ] ;
ushort periodo = Converter2BytesU16 ( data , 3 ) ;
double vazao = ConverterByteParaDouble ( data , 5 ) ;
2026-04-02 17:38:24 +00:00
//Variaveis.MostrarLog($"[AtuadorModel] Vazao: {vazao}, pulsos: {qtdPulsos}, Periodo: {periodo}");
2025-12-16 17:17:26 +00:00
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { qtdPulsos , periodo , vazao } ) ;
2025-04-10 20:59:50 +00:00
break ;
}
2025-05-30 20:11:31 +00:00
}
break ;
}
case S_Code . sMAS :
{
switch ( posicao )
{
2025-07-23 15:14:50 +00:00
case CanMessagePosicaoDados . Status :
{
bool Iniciado = data [ 2 ] = = 1 ;
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { Iniciado } ) ;
break ;
}
2025-05-30 20:11:31 +00:00
case CanMessagePosicaoDados . Dados1 :
2025-04-10 20:59:50 +00:00
{
2025-12-16 17:17:26 +00:00
double raw = ConverterByteParaDouble ( data , 2 ) ;
double massa = ConverterByteParaDouble ( data , 4 ) ;
2026-04-02 17:38:24 +00:00
//Variaveis.MostrarLog($"[AtuadorModel] Massa: {massa}, Raw: {raw}");
2025-12-16 17:17:26 +00:00
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { raw , massa } ) ;
2025-04-10 20:59:50 +00:00
break ;
}
2025-05-30 20:11:31 +00:00
}
break ;
}
case S_Code . sPRS :
{
switch ( posicao )
{
2025-07-23 15:14:50 +00:00
case CanMessagePosicaoDados . Status :
{
bool Iniciado = data [ 2 ] = = 1 ;
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { Iniciado } ) ;
break ;
}
2025-05-30 20:11:31 +00:00
case CanMessagePosicaoDados . Dados1 :
2025-04-10 20:59:50 +00:00
{
2025-12-16 17:17:26 +00:00
ushort raw = Converter2BytesU16 ( data , 2 ) ;
double pressao = ConverterByteParaDouble ( data , 4 ) ;
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { raw , pressao } ) ;
2025-04-10 20:59:50 +00:00
break ;
}
2025-05-30 20:11:31 +00:00
}
break ;
}
case S_Code . sBMB :
{
switch ( posicao )
{
2025-07-23 15:14:50 +00:00
case CanMessagePosicaoDados . Status :
{
bool Iniciado = data [ 2 ] = = 1 ;
2026-04-02 17:38:24 +00:00
bool MalhaFechada = data [ 3 ] = = 1 ;
2025-07-23 15:14:50 +00:00
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { Iniciado } ) ;
break ;
}
2025-05-30 20:11:31 +00:00
case CanMessagePosicaoDados . Dados1 :
2025-04-10 20:59:50 +00:00
{
2025-04-11 20:13:15 +00:00
Estado estado = ( Estado ) data [ 2 ] ;
2026-04-02 17:38:24 +00:00
int potenciaSp = data [ 3 ] ;
int percentualPotencia = data [ 4 ] ;
int pressaoSp = data [ 5 ] ;
int pressaoAtual = data [ 6 ] ;
2026-06-09 13:39:44 +00:00
ModoControleBomba modo = ( ModoControleBomba ) data [ 7 ] ;
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { estado , potenciaSp , percentualPotencia , pressaoSp , pressaoAtual , modo } ) ;
2025-04-10 20:59:50 +00:00
break ;
}
}
break ;
}
2025-12-04 13:51:11 +00:00
case S_Code . sMAG :
{
switch ( posicao )
{
case CanMessagePosicaoDados . Status :
{
bool Iniciado = data [ 2 ] = = 1 ;
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { Iniciado } ) ;
break ;
}
case CanMessagePosicaoDados . Dados1 :
{
ushort raw = Converter2BytesU16 ( data , 2 ) ;
double angle = ConverterAngle100 ( data , 4 ) ;
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { raw , angle } ) ;
//Console.WriteLine($"[sMAG] {ID_Num}, Raw: {raw}, Angulo: {angle}");
break ;
}
}
break ;
}
2026-06-09 13:39:44 +00:00
case S_Code . sBOT :
{
switch ( posicao )
{
case CanMessagePosicaoDados . Status :
{
bool Iniciado = data [ 2 ] = = 1 ;
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { Iniciado } ) ;
break ;
}
case CanMessagePosicaoDados . Dados1 :
{
bool pressionado = data [ 2 ] = = 1 ;
bool leitura = data [ 3 ] = = 1 ;
bool mudou = data [ 4 ] = = 1 ;
AtualizarDados ( ID_Num , posicao , componente , new List < dynamic > ( ) { pressionado , leitura , mudou } ) ;
break ;
}
}
break ;
}
2025-12-16 17:17:26 +00:00
2025-04-09 21:11:40 +00:00
}
2025-12-16 17:17:26 +00:00
2025-05-30 20:11:31 +00:00
Dados . DadosLeitura . UltimoComandoRespondido = DateTime . Now ;
2025-12-05 18:25:29 +00:00
Variaveis . OperacaoEmAndamento . DispAtu . Dados . AtualizarDadosSensoresExternos ( componente , ID_Num ) ;
2025-04-09 21:11:40 +00:00
}
2024-11-29 20:28:25 +00:00
}
2024-01-03 10:52:37 +00:00
}