Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Issue] System.UnauthorizedAccessException #81

Open
NintendoPlayer opened this issue Feb 21, 2022 · 4 comments
Open

[Issue] System.UnauthorizedAccessException #81

NintendoPlayer opened this issue Feb 21, 2022 · 4 comments

Comments

@NintendoPlayer
Copy link

Hi!

I've been using the library in a project. I'm connecting to Modbus RTU flow meters. First I designed the app for one type of them. Now I'm adding a second one.

I wrote a function that test the flow meter connected to guess the type. I read certain registers that are unique of each type and the return the type of the meter. The problem I'm getting is this

`
public static KeyValuePair<PingResult, MeterType> TestEquipmentExistsAndGetType(string serialPort, int baudRate = 9600, int unitIdentifier = 1, bool newClient = true, bool disconnectAtEnding = true)
{
PingResult test = PingResult.Error;

foreach (MeterType i in Enum.GetValues(typeof(MeterType)))

        {

            PingResult test = TestEquipmentExists(serialPort, i, baudRate, unitIdentifier);

            Thread.Sleep(100);

            if (((int)test) < 1)
            {
                test = PingResult.Ok;
                return new KeyValuePair<PingResult, MeterType>(test, i);
            }
        }

`

`public static PingResult TestEquipmentExists(string serialPort, MeterType meterType = MeterType.TypeOne, int baudRate = 9600, int unitIdentifier = 1, bool newClient = true, bool disconnectAtEnding = true)
{
PingResult result = PingResult.Error;
try
{
if (newClient)
{
NewStandardClient(serialPort, baudRate, unitIdentifier);
client.ConnectionTimeout = 1000;
client.NumberOfRetries = 2;
client.Connect();
}

            int[] respInstFlow = new int[2];
            switch (meterType)
            {
                case MeterType.TypeOne:
                    respInstFlow = ReadVariable(client, TypeOne.Variables.BASE_ADDRESS, 2);
                    break;

                case MeterType.TypeTwo:
                    respInstFlow = ReadVariable(client, TypeTwo.Parameters.BASE_ADDRESS, 2);
                    break;
            }

            if (respInstFlow[0] == -9876 && respInstFlow[1] == -1234)
            {
                throw new Helper.Exceptions.TimeoutException();
            }

            result = PingResult.Ok;
        }
        catch (Helper.Exceptions.TimeoutException ex)
        {
            result = PingResult.Timeout;
        }
        catch (UnauthorizedAccessException ex)
        {
            result = PingResult.PortInUse;
        }
        finally
        {
            if (disconnectAtEnding)
                Disconnect(true);
        }
        return result;
    }`

public static void Disconnect(bool destroy = false, bool disconnectReadings = true) { string serialPort = client.SerialPort; if (disconnectReadings) { FlagAllowVariableReadings = false; flagAllowParameterReadings = false; } client.Disconnect(); if (destroy) client = null; }

Ok, so this is what I try:

  • I call TestEquipmentExistsAndType(...)
  • I iterate through the two types of flow meters I have.
  • I read a different register in each type of meter.
  • Depending on the response I get I know the flow meter type.

I'm connected to a TypeTwo flowmeter, so:

  • The first test should throw a TimeoutException (custom exception that tells me that there was no valid response), this works.
  • The second iteration should throw a correct reading. But this is not happening. What I get is a System.UnauthorizedAccessException, which I catch as a PortInUse. But inside the Connect() on ModbusClient.cs, serialPort.IsOpen is false, so it is not the case.

What the real problem is; When I'm trying to read certain address on the TypeTwo meter, ReadInputRegister throws an EasyModbus.Exceptions.CRCCheckFailedException("Response CRC check failed") or an EasyModbus.Exceptions.StartingAddressInvalidException("Starting address invalid or starting address + quantity invalid"). TypeTwo meter only wants you to read the addresses in a certain fashion, otherwise it throws this error.

The thing is that, if I put a breakpoint in between the two iterations and wait enough time, like 30 seconds or so, the result is as expected. I don't know if this is something related to the meter, like it get's blocked when I try an invalid address, or it has something to do with the code. I know it's a bit convoluted, but maybe someone has a clue.

Thank you!

P.D: Please, fix the code, I can format it correctly :(

@NintendoPlayer NintendoPlayer changed the title [BUG] System.UnauthorizedAccessException aka ¿Serial Port in use? [BUG] System.UnauthorizedAccessException Feb 21, 2022
@NintendoPlayer NintendoPlayer changed the title [BUG] System.UnauthorizedAccessException [Issue] System.UnauthorizedAccessException Feb 21, 2022
@Padanian
Copy link

I don't know if this is related to your meters, but here's an hint. Battery-operated flow meters need to save energy, so their communication capability is budgeted to a max number of queries per day or a max frequency of queries.
There might be a delay required by the meter before the next query, after the first one.
If this is true, skip the first query in debug, and try the second iteration only. Come back to us with the result. I might be wrong, but I've had some experience with flow meters before.

@NintendoPlayer
Copy link
Author

NintendoPlayer commented Feb 21, 2022

I don't know if this is related to your meters, but here's an hint. Battery-operated flow meters need to save energy, so their communication capability is budgeted to a max number of queries per day or a max frequency of queries. There might be a delay required by the meter before the next query, after the first one. If this is true, skip the first query in debug, and try the second iteration only. Come back to us with the result. I might be wrong, but I've had some experience with flow meters before.

Hi @Padanian! Thanks for the help! The thing is that, if I connect directly to the meter, testing it without the first iteration, the connection is flawless as you say. The thing is that after the connection, I read an array of 20 registers each 500 ms and the communications works without an issue, so it must be another thing.

EDIT: Sorry, you try to say that, if the first reading is not right, the meter just waits longer to be able to read again from it?

@Padanian
Copy link

What I'm saying is that doesn't matter how many registers you read. The power consumption is not on the data transmission (or let's say there's a very little power consumption). Most of the power goes into polarising the wires, so when the connection is dropped (after first iteration), it might be that the meter wants you to wait before the next session. Is the flow meter battery-operated? If yes, we might be on the right track. Please be gentle on batteries, as your customer might end up with a flow meter that instead of lasting 7-10 years on batteries, might need replacement after 4-6 years, well below the projected life time.

@NintendoPlayer
Copy link
Author

This won't be a problem because the meters are not battery operated. What I did and, in fact work, is swithc the order of the enum, so that it first tries to check if the meter is TypeTwo insted of TypeOne. So after the two iterations, the function returns the correct type and the reading is correct.

I will try to test to connect to a TypeOne meter and do the same, iterate first with TypeTwo and second with TypeOne and see if the other meter throws the same System.UnauthorizedAccessException. If not, I will be that TypeTwo meter just wants you to wait before you try a reading after you tried reading an unathorized register. This meter doesn't like you tu read a register, it wants you to read a pair of them and with the right index. If not it throws an error, even with other test software.

I will try and update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants