Boa tarde...
Consegui identificar o que estava acontecendo.
O retorno recebido da balança continha CarriageReturn (#13) que não eram tratados quando entrava na primeira condição do if wAchouE or wAchouO then da função InterpretarRepostaPeso da unit ACBrBALSaturno, já que a remoção de caracteres especiais não estava tratando os caracteres #13 e #10, e no else estavam sendo tratados, fazendo que com dependendo do tamanho do pacote a conversão da resposta pela função StrToFloat sempre caísse no bloco Except.
Trecho anterior (Condição if da função InterpretarRepostaPeso:
if wAchouE then
wPosEO := Pos('E', UpperCase(aResposta))
else
wPosEO := Pos('O', UpperCase(aResposta));
wResposta := Copy(aResposta, 0, wPosEO - 1);
{ Removendo caracteres especiais, caso encontre algum }
wResposta := StringReplace(wResposta, '°', '0', [rfReplaceAll]);
wResposta := StringReplace(wResposta, '±', '1', [rfReplaceAll]);
wResposta := StringReplace(wResposta, '²', '2', [rfReplaceAll]);
wResposta := StringReplace(wResposta, '³', '3', [rfReplaceAll]);
wResposta := StringReplace(wResposta, '´', '4', [rfReplaceAll]);
wResposta := StringReplace(wResposta, 'µ', '5', [rfReplaceAll]);
wResposta := StringReplace(wResposta, '¶', '6', [rfReplaceAll]);
wResposta := StringReplace(wResposta, '·', '7', [rfReplaceAll]);
wResposta := StringReplace(wResposta, '¸', '8', [rfReplaceAll]);
wResposta := StringReplace(wResposta, '¹', '9', [rfReplaceAll]);
// Sem tratamento para #13 e #10
end
Acabei unificando a remoção dos caracteres especiais em uma function interna SanitizarRespostaPeso(const aResposta: AnsiString) : AnsiString; e deixando nela também o tratamento para #13 e #10 (igual estava condição else) independente se na reposta de peso forem encontrados os indicadores de Estado do Peso (Caracteres "E" ou "O").
Também passei para remover os valores inválidos antes de tentar localizar os indicadores de Estado do Peso, pois imagino que de qualquer forma os caracteres especiais devem ser removidos nos dois casos (de ter localizado indicador de Estado do Peso ou não), caso isso estiver errado posso corrigir.
Modifiquei também para ler o valor do parâmetro aResposta somente no início, passando para a variável wResposta, para a partir disso o método somente trabalhar com o valor de wResposta já sanitizado.
Segue abaixo o trecho modificado de InterpretarRepostaPeso na unit ACBrBALSaturno:
function TACBrBALSaturno.InterpretarRepostaPeso(const aResposta: AnsiString): Double;
var
wAchouE, wAchouO: Boolean;
wPosEO: Integer;
wResposta: AnsiString;
function SanitizarRespostaPeso(const aResposta: AnsiString) : AnsiString;
begin
Result := Trim(aResposta);
if Result = EmptyStr then
Exit;
Result := StringReplace(Result, '°', '0', [rfReplaceAll]);
Result := StringReplace(Result, '±', '1', [rfReplaceAll]);
Result := StringReplace(Result, '²', '2', [rfReplaceAll]);
Result := StringReplace(Result, '³', '3', [rfReplaceAll]);
Result := StringReplace(Result, '´', '4', [rfReplaceAll]);
Result := StringReplace(Result, 'µ', '5', [rfReplaceAll]);
Result := StringReplace(Result, '¶', '6', [rfReplaceAll]);
Result := StringReplace(Result, '·', '7', [rfReplaceAll]);
Result := StringReplace(Result, '¸', '8', [rfReplaceAll]);
Result := StringReplace(Result, '¹', '9', [rfReplaceAll]);
Result := StringReplace(Result, #13, '', [rfReplaceAll]);
Result := StringReplace(Result, #10, '', [rfReplaceAll]);
Result := StringReplace(Result, '[CR]', '', [rfReplaceAll]);
Result := StringReplace(Result, '[LF]', '', [rfReplaceAll]);
end;
begin
Result := 0;
wAchouE := False;
wAchouO := False;
wPosEO := -1;
wResposta := EmptyStr;
{ Removendo caracteres especiais, caso encontre algum }
wResposta := SanitizarRespostaPeso(aResposta);
if (Trim(wResposta) = EmptyStr) then
Exit;
wAchouE := (Pos('E', UpperCase(wResposta)) > 0);
wAchouO := (Pos('O', UpperCase(wResposta)) > 0);
// Se encontrar a letra 'E' (Estável) ou 'O' (Oscilante), captura o peso da
// posição 1 a 7 da string
if wAchouE or wAchouO then
begin
if wAchouE then
wPosEO := Pos('E', UpperCase(wResposta))
else
wPosEO := Pos('O', UpperCase(wResposta));
wResposta := Copy(wResposta, 0, wPosEO - 1);
end
else
begin
wResposta := Copy(wResposta, 1, 9);
end;
if (Length(wResposta) > 0) then
begin
try
Result := StrToFloat(wResposta);
except
case PadLeft(Trim(wResposta),1)[1] of
'I': Result := -1; { Instavel }
'N': Result := -2; { Peso Negativo }
'S': Result := -10; { Sobrecarga de Peso }
else
Result := 0;
end;
end;
end
else
Result := 0;
end;
Segue em anexo o código-fonte completo alterado, caso puder ser analisado por algum committer do projeto ACBr e ser ou não adicionado no trunk.
Ainda com relação a gravação do log de pesagem, desculpem o equívoco, acredito que o componente está gravando correto, favor desconsiderar essa questão.
Qualquer dúvida ou erro estou a disposição.
Obrigado.
ACBrBALSaturno.pas