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

pvaPy server listing all fields as 'changed' despite only updating value and timeStamp #88

Open
kathryn-baker opened this issue Apr 9, 2024 · 3 comments

Comments

@kathryn-baker
Copy link

Hi there, I am unsure which of the two libraries is best to post this in as it could be a pvapy or a p4p issue but I thought I would post it here first, apologies if that's wrong!

I am running a PvaPy server and updating values internally within the server (see the code snippet below), in most cases only updating the value and timeStamp (see the code snippet below) fields (see the code snippet below).

...
            example_pv.set(
                {"value": start_val, "timeStamp": PvTimeStamp(time.time()).toDict()}
            )
            server.update(pvname, example_pv)
...

However, when I use p4p to monitor the PV, the changedSet seems to indicate that all of the fields have updated each time, which is not the case.

... 
def callback(val):
    print(val.changedSet(expand=False))
...
mon = c.monitor(pv_name, cb=callback)

Output:

{'display.limitLow', 'valueAlarm.highWarningSeverity', 'display.description', 'valueAlarm.highAlarmSeverity', 'valueAlarm.highWarningLimit', 'value', 'alarm.status', 'display.units', 'valueAlarm.hysteresis', 'timeStamp.secondsPastEpoch', 'timeStamp.nanoseconds', 'valueAlarm.highAlarmLimit', 'valueAlarm.lowWarningSeverity', 'timeStamp.userTag', 'alarm.message', 'valueAlarm.lowAlarmSeverity', 'valueAlarm.lowAlarmLimit', 'valueAlarm.active', 'display.limitHigh', 'alarm.severity', 'valueAlarm.lowWarningLimit', 'display.format'}

At the moment this isn't too much of an issue but we are hoping to write more applications where it would be easier to identify the changedSet based on the results of this call rather than the user having to compare field equality on the application end each time.

Is there something extra we need to do on the server side to get this call right or is it possibly a difference in how the two libraries communicate?

I've attached a more complete example of the issue in Docker as a .zip file below to better illustrate the issue but for reference I am using Python 3.10 on Debian Linux with pvapy==5.3.1 and p4p==4.1.12
example.zip

Thanks in advance for your help!

@sveseli
Copy link
Collaborator

sveseli commented Apr 30, 2024

Thanks for the bug report. The problem is on the pvaPy side. The existing update() method updates entire record. The next release will contain method that will allow you to only update fields that have changed, e.g. something like this:

pv = PvObject({'x':INT, 'y':INT, 'z':FLOAT})
s = PvaServer()
s.addRecord('a', pv)
s.start()
for i in range(0,10):
    x = int(random.uniform(0,100))
    s.update('a', {'x' : x, 'y' : 2*x})
    time.sleep(10)

See commit 79bd642.

@kathryn-baker
Copy link
Author

That's great, thank you!

Out of interest, will this behaviour only work when passing the dictionary rather than the full object?

Currently we are running .set() on the PV Object and then using this object in the server.update() call e.g.

update = {'value': 2}
pvobject.set(update)
server.update('pv:name', pvobject)

With this update does this mean we can remove the set() call completely? e.g.

update = {'value': 2}
server.update('pv:name', update)

@sveseli
Copy link
Collaborator

sveseli commented Apr 30, 2024

Correct, you will be able to remove the "set()" call. The update(pvObject) method updates the whole record structure.

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