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

Add SQLite history for Events #171

Closed
wants to merge 14 commits into from
Closed

Add SQLite history for Events #171

wants to merge 14 commits into from

Conversation

zerox1212
Copy link
Contributor

@zerox1212 zerox1212 commented Apr 30, 2016

PR for work IN PROGRESS to add historizing events. At the moment it kind of works. Main problems are:

  1. Storage table isn't built dynamically; so only base event fields are historized at the moment.
  2. Reading of historized events don't get returned in same order as SelectClauses, this doesn't meet the spec and obviously needs to be fixed.
  3. Not sure how to handle a single object generating many event types. Should we make a table for each event type (easier) or add columns to single object table so that a multitude of event types for an object are in one table (harder).

One question I have for you guys. Even though an event uses ua.BaseEventType, it doesn't actually have all the fields in the event object. UaExpert gives 18 select clauses for the BaseType:
image
Even though our event only has 10 fields. I don't really know the best way to handle this. For now I just remove any select clauses that the event does not have. What is the best way to handle this?

@destogl FYI even when the server is subscribed to an event, the EventResult doesn't have the custom fields. Only the base fields are part of the EventResult class. Could be why UaExpert doesn't display custom properties that are added to a custom event.

@oroulet Sorry, no tests yet and this will probably fail existing tests until it can be cleaned up.

Enable historizing on an object which generates events (in most cases
probably the UA server object).
Expanding functionality so custom event types can be historized
Key change is in subscription; the idea is that whenever an event is to
be historized the history manager can just call event.getfields() and
store all the variant binaries in SQL.
Events are returned, but the order does not match select clauses which
creates problems
Now works with latest event implementation. Event history is returned,
but order is not correct yet. Also event table needs to be created
dynamically (hard coded at the moment for testing).
Manually update due to git errors
Start working on system to make tables dynamically based on fields.
Clean up some method names and isolate SQL string function.
Will need to use SQL UPDATE via field keyword because keeping attributes
on mutating classes is too difficult
@destogl
Copy link
Member

destogl commented Apr 30, 2016

@destogl FYI even when the server is subscribed to an event, the EventResult doesn't have the custom fields. Only the base fields are part of the EventResult class. Could be why UaExpert doesn't display custom properties that are added to a custom event.

Are you sure? Because I am pretty sure this is working properly since it is also well tested. Are you setting the right filter when subscribing to events?

@oroulet
Copy link
Member

oroulet commented Apr 30, 2016 via email

@oroulet
Copy link
Member

oroulet commented Apr 30, 2016

Maybe I remember wrong, but I think there is no way to discover what kind of events a node can generate. You need to know what event will be generated and create a filter for the properties you want.

This is the same when reading history, the reader need to create a filter for the event properties he wants. Thus we return a homogeneous list of fieldlist for every requested property

Events working in a limited capacity. Must find a better way to make
sure Object Event historical table has columns for every field of events
generated by the object. Currently only one event type is used to create
the columns.
@zerox1212
Copy link
Contributor Author

I fixed items 1 an 2 so I have event history working at the moment. I will clean it up and update the PR in a while.

@destogl how do I subscribe to the custom event fields? I don't see that in the example.

@zerox1212
Copy link
Contributor Author

zerox1212 commented May 1, 2016

So after I got history working with commit f590cb9 I realized I didn't really like how it's used by the user.

I really want a single enable_history high level method where only the node is given. Then the enable history method will check what kind of historizing to do (variable or events from object/server). But I'm stuck...

How can I get all generated events from an object node?
Seems like UaExpert gets close to what I want to do, I just need the event class afterwards:
image

I want to do something like this psuedo code:

# get event types
    for node in source.get_referenced_nodes():
        if node.get_type_definition() is Event:
            obj_events.append(instance_of_event_type)  # add the base event or custom event to a list so I can 
                                                        # build a table for all possible fields of source node

Without something like this the user will need to call enable_history(obj, event, period) for every event obj generates and I need to alter the SQL table with new fields that a different event might have.

Thoughts?

@oroulet
Copy link
Member

oroulet commented May 1, 2016

Many changes here are from destogl. Can you do a rebase on master?

@zerox1212
Copy link
Contributor Author

zerox1212 commented May 1, 2016

Ok sorry. I don't know git that well and git hub desktop sucks for this.

@zerox1212 zerox1212 closed this May 1, 2016
@oroulet oroulet reopened this May 1, 2016
@oroulet
Copy link
Member

oroulet commented May 1, 2016

no need to close this one

@oroulet
Copy link
Member

oroulet commented May 1, 2016

usually you avoid such thing by doing a 'pull -r' instead of pull. Now you already did a merge, so I am unsure how you should clean this up.

Maybe the easiest for you is to create a new branch from master. then cherry pick your commits (not many) and create new PR

and next time use "git pull -r" to merge changes from master

@oroulet
Copy link
Member

oroulet commented May 1, 2016

I really want a single enable_history high level method where only the node is given.

Yes I think this is what we should do. As far as I know there is no way to know what events a node generates but this is server side, the developer knows what event he generates and what we really need to specify is a list of event properties to store in DB. maybe something like
enable_history(obj, properties=list_of_properties, period=period)
or/and
enable_history(obj, events=list_of_events, period) #eventtypes or event objects that the server will generate

and then have both call internally:
enable_event_history(self, source, list_of_properties, period=timedelta(days=7)):
then you can create one sql column per property

Need to go. look at rest later

@zerox1212
Copy link
Contributor Author

I couldn't get git pull -r to work. It just made errors. I recreated the entire thing...

@zerox1212 zerox1212 closed this May 1, 2016
@destogl
Copy link
Member

destogl commented May 1, 2016

@destogl how do I subscribe to the custom event fields? I don't see that in the example.

When you subscribing to events than you should give event type as parameter, than you get all fields of that event into the filter (s. test)

Is is possible to get all events the node is generating with following code (the code is not tested so they are some small error, but logically should be correct):

obj = server.get_node("2:MyObject")
events = obj.get_referenced_nodes(ua.ObjectIds.GeneratesEvent) # or with all parameters: source.get_referenced_nodes(ua.ObjectIds.GeneratesEvent, direction=ua.BrowseDirection.Forward, ua.NodeClass.ObjectType, False)
print events
# here you should get all event nodes, if you want to get all fields than do following
for event in events:
    ev_properties = opcua.common.event.get_event_properties_from_type_node(event)
    print ev_properties
    # Now you have all properties for the event it is easy at that

@zerox1212: Why are you changing tables? Is this good approach? Why just not put EventResuts as json string into the one filed. In this way you have static table working with all types of events (but not only events, also datatypes since this is also a thing we are not doing much, but it is usually used.)

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 this pull request may close these issues.

3 participants