ajustes para nao deixar a saude do atuador falhar por incoerencia
This commit is contained in:
parent
912773fea2
commit
b953ff524e
|
|
@ -150,21 +150,36 @@ namespace AgroBase.Forms.Atuador
|
|||
|
||||
private void nudPressaoSP_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
var Bomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombaPressurizadora;
|
||||
Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha = Convert.ToInt32(((NumericUpDown)sender).Value);
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, Bomba.ID, Status: Bomba.ComandoAtuar, Comando: Services.CanMessagePosicaoDados.Command1);
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
var Bomba = op.DispAtu.Dados.BombaPressurizadora;
|
||||
op.Parametros.Controle.AtuPressaoLinha = Convert.ToInt32(((NumericUpDown)sender).Value);
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBomba(
|
||||
Bomba,
|
||||
Services.CanMessagePosicaoDados.Command1,
|
||||
Bomba.ComandoAtuar
|
||||
);
|
||||
}
|
||||
|
||||
private void btnLigarBomba_Click(object sender, EventArgs e)
|
||||
{
|
||||
var Bomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombaPressurizadora;
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, Bomba.ID, Status: true, Comando: Services.CanMessagePosicaoDados.Command1, Forcar: true);
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
var Bomba = op.DispAtu.Dados.BombaPressurizadora;
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBomba(
|
||||
Bomba,
|
||||
Services.CanMessagePosicaoDados.Command1,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
private void btnDesligarBomba_Click(object sender, EventArgs e)
|
||||
{
|
||||
var Bomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombaPressurizadora;
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, Bomba.ID, Status: false, Comando: Services.CanMessagePosicaoDados.Command1, Forcar: true);
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
var Bomba = op.DispAtu.Dados.BombaPressurizadora;
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBomba(
|
||||
Bomba,
|
||||
Services.CanMessagePosicaoDados.Command1,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
private void pnlBico_Paint(object sender, PaintEventArgs e)
|
||||
|
|
@ -188,7 +203,13 @@ namespace AgroBase.Forms.Atuador
|
|||
{
|
||||
Button btn = (Button)sender;
|
||||
string ID = btn.Name.Replace("btn0_", "");
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, ID, Status: false, Forcar: true);
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
var Bico = op?.DispAtu?.Dados?.BicosPulverizadores?.FirstOrDefault(x => x.ID == ID);
|
||||
Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.EnviarComandoFisicoBico(
|
||||
Bico,
|
||||
Services.CanMessagePosicaoDados.Command1,
|
||||
false
|
||||
);
|
||||
pnlBicos.Controls.OfType<Panel>().First(x => x.Name == "pnlB_" + ID).Invalidate();
|
||||
pnlBicos.Controls.OfType<Panel>().First(x => x.Name == "pnlB_" + ID).Controls.OfType<Label>().First(x => x.Name == "lblCmd_" + ID).Text = "Comando: Desligado";
|
||||
}
|
||||
|
|
@ -197,7 +218,13 @@ namespace AgroBase.Forms.Atuador
|
|||
{
|
||||
Button btn = (Button)sender;
|
||||
string ID = btn.Name.Replace("btn1_", "");
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, ID, Status: true, Forcar: true);
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
var Bico = op?.DispAtu?.Dados?.BicosPulverizadores?.FirstOrDefault(x => x.ID == ID);
|
||||
Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.EnviarComandoFisicoBico(
|
||||
Bico,
|
||||
Services.CanMessagePosicaoDados.Command1,
|
||||
true
|
||||
);
|
||||
pnlBicos.Controls.OfType<Panel>().First(x => x.Name == "pnlB_" + ID).Invalidate();
|
||||
pnlBicos.Controls.OfType<Panel>().First(x => x.Name == "pnlB_" + ID).Controls.OfType<Label>().First(x => x.Name == "lblCmd_" + ID).Text = "Comando: Ligado";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -525,9 +525,15 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
private async Task EnviarComandoBomba(bool Ligar, double Pressao, int Timeout, AtuadorModel disp = null)
|
||||
{
|
||||
var Bomba = Variaveis.OperacaoEmAndamento.DispAtu.Dados.BombaPressurizadora;
|
||||
Variaveis.OperacaoEmAndamento.Parametros.Controle.AtuPressaoLinha = Pressao + 10;
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBMB, Bomba.ID, Status: Ligar, Comando: CanMessagePosicaoDados.Command1);
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
var Bomba = op.DispAtu.Dados.BombaPressurizadora;
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBomba(
|
||||
Bomba,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
Ligar,
|
||||
potencia: 100,
|
||||
pressao: Pressao + 10
|
||||
);
|
||||
|
||||
DateTime inicio = DateTime.Now;
|
||||
while (DateTime.Now < inicio.AddMilliseconds(Timeout))
|
||||
|
|
@ -544,7 +550,11 @@ namespace AgroBase.Forms.IHM
|
|||
|
||||
private async Task EnviarComandoBico(AtuadorBicoModel Bico, bool Ligar, int Timeout, double ValorComparar = 0, AtuadorModel disp = null)
|
||||
{
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sBIC, Bico.ID, Status: Ligar);
|
||||
Variaveis.OperacaoEmAndamento.DispAtu?.Dados?.EnviarComandoFisicoBico(
|
||||
Bico,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
Ligar
|
||||
);
|
||||
DateTime inicio = DateTime.Now;
|
||||
while (DateTime.Now < inicio.AddMilliseconds(Timeout))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -672,7 +672,11 @@ namespace AgroBase.Forms.Operacoes
|
|||
if (Bico != null)
|
||||
{
|
||||
bool comando = !Bico.ComandoAtuar;
|
||||
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: comando, Forcar: true);
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBico(
|
||||
Bico,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
comando
|
||||
);
|
||||
|
||||
pnlAtuadores.Controls.OfType<Label>().First(x => x.Name == "lblCmd_" + ID).Text = "Comando: " + (comando ? "Ligado" : "Desligado");
|
||||
btn.Text = comando ? "Desligar" : "Ligar";
|
||||
|
|
@ -692,8 +696,25 @@ namespace AgroBase.Forms.Operacoes
|
|||
double Kp = Convert.ToDouble(txtKp.Text);
|
||||
double Ki = Convert.ToDouble(txtKi.Text);
|
||||
double Kd = Convert.ToDouble(txtKd.Text);
|
||||
GeneralJoystick.EnviarComandoAtuador(Bomba.Componente, Bomba.ID, Status: true, Valores: new System.Collections.Generic.List<double?>() { cmbModoBomba.SelectedIndex, potMin, Kp, Ki, Kd }, Comando: CanMessagePosicaoDados.Command2, Forcar: true);
|
||||
GeneralJoystick.EnviarComandoAtuador(Bomba.Componente, Bomba.ID, Status: true, Valores: new System.Collections.Generic.List<double?>() { potMax, pressao }, Comando: CanMessagePosicaoDados.Command1, Forcar: true);
|
||||
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBomba(
|
||||
Bomba,
|
||||
CanMessagePosicaoDados.Command2,
|
||||
true,
|
||||
modo: (ModoControleBomba)cmbModoBomba.SelectedIndex,
|
||||
potenciaMinPid: potMin,
|
||||
Kp: Kp,
|
||||
Ki: Ki,
|
||||
Kd: Kd
|
||||
);
|
||||
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBomba(
|
||||
Bomba,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
true,
|
||||
potencia: potMax,
|
||||
pressao: pressao
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -701,7 +722,11 @@ namespace AgroBase.Forms.Operacoes
|
|||
{
|
||||
var Bomba = op.DispAtu.Dados.BombaPressurizadora;
|
||||
if (Bomba != null)
|
||||
GeneralJoystick.EnviarComandoAtuador(Bomba.Componente, Bomba.ID, Status: false, Comando: CanMessagePosicaoDados.Command1, Forcar: true);
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBomba(
|
||||
Bomba,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
private void btnLigarAgitador_Click(object sender, EventArgs e)
|
||||
|
|
@ -710,9 +735,25 @@ namespace AgroBase.Forms.Operacoes
|
|||
if (Agitador != null)
|
||||
{
|
||||
op.Parametros.Controle.AtuAgitadorModo = (ModoAgitadorCalda)cmbModoAgitador.SelectedIndex;
|
||||
|
||||
double potencia = Convert.ToInt32(nudPotenciaAgitador.Value);
|
||||
GeneralJoystick.EnviarComandoAtuador(Agitador.Componente, Agitador.ID, Status: true, Valores: new System.Collections.Generic.List<double?>() { potencia }, Comando: CanMessagePosicaoDados.Command1, Forcar: true);
|
||||
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBomba(
|
||||
Agitador,
|
||||
CanMessagePosicaoDados.Command2,
|
||||
true,
|
||||
modo: Agitador.Controle.Modo,
|
||||
potenciaMinPid: Agitador.Controle.PotenciaMinPID,
|
||||
Kp: Agitador.Controle.Kp,
|
||||
Ki: Agitador.Controle.Ki,
|
||||
Kd: Agitador.Controle.Kd
|
||||
);
|
||||
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBomba(
|
||||
Agitador,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
true,
|
||||
potencia: potencia
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -720,7 +761,11 @@ namespace AgroBase.Forms.Operacoes
|
|||
{
|
||||
var Agitador = op.DispAtu.Dados.AgitadorDeCalda;
|
||||
if (Agitador != null)
|
||||
GeneralJoystick.EnviarComandoAtuador(Agitador.Componente, Agitador.ID, Status: false, Comando: CanMessagePosicaoDados.Command1, Forcar: true);
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBomba(
|
||||
Agitador,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
private void nudPressaoSP_ValueChanged(object sender, EventArgs e)
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ namespace AgroBase.Forms.Sensoriamento
|
|||
if (MessageBox.Show($"Tem certeza que deseja reiniciar o módulo {Dispositivo}?", "Confirmação", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
||||
{
|
||||
if (Dispositivo == T_Code.Atu)
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sMOD, "", true);
|
||||
(Disp as AtuadorModel).EnviarComandoFisicoReset();
|
||||
if (Dispositivo == T_Code.Sen)
|
||||
GeneralJoystick.EnviarComandoSensoriamento(S_Code.sMOD, "", true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -625,75 +625,24 @@ namespace AgroBase
|
|||
var bomba = op.DispAtu?.Dados?.BombasPressurizadoras?.FirstOrDefault(x => x.ID == Comando.IDcontrolar);
|
||||
S_Code comp = bico?.Componente ?? bomba?.Componente ?? S_Code.sVZO;
|
||||
|
||||
for (int i = 0; i < 1; i++)
|
||||
switch (comp)
|
||||
{
|
||||
EnviarComandoAtuador(comp, Comando.IDcontrolar, Status: Comando.EstadoAplicar, Comando: Comando.Comando);
|
||||
}
|
||||
}
|
||||
|
||||
public static void EnviarComandoAtuador(S_Code Componente, string ID, bool? Status = null, List<double?> Valores = null, CanMessagePosicaoDados Comando = CanMessagePosicaoDados.Command1, bool Forcar = false)
|
||||
{
|
||||
var op = Variaveis.OperacaoEmAndamento;
|
||||
|
||||
var DispAtu = op.DispAtu;
|
||||
if (!DispAtu.Dados.Conectado)
|
||||
return;
|
||||
|
||||
if (!Forcar)
|
||||
{
|
||||
if (!op.Sensoriamento.Operacao.OperacaoIniciada) return;
|
||||
bool componente_em_uso = op.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Atu && (x.ComponentesEmUso?.ContainsKey(ID) ?? false) && x.ComponentesEmUso[ID].Item2);
|
||||
if (!componente_em_uso && (Status ?? false)) return; // Impede execucao de comandos que liguem componentes quando estiver marcado para nao utilizar
|
||||
}
|
||||
|
||||
int id_num = -1;
|
||||
CanMessagePosicaoDados comando = Comando;
|
||||
byte[] data = null;
|
||||
|
||||
switch (Componente)
|
||||
{
|
||||
case S_Code.sMOD:
|
||||
if (DispAtu?.Dados != null && Status == true)
|
||||
{
|
||||
(id_num, comando, data) = DispAtu.Dados.ProtocoloComandoReset();
|
||||
}
|
||||
break;
|
||||
case S_Code.sBMB:
|
||||
var Bomba = DispAtu?.Dados?.BombasPressurizadoras?.FirstOrDefault(x => x.ID == ID);
|
||||
if (Bomba != null)
|
||||
{
|
||||
switch (comando)
|
||||
{
|
||||
case CanMessagePosicaoDados.Command1:
|
||||
if (Status != null) Bomba.ComandoAtuar = (bool)Status;
|
||||
if (Valores?.Count() > 0 && Valores[0] is double) Bomba.PotenciaSP = (double)Valores[0];
|
||||
if (Valores?.Count() > 1 && Valores[1] is double) Bomba.PressaoSP = (double)Valores[1];
|
||||
(id_num, comando, data) = Bomba.ProtocoloComando(comando);
|
||||
break;
|
||||
case CanMessagePosicaoDados.Command2:
|
||||
if (Valores?.Count() > 0 && Valores[0] is double) Bomba.Controle.Modo = (ModoControleBomba)((int)Valores[0]);
|
||||
if (Valores?.Count() > 1 && Valores[1] is double) Bomba.Controle.PotenciaMinPID = (double)Valores[1];
|
||||
if (Valores?.Count() > 2 && Valores[2] is double) Bomba.Controle.Kp = (double)Valores[2];
|
||||
if (Valores?.Count() > 3 && Valores[3] is double) Bomba.Controle.Ki = (double)Valores[3];
|
||||
if (Valores?.Count() > 4 && Valores[4] is double) Bomba.Controle.Kd = (double)Valores[4];
|
||||
(id_num, comando, data) = Bomba.ProtocoloComando(comando);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case S_Code.sBIC:
|
||||
var Bico = DispAtu.Dados.BicosPulverizadores.FirstOrDefault(x => x.ID == ID);
|
||||
if (Bico != null)
|
||||
{
|
||||
if (Status != null) Bico.ComandoAtuar = (bool)Status;
|
||||
if (Valores?.Count() > 0) Bico.AnguloControle = (int)Valores[0];
|
||||
(id_num, comando, data) = Bico.ProtocoloComando();
|
||||
}
|
||||
break;
|
||||
op?.DispAtu?.Dados?.EnviarComandoFisicoBico(
|
||||
bico,
|
||||
Comando.Comando,
|
||||
Comando.EstadoAplicar
|
||||
);
|
||||
return;
|
||||
|
||||
case S_Code.sBMB:
|
||||
op?.DispAtu?.Dados?.EnviarComandoFisicoBomba(
|
||||
bomba,
|
||||
Comando.Comando,
|
||||
Comando.EstadoAplicar
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
DispAtu.AdicionarMensagemFila(id_num, comando, comando, data, false);
|
||||
|
||||
}
|
||||
|
||||
public static void EnviarComandoSensoriamento(S_Code Componente, string ID, dynamic Status) //, bool Forcar = false
|
||||
|
|
|
|||
|
|
@ -1331,6 +1331,17 @@ namespace AgroBase.Models.Modules
|
|||
bomba.PotenciaSP = 100;
|
||||
bomba.PressaoSP = controle.AtuPressaoLinha;
|
||||
bomba.Controle.Modo = controle.AtuModoControle;
|
||||
|
||||
EnviarComandoFisicoBomba(
|
||||
bomba,
|
||||
CanMessagePosicaoDados.Command2,
|
||||
true,
|
||||
modo: bomba.Controle.Modo,
|
||||
potenciaMinPid: bomba.Controle.PotenciaMinPID,
|
||||
Kp: bomba.Controle.Kp,
|
||||
Ki: bomba.Controle.Ki,
|
||||
Kd: bomba.Controle.Kd
|
||||
);
|
||||
}
|
||||
|
||||
var agitador = dadosAtuador.AgitadorDeCalda;
|
||||
|
|
@ -1346,6 +1357,17 @@ namespace AgroBase.Models.Modules
|
|||
*/
|
||||
agitador.PotenciaSP = 0;
|
||||
agitador.PressaoSP = -1;
|
||||
|
||||
EnviarComandoFisicoBomba(
|
||||
agitador,
|
||||
CanMessagePosicaoDados.Command2,
|
||||
true,
|
||||
modo: agitador.Controle.Modo,
|
||||
potenciaMinPid: agitador.Controle.PotenciaMinPID,
|
||||
Kp: agitador.Controle.Kp,
|
||||
Ki: agitador.Controle.Ki,
|
||||
Kd: agitador.Controle.Kd
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1408,9 +1430,10 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
EnviarComandoFisicoBomba(
|
||||
bomba,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
statusDesejado,
|
||||
potenciaEfetiva,
|
||||
pressaoEfetiva
|
||||
potencia: potenciaEfetiva,
|
||||
pressao: pressaoEfetiva
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1714,8 +1737,9 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
EnviarComandoFisicoBico(
|
||||
bico,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
statusDesejado,
|
||||
anguloDesejado
|
||||
angulo: anguloDesejado
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1806,65 +1830,84 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
EnviarComandoFisicoBomba(
|
||||
bomba,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
statusDesejado,
|
||||
potenciaEfetiva,
|
||||
pressaoEfetiva
|
||||
potencia: potenciaEfetiva,
|
||||
pressao: pressaoEfetiva
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnviarComandoFisicoBico(AtuadorBicoModel bico, bool status, double angulo)
|
||||
public void EnviarComandoFisicoReset()
|
||||
{
|
||||
var dispAtu = Variaveis.OperacaoEmAndamento?.DispAtu;
|
||||
|
||||
if (dispAtu?.Dados?.Conectado != true)
|
||||
return;
|
||||
|
||||
(int id_num, CanMessagePosicaoDados dado, byte[] data) = dispAtu.Dados.ProtocoloComandoReset();
|
||||
dispAtu.AdicionarMensagemFila(id_num, dado, dado, data, false);
|
||||
}
|
||||
|
||||
public void EnviarComandoFisicoBico(
|
||||
AtuadorBicoModel bico,
|
||||
CanMessagePosicaoDados dado,
|
||||
bool status,
|
||||
double? angulo = null
|
||||
)
|
||||
{
|
||||
var dispAtu = Variaveis.OperacaoEmAndamento?.DispAtu;
|
||||
|
||||
if (dispAtu?.Dados?.Conectado != true || bico == null)
|
||||
return;
|
||||
|
||||
byte anguloByte = (byte)Math.Round(FuncoesMatematicas.Clamp(angulo, 0, 255));
|
||||
bico.ComandoAtuar = status;
|
||||
if (angulo.HasValue) bico.AnguloControle = angulo.Value;
|
||||
|
||||
byte[] data =
|
||||
{
|
||||
(byte)(status ? Estado.Ligado : Estado.Desligado),
|
||||
anguloByte
|
||||
};
|
||||
(_, _, byte[] data) = bico.ProtocoloComando();
|
||||
|
||||
dispAtu.AdicionarMensagemFila(bico.ID_Num, CanMessagePosicaoDados.Command1, CanMessagePosicaoDados.Command1, data, false);
|
||||
dispAtu.AdicionarMensagemFila(bico.ID_Num, dado, dado, data, false);
|
||||
bico.UltimoComandoEnviado = DateTime.Now;
|
||||
bico.UltimoStatusDesejado = status;
|
||||
bico.UltimoAnguloDesejado = angulo;
|
||||
if (angulo.HasValue) bico.UltimoAnguloDesejado = angulo.Value;
|
||||
}
|
||||
|
||||
private void EnviarComandoFisicoBomba(AtuadorBombaModel bomba, bool status, double potencia, double pressao)
|
||||
public void EnviarComandoFisicoBomba(
|
||||
AtuadorBombaModel bomba,
|
||||
CanMessagePosicaoDados dado,
|
||||
bool status,
|
||||
double? potencia = null,
|
||||
double? pressao = null,
|
||||
ModoControleBomba? modo = null,
|
||||
double? potenciaMinPid = null,
|
||||
double? Kp = null,
|
||||
double? Ki = null,
|
||||
double? Kd = null
|
||||
)
|
||||
{
|
||||
var dispAtu = Variaveis.OperacaoEmAndamento?.DispAtu;
|
||||
|
||||
if (dispAtu?.Dados?.Conectado != true || bomba == null)
|
||||
return;
|
||||
|
||||
byte potenciaByte = (byte)Math.Round(FuncoesMatematicas.Clamp(potencia, 0, 100));
|
||||
bomba.ComandoAtuar = status;
|
||||
if (potencia.HasValue) bomba.PotenciaSP = potencia.Value;
|
||||
if (pressao.HasValue) bomba.PressaoSP = pressao.Value;
|
||||
if (modo.HasValue) bomba.Controle.Modo = modo.Value;
|
||||
if (potenciaMinPid.HasValue) bomba.Controle.PotenciaMinPID = potenciaMinPid.Value;
|
||||
if (Kp.HasValue) bomba.Controle.Kp = Kp.Value;
|
||||
if (Ki.HasValue) bomba.Controle.Ki = Ki.Value;
|
||||
if (Kd.HasValue) bomba.Controle.Kd = Kd.Value;
|
||||
|
||||
/*
|
||||
* -1 é usado para indicar ausência de sensor
|
||||
* de pressão. No protocolo atual, representa 255.
|
||||
*/
|
||||
byte pressaoByte = pressao < 0 ? byte.MaxValue : (byte)Math.Round(FuncoesMatematicas.Clamp(pressao, 0, 255));
|
||||
(_, _, byte[] data) = bomba.ProtocoloComando(dado);
|
||||
|
||||
byte[] data =
|
||||
{
|
||||
(byte)(status ? Estado.Ligado : Estado.Desligado),
|
||||
potenciaByte,
|
||||
pressaoByte
|
||||
};
|
||||
|
||||
dispAtu.AdicionarMensagemFila(bomba.ID_Num, CanMessagePosicaoDados.Command1, CanMessagePosicaoDados.Command1, data, false);
|
||||
|
||||
Variaveis.MostrarLog($"Enviando comando para a bomba {bomba.ID}: potencia={potencia}, pressao={pressao}");
|
||||
dispAtu.AdicionarMensagemFila(bomba.ID_Num, dado, dado, data, false);
|
||||
|
||||
bomba.UltimoComandoEnviado = DateTime.Now;
|
||||
bomba.UltimoStatusDesejado = status;
|
||||
bomba.UltimaPotenciaDesejada = potencia;
|
||||
bomba.UltimaPressaoDesejada = pressao;
|
||||
if (potencia.HasValue) bomba.UltimaPotenciaDesejada = potencia.Value;
|
||||
if (pressao.HasValue) bomba.UltimaPressaoDesejada = pressao.Value;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1917,19 +1960,37 @@ namespace AgroBase.Models.Modules
|
|||
continue;
|
||||
}
|
||||
|
||||
Bomba.PotenciaSP = 100;
|
||||
if (Bomba.ID == BombaPressurizadora.ID)
|
||||
{
|
||||
Bomba.Controle.Modo = op.Parametros.Controle.AtuModoControle;
|
||||
Bomba.PressaoSP = op.Parametros.Controle.AtuPressaoLinha;
|
||||
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);
|
||||
GeneralJoystick.EnviarComandoAtuador(Bomba.Componente, Bomba.ID, Status: true, Valores: new List<double?>() { Bomba.PotenciaSP, Bomba.PressaoSP }, Comando: CanMessagePosicaoDados.Command1, Forcar: true);
|
||||
EnviarComandoFisicoBomba(
|
||||
Bomba,
|
||||
CanMessagePosicaoDados.Command2,
|
||||
true,
|
||||
modo: op.Parametros.Controle.AtuModoControle,
|
||||
potenciaMinPid: Bomba.Controle.PotenciaMinPID,
|
||||
Kp: Bomba.Controle.Kp,
|
||||
Ki: Bomba.Controle.Ki,
|
||||
Kd: Bomba.Controle.Kd
|
||||
);
|
||||
|
||||
EnviarComandoFisicoBomba(
|
||||
Bomba,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
true,
|
||||
potencia: 100,
|
||||
pressao: op.Parametros.Controle.AtuPressaoLinha
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Bomba.PressaoSP = -1;
|
||||
bool ligar = op.Parametros.Controle.AtuAgitadorModo != ModoAgitadorCalda.SemAgitacao;
|
||||
GeneralJoystick.EnviarComandoAtuador(Bomba.Componente, Bomba.ID, Status: ligar, Valores: new List<double?>() { Bomba.PotenciaSP, Bomba.PressaoSP }, Comando: CanMessagePosicaoDados.Command1, Forcar: true);
|
||||
EnviarComandoFisicoBomba(
|
||||
Bomba,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
ligar,
|
||||
potencia: 100,
|
||||
pressao: -1
|
||||
);
|
||||
}
|
||||
|
||||
if (Bomba.Sensor_ID_Num == -1)
|
||||
|
|
@ -1951,14 +2012,22 @@ namespace AgroBase.Models.Modules
|
|||
{
|
||||
foreach (var Bico in BicosPulverizadores.Where(x => x.Comandar && x.Inicializado))
|
||||
{
|
||||
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: true, Forcar: true);
|
||||
EnviarComandoFisicoBico(
|
||||
Bico,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
await Task.Delay(3000);
|
||||
|
||||
foreach (var Bico in BicosPulverizadores.Where(x => x.Comandar && x.Inicializado))
|
||||
{
|
||||
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: false, Forcar: true);
|
||||
EnviarComandoFisicoBico(
|
||||
Bico,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
await FuncoesGlobais.AguardarCondicaoAsync(Bomba.AtingiuPressao, 4000, 200);
|
||||
|
|
@ -1978,11 +2047,19 @@ namespace AgroBase.Models.Modules
|
|||
|
||||
if (Bico.Inicializado)
|
||||
{
|
||||
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: true, Forcar: true);
|
||||
EnviarComandoFisicoBico(
|
||||
Bico,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
true
|
||||
);
|
||||
|
||||
await Task.Delay(200);
|
||||
|
||||
GeneralJoystick.EnviarComandoAtuador(Bico.Componente, Bico.ID, Status: false, Forcar: true);
|
||||
EnviarComandoFisicoBico(
|
||||
Bico,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
false
|
||||
);
|
||||
|
||||
await Task.Delay(200);
|
||||
|
||||
|
|
|
|||
|
|
@ -1152,6 +1152,12 @@ namespace AgroBase.Models
|
|||
if (op.Sensoriamento.Operacao.Finalizando)
|
||||
return;
|
||||
|
||||
if (op.Sensoriamento?.Operacao?.OperacaoIniciada != true)
|
||||
{
|
||||
Variaveis.MostrarLog("[OperacaoModel.FinalizarOperacao] Ignorado: operação não iniciada.");
|
||||
return;
|
||||
}
|
||||
|
||||
op.Sensoriamento.Operacao.Finalizando = true;
|
||||
|
||||
op.Trajetoria?.LoopAtualizaDados();
|
||||
|
|
@ -1785,7 +1791,11 @@ namespace AgroBase.Models
|
|||
Estado comandoEstado = bicos[i].ComandoAtuar ? Estado.Ligado : Estado.Desligado;
|
||||
if (ForcarEnvio || comandoEstado != bicos[i]._EstadoLeitura)
|
||||
{
|
||||
GeneralJoystick.EnviarComandoAtuador(bicos[i].Componente, bicos[i].ID, Status: bicos[i].ComandoAtuar);
|
||||
op.DispAtu?.Dados?.EnviarComandoFisicoBico(
|
||||
bicos[i],
|
||||
CanMessagePosicaoDados.Command1,
|
||||
bicos[i].ComandoAtuar
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2360,8 +2370,6 @@ namespace AgroBase.Models
|
|||
return;
|
||||
}
|
||||
|
||||
List<double?> valores = null;
|
||||
|
||||
switch (comp)
|
||||
{
|
||||
case S_Code.sMOD:
|
||||
|
|
@ -2369,39 +2377,37 @@ namespace AgroBase.Models
|
|||
{
|
||||
op.Controle.AlturaBarra = (double)controleBase.Controle.Altura;
|
||||
}
|
||||
break;
|
||||
|
||||
dadosAtu?.EnviarComandoFisicoReset();
|
||||
return;
|
||||
|
||||
case S_Code.sBIC:
|
||||
var bico = dadosAtu.BicosPulverizadores?.FirstOrDefault(x => x.ID == controleBase._comp_id);
|
||||
|
||||
if (controleBase._comp_value != null)
|
||||
{
|
||||
int angulo;
|
||||
|
||||
if (TryDeserializeValue(controleBase._comp_value, out angulo))
|
||||
{
|
||||
var bico = dadosAtu.BicosPulverizadores?.FirstOrDefault(x => x.ID == controleBase._comp_id);
|
||||
|
||||
if (bico != null)
|
||||
bico.AnguloAbertura = angulo;
|
||||
}
|
||||
|
||||
valores = new List<double?>
|
||||
{
|
||||
controleBase.Controle.AnguloSP
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
dadosAtu?.EnviarComandoFisicoBico(
|
||||
bico,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
controleBase.Controle.Estado == true,
|
||||
angulo: controleBase.Controle.AnguloSP
|
||||
);
|
||||
return;
|
||||
|
||||
case S_Code.sBMB:
|
||||
var bomba = dadosAtu.BombasPressurizadoras?.FirstOrDefault(x => x.ID == controleBase._comp_id);
|
||||
|
||||
switch (controleBase.Controle.Comando)
|
||||
{
|
||||
case CanMessagePosicaoDados.Command1:
|
||||
valores = new List<double?>
|
||||
{
|
||||
controleBase.Controle.Potencia,
|
||||
controleBase.Controle.Pressao
|
||||
};
|
||||
break;
|
||||
|
||||
case CanMessagePosicaoDados.Command2:
|
||||
ModoControleBomba modo;
|
||||
|
||||
|
|
@ -2411,26 +2417,20 @@ namespace AgroBase.Models
|
|||
{
|
||||
op.Parametros.Controle.AtuModoControle = modo;
|
||||
}
|
||||
|
||||
valores = new List<double?>
|
||||
{
|
||||
(int)modo,
|
||||
controleBase.Controle.Potencia
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
GeneralJoystick.EnviarComandoAtuador(
|
||||
comp,
|
||||
controleBase._comp_id,
|
||||
Status: controleBase.Controle.Estado,
|
||||
Valores: valores,
|
||||
Comando: controleBase.Controle.Comando,
|
||||
Forcar: true
|
||||
);
|
||||
dadosAtu?.EnviarComandoFisicoBomba(
|
||||
bomba,
|
||||
CanMessagePosicaoDados.Command1,
|
||||
controleBase.Controle.Estado == true,
|
||||
potencia: controleBase.Controle.Potencia,
|
||||
pressao: controleBase.Controle.Pressao,
|
||||
modo: op.Parametros.Controle.AtuModoControle
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecutarComandoSensoriamento(OperacaoComandoBaseModel controleBase, OperacaoModel op)
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ namespace AgroBase.Comum
|
|||
if (Dispositivo == T_Code.Sen)
|
||||
GeneralJoystick.EnviarComandoSensoriamento(S_Code.sMOD, "", Status: true);
|
||||
else if (Dispositivo == T_Code.Atu)
|
||||
GeneralJoystick.EnviarComandoAtuador(S_Code.sMOD, "", Status: true);
|
||||
(Dados as AtuadorModel)?.EnviarComandoFisicoReset();
|
||||
}
|
||||
|
||||
private void btnPinout_Click(object sender, EventArgs e)
|
||||
|
|
|
|||
|
|
@ -974,9 +974,6 @@ namespace AgroBase.Services.Operadores
|
|||
angulo_controle = bico.AnguloControle,
|
||||
angulo_abertura = bico.AnguloAbertura,
|
||||
|
||||
ultimo_comando_ms = idadeUltimoComandoBicoMs,
|
||||
ultima_resposta_ms = idadeUltimaRespostaBicoMs,
|
||||
|
||||
atuacoes = bico.Atuacoes,
|
||||
tempo_atuado = bico.TempoAtuado,
|
||||
tempo_atuado_em_movimento = bico.TempoAtuadoEmMovimento,
|
||||
|
|
@ -984,6 +981,16 @@ namespace AgroBase.Services.Operadores
|
|||
vazao_instantanea_mls = bico.VazaoInstantaneaMLs,
|
||||
vazao_media_mls = bico.VazaoMediaMLs,
|
||||
volume_vazado_ml = bico.VolumeVazadoML,
|
||||
|
||||
comando_solicitado = bico.ComandoAtuar,
|
||||
status_desejado_fisico = bico.UltimoStatusDesejado,
|
||||
angulo_desejado_fisico = bico.UltimoAnguloDesejado,
|
||||
ultimo_comando_ms = idadeUltimoComandoBicoMs,
|
||||
ultima_resposta_ms = idadeUltimaRespostaBicoMs,
|
||||
telemetria_pos_comando =
|
||||
bico.UltimoComandoEnviado != DateTime.MinValue &&
|
||||
bico.UltimaLeitura != DateTime.MinValue &&
|
||||
bico.UltimaLeitura >= bico.UltimoComandoEnviado
|
||||
};
|
||||
|
||||
atuBicosAtualizados.Add(($"{basePath}", bicoObj));
|
||||
|
|
@ -1056,13 +1063,21 @@ namespace AgroBase.Services.Operadores
|
|||
modo_controle = bomba.Controle?.Modo,
|
||||
sensor_id_num = bomba.Sensor_ID_Num,
|
||||
|
||||
ultimo_comando_ms = idadeUltimoComandoBombaMs,
|
||||
ultima_resposta_ms = idadeUltimaRespostaBombaMs,
|
||||
|
||||
atuacoes = bomba.Atuacoes,
|
||||
tempo_atuado = bomba.TempoAtuado,
|
||||
tempo_com_potencia = bomba.TempoComPotencia,
|
||||
potencia_media_ativa = bomba.PotenciaMediaAtiva,
|
||||
|
||||
comando_solicitado = bomba.ComandoAtuar,
|
||||
status_desejado_fisico = bomba.UltimoStatusDesejado,
|
||||
potencia_desejada_fisica = bomba.UltimaPotenciaDesejada,
|
||||
pressao_desejada_fisica = bomba.UltimaPressaoDesejada,
|
||||
ultimo_comando_ms = idadeUltimoComandoBombaMs,
|
||||
ultima_resposta_ms = idadeUltimaRespostaBombaMs,
|
||||
telemetria_pos_comando =
|
||||
bomba.UltimoComandoEnviado != DateTime.MinValue &&
|
||||
bomba.UltimaLeitura != DateTime.MinValue &&
|
||||
bomba.UltimaLeitura >= bomba.UltimoComandoEnviado
|
||||
};
|
||||
|
||||
atuBombasAtivos.Add($"{tipo}.{id}");
|
||||
|
|
|
|||
|
|
@ -562,7 +562,7 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
"ultimo_status_desejado" in dados
|
||||
)
|
||||
|
||||
comando = self._estado_desejado_ligado(dados)
|
||||
comando = self._estado_fisico_desejado_ligado(dados)
|
||||
estado = self._get(dados, "estado_leitura", self._campo_atual(dados, "EstadoLeitura", 0))
|
||||
estado_on = self._estado_ligado(estado)
|
||||
|
||||
|
|
@ -583,7 +583,13 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
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),
|
||||
dados.get(
|
||||
"angulo_desejado_fisico",
|
||||
dados.get(
|
||||
"angulo_desejado",
|
||||
angulo_controle if comando else angulo_neutro
|
||||
)
|
||||
),
|
||||
angulo_controle if comando else angulo_neutro,
|
||||
)
|
||||
|
||||
|
|
@ -610,6 +616,21 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
"angulo_desejado": angulo_desejado,
|
||||
"ultimo_comando_ms": ultimo_comando_ms,
|
||||
}
|
||||
|
||||
if self._aguardando_telemetria_pos_comando(dados):
|
||||
return 94, {
|
||||
"comando_disponivel": True,
|
||||
"aguardando_telemetria_pos_comando": True,
|
||||
"comando_fisico": comando,
|
||||
"comando_logico": self._comando_logico_ligado(dados),
|
||||
"estado_on": estado_on,
|
||||
"usa_servo": usa_servo,
|
||||
"angulo": angulo,
|
||||
"angulo_desejado": angulo_desejado,
|
||||
"ultimo_comando_ms": ultimo_comando_ms,
|
||||
"ultima_resposta_ms": self._float(dados.get("ultima_resposta_ms", 999999), 999999),
|
||||
"telemetria_pos_comando": self._telemetria_depois_do_comando(dados),
|
||||
}
|
||||
|
||||
if comando and not estado_on:
|
||||
severidade = 85 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_FALHA_MS else 70
|
||||
|
|
@ -631,14 +652,20 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
score = min(score, 55 if severidade >= 85 else 75)
|
||||
|
||||
if not comando and estado_on:
|
||||
severidade = 95 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_FALHA_MS else 82
|
||||
falha_confirmada = (
|
||||
tem_idade_comando and
|
||||
ultimo_comando_ms >= self.COMANDO_FALHA_MS and
|
||||
self._telemetria_depois_do_comando(dados)
|
||||
)
|
||||
|
||||
severidade = 95 if falha_confirmada else 82
|
||||
|
||||
motivos.append(f"Bico ligado sem comando ({label})")
|
||||
condicoes.append({
|
||||
"label": "Bico",
|
||||
"valor": 1,
|
||||
"severidade": severidade,
|
||||
"classe": "falha_hardware" if severidade > 90 else "processo",
|
||||
"classe": "falha_hardware" if falha_confirmada else "processo",
|
||||
"descricao": f"Bico {label} aparenta estar ligado sem comando",
|
||||
"acoes": [
|
||||
"Verificar travamento da solenoide.",
|
||||
|
|
@ -646,7 +673,7 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
],
|
||||
})
|
||||
|
||||
score = min(score, 25 if severidade > 90 else 65)
|
||||
score = min(score, 25 if falha_confirmada else 65)
|
||||
|
||||
if usa_servo and angulo is not None and angulo_desejado is not None:
|
||||
erro_ang = abs(angulo - angulo_desejado)
|
||||
|
|
@ -734,7 +761,7 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
"status_desejado_fisico" in dados or
|
||||
"ultimo_status_desejado" in dados
|
||||
)
|
||||
comando = self._estado_desejado_ligado(dados)
|
||||
comando = self._estado_fisico_desejado_ligado(dados)
|
||||
estado = self._get(dados, "estado_leitura", self._campo_atual(dados, "EstadoLeitura", 0))
|
||||
estado_on = self._estado_ligado(estado)
|
||||
|
||||
|
|
@ -768,6 +795,23 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
"pressao_sp": pressao_sp,
|
||||
"ultimo_comando_ms": ultimo_comando_ms,
|
||||
}
|
||||
|
||||
if self._aguardando_telemetria_pos_comando(dados):
|
||||
return 94, {
|
||||
"comando_disponivel": True,
|
||||
"aguardando_telemetria_pos_comando": True,
|
||||
"comando_fisico": comando,
|
||||
"comando_logico": self._comando_logico_ligado(dados),
|
||||
"estado_on": estado_on,
|
||||
"bomba_ligada": bomba_ligada,
|
||||
"potencia": potencia,
|
||||
"potencia_sp": potencia_sp,
|
||||
"pressao": pressao,
|
||||
"pressao_sp": pressao_sp,
|
||||
"ultimo_comando_ms": ultimo_comando_ms,
|
||||
"ultima_resposta_ms": self._float(dados.get("ultima_resposta_ms", 999999), 999999),
|
||||
"telemetria_pos_comando": self._telemetria_depois_do_comando(dados),
|
||||
}
|
||||
|
||||
if comando and not bomba_ligada:
|
||||
severidade = 85 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_FALHA_MS else 70
|
||||
|
|
@ -789,14 +833,25 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
score = min(score, 55 if severidade >= 85 else 75)
|
||||
|
||||
if not comando and bomba_ligada:
|
||||
severidade = 95 if tem_idade_comando and ultimo_comando_ms >= self.COMANDO_FALHA_MS else 82
|
||||
falha_confirmada = (
|
||||
tem_idade_comando and
|
||||
ultimo_comando_ms >= self.COMANDO_FALHA_MS and
|
||||
self._telemetria_depois_do_comando(dados)
|
||||
)
|
||||
|
||||
# O agitador não deve parar a operação por esse caso sozinho.
|
||||
# Ele pode alertar, mas não virar falha crítica do ATU.
|
||||
if eh_agitador:
|
||||
falha_confirmada = False
|
||||
|
||||
severidade = 95 if falha_confirmada else 82
|
||||
|
||||
motivos.append(f"Bomba {label} ligada sem comando")
|
||||
condicoes.append({
|
||||
"label": "Bomba",
|
||||
"valor": potencia,
|
||||
"severidade": severidade,
|
||||
"classe": "falha_hardware" if severidade > 90 else "processo",
|
||||
"classe": "falha_hardware" if falha_confirmada else "processo",
|
||||
"descricao": f"Bomba {label} aparenta ligada sem comando",
|
||||
"acoes": [
|
||||
"Verificar travamento de relé/saída.",
|
||||
|
|
@ -804,7 +859,7 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
],
|
||||
})
|
||||
|
||||
score = min(score, 25 if severidade > 90 else 65)
|
||||
score = min(score, 25 if falha_confirmada else 65)
|
||||
|
||||
if eh_principal and comando and bomba_ligada:
|
||||
pressao_ref = pressao if pressao > 0 else ctx["pressao_linha"]
|
||||
|
|
@ -1328,8 +1383,27 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
|
||||
def _comando_em_transicao(self, dados, janela_ms=None):
|
||||
janela_ms = janela_ms if janela_ms is not None else self.PROCESSO_GRACE_MS
|
||||
ultimo_comando_ms = self._float(dados.get("ultimo_comando_ms", 999999), 999999)
|
||||
return ultimo_comando_ms < 900000 and ultimo_comando_ms < janela_ms
|
||||
|
||||
ultimo_comando_ms = self._float(
|
||||
dados.get("ultimo_comando_ms", 999999),
|
||||
999999
|
||||
)
|
||||
|
||||
if ultimo_comando_ms >= 900000:
|
||||
return False
|
||||
|
||||
if ultimo_comando_ms < janela_ms:
|
||||
return True
|
||||
|
||||
# Mesmo fora da janela curta, se ainda não chegou telemetria
|
||||
# posterior ao comando, não dá para julgar a atuação como falha real.
|
||||
if (
|
||||
ultimo_comando_ms < self.COMANDO_FALHA_MS and
|
||||
not self._telemetria_depois_do_comando(dados)
|
||||
):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _pulverizacao_em_transicao(self, ctx):
|
||||
bomba = ctx.get("bomba_principal")
|
||||
|
|
@ -1413,22 +1487,85 @@ class ModuloAtuador(ModuloDiagnosticoBase):
|
|||
return texto in ["1", "ligado", "true", "on", "sim", "yes"]
|
||||
|
||||
def _estado_desejado_ligado(self, dados):
|
||||
"""
|
||||
Compatibilidade com código antigo.
|
||||
|
||||
A partir de agora, 'estado desejado' no health significa
|
||||
último estado físico enviado ao ATU, não intenção lógica instantânea.
|
||||
"""
|
||||
return self._estado_fisico_desejado_ligado(dados)
|
||||
|
||||
def _estado_fisico_desejado_ligado(self, dados):
|
||||
if not isinstance(dados, dict):
|
||||
return False
|
||||
|
||||
if "comando_atuar" in dados:
|
||||
return self._bool(dados.get("comando_atuar", False))
|
||||
|
||||
for key in [
|
||||
"estado_desejado",
|
||||
"status_desejado",
|
||||
"status_desejado_fisico",
|
||||
"estado_desejado_fisico",
|
||||
"estado_desejado",
|
||||
"ultimo_status_desejado",
|
||||
"status_desejado",
|
||||
]:
|
||||
if key in dados:
|
||||
if key in dados and dados.get(key) is not None:
|
||||
return self._estado_ligado(dados.get(key))
|
||||
|
||||
return False
|
||||
# Fallback para versões antigas do Redis.
|
||||
return self._bool(
|
||||
dados.get(
|
||||
"comando_solicitado",
|
||||
dados.get("comando_atuar", False)
|
||||
)
|
||||
)
|
||||
|
||||
def _comando_logico_ligado(self, dados):
|
||||
if not isinstance(dados, dict):
|
||||
return False
|
||||
|
||||
return self._bool(
|
||||
dados.get(
|
||||
"comando_solicitado",
|
||||
dados.get("comando_atuar", False)
|
||||
)
|
||||
)
|
||||
|
||||
def _tem_comando_fisico_registrado(self, dados):
|
||||
ultimo_comando_ms = self._float(
|
||||
dados.get("ultimo_comando_ms", 999999),
|
||||
999999
|
||||
)
|
||||
|
||||
return ultimo_comando_ms < 900000
|
||||
|
||||
def _telemetria_depois_do_comando(self, dados, tolerancia_ms=150):
|
||||
if not isinstance(dados, dict):
|
||||
return True
|
||||
|
||||
if not self._tem_comando_fisico_registrado(dados):
|
||||
return True
|
||||
|
||||
if "telemetria_pos_comando" in dados:
|
||||
return self._bool(dados.get("telemetria_pos_comando", False))
|
||||
|
||||
ultimo_comando_ms = self._float(dados.get("ultimo_comando_ms", 999999), 999999)
|
||||
ultima_resposta_ms = self._float(dados.get("ultima_resposta_ms", 999999), 999999)
|
||||
|
||||
if ultimo_comando_ms >= 900000 or ultima_resposta_ms >= 900000:
|
||||
return False
|
||||
|
||||
# idade menor = evento mais recente
|
||||
return ultima_resposta_ms <= ultimo_comando_ms + tolerancia_ms
|
||||
|
||||
def _aguardando_telemetria_pos_comando(self, dados):
|
||||
ultimo_comando_ms = self._float(
|
||||
dados.get("ultimo_comando_ms", 999999),
|
||||
999999
|
||||
)
|
||||
|
||||
return (
|
||||
ultimo_comando_ms < 900000 and
|
||||
ultimo_comando_ms < self.COMANDO_FALHA_MS and
|
||||
not self._telemetria_depois_do_comando(dados)
|
||||
)
|
||||
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
Loading…
Reference in New Issue