-
Notifications
You must be signed in to change notification settings - Fork 88
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
Write to NTTables #1214
Comments
Has anybody taken a look at this issue? It is still unassigned. The write functionality would be a really highly appreciated feature to have. |
We discussed this in today's meetings.. we have 2 AI associated with this request |
All right, that sounds promising, thanks! |
Each table use case seems to basically describe its own little application, requiring specialized behavior. At best you could add "limited" write support, as you suggest, only for string cells. |
Well, I can do pvput's to NTTables so I do not immediately see why that would not be doable from a table widget? |
So I think the agreement was to aim for a "limited" write support... something that covers basic cases and avoids the use of scripts. I agree with maintaining the "confirmation" behavior... we can do a write each cell when Enter is pressed. |
That's good because it matches the text entry field behavior. But I don't think you can write just one cell, so each cell change would write the complete table. |
exactly.. going for simple and predictable behaviour here
We brought this up for discussion, it turns out that all the use cases from ESS and DLS would be fine with writing the complete table when updating a single cell.
We can bring up this issue... |
In fact, I would even expect and insist on writing the full table. But after updating each individual cell...? That could be a problem. If you are for instance updating a (breakpoint) conversion table (just imagining here), you want to have the full table completed before committing it. |
Right, in that case you probably want to submit a consistent set of values, and assert that the values are increasing along one axis, which can be handled by a simple "values_in_column_1_increase_monotonically" option on the table widget. |
That was a bit of an imagined example. I would not encourge editing breakpoint tables in a table widget anyway, this would be too risky for a number of reasons. But I still would not back up from the original argument of covering the generic use case a la pvput. No custom logic required. |
Yes, there are application specific issues, but I don't think it's hopeless. For the breakpoint example, it would make more sense for the IOC to validate the table input and reject invalid tables. I think what @ttkorhonen is asking for is just a single option for write on blur (for the table) vs focusout (for the cell) as suggested in the original issue. This should be a simple boolean option for the widget. |
I must add that I have no idea about how the table widget is implemented. If I write a script, would that script be executed after each cell update? |
The script is for example attached to a "Submit" button. |
Right. Then instead of the script, we could have a piece of Java code that reads the elements from the table and does a pvput. This is more or less all I would ask for. If I need custom logic, I would write a script or do something else. |
My main concern is an explosion of widget properties and logic. |
That makes sense. I would love to help, but unfortunately the project I originally needed this for has been put on indefinite hold and I don't really have the bandwidth to take this on currently. |
After talking to @aawdls I believe the DLS requirement is one that originates from me, so I'll put it here for completeness. A PandABox is a configurable FPGA based trigger box. One of its functions is a sequencer table, which takes rows of trigger enum, number of repeats, phased times and output selections. It is currently controlled via a web GUI that looks like this: In the web GUI we don't send the value of the table down to the server until the submit button is pressed, and there is a discard button to revert to the server's copy. However, sites have requested an EPICS IOC that lets you set every single parameter of a PandA. I've packaged every column of the table in a waveform record, and tied them together into an NTTable in the IOC with QSRV. This is not quite working, but is almost there. I hoped to be able to attach a phoebus table widget to this NTTable, but haven't tried it out yet, so this ticket is very relevant. A slight issue is that the columns have different datatypes, uint8, uint32, and enum. The first two are expressible in an NTTable, the last is not. I'm going to talk about this in the EPICS core meeting Wednesday next week to work out how this could be expressed in an NTTable, but I see that the phoebus widget already the ability to add choices to a column so maybe this will not be an issue? |
I'm not at all familiar with Phoebus, but I've had a go at mocking up a table that switches between from org.csstudio.display.builder.runtime.script import PVUtil, ScriptUtil
mode = PVUtil.getLong(pvs[0])
table = PVUtil.getTable(pvs[1])
if mode == 0: # Displaying
widget.setValue(table)
widget.setPropertyValue("editable", False)
elif mode == 1: # Editing
widget.setPropertyValue("editable", True)
elif mode == 2: # Submit
pvs[0].write(0)
pvs[1].write(widget.getValue()) is in the repo along with the QSRV ioc that serves the NTTable: https://github.com/thomascobb/nt_table_test I can't make a couple of things work:
|
I've worked around the last point by converting from number to string in the embedded script. Obviously type conversion in an embedded Jython script is not a long term solution, but it is sufficient to demonstrate the principle. I've also made a proposal for getting |
@thomascobb Your use case is almost identical to mine. I was able to write to NTTables by doing the following: from org.csstudio.display.builder.runtime.script import ScriptUtil
from org.epics.pva.data import PVAStructure, PVAStringArray
table = ScriptUtil.findWidgetByName(widget, "table")
data = table.getValue()
# Modify data ...
pv = ScriptUtil.getPrimaryPV(table)
ncol = len(data[0])
ntrows = [PVAStringArray("column"+str(i), [row[i] for row in data]) for i in range(ncol)]
pv.write(PVAStructure("", "", ntrows)) You can modify the individual column types (e.g., |
@jjaraalm thanks, that looks like just what I need! |
So based on push from users I started to look into "native" support for writing NTTable from Phoebus. I've come far enough to construct a Java object that - based on my understanding at least - should be good enough. The write operation seems to succeed as the IOC shell echos a message, and a pvmonitor on the PV in question also echoes. Problem is the actual values in the table are unchanged, kind of a deal breaker here. To summarize, I have table with two integer array columns. In |
The above examples all use a string table, while you have integer columns. Maybe try string columns. |
Not sure I understand why strings should work. After all, we know what underlying types we're dealing with. |
To clarify, I'm not (yet) implementing write from Table widget. My use case is save&restore. |
Digging deeper into my failed attempts to actually write data I have identified the reason: the BitSet portion of the put request. Tests performed on the following PV running on a 7.0.7 server:
So when trying to update values in arrays A and B the client currently sets only bit 14 ( In Maybe I'm not using the API correctly...? @kasemir, can you please comment? |
The bitfield usage might be the reason. What we've tried so far is reading and sometimes writing the types presented by IOCs, where we don't get any table data. Brings up the question how to duplicate this. |
Well, with code adding the "missing" indices I am able to replicate the CLI pvput functionality. |
Did you update the existing code so that when it flags the "structure" as changed, it will recurse inside the structure and flag all elements as changed? Or do you just manually flag "A" and "B" to test this specific case? |
Don't worry, won't push my hack. |
If a structure is flagged as changed, does that mean I don't think the exact behavior is defined anywhere, but you clearly see the latter case. Since we have at least one server that requires each element to be flagged, we can use that as the defining case since it should still "work" for those servers that go by just the overall structure flag, so we won't break anything.
Feel free to turn that into a PR |
If the structure has two arrays and only one of them changes, is the "whole" structure changed?
That is what I conclude and that is what pvput does.
Vanilla Epics 7.0.7 built on Mac. With pvAccess module. |
How do you create the table? 'group' settings on records? Can you post that? |
I found a thing a bit concerning on page 12 in https://epics-controls.org/wp-content/uploads/2018/10/pvAccess-Protocol-Specification.pdf:
But maybe that spec is outdated... |
That refers to array elements. We always flag the whole array as changed, and send the complete array. There is nothing in the protocol to say: For array X, replace element 5 with 47, then set elements 10 to 20 to 0. No support for slices within an array. |
I see. Apparently "array elements" can be interpreted in multiple ways... |
Yes, it's meant as "BitSet does not apply to individual array elements. One bit in bitset addresses the complete array". |
That group-based table example is good. Include that in a PR which recursively flags the elements of a structure. |
Kudos to @ttkorhonen for providing me with the table example. |
Well, good as in providing an easy to use example. |
I got mentioned :-) Michael has improved the group PV documentation in the meantime: https://mdavidsaver.github.io/pvxs/qgroup.html And yes, the definition syntax is somewhat complicated but also powerful. However, if you ask me, it is on the easier side of things to learn related to PVA. But sure, one could probably make it easier. I just do not have any good ideas how. |
@kasemir, one more question before I proceed. By default |
I'd leave the labels alone. With IOC records that support enumerated values (bo, mbbo) you receive the value with labels. You can write the value, but I don't think you can write the labels. So change the labels you'd need a separate channel to for example "record.ZNAM" of a bi/bo record or a "record.ZRST" of an mbbi/o, which gives a string value and when you write that value, you change the first enumeration label. But you can't directly write the labels associated with a value update, just like you can't write the time stamp or alarm info. |
Currently, the table widget does not appear to write to
NTTable
PVs. SinceNTTable
is well defined, it would be nice if there was (limited) support for writing toNTTable
PVs.Potential Issues
Suggested Options
The text was updated successfully, but these errors were encountered: