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

Handling libplctag exceptions when using alternative to mappers #425

Closed
MountainKing91 opened this issue Nov 25, 2024 · 5 comments
Closed

Comments

@MountainKing91
Copy link

Hi,

I am giving a try to the approach recently added to the examples as an alternative to the mappers system. I am using version 1.5.2.

I instantiated a few tags using the "TagDint" class defined in Definitions.cs:

public class Tags
{

    public string Gateway { get; private set; }
    public TagDint PartsCount { get; private set; }
    public TagDint PartsPreset { get; private set; }

    private const string PATH = "1,0";
    private const PlcType PLC_TYPE = PlcType.Omron;
    private const Protocol PROTOCOL = Protocol.ab_eip;

    public Tags(string gateway)
    {
        this.Gateway = gateway;

        PartsCount = new TagDint()
        {
            Name = "PartsCount",
            Gateway = this.Gateway,
            Path = PATH,
            PlcType = PLC_TYPE,
            Protocol = PROTOCOL,
            AutoSyncReadInterval = TimeSpan.FromMilliseconds(500),
            Timeout = TimeSpan.FromMilliseconds(5000),
            DebugLevel = DebugLevel.Error
        };

        PartsPreset = new TagDint()
        {
            Name = "PartsPreset",
            Gateway = this.Gateway,
            Path = PATH,
            PlcType = PLC_TYPE,
            Protocol = PROTOCOL,
            AutoSyncReadInterval = TimeSpan.FromMilliseconds(500),
            Timeout = TimeSpan.FromMilliseconds(5000),
            DebugLevel = DebugLevel.Error
        };
    }
}

At this time the PLC is not connected and whenever I instantiate my Tags class, I get an ErrorNotFound exception from the Decode method of the TagDint class.
While it is expected that the tag isn't to be found, I am not sure how I am supposed to handle this situation, since when using the mappers with version 1.4.0 that exception was not thrown. For reference, this is what I used with mappers:

private Tag<M, T> RegisterTag<M, T>(string name, int arrayLength, List<ITag> list) where M : IPlcMapper<T>, new()
{

var tag = new Tag<M, T>()
{
    Name = name,
    Gateway = ServiceParameters.IpAddress,
    Path = PATH,
    PlcType = PLC_TYPE,
    Protocol = PROTOCOL,
    ArrayDimensions = arrayLength > 0 ? new int[] { arrayLength } : null,
    Timeout = TimeSpan.FromMilliseconds(5000),
    AutoSyncReadInterval = TimeSpan.FromMilliseconds(100)
};

tag.ReadCompleted += Tag_ReadCompleted;
list.Add(tag);

return tag;
}

Can anybody give some insights? Thank you

@timyhac
Copy link
Collaborator

timyhac commented Nov 25, 2024

@MountainKing91 - I can't see any reason that Decode would be called from that code alone. Are you able to follow the stack trace to see what is calling it?

All the usual stuff will help, particularly logs and a repro.

@MountainKing91
Copy link
Author

And you're right, I was looking in the wrong direction - that code is not calling Decode, this one is (in another part of my app):

PartsCount = plcService.Tags.PartsCount.Value;
PartsPreset = plcService.Tags.PartsPreset.Value;

Commenting out the above code the exception is not thrown. I guess before I try to access the tag value I must make sure it is correctly initialized and its status is not < 0 ?

That is also what I actually did with mappers: looping over my tag list, I used a try-catch to initialize each tag and kept trying until GetStatus() returned 0.

@timyhac
Copy link
Collaborator

timyhac commented Nov 26, 2024

Yes you do need to initialize a tag before using it.
The only methods on Tag that trigger initialization are Initialize, Read, and their async equivalents - since you're using the inheritance example, you could add different behaviour if you want to.

@MountainKing91
Copy link
Author

MountainKing91 commented Nov 29, 2024

@timyhac Is there any reason not to do something like this (in BaseTag.cs)?

public void Read()
{
    if (tag.IsInitialized)
        tag.Read();
}

I'm thinking that doing this for every method that should be called only if the tag has been properly initialized (that is, the plc was "connected" successfully at least once) would make sure that decode/encode are called only if actually possible without throwing exceptions. The goal is to share the tag value across other part of an application without having to consider each time if the tag has been initialized or not.

@timyhac
Copy link
Collaborator

timyhac commented Nov 29, 2024

Feel free to modify the example code to suit your needs!

@timyhac timyhac closed this as completed Jan 1, 2025
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