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

Access tag name from PIAFAttribute #528

Closed
mro-msandford opened this issue Apr 21, 2020 · 2 comments · Fixed by #675
Closed

Access tag name from PIAFAttribute #528

mro-msandford opened this issue Apr 21, 2020 · 2 comments · Fixed by #675

Comments

@mro-msandford
Copy link

Feature request

Abstract

When querying data from a PIAFAttribute it's possible to get the underlying data, but it does not seem easy (or possible) to get the tag name that the attribute must be pointing to or otherwise referencing in order for that data to be retrieved.

Motivation and summary

When building applications on top of PI data one often wants to use PI AF in order to discover what data is available but once discovered to not incur the overhead of going back to AF in order to run additional queries on the timeseries data.

AF data is typically fairly static or is slowly changing. Once a PI tag name is determined from a PIAF attribute it's usually fixed for quite some time.

I've poked around the PIAFAttribute class and started peering into the PIAFAttribute.attribute but while I can find things that seem to be "name" or in some cases "tag" the value often seems to be much closer to a display name than an underlying tag name. Something like "Tank Level" which looks like a display name rather than "\SERVER\REGION.LOCATION.SITE.SKID.EQUIPMENT" which looks much more like a SCADA tag name.

Suggested solution

It would be great if there were a property or a function on the PIAFAttribute that one could call to retrieve the tag name. I can see it with the OSI PI Explorer but I haven't been able to figure out how to track it down within the PIConnect system.

Rejected options

I did poke around both the PIAttribute.attribute and PIAttribute.attribute.Data (using print(dir())) and also what comes back from PIAttribute.recorded_values(start, end) but none of them seemed to have what I was looking for. This despite the PISeries having an attribute called "tag" but again it seems to have a display name in it, not something that looks like a PI tag.

Additional context

This seems like it might be related to #506: #506

I'm happy to help by forking and making a PR but I suppose I'm not sure entirely where to start! I'm hoping that I could get some guidance or advice. Thanks!

@Hugovdberg
Copy link
Owner

This is somewhat related to #506, but not exactly. That issue was to get the internal name of the element itself, while this requests the name of a referenced PIPoint. I don't provide the option in the python code yet, but you can access the underlying .NET object to get the reference:

import PIconnect as PI

with PI.PIAFDatabase() as db:
    elem = db.descendant(r'Some\Path\To\An\Element')
    attr = elem.attributes['Interesting attribute']
    # Here it gets a little dirty:
    data_ref =attr.attribute.DataReference # returns the data reference for the underlying .NET AFAttribute
    if data_ref.Name == 'PI Point':
        pi_point = PI.PI.PIPoint(data_ref.PIPoint) # construct a python PIPoint object from the returned .NET object

Since PIconnect is very little more than a wrapper around the .NET attributes it should be not much of a problem to implement this more cleanly. I just haven't had the need for this yet. My thinking is that the nicest way to implement this would be to create a new class AFDataReference roughly like this, including the reference in the PIAFAttribute:

class AFDataReference:
    def __init__(self, attribute, data_reference):
        self.attribute = attribute # refering AF attribute
        self.data_reference = data_reference

    @property
    def name(self):
        return self.data_reference.Name

    @property
    def pi_point(self):
        if self.name == 'PI Point':
            return PI.PIPoint(self.data_reference.PIPoint)

class PIAFAttribute:
    # [...]
    @property
    def data_reference(self):
        return AFDataReference(self, self.attribute.DataReference)

This should be easy to add, I need to add attributes of attributes today, so this will be added soon.

@mro-msandford
Copy link
Author

I read this much earlier but haven't had time to say anything meaningful until now.

Thank you for the reference! I will give that a shot. I would love to be able to contribute more meaningfully but I've had a bit of a hard time understanding what's going on.

Also I am excited to see that the request isn't too difficult and that you're planning on adding functionality.

The thing that I'm probably most unclear on is the parallel class hierarchies and then how all the references get passed around and what their relations are. I wouldn't mind spending a bit of time to better understand this and I was thinking that a good exercise might be to try and generate some class diagrams. If I go to the effort I'd like to be able to contribute it to the project so I'd love feedback on what tools I should/shouldn't use if you have any preferences. If not I'm sure I can figure something out on my own.

Hugovdberg added a commit that referenced this issue Dec 17, 2022
closes #528

Added new data_reference property
Fixed circular import errors
@Hugovdberg Hugovdberg linked a pull request Dec 17, 2022 that will close this issue
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

Successfully merging a pull request may close this issue.

2 participants